aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVladimir Makarov <vmakarov@redhat.com>2008-07-28 21:13:22 +0000
committerVladimir Makarov <vmakarov@redhat.com>2008-07-28 21:13:22 +0000
commit5a5cfb65e55cd766d62c9cc7e8bf3f56602e9bb4 (patch)
tree77c2df5e1bb71f2d757082d579cfa10b1d6cb75b
parent0f4c846302c425282a196c1b2e5351a5eb984d84 (diff)
Merge from trunk @ 138209
git-svn-id: https://gcc.gnu.org/svn/gcc/branches/ira@138218 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--ChangeLog4
-rw-r--r--MAINTAINERS1
-rw-r--r--boehm-gc/ChangeLog6
-rw-r--r--boehm-gc/Makefile.in10
-rwxr-xr-xboehm-gc/configure3
-rw-r--r--boehm-gc/configure.ac2
-rw-r--r--boehm-gc/threads.mk.in3
-rw-r--r--config/ChangeLog5
-rw-r--r--config/mh-mingw2
-rw-r--r--contrib/ChangeLog4
-rw-r--r--contrib/check_makefile_deps.sh94
-rw-r--r--gcc/ChangeLog2247
-rw-r--r--gcc/ChangeLog.tuples8231
-rw-r--r--gcc/DATESTAMP2
-rw-r--r--gcc/Makefile.in874
-rw-r--r--gcc/ada/ChangeLog76
-rw-r--r--gcc/ada/Make-lang.in4
-rw-r--r--gcc/ada/ada-tree.h2
-rw-r--r--gcc/ada/adaint.c10
-rw-r--r--gcc/ada/gigi.h12
-rw-r--r--gcc/ada/gnat_ugn.texi278
-rw-r--r--gcc/ada/gnathtml.pl1115
-rw-r--r--gcc/ada/misc.c4
-rw-r--r--gcc/ada/raise-gcc.c4
-rw-r--r--gcc/ada/targtyps.c6
-rw-r--r--gcc/ada/trans.c49
-rw-r--r--gcc/ada/utils.c40
-rw-r--r--gcc/attribs.c36
-rw-r--r--gcc/basic-block.h20
-rw-r--r--gcc/bt-load.c67
-rw-r--r--gcc/builtins.c521
-rw-r--r--gcc/c-common.c604
-rw-r--r--gcc/c-common.h44
-rw-r--r--gcc/c-cppbuiltin.c52
-rw-r--r--gcc/c-decl.c321
-rw-r--r--gcc/c-errors.c6
-rw-r--r--gcc/c-format.c2
-rw-r--r--gcc/c-gimplify.c21
-rw-r--r--gcc/c-lex.c11
-rw-r--r--gcc/c-omp.c2
-rw-r--r--gcc/c-opts.c19
-rw-r--r--gcc/c-parser.c327
-rw-r--r--gcc/c-pch.c5
-rw-r--r--gcc/c-pragma.c344
-rw-r--r--gcc/c-pretty-print.c6
-rw-r--r--gcc/c-semantics.c3
-rw-r--r--gcc/c-tree.h6
-rw-r--r--gcc/c-typeck.c262
-rw-r--r--gcc/caller-save.c79
-rw-r--r--gcc/calls.c27
-rw-r--r--gcc/cfg.c14
-rw-r--r--gcc/cfgexpand.c536
-rw-r--r--gcc/cfghooks.c8
-rw-r--r--gcc/cfghooks.h6
-rw-r--r--gcc/cfgloop.c11
-rw-r--r--gcc/cfgloop.h2
-rw-r--r--gcc/cfgrtl.c4
-rw-r--r--gcc/cgraph.c347
-rw-r--r--gcc/cgraph.h48
-rw-r--r--gcc/cgraphbuild.c142
-rw-r--r--gcc/cgraphunit.c261
-rw-r--r--gcc/collect2.c70
-rw-r--r--gcc/combine-stack-adj.c83
-rw-r--r--gcc/combine.c205
-rw-r--r--gcc/common.opt32
-rw-r--r--gcc/config.gcc98
-rw-r--r--gcc/config.in24
-rw-r--r--gcc/config/alpha/alpha.c48
-rw-r--r--gcc/config/arm/aout.h3
-rw-r--r--gcc/config/arm/arm.c84
-rw-r--r--gcc/config/arm/bpabi.h7
-rw-r--r--gcc/config/arm/eabi.h125
-rw-r--r--gcc/config/arm/eabi.opt23
-rw-r--r--gcc/config/arm/elf.h6
-rw-r--r--gcc/config/arm/iwmmxt.md36
-rw-r--r--gcc/config/arm/unknown-elf.h8
-rw-r--r--gcc/config/avr/avr-protos.h1
-rw-r--r--gcc/config/avr/avr.c31
-rw-r--r--gcc/config/avr/avr.md27
-rw-r--r--gcc/config/bfin/bfin.c17
-rw-r--r--gcc/config/cris/cris.c11
-rw-r--r--gcc/config/cris/cris.h12
-rw-r--r--gcc/config/cris/cris.md82
-rw-r--r--gcc/config/frv/frv.c2
-rw-r--r--gcc/config/h8300/h8300.c18
-rw-r--r--gcc/config/h8300/h8300.md2
-rw-r--r--gcc/config/host-linux.c2
-rw-r--r--gcc/config/host-solaris.c8
-rw-r--r--gcc/config/i386/cross-stdarg.h76
-rw-r--r--gcc/config/i386/darwin.h4
-rw-r--r--gcc/config/i386/i386-c.c344
-rw-r--r--gcc/config/i386/i386-protos.h12
-rw-r--r--gcc/config/i386/i386.c1627
-rw-r--r--gcc/config/i386/i386.h222
-rw-r--r--gcc/config/i386/i386.md62
-rw-r--r--gcc/config/i386/i386.opt163
-rw-r--r--gcc/config/i386/sse.md144
-rw-r--r--gcc/config/i386/t-i38613
-rw-r--r--gcc/config/ia64/ia64.c30
-rw-r--r--gcc/config/m32c/m32c-protos.h4
-rw-r--r--gcc/config/m32c/m32c.c2
-rw-r--r--gcc/config/m68k/lb1sf68.asm36
-rw-r--r--gcc/config/m68k/m68k-devices.def30
-rw-r--r--gcc/config/m68k/m68k.c4
-rw-r--r--gcc/config/m68k/t-cf3
-rw-r--r--gcc/config/m68k/t-linux11
-rw-r--r--gcc/config/mips/constraints.md5
-rw-r--r--gcc/config/mips/driver-native.c6
-rw-r--r--gcc/config/mips/mips.c100
-rw-r--r--gcc/config/mips/mips.h3
-rw-r--r--gcc/config/mips/mips.md52
-rw-r--r--gcc/config/mn10300/mn10300.h13
-rw-r--r--gcc/config/mn10300/mn10300.md24
-rw-r--r--gcc/config/pa/pa.c7
-rw-r--r--gcc/config/rs6000/host-darwin.c5
-rw-r--r--gcc/config/rs6000/rs6000-c.c157
-rw-r--r--gcc/config/rs6000/rs6000.c107
-rw-r--r--gcc/config/s390/s390.c63
-rw-r--r--gcc/config/s390/s390.md10
-rw-r--r--gcc/config/sh/sh.c63
-rw-r--r--gcc/config/sh/sh.h10
-rw-r--r--gcc/config/sh/sh.md3
-rw-r--r--gcc/config/sparc/sparc.c10
-rw-r--r--gcc/config/sparc/sparc.h7
-rw-r--r--gcc/config/spu/spu-c.c74
-rw-r--r--gcc/config/spu/spu.c33
-rw-r--r--gcc/config/spu/spu.md65
-rw-r--r--gcc/config/stormy16/stormy16.c21
-rw-r--r--gcc/config/xtensa/libgcc-xtensa.ver3
-rw-r--r--gcc/config/xtensa/t-linux2
-rw-r--r--gcc/config/xtensa/xtensa.c44
-rw-r--r--gcc/config/xtensa/xtensa.h16
-rwxr-xr-xgcc/configure122
-rw-r--r--gcc/configure.ac26
-rw-r--r--gcc/coretypes.h15
-rw-r--r--gcc/cp/ChangeLog422
-rw-r--r--gcc/cp/Make-lang.in8
-rw-r--r--gcc/cp/call.c24
-rw-r--r--gcc/cp/class.c118
-rw-r--r--gcc/cp/cp-gimplify.c243
-rw-r--r--gcc/cp/cp-tree.h38
-rw-r--r--gcc/cp/cvt.c10
-rw-r--r--gcc/cp/cxx-pretty-print.c6
-rw-r--r--gcc/cp/decl.c223
-rw-r--r--gcc/cp/decl2.c62
-rw-r--r--gcc/cp/error.c2
-rw-r--r--gcc/cp/except.c45
-rw-r--r--gcc/cp/friend.c8
-rw-r--r--gcc/cp/init.c36
-rw-r--r--gcc/cp/lex.c204
-rw-r--r--gcc/cp/mangle.c31
-rw-r--r--gcc/cp/method.c1
-rw-r--r--gcc/cp/name-lookup.c143
-rw-r--r--gcc/cp/operators.def4
-rw-r--r--gcc/cp/optimize.c28
-rw-r--r--gcc/cp/parser.c916
-rw-r--r--gcc/cp/pt.c237
-rw-r--r--gcc/cp/rtti.c2
-rw-r--r--gcc/cp/search.c14
-rw-r--r--gcc/cp/semantics.c48
-rw-r--r--gcc/cp/tree.c16
-rw-r--r--gcc/cp/typeck.c80
-rw-r--r--gcc/cp/typeck2.c27
-rw-r--r--gcc/cse.c126
-rw-r--r--gcc/dbgcnt.def2
-rw-r--r--gcc/defaults.h6
-rw-r--r--gcc/df-core.c2
-rw-r--r--gcc/df-problems.c18
-rw-r--r--gcc/df-scan.c18
-rw-r--r--gcc/diagnostic.c47
-rw-r--r--gcc/diagnostic.h16
-rw-r--r--gcc/doc/c-tree.texi13
-rw-r--r--gcc/doc/extend.texi344
-rw-r--r--gcc/doc/install.texi18
-rw-r--r--gcc/doc/invoke.texi105
-rw-r--r--gcc/doc/md.texi10
-rw-r--r--gcc/doc/options.texi15
-rw-r--r--gcc/doc/tm.texi93
-rw-r--r--gcc/dojump.c3
-rw-r--r--gcc/domwalk.c24
-rw-r--r--gcc/domwalk.h4
-rw-r--r--gcc/dse.c16
-rw-r--r--gcc/dwarf2asm.c10
-rw-r--r--gcc/dwarf2out.c103
-rw-r--r--gcc/ebitmap.h2
-rw-r--r--gcc/emit-rtl.c142
-rw-r--r--gcc/except.c44
-rw-r--r--gcc/except.h11
-rw-r--r--gcc/explow.c12
-rw-r--r--gcc/expmed.c8
-rw-r--r--gcc/expr.c53
-rw-r--r--gcc/expr.h3
-rw-r--r--gcc/final.c52
-rw-r--r--gcc/flags.h12
-rw-r--r--gcc/fold-const.c54
-rw-r--r--gcc/fortran/ChangeLog425
-rw-r--r--gcc/fortran/Make-lang.in7
-rw-r--r--gcc/fortran/arith.c46
-rw-r--r--gcc/fortran/array.c30
-rw-r--r--gcc/fortran/bbt.c14
-rw-r--r--gcc/fortran/check.c62
-rw-r--r--gcc/fortran/data.c6
-rw-r--r--gcc/fortran/decl.c96
-rw-r--r--gcc/fortran/dependency.c28
-rw-r--r--gcc/fortran/dump-parse-tree.c8
-rw-r--r--gcc/fortran/expr.c42
-rw-r--r--gcc/fortran/f95-lang.c18
-rw-r--r--gcc/fortran/gfc-internals.texi149
-rw-r--r--gcc/fortran/gfortran.h34
-rw-r--r--gcc/fortran/interface.c202
-rw-r--r--gcc/fortran/intrinsic.c288
-rw-r--r--gcc/fortran/invoke.texi55
-rw-r--r--gcc/fortran/io.c76
-rw-r--r--gcc/fortran/iresolve.c6
-rw-r--r--gcc/fortran/lang.opt16
-rw-r--r--gcc/fortran/match.c21
-rw-r--r--gcc/fortran/matchexp.c29
-rw-r--r--gcc/fortran/module.c88
-rw-r--r--gcc/fortran/openmp.c8
-rw-r--r--gcc/fortran/options.c32
-rw-r--r--gcc/fortran/parse.c6
-rw-r--r--gcc/fortran/primary.c10
-rw-r--r--gcc/fortran/resolve.c102
-rw-r--r--gcc/fortran/scanner.c25
-rw-r--r--gcc/fortran/st.c10
-rw-r--r--gcc/fortran/symbol.c46
-rw-r--r--gcc/fortran/trans-array.c255
-rw-r--r--gcc/fortran/trans-array.h14
-rw-r--r--gcc/fortran/trans-common.c8
-rw-r--r--gcc/fortran/trans-decl.c23
-rw-r--r--gcc/fortran/trans-expr.c127
-rw-r--r--gcc/fortran/trans-intrinsic.c104
-rw-r--r--gcc/fortran/trans-io.c40
-rw-r--r--gcc/fortran/trans-openmp.c57
-rw-r--r--gcc/fortran/trans-stmt.c155
-rw-r--r--gcc/fortran/trans-types.c20
-rw-r--r--gcc/fortran/trans.c74
-rw-r--r--gcc/fortran/trans.h22
-rw-r--r--gcc/function.c67
-rw-r--r--gcc/function.h4
-rw-r--r--gcc/fwprop.c95
-rw-r--r--gcc/gcc.c22
-rw-r--r--gcc/gcse.c52
-rw-r--r--gcc/genattrtab.c16
-rw-r--r--gcc/genemit.c16
-rw-r--r--gcc/gengtype.c10
-rw-r--r--gcc/gengtype.h2
-rw-r--r--gcc/genoutput.c40
-rw-r--r--gcc/genrecog.c52
-rw-r--r--gcc/gensupport.c10
-rw-r--r--gcc/ggc-common.c4
-rw-r--r--gcc/ggc-page.c8
-rw-r--r--gcc/ggc-zone.c30
-rw-r--r--gcc/gimple-iterator.c771
-rw-r--r--gcc/gimple-low.c575
-rw-r--r--gcc/gimple-pretty-print.c1857
-rw-r--r--gcc/gimple.c3144
-rw-r--r--gcc/gimple.def357
-rw-r--r--gcc/gimple.h4539
-rw-r--r--gcc/gimplify.c2704
-rw-r--r--gcc/global.c4
-rw-r--r--gcc/graph.c10
-rw-r--r--gcc/gsstruct.def48
-rw-r--r--gcc/input.h5
-rw-r--r--gcc/ipa-cp.c158
-rw-r--r--gcc/ipa-inline.c276
-rw-r--r--gcc/ipa-prop.c1234
-rw-r--r--gcc/ipa-prop.h185
-rw-r--r--gcc/ipa-pure-const.c167
-rw-r--r--gcc/ipa-reference.c222
-rw-r--r--gcc/ipa-struct-reorg.c532
-rw-r--r--gcc/ipa-struct-reorg.h8
-rw-r--r--gcc/ipa-type-escape.c519
-rw-r--r--gcc/ipa-type-escape.h4
-rw-r--r--gcc/ipa-utils.c2
-rw-r--r--gcc/java/ChangeLog78
-rw-r--r--gcc/java/Make-lang.in13
-rw-r--r--gcc/java/decl.c24
-rw-r--r--gcc/java/expr.c15
-rw-r--r--gcc/java/java-gimplify.c25
-rw-r--r--gcc/java/java-tree.h4
-rw-r--r--gcc/java/jcf-io.c144
-rw-r--r--gcc/java/jcf.h10
-rw-r--r--gcc/java/lang.c6
-rw-r--r--gcc/lambda-code.c380
-rw-r--r--gcc/lambda-mat.c1
-rw-r--r--gcc/lambda-trans.c1
-rw-r--r--gcc/lambda.h4
-rw-r--r--gcc/langhooks-def.h2
-rw-r--r--gcc/langhooks.c17
-rw-r--r--gcc/langhooks.h2
-rw-r--r--gcc/lcm.c24
-rw-r--r--gcc/local-alloc.c16
-rw-r--r--gcc/lower-subreg.c6
-rw-r--r--gcc/matrix-reorg.c95
-rw-r--r--gcc/mode-switching.c8
-rw-r--r--gcc/objc/ChangeLog45
-rw-r--r--gcc/objc/Make-lang.in4
-rw-r--r--gcc/objc/objc-act.c194
-rw-r--r--gcc/objc/objc-act.h4
-rw-r--r--gcc/objcp/Make-lang.in6
-rw-r--r--gcc/omp-low.c2776
-rw-r--r--gcc/opt-functions.awk17
-rw-r--r--gcc/optabs.c72
-rw-r--r--gcc/optc-gen.awk319
-rw-r--r--gcc/opth-gen.awk171
-rw-r--r--gcc/opts.c417
-rw-r--r--gcc/opts.h1
-rw-r--r--gcc/passes.c51
-rw-r--r--gcc/postreload.c12
-rw-r--r--gcc/predict.c306
-rw-r--r--gcc/print-tree.c43
-rw-r--r--gcc/profile.c47
-rw-r--r--gcc/ra.h8
-rw-r--r--gcc/recog.c84
-rw-r--r--gcc/reg-stack.c76
-rw-r--r--gcc/regclass.c136
-rw-r--r--gcc/regrename.c138
-rw-r--r--gcc/reload.c226
-rw-r--r--gcc/reload.h2
-rw-r--r--gcc/reload1.c120
-rw-r--r--gcc/rtlanal.c28
-rw-r--r--gcc/rtlhooks.c8
-rw-r--r--gcc/sched-ebb.c6
-rw-r--r--gcc/sched-rgn.c6
-rw-r--r--gcc/stmt.c12
-rw-r--r--gcc/stor-layout.c14
-rw-r--r--gcc/system.h6
-rw-r--r--gcc/target-def.h55
-rw-r--r--gcc/target.h55
-rw-r--r--gcc/targhooks.c58
-rw-r--r--gcc/targhooks.h3
-rw-r--r--gcc/testsuite/ChangeLog580
-rw-r--r--gcc/testsuite/g++.dg/conversion/op5.C20
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/defaulted1.C43
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/defaulted2.C66
-rw-r--r--gcc/testsuite/g++.dg/eh/async-unwind1.C61
-rw-r--r--gcc/testsuite/g++.dg/ext/has_nothrow_assign.C12
-rw-r--r--gcc/testsuite/g++.dg/ext/has_nothrow_assign_odr.C16
-rw-r--r--gcc/testsuite/g++.dg/ext/has_nothrow_constructor.C4
-rw-r--r--gcc/testsuite/g++.dg/ext/has_nothrow_constructor_odr.C16
-rw-r--r--gcc/testsuite/g++.dg/ext/has_nothrow_copy-1.C (renamed from gcc/testsuite/g++.dg/ext/has_nothrow_copy.C)12
-rw-r--r--gcc/testsuite/g++.dg/ext/has_nothrow_copy-2.C12
-rw-r--r--gcc/testsuite/g++.dg/ext/has_nothrow_copy-3.C13
-rw-r--r--gcc/testsuite/g++.dg/ext/has_nothrow_copy-4.C13
-rw-r--r--gcc/testsuite/g++.dg/ext/has_nothrow_copy-5.C13
-rw-r--r--gcc/testsuite/g++.dg/ext/has_nothrow_copy-6.C12
-rw-r--r--gcc/testsuite/g++.dg/ext/has_nothrow_copy-7.C13
-rw-r--r--gcc/testsuite/g++.dg/ext/has_nothrow_copy_odr.C16
-rw-r--r--gcc/testsuite/g++.dg/ext/has_trivial_destructor-1.C (renamed from gcc/testsuite/g++.dg/ext/has_trivial_destructor.C)0
-rw-r--r--gcc/testsuite/g++.dg/ext/has_trivial_destructor-2.C3
-rw-r--r--gcc/testsuite/g++.dg/ext/no-asm-1.C10
-rw-r--r--gcc/testsuite/g++.dg/ext/no-asm-2.C10
-rw-r--r--gcc/testsuite/g++.dg/ext/no-gnu-keywords-1.C9
-rw-r--r--gcc/testsuite/g++.dg/ext/utf-array-short-wchar.C36
-rw-r--r--gcc/testsuite/g++.dg/ext/utf-array.C36
-rw-r--r--gcc/testsuite/g++.dg/ext/utf-rtti.C12
-rw-r--r--gcc/testsuite/g++.dg/ext/utf-type.C15
-rw-r--r--gcc/testsuite/g++.dg/ext/visibility/arm1.C1
-rw-r--r--gcc/testsuite/g++.dg/ext/visibility/arm3.C26
-rw-r--r--gcc/testsuite/g++.dg/gomp/pr36790.C23
-rw-r--r--gcc/testsuite/g++.dg/inherit/thunk8.C2
-rw-r--r--gcc/testsuite/g++.dg/ipa/iinline-1.C47
-rw-r--r--gcc/testsuite/g++.dg/lookup/extern-c-redecl.C11
-rw-r--r--gcc/testsuite/g++.dg/other/pr36944.C26
-rw-r--r--gcc/testsuite/g++.dg/other/semicolon.C7
-rw-r--r--gcc/testsuite/g++.dg/parse/constructor1.C5
-rw-r--r--gcc/testsuite/g++.dg/parse/crash27.C3
-rw-r--r--gcc/testsuite/g++.dg/parse/dtor13.C8
-rw-r--r--gcc/testsuite/g++.dg/parse/error-column.C9
-rw-r--r--gcc/testsuite/g++.dg/parse/error1.C3
-rw-r--r--gcc/testsuite/g++.dg/parse/error10.C8
-rw-r--r--gcc/testsuite/g++.dg/parse/error11.C27
-rw-r--r--gcc/testsuite/g++.dg/parse/error12.C5
-rw-r--r--gcc/testsuite/g++.dg/parse/error13.C7
-rw-r--r--gcc/testsuite/g++.dg/parse/error14.C3
-rw-r--r--gcc/testsuite/g++.dg/parse/error15.C33
-rw-r--r--gcc/testsuite/g++.dg/parse/error16.C5
-rw-r--r--gcc/testsuite/g++.dg/parse/error17.C5
-rw-r--r--gcc/testsuite/g++.dg/parse/error18.C3
-rw-r--r--gcc/testsuite/g++.dg/parse/error19.C5
-rw-r--r--gcc/testsuite/g++.dg/parse/error2.C7
-rw-r--r--gcc/testsuite/g++.dg/parse/error20.C3
-rw-r--r--gcc/testsuite/g++.dg/parse/error21.C4
-rw-r--r--gcc/testsuite/g++.dg/parse/error22.C3
-rw-r--r--gcc/testsuite/g++.dg/parse/error23.C4
-rw-r--r--gcc/testsuite/g++.dg/parse/error24.C3
-rw-r--r--gcc/testsuite/g++.dg/parse/error25.C13
-rw-r--r--gcc/testsuite/g++.dg/parse/error26.C6
-rw-r--r--gcc/testsuite/g++.dg/parse/error27.C9
-rw-r--r--gcc/testsuite/g++.dg/parse/error28.C7
-rw-r--r--gcc/testsuite/g++.dg/parse/error29.C7
-rw-r--r--gcc/testsuite/g++.dg/parse/error3.C17
-rw-r--r--gcc/testsuite/g++.dg/parse/error30.C5
-rw-r--r--gcc/testsuite/g++.dg/parse/error31.C4
-rw-r--r--gcc/testsuite/g++.dg/parse/error4.C11
-rw-r--r--gcc/testsuite/g++.dg/parse/error5.C17
-rw-r--r--gcc/testsuite/g++.dg/parse/error6.C9
-rw-r--r--gcc/testsuite/g++.dg/parse/error7.C5
-rw-r--r--gcc/testsuite/g++.dg/parse/error8.C10
-rw-r--r--gcc/testsuite/g++.dg/parse/error9.C8
-rw-r--r--gcc/testsuite/g++.dg/template/crash60.C2
-rw-r--r--gcc/testsuite/g++.dg/template/crash7.C6
-rw-r--r--gcc/testsuite/g++.dg/torture/pr36745.C121
-rw-r--r--gcc/testsuite/g++.dg/torture/pr36826.C166
-rw-r--r--gcc/testsuite/g++.dg/tree-ssa/pr19637.C3
-rw-r--r--gcc/testsuite/g++.dg/tree-ssa/ptrmemfield.C27
-rw-r--r--gcc/testsuite/g++.dg/warn/Wdisallowed-functions-1.C7
-rw-r--r--gcc/testsuite/g++.dg/warn/Wdisallowed-functions-2.C12
-rw-r--r--gcc/testsuite/g++.dg/warn/Wreturn-type-4.C2
-rw-r--r--gcc/testsuite/g++.dg/warn/pr23075.C2
-rw-r--r--gcc/testsuite/g++.dg/warn/pragma-system_header5.C10
-rw-r--r--gcc/testsuite/g++.dg/warn/pragma-system_header5.h3
-rw-r--r--gcc/testsuite/g++.old-deja/g++.brendan/crash16.C8
-rw-r--r--gcc/testsuite/g++.old-deja/g++.brendan/crash52.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/crash11.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/report.C4
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/ctors5.C9
-rw-r--r--gcc/testsuite/g++.old-deja/g++.other/crash25.C7
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/error2.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/niklas01a.C5
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/20080625-1.c1
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/20080704-1.c43
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/20080721-1.c15
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr11832.c4
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr33009.c4
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr35492.c26
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/20080719-1.c65
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/pr36765.c15
-rw-r--r--gcc/testsuite/gcc.dg/20080615-1.c25
-rw-r--r--gcc/testsuite/gcc.dg/Wcxx-compat-2.c35
-rw-r--r--gcc/testsuite/gcc.dg/Wdeclaration-after-statement-3.c24
-rw-r--r--gcc/testsuite/gcc.dg/Wpointer-arith.c10
-rw-r--r--gcc/testsuite/gcc.dg/Wstrict-aliasing-bogus-ref-all.c41
-rw-r--r--gcc/testsuite/gcc.dg/Wstrict-aliasing-float-ptr-int-obj.c4
-rw-r--r--gcc/testsuite/gcc.dg/callabi/callabi.h50
-rw-r--r--gcc/testsuite/gcc.dg/callabi/func-1.c40
-rw-r--r--gcc/testsuite/gcc.dg/callabi/vaarg-1.c47
-rw-r--r--gcc/testsuite/gcc.dg/callabi/vaarg-2.c47
-rw-r--r--gcc/testsuite/gcc.dg/callabi/vaarg-3.c47
-rw-r--r--gcc/testsuite/gcc.dg/compat/struct-layout-1_generate.c12
-rw-r--r--gcc/testsuite/gcc.dg/compat/union-m128-1_main.c21
-rw-r--r--gcc/testsuite/gcc.dg/compat/union-m128-1_x.c7
-rw-r--r--gcc/testsuite/gcc.dg/compat/union-m128-1_y.c7
-rw-r--r--gcc/testsuite/gcc.dg/compat/vector-1_x.c8
-rw-r--r--gcc/testsuite/gcc.dg/compat/vector-1_y.c4
-rw-r--r--gcc/testsuite/gcc.dg/compat/vector-1a_main.c26
-rw-r--r--gcc/testsuite/gcc.dg/compat/vector-1a_x.c3
-rw-r--r--gcc/testsuite/gcc.dg/compat/vector-1a_y.c3
-rw-r--r--gcc/testsuite/gcc.dg/compat/vector-2_x.c4
-rw-r--r--gcc/testsuite/gcc.dg/compat/vector-2_y.c2
-rw-r--r--gcc/testsuite/gcc.dg/compat/vector-2a_main.c26
-rw-r--r--gcc/testsuite/gcc.dg/compat/vector-2a_x.c3
-rw-r--r--gcc/testsuite/gcc.dg/compat/vector-2a_y.c3
-rw-r--r--gcc/testsuite/gcc.dg/compat/vector-defs.h14
-rw-r--r--gcc/testsuite/gcc.dg/cpp/line6.c7
-rw-r--r--gcc/testsuite/gcc.dg/fold-alloca-1.c6
-rw-r--r--gcc/testsuite/gcc.dg/fshort-wchar.c1
-rw-r--r--gcc/testsuite/gcc.dg/gomp/atomic-11.c17
-rw-r--r--gcc/testsuite/gcc.dg/gomp/block-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/gomp/block-2.c2
-rw-r--r--gcc/testsuite/gcc.dg/gomp/block-3.c6
-rw-r--r--gcc/testsuite/gcc.dg/gomp/block-4.c2
-rw-r--r--gcc/testsuite/gcc.dg/gomp/block-5.c4
-rw-r--r--gcc/testsuite/gcc.dg/gomp/block-6.c2
-rw-r--r--gcc/testsuite/gcc.dg/gomp/block-7.c12
-rw-r--r--gcc/testsuite/gcc.dg/gomp/block-8.c2
-rw-r--r--gcc/testsuite/gcc.dg/gomp/pr36790.c23
-rw-r--r--gcc/testsuite/gcc.dg/ipa/iinline-1.c26
-rw-r--r--gcc/testsuite/gcc.dg/ipa/modif-1.c44
-rw-r--r--gcc/testsuite/gcc.dg/mallign.c15
-rw-r--r--gcc/testsuite/gcc.dg/no-asm-1.c10
-rw-r--r--gcc/testsuite/gcc.dg/no-asm-2.c9
-rw-r--r--gcc/testsuite/gcc.dg/no-asm-3.c10
-rw-r--r--gcc/testsuite/gcc.dg/no-asm-4.c11
-rw-r--r--gcc/testsuite/gcc.dg/pch/valid-3.c6
-rw-r--r--gcc/testsuite/gcc.dg/pch/valid-3.hs3
-rw-r--r--gcc/testsuite/gcc.dg/pr28322-2.c2
-rw-r--r--gcc/testsuite/gcc.dg/pragma-message.c53
-rw-r--r--gcc/testsuite/gcc.dg/torture/20080716-1.c58
-rw-r--r--gcc/testsuite/gcc.dg/torture/ipa-pta-1.c40
-rw-r--r--[-rwxr-xr-x]gcc/testsuite/gcc.dg/torture/pr35842.c0
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr36373-10.c8
-rw-r--r--gcc/testsuite/gcc.dg/torture/pta-ptrarith-1.c33
-rw-r--r--gcc/testsuite/gcc.dg/torture/pta-ptrarith-2.c36
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20030728-1.c6
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20040204-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20080530.c22
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/data-dep-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/loadpre1.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/loadpre24.c4
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr21658.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr23455.c23
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr30375.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr35286.c23
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr35287.c15
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pta-callused.c27
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-13.c4
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-14.c4
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-17.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-7.c10
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-8.c4
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-9.c4
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-15.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/tailcall-3.c28
-rw-r--r--gcc/testsuite/gcc.dg/utf-array-short-wchar.c41
-rw-r--r--gcc/testsuite/gcc.dg/utf-array.c41
-rw-r--r--gcc/testsuite/gcc.dg/utf-inc-init.c45
-rw-r--r--gcc/testsuite/gcc.dg/utf-type.c18
-rw-r--r--gcc/testsuite/gcc.dg/vect/fast-math-vect-complex-3.c61
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-complex-1.c56
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-complex-2.c56
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-complex-4.c109
-rw-r--r--gcc/testsuite/gcc.dg/vmx/1b-06-ansi.c24
-rw-r--r--gcc/testsuite/gcc.dg/vmx/1b-06.c1
-rw-r--r--gcc/testsuite/gcc.dg/vmx/1b-07-ansi.c59
-rw-r--r--gcc/testsuite/gcc.dg/vmx/1b-07.c1
-rw-r--r--gcc/testsuite/gcc.dg/wdisallowed-functions-1.c7
-rw-r--r--gcc/testsuite/gcc.dg/wdisallowed-functions-2.c12
-rw-r--r--gcc/testsuite/gcc.dg/winline-4.c11
-rw-r--r--gcc/testsuite/gcc.target/i386/20080723-1.c49
-rw-r--r--gcc/testsuite/gcc.target/i386/cmov8.c13
-rw-r--r--gcc/testsuite/gcc.target/i386/cold-1.c13
-rw-r--r--gcc/testsuite/gcc.target/i386/funcspec-1.c34
-rw-r--r--gcc/testsuite/gcc.target/i386/funcspec-10.c15
-rw-r--r--gcc/testsuite/gcc.target/i386/funcspec-11.c15
-rw-r--r--gcc/testsuite/gcc.target/i386/funcspec-2.c99
-rw-r--r--gcc/testsuite/gcc.target/i386/funcspec-3.c66
-rw-r--r--gcc/testsuite/gcc.target/i386/funcspec-4.c14
-rw-r--r--gcc/testsuite/gcc.target/i386/funcspec-5.c125
-rw-r--r--gcc/testsuite/gcc.target/i386/funcspec-6.c71
-rw-r--r--gcc/testsuite/gcc.target/i386/funcspec-7.c13
-rw-r--r--gcc/testsuite/gcc.target/i386/funcspec-8.c161
-rw-r--r--gcc/testsuite/gcc.target/i386/funcspec-9.c36
-rw-r--r--gcc/testsuite/gcc.target/i386/hot-1.c33
-rw-r--r--gcc/testsuite/gcc.target/i386/opt-1.c35
-rw-r--r--gcc/testsuite/gcc.target/i386/opt-2.c38
-rw-r--r--gcc/testsuite/gcc.target/i386/pr36753.c31
-rw-r--r--gcc/testsuite/gcc.target/i386/pr36786.c13
-rw-r--r--gcc/testsuite/gcc.target/i386/sse-22.c171
-rw-r--r--gcc/testsuite/gcc.target/i386/sse-23.c108
-rw-r--r--gcc/testsuite/gcc.target/i386/vararg-1.c32
-rw-r--r--gcc/testsuite/gcc.target/i386/vararg-2.c40
-rw-r--r--gcc/testsuite/gcc.target/m68k/interrupt-2.c22
-rw-r--r--gcc/testsuite/gcc.target/mips/gcc-have-sync-compare-and-swap-1.c6
-rw-r--r--gcc/testsuite/gcc.target/mips/gcc-have-sync-compare-and-swap-2.c8
-rw-r--r--gcc/testsuite/gcc.target/mips/gcc-have-sync-compare-and-swap-3.c23
-rw-r--r--gcc/testsuite/gcc.target/mips/gcc-have-sync-compare-and-swap-4.c23
-rw-r--r--gcc/testsuite/gcc.target/mips/pr35802.c17
-rw-r--r--gcc/testsuite/gcc.target/powerpc/altivec-26.c11
-rw-r--r--gcc/testsuite/gcc.target/powerpc/altivec-macros.c63
-rw-r--r--gcc/testsuite/gcc.target/powerpc/asm-y.c11
-rw-r--r--gcc/testsuite/gcc.target/powerpc/ppc-negeq0-1.c10
-rw-r--r--gcc/testsuite/gcc.target/s390/pr36822.c16
-rw-r--r--gcc/testsuite/gcc.target/spu/vector-ansi.c35
-rw-r--r--gcc/testsuite/gcc.target/spu/vector.c32
-rw-r--r--gcc/testsuite/gfortran.dg/allocatable_module_1.f9018
-rw-r--r--gcc/testsuite/gfortran.dg/array_4.f9012
-rw-r--r--gcc/testsuite/gfortran.dg/array_temporaries_1.f9019
-rw-r--r--gcc/testsuite/gfortran.dg/array_temporaries_2.f9015
-rw-r--r--gcc/testsuite/gfortran.dg/c_sizeof_2.f905
-rw-r--r--gcc/testsuite/gfortran.dg/char_expr_1.f9020
-rw-r--r--gcc/testsuite/gfortran.dg/char_expr_2.f9015
-rw-r--r--gcc/testsuite/gfortran.dg/fmt_error_3.f9036
-rw-r--r--gcc/testsuite/gfortran.dg/fmt_error_4.f9022
-rw-r--r--gcc/testsuite/gfortran.dg/fmt_error_5.f9022
-rw-r--r--gcc/testsuite/gfortran.dg/fmt_g0_2.f082
-rw-r--r--gcc/testsuite/gfortran.dg/fmt_g0_3.f082
-rw-r--r--gcc/testsuite/gfortran.dg/fmt_g0_4.f085
-rw-r--r--gcc/testsuite/gfortran.dg/gamma_2.f9024
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/block-1.f902
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/pr36726.f9020
-rw-r--r--gcc/testsuite/gfortran.dg/internal_pack_4.f9031
-rw-r--r--gcc/testsuite/gfortran.dg/internal_pack_5.f9021
-rw-r--r--gcc/testsuite/gfortran.dg/intrinsic_argument_conformance_2.f9044
-rw-r--r--gcc/testsuite/gfortran.dg/intrinsic_shadow_1.f0357
-rw-r--r--gcc/testsuite/gfortran.dg/intrinsic_shadow_2.f0329
-rw-r--r--gcc/testsuite/gfortran.dg/intrinsic_shadow_3.f0327
-rw-r--r--gcc/testsuite/gfortran.dg/intrinsic_std_1.f9048
-rw-r--r--gcc/testsuite/gfortran.dg/intrinsic_std_2.f9015
-rw-r--r--gcc/testsuite/gfortran.dg/intrinsic_std_3.f9015
-rw-r--r--gcc/testsuite/gfortran.dg/intrinsic_std_4.f9046
-rw-r--r--gcc/testsuite/gfortran.dg/matmul_bounds_2.f9016
-rw-r--r--gcc/testsuite/gfortran.dg/matmul_bounds_3.f9016
-rw-r--r--gcc/testsuite/gfortran.dg/matmul_bounds_4.f9016
-rw-r--r--gcc/testsuite/gfortran.dg/matmul_bounds_5.f9016
-rw-r--r--gcc/testsuite/gfortran.dg/namelist_52.f9032
-rw-r--r--gcc/testsuite/gfortran.dg/parameter_array_init_4.f908
-rw-r--r--gcc/testsuite/gfortran.dg/pointer_to_substring.f9010
-rw-r--r--gcc/testsuite/gfortran.dg/product_sum_bounds_1.f908
-rw-r--r--gcc/testsuite/gfortran.dg/rank_2.f904
-rw-r--r--gcc/testsuite/gfortran.dg/selected_char_kind_3.f904
-rw-r--r--gcc/testsuite/gfortran.dg/used_types_21.f9011
-rw-r--r--gcc/testsuite/gfortran.dg/warn_std_1.f902
-rw-r--r--gcc/testsuite/gfortran.dg/warn_std_2.f908
-rw-r--r--gcc/testsuite/gfortran.dg/warn_std_3.f906
-rw-r--r--gcc/testsuite/gfortran.dg/zero_sized_1.f9010
-rw-r--r--gcc/testsuite/gfortran.dg/zero_sized_5.f9015
-rw-r--r--gcc/testsuite/gnat.dg/allocator_maxalign1.adb42
-rw-r--r--gcc/testsuite/gnat.dg/allocator_maxalign2.adb33
-rw-r--r--gcc/testsuite/gnat.dg/allocator_maxalign2.ads12
-rw-r--r--gcc/testsuite/gnat.dg/case_optimization1.adb21
-rw-r--r--gcc/testsuite/gnat.dg/case_optimization1.ads7
-rw-r--r--gcc/testsuite/gnat.dg/case_optimization_pkg1.ads432
-rw-r--r--gcc/testsuite/gnat.dg/decl_ctx_def.ads4
-rw-r--r--gcc/testsuite/gnat.dg/decl_ctx_use.adb14
-rw-r--r--gcc/testsuite/gnat.dg/decl_ctx_use.ads5
-rw-r--r--gcc/testsuite/gnat.dg/test_allocator_maxalign2.adb8
-rw-r--r--gcc/testsuite/gnat.dg/tree_static_def.adb11
-rw-r--r--gcc/testsuite/gnat.dg/tree_static_def.ads10
-rw-r--r--gcc/testsuite/gnat.dg/tree_static_use.adb12
-rw-r--r--gcc/testsuite/lib/compat.exp5
-rw-r--r--gcc/testsuite/lib/g++.exp1
-rw-r--r--gcc/testsuite/lib/gcc-dg.exp5
-rw-r--r--gcc/testsuite/lib/target-supports.exp24
-rw-r--r--gcc/testsuite/objc.dg/gnu-encoding/gnu-encoding.exp12
-rw-r--r--gcc/toplev.c12
-rw-r--r--gcc/toplev.h9
-rw-r--r--gcc/tracer.c8
-rw-r--r--gcc/tree-affine.c66
-rw-r--r--gcc/tree-call-cdce.c212
-rw-r--r--gcc/tree-cfg.c3510
-rw-r--r--gcc/tree-cfgcleanup.c179
-rw-r--r--gcc/tree-chrec.c20
-rw-r--r--gcc/tree-chrec.h4
-rw-r--r--gcc/tree-complex.c811
-rw-r--r--gcc/tree-data-ref.c264
-rw-r--r--gcc/tree-data-ref.h16
-rw-r--r--gcc/tree-dfa.c209
-rw-r--r--gcc/tree-dump.c9
-rw-r--r--gcc/tree-eh.c1797
-rw-r--r--gcc/tree-flow-inline.h444
-rw-r--r--gcc/tree-flow.h327
-rw-r--r--gcc/tree-gimple.c653
-rw-r--r--gcc/tree-gimple.h215
-rw-r--r--gcc/tree-if-conv.c284
-rw-r--r--gcc/tree-inline.c2161
-rw-r--r--gcc/tree-inline.h27
-rw-r--r--gcc/tree-into-ssa.c284
-rw-r--r--gcc/tree-iterator.c2
-rw-r--r--gcc/tree-loop-distribution.c134
-rw-r--r--gcc/tree-loop-linear.c24
-rw-r--r--gcc/tree-mudflap.c324
-rw-r--r--gcc/tree-nested.c1003
-rw-r--r--gcc/tree-nomudflap.c2
-rw-r--r--gcc/tree-nrv.c100
-rw-r--r--gcc/tree-object-size.c391
-rw-r--r--gcc/tree-optimize.c73
-rw-r--r--gcc/tree-outof-ssa.c274
-rw-r--r--gcc/tree-parloops.c516
-rw-r--r--gcc/tree-pass.h5
-rw-r--r--gcc/tree-phinodes.c216
-rw-r--r--gcc/tree-predcom.c431
-rw-r--r--gcc/tree-pretty-print.c527
-rw-r--r--gcc/tree-profile.c188
-rw-r--r--gcc/tree-scalar-evolution.c597
-rw-r--r--gcc/tree-scalar-evolution.h4
-rw-r--r--gcc/tree-sra.c790
-rw-r--r--gcc/tree-ssa-address.c32
-rw-r--r--gcc/tree-ssa-alias-warnings.c155
-rw-r--r--gcc/tree-ssa-alias.c227
-rw-r--r--gcc/tree-ssa-ccp.c1452
-rw-r--r--gcc/tree-ssa-coalesce.c152
-rw-r--r--gcc/tree-ssa-copy.c235
-rw-r--r--gcc/tree-ssa-copyrename.c35
-rw-r--r--gcc/tree-ssa-dce.c242
-rw-r--r--gcc/tree-ssa-dom.c1668
-rw-r--r--gcc/tree-ssa-dse.c185
-rw-r--r--gcc/tree-ssa-forwprop.c595
-rw-r--r--gcc/tree-ssa-ifcombine.c258
-rw-r--r--gcc/tree-ssa-live.c123
-rw-r--r--gcc/tree-ssa-live.h4
-rw-r--r--gcc/tree-ssa-loop-ch.c46
-rw-r--r--gcc/tree-ssa-loop-im.c573
-rw-r--r--gcc/tree-ssa-loop-ivcanon.c81
-rw-r--r--gcc/tree-ssa-loop-ivopts.c377
-rw-r--r--gcc/tree-ssa-loop-manip.c153
-rw-r--r--gcc/tree-ssa-loop-niter.c382
-rw-r--r--gcc/tree-ssa-loop-prefetch.c65
-rw-r--r--gcc/tree-ssa-loop-unswitch.c28
-rw-r--r--gcc/tree-ssa-loop.c15
-rw-r--r--gcc/tree-ssa-math-opts.c217
-rw-r--r--gcc/tree-ssa-operands.c723
-rw-r--r--gcc/tree-ssa-operands.h37
-rw-r--r--gcc/tree-ssa-phiopt.c396
-rw-r--r--gcc/tree-ssa-phiprop.c88
-rw-r--r--gcc/tree-ssa-pre.c3418
-rw-r--r--gcc/tree-ssa-propagate.c684
-rw-r--r--gcc/tree-ssa-propagate.h38
-rw-r--r--gcc/tree-ssa-reassoc.c409
-rw-r--r--gcc/tree-ssa-sccvn.c1299
-rw-r--r--gcc/tree-ssa-sccvn.h146
-rw-r--r--gcc/tree-ssa-sink.c112
-rw-r--r--gcc/tree-ssa-structalias.c1120
-rw-r--r--gcc/tree-ssa-structalias.h8
-rw-r--r--gcc/tree-ssa-ter.c101
-rw-r--r--gcc/tree-ssa-threadedge.c264
-rw-r--r--gcc/tree-ssa-threadupdate.c48
-rw-r--r--gcc/tree-ssa-uncprop.c58
-rw-r--r--gcc/tree-ssa.c250
-rw-r--r--gcc/tree-ssanames.c18
-rw-r--r--gcc/tree-stdarg.c239
-rw-r--r--gcc/tree-switch-conversion.c281
-rw-r--r--gcc/tree-tailcall.c481
-rw-r--r--gcc/tree-vect-analyze.c411
-rw-r--r--gcc/tree-vect-generic.c191
-rw-r--r--gcc/tree-vect-patterns.c288
-rw-r--r--gcc/tree-vect-transform.c1397
-rw-r--r--gcc/tree-vectorizer.c486
-rw-r--r--gcc/tree-vectorizer.h112
-rw-r--r--gcc/tree-vn.c406
-rw-r--r--gcc/tree-vrp.c983
-rw-r--r--gcc/tree.c509
-rw-r--r--gcc/tree.def85
-rw-r--r--gcc/tree.h363
-rw-r--r--gcc/treestruct.def4
-rw-r--r--gcc/unwind-pe.h3
-rw-r--r--gcc/value-prof.c739
-rw-r--r--gcc/value-prof.h24
-rw-r--r--gcc/varasm.c15
-rw-r--r--gcc/varpool.c51
-rw-r--r--include/ChangeLog11
-rw-r--r--include/safe-ctype.h39
-rw-r--r--libcpp/ChangeLog45
-rw-r--r--libcpp/directives-only.c3
-rw-r--r--libcpp/directives.c47
-rw-r--r--libcpp/errors.c2
-rw-r--r--libcpp/include/cpplib.h10
-rw-r--r--libcpp/include/line-map.h17
-rw-r--r--libcpp/internal.h5
-rw-r--r--libcpp/lex.c68
-rw-r--r--libcpp/line-map.c6
-rw-r--r--libcpp/macro.c66
-rw-r--r--libcpp/traditional.c2
-rw-r--r--libffi/ChangeLog5
-rw-r--r--libffi/src/sh/ffi.c5
-rw-r--r--libgcc/ChangeLog25
-rw-r--r--libgcc/config/i386/32/sfp-machine.h128
-rw-r--r--libgcc/config/i386/64/_divtc3.c (renamed from libgcc/config/i386/64/_divtc3-compat.c)0
-rw-r--r--libgcc/config/i386/64/_multc3.c (renamed from libgcc/config/i386/64/_multc3-compat.c)0
-rw-r--r--libgcc/config/i386/64/_powitf2.c (renamed from libgcc/config/i386/64/_powitf2-compat.c)0
-rw-r--r--libgcc/config/i386/64/t-softfp-compat9
-rw-r--r--libgfortran/ChangeLog90
-rw-r--r--libgfortran/acinclude.m46
-rwxr-xr-xlibgfortran/configure10
-rw-r--r--libgfortran/generated/cshift1_16.c8
-rw-r--r--libgfortran/generated/cshift1_4.c8
-rw-r--r--libgfortran/generated/cshift1_8.c8
-rw-r--r--libgfortran/generated/eoshift1_16.c5
-rw-r--r--libgfortran/generated/eoshift1_4.c5
-rw-r--r--libgfortran/generated/eoshift1_8.c5
-rw-r--r--libgfortran/generated/eoshift3_16.c5
-rw-r--r--libgfortran/generated/eoshift3_4.c5
-rw-r--r--libgfortran/generated/eoshift3_8.c5
-rw-r--r--libgfortran/generated/matmul_c10.c41
-rw-r--r--libgfortran/generated/matmul_c16.c41
-rw-r--r--libgfortran/generated/matmul_c4.c41
-rw-r--r--libgfortran/generated/matmul_c8.c41
-rw-r--r--libgfortran/generated/matmul_i1.c41
-rw-r--r--libgfortran/generated/matmul_i16.c41
-rw-r--r--libgfortran/generated/matmul_i2.c41
-rw-r--r--libgfortran/generated/matmul_i4.c41
-rw-r--r--libgfortran/generated/matmul_i8.c41
-rw-r--r--libgfortran/generated/matmul_l16.c41
-rw-r--r--libgfortran/generated/matmul_l4.c41
-rw-r--r--libgfortran/generated/matmul_l8.c41
-rw-r--r--libgfortran/generated/matmul_r10.c41
-rw-r--r--libgfortran/generated/matmul_r16.c41
-rw-r--r--libgfortran/generated/matmul_r4.c41
-rw-r--r--libgfortran/generated/matmul_r8.c41
-rw-r--r--libgfortran/gfortran.map1
-rw-r--r--libgfortran/intrinsics/cshift0.c61
-rw-r--r--libgfortran/intrinsics/eoshift0.c5
-rw-r--r--libgfortran/intrinsics/eoshift2.c13
-rw-r--r--libgfortran/io/file_pos.c2
-rw-r--r--libgfortran/io/format.c10
-rw-r--r--libgfortran/io/list_read.c2
-rw-r--r--libgfortran/io/write_float.def53
-rw-r--r--libgfortran/libgfortran.h3
-rw-r--r--libgfortran/m4/cshift1.m48
-rw-r--r--libgfortran/m4/eoshift1.m45
-rw-r--r--libgfortran/m4/eoshift3.m45
-rw-r--r--libgfortran/m4/matmul.m441
-rw-r--r--libgfortran/m4/matmull.m441
-rw-r--r--libgfortran/runtime/error.c15
-rw-r--r--libgomp/ChangeLog13
-rw-r--r--libgomp/team.c3
-rw-r--r--libgomp/testsuite/lib/libgomp.exp4
-rw-r--r--libgomp/testsuite/libgomp.c++/c++.exp1
-rw-r--r--libgomp/testsuite/libgomp.c/c.exp1
-rw-r--r--libgomp/testsuite/libgomp.fortran/fortran.exp1
-rw-r--r--libiberty/ChangeLog7
-rw-r--r--libiberty/Makefile.in150
-rw-r--r--libiberty/maint-tool4
-rw-r--r--libjava/ChangeLog18
-rw-r--r--libjava/Makefile.am3
-rw-r--r--libjava/Makefile.in5
-rw-r--r--libjava/classpath/ChangeLog7
-rwxr-xr-xlibjava/classpath/configure12
-rw-r--r--libjava/classpath/configure.ac8
-rw-r--r--libjava/classpath/m4/acinclude.m416
-rwxr-xr-xlibjava/classpath/tools/Makefile.am3
-rw-r--r--libjava/gnu/gcj/convert/gen-from-JIS.c16
-rw-r--r--libjava/gnu/gcj/convert/make-trie.c1
-rw-r--r--libjava/gnu/gcj/convert/make-trie.h13
-rw-r--r--libjava/libtool-version2
-rw-r--r--libjava/scripts/jar.in7
-rw-r--r--libobjc/ChangeLog13
-rw-r--r--libobjc/Makefile.in10
-rw-r--r--libstdc++-v3/ChangeLog369
-rw-r--r--libstdc++-v3/acinclude.m488
-rw-r--r--libstdc++-v3/config.h.in9
-rw-r--r--libstdc++-v3/config/abi/pre/gnu.ver67
-rw-r--r--libstdc++-v3/config/os/gnu-linux/arm-eabi-extra.ver18
-rwxr-xr-xlibstdc++-v3/configure565
-rw-r--r--libstdc++-v3/configure.ac6
-rw-r--r--libstdc++-v3/configure.host5
-rw-r--r--libstdc++-v3/doc/doxygen/doxygroups.cc7
-rw-r--r--libstdc++-v3/doc/doxygen/user.cfg.in16
-rw-r--r--libstdc++-v3/doc/html/api.html2
-rw-r--r--libstdc++-v3/doc/html/manual/abi.html20
-rw-r--r--libstdc++-v3/doc/html/manual/api.html4
-rw-r--r--libstdc++-v3/doc/html/manual/backwards.html48
-rw-r--r--libstdc++-v3/doc/html/manual/bitmap_allocator.html2
-rw-r--r--libstdc++-v3/doc/html/manual/bk01pt01ch01.html4
-rw-r--r--libstdc++-v3/doc/html/manual/bk01pt01ch03s02.html10
-rw-r--r--libstdc++-v3/doc/html/manual/bk01pt02pr01.html2
-rw-r--r--libstdc++-v3/doc/html/manual/bk01pt04ch11.html24
-rw-r--r--libstdc++-v3/doc/html/manual/bk01pt06ch14.html14
-rw-r--r--libstdc++-v3/doc/html/manual/bk01pt06ch15.html16
-rw-r--r--libstdc++-v3/doc/html/manual/bk01pt09pr02.html2
-rw-r--r--libstdc++-v3/doc/html/manual/bk01pt12ch30s03.html4
-rw-r--r--libstdc++-v3/doc/html/manual/bk01pt12ch31s03.html2
-rw-r--r--libstdc++-v3/doc/html/manual/bk01pt12pr03.html2
-rw-r--r--libstdc++-v3/doc/html/manual/codecvt.html20
-rw-r--r--libstdc++-v3/doc/html/manual/messages.html18
-rw-r--r--libstdc++-v3/doc/html/manual/parallel_mode.html4
-rw-r--r--libstdc++-v3/doc/html/manual/shared_ptr.html22
-rw-r--r--libstdc++-v3/doc/html/manual/spine.html4
-rw-r--r--libstdc++-v3/doc/xml/manual/allocator.xml8
-rw-r--r--libstdc++-v3/include/Makefile.am3
-rw-r--r--libstdc++-v3/include/Makefile.in3
-rw-r--r--libstdc++-v3/include/bits/basic_string.h87
-rw-r--r--libstdc++-v3/include/bits/basic_string.tcc10
-rw-r--r--libstdc++-v3/include/bits/c++config6
-rw-r--r--libstdc++-v3/include/bits/postypes.h10
-rw-r--r--libstdc++-v3/include/bits/stl_bvector.h28
-rw-r--r--libstdc++-v3/include/bits/stl_deque.h68
-rw-r--r--libstdc++-v3/include/bits/stl_list.h58
-rw-r--r--libstdc++-v3/include/bits/stl_map.h37
-rw-r--r--libstdc++-v3/include/bits/stl_multimap.h49
-rw-r--r--libstdc++-v3/include/bits/stl_multiset.h49
-rw-r--r--libstdc++-v3/include/bits/stl_set.h49
-rw-r--r--libstdc++-v3/include/bits/stl_vector.h72
-rw-r--r--libstdc++-v3/include/bits/unique_ptr.h5
-rw-r--r--libstdc++-v3/include/debug/deque28
-rw-r--r--libstdc++-v3/include/debug/list26
-rw-r--r--libstdc++-v3/include/debug/map.h19
-rw-r--r--libstdc++-v3/include/debug/multimap.h19
-rw-r--r--libstdc++-v3/include/debug/multiset.h19
-rw-r--r--libstdc++-v3/include/debug/safe_association.h12
-rw-r--r--libstdc++-v3/include/debug/set.h19
-rw-r--r--libstdc++-v3/include/debug/string56
-rw-r--r--libstdc++-v3/include/debug/unordered_map33
-rw-r--r--libstdc++-v3/include/debug/unordered_set33
-rw-r--r--libstdc++-v3/include/debug/vector44
-rw-r--r--libstdc++-v3/include/ext/pb_ds/detail/binomial_heap_base_/debug_fn_imps.hpp33
-rw-r--r--libstdc++-v3/include/ext/pb_ds/detail/debug_map_base.hpp3
-rw-r--r--libstdc++-v3/include/ext/pb_ds/detail/left_child_next_sibling_heap_/null_metadata.hpp4
-rw-r--r--libstdc++-v3/include/ext/rc_string_base.h2
-rw-r--r--libstdc++-v3/include/ext/rope26
-rw-r--r--libstdc++-v3/include/ext/sso_string_base.h2
-rw-r--r--libstdc++-v3/include/ext/vstring.h85
-rw-r--r--libstdc++-v3/include/parallel/algo.h2
-rw-r--r--libstdc++-v3/include/parallel/algobase.h2
-rw-r--r--libstdc++-v3/include/parallel/algorithmfwd.h2
-rw-r--r--libstdc++-v3/include/parallel/balanced_quicksort.h14
-rw-r--r--libstdc++-v3/include/parallel/base.h2
-rw-r--r--libstdc++-v3/include/parallel/basic_iterator.h2
-rw-r--r--libstdc++-v3/include/parallel/checkers.h6
-rw-r--r--libstdc++-v3/include/parallel/compatibility.h2
-rw-r--r--libstdc++-v3/include/parallel/equally_split.h2
-rw-r--r--libstdc++-v3/include/parallel/features.h2
-rw-r--r--libstdc++-v3/include/parallel/find.h2
-rw-r--r--libstdc++-v3/include/parallel/find_selectors.h6
-rw-r--r--libstdc++-v3/include/parallel/for_each.h2
-rw-r--r--libstdc++-v3/include/parallel/for_each_selectors.h2
-rw-r--r--libstdc++-v3/include/parallel/iterator.h2
-rw-r--r--libstdc++-v3/include/parallel/list_partition.h2
-rw-r--r--libstdc++-v3/include/parallel/losertree.h2
-rw-r--r--libstdc++-v3/include/parallel/merge.h2
-rw-r--r--libstdc++-v3/include/parallel/multiseq_selection.h3
-rw-r--r--libstdc++-v3/include/parallel/multiway_merge.h2
-rw-r--r--libstdc++-v3/include/parallel/multiway_mergesort.h6
-rw-r--r--libstdc++-v3/include/parallel/numericfwd.h2
-rw-r--r--libstdc++-v3/include/parallel/omp_loop.h2
-rw-r--r--libstdc++-v3/include/parallel/omp_loop_static.h2
-rw-r--r--libstdc++-v3/include/parallel/par_loop.h2
-rw-r--r--libstdc++-v3/include/parallel/parallel.h2
-rw-r--r--libstdc++-v3/include/parallel/partial_sum.h2
-rw-r--r--libstdc++-v3/include/parallel/partition.h2
-rw-r--r--libstdc++-v3/include/parallel/queue.h2
-rw-r--r--libstdc++-v3/include/parallel/quicksort.h2
-rw-r--r--libstdc++-v3/include/parallel/random_number.h2
-rw-r--r--libstdc++-v3/include/parallel/random_shuffle.h5
-rw-r--r--libstdc++-v3/include/parallel/search.h2
-rw-r--r--libstdc++-v3/include/parallel/set_operations.h2
-rw-r--r--libstdc++-v3/include/parallel/settings.h2
-rw-r--r--libstdc++-v3/include/parallel/sort.h2
-rw-r--r--libstdc++-v3/include/parallel/types.h2
-rw-r--r--libstdc++-v3/include/parallel/unique_copy.h6
-rw-r--r--libstdc++-v3/include/parallel/workstealing.h2
-rw-r--r--libstdc++-v3/include/precompiled/stdc++.h3
-rw-r--r--libstdc++-v3/include/std/chrono628
-rw-r--r--libstdc++-v3/include/std/complex2
-rw-r--r--libstdc++-v3/include/std/condition_variable75
-rw-r--r--libstdc++-v3/include/std/date_time245
-rw-r--r--libstdc++-v3/include/std/mutex129
-rw-r--r--libstdc++-v3/include/std/ratio298
-rw-r--r--libstdc++-v3/include/std/system_error4
-rw-r--r--libstdc++-v3/include/std/type_traits39
-rw-r--r--libstdc++-v3/include/std/unordered_map1
-rw-r--r--libstdc++-v3/include/std/unordered_set1
-rw-r--r--libstdc++-v3/include/std/valarray36
-rw-r--r--libstdc++-v3/include/tr1_impl/hashtable6
-rw-r--r--libstdc++-v3/include/tr1_impl/regex14
-rw-r--r--libstdc++-v3/include/tr1_impl/type_traits2
-rw-r--r--libstdc++-v3/include/tr1_impl/unordered_map34
-rw-r--r--libstdc++-v3/include/tr1_impl/unordered_set34
-rw-r--r--libstdc++-v3/libsupc++/eh_arm.cc8
-rw-r--r--libstdc++-v3/libsupc++/eh_personality.cc8
-rw-r--r--libstdc++-v3/libsupc++/initializer_list5
-rw-r--r--libstdc++-v3/libsupc++/unwind-cxx.h26
-rw-r--r--libstdc++-v3/src/Makefile.am22
-rw-r--r--libstdc++-v3/src/Makefile.in52
-rw-r--r--libstdc++-v3/src/chrono.cc76
-rw-r--r--libstdc++-v3/testsuite/17_intro/headers/c++200x/all.cc3
-rw-r--r--libstdc++-v3/testsuite/17_intro/headers/c++200x/all_multiple_inclusion.cc7
-rw-r--r--libstdc++-v3/testsuite/20_util/clocks/1.cc (renamed from libstdc++-v3/testsuite/31_date_time/nanoseconds/requirements/traits.cc)28
-rw-r--r--libstdc++-v3/testsuite/20_util/common_type/requirements/explicit_instantiation.cc46
-rw-r--r--libstdc++-v3/testsuite/20_util/common_type/requirements/typedefs-1.cc118
-rw-r--r--libstdc++-v3/testsuite/20_util/duration/arithmetic/1.cc94
-rw-r--r--libstdc++-v3/testsuite/20_util/duration/arithmetic/2.cc62
-rw-r--r--libstdc++-v3/testsuite/20_util/duration/comparisons/1.cc (renamed from libstdc++-v3/testsuite/31_date_time/nanoseconds/requirements/duration.cc)60
-rw-r--r--libstdc++-v3/testsuite/20_util/duration/cons/1.cc138
-rw-r--r--libstdc++-v3/testsuite/20_util/duration/cons/1_neg.cc46
-rw-r--r--libstdc++-v3/testsuite/20_util/duration/cons/2.cc120
-rw-r--r--libstdc++-v3/testsuite/20_util/duration/requirements/explicit_instantiation/explicit_instantiation.cc (renamed from libstdc++-v3/testsuite/31_date_time/headers/date_time/types_std.cc)26
-rw-r--r--libstdc++-v3/testsuite/20_util/make_signed/requirements/typedefs-2.cc1
-rw-r--r--libstdc++-v3/testsuite/20_util/make_unsigned/requirements/typedefs-2.cc1
-rw-r--r--libstdc++-v3/testsuite/20_util/ratio/comparisons/comp1.cc82
-rw-r--r--libstdc++-v3/testsuite/20_util/ratio/comparisons/comp2.cc51
-rw-r--r--libstdc++-v3/testsuite/20_util/ratio/cons/cons1.cc52
-rw-r--r--libstdc++-v3/testsuite/20_util/ratio/cons/cons_overflow.cc55
-rw-r--r--libstdc++-v3/testsuite/20_util/ratio/operations/ops1.cc75
-rw-r--r--libstdc++-v3/testsuite/20_util/ratio/operations/ops2.cc73
-rw-r--r--libstdc++-v3/testsuite/20_util/ratio/operations/ops3.cc72
-rw-r--r--libstdc++-v3/testsuite/20_util/ratio/operations/ops_overflow.cc48
-rw-r--r--libstdc++-v3/testsuite/20_util/time_point/1.cc49
-rw-r--r--libstdc++-v3/testsuite/20_util/time_point/2.cc72
-rw-r--r--libstdc++-v3/testsuite/20_util/time_point/3.cc53
-rw-r--r--libstdc++-v3/testsuite/20_util/time_point/requirements/explicit_instantiation/explicit_instantiation.cc (renamed from libstdc++-v3/testsuite/31_date_time/headers/date_time/std_c++0x_neg.cc)17
-rw-r--r--libstdc++-v3/testsuite/21_strings/basic_string/init-list.cc81
-rw-r--r--libstdc++-v3/testsuite/22_locale/time_put/put/char/4.cc30
-rw-r--r--libstdc++-v3/testsuite/22_locale/time_put/put/wchar_t/4.cc30
-rw-r--r--libstdc++-v3/testsuite/23_containers/deque/init-list.cc69
-rw-r--r--libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/assign_neg.cc2
-rw-r--r--libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_1_neg.cc2
-rw-r--r--libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_2_neg.cc2
-rw-r--r--libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/insert_neg.cc2
-rw-r--r--libstdc++-v3/testsuite/23_containers/list/init-list.cc74
-rw-r--r--libstdc++-v3/testsuite/23_containers/list/requirements/dr438/assign_neg.cc2
-rw-r--r--libstdc++-v3/testsuite/23_containers/list/requirements/dr438/constructor_1_neg.cc2
-rw-r--r--libstdc++-v3/testsuite/23_containers/list/requirements/dr438/constructor_2_neg.cc2
-rw-r--r--libstdc++-v3/testsuite/23_containers/list/requirements/dr438/insert_neg.cc2
-rw-r--r--libstdc++-v3/testsuite/23_containers/map/init-list.cc63
-rw-r--r--libstdc++-v3/testsuite/23_containers/multimap/init-list.cc72
-rw-r--r--libstdc++-v3/testsuite/23_containers/multiset/init-list.cc68
-rw-r--r--libstdc++-v3/testsuite/23_containers/set/init-list.cc68
-rw-r--r--libstdc++-v3/testsuite/23_containers/unordered_map/init-list.cc63
-rw-r--r--libstdc++-v3/testsuite/23_containers/unordered_multimap/init-list.cc77
-rw-r--r--libstdc++-v3/testsuite/23_containers/unordered_multiset/init-list.cc68
-rw-r--r--libstdc++-v3/testsuite/23_containers/unordered_set/init-list.cc68
-rw-r--r--libstdc++-v3/testsuite/23_containers/vector/init-list.cc69
-rw-r--r--libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/assign_neg.cc2
-rw-r--r--libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_1_neg.cc2
-rw-r--r--libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_2_neg.cc2
-rw-r--r--libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/insert_neg.cc2
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/heap/1.cc2
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/random_shuffle/1.cc75
-rw-r--r--libstdc++-v3/testsuite/26_numerics/valarray/init-list.cc (renamed from libstdc++-v3/src/date_time.cc)50
-rw-r--r--libstdc++-v3/testsuite/28_regex/init-list.cc58
-rw-r--r--libstdc++-v3/testsuite/30_threads/mutex/cons/assign_neg.cc2
-rw-r--r--libstdc++-v3/testsuite/30_threads/mutex/cons/copy_neg.cc2
-rw-r--r--libstdc++-v3/testsuite/30_threads/recursive_mutex/cons/assign_neg.cc2
-rw-r--r--libstdc++-v3/testsuite/30_threads/recursive_mutex/cons/copy_neg.cc2
-rw-r--r--libstdc++-v3/testsuite/31_date_time/headers/date_time/synopsis.cc70
-rw-r--r--libstdc++-v3/testsuite/31_date_time/system_time/requirements/traits.cc33
-rw-r--r--libstdc++-v3/testsuite/ext/rope/36832.cc (renamed from libstdc++-v3/testsuite/31_date_time/headers/date_time/functions_std.cc)21
-rw-r--r--libstdc++-v3/testsuite/ext/vstring/init-list.cc79
-rw-r--r--libstdc++-v3/testsuite/lib/dg-options.exp9
-rw-r--r--libstdc++-v3/testsuite/lib/libstdc++.exp66
-rw-r--r--libstdc++-v3/testsuite/util/testsuite_abi.cc1
-rw-r--r--maintainer-scripts/ChangeLog10
-rw-r--r--maintainer-scripts/crontab1
-rwxr-xr-xmaintainer-scripts/gcc_release35
-rwxr-xr-xmaintainer-scripts/update_version113
-rwxr-xr-xmaintainer-scripts/update_version_svn45
-rwxr-xr-xmaintainer-scripts/update_web_docs_svn1
1009 files changed, 77636 insertions, 32493 deletions
diff --git a/ChangeLog b/ChangeLog
index 67913947421..69d15720422 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2008-07-11 Dodji Seketeli <dseketel@redhat.com>
+
+ * MAINTAINERS (Write after Approval): Add myself.
+
2008-07-02 Xuepeng Guo <xuepeng.guo@intel.com>
* MAINTAINERS (Write After Approval): Add myself.
diff --git a/MAINTAINERS b/MAINTAINERS
index b578e25accc..ba77126fee1 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -418,6 +418,7 @@ Maciej W. Rozycki macro@linux-mips.org
Douglas Rupp rupp@gnat.com
Silvius Rus rus@google.com
Matthew Sachs msachs@apple.com
+Dodji Seketeli dseketel@redhat.com
Svein Seldal svein@dev.seldal.com
Thiemo Seufer ths@networkno.de
Mark Shinwell shinwell@codesourcery.com
diff --git a/boehm-gc/ChangeLog b/boehm-gc/ChangeLog
index d6d37671c3c..a7eeec051c2 100644
--- a/boehm-gc/ChangeLog
+++ b/boehm-gc/ChangeLog
@@ -1,3 +1,9 @@
+2008-07-18 Matthias Klose <doko@ubuntu.com>
+
+ * configure.ac (AC_CONFIG_FILES): Add threads.mk.
+ * threads.mk.in: New.
+ * Makefile.in, configure: Regenerate.
+
2008-06-17 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
* Makefile.in: Regenerate.
diff --git a/boehm-gc/Makefile.in b/boehm-gc/Makefile.in
index 91918f2075a..e3a2e30160b 100644
--- a/boehm-gc/Makefile.in
+++ b/boehm-gc/Makefile.in
@@ -41,7 +41,7 @@ check_PROGRAMS = gctest$(EXEEXT)
DIST_COMMON = $(srcdir)/../config.guess $(srcdir)/../config.sub \
ChangeLog $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
$(top_srcdir)/configure $(am__configure_deps) \
- $(srcdir)/../mkinstalldirs $(srcdir)/../compile \
+ $(srcdir)/../mkinstalldirs $(srcdir)/threads.mk.in \
$(srcdir)/../compile $(srcdir)/../compile $(srcdir)/../compile \
$(srcdir)/../compile $(srcdir)/../compile $(srcdir)/../compile \
$(srcdir)/../compile $(srcdir)/../compile $(srcdir)/../compile \
@@ -62,8 +62,8 @@ DIST_COMMON = $(srcdir)/../config.guess $(srcdir)/../config.sub \
$(srcdir)/../compile $(srcdir)/../compile $(srcdir)/../compile \
$(srcdir)/../compile $(srcdir)/../compile $(srcdir)/../compile \
$(srcdir)/../compile $(srcdir)/../compile $(srcdir)/../compile \
- $(srcdir)/../ltmain.sh $(srcdir)/../config.guess \
- $(srcdir)/../config.sub
+ $(srcdir)/../compile $(srcdir)/../ltmain.sh \
+ $(srcdir)/../config.guess $(srcdir)/../config.sub
subdir = .
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/../config/acx.m4 \
@@ -82,7 +82,7 @@ am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
configure.lineno configure.status.lineno
CONFIG_HEADER = $(top_builddir)/include/gc_config.h \
$(top_builddir)/include/gc_ext_config.h
-CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_FILES = threads.mk
LTLIBRARIES = $(noinst_LTLIBRARIES)
am__DEPENDENCIES_1 =
@POWERPC_DARWIN_TRUE@am__objects_1 = powerpc_darwin_mach_dep.lo
@@ -387,6 +387,8 @@ $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
cd $(srcdir) && $(AUTOCONF)
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
+threads.mk: $(top_builddir)/config.status $(srcdir)/threads.mk.in
+ cd $(top_builddir) && $(SHELL) ./config.status $@
clean-noinstLTLIBRARIES:
-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
diff --git a/boehm-gc/configure b/boehm-gc/configure
index 97cb19130ad..5308c77043c 100755
--- a/boehm-gc/configure
+++ b/boehm-gc/configure
@@ -16103,7 +16103,7 @@ fi
ac_config_headers="$ac_config_headers include/gc_config.h include/gc_ext_config.h"
- ac_config_files="$ac_config_files Makefile include/Makefile"
+ ac_config_files="$ac_config_files Makefile include/Makefile threads.mk"
cat >confcache <<\_ACEOF
# This file is a shell script that caches the results of configure
@@ -17035,6 +17035,7 @@ do
# Handling of arguments.
"Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;;
"include/Makefile" ) CONFIG_FILES="$CONFIG_FILES include/Makefile" ;;
+ "threads.mk" ) CONFIG_FILES="$CONFIG_FILES threads.mk" ;;
"default-1" ) CONFIG_COMMANDS="$CONFIG_COMMANDS default-1" ;;
"depfiles" ) CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;;
"libtool" ) CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;;
diff --git a/boehm-gc/configure.ac b/boehm-gc/configure.ac
index 29331e607d6..326a051f767 100644
--- a/boehm-gc/configure.ac
+++ b/boehm-gc/configure.ac
@@ -547,5 +547,5 @@ fi
AC_CONFIG_HEADERS([include/gc_config.h include/gc_ext_config.h])
-AC_CONFIG_FILES(Makefile include/Makefile)
+AC_CONFIG_FILES(Makefile include/Makefile threads.mk)
AC_OUTPUT
diff --git a/boehm-gc/threads.mk.in b/boehm-gc/threads.mk.in
new file mode 100644
index 00000000000..31119df2018
--- /dev/null
+++ b/boehm-gc/threads.mk.in
@@ -0,0 +1,3 @@
+# to be used in libobjc for libobjc_gc
+
+thread_libs_and_flags = @THREADLIBS@ @extra_ldflags_libgc@
diff --git a/config/ChangeLog b/config/ChangeLog
index ff2d7b0c39c..e64c1cab72e 100644
--- a/config/ChangeLog
+++ b/config/ChangeLog
@@ -1,3 +1,8 @@
+2008-07-11 Joseph Myers <joseph@codesourcery.com>
+
+ * mh-mingw (LDFLAGS): Append to rather than replacing previous
+ value.
+
2008-06-17 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
* override.m4: Use m4_version_prereq throughout.
diff --git a/config/mh-mingw b/config/mh-mingw
index e31bfd323b4..4c49d5d5917 100644
--- a/config/mh-mingw
+++ b/config/mh-mingw
@@ -3,4 +3,4 @@
BOOT_CFLAGS += -D__USE_MINGW_ACCESS
CFLAGS += -D__USE_MINGW_ACCESS
# Increase stack limit to same as Linux default.
-LDFLAGS = -Wl,--stack,8388608
+LDFLAGS += -Wl,--stack,8388608
diff --git a/contrib/ChangeLog b/contrib/ChangeLog
index 5669ce28801..119e0779db9 100644
--- a/contrib/ChangeLog
+++ b/contrib/ChangeLog
@@ -1,3 +1,7 @@
+2008-07-14 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
+
+ * check_makefile_deps.sh: New file.
+
2008-05-08 Sebastian Pop <sebastian.pop@amd.com>
* patch_tester.sh (report): Do not print "Checker: ".
diff --git a/contrib/check_makefile_deps.sh b/contrib/check_makefile_deps.sh
new file mode 100644
index 00000000000..60b9c1757fd
--- /dev/null
+++ b/contrib/check_makefile_deps.sh
@@ -0,0 +1,94 @@
+#! /bin/sh
+#
+# Check for accurate dependencies in gcc/Makefile.in.
+#
+# Copyright (C) 2008 Free Software Foundation, Inc.
+# Written by Ralf Wildenhues <Ralf.Wildenhues@gmx.de>.
+#
+# This script is Free Software, and it can be copied, distributed and
+# modified as defined in the GNU General Public License. A copy of
+# its license can be downloaded from http://www.gnu.org/copyleft/gpl.html
+#
+# Start this script in an up to date build-tree/gcc directory.
+# Using it in stage1 only works if the host compiler is GCC.
+
+# To continue an interrupted check, make sure there are no *.o.backup
+# files lying around (i.e., move them back to their original name),
+# and set $start_after to the name of the last object that should be skipped.
+start_after=
+
+# Skip some objects unconditionally; make sure each name in this list is
+# surrounded by spaces.
+skip=" crtbegin.o crtbeginS.o crtbeginT.o crtend.o crtendS.o crtfastmath.o crtprec64.o crtprec80.o crtprec32.o "
+
+# Files which show up as dependencies other than through unconditional #include.
+# This is an egrep pattern.
+hidden_dep_files='(BASE-VER|DATESTAMP|DEV-PHASE|Makefile|xcoffout\.h|basic-block\.h|bconfig\.h)$'
+
+: ${MAKE=make}
+: ${EGREP="grep -E"}
+
+# -------------------------------------------------------------------------
+# There should be no need for changes beyond this point.
+
+set -e
+st=0
+
+if test -f c-common.o; then :; else
+ echo "$0: rerun in an up to date build-tree/gcc directory" >&2
+ exit 1
+fi
+
+for obj in *.o
+do
+ if test -n "$start_after"; then
+ if test $obj = $start_after; then
+ start_after=
+ fi
+ continue
+ fi
+ case $skip in *\ $obj\ *) continue ;; esac
+
+ mv -f $obj $obj.backup
+ ${MAKE} $obj CFLAGS='-MM -MF depfile'
+ mv -f $obj.backup $obj
+ ${MAKE} -t
+ LC_ALL=C ${MAKE} -d $obj >make-d-log
+ hdrs=`cat depfile`
+ for hdr in $hdrs; do
+ case $hdr in
+ *: | *.o | \\ | /* ) ;;
+ *)
+ echo $hdr ;;
+ esac
+ done < depfile |
+ LC_ALL=C sort -u > hdrs
+
+
+ sed -n '/.*Prerequisite..\([^ ]*\). is newer than target .'"$obj"'.*/s//\1/p' \
+ < make-d-log |
+ LC_ALL=C sort -u > not-up-to-date
+ if test -s not-up-to-date; then
+ st=1
+ echo "$0: error: prerequisites for $obj are not up to date:" >&2
+ cat not-up-to-date >&2
+ fi
+ sed -n '/.*Prerequisite..\([^ ]*\). is older than target .'"$obj"'.*/s//\1/p' \
+ < make-d-log |
+ LC_ALL=C sort -u > deps
+ missing_deps=`LC_ALL=C join -v 1 hdrs deps`
+ unneeded_deps=`LC_ALL=C join -v 2 hdrs deps | $EGREP -v "$hidden_dep_files" || :`
+ if test -n "$missing_deps"; then
+ st=1
+ echo "missing deps for $obj:"
+ echo "$missing_deps" | sed 's/^/ /'
+ fi
+ if test -n "$unneeded_deps"; then
+ # unneeded dependencies are not a big problem, so they cause no failure.
+ echo "unneeded deps for $obj:"
+ echo "$unneeded_deps" | sed 's/^/ /'
+ fi
+done
+exit $st
+
+# vi:sw=2:
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 5b9cf46e53a..3eea708d4c3 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,6 +1,2248 @@
+2008-07-28 Richard Guenther <rguenther@suse.de>
+
+ Merge from gimple-tuples-branch.
+
+ * ChangeLog.tuples: ChangeLog from gimple-tuples-branch.
+ * gimple.def: New file.
+ * gsstruct.def: Likewise.
+ * gimple-iterator.c: Likewise.
+ * gimple-pretty-print.c: Likewise.
+ * tree-gimple.c: Removed. Merged into ...
+ * gimple.c: ... here. New file.
+ * tree-gimple.h: Removed. Merged into ...
+ * gimple.h: ... here. New file.
+
+ * Makefile.in: Add dependencies on GIMPLE_H and tree-iterator.h.
+ * configure.ac: Added support for ENABLE_GIMPLE_CHECKING and the
+ --enable-checking=gimple flag.
+ * config.in: Likewise.
+ * configure: Regenerated.
+
+ * tree-ssa-operands.h: Tuplified.
+ * tree-vrp.c: Likewise.
+ * tree-loop-linear.c: Likewise.
+ * tree-into-ssa.c: Likewise.
+ * tree-ssa-loop-im.c: Likewise.
+ * tree-dump.c: Likewise.
+ * tree-complex.c: Likewise.
+ * cgraphbuild.c: Likewise.
+ * tree-ssa-threadupdate.c: Likewise.
+ * tree-ssa-loop-niter.c: Likewise.
+ * tree-pretty-print.c: Likewise.
+ * tracer.c: Likewise.
+ * gengtype.c: Likewise.
+ * tree-loop-distribution.c: Likewise.
+ * tree-ssa-loop-unswitch.c: Likewise.
+ * cgraph.c: Likewise.
+ * cgraph.h: Likewise.
+ * tree-ssa-loop-manip.c: Likewise.
+ * value-prof.c: Likewise.
+ * tree-ssa-loop-ch.c: Likewise.
+ * tree-tailcall.c: Likewise.
+ * value-prof.h: Likewise.
+ * tree.c: Likewise.
+ * tree.h: Likewise.
+ * tree-pass.h: Likewise.
+ * ipa-cp.c: Likewise.
+ * tree-scalar-evolution.c: Likewise.
+ * tree-scalar-evolution.h: Likewise.
+ * target.h: Likewise.
+ * lambda-mat.c: Likewise.
+ * tree-phinodes.c: Likewise.
+ * diagnostic.h: Likewise.
+ * builtins.c: Likewise.
+ * tree-ssa-alias-warnings.c: Likewise.
+ * cfghooks.c: Likewise.
+ * fold-const.c: Likewise.
+ * cfghooks.h: Likewise.
+ * omp-low.c: Likewise.
+ * tree-ssa-dse.c: Likewise.
+ * ipa-reference.c: Likewise.
+ * tree-ssa-uncprop.c: Likewise.
+ * toplev.c: Likewise.
+ * tree-gimple.c: Likewise.
+ * tree-gimple.h: Likewise.
+ * tree-chrec.c: Likewise.
+ * tree-chrec.h: Likewise.
+ * tree-ssa-sccvn.c: Likewise.
+ * tree-ssa-sccvn.h: Likewise.
+ * cgraphunit.c: Likewise.
+ * tree-ssa-copyrename.c: Likewise.
+ * tree-ssa-ccp.c: Likewise.
+ * tree-ssa-loop-ivopts.c: Likewise.
+ * tree-nomudflap.c: Likewise.
+ * tree-call-cdce.c: Likewise.
+ * ipa-pure-const.c: Likewise.
+ * c-format.c: Likewise.
+ * tree-stdarg.c: Likewise.
+ * tree-ssa-math-opts.c: Likewise.
+ * tree-ssa-dom.c: Likewise.
+ * tree-nrv.c: Likewise.
+ * tree-ssa-propagate.c: Likewise.
+ * ipa-utils.c: Likewise.
+ * tree-ssa-propagate.h: Likewise.
+ * tree-ssa-alias.c: Likewise.
+ * gimple-low.c: Likewise.
+ * tree-ssa-sink.c: Likewise.
+ * ipa-inline.c: Likewise.
+ * c-semantics.c: Likewise.
+ * dwarf2out.c: Likewise.
+ * expr.c: Likewise.
+ * tree-ssa-loop-ivcanon.c: Likewise.
+ * predict.c: Likewise.
+ * tree-ssa-loop.c: Likewise.
+ * tree-parloops.c: Likewise.
+ * tree-ssa-address.c: Likewise.
+ * tree-ssa-ifcombine.c: Likewise.
+ * matrix-reorg.c: Likewise.
+ * c-decl.c: Likewise.
+ * tree-eh.c: Likewise.
+ * c-pretty-print.c: Likewise.
+ * lambda-trans.c: Likewise.
+ * function.c: Likewise.
+ * langhooks.c: Likewise.
+ * ebitmap.h: Likewise.
+ * tree-vectorizer.c: Likewise.
+ * function.h: Likewise.
+ * langhooks.h: Likewise.
+ * tree-vectorizer.h: Likewise.
+ * ipa-type-escape.c: Likewise.
+ * ipa-type-escape.h: Likewise.
+ * domwalk.c: Likewise.
+ * tree-if-conv.c: Likewise.
+ * profile.c: Likewise.
+ * domwalk.h: Likewise.
+ * tree-data-ref.c: Likewise.
+ * tree-data-ref.h: Likewise.
+ * tree-flow-inline.h: Likewise.
+ * tree-affine.c: Likewise.
+ * tree-vect-analyze.c: Likewise.
+ * c-typeck.c: Likewise.
+ * gimplify.c: Likewise.
+ * coretypes.h: Likewise.
+ * tree-ssa-phiopt.c: Likewise.
+ * calls.c: Likewise.
+ * tree-ssa-coalesce.c: Likewise.
+ * tree.def: Likewise.
+ * tree-dfa.c: Likewise.
+ * except.c: Likewise.
+ * except.h: Likewise.
+ * cfgexpand.c: Likewise.
+ * tree-cfgcleanup.c: Likewise.
+ * tree-ssa-pre.c: Likewise.
+ * tree-ssa-live.c: Likewise.
+ * tree-sra.c: Likewise.
+ * tree-ssa-live.h: Likewise.
+ * tree-predcom.c: Likewise.
+ * lambda.h: Likewise.
+ * tree-mudflap.c: Likewise.
+ * ipa-prop.c: Likewise.
+ * print-tree.c: Likewise.
+ * tree-ssa-copy.c: Likewise.
+ * ipa-prop.h: Likewise.
+ * tree-ssa-forwprop.c: Likewise.
+ * ggc-page.c: Likewise.
+ * c-omp.c: Likewise.
+ * tree-ssa-dce.c: Likewise.
+ * tree-vect-patterns.c: Likewise.
+ * tree-ssa-ter.c: Likewise.
+ * tree-nested.c: Likewise.
+ * tree-ssa.c: Likewise.
+ * lambda-code.c: Likewise.
+ * tree-ssa-loop-prefetch.c: Likewise.
+ * tree-inline.c: Likewise.
+ * tree-inline.h: Likewise.
+ * tree-iterator.c: Likewise.
+ * tree-optimize.c: Likewise.
+ * tree-ssa-phiprop.c: Likewise.
+ * tree-vect-transform.c: Likewise.
+ * tree-object-size.c: Likewise.
+ * tree-outof-ssa.c: Likewise.
+ * cfgloop.c: Likewise.
+ * system.h: Likewise.
+ * tree-profile.c: Likewise.
+ * cfgloop.h: Likewise.
+ * c-gimplify.c: Likewise.
+ * c-common.c: Likewise.
+ * tree-vect-generic.c: Likewise.
+ * tree-flow.h: Likewise.
+ * c-common.h: Likewise.
+ * basic-block.h: Likewise.
+ * tree-ssa-structalias.c: Likewise.
+ * tree-switch-conversion.c: Likewise.
+ * tree-ssa-structalias.h: Likewise.
+ * tree-cfg.c: Likewise.
+ * passes.c: Likewise.
+ * ipa-struct-reorg.c: Likewise.
+ * ipa-struct-reorg.h: Likewise.
+ * tree-ssa-reassoc.c: Likewise.
+ * cfgrtl.c: Likewise.
+ * varpool.c: Likewise.
+ * stmt.c: Likewise.
+ * tree-ssanames.c: Likewise.
+ * tree-ssa-threadedge.c: Likewise.
+ * langhooks-def.h: Likewise.
+ * tree-ssa-operands.c: Likewise.
+ * config/alpha/alpha.c: Likewise.
+ * config/frv/frv.c: Likewise.
+ * config/s390/s390.c: Likewise.
+ * config/m32c/m32c.c: Likewise.
+ * config/m32c/m32c-protos.h: Likewise.
+ * config/spu/spu.c: Likewise.
+ * config/sparc/sparc.c: Likewise.
+ * config/i386/i386.c: Likewise.
+ * config/sh/sh.c: Likewise.
+ * config/xtensa/xtensa.c: Likewise.
+ * config/stormy16/stormy16.c: Likewise.
+ * config/ia64/ia64.c: Likewise.
+ * config/rs6000/rs6000.c: Likewise.
+ * config/pa/pa.c: Likewise.
+ * config/mips/mips.c: Likewise.
+
+2008-07-28 Simon Baldwin <simonb@google.com>
+
+ * c-pragma.c (handle_pragma_message): New function.
+ (init_pragma): Register handle_pragma_message.
+ * doc/extend.texi (Diagnostic Pragmas): Added #pragma message
+ documentation.
+
+2008-07-27 Victor Kaplansky <victork@il.ibm.com>
+
+ PR tree-optimization/35252
+ * tree-vect-analyze.c (vect_build_slp_tree): Make IMAGPART_EXPR and
+ REALPART_EXPR to be considered as same load operation.
+
+2008-07-27 Eric Botcazou <ebotcazou@adacore.com>
+
+ PR tree-optimization/36830
+ * tree-ssa-sccvn.c (vn_reference_op_compute_hash): Hash operand #2.
+ (expressions_equal_p): Return false if only one operand is null.
+
+2008-07-26 Gerald Pfeifer <gerald@pfeifer.com>
+
+ * doc/install.texi (powerpc-*-netbsd*): Remove redundant texinfo
+ version requirements.
+
+2008-07-26 Olivier Hainque <hainque@adacore.com>
+
+ * collect2.c (symkind): New enum. Symbol kinds we care about.
+ (is_ctor_dtor): Return symkind instead of int. Adjust prototype,
+ code and head comment accordingly.
+ (scan_prog_file): Use symkind names instead of bare integers.
+
+2008-07-25 Jan Hubicka <jh@suse.cz>
+
+ * cgraph.c (cgraph_function_possibly_inlined_p): Do not rely on DECL_INLINE.
+ * cgraphunit.c (record_cdtor_fn): Do not initialize DECL_INLINE
+ (cgraph_preserve_function_body_p): Do not rely on DECL_INLINE.
+ * dojump.c (clear_pending_stack_adjust): Likewise.
+ * print-tree.c (print_node): Ignore DECL_INLINE.
+ * tree-inline.c (inlinable_function_p): Likewise.
+
+2008-07-25 Michael Meissner <gnu@the-meissners.org>
+
+ * doc/extend.texi (hot attribute): Document that the hot attribute
+ turns on -O3 for some ports.
+ (cold attribute): Document that the cold attribute turns on -Os
+ for some ports
+
+ * doc/tm.texi (OPTIMIZATION_OPTIONS): Update documentation to
+ reflect function specific option support.
+
+ * target.h (struct target_option_hooks): Add fields to say whether
+ the cold attribute implies -Os and the hot attribute implies -O3.
+
+ * target-def.h (TARGET_OPTION_COLD_ATTRIBUTE_SETS_OPTIMIZATION):
+ By default, do not turn on -Os for cold functions.
+ (TARGET_OPTION_COLD_ATTRIBUTE_SETS_OPTIMIZATION): By default, do
+ not turn on -O3 for hot functions.
+
+ * c-common.c (handle_hot_attribute): Use target hook to determine
+ if hot functions should enable -O3.
+ (handle_cold_attribute): Use target hook to determine if cold
+ functions should enable -Os.
+
+ * config/i386/i386.c (ix86_target_string): Add -m3dnowa support.
+ (override_options): Move disable scheduling to
+ optimization_options.
+ (optimization_options): Disable scheduling here, not
+ override_options.
+ (TARGET_OPTION_COLD_ATTRIBUTE_SETS_OPTIMIZATION): Define.
+ (TARGET_OPTION_HOT_ATTRIBUTE_SETS_OPTIMIZATION): Define.
+
+ * config/ia64/ia64.c (ia64_override_options): Move setting
+ scheduling flags to ia64_optimization_options.
+ (ia64_optimization_options): Disable scheduling options here, and
+ not in ia64_override_options.
+ (TARGET_OPTION_COLD_ATTRIBUTE_SETS_OPTIMIZATION): Define.
+ (TARGET_OPTION_HOT_ATTRIBUTE_SETS_OPTIMIZATION): Define.
+
+2008-07-25 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR target/36936
+ * config/i386/i386.c (override_options): Don't clear TARGET_CMOVE.
+
+2008-07-25 Martin Jambor <mjambor@suse.cz>
+
+ PR tree-optimization/36926
+ * ipa-prop.c (ipa_analyze_call_uses): Call
+ ipa_is_ssa_with_stmt_def instead of SSA_NAME_IS_DEFAULT_DEF.
+
+2008-07-25 Joseph Myers <joseph@codesourcery.com>
+
+ * config/arm/iwmmxt.md (movv8qi_internal, movv4hi_internal,
+ movv2si_internal): Add mem = reg alternative.
+
+2008-07-25 Andreas Tobler <a.tobler@schweiz.org>
+
+ PR bootstrap/36918
+ * config/sparc/sparc.h (DEFAULT_PCC_STRUCT_RETURN): Define
+ DEFAULT_PCC_STRUCT_RETURN to 127.
+
+2008-07-24 Jan Hubicka <jh@suse.cz>
+
+ * cgraphbuild.c (record_reference): Drop non-unit-at-a-time code.
+ (build_cgraph_edges): Likewise.
+ * cgraph.c (cgraph_node): Do not update assembler hash.
+ (cgraph_remove_node): Drop non-unit-at-a-time code.
+ * tree-pass.h (pass_O0_always_inline): Remove.
+ * ipa-reference.c (gate_reference): Remove unit-at-a-time check.
+ * toplev.c (process_options): Flag unit-at-a-time does not imply
+ no section anchors.
+ * cgraphunit.c: Update comments.
+ (decide_is_function_needed): Drop non-unit-at-a-time mode.
+ (cgraph_assemble_pending_functions): Remove.
+ (cgraph_reset_node): Drop non-unit-at-a-time code.
+ (cgraph_finalize_function): Likewise.
+ (cgraph_analyze_function): Likewise.
+ (cgraph_finalize_compilation_unit): Likewise.
+ (cgraph_expand_function): Likewise.
+ (cgraph_optimize): Likesise.
+ (save_inline_function_body): Likewise.
+ * ipa-pure-const.c (gate_pure_const): Drop flag_unit_at_a_time check.
+ * tree-ssa-alias.c (maybe_be_aliased): Likewise.
+ * ipa-inline.c: Update comments.
+ (enum inlining_mode): remove INLINE_SPEED.
+ (cgraph_clone_inlined_nodes): Drop unit-at-a-time check.
+ (cgraph_mark_inline_edge): Likewise.
+ (try_inline): Likewise.
+ (cgraph_decide_inlining_incrementally): Likewise.
+ (cgraph_gate_inlining): Remove.
+ (cgraph_early_inlining): Remove flag_unit_at_a_time checks.
+ (cgraph_gate_early_inlining): Likewise.
+ (gate_inline_passes): Remove.
+ (pass_inline_parameters, pass_ipa_inline): Remove gates.
+ (cgraph_gate_O0_always_inline, cgraph_O0_always_inline,
+ pass_O0_always_inline): Remove.
+ * c-pch.c (c_pch_matching): Remove -funit-at-a-time.
+ * dwarf2out.c (reference_to_unused): Remove flag_unit_at_a_time check.
+ * opts.c (no_unit_at_a_time_default): Remove.
+ (decode_options): Remove flag_unit_at_a_time reset and warning.
+ * opts.h (no_unit_at_a_time_default): Remove.
+ * c-decl.c (diagnose_mismatched_decls): Do not require inline keyword
+ early in GNU dialect.
+ (merge_decls): Update comment; drop unit-at-a-time check.
+ (finish_decl): Likewise.
+ (grok_declaration): Remove flag_inline_trees code.
+ (finish_functions): Return on function returning non-void on all
+ statics.
+ * ipa-tye-escape.c (gate_type_escape_vars): Remove.
+ * cfgexpand.c (expand_one_static_var): Remove.
+ (expand_one_var): Remove expand_one_static_var call.
+ (expand_used_vars_for_block): Remove flag_unit_a_time check.
+ * c-opts.c (c_common_post_options): Remove flag_inline_trees code
+ and flag_unit_at_a-time compatibility checks.
+ * varasm.c (assemble_alias): Remove flag_unit_at_a_time check.
+ * tree-inline.c (flag_inline_trees): Remove.
+ (inlinable_function_p): Don't check it.
+ (expand_call_inline): Remove non-unit-at-a-time code.
+ * tree-inline.h (flag_inline_trees): Remove.
+ * tree-optimize.c (execute_early_local_optimizations): Remove
+ unit-at-a-time checks.
+ (tree_rest_of_compilation): Likewise.
+ * combine.c (setup_incoming_promotions): Likewise.
+ * tree-profile.c (tree_gen_ic_func_profiler): Likewise.
+ * tree-ssa-structalias.c (delete_points_to_sets): Likewise.
+ * passes.c (pass_inline_parameters): Update comments; remove
+ O0_alwaysinline pass.
+ (execute_one_ipa_transform_pass): Do not reset in_gimple_form.
+ (execute_one_pass): Likewise.
+ * i386.c (ix86_function_regparm): Remove unit-at-a-time check.
+ (ix86_function_sseregparm): Likewise.
+ * arm.c (arm_function_in_section_p): Likewise.
+ * bfin.c (bfin_load_pic_reg, bfin_function_ok_for_sibcall): Likewise.
+ * varpool.c: Update comments.
+ (decide_is_variable_needed): Remove unit-at-a-time checks.
+ (varpool_finalize_decl): Likewise.
+
+2008-07-24 Kaz Kojima <kkojima@gcc.gnu.org>
+
+ * config/sh/sh.h (OPTIMIZATION_OPTIONS): Set flag_omit_frame_pointer
+ to 2 instead of -1.
+ (OVERRIDE_OPTIONS): Check if flag_omit_frame_pointer is equal
+ to 2.
+
+2008-07-24 Kai Tietz <kai.tietz@onevision.com>
+
+ * config/i386/i386.c (get_dllimport_decl): Treat user_label_prefix for
+ imp symbol extension.
+
+ 2008-07-23 Ian Lance Taylor <iant@google.com>
+
+ * tree-vrp.c (infer_value_range): Ignore asm statements when
+ looking for memory accesses for -fdelete-null-pointer-checks.
+
+2008-07-24 Ben Elliston <bje@au.ibm.com>
+
+ * config/spu/spu-c.c (__vector_keyword): New variable.
+ (vector_keyword): Likewise.
+ (spu_categorize_keyword): New function.
+ (spu_macro_to_expand): Likewise.
+ (spu_cpu_cpp_builtins): Enable context-sensitive macros if not
+ compiling an ISO C dialect.
+
+2008-07-24 Ben Elliston <bje@au.ibm.com>
+
+ * config/rs6000/rs6000-c.c: Move GTY(()) markers to match
+ conventional usage.
+
+2008-07-23 Aaron W. LaFramboise <aaronavay62@aaronwl.com>
+
+ * configure: Regenerate.
+ * configure.ac: Require texinfo 4.7.
+ * doc/install.texi: Document texinfo 4.7 requirement.
+
+2008-07-23 Martin Jambor <mjambor@suse.cz>
+
+ * ipa-cp.c (ipcp_print_edge_profiles): Test for node->analyzed
+ rather than for DECL_SAVED_TREE.
+ * ipa-prop.c: Include diagnostic.h.
+ (ipa_check_stmt_modifications): Check LHS of GIMPLE_MODIFY_EXPRs
+ thoroughly.
+ (ipa_detect_param_modifications): Function rewritten from scratch.
+ (ipa_compute_jump_functions): Changed accesses to modification flags.
+ (ipa_free_node_params_substructures): Update flags destruction.
+ (ipa_node_duplication_hook): Update flags duplication.
+ (ipa_print_all_params_modified): Updated flag access.
+ * ipa-prop.h (struct ipa_param_flags): New structure.
+ (struct ipa_node_params): New field modification_analysis_done,
+ modified_flags changed into param_flags.
+ (ipa_is_ith_param_modified): Changed to use new flags.
+ * Makefile.in (ipa-prop.o): Add $(DIAGNOSTIC_H) to dependencies.
+
+ * ipa-prop.c (ipa_print_all_jump_functions): Moved here from
+ ipa-cp.c and split into two functions.
+ (ipa_print_node_jump_functions): New function.
+ (compute_scalar_jump_functions): New function.
+ (type_like_member_ptr_p): New function.
+ (compute_pass_through_member_ptrs): New function.
+ (fill_member_ptr_cst_jump_function): New function.
+ (determine_cst_member_ptr): New function.
+ (compute_cst_member_ptr_arguments): New function.
+ (ipa_compute_jump_functions): Complete rewrite.
+ * ipa-prop.h (enum jump_func_type): Make explicit that we depend
+ on IPA_UNKNOWN being zero. Added value IPA_CONST_MEMBER_PTR.
+ (struct ipa_member_ptr_cst): New structure.
+ (union jump_func_value): New field member_cst.
+ * ipa-cp.c (ipcp_lat_is_insertable): New function.
+ (ipcp_lattice_from_jfunc): Produces bottom lattices for unhandled
+ jump function types.
+ (ipcp_print_all_lattices): Slight fprintf rearrangement.
+ (ipcp_print_all_structures): Call ipa_print_all_jump_functions
+ instead of ipcp_print_all_jump_functions.
+ (ipcp_insert_stage): Use ipcp_lat_is_insertable, create replace maps
+ only for replacable scalars.
+
+ * doc/invoke.texi (Optimize options): Add description of
+ -findirect-inlining.
+ * common.opt (flag_indirect_inlining): New flag.
+ * opts.c (decode_options): Set flag_indirect_inlining when
+ optimize >= 3.
+
+ * ipa-inline.c: Include ipa-prop.h.
+ (inline_indirect_intraprocedural_analysis): New function.
+ (inline_generate_summary): Allocate parameter and argument info
+ structures, call inline_indirect_intraprocedural_analysis on each
+ node when doing indirect inlining and deallocate indirect inlining
+ data structures in the end.
+ * ipa-prop.c (ipa_create_param_decls_array): Return if already done.
+ (free_all_ipa_structures_after_iinln): New function.
+ (free_all_ipa_structures_after_ipa_cp): Checks whether iinln will be
+ done.
+ * Makefile.in (ipa-inline.o): Added $(IPA_PROP_H) to dependencies.
+
+ * cgraphbuild.c (compute_call_stmt_bb_frequency): New function.
+ (build_cgraph_edges): Call compute_call_stmt_bb_frequency instead
+ of computing the frequency separately.
+ (rebuild_cgraph_edges): Call compute_call_stmt_bb_frequency instead
+ of computing the frequency separately.
+ * ipa-cp.c (ipcp_print_all_structures): Replace a call to
+ ipa_print_all_param_modified with a call to ipa_print_all_param_flags.
+ * ipa-prop.c (ipa_get_member_ptr_load_param): New function.
+ (ipa_get_stmt_member_ptr_load_param): New function.
+ (ipa_is_ssa_with_stmt_def): New function.
+ (ipa_note_param_call): New function.
+ (ipa_analyze_call_uses): New function.
+ (ipa_analyze_stmt_uses): New function.
+ (ipa_analyze_params_uses): New function.
+ (ipa_free_node_params_substructures): Also free the param_calls linked
+ list.
+ (ipa_node_duplication_hook): Also duplicate the param_calls linked list.
+ (ipa_print_node_param_flags): New function.
+ (ipa_print_all_params_modified): Renamed to ipa_print_all_param_flags.
+ (ipa_print_all_param_flags): Calls ipa_print_node_param_flags.
+ * ipa-prop.h (struct ipa_param_flags): New field called.
+ (struct ipa_param_call_note): New structure.
+ (struct ipa_node_params): New fields param_calls and
+ uses_analysis_done.
+ (ipa_is_ith_param_called): New function.
+ * ipa-inline.c (inline_indirect_intraprocedural_analysis): Call
+ ipa_analyze_params_uses and dump parameter flags.
+
+ * ipa-inline.c (cgraph_decide_recursive_inlining): Call
+ ipa_propagate_indirect_call_infos if performing indirect inlining,
+ pass a new parameter new_edges to it.
+ (add_new_edges_to_heap): New fucntion.
+ (cgraph_decide_inlining_of_small_functions): New vector
+ new_indirect_edges for newly found indirect edges , call
+ ipa_propagate_indirect_call_infos after inlining.
+ (cgraph_decide_inlining): Call ipa_propagate_indirect_call_infos after
+ inlining if performing indirect inlining. Call
+ free_all_ipa_structures_after_iinln when doing so too.
+ (inline_generate_summary): Do not call
+ free_all_ipa_structures_after_iinln here.
+ * ipa-prop.c (update_jump_functions_after_inlining): New function.
+ (print_edge_addition_message): New function.
+ (update_call_notes_after_inlining): New function.
+ (propagate_info_to_inlined_callees): New function.
+ (ipa_propagate_indirect_call_infos): New function.
+ * ipa-prop.h: Include cgraph.h
+ (struct ipa_param_call_note): Fields reordered, new field processed.
+ * cgraph.h (cgraph_edge): Shrink loop_nest field to 31 bits, add a new
+ flag indirect_call.
+ * cgraphunit.c (verify_cgraph_node): Allow indirect edges not to have
+ rediscovered call statements.
+ * cgraph.c (cgraph_create_edge): Initialize indirect_call to zero.
+ (dump_cgraph_node): Dump also the indirect_call flag.
+ (cgraph_clone_edge): Copy also the indirect_call flag.
+ * tree-inline.c (copy_bb): Do not check for fndecls from call
+ expressions, check for edge availability when moving clones.
+ (get_indirect_callee_fndecl): New function.
+ (expand_call_inline): If callee declaration is not apprent from
+ the statement, try calling get_indirect_callee_fndecl. Do not
+ issue warnings or call sorry when not inlinings an indirect edge.
+ * Makefile.in (IPA_PROP_H): Added $(CGRAPH_H) to dependencies.
+
+ * ipa-prop.c (ipa_print_node_param_flags): Make the dump format a
+ bit more frandly to matching.
+ * testsuite/g++.dg/ipa/iinline-1.C: New testcase.
+ * testsuite/gcc.dg/ipa/iinline-1.c: New testcase.
+ * testsuite/gcc.dg/ipa/modif-1.c: New testcase.
+
+2008-07-23 Michael Meissner <gnu@the-meissners.org>
+
+ PR 36907
+ * opth-gen.awk: Suppress function specific features when building
+ target libraries.
+ * optc-gen.awk: Ditto.
+
+2008-07-23 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
+
+ PR 35058
+ * diagnostic.c (pedwarn): Add opt parameter.
+ (pedwarn0): New.
+ * c-tree.h (pedwarn_init): Add opt parameter.
+ (pedwarn_c90): Likewise.
+ (pedwarn_c99): Likewise.
+ * c-errors.c (pedwarn_c99): Likewise.
+ (pedwarn_c90): Likewise.
+ * toplev.h (pedwarn): Update declaration.
+ (pedwarn0): Declare.
+ * c-lex.c: All calls to pedwarn changed.
+ * builtins.c: All calls to pedwarn changed.
+ * toplev.c: All calls to pedwarn changed.
+ * c-decl.c: All calls to pedwarn changed.
+ * c-typeck.c: All calls to pedwarn changed.
+ * c-common.c: All calls to pedwarn changed.
+ * c-parser.c: All calls to pedwarn changed.
+
+2008-07-23 Michael Meissner <gnu@the-meissners.org>
+ Karthik Kumar <karthikkumar@gmail.com>
+
+ * attribs.c (file scope): Include c-common.h.
+ (decl_attributes): Add support for #pragma GCC optimize and
+ #pragma GCC option.
+
+ * targhooks.c (default_can_inline_p): New function that is the
+ default for the TARGET_CAN_INLINE_P target hook.
+
+ * targhooks.h (default_can_inline_p): Add declaration.
+
+ * tree.c (cl_optimization_node): New static tree for building
+ OPTIMIZATION_NODE tree.
+ (cl_target_option_node): New static tree for building
+ TARGET_OPTION_NODE tree.
+ (cl_option_hash_table): New hash table for hashing
+ OPTIMIZATION_NODE and TARGET_OPTION_NODE trees.
+ (cl_option_hash_hash): New function to provide the hash value for
+ OPTIMIZATION_NODE and TARGET_OPTION_NODE trees.
+ (cl_option_hash_eq): New function to provide an equality test for
+ OPTIMIZATION_NODE and TARGET_OPTION_NODE trees.
+ (tree_code_size): Add support for OPTIMIZATION_NODE and
+ TARGET_OPTION_NODE trees.
+ (tree_code_structure): Add support for OPTIMIZATION_NODE and
+ TARGET_OPTION_NODE trees.
+ (build_optimization_node): Build a tree that has all of the
+ current optimization options.
+ (build_target_option_node): Build a tree that has the target
+ options that might be changed on a per function basis.
+
+ * tree.h (file scope): Include options.h.
+ (DECL_FUNCTION_SPECIFIC_TARGET): New accessor macro.
+ (DECL_FUNCTION_SPECIFIC_OPTIMIZATION): Ditto.
+ (TREE_OPTIMIZATION): Ditto.
+ (TREE_TARGET_SPECIFIC): Ditto.
+ (struct tree_function_decl): Add fields for remembering the
+ current optimization options and target specific options.
+ (struct tree_optimization_option): New tree variant that remembers
+ the optimization options.
+ (struct tree_target_option): New tree variant that remembers the
+ target specific flags that might change for compiling a particular
+ function.
+ (union tree_node): Include tree_optimization_option and
+ tree_target_option fields.
+ (enum tree_index): Add TI_OPTIMIZATION_DEFAULT,
+ TI_OPTIMIZATION_CURRENT, TI_OPTIMIZATION_COLD,
+ TI_OPTIMIZATION_HOT, TI_TARGET_OPTION_DEFAULT,
+ TI_TARGET_OPTION_CURRENT, TI_CURRENT_OPTION_PRAGMA,
+ TI_CURRENT_OPTIMIZE_PRAGMA entries for saving function specific
+ optimization and target options.
+ (optimization_default_node): New macro to refer to global_trees
+ field.
+ (optimization_current_node): Ditto.
+ (optimization_cold_node): Ditto.
+ (optimization_hot_node): Ditto.
+ (target_option_default_node): Ditto.
+ (target_option_current_node): Ditto.
+ (current_option_pragma): Ditto.
+ (current_optimize_pragma): Ditto.
+
+ * target.h (struct gcc_target): Add valid_option_attribute_p,
+ target_option_save, target_option_restore, target_option_print,
+ target_option_pragma_parse, and can_inline_p hooks.
+
+ * toplev.h (parse_optimize_options): Add declaration.
+ (fast_math_flags_struct_set_p): Ditto.
+
+ * c-cppbuiltin.c (c_cpp_builtins_optimize_pragma): New function to
+ adjust the current __OPTIMIZE__, etc. macros when #pragma GCC
+ optimize is used.
+
+ * ipa-inline.c (cgraph_decide_inlining_of_small_function): Call
+ tree_can_inline_p hook to see if one function can inline another.
+ (cgraph_decide_inlining): Ditto.
+ (cgraph_decide_inlining_incrementally): Ditto.
+
+ * opts.c (decode_options): Add support for running multiple times
+ to allow functions with different target or optimization options
+ than was specified on the command line.
+ (fast_math_flags_struct_set_p): New function that is similar to
+ fast_math_flags_set_p, except it uses the values in the
+ cl_optimization structure instead of global variables.
+
+ * optc-gen.awk: Add support for TargetSave to allow a back end to
+ declare new fields that need to be saved when using function
+ specific options. Include flags.h and target.h in the options.c
+ source. Add support for Save to indicate which options can be set
+ for individual functions. Generate cl_optimize_save,
+ cl_optimize_restore, cl_optimize_print, cl_target_option_save,
+ cl_target_option_restore, cl_target_option_print functions to
+ allow functions to use different optimization or target options.
+
+ * opt-functions.awk (var_type_struct): Return the type used for
+ storing the field in a structure.
+
+ * opth-gen.awk: Add support for TargetSave to allow a back end to
+ declare new fields that need to be saved when using function
+ specific options. Add support for Save to indicate which options
+ can be set for individual functions. Only generate one extern for
+ Mask fields. Generate cl_optimization and cl_target_option
+ structures to remember optimization and target options.
+
+ * treestruct.def (TS_OPTIMIZATION): Add support for garbage
+ collecting new tree nodes.
+ (TS_TARGET_OPTION): Ditto.
+
+ * c-decl.c (merge_decls): Merge function specific target and
+ optimization options.
+
+ * function.c (invoke_set_current_function_hook): If the function
+ uses different optimization options, change the global variables
+ to reflect this.
+
+ * coretypes.h (struct cl_optimization): Add forward reference.
+ (struct cl_target_option): Ditto.
+
+ * c-pragma.c (option_stack): New static vector to remember the
+ current #pragma GCC option stack.
+ (handle_pragma_option): New function to support #pragma GCC option
+ to change target options.
+ (optimize_stack): New static vector to remember the current
+ #pragma GCC optimize stack.
+ (handle_pragma_optimize): New function to support #pragma GCC
+ optimize to change optimization options.
+ (init_pragma): Add support for #pragma GCC optimize and #pragma
+ GCC option.
+
+ * tree.def (OPTIMIZATION_NODE): New tree code for remembering
+ optimization options.
+ (TARGET_OPTION_NODE): New tree code for remembering certain target
+ options.
+
+ * print-tree.c (print_node): Add support for OPTIMIZATION_NODE and
+ TARGET_OPTION_NODE trees.
+
+ * common.opt (-O): Add Optimization flag.
+ (-Os): Ditto.
+ (-fmath-errno): Ditto.
+ (-falign-functions): Add UInteger flag to make sure flag gets full
+ int in cl_optimization structure.
+ (-falign-jumps): Ditto.
+ (-falign-labels): Ditto.
+ (-falign-loops): Ditto.
+ (-fsched-stalled-insns): Ditto.
+ (-fsched-stalled-insns-dep): Ditto.
+
+ * target-def.h (TARGET_VALID_OPTION_ATTRIBUTE_P): Add default
+ definition.
+ (TARGET_OPTION_SAVE): Ditto.
+ (TARGET_OPTION_RESTORE): Ditto.
+ (TARGET_OPTION_PRINT): Ditto.
+ (TARGET_OPTION_PRAGMA_PARSE): Ditto.
+ (TARGET_CAN_INLINE_P): Ditto.
+ (TARGET_INITIALIZER): Add new hooks.
+
+ * tree-inline.c (tree_can_inline_p): New function to determine
+ whether one function can inline another. Check if the functions
+ use compatible optimization options, and also call the backend
+ can_inline_p hook.
+
+ * tree-inline.h (tree_can_inline_p): Add declaration.
+
+ * c-common.c (c_common_attribute): Add support for option and
+ optimize attributes.
+ (handle_option_attribute): Add support for the option attribute to
+ allow the user to specify different target options for compiling a
+ specific function.
+ (handle_optimize_attribute): Add support for the optimize
+ attribute to allow the user to specify different optimization
+ options for compiling a specific function.
+ (handle_hot_attribute): Turn on -O3 optimization for this one
+ function if it isn't the default optimization level.
+ (handle_cold_attribute): Turn on -Os optimization for this one
+ function if it insn't the default optimization.
+ (const_char_p): New const char * typedef.
+ (optimize_args): New static vector to remember the optimization
+ arguments.
+ (parse_optimize_options): New function to set up the optimization
+ arguments from either the optimize attribute or #pragma GCC
+ optimize.
+
+ * c-common.h (c_cpp_builtins_optimize_pragma): Add declaration.
+ (builtin_define_std): Ditto.
+
+ * config.gcc (i[3467]86-*-*): Add i386-c.o to C/C++ languages.
+ Add t-i386 Makefile fragment to add i386-c.o and i386.o
+ dependencies.
+ (x86_64-*-*): Ditto.
+
+ * Makefile.in (TREE_H): Add options.h.
+ (options.o): Add $(TARGET_H) $(FLAGS_H) dependencies.
+
+ * doc/extend.texi (option attribute): Document new attribute.
+ (optimize attribute): Ditto.
+ (hot attribute): Document hot attribute sets -O3.
+ (cold attribute): Document cold attribute sets -Os.
+ (#pragma GCC option): Document new pragma.
+ (#pragma GCC optimize): Ditto.
+
+ * doc/options.texi (TargetSave): Document TargetSave syntax.
+ (UInteger): Document UInteger must be used for certain flags.
+ (Save): Document Save option to create target specific options
+ that can be saved/restored on a function specific context.
+
+ * doc/c-tree.texi (DECL_FUNCTION_SPECIFIC_TARGET): Document new
+ macro.
+ (DECL_FUNCTION_SPECIFIC_OPTIMIZATION): Ditto.
+
+ * doc/tm.texi (TARGET_VALID_OPTION_ATTRIBUTE_P): Document new
+ hook.
+ (TARGET_OPTION_SAVE): Ditto.
+ (TARGET_OPTION_RESTORE): Ditto.
+ (TARGET_OPTION_PRINT): Ditto.
+ (TARGET_OPTION_PRAGMA_PARSE): Ditto.
+ (TARGET_CAN_INLINE_P): Ditto.
+
+ * doc/invoke.texi (-mfpmath=sse+387): Document as an alias for
+ -mfpmath=sse,387.
+ (-mfpmath=both): Ditto.
+
+2008-07-23 Michael Meissner <gnu@the-meissners.org>
+ Karthik Kumar <karthikkumar@gmail.com>
+
+ * config/i386/i386.h (TARGET_ABM): Move switch into
+ ix86_isa_flags.
+ (TARGET_POPCNT): Ditto.
+ (TARGET_SAHF): Ditto.
+ (TARGET_AES): Ditto.
+ (TARGET_PCLMUL): Ditto.
+ (TARGET_CMPXCHG16B): Ditto.
+ (TARGET_RECIP): Move switch into target_flags.
+ (TARGET_FUSED_MADD): Ditto.
+ (ix86_arch_features): Make an unsigned char type.
+ (ix86_tune_features): Ditto.
+ (OVERRIDE_OPTIONS): Add bool argument to override_options call.
+ (TARGET_CPU_CPP_BUILTINS): Move into ix86_target_macros.
+ (REGISTER_TARGET_PRAGMAS): Define, call ix86_register_pragmas.
+
+ * config/i386/i386.opt (arch): New TargetSave field to define
+ fields that need to be saved for function specific option
+ support.
+ (tune): Ditto.
+ (fpmath): Ditto.
+ (branch_cost): Ditto.
+ (ix86_isa_flags_explicit): Ditto.
+ (tune_defaulted): Ditto.
+ (arch_specified): Ditto.
+ (-m128-long-double): Add Save flag to save option for target
+ specific option support.
+ (-m80387): Ditto.
+ (-maccumulate-outgoing-args): Ditto.
+ (-malign-double): Ditto.
+ (-malign-stringops): Ditto.
+ (-mfancy-math-387): Ditto.
+ (-mhard-float): Ditto.
+ (-mieee-fp): Ditto.
+ (-minline-all-stringops): Ditto.
+ (-minline-stringops-dynamically): Ditto.
+ (-mms-bitfields): Ditto.
+ (-mno-align-stringops): Ditto.
+ (-mno-fancy-math-387): Ditto.
+ (-mno-push-args): Ditto.
+ (-mno-red-zone): Ditto.
+ (-mpush-args): Ditto.
+ (-mred-zone): Ditto.
+ (-mrtd): Ditto.
+ (-msseregparm): Ditto.
+ (-mstack-arg-probe): Ditto.
+ (-m32): Ditto.
+ (-m64): Ditto.
+ (-mmmx): Ditto.
+ (-m3dnow): Ditto.
+ (-m3dnowa): Ditto.
+ (-msse): Ditto.
+ (-msse2): Ditto.
+ (-msse3): Ditto.
+ (-msse4.1): Ditto.
+ (-msse4.2): Ditto.
+ (-msse4): Ditto.
+ (-mno-sse4): Ditto.
+ (-msse4a): Ditto.
+ (-msse5): Ditto.
+ (-mrecip): Move flag into target_flags.
+ (-mcld): Ditto.
+ (-mno-fused-madd): Ditto.
+ (-mfused-madd): Ditto.
+ (-mabm): Move flag into ix86_isa_flags.
+ (-mcx16): Ditto.
+ (-mpopcnt): Ditto.
+ (-msahf): Ditto.
+ (-maes): Ditto.
+ (-mpclmul): Ditto.
+
+ * config/i386/i386-c.c: New file for #pragma support.
+ (ix86_target_macros_internal): New function to #define or #undef
+ target macros based when the user uses the #pragma GCC option to
+ change target options.
+ (ix86_pragma_option_parse): New function to add #pragma GCC option
+ support.
+ (ix86_target_macros): Move defining the target macros here from
+ TARGET_CPU_CPP_BUILTINS in i386.h.
+ (ix86_register_pragmas): Register the #pragma GCC option hook. If
+ defined, initialize any subtarget #pragmas.
+
+ * config/i386/darwin.h (REGISTER_SUBTARGET_PRAGMAS): Rename from
+ REGISTER_TARGET_PRAGMAS.
+
+ * config/i386/t-i386: New file for x86 dependencies.
+ (i386.o): Make dependencies mirror the include files used.
+ (i386-c.o): New file, add dependencies.
+
+ * config/i386/i386-protos.h (override_options): Add bool
+ argument.
+ (ix86_valid_option_attribute_tree): Add declaration.
+ (ix86_target_macros): Ditto.
+ (ix86_register_macros): Ditto.
+
+ * config/i386/i386.c (ix86_tune_features): Move initialization of
+ the target masks to initial_ix86_tune_features to allow functions
+ to have different target options. Make type unsigned char,
+ instead of unsigned int.
+ (initial_ix86_tune_features): New static vector to hold processor
+ masks for the tune variables.
+ (ix86_arch_features): Move initialization of the target masks to
+ initial_ix86_arch_features to allow functions to have different
+ target options. Make type unsigned char, instead of unsigned
+ int.
+ (initial_ix86_arch_features): New static vector to hold processor
+ masks for the arch variables.
+ (enum ix86_function_specific_strings): New enum to describe the
+ string options used for attribute((option(...))).
+ (ix86_target_string): New function to return a string that
+ describes the target options.
+ (ix86_debug_options): New function to print the current options in
+ the debugger.
+ (ix86_function_specific_save): New function hook to save the
+ function specific global variables in the cl_target_option
+ structure.
+ (ix86_function_specific_restore): New function hook to restore the
+ function specific variables from the cl_target_option structure to
+ the global variables.
+ (ix86_function_specific_print): New function hook to print the
+ target specific options in the cl_target_option structure.
+ (ix86_valid_option_attribute_p): New function hook to validate
+ attribute((option(...))) arguments.
+ (ix86_valid_option_attribute_tree): New function that is common
+ code between attribute((option(...))) and #pragma GCC option
+ support that parses the options and returns a tree holding the
+ options.
+ (ix86_valid_option_attribute_inner_p): New helper function for
+ ix86_valid_option_attribute_tree.
+ (ix86_can_inline_p): New function hook to decide if one function
+ can inline another on a target specific basis.
+ (ix86_set_current_function); New function hook to switch target
+ options if the user used attribute((option(...))) or #pragma GCC
+ option.
+ (ix86_tune_defaulted): Move to static file scope from
+ override_options.
+ (ix86_arch_specified): Ditto.
+ (OPTION_MASK_ISA_AES_SET): New macro for moving switches into
+ ix86_isa_flags.
+ (OPTION_MASK_ISA_PCLMUL_SET): Ditto.
+ (OPTION_MASK_ISA_ABM_SET): Ditto.
+ (OPTION_MASK_ISA_POPCNT_SET): Ditto.
+ (OPTION_MASK_ISA_CX16_SET): Ditto.
+ (OPTION_MASK_ISA_SAHF_SET): Ditto.
+ (OPTION_MASK_ISA_AES_UNSET): Ditto.
+ (OPTION_MASK_ISA_PCLMUL_UNSET): Ditto.
+ (OPTION_MASK_ISA_ABM_UNSET): Ditto.
+ (OPTION_MASK_ISA_POPCNT_UNSET): Ditto.
+ (OPTION_MASK_ISA_CX16_UNSET): Ditto.
+ (OPTION_MASK_ISA_SAHF_UNSET): Ditto.
+ (struct ptt): Move to static file scope from override_options.
+ (processor_target_table): Ditto.
+ (cpu_names): Ditto.
+ (ix86_handle_option): Add support for options that are now isa
+ options.
+ (override_options): Add support for declaring functions that
+ support different target options than were specified on the
+ command line. Move struct ptt, processor_target_table, cpu_names,
+ ix86_tune_defaulted, ix86_arch_specified to static file scope.
+ Add bool argument. Fix up error messages so the appropriate error
+ is given for either command line or attribute.
+ (ix86_previous_fndecl): New static to remember previous function
+ declaration to see if we need to change target options.
+ (ix86_builtins_isa): New array to record the ISA of each builtin
+ function.
+ (def_builtin): Always create the builtin function, even if the
+ current ISA doesn't support it.
+ (ix86_init_mmx_sse_builtins): Remove TARGET_AES and TARGET_PCLMUL
+ tests for those builtins.
+ (ix86_init_builtins): Remove TARGET_MMX test for calling
+ ix86_init_mmx_sse_builtins.
+ (ix86_expand_builtin): If the current ISA doesn't support a given
+ builtin, signal an error.
+ (TARGET_VALID_OPTION_ATTRIBUTE_P): Set target hook.
+ (TARGET_SET_CURRENT_FUNCTION): Ditto.
+ (TARGET_OPTION_SAVE): Ditto.
+ (TARGET_OPTION_RESTORE): Ditto.
+ (TARGET_OPTION_PRINT): Ditto.
+ (TARGET_CAN_INLINE_P): Ditto.
+
+2008-07-22 Rafael Avila de Espindola <espindola@google.com>
+
+ * c-typeck.c (build_external_ref): Don't call assemble_external.
+ * final.c (output_operand): Call assemble_external.
+
+2008-07-21 DJ Delorie <dj@redhat.com>
+
+ * config/h8300/h8300.c (h8300_hard_regno_scratch_ok): New.
+ (TARGET_HARD_REGNO_SCRATCH_OK): Define.
+
+2008-07-21 Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
+
+ * config/spu/spu.md ("div<mode>3"): Convert into expander, move
+ original insn and splitter contents into ...
+ ("*div<mode>3_fast"): ... this new pattern. Enable only if
+ flag_unsafe_math_optimizations. Add dummy scratch register.
+ ("*div<mode>3_adjusted"): New insn and splitter. Enable only if
+ !flag_unsafe_math_optimizations. Returns number with next
+ highest magnitude if this is still less or equal to the true
+ quotient in magnitude.
+
+2008-07-21 Rafael Avila de Espindola <espindola@google.com>
+
+ * Makefile.in: Replace toplev.h with TOPLEV_H.
+ * c-decl.c (merge_decls): Don't set DECL_IN_SYSTEM_HEADER.
+ * c-lex.c (fe_file_change): Don't set in_system_header.
+ * c-parser.c (c_token): Remove in_system_header.
+ (c_lex_one_token): Don't set in_system_header.
+ (c_parser_set_source_position_from_token): Don't set in_system_header.
+ * diagnostic.c (diagnostic_report_diagnostic): Use location from
+ diagnostic_info.
+ (warning_at): New.
+ * diagnostic.h (diagnostic_report_warnings_p): Add LOC argument.
+ * flags.h (in_system_header): Remove.
+ * function.c (saved_in_system_header): Remove.
+ (push_cfun): Don't set in_system_header.
+ (pop_cfun): Don't set in_system_header.
+ (push_struct_function): Don't set in_system_header.
+ * input.h (expanded_location): Add sysp.
+ (in_system_header_at): New.
+ (in_system_header): New.
+ * toplev.c (in_system_header): Remove.
+ * toplev.h: Include input.h
+ (warning_at): New.
+ * tree-cfg.c (execute_warn_function_return): Call warning_at.
+ * tree-ssa.c (warn_uninit): Call warning_at.
+ (warn_uninitialized_var): Update calls to warn_uninit.
+ (warn_uninitialized_phi): Update calls to warn_uninit.
+ * tree.c (make_node_stat): Don't set DECL_IN_SYSTEM_HEADER.
+ (expand_location): Initialize xloc.sysp.
+ * tree.h (DECL_IN_SYSTEM_HEADER): Use in_system_header_at.
+ (tree_decl_with_vis): Remove in_system_header_flag.
+
+2008-07-21 Andreas Krebbel <krebbel1@de.ibm.com>
+
+ PR target/36822
+ * recog.c (asm_operand_ok): Change the order of the extra
+ memory constraint checks.
+
+2008-07-20 Andrew Pinski <andrew_pinski@playstation.sony.com>
+
+ PR tree-opt/36879
+ * tree-switch-conversion.c (build_one_array): Call
+ varpool_mark_needed_node and varpool_finalize_decl
+ instead of assemble_variable.
+
+2008-07-19 Jan Hubicka <jh@suse.cz>
+
+ * cgraph.c (cgraph_add_new_function): Do early local passes.
+ * tree-nrv.c (gate_pass_return_slot): New gate.
+ (pass_nrv): Add the gate.
+ * tree-ssa-coalese.c (hash_ssa_name_by_var, eq_ssa_name_by_var): New
+ functions.
+ (coalesce_ssa_name): Coalesce SSA names.
+ * tree-ssa-live.c (remove_unused_locals): Be more conservative when
+ not optimizing so unused user vars remains visible.
+ * common.opt (flag_tree_ter): Always enable by default.
+ * tree-ssa-ter.c: Include flags.h
+ (is_replaceable_p): Check that locations match; when aliasing is missing
+ be conservative about loads.
+ * tree-optimize.c (gate_init_datastructures): Remove.
+ (pass_init_datastructures): New.
+ * passes.c: Reorder passes so we always go into SSA.
+
+2008-07-19 Jan Hubicka <jh@suse.cz>
+
+ * doc/extend.texi (flatten attribute): Remove note about unit-at-a-time
+ * doc/invoke.texi (--combine): Likewise.
+ (-finline-functions-called-once): Update levels when enabled.
+ (-funit-at-a-time): Document new behaviour.
+ (-ftoplevel-reorder): Document that it is enabled -O0 and imply
+ -fno-section-anchors when disabled explicitly.
+ (inline params): They are not ignored now.
+ (precompiled headers): Remove unit-at-a-time as being incompatible.
+ * opts.c (decode_options): Handle unit-at-a-time as alias;
+ imply -fno-section-anchors when toplevel reorder is disabled
+ explicitly.
+ * common.opt (ftoplevel-reorder): Set default value to 2.
+ (funit-at-a-time): Set default value to 1.
+ * config/rs6000/rs6000.c (optimization_options): Set section anchors
+ to 2.
+
+2008-07-19 Jan Hubicka <jh@suse.cz>
+
+ * builtins.c (expand_builtin_int_roundingfn,
+ expand_builtin_int_roundingfn_2): Do not take subtarget argument;
+ it is not useful.
+
+2008-07-19 Richard Guenther <rguenther@suse.de>
+
+ PR bootstrap/36864
+ * tree-ssa-sccvn.h (get_constant_value_id): Declare.
+ * tree-ssa-sccvn.c (get_constant_value_id): New function.
+ * tree-ssa-pre.c (get_expr_value_id): For newly created
+ constant value-ids make sure to add the expression to its
+ expression-set.
+
+2008-07-19 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/36877
+ * omp-low.c (expand_omp_atomic_fetch_op): Make sure the
+ return value of the builtin is ignored.
+
+2008-07-19 Olivier Hainque <hainque@adacore.com>
+
+ * doc/tm.texi (MALLOC_ABI_ALIGNMENT): New macro. Alignment, in
+ bits, a C conformant malloc implementation has to provide.
+ * defaults.h (MALLOC_ABI_ALIGNMENT): Default to BITS_PER_WORD.
+
+2008-07-19 Joseph Myers <joseph@codesourcery.com>
+
+ PR target/36780
+ PR target/36827
+ * reload.c (find_reloads_subreg_address): Only reload address if
+ reloaded == 0, not for reloaded != 1.
+
+ Revert:
+ 2008-07-16 Joseph Myers <joseph@codesourcery.com>
+ * config/m32c/m32c.c (BIG_FB_ADJ): Move definition earlier.
+ (m32c_legitimate_address_p): Handle "++rii" addresses created by
+ m32c_legitimize_reload_address.
+
+ 2008-07-15 Kaz Kojima <kkojima@gcc.gnu.org>
+ * config/sh/sh.h (GO_IF_LEGITIMATE_ADDRESS): Allow
+ (plus (plus (reg) (const_int)) (const_int)) when reload_in_progress.
+
+2008-07-19 Olivier Hainque <hainque@adacore.com>
+
+ * dwarf2out.c (add_subscript_info): New explicit COLLAPSE_P
+ argument, saying whether nested array are to be collapsed
+ into a single array type DIE with multiple subscripts.
+ (gen_array_type_die): Factorize comments about the MIPS_DEBUG_INFO
+ issues, centralize the nested array types collapsing control and
+ disable the transformation for Ada.
+
+2008-07-18 Uros Bizjak <ubizjak@gmail.com>
+
+ PR target/36786
+ * config/i386/i386.md (x86_64_shift_adj_1): Rename from
+ x86_64_shift_adj.
+ (x86_64_shift_adj_2): New expander.
+ (x86_64_shift_adj_3): Ditto.
+ * config/i386/i386.c (ix86_split_ashr): Use gen_x86_64_shift_adj_3
+ to split TImode operands.
+ (ix86_split_ashl): Use gen_x86_64_shift_adj_2 to split TImode operands.
+ (ix86_split_lshr): Ditto.
+
+2008-07-18 Kris Van Hees <kris.van.hees@oracle.com>
+
+ * c-common.c (c_stddef_cpp_builtins): Define __CHAR16_TYPE__
+ and __CHAR32_TYPE__.
+ * c-typeck.c (digest_init): Support char16_t and char32_t.
+ (set_nonincremental_init_from_string): Idem.
+
+2008-07-18 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR middle-end/36859
+ * builtins.c (std_gimplify_va_arg_expr): Limit alignment to
+ PREFERRED_STACK_BOUNDARY.
+ * config/i386/i386.c (ix86_gimplify_va_arg): Likewise.
+
+2008-07-18 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR middle-end/36858
+ * function.c (locate_and_pad_parm): Cap boundary earlier.
+
+2008-07-17 Julian Brown <julian@codesourcery.com>
+
+ * config/arm/arm.c (arm_cxx_determine_class_data_visibility): Make
+ no-op for targets which don't use DLLs.
+
+2008-07-17 Martin Jambor <mjambor@suse.cz>
+
+ * ipa-cp.c (ipcp_print_all_lattices): New variable info, check
+ that nodes are relevant by examining the node->analyzed flag.
+ (ipcp_init_stage): Check which nodes are relevant, assert that the
+ relevant ones are also required.
+ (ipcp_propagate_stage): Check on the side arrays are properly
+ allocated.
+ (ipcp_print_all_jump_functions): Make sure not to touch any node
+ that is not analyzed or an edge that does not have a corresponding
+ entry in the on-the-side vectors.
+ (ipcp_function_scale_print): Likewise.
+ (ipcp_update_callgraph): Check that the node is relevant.
+ (ipcp_insert_stage): Check that the node is relevant. Check there is
+ an info for every node and edge.
+ * ipa-prop.c (ipa_init_func_list): Check the nodes are relevant.
+ (ipa_print_all_tree_maps): Likewise and a new variable info.
+ (ipa_print_all_params_modified): Likewise.
+ * ipa-prop.h (ipa_edge_args_info_available_for_edge_p): New function.
+
+2008-07-17 Roman Zippel <zippel@linux-m68k.org>
+
+ PR target/25343
+ * config/host-linux.c (TRY_EMPTY_VM_SPACE): Define for __mc68000__.
+
+2008-07-17 Paolo Bonzini <bonzini@gnu.org>
+
+ PR rtl-optimization/36753
+ * fwprop.c (use_killed_between): Don't shortcut
+ single-definition global registers.
+
+2008-07-16 Jan Hubicka <jh@suse.cz>
+
+ * cgraph.h (varpool_empty_needed_queue): Declare.
+ * cgraphunit.c (output_in_order): Mark all variables as needed;
+ empty the queue.
+ * varpool.c (varpool_assemble_node): Update debug queue.
+ (varpool_assemble_pending_decls): Don't do it here.
+ (varpool_empty_needed_queue): New function.
+
+2008-07-16 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * recog.c (peephole2_optimize): Fix formatting.
+
+2008-07-16 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * c-pch.c (get_ident): Avoid C++ keywords.
+ * combine-stack-adj.c (single_set_for_csa): Likewise.
+ * final.c (asm_insn_count, final_scan_insn, alter_subreg,
+ output_asm_insn): Likewise.
+ * reload.c (push_secondary_reload, find_reusable_reload,
+ push_reload, combine_reloads, find_reloads,
+ debug_reload_to_stream): Likewise.
+ * reload.h (struct reload): Likewise.
+ * reload1.c (reload_reg_class_lower, find_reg, find_reload_regs,
+ allocate_reload_reg, choose_reload_regs, emit_input_reload_insns,
+ emit_output_reload_insns): Likewise.
+ * targhooks.c (default_secondary_reload): Likewise.
+ * varasm.c (section_entry_eq, object_block_entry_eq): Likewise.
+
+2008-07-16 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * recog.c (validate_change_1, validate_change,
+ validate_unshare_change, validate_replace_rtx_1, struct
+ funny_match, constrain_operands, peephole2_optimize): Avoid C++
+ keywords.
+ * reload.c (push_secondary_reload, secondary_reload_class,
+ scratch_reload_class, find_valid_class, find_reusable_reload,
+ push_reload, find_dummy_reload, find_reloads_address_1,
+ find_reloads_address_part, find_equiv_reg): Likewise.
+ * reload1.c (spill_failure, eliminate_regs_1, allocate_reload_reg,
+ choose_reload_regs): Likewise.
+ * rtlanal.c (replace_rtx, nonzero_bits1, num_sign_bit_copies1):
+ Likewise.
+ * rtlhooks.c (gen_lowpart_if_possible): Likewise.
+ * sched-ebb.c (add_deps_for_risky_insns): Likewise.
+ * sched-rgn.c (concat_INSN_LIST): Likewise.
+ * stor-layout.c (mode_for_size, mode_for_size_tree,
+ smallest_mode_for_size): Likewise.
+
+2008-07-16 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * cfg.c (dump_reg_info): Avoid C++ keywords.
+ * dwarf2asm.c (dw2_force_const_mem,
+ dw2_asm_output_encoded_addr_rtx): Likewise.
+ * except.c (gen_eh_region, add_action_record, output_ttype): Likewise.
+ * expmed.c (expand_shift): Likewise.
+ * global.c (find_reg): Likewise.
+ * graph.c (draw_edge): Likewise.
+ * local-alloc.c (reg_meets_class_p, find_free_reg): Likewise.
+ * optabs.c (expand_binop, expand_twoval_unop, expand_twoval_binop,
+ widen_clz, widen_bswap, expand_parity, expand_unop,
+ emit_cmp_and_jump_insn_1): Likewise.
+ * postreload.c (reload_cse_simplify_operands): Likewise.
+ * ra.h (add_neighbor): Likewise.
+ * reg-stack.c (remove_regno_note, change_stack): Likewise.
+ * regclass.c (memory_move_secondary_cost, dump_regclass, regclass,
+ record_reg_classes, copy_cost, record_address_regs,
+ invalid_mode_change_p): Likewise.
+ * regrename.c (regrename_optimize, scan_rtx_reg,
+ dump_def_use_chain, find_oldest_value_reg,
+ replace_oldest_value_reg, copyprop_hardreg_forward_1): Likewise.
+
+2008-07-16 David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/rs6000.c (processor_target_table): Remove duplicate
+ MASK_POWERPC64 for power4 in previous commit.
+
+2008-07-16 Olivier Hainque <hainque@adacore.com>
+
+ * collect2.c (scan_prog_file, COFF version): Use CONST_CAST
+ instead of bare conversion to cast const-ness away.
+
+2008-07-16 Anatoly Sokolov <aesok@post.ru>
+
+ * config/xtensa/xtensa.h (FUNCTION_OUTGOING_VALUE,
+ XTENSA_FUNCTION_VALUE, XTENSA_FUNCTION_VALUE): Remove.
+ * config/xtensa/xtensa.c (xtensa_function_value): New function.
+ (TARGET_FUNCTION_VALUE): Define.
+
+2008-07-16 David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/rs6000.c (processor_target_table): Add
+ MASK_PPC_GPOPT for power4, power5, power5+, power6, and power6x.
+
+2008-07-16 Joseph Myers <joseph@codesourcery.com>
+
+ PR target/36827
+ * config/m32c/m32c.c (BIG_FB_ADJ): Move definition earlier.
+ (m32c_legitimate_address_p): Handle "++rii" addresses created by
+ m32c_legitimize_reload_address.
+
+2007-07-16 Rafael Avila de Espindola <espindola@google.com>
+
+ * c-decl.c (merge_decls): Keep DECL_SOURCE_LOCATION and
+ DECL_IN_SYSTEM_HEADER in sync.
+
+2008-07-15 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-ssa-sccvn.c (expressions_equal_p): Check type equality.
+ * tree-ssa-pre.c (pre_expr_eq): Ditto
+ (get_constant_for_value_id): Take a type as an argument.
+ (fully_constant_expression): Pass in type.
+ (find_or_generate_expression): Short circuit constant case.
+ (create_expression_by_pieces): Remove special casing of
+ pointer_plus.
+ (do_regular_insertion): Short circuit constant case.
+ (do_partial_partial_insertion): Ditto.
+
+2008-07-15 Kaz Kojima <kkojima@gcc.gnu.org>
+
+ PR target/36782
+ * config/sh/sh.md (symGOT_load): Don't add REG_EQUAL note.
+
+2008-07-15 Bob Wilson <bob.wilson@acm.org>
+
+ * config/xtensa/libgcc-xtensa.ver: New file.
+ * config/xtensa/t-linux (SHLIB_MAPFILES): Append libgcc-xtensa.ver.
+
+2008-07-15 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * df-problems.c (df_set_note): Avoid C++ keywords.
+ * df-scan.c (df_ref_change_reg_with_loc_1): Likewise.
+ * dse.c (record_store, remove_useless_values): Likewise.
+ * emit-rtl.c (gen_reg_rtx, update_reg_offset, gen_rtx_REG_offset,
+ gen_reg_rtx_offset, operand_subword, change_address_1,
+ change_address, adjust_address_1, offset_address,
+ widen_memory_access, emit_copy_of_insn_after): Likewise.
+ * explow.c (round_push, allocate_dynamic_stack_space): Likewise.
+ * fwprop.c (should_replace_address, propagate_rtx_1,
+ propagate_rtx, try_fwprop_subst, forward_propagate_and_simplify):
+ Likewise.
+ * gcse.c (cprop_jump, find_implicit_sets, bypass_block,
+ gcse_emit_move_after, update_ld_motion_stores): Likewise.
+ * lcm.c (compute_insert_delete, pre_edge_lcm,
+ compute_rev_insert_delete, pre_edge_rev_lcm): Likewise.
+ * lower-subreg.c (resolve_reg_notes): Likewise.
+ * mode-switching.c (optimize_mode_switching): Likewise.
+
+2008-07-15 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * bt-load.c (add_btr_def, migrate_btr_def,
+ branch_target_load_optimize): Avoid C++ keywords.
+ * caller-save.c (insert_restore, insert_save, insert_one_insn):
+ Likewise.
+ * combine.c (subst, simplify_set, make_extraction,
+ make_compound_operation, known_cond, simplify_shift_const_1): Likewise.
+ * cse.c (make_regs_eqv, merge_equiv_classes, validate_canon_reg,
+ fold_rtx, equiv_constant, cse_insn, cse_process_notes_1): Likewise.
+
+2008-07-15 Richard Guenther <rguenther@suse.de>
+
+ PR middle-end/36369
+ * c-common.c (strict_aliasing_warning): Do not warn for
+ TYPE_REF_CAN_ALIAS_ALL pointers.
+ (c_common_get_alias_set): may_alias types are not special.
+ * tree.c (build_pointer_type_for_mode): Look up the may_alias
+ attribute and set can_ref_all accordingly.
+ (build_reference_type_for_mode): Likewise.
+ * doc/extend.texi (may_alias): Clarify.
+
+2008-07-15 Kaz Kojima <kkojima@gcc.gnu.org>
+
+ PR target/36780
+ * config/sh/sh.h (GO_IF_LEGITIMATE_ADDRESS): Allow
+ (plus (plus (reg) (const_int)) (const_int)) when reload_in_progress.
+
+2008-07-15 Andrew Pinski <andrew_pinski@playstation.sony.com>
+
+ PR target/31568
+ * config/rs6000/rs6000.c (print_operand <case 'y'>): Don't use
+ gcc_assert, instead call output_operand_lossage.
+
+2008-07-15 Kai Tietz <kai.tietz@onevision.com>
+
+ * builtins.c (std_canonical_va_list): Treat structure based
+ va_list types.
+
+2008-07-15 Ben Elliston <bje@au.ibm.com>
+
+ * emit-rtl.c (set_mem_attributes_minus_bitpos): Improve comment.
+
+2007-07-14 Rafael Avila de Espindola <espindola@google.com>
+
+ * c-decl.c (diagnose_mismatched_decls): Don't warn if TREE_NO_WARNING
+ is set.
+
+2008-07-14 Jan Hubicka <jh@suse.cz>
+
+ * i386.md (sse5 cmov pattern): Update call of ix86_sse5_valid_op_p
+ * sse.md (sse5 patterns): Update call of ix86_sse5_valid_op_p;
+ fix predicates and constraints.
+ * i386.c (ix86_sse5_valid_op_p): Add commutative parameter.
+ * i386-protos.h (ix86_sse5_valid_op_p): Update declaration.
+
+2008-07-14 Doug Kwan <dougkwan@google.com>
+
+ * config.gcc (arm*-*-eabi*): Include arm/eabi.h and use
+ additional option file arm/eabi.opt.
+ * config/arm/eabi.h (File): New configuration file for EABI targets.
+ * config/arm/elf.h (SUBTARGET_EXTRA_SPECS): Add
+ SUBSUBTARGET_EXTRA_SPECS.
+ (SUBSUBTARGET_EXTRA_SPECS): Provide empty default.
+ * config/arm/unknown-elf.h (UNKNOWN_ELF_STARTFILE_SPEC): Renamed
+ from STARTFILE_SPEC so that it can be referenced in an override.
+ (STARTFILE_SPEC): Use UNKNOWN_ELF_STARTFILE_SPEC.
+ (UNKNOWN_ELF_ENDFILE_SPEC): Renamed from ENDFILE_SPEC so that it
+ can be referenced in an override.
+ (ENDFILE_SPEC): Use UNKNOWN_ELF_ENDFILE_SPEC.
+ * config/arm/bpabi.h (BPABI_LINK_SPEC): Renamed from LINK_SPEC
+ so that it can be referenced in an override.
+ (LINK_SPEC): Use BPABI_LINK_SPEC.
+ * config/arm/eabi.opt (File): New.
+
+2008-07-14 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
+
+ * Makefile.in (TARGET_DEF_H): Add targhooks.h.
+ (FIXED_VALUE_H): New variable.
+ (RTL_BASE_H): Use $(INPUT_H) and $(FIXED_VALUE_H) instead of
+ input.h, fixed-value.h.
+ (TREE_H): Use $(INPUT_H), add $(SYMTAB_H).
+ (BASIC_BLOCK_H): Use $(BITMAP_H).
+ (FUNCTION_H): Add varray.h.
+ (IPA_REFERENCE_H): Use $(BITMAP_H).
+ (CGRAPH_H): Add $(BASIC_BLOCK_H).
+ (DF_H): Use $(BITMAP_H).
+ (GGC_H): Add statistics.h.
+ (INSN_ADDR_H): New.
+ (INSN_ATTR_H): Use it.
+ (SYSTEM_H): Add safe-ctype.h, filenames.h.
+ (INPUT_H): New.
+ (SYMTAB_H): Add $(OBSTACK_H).
+ (CPP_INTERNAL_H): New.
+ (TREE_DUMP_H): Add tree-pass.h.
+ (TREE_FLOW_H): Use $(BITMAP_H)
+ (PRETTY_PRINT_H): Use $(INPUT_H).
+ (EBITMAP_H): Rename from typo-ed EBIMAP_H.
+ (GSTAB_H): New.
+ (BITMAP_H): New.
+ (many object files): Fix lots of header dependencies throughout.
+
+2008-07-14 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
+
+ * Makefile.in (write_entries_to_file, write_entries_to_file_split):
+ New macros.
+ (s-gtyp-input): Use them to write tmp-gi.list.
+ (echo_to_gi.list): Remove.
+
+2008-07-14 Richard Guenther <rguenther@suse.de>
+
+ * tree-ssa-sccvn.c (pre_info): Remove.
+ (switch_to_PRE_table): Likewise.
+ (free_scc_vn): Do not clear SSA_NAME_VALUE. Do not free pre_info.
+ (set_hashtable_value_ids): Do not create value-ids for the
+ optimistic tables.
+ (run_scc_vn): Remove double test. Remove bogus special-case
+ in value-number printing.
+ * tree-ssa-sccvn.h (switch_to_PRE_table): Remove.
+ * tree-ssa-ccp.c (get_symbol_constant_value): Do not look at
+ SSA_NAME_VALUE.
+ * tree-flow-inline.h (get_value_handle): Remove.
+ * tree-flow.h (get_value_handle): Remove.
+
+2008-07-14 Martin Jambor <mjambor@suse.cz>
+
+ * tree-switch-conversion.c (gen_inbound_check): Make sure the type
+ in which we generate arithmetics is not a subrange.
+
+2008-07-14 Martin Jambor <mjambor@suse.cz>
+
+ * Makefile.in (IPA_PROP_H): Added ipa-prop.h to IPA_PROP_H variable.
+
+2008-07-14 Richard Guenther <rguenther@suse.de>
+
+ * tree-ssa-pre.c (insert_into_preds_of_block): Do not call convert.
+
+2008-07-14 Andreas Krebbel <krebbel1@de.ibm.com>
+
+ PR target/36745
+ * config/s390/s390.c: (s390_secondary_reload): Add a secondary
+ reload for symbol refs moved to r0 with -fPIC.
+ (legitimize_pic_address): Use the target register as temporary
+ reg if possible.
+ (emit_symbolic_move): Adjust comment.
+ * config/s390/s390.md (reloadsi_PIC_addr, reloaddi_PIC_addr):
+ New expanders.
+
+2008-07-14 Ben Elliston <bje@au.ibm.com>
+
+ * c-common.h (C_CPP_HASHNODE): New macro.
+ * coretypes.h (struct cpp_token): Forward declare.
+ * doc/extend.texi (PowerPC AltiVec Built-in Functions): Document
+ the context-sensitive keyword method.
+ * config/rs6000/rs6000-c.c (__vector_keyword, vector_keyword,
+ __pixel_keyword, pixel_keyword, __bool_keyword, bool_keyword,
+ expand_bool_pixel): New.
+ (altivec_categorize_keyword): New function.
+ (init_vector_keywords): New function.
+ (rs6000_macro_to_expand): Likewise.
+ (rs6000_cpu_cpp_builtins): Enable context-sensitive macros if not
+ compiling an ISO C dialect.
+
+2008-07-13 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-ssa-pre.c (fully_constant_expression): Add fold_convert calls.
+ (create_expression_by_pieces): Fix typo.
+ (do_regular_insertion): Use debug counter here too.
+
+2008-07-14 Hans-Peter Nilsson <hp@axis.com>
+
+ PR target/35492.
+ * config/cris/cris.h (CRIS_CONST_OK_FOR_LETTER_P): Renamed from
+ CONST_OK_FOR_LETTER_P. All port-local users changed.
+ (CONST_OK_FOR_CONSTRAINT_P): Define; implement Kc as old K,
+ implement Kp matching power-of-two.
+ (CONSTRAINT_LEN): Define to match.
+ * config/cris/cris.md: Replace all use of constraint K with Kc.
+ ("*btst*): Use Kp for operand 0 of last alternative.
+
+2008-07-13 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ PR testsuite/36440
+ * tree-call-cdce.c (check_target_format): Accept MIPS single, double
+ and quad formats.
+
+2008-07-13 Jan Hubicka <jh@suse.cz>
+
+ * tree.c (decl_assembler_name_equal): Expect assembler name of decl
+ to be mangled too.
+
+2008-07-13 Richard Guenther <rguenther@suse.de>
+
+ PR middle-end/36811
+ * langhooks.c (lhd_print_error_function): Deal with recursive
+ BLOCK trees.
+
+2008-07-12 Jan Hubicka <jh@suse.cz>
+
+ * cgraph.c (assembler_name_hash): New static var.
+ (hash_node_by_assembler_name, eq_assembler_name): New.
+ (cgraph_node_for_asm): Use hashtable.
+ (cgraph_remove_node): Maintain hashtable.
+ (change_decl_assembler_name): Sanity check that names are not changing
+ after aliasing was processed.
+ * cgraph.h (varpoon_node): Add next GGC marker.
+ * tree.c (decl_assembler_name_equal): Constify.
+ (decl_assembler_name_hash): New.
+ * tree.h (decl_assembler_name_equal): Constify.
+ (decl_assembler_name_hash): Update.
+
+2008-07-12 David Daney <ddaney@avtrex.com>
+
+ * config/mips/driver-native.c (host_detect_local_cpu): Handle
+ sb1 and r5000 cpus.
+
+2008-07-12 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * doc/md.texi: Document the MIPS "v" constraint.
+ * config/mips/mips.h (reg_class): Revert last change.
+ (REG_CLASS_NAMES): Likewise.
+ (REG_CLASS_CONTENTS): Likewise.
+ * config/mips/mips.c (mips_regno_to_class): Likewise.
+ * config/mips/constraints.md (v): Likewise, but add documentation.
+ Add a comment to say that this constraint should not be used in
+ gcc code.
+
+2008-07-11 DJ Delorie <dj@redhat.com>
+
+ * config/h8300/h8300.md (length): Fix branch offset limit.
+
+2008-07-11 Anatoly Sokolov <aesok@post.ru>
+
+ * config/avr/avr-protos.h (avr_peep2_scratch_safe): Remove prototype.
+ * config/avr/avr.c (avr_peep2_scratch_safe): Remove.
+ (avr_hard_regno_scratch_ok): New function.
+ (TARGET_HARD_REGNO_SCRATCH_OK): Define.
+ * config/avr/avr.md (all peepholes that request a scratch register):
+ Remove avr_peep2_scratch_safe use.
+
+2008-07-11 Tom Tromey <tromey@redhat.com>
+ Ian Lance Taylor <iant@google.com>
+
+ * c-common.h (enum rid): Add RID_CXX_COMPAT_WARN.
+ (struct c_common_resword): Define.
+ (D_CONLY, D_CXXONLY, D_C99, D_CXX0X, D_EXT, D_EXT89): Define.
+ (D_ASM, D_OBJC, D_CXX_OBJC, D_CXXWARN): Define.
+ (c_common_reswords, num_c_common_reswords): Declare.
+ * c-common.c (c_common_reswords): New global const array.
+ (num_c_common_reswords): New const int.
+ * c-parser.c (struct resword, reswords): Don't define.
+ (D_C89, D_EXT, D_EXT89, D_OBJC): Don't define.
+ (c_parse_init): Clarify mask code. Use c_common_reswords rather
+ than reswords. If warning about C++ keywords, give them a special
+ RID code.
+ (c_lex_one_token): Warn about C++ keywords. Call
+ objc_is_reserved_word rather than OBJC_IS_AT_KEYWORD.
+ (c_parser_external_declaration): Look for RID_xxx rather than
+ RID_AT_xxx, for ObjC++ keywords which are also C++ keywords.
+ (c_parser_statement_after_labels): Likewise.
+ (c_parser_objc_class_instance_variables): Likewise.
+ (c_parser_objc_class_declaration): Likewise.
+ (c_parser_objc_try_catch_statement): Likewise.
+ * c-decl.c (c_print_identifier): Ignore RID_CXX_COMPAT_WARN.
+ (declspecs_add_type): Likewise.
+
+2008-07-11 Angelo Graziosi <angelo.graziosi@alice.it>
+
+ * ggc-page.c (alloc_page):
+ Substituting xmalloc, xcalloc with
+ XNEWVEC and XCNEWVAR macros which add the
+ needed casts.
+
+2008-07-11 Richard Guenther <rguenther@suse.de>
+
+ PR tree-optimization/36765
+ * tree-ssa-alias.c (compute_flow_insensitive_aliasing): Add
+ aliases from HEAP vars to SMTs.
+
+2008-07-10 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * Makefile.in (LOOSE_WARN, STRICT_WARN): Update comments.
+ * configure.ac (loose_warn): Move -Wc++-compat from here...
+ (strict_warn): ...to here.
+ * configure: Regenerate.
+
+2008-07-10 Joseph Myers <joseph@codesourcery.com>
+
+ * config.gcc (arm-*-coff*, armel-*-coff*, h8300-*-*,
+ i[34567]86-*-aout*, i[34567]86-*-coff*, m68k-*-aout*,
+ m68k-*-coff*, sh-*-*, mips-sgi-irix[56]*, pdp11-*-bsd,
+ rs6000-ibm-aix4.[12]*, powerpc-ibm-aix4.[12]*): Deprecate targets,
+ excluding more specific h8300-*-* and sh-*-* targets.
+
+2008-07-10 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-ssa-pre.c (create_expression_by_pieces): Add fold_convert calls.
+ (eliminate): Ditto.
+ (execute_pre): Call loop_optimizer_finalize in early exit.
+
+2008-07-10 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/36790
+ * omp-low.c (lower_omp_2): If task_shared_vars, test all DECL_P
+ uids in the bitmap, not just VAR_DECL uids.
+
+ PR rtl-optimization/36419
+ * combine-stack-adj.c (adjust_frame_related_expr): New function.
+ (combine_stack_adjustments_for_block): Call it if needed. Delete
+ correct insn.
+ * dwarf2out.c (dwarf2out_frame_debug_expr): Adjust
+ DW_CFA_GNU_args_size if CSA pass merged some adjustments into
+ prologue sp adjustment.
+
+2008-07-10 Peter Maydell <pmaydell@chiark.greenend.org.uk>
+
+ PR other/28322
+ * opts.c (print_ignored_options): Report postponed diagnostics for
+ unknown -Wno-* options as warnings, not errors.
+ (postpone_unknown_option_error): Renamed to...
+ (postpone_unknown_option_warning): ... this.
+
+2008-07-09 Doug Kwan <dougkwan@google.com>
+
+ Revert:
+ 2008-07-08 Doug Kwan <dougkwan@google.com>
+
+ * config/arm/arm.opt (mandroid): New option.
+ * config/arm/bpabi.h (ANDROID_LINK_SPEC): New macro.
+ (LINK_SPEC): Enable Android specific behaviour when -mandroid is used.
+ (CC1_SPEC): Same.
+ (CC1PLUS_SPEC): Same.
+ (LIB_SPEC): Same.
+ (STARTFILE_SPEC): Same.
+ (ENDFILE_SPEC): Same.
+ (TARGET_BPABI_CPP_BUILTINS): Define __ANDROID__ when -mandroid is
+ used.
+
+2008-07-09 Richard Sandiford <rdsandiford@googlemail.com>
+
+ PR target/35802
+ * config/mips/mips.h (reg_class): Remove V1_REG.
+ (REG_CLASS_NAMES, REG_CLASS_CONTENTS): Update accordingly.
+ * config/mips/mips.c (mips_regno_to_class): Map $3 to M16_NA_REGS
+ instead of V1_REGS.
+ (mips_get_tp): New function.
+ (mips_legitimize_tls_address): Use it.
+ * config/mips/constraints.md (v): Delete.
+ * config/mips/mips.md (TLS_GET_TP_REGNUM): New constant.
+ (tls_get_tp_<mode>): Allow any GPR destination and clobber $3.
+ After reload, split into a move and ...
+ (*tls_get_tp_<mode>_split): ...this new instruction.
+
+2008-07-09 David Daney <ddaney@avtrex.com>
+
+ * config/mips/driver-native.c: Include coretypes.h and tm.h.
+
+2008-07-09 Jakub Jelinek <jakub@redhat.com>
+
+ * gimplify.c (struct gimplify_ctx): Move to tree-gimple.h.
+ (push_gimplify_context): Don't allocate temp_htab nor c itself here.
+ Add c argument.
+ (pop_gimplify_context): Check c->temp_htab instead of optimize whether
+ htab_delete should be called. Don't free c.
+ (lookup_tmp_var): Create temp_htab lazily.
+ (gimplify_scan_omp_clauses, gimplify_omp_parallel, gimplify_omp_task,
+ gimplify_body, force_gimple_operand): Adjust push_gimplify_context
+ callers.
+ * omp-low.c (lower_omp_sections, lower_omp_single, lower_omp_master,
+ lower_omp_ordered, lower_omp_critical, lower_omp_for,
+ create_task_copyfn, lower_omp_taskreg, execute_lower_omp):
+ * tree-ssa-ccp.c (convert_to_gimple_builtin): Likewise.
+ * tree-sra.c (generate_element_init): Likewise.
+ * tree-mudflap.c (execute_mudflap_function_ops,
+ execute_mudflap_function_decls): Likewise.
+ * tree-inline.c (setup_one_parameter, optimize_inline_calls): Likewise.
+ * tree-gimple.h (struct gimplify_ctx): New type.
+ (push_gimplify_context): Adjust prototype.
+
+2008-07-09 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree-ssa-pre.c (phi_translate_1): Update placement of
+ add_to_value calls.
+
+2008-07-09 Anatoly Sokolov <aesok@post.ru>
+
+ * target.h (struct gcc_target): Add hard_regno_scratch_ok field.
+ * target-def.h (TARGET_HARD_REGNO_SCRATCH_OK): New.
+ (TARGET_INITIALIZER): Use TARGET_HARD_REGNO_SCRATCH_OK.
+ * targhooks.c (default_hard_regno_scratch_ok): New function.
+ * targhooks.h (default_hard_regno_scratch_ok): Declare function.
+ * doc/tm.texi: Document TARGET_HARD_REGNO_SCRATCH_OK hook.
+ * recog.c: Include "target.h".
+ (peep2_find_free_register): Add check for global regs. Add target
+ specific check.
+ * Makefile.in (recog.o): Depend on target.h.
+
+2008-07-09 Kaz Kojima <kkojima@gcc.gnu.org>
+
+ * config/sh/sh.c (sh_canonical_va_list_type): New.
+ (TARGET_CANONICAL_VA_LIST_TYPE): Define.
+
+2008-07-09 Raksit Ashok <raksit@google.com>
+
+ * doc/invoke.texi (Option Summary): Mention new option
+ -Wdisallowed-function-list=...
+ (Warning Options): Document -Wdisallowed-function-list=...
+ * common.opt (Wdisallowed-function-list=): New flag.
+ * flags.h (warn_disallowed_functions): External definition of new
+ boolean warning flag.
+ (warn_if_disallowed_function_p): Declare new function.
+ * opts.c (warning_disallowed_functions): New static variable.
+ (warn_disallowed_functions): New boolean warning flag.
+ (warn_if_disallowed_function_p): New function.
+ (add_comma_separated_to_vector): Rename
+ add_instrument_functions_exclude_list to this.
+ (common_handle_option): Handle new option. Rename calls to
+ add_instrument_functions_exclude_list into calls to
+ add_comma_separated_to_vector.
+ * c-parser.c (c_parser_postfix_expression_after_primary): New warning
+ based on flag warn_disallowed_functions.
+
+2008-07-09 Christian Bruel <christian.bruel@st.com>
+
+ * final.c (get_attr_length_1): Call get_attr_length_1 with fallback_fn
+ instead of get_attr_length.
+
+2008-07-09 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * genattrtab.c (insert_right_side, evaluate_eq_attr): Avoid C++
+ keywords.
+ * genemit.c (gen_insn): Likewise.
+ * gengtype.c (note_def_vec): Likewise.
+ * gengtype.h (note_def_vec): Likewise.
+ * genoutput.c (struct data, output_insn_data, process_template,
+ gen_expand, gen_split, note_constraint): Likewise.
+ * genrecog.c (new_decision, add_to_sequence, factor_tests,
+ make_insn_sequence): Likewise.
+ * gensupport.c (record_insn_name): Likewise.
+
+2008-07-08 Doug Kwan <dougkwan@google.com>
+
+ * config/arm/arm.opt (mandroid): New option.
+ * config/arm/bpabi.h (ANDROID_LINK_SPEC): New macro.
+ (LINK_SPEC): Enable Android specific behaviour when -mandroid is used.
+ (CC1_SPEC): Same.
+ (CC1PLUS_SPEC): Same.
+ (LIB_SPEC): Same.
+ (STARTFILE_SPEC): Same.
+ (ENDFILE_SPEC): Same.
+ (TARGET_BPABI_CPP_BUILTINS): Define __ANDROID__ when -mandroid is
+ used.
+
+2008-07-08 Raksit Ashok <raksit@google.com>
+
+ * expr.c (emit_block_move_via_movmem): Fix expected_align parameter.
+ (set_storage_via_setmem): Fix expected_align parameter.
+ * doc/invoke.texi (i386 and x86-64 Options): Add a couple of options
+ missing from the list.
+ * doc/md.texi (movmem): Explicitly state that expected alignment is
+ to be expressed in bytes.
+ (setmem): Explicitly state that expected alignment is to be expressed
+ in bytes.
+
+2008-07-08 Joseph Myers <joseph@codesourcery.com>
+
+ * reload.c (find_reloads_subreg_address): Do not require validity
+ of address in original mode before reloading address.
+
+2008-07-07 Tianwei Sheng <tianweis@google.com>
+
+ * df-core.c (df_remove_problem): Adjust the access to avoid out of
+ bounds array access.
+
+2008-07-08 Jakub Jelinek <jakub@redhat.com>
+
+ * tree-sra.c (sra_build_assignment): Handle CONVERT_EXPR_P dst.
+
+2008-07-05 Daniel Berlin <dberlin@dberlin.org>
+
+ Fix PR tree-optimization/23455
+ Fix PR tree-optimization/35286
+ Fix PR tree-optimization/35287
+ * Makefile.in (OBJS-common): Remove tree-vn.o.
+ (tree-vn.o): Remove.
+ * dbgcnt.def: Add treepre_insert debug counter.
+ * gcc/tree-flow.h (add_to_value): Updated for other changes.
+ (debug_value_expressions): Ditto.
+ (print_value_expressions): Ditto.
+ * tree-pretty-print.c (dump_generic_node): Updated for
+ VALUE_HANDLE removal.
+ * tree-ssa-dom.c (record_equality): Ditto.
+ (cprop_operand): Ditto.
+ (lookup_avail_expr): Ditto.
+ * tree-ssa-threadedge.c
+ (record_temporary_equivalences_from_stmts_at_dest): Ditto.
+ (simplify_control_stmt_condition): Ditto.
+ * tree.c (tree_code_size): Ditto.
+ (tree_node_structure): Ditto.
+ (iterative_hash_expr): Ditto.
+ * tree.def: Ditto.
+ * tree.h (VALUE_HANDLE_ID): Ditto.
+ (VALUE_HANDLE_EXPR_SET): Ditto.
+ (struct tree_value_handle): Ditto.
+ (union tree_node): Ditto.
+ * treestruct.def: Ditto.
+ * tree-vn.c: Removed.
+ * tree-ssa-pre.c: Rewritten entirely.
+ * tree-ssa-sccvn.c (constant_to_value_id): New hashtable.
+ (constant_value_ids): Ditto.
+ (vn_nary_op_t): Moved to header.
+ (vn_phi_t): Ditto.
+ (vn_reference_op_t): Ditto
+ (vn_reference_t): Ditto.
+ (next_value_id): New variable.
+ (VN_INFO): Add an assert.
+ (vn_constant_eq): New function.
+ (vn_constant_hash): Ditto.
+ (get_or_alloc_constant_value_id): Ditto.
+ (value_id_constant_p): Ditto.
+ (vn_reference_compute_hash): De-staticify.
+ (copy_reference_ops_from_ref): Don't use get_callee_fndecl.
+ Disable some code with a FIXME. Remove VALUE_HANDLE use.
+ (valueize_refs): Update opcode if it changes from ssa name to constant.
+ (vn_reference_lookup_1): Add new argument.
+ (vn_reference_lookup): Ditto.
+ (vn_reference_lookup_pieces): New function.
+ (vn_reference_insert): Add return type. Modify to deal with value ids.
+ (vn_reference_insert_pieces): New function.
+ (vn_nary_op_compute_hash): De-staticify.
+ (vn_nary_op_eq): Ditto.
+ (vn_nary_op_lookup_pieces): New function.
+ (vn_nary_op_lookup): Add new argument.
+ (vn_nary_op_insert_pieces): New function.
+ (vn_nary_op_insert): Add return type. Modify to deal with value ids.
+ (vn_phi_insert): Ditto.
+ (visit_unary_op): Update for callee changes.
+ (visit_binary_op): Ditto.
+ (visit_reference_op_load): Ditto.
+ (visit_reference_op_store): Ditto.
+ (init_scc_vn): Init next_value_id, constant_to_value_id and
+ constant_value_ids.
+ (free_scc_vn): Free them.
+ (set_hashtable_value_ids): New function.
+ (run_scc_vn): Use it.
+ (get_max_value_id): New function.
+ (get_next_value_id): Ditto.
+ (expressions_equal_p): Moved from tree-vn.c
+ (sort_vuses): Ditto.
+ (sort_vuses_heap): Ditto.
+ * tree-ssa-sccvn.h: Structures moved from tree-ssa-sccvn.c (noted
+ above).
+ * tree.c (iterative_hash_hashval_t): Made non-static
+ * tree.h (iterative_hash_hashval_t): Declare it.
+
+2008-07-08 Martin Jambor <mjambor@suse.cz>
+
+ * ipa-cp.c (ipcp_init_cloned_node): Call ipa_check_create_node_params
+ instead of ipa_create_node_params.
+ (ipcp_driver): Allocate infos with ipa_check_create_node_params and
+ ipa_check_create_edge_args, free them with
+ free_all_ipa_structures_after_ipa_cp, call ipa_register_cgraph_hooks.
+
+ * ipa-prop.c: Include flags.h and tree-inline.h.
+ (ipa_node_params_vector): New variable.
+ (ipa_edge_args_vector): New variable.
+ (edge_removal_hook_holder): New variable.
+ (node_removal_hook_holder): New variable.
+ (edge_duplication_hook_holder): New variable.
+ (node_duplication_hook_holder): New variable.
+ (ipa_detect_param_modifications): Check for presence of modified flags.
+ (ipa_compute_jump_functions): Check for presence of jump functions.
+ (ipa_free_edge_args_substructures): New function.
+ (ipa_create_node_params): Removed.
+ (ipa_free_all_edge_args): Changed to deallocate the on-the-side vector.
+ (ipa_free_node_params_substructures): New function.
+ (ipa_free_all_node_params): Changed to deallocate the on-the-side
+ vector.
+ (ipa_edge_removal_hook): New function.
+ (ipa_node_removal_hook): New function.
+ (duplicate_array): New function.
+ (ipa_edge_duplication_hook): New function.
+ (ipa_node_duplication_hook): New function.
+ (ipa_register_cgraph_hooks): New function.
+ (ipa_unregister_cgraph_hooks): New function.
+ (free_all_ipa_structures_after_ipa_cp): New function.
+
+ * ipa-prop.h: Include vec.h.
+ (ipa_node_params_t): New typedef with vector types for it.
+ (ipa_edge_args_t): New typedef with vector types for it.
+ (IPA_NODE_REF): Changed to access an on-the-side vector.
+ (IPA_EDGE_REF): Changed to access an on-the-side vector.
+ (ipa_check_create_node_params): New function.
+ (ipa_check_create_edge_args): New function.
+
+ * Makefile.in (IPA_PROP_H): New variable for ipa-prop.h. Converted
+ all users.
+
+2008-07-07 Tom Tromey <tromey@redhat.com>
+
+ * configure, config.in: Rebuilt.
+ * configure.ac: Don't check for scandir or alphasort.
+
+2008-07-07 Joseph Myers <joseph@codesourcery.com>
+
+ * config/arm/arm.c (arm_init_neon_builtins): Register built-in
+ types immediately after creating them.
+
+2008-07-07 Joseph Myers <joseph@codesourcery.com>
+
+ * config/arm/aout.h (DOLLARS_IN_IDENTIFIERS): Remove.
+
+2008-07-07 Fernando Pereira <fernando@cs.ucla.edu>
+
+ * tree-ssa-structalias.c (compute_points_to_sets): Add call to
+ dump_constraint_graph.
+ (dump_constraint_edge): New function.
+ (dump_constraint_graph): New function.
+ (debug_constraint_graph): New function.
+ (dump_constraint): Removed useless comparison.
+ * tree-ssa-structalias.h (dump_constraint_edge): Declare.
+ (dump_constraint_graph): Declare.
+ (debug_constraint_graph): Declare.
+ * tree-dump.c (struct dump_option_value_info): Declare TDF_GRAPH.
+
+2008-07-07 Kai Tietz <kai.tietz@onevision.com>
+
+ * config/i386/i386.c (is_va_list_char_pointer): New.
+ (ix86_va_start): Replace compare with ms_va_list_type_node
+ by is_va_list_char_pointer.
+ (ix86_gimplify_va_arg): Likewise.
+
+2008-07-07 Martin Jambor <mjambor@suse.cz>
+
+ * cgraph.c (cgraph_edge_max_uid): New variable.
+ (struct cgraph_edge_hook_list): New type.
+ (struct cgraph_node_hook_list): New type.
+ (struct cgraph_2edge_hook_list): New type.
+ (struct cgraph_2node_hook_list): New type.
+ (first_cgraph_edge_removal_hook): New variable.
+ (first_cgraph_node_removal_hook): New variable.
+ (first_cgraph_edge_duplicated_hook): New variable.
+ (first_cgraph_node_duplicated_hook): New variable.
+ (cgraph_add_edge_removal_hook): New function.
+ (cgraph_remove_edge_removal_hook): New function.
+ (cgraph_call_edge_removal_hooks): New function.
+ (cgraph_add_node_removal_hook): New function.
+ (cgraph_remove_node_removal_hook): New function.
+ (cgraph_call_node_removal_hooks): New function.
+ (cgraph_add_edge_duplication_hook): New function.
+ (cgraph_remove_edge_duplication_hook): New function.
+ (cgraph_call_edge_duplication_hooks): New function.
+ (cgraph_add_node_duplication_hook): New function.
+ (cgraph_remove_node_duplication_hook): New function.
+ (cgraph_call_node_duplication_hooks): New function.
+ (cgraph_create_edge): Assign to edge uid.
+ (cgraph_remove_edge): Call edge removal hooks.
+ (cgraph_node_remove_callees): Call edge removal hooks.
+ (cgraph_node_remove_callers): Call edge removal hooks.
+ (cgraph_remove_node): Call node removal hooks.
+ (cgraph_clone_edge): Call edge duplication hooks.
+ (cgraph_clone_node): Call node duplication hooks.
+
+ * cgraph.h (cgraph_edge): New field uid.
+ (cgraph_edge_hook): New type.
+ (cgraph_node_hook): New type.
+ (cgraph_2edge_hook): New type.
+ (cgraph_2node_hook): New type.
+
+2008-07-07 Andreas Tobler <a.tobler@schweiz.org>
+
+ * config.in: Regenerate.
+
+2008-07-07 Vladimir Prus <vladimir@codesourcery.com>
+
+ * gcc.c (print_sysroot): New.
+ (option_map, display_help, process_command): Handle the
+ -print-sysroot option.
+ (main): Print the sysroot if requested.
+ * doc/invoke.texi (Debugging Options): Document -print-sysroot.
+
+2008-07-07 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
+
+ PR target/34780
+ * unwind-pe.h (size_of_encoded_value): add attribute unused.
+
+2008-07-07 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * function.c (assign_parm_remove_parallels): Check mode of entry_parm.
+ (assign_parm_setup_block_p): Also check mode of entry_parm.
+
+2008-07-07 Richard Guenther <rguenther@suse.de>
+
+ * tree-ssa-structalias.h (set_used_smts): Remove.
+ * tree-ssa-structalias.c (used_smts): Likewise.
+ (set_used_smts): Likewise.
+ * tree-ssa-alias.c (compute_flow_sensitive_aliasing): Remove
+ call to set_used_smts.
+
+2008-07-07 Richard Guenther <rguenther@suse.de>
+
+ * tree-ssa-structalias.c (struct variable_info): Add is_full_var flag.
+ (new_var_info): Set it to false.
+ (solution_set_add): Correctly handle pointers outside a var and
+ inside a field.
+ (type_safe): Treat variables with is_full_var properly.
+ (do_sd_constraint): Likewise.
+ (do_ds_constraint): Likewise.
+ (process_constraint): Remove zeroing offset for !use_field_sensitive.
+ (get_constraint_for_ptr_offset): New function.
+ (get_constraint_for_component_ref): For addresses at least include
+ the last field of the variable. Handle is_full_vars properly.
+ (get_constraint_for_1): Factor common code, handle POINTER_PLUS_EXPR.
+ (handle_ptr_arith): Remove.
+ (find_func_aliases): Simplify assignment handling.
+ (create_function_info_for): For parameter and result varinfos set
+ is_full_var flag.
+ (create_variable_info_for): Set is_full_var flag whenever we
+ just created a single varinfo for a decl.
+ (init_alias_vars): Initialize use_field_sensitive from
+ max-fields-for-field-sensitive parameter.
+
+2008-07-07 Richard Guenther <rguenther@suse.de>
+
+ PR tree-optimization/36713
+ * tree-flow-inline.h (is_call_used): New function.
+ * tree-nrv.c (dest_safe_for_nrv_p): Use it.
+ * tree-tailcall.c (suitable_for_tail_opt_p): Likewise.
+ * tree-outof-ssa.c (create_temp): Set call-used flag if required.
+
+2008-07-07 Maxim Kuvyrkov <maxim@codesourcery.com>
+
+ * config/m68k/m68k.c (m68k_return_in_memory): Fix arguments types.
+
+2008-07-07 Mark Shinwell <shinwell@codesourcery.com>
+
+ * config/m68k/lb1sf68.asm: Add PIC macros for Linux targets.
+
+2008-07-07 Maxim Kuvyrkov <maxim@codesourcery.com>
+ Nathan Sidwell <nathan@codesourcery.com>
+
+ * config.gcc (m68k-*-linux*): Add with_arch. Add sysroot-suffix.h
+ to tm_file. Add m68k/t-floatlib, m68k/t-linux & m68k/t-mlibs to
+ tmake_file.
+ * config/m68k/t-linux: New.
+ * doc/install.texi: Document m68k-*-linux is now multilibbed by
+ default.
+
+2008-07-07 Nathan Sidwell <nathan@codesourcery.com>
+
+ * config/m68k/t-cf (MULTILIB_EXTRA_OPTS): Add no-mac.
+ * config/m68k/m68k-devices.def: Remove multilibs that only differ
+ by MAC/EMAC.
+
+2008-07-06 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * gcc.c (execute): Fix -Wc++-compat warning.
+
+2008-07-06 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR target/36720
+ * config/ia64/ia64.c (ia64_split_tmode): Fix typo in TImode
+ constant for little endian.
+
+2008-07-06 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * config/mips/mips.h (TARGET_CPU_CPP_BUILTINS): Check
+ mips_base_mips16 instead of TARGET_MIPS16.
+ (mips_base_mips16): Declare.
+ * config/mips/mips.c (mips_base_mips16): Make global.
+ (was_mips16_p): Remove GTY marker.
+ (was_mips16_pch_p): New variable.
+ (mips_set_mips16_mode): Check both was_mips16_p and was_mips16_pch_p.
+ (mips_override_options): Force to non-MIPS16 mode initially.
+ Do not complain about MIPS16 PIC incompatibilities here.
+ Only allow -mgpopt if -mexplicit-relocs is in force for
+ non-MIPS16 code.
+
+2008-07-06 Andreas Tobler <a.tobler@schweiz.org>
+
+ * configure.ac: Check for caddr_t, define to char * if not defined.
+ * configure: Regenerate.
+ * ggc-common.c (mmap_gt_pch_get_address): Fix -Wc++-compat warnings.
+ (mmap_gt_pch_use_address): Likewise.
+ * config/host-solaris.c (sol_gt_pch_use_address): Likewise.
+
+2008-07-06 Richard Guenther <rguenther@suse.de>
+
+ * tree-ssa-structalias.c (struct variable_info): Remove has_union.
+ (new_var_info): Deal with it.
+ (solution_set_add): Likewise.
+ (bitpos_of_field): Make signed, fix.
+ (struct fieldoff): Remove type and decl fields. Make size field
+ unsigned HOST_WIDE_INT. Add has_unknown_size and may_have_pointers
+ flags.
+ (fieldoff_compare): Deal with it.
+ (push_fields_onto_fieldstack): Remove has_union argument, glob
+ adjacent non-pointer fields together.
+ (create_function_info_for): Do not set has_union.
+ (create_variable_info_for): Simplify.
+
+2008-07-06 Kai Tietz <kai.tietz@onevision.com>
+
+ * config.gcc (extra_headers): Add cross-stdarg.h for target
+ x86_64-*-* and i?86-*-*.
+ * config/i386/cross-stdarg.h: New.
+ * builtins.c (std_fn_abi_va_list): New.
+ (std_canonical_va_list_type): New.
+ (stabilize_va_list): Replace va_list_type_node use by
+ mtarget.canonical_va_list_type.
+ (gimplify_va_arg_expr): Likewise.
+ (expand_builtin_va_copy): Replace va_list_type_node use by
+ mtarget.fn_abi_va_list.
+ * tree-sra.c (is_va_list_type): New helper.
+ (decl_can_be_decomposed_p): Replace
+ va_list_type_node use by is_va_list_type.
+ * tree-ssa-ccp.c (optimize_stdarg_builtin): Likewise.
+ * tree-stdarg.c (execute_optimize_stdarg): Likewise.
+ * c-common.c (c_common_nodes_and_builtins): Use TARGET_ENUM_VA_LIST.
+ * config/i386/i386-protos.h (ix86_get_valist_type): New.
+ (ix86_enum_va_list): New.
+ * config/i386/i386.c (sysv_va_list_type_node): New.
+ (ms_va_list_type_node): New.
+ (ix86_function_type_abi): Remove sorry.
+ (ix86_build_builtin_va_list_abi): New.
+ (ix86_build_builtin_va_list): Call ix86_build_builtin_va_list_abi
+ for 64-bit targets.
+ (ix86_va_start): Replace va_list_type_node by sysv_va_list_type_node.
+ (ix86_init_builtins_va_builtins_abi): New.
+ (ix86_init_builtins): Use ix86_init_builtins_va_builtins_abi
+ for 64-bit targets.
+ (ix86_handle_abi_attribute): New.
+ (attribute_spec): Add sysv_abi and ms_abi.
+ (ix86_fn_abi_va_list): New.
+ (ix86_canonical_va_list_type): New.
+ (ix86_enum_va_list): New.
+ (TARGET_FN_ABI_VA_LIST): New.
+ (TARGET_CANONICAL_VA_LIST_TYPE): New.
+ * config/i386/i386.h (TARGET_ENUM_VA_LIST): New.
+ * doc/tm.texi (TARGET_FN_ABI_VA_LIST): New.
+ (TARGET_CANONICAL_VA_LIST_TYPE): New.
+ (TARGET_ENUM_VA_LIST): New.
+ * expr.h (std_fn_abi_va_list): New.
+ (std_canonical_va_list_type): New.
+ * target-def.h (TARGET_FN_ABI_VA_LIST): New.
+ (TARGET_CANONICAL_VA_LIST_TYPE): New.
+ (TARGET_INITIALIZER): Add TARGET_FN_ABI_VA_LIST and
+ TARGET_CANONICAL_VA_LIST_TYPE.
+ * target.h (struct gcc_target): Add fn_abi_va_list hook
+ and canonical_va_list_type hook.
+
+2008-07-05 Andrew Pinski <andrew_pinski@playstation.sony.com>
+
+ * fold-const.c (fold_convert_const): Treat OFFSET_TYPE the same as
+ integral and pointer types.
+
+2008-07-04 Roger Sayle <roger@eyesopen.com>
+
+ * config/rs6000/host-darwin.c (darwin_rs6000_extra_signals): Cast
+ the "void*" result of xmalloc to "char*" to fix bootstrap breakage.
+
+2008-07-04 Kaz Kojima <kkojima@gcc.gnu.org>
+
+ PR target/36684
+ * config/sh/sh.h (OVERRIDE_OPTIONS): Disable -fschedule-insns for PIC.
+
+2008-07-04 Jakub Jelinek <jakub@redhat.com>
+
+ * tree-switch-conversion.c (build_one_array, gen_def_assigns): Use
+ build_gimple_modify_stmt.
+ (build_arrays, gen_inbound_check): Likewise. Force RHS to be
+ gimple operand. Use fold_build* instead of build*.
+
+2008-07-04 Richard Guenther <rguenther@suse.de>
+
+ * tree-ssa-structalias.c (lookup_vi_for_tree): Declare.
+ (do_sd_constraint): Handle a dereference of ESCAPED and CALLUSED
+ properly to compute the reachability set if we do field-sensitive PTA.
+ * invoke.texi (max-fields-for-field-sensitive): Document default.
+ * opts.c (decode_options): Set max-fields-for-field-sensitive to
+ 100 for optimize >= 2.
+
+2008-07-04 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * ggc-zone.c (lookup_page_table_if_allocated,
+ set_page_table_entry, zone_find_object_size, alloc_small_page,
+ alloc_large_page, ggc_free, gt_ggc_m_S, ggc_marked_p, init_ggc,
+ new_ggc_zone, init_ggc_pch, ggc_pch_this_base, ggc_pch_read): Fix
+ -Wc++-compat and/or -Wcast-qual warnings.
+
+2008-07-04 Alan Modra <amodra@bigpond.net.au>
+
+ PR target/36634
+ * config/rs6000/rs6000.md (call, call_value): Don't arrange for
+ pic_offset_table_rtx to be marked as used here.
+ (call_nonlocal_sysv, call_value_nonlocal_sysv): Add split for
+ TARGET_SECURE_PLT to "use" pic_offset_table_rtx.
+ (call_nonlocal_sysv_secure, call_value_nonlocal_sysv_secure): New insn.
+ (sibcall_nonlocal_sysv, sibcall_value_nonlocal_sysv): Assert
+ !TARGET_SECURE_PLT.
+
2008-07-15 Vladimir Makarov <vmakarov@redhat.com>
- * caller-save.c (calculate_local_save_info): Clear save)in,
+ * caller-save.c (calculate_local_save_info): Clear save_in,
restore_out, free_in.
2008-07-14 Vladimir Makarov <vmakarov@redhat.com>
@@ -5747,8 +7989,7 @@
Likewise.
* ggc-common.c (hash_descriptor, eq_descriptor, hash_ptr, eq_ptr,
loc_descriptor, ggc_prune_ptr, ggc_free_overhead,
- final_cmp_statistic, cmp_statistic, dump_ggc_loc_statistics):
- Likewise.
+ final_cmp_statistic, cmp_statistic, dump_ggc_loc_statistics): Likewise.
* varray.c (hash_descriptor, eq_descriptor, varray_descriptor):
Likewise.
diff --git a/gcc/ChangeLog.tuples b/gcc/ChangeLog.tuples
new file mode 100644
index 00000000000..d5e338368b5
--- /dev/null
+++ b/gcc/ChangeLog.tuples
@@ -0,0 +1,8231 @@
+2008-07-28 Richard Guenther <rguenther@suse.de>
+
+ Merge with mainline @138201.
+
+ * configure.ac (ACX_PKGVERSION): Update revision merge string.
+ * configure: Regenerate.
+
+2008-07-27 Jakub Jelinek <jakub@redhat.com>
+
+ * omp-low.c (expand_omp_atomic_fetch_op): Fix a merge glitch.
+
+2008-07-27 Andrew Pinski <andrew_pinski@playstation.sony.com>
+
+ * config/spu/spu.c (spu_gimplify_va_arg_expr): Unshare the args
+ and skip trees.
+
+2008-07-27 Richard Guenther <rguenther@suse.de>
+
+ * tree-eh.c (lookup_expr_eh_region): Do not allocate a tree
+ annotation.
+ * tree-dfa.c (create_tree_common_ann): Set eh region to -1.
+ * tree-flow.h (struct tree_ann_common_d): Reorder rn member
+ to pack with type.
+
+2008-07-26 Richard Guenther <rguenther@suse.de>
+
+ Merge with mainline @138159.
+
+ * configure.ac (ACX_PKGVERSION): Update revision merge string.
+ * configure: Regenerate.
+
+2008-07-26 Richard Guenther <rguenther@suse.de>
+
+ * gimple.h (CALL_STMT_CANNOT_INLINE_P): Remove.
+
+2008-07-26 Jan Hubicka <jh@suse.cz>
+
+ * ipa-inline.c (cgraph_decide_inlining_of_small_function): Use
+ gimple_call_set_cannot_inline.
+ (cgraph_decide_inlining): Likewise.
+ (cgraph_decide_inlining_incrementally): Likewise.
+
+2008-07-26 Richard Guenther <rguenther@suse.de>
+
+ Merge with mainline @138092.
+
+ * configure.ac (ACX_PKGVERSION): Update revision merge string.
+ * configure: Regenerate.
+
+2008-07-26 Richard Guenther <rguenther@suse.de>
+
+ Merge with mainline @138091.
+
+2008-07-25 Richard Guenther <rguenther@suse.de>
+
+ * config/ia64/ia64.c (ia64_gimplify_va_arg): Unshare valist
+ before reusing it.
+
+2008-07-25 Andreas Krebbel <krebbel1@de.ibm.com>
+
+ * tree-tailcall.c (process_assignment): Prevent tail call
+ optimization if the modes of the return types don't match.
+
+2008-07-24 Aldy Hernandez <aldyh@redhat.com>
+
+ * tree-inline.c (expand_call_inline): Allow casts in assert.
+
+2008-07-24 Richard Guenther <rguenther@suse.de>
+
+ PR middle-end/36885
+ * tree.c (walk_tree_1): Also walk CHANGE_DYNAMIC_TYPE_EXPR operands.
+ * gimple.c (gss_for_code): GIMPLE_CHANGE_DYNAMIC_TYPE is GSS_WITH_OPS.
+ * gsstruct.def (GSS_CHANGE_DYNAMIC_TYPE): Remove.
+
+2008-07-24 Richard Guenther <rguenther@suse.de>
+
+ * tree-sra.c (sra_walk_expr): Also handle CONVERT_EXPR.
+ (sra_walk_gimple_assign): Correctly detect assigns we can handle.
+ * expr.c (expand_expr_real_1): Pass MOVE_NONTEMPORAL to
+ expand_assignment.
+
+2008-07-23 Richard Guenther <rguenther@suse.de>
+
+ * tree-ssa-dse.c (get_kill_of_stmt_lhs): Tuplify correct.
+ * gimple-pretty-print.c (dump_gimple_label): Dump non-local flag.
+ * tree.h (maybe_fold_stmt_addition): Declare.
+ * tree-ssa-ccp.c (maybe_fold_stmt_addition): Export.
+ (fold_gimple_assign): Return the new rhs instead of modifying the stmt.
+ (fold_stmt): Deal with that.
+ (fold_stmt_inplace): Only replace the rhs of a statement if
+ that has enough operand space to hold the new operands.
+ * tree-ssa-forwprop.c (forward_propagate_addr_expr_1): Fix
+ POINTER_PLUS_EXPR handling.
+
+2008-07-23 Richard Guenther <rguenther@suse.de>
+
+ * tree-eh.c (record_in_goto_queue): Fix bootstrap with
+ --disable-checking.
+
+2008-07-23 Aldy Hernandez <aldyh@redhat.com>
+
+ Merge with mainline @138071.
+
+ * configure.ac (ACX_PKGVERSION): Update revision merge string.
+ * configure: Regenerate.
+
+2008-07-23 Richard Guenther <rguenther@suse.de>
+
+ * tree-eh.c (union treemple): Add tree * member.
+ (find_goto_replacement): Adjust.
+ (replace_goto_queue_cond_clause): Use the address of the
+ individual labels as unique identifier.
+ (replace_goto_queue_1): Use the statement as unique identifier
+ for GIMPLE_GOTO.
+ (record_in_goto_queue): Add checking.
+ (record_in_goto_queue_label): Adjust.
+ (maybe_record_in_goto_queue): Likewise.
+ (do_goto_redirection): Get leh_tf_state.
+ (lower_try_finally_nofallthru): Pass it.
+ (lower_try_finally_onedest): Likewise.
+ (lower_try_finally_copy): Likewise.
+ (lower_try_finally_switch): Likewise.
+
+2008-07-22 Aldy Hernandez <aldyh@redhat.com>
+ Jakub Jelinek <jakub@redhat.com>
+
+ * gimplify.c (gimple_do_not_emit_location_p): New.
+ (gimple_set_do_not_emit_location): New.
+ (annotate_one_with_location): Do not annotate if
+ gimple_do_not_emit_location_p.
+ (gimplify_cond_expr): Do not optimize if the COND_EXPR and
+ GOTO_EXPR have different locations.
+ Do not emit location information for some GIMPLE_COND's.
+
+2008-07-22 Richard Guenther <rguenther@suse.de>
+
+ * tree-ssa-ccp.c (ccp_fold): Use gimple_expr_type.
+ (fold_gimple_assign): Likewise.
+ * tree-inline.c (remap_gimple_op_r): Do not set TREE_BLOCK on
+ non-statements. Recurse to copy_tree_body_r with NULL block.
+ (copy_phis_for_bb): Likewise.
+ * tree-cfg.c (move_stmt_op): Do not set TREE_BLOCK on
+ non-statements.
+
+2008-07-22 Diego Novillo <dnovillo@google.com>
+ Richard Guenther <rguenther@suse.de>
+
+ * tree-ssa-dom.c (hashable_expr_equal_p): Do nothing if
+ either TYPE0 or TYPE1 is NULL.
+
+2008-07-21 Diego Novillo <dnovillo@google.com>
+
+ * tree-ssa-alias-warnings.c (struct gimple_tree_map): New.
+ Change every use of struct tree_map to struct gimple_tree_map.
+ (gimple_tree_map_eq): New.
+ (gimple_tree_map_hash): New.
+ * tree-ssa-ccp.c (evaluate_stmt): Remove stale FIXME note.
+ * gimplify.c (gimplify_expr): Remove stale FIXME note.
+ * tree-ssa-pre.c: Remove stale references to GIMPLE_MODIFY_STMT.
+ * tree-vect-generic.c (expand_vector_operations_1): Change
+ FIXME tuples to NOTE.
+
+2008-07-21 Richard Guenther <rguenther@suse.de>
+
+ * tree-ssa-phiprop.c (propagate_with_phi): Only look through
+ SSA_NAME copies.
+
+2008-07-21 Richard Guenther <rguenther@suse.de>
+
+ * gimplify.c (gimplify_init_constructor): Clear TREE_SIDE_EFFECTS
+ on the remaining empty constructor.
+
+2008-07-21 Richard Guenther <rguenther@suse.de>
+
+ * tree-ssa-ccp.c (fold_gimple_assign): Handle pointer conversions
+ like fold_stmt_r did.
+ * gimple-pretty-print.c (dump_gimple_cond): Place semicolons
+ where trunk did.
+ * tree-inline.c (copy_bb): Do not insert GIMPLE_NOPs.
+
+2008-07-21 Richard Guenther <rguenther@suse.de>
+
+ PR tree-optimization/36826
+ * tree-ssa-pre.c (eliminate): Do not eliminate in unused
+ statements.
+
+2008-07-20 Richard Guenther <rguenther@suse.de>
+
+ * gimple.h (gimple_expr_type): The expression type is always
+ the base type of an integral sub-type result type.
+ * tree-eh.c (replace_goto_queue_cond_clause): Copy the sequence
+ before handing it off to gsi_insert_seq_after.
+ * tree-sra.c (insert_edge_copies_seq): Make sure to not keep an
+ uninserted but marked for update sequence.
+
+2008-07-20 Richard Guenther <rguenther@suse.de>
+
+ * gimple.c (DEFTREECODE): Add REALIGN_LOAD_EXPR.
+
+2008-07-19 Richard Guenther <rguenther@suse.de>
+
+ * tree-ssa-sccvn.h (get_constant_value_id): Declare.
+ (vn_constant_eq_with_type): Make sure an integral type is
+ never equal to a non-integral type.
+ (vn_hash_constant_with_type): Adjust.
+ * tree-ssa-sccvn.c (get_constant_value_id): New function.
+ * tree-ssa-pre.c (get_expr_value_id): For newly created
+ constant value-ids make sure to add the expression to its
+ expression-set.
+
+2008-07-18 Jakub Jelinek <jakub@redhat.com>
+
+ * gimple.c (gimple_regimplify_operands): Moved to...
+ * gimplify.c (gimple_regimplify_operands): ... here. Rework using
+ lower_omp_1 regimplification code, if regimplified LHS of
+ GIMPLE_ASSIGN or GIMPLE_CALL requires simpler RHS, create a temporary.
+ * omp-low.c (gimple_regimplify_operands): Use
+ gimple_regimplify_operands.
+
+2008-07-18 Richard Guenther <rguenther@suse.de>
+
+ * tree-ssa-reassoc.c (get_rank): For single rhs process its
+ operands.
+
+2008-07-18 Richard Guenther <rguenther@suse.de>
+
+ * tree-ssa-loop-niter.c (expand_simple_operations): Expand
+ as much as trunk does.
+ * tree-ssa-sccvn.c (simplify_binary_expression): For comparisons
+ always expand the first operand.
+
+2008-07-18 Jakub Jelinek <jakub@redhat.com>
+
+ * gimple-pretty-print.c (dump_gimple_cond): Print a semicolon if
+ goto or else goto has been printed.
+ (dump_gimple_goto): Print as goto instead of gimple_goto, print
+ a semicolon at the end.
+ (dump_gimple_asm): Print a semicolon at the end.
+
+ * gimplify.c (gimplify_cond_expr): If COND_EXPR has both non-trivial
+ THEN and ELSE statements and the THEN sequence can't fallthru, avoid
+ adding label_cont and jump to it.
+
+2008-07-18 Aldy Hernandez <aldyh@redhat.com>
+
+ * Makefile.in. Remove TREE_GIMPLE_H definition.
+ Rename all TREE_GIMPLE_H uses to GIMPLE_H.
+ Depend on tree-iterator.h when necessary.
+ * tree-into-ssa.c: Include gimple.h instead of tree-gimple.h.
+ * tree-complex.c: Same.
+ * cgraphbuild.c: Same.
+ * cgraph.c: Same.
+ * builtins.c: Same.
+ * tree-ssa-sccvn.c: Same.
+ * tree-ssa-copyrename.c: Same.
+ * tree-nomudflap.c: Same.
+ * tree-call-cdce.c: Same.
+ * ipa-pure-const.c: Same.
+ * ipa-utils.c: Same.
+ * tree-ssa-alias.c: Same.
+ * tree-ssa-sink.c: Same.
+ * langhooks.c: Same.
+ * function.c: Same.
+ * ipa-type-escape.c: Same.
+ * tree-affine.c: Same.
+ * c-typeck.c: Same.
+ * tree-dfa.c: Same.
+ * tree-ssa-pre.c: Same.
+ * tree-sra.c: Same.
+ * c-omp.c: Same.
+ * tree-ssa-dce.c: Same.
+ * tree-nested.c: Same.
+ * tree-ssa.c: Same.
+ * tree-inline.c: Same.
+ * tree-iterator.c: Same.
+ * c-gimplify.c: Same.
+ * tree-vect-generic.c: Same.
+ * tree-flow.h: Same.
+ * tree-ssa-structalias.c: Same.
+ * ipa-struct-reorg.c: Same.
+ * tree-ssa-reassoc.c: Same.
+ * config/alpha/alpha.c: Same.
+ * config/s390/s390.c: Same.
+ * config/m32c/m32c.c: Same.
+ * config/spu/spu.c: Same.
+ * config/sparc/sparc.c: Same.
+ * config/i386/i386.c: Same.
+ * config/sh/sh.c: Same.
+ * config/xtensa/xtensa.c: Same.
+ * config/stormy16/stormy16.c: Same.
+ * config/ia64/ia64.c: Same.
+ * config/rs6000/rs6000: Same.
+ * config/mips/mips.c: Same.
+ * varpool.c: Same.
+ * cgraphunit.c: Same. Include tree-iterator.h
+ * tree-mudflap.c: Same.
+ * gimplify.c: Same.
+ * c-decl.c: Same.
+ * omp-low.c: Same.
+ * c-semantics: Same.
+ * gimple-low.c: Same.
+ * tree-gimple.c: Merge contents into...
+ * gimple.c: ...here.
+ * tree-gimple.h: Merge contents into...
+ * gimple.h: ...here.
+
+2008-07-17 Jakub Jelinek <jakub@redhat.com>
+
+ * omp-low.c (expand_omp_atomic_pipeline): Call
+ force_gimple_operand_gsi on RHS for IADDR initialization.
+
+ * gimplify.c (gimplify_cond_expr): Push statements in between
+ gimple_push_condition and gimple_pop_condition into a new
+ gimple_seq, append it after gimple_pop_condition cleanups.
+
+2008-07-17 Richard Guenther <rguenther@suse.de>
+
+ * tree-complex.c (init_dont_simulate_again): Handle
+ {REAL,IMAG}PART_EXPR correctly.
+ * gimple-pretty-print.c (dump_unary_rhs): Dump VIEW_CONVERT_EXPR
+ and ASSERT_EXPR the same way as on trunk.
+ * tree-ssa-dom.c (initialize_hash_element): Do not record
+ the type for single rhs assigns.
+ (hashable_expr_equal_p): Deal with NULL types.
+ (eliminate_redundant_computations): Use print_gimple_expr.
+ * tree-vrp.c (stmt_interesting_for_vrp): Fix builtin call check.
+ (vrp_visit_stmt): Likewise.
+ * tree-ssa-forwprop.c (simplify_gimple_switch): Fix typo.
+
+2008-07-16 Richard Guenther <rguenther@suse.de>
+
+ PR tree-optimization/36792
+ * tree-ssa-pre.c (get_or_alloc_expr_for): Handle unary
+ expressions inserted by SCCVN.
+ (do_SCCVN_insertion): Adjust comment.
+ (execute_pre): Allow insertion for FRE again.
+
+ * tree-ssa-sccvn.c (simplify_unary_expression): Deal with
+ the GIMPLE_SINGLE_RHS statemens we get.
+ (init_scc_vn): Init VN_INFO->expr to NULL.
+
+2008-07-16 Richard Guenther <rguenther@suse.de>
+
+ Revert
+ 2008-07-16 Richard Guenther <rguenther@suse.de>
+ * tree-ssa-pre.c (get_constant_for_value_id): Only hand out
+ constants of the correct type.
+ (fully_constant_expression): Pass the required type to
+ get_constant_for_value_id.
+
+ * tree-ssa-sccvn.h (vn_hash_constant_with_type): New function.
+ (vn_constant_eq_with_type): Likewise.
+ * tree-ssa-sccvn.c (vn_constant_eq): Use vn_constant_eq_with_type.
+ (get_or_alloc_constant_value_id): Use vn_hash_constant_with_type.
+ * tree-ssa-pre.c (pre_expr_eq): Use vn_constant_eq_with_type.
+ (pre_expr_hash): Use vn_hash_constant_with_type.
+ (get_representative_for): Use constants as their representative.
+ (fully_constant_expression): Use constant parts in expressions
+ directly.
+
+2008-07-15 Aldy Hernandez <aldyh@redhat.com>
+
+ * tree-ssa-propagate.c (valid_gimple_expression_p): Remove.
+ * tree-ssa-propagate.h (valid_gimple_expression_p): Remove.
+ * tree-eh.c: Factor out common code in operation_could_trap_p and
+ stmt_could_throw_1_p into...
+ (operation_could_trap_helper_p): New.
+ * gimplify.c (gimplify_expr): Rephrase fixme.
+ * tree-mudflap.c: Remove fixme.
+
+2008-07-17 Jakub Jelinek <jakub@redhat.com>
+
+ * tree-eh.c (collect_finally_tree): Call collect_finally_tree_1
+ with region as second argument for GIMPLE_TRY_FINALLY's cleanup.
+
+ * gimplify.c (gimplify_expr): Call gimple_try_set_catch_is_cleanup
+ for TRY_CATCH_EXPR.
+
+2008-07-16 Jakub Jelinek <jakub@redhat.com>
+
+ * tree-gimple.c (is_gimple_reg_rhs): Don't check for CALL_EXPRs
+ with side-effects.
+ * gimple.c (extract_ops_from_tree): Remove assert.
+ * gimplify.c (is_gimple_reg_or_call_rhs): New function.
+ (rhs_predicate_for): Return it instead of is_gimple_reg_rhs.
+ (gimplify_expr): Handle is_gimple_reg_or_call_rhs.
+
+ * tree-ssa-threadedge.c (record_temporary_equivalences_for_stmts,
+ simplify_control_stmt_condition): Pass stmt instead of NULL as second
+ argument to simplify callback.
+
+ * tree-vect-patterns.c (vect_recog_pow_pattern): Don't call
+ gimple_call_set_lhs with lhs of last_stmt.
+ * tree-vect-transform.c (vectorizable_call): Build a new dummy
+ assignment, replace the call with it and move over stmt_info.
+
+ * tree-ssa-loop-niter.c (infer_loop_bounds_from_array): Use
+ is_gimple_assign instead of gimple_code () == GIMPLE_ASSIGN and
+ is_gimple_call instead of gimple_code () == GIMPLE_CALL.
+ * tree-ssa-propagate.c (update_call_from_tree, substitute_and_fold):
+ Likewise.
+ * tree-ssa-sccvn.c (visit_use): Likewise.
+ * tree-eh.c (stmt_could_throw_p): Likewise.
+ * tree-optimize.c (execute_fixup_cfg): Likewise.
+ * omp-low.c (check_omp_nesting_restrictions, scan_omp_1_stmt,
+ optimize_omp_library_calls): Likewise.
+ * tree-ssa-loop-im.c (movement_possibility, stmt_cost,
+ determine_invariantness_stmt): Likewise.
+ * tree-ssa-phiprop.c (phivn_valid_p, phiprop_insert_phi,
+ propagate_with_phi): Likewise.
+ * tree-ssa-ccp.c (get_default_value, surely_varying_stmt_p,
+ ccp_fold_builtin, gimplify_and_update_call_from_tree): Likewise.
+ * ipa-struct-reorg.c (is_result_of_mult, create_general_new_stmt):
+ Likewise.
+ * tree-ssa-coalesce.c (build_ssa_conflict_graph): Likewise.
+ * tree-object-size.c (alloc_object_size, call_object_size,
+ check_for_plus_in_loops): Likewise.
+ * tree-ssa.c (verify_ssa): Likewise.
+ * predict.c (expr_expected_value_1, tree_bb_level_predictions,
+ tree_estimate_probability): Likewise.
+ * tree-cfg.c (verify_stmt): Likewise.
+ * tree-ssa-loop-ch.c (should_duplicate_loop_header_p,
+ copy_loop_headers): Likewise.
+ * tree-ssa-ter.c (is_replaceable_p): Likewise.
+ * ipa-prop.c (ipa_count_arguments, ipa_compute_jump_functions):
+ Likewise.
+ * tree-ssa-dom.c (gimple_assign_unary_useless_conversion_p,
+ record_equivalences_from_stmt, optimize_stmt,
+ get_lhs_or_phi_result): Likewise.
+ * tree-ssa-sink.c (is_hidden_global_store): Likewise.
+ * tree-nrv.c (tree_nrv, execute_return_slot_opt): Likewise.
+ * value-prof.c (gimple_divmod_fixed_value,
+ gimple_mod_pow2, gimple_mod_subtract): Likewise.
+ * tree-predcom.c (name_for_ref, find_looparound_phi,
+ replace_ref_with, remove_name_from_operation): Likewise.
+ * tree-ssa-math-opts.c (is_division_by, execute_cse_reciprocals,
+ execute_cse_sincos, execute_convert_to_rsqrt): Likewise.
+ * tree-complex.c (expand_complex_move, expand_complex_operations_1):
+ Likewise.
+ * tree-outof-ssa.c (identical_copies_p): Likewise.
+ * tree-ssa-pre.c (is_exception_related): Likewise.
+ * tree-sra.c (scalarize_use, scalarize_copy): Likewise.
+ * tree-ssa-alias.c (count_uses_and_derefs, update_alias_info_1,
+ is_escape_site): Likewise.
+ * lambda-code.c (can_put_in_inner_loop,
+ cannot_convert_bb_to_perfect_nest): Likewise.
+ * tree-tailcall.c (find_tail_calls, eliminate_tail_call): Likewise.
+ * ipa-type-escape.c (look_for_casts_stmt, is_cast_from_non_pointer):
+ Likewise.
+ * tree-vect-transform.c (vectorizable_reduction): Likewise.
+ * tree-ssa-threadedge.c (record_temporary_equivalences_from_stmts):
+ Likewise.
+ * tree-ssa-phiopt.c (nt_init_block): Likewise.
+ * tree-ssa-structalias.c (find_func_aliases): Likewise.
+ * tree-ssa-forwprop.c (can_propagate_from,
+ forward_propagate_comparison, simplify_not_neg_expr,
+ simplify_gimple_switch, tree_ssa_forward_propagate_single_use_vars):
+ Likewise.
+ * tree-ssa-dce.c (eliminate_unnecessary_stmts): Likewise.
+ * tree-ssa-dse.c (get_kill_of_stmt_lhs, dse_possible_dead_store_p,
+ dse_optimize_stmt, execute_simple_dse): Likewise.
+ * tree-ssa-loop-ivopts.c (find_interesting_uses_op,
+ find_interesting_uses_stmt, rewrite_use_nonlinear_expr): Likewise.
+ * tree-vrp.c (stmt_overflow_infinity, vrp_stmt_computes_nonzero,
+ register_edge_assert_for_2, register_edge_assert_for,
+ find_assert_locations, check_all_array_refs,
+ remove_range_assertions, stmt_interesting_for_vrp, vrp_visit_stmt,
+ simplify_stmt_using_ranges): Likewise.
+ * tree-ssa-loop-prefetch.c (gather_memory_references): Likewise.
+ * tree-ssa-copy.c (may_propagate_copy_into_stmt,
+ propagate_tree_value_into_stmt): Likewise.
+ * tree-inline.c (copy_bb, expand_call_inline,
+ gimple_expand_calls_inline, fold_marked_statements): Likewise.
+
+ * tree-ssa-copyrename.c (rename_ssa_copies): Use
+ gimple_assign_ssa_name_copy_p.
+
+ * tree-ssa-forwprop.c (forward_propagate_addr_expr_1): Check
+ gimple_assign_rhs_code, type of rhs is TREE_TYPE (lhs), update
+ rhs_code.
+
+2008-07-16 Richard Guenther <rguenther@suse.de>
+
+ * tree-ssa-pre.c (get_constant_for_value_id): Only hand out
+ constants of the correct type.
+ (fully_constant_expression): Pass the required type to
+ get_constant_for_value_id.
+
+2008-07-15 Aldy Hernandez <aldyh@redhat.com>
+
+ Merge with mainline @137837.
+
+ * configure.ac (ACX_PKGVERSION): Update revision merge string.
+ * configure: Regenerate.
+
+2008-07-15 Jakub Jelinek <jakub@redhat.com>
+
+ * common.opt (-fgimple-conversion=): Remove.
+
+ * tree-affine.c (aff_combination_expand): Tuplify.
+ * cfgexpand.c (gimple_assign_rhs_to_tree): Remove prototype.
+ * tree-outof-ssa.c (gimple_assign_rhs_to_tree): Likewise.
+ * tree-gimple.h (gimple_assign_rhs_to_tree): New prototype.
+
+2008-07-15 Aldy Hernandez <aldyh@redhat.com>
+
+ * tree.h: Remove gimple_unreachable_1 prototype.
+
+2008-07-15 Aldy Hernandez <aldyh@redhat.com>
+
+ * Makefile.in (gimple-dummy.o): Remove.
+ * gimple-dummy.c: Delete.
+ * tree-ssa-propagate.c (valid_gimple_expression_p): Change
+ gimple_unreachable to gcc_unreachable.
+ * tree-affine.c (aff_combination_expand): Same.
+ * tree-vect-transform.c (vectorizable_call): Same.
+
+2008-07-15 Richard Guenther <rguenther@suse.de>
+
+ * gimplify.c (gimplify_expr): Gimplify an unused volatile load
+ properly.
+
+2008-07-15 Richard Guenther <rguenther@suse.de>
+
+ * tree-ssa-pre.c: Tuplify. Enable FRE and PRE.
+ (execute_pre): Disable SCCVN insertion even for FRE.
+ * tree-ssa-sccvn.h (copy_reference_ops_from_call): Declare.
+ * tree-ssa-sccvn.c (copy_reference_ops_from_call): Export.
+ (vn_get_expr_for): Handle more expression kinds.
+ (visit_reference_op_load): Properly set a value id for
+ inserted names.
+ (simplify_binary_expression): Use valid_gimple_rhs_p instead of
+ valid_gimple_expression_p.
+ (simplify_unary_expression): Likewise.
+ (process_scc): Clear the cached/simplified expressions at the
+ start of the iteration.
+ (free_scc_vn): Do not clear SSA_NAME_VALUE.
+ (run_scc_vn): Remove broken special case in printing VNs.
+ * tree-ssa-propagate.c (valid_gimple_rhs_p): Allow
+ gimple-min-invariants and SSA names.
+
+2008-07-14 Andreas Krebbel <krebbel1@de.ibm.com>
+
+ * config/s390/s390.c: (s390_gimplify_va_arg) Unshare the args* tree.
+
+2008-07-14 Richard Guenther <rguenther@suse.de>
+
+ * tree-ssa-math-opts.c (execute_cse_reciprocals): Process
+ SSA_NAME defs of calls.
+ * gimple-pretty-print.c (dump_unary_rhs): Do not prefix
+ CONSTRUCTOR with [constructor].
+
+2008-07-14 Aldy Hernandez <aldyh@redhat.com>
+
+ * config/alpha/alpha.c (va_list_skip_additions): Change
+ GIMPLE_STMT_OPERAND to TREE_OPERAND.
+
+2008-07-14 Jakub Jelinek <jakub@redhat.com>
+
+ * tree-vect-transform.c (vect_create_data_ref_ptr): Update comment.
+ * config/s390/s390.c (s390_va_start): Build MODIFY_EXPR instead of
+ GIMPLE_MODIFY_STMT.
+ (s390_gimplify_va_arg): Use gimplify_assign.
+ * config/sh/sh.c (sh_va_start): Build MODIFY_EXPR instead of
+ GIMPLE_MODIFY_STMT.
+ (sh_gimplify_va_arg_expr): Use gimplify_assign.
+ * config/sparc/sparc.c (sparc_gimplify_va_arg): Likewise.
+ * config/spu/spu.c (spu_va_start): Build MODIFY_EXPR instead of
+ GIMPLE_MODIFY_STMT.
+ (spu_gimplify_va_arg_expr): Use gimplify_assign.
+ * config/stormy16/stormy16.c (xstormy16_expand_builtin_va_start):
+ Build MODIFY_EXPR instead of GIMPLE_MODIFY_STMT.
+ (xstormy16_gimplify_va_arg_expr): Likewise. Use gimplify_assign.
+ * config/xtensa/xtensa.c (xtensa_va_start): Build MODIFY_EXPR
+ instead of GIMPLE_MODIFY_STMT.
+ (xtensa_gimplify_va_arg_expr): Use gimplify_assign.
+
+2008-07-14 Aldy Hernandez <aldyh@redhat.com>
+
+ * config/alpha/alpha.c (va_list_skip_additions): Rename
+ GIMPLE_MODIFY_STMT to MODIFY_EXPR.
+ (alpha_va_start): Same.
+ (alpha_gimplify_va_arg_1): Use gimplify_assign.
+ (alpha_gimplify_va_arg): Same.
+ * config/frv/frv.c (frv_expand_builtin_va_start): Rename
+ GIMPLE_MODIFY_STMT to MODIFY_EXPR.
+ * config/ia64/ia64.c (ia64_gimplify_va_arg): Use gimplify_assign.
+ * config/alpha/mips.c (mips_va_start): Rename GIMPLE_MODIFY_STMT to
+ MODIFY_EXPR or use gimplify_assign when appropriate.
+ (mips_gimplify_va_arg_expr): Same.
+
+2008-07-14 Aldy Hernandez <aldyh@redhat.com>
+
+ * config/rs6000/rs6000.c (rs6000_va_start): Change
+ GIMPLE_MODIFY_STMT to MODIFY_EXPR.
+ (rs6000_gimplify_va_arg): Use gimplify_assign.
+ Build GIMPLE_GOTO directly.
+
+2008-07-14 Aldy Hernandez <aldyh@redhat.com>
+
+ * tree-dump.c (dequeue_and_dump): Remove GIMPLE_MODIFY_STMT case.
+ * tree-ssa-loop-niter.c (simplify_replace_tree): Remove GIMPLE_STMT_P
+ call.
+ * tree-pretty-print.c (dump_generic_node): Remove any references to
+ GIMPLE_MODIFY_STMT, GIMPLE_STMT_P, GIMPLE_TUPLE_P.
+ (op_prio): Same.
+ (op_symbol_code): Same.
+ * java/java-gimplify.c (java_gimplify_expr): Same.
+ (java_gimplify_modify_expr): Same.
+ * java/java-tree.h: Rename GENERIC_NEXT to TREE_CHAIN.
+ * tree-tailcall.c (find_tail_calls): Update comment.
+ * tree.c (tree_code_class_string): Remove "gimple_stmt".
+ (tree_node_kind): Remove "gimple statments".
+ (tree_code_size): Remove tcc_gimple_stmt.
+ (make_node_stat): Same.
+ (copy_node_stat): Remove any references to
+ GIMPLE_MODIFY_STMT, GIMPLE_STMT_P, GIMPLE_TUPLE_P, tcc_gimple_stmt,
+ TS_GIMPLE_STATEMENT, GENERIC_TREE_OPERAND, GENERIC_TREE_TYPE,
+ GIMPLE_TUPLE_HAS_LOCUS_P, GIMPLE_STMT_LOCUS, GIMPLE_STMT_BLOCK,
+ IS_GIMPLE_STMT_CODE_CLASS, GIMPLE_STMT_BLOCK.
+ (expr_align): Same.
+ (tree_node_structure): Same.
+ (build2_stat): Same.
+ (set_expr_locus): Same.
+ (walk_tree_1): Same.
+ (tree_block): Same.
+ (build_gimple_modify_stmt_stat): Remove.
+ (expr_location): Remove.
+ (set_expr_location): Remove.
+ (expr_hash_location): Remove.
+ (expr_locus): Remove.
+ (expr_filename): Remove.
+ (expr_lineno): Remove.
+ (generic_tree_operand): Remove.
+ (generic_tree_type): Remove.
+ * tree.h (tree_code_class): Remove tcc_gimple_stmt.
+ (IS_GIMPLE_STMT_CODE_CLASS): Remove.
+ (struct gimple_stmt): Remove.
+ (GIMPLE_STMT_CHECK): Remove.
+ (TREE_OPERAND_CHECK): Remove GIMPLE_TUPLE_P.
+ (TREE_CHAIN): Same.
+ (GIMPLE_STMT_OPERAND_CHECK): Remove.
+ (GIMPLE_STMT_OPERAND_CHECK): Remove.
+ (GIMPLE_STMT_P): Remove.
+ (GIMPLE_TUPLE_P): Remove.
+ (GIMPLE_TUPLE_HAS_LOCUS_P): Remove.
+ (GENERIC_TREE_OPERAND): Remove.
+ (GENERIC_TREE_TYPE): Remove.
+ (GENERIC_NEXT): Remove.
+ (IS_CONVERT_EXPR_CODE_P): Rename GENERIC_TREE_TYPE to TREE_TYPE.
+ (MOVE_NONTEMPORAL): Remove GIMPLE_MODIFY_STMT_CHECK.
+ Remove GIMPLE_STMT_OPERAND, GIMPLE_STMT_LOCUS, GIMPLE_STMT_BLOCK.
+ (EXPR_LOCATION, SET_EXPR_LOCATION, EXPR_HAS_LOCATION, EXPR_LOCUS,
+ EXPR_FILENAME, EXPR_LINENO): Do ont call functions.
+ (CAN_HAVE_LOCATION_P): Remove GIMPLE_STMT_P.
+ (union tree_node): Remove gstmt.
+ (build_gimple_modify_stmt*): Remove.
+ (expr_location, set_expr_location, expr_has_location,
+ expr_locus, expr_filename, expr_lineno, generic_tree_operand,
+ generic_tree_type): Remove.
+ * tree-scalar-evolution.c (follow_ssa_edge): Update comment.
+ (interpret_condition_phi): Same.
+ * gimple.h (gimplify_assign): New.
+ * builtins.c, fold-const.c, omp-low.c, tree-ssa-dse.c, tree-gimple.c,
+ tree-ssa-math-opts.c, tree-nrv.c, gimple-low.c, dwarf2out.c,
+ expr.c, tree-parloops.c, matrix-reorg.c, c-decl.c, tree-eh.c,
+ c-pretty-print.c, langhooks.c, function.c, tree-affine.c,
+ gimplify.c, tree.def, cfgexpand.c, tree-predcom.c, print-tree.c,
+ tree-ssa-ter.c, tree-ssa.c, tree-inline.c, gimple.c, gimple.h,
+ tree-cfg.c, config/i386/i386.c, stmt.c, tree-ssa-operands.c)
+ Remove any references to
+ GIMPLE_MODIFY_STMT, GIMPLE_STMT_P, GIMPLE_TUPLE_P, tcc_gimple_stmt,
+ TS_GIMPLE_STATEMENT, GENERIC_TREE_OPERAND, GENERIC_TREE_TYPE,
+ GIMPLE_TUPLE_HAS_LOCUS_P, GIMPLE_STMT_LOCUS, GIMPLE_STMT_BLOCK,
+ IS_GIMPLE_STMT_CODE_CLASS, GIMPLE_STMT_BLOCK.
+ Call gimplify_assign or generate a GIMPLE_ASSIGN directly when
+ appropriate.
+
+2008-07-14 Jakub Jelinek <jakub@redhat.com>
+
+ * cfgexpand.c (gimple_cond_pred_to_tree): New function.
+ (gimple_to_tree) <case GIMPLE_COND>: Use it.
+ (release_stmt_tree): New function.
+ (expand_gimple_cond): Call just gimple_cond_pred_to_tree
+ instead of gimple_to_tree, ggc_free pred before returning.
+ (expand_gimple_tailcall): Call release_stmt_tree.
+ (expand_gimple_basic_block): Call release_stmt_tree instead
+ of ggc_free.
+
+ * gimplify.c (internal_get_tmp_var, gimplify_decl_expr,
+ gimplify_init_ctor_eval, gimplify_target_expr): Call ggc_free
+ on the INIT_EXPR.
+
+2008-07-14 Richard Guenther <rguenther@suse.de>
+
+ * tree-ssa-ccp.c (ccp_fold): Move ADDR_EXPR handing to
+ GIMPLE_SINGLE_RHS case.
+ * tree-ssa-ifcombine.c (ifcombine_iforif): Fix typo.
+
+2008-07-14 Jakub Jelinek <jakub@redhat.com>
+
+ * system.h (CONST_CAST2): Avoid using a union for all GCCs <= 4.0.x.
+
+2008-07-12 Diego Novillo <dnovillo@google.com>
+
+ * tree-loop-distribution.c: Tuplify.
+ * tree-ssa-propagate.c (substitute_and_fold): Remove
+ stale FIXME tuples note.
+
+2008-07-11 Jakub Jelinek <jakub@redhat.com>
+
+ * tree-dump.c (dump_options): Don't set TDF_RHS_ONLY for -all.
+
+ * omp-low.c (lower_omp_1): Only use rhs_predicate_for if
+ GIMPLE_SINGLE_RHS.
+
+ * tree-vect-analyze.c (vect_determine_vectorization_factor): Handle
+ GIMPLE_CALL with non-NULL lhs.
+ (vect_build_slp_tree): Likewise. Fix reversed check for references.
+ * tree-vectorizer.c (stmt_vec_info_htab, stmt_vec_info_eq,
+ stmt_vec_info_hash, init_stmt_vec_info_htab,
+ free_stmt_vec_info_htab): Remove.
+ (stmt_vec_info_vec): New variable.
+ (init_stmt_vec_info_vec, free_stmt_vec_info_vec): New functions.
+ (new_loop_vec_info): Clear stmt uid before calling
+ set_vinfo_for_stmt.
+ (vect_is_simple_use): Handle GIMPLE_CALL with non-NULL lhs.
+ (vectorize_loops): Call {init,free}_stmt_vec_info_vec instead of
+ {init,free}_stmt_vec_info_htab.
+ * tree-parloops.c (parallelize_loops): Likewise.
+ * tree-ssa-operands.c (get_expr_operands): Handle VEC_COND_EXPR.
+ * tree-vectorizer.h (stmt_vec_info_htab): Removed.
+ (init_stmt_vec_info_htab, free_stmt_vec_info_htab): Remove
+ prototypes.
+ (stmt_vec_info_vec): New extern decl.
+ (init_stmt_vec_info_vec, free_stmt_vec_info_vec): New prototypes.
+ (vinfo_for_stmt, set_vinfo_for_stmt): Rewritten using stmt uid
+ and vector instead of a hash table.
+ * tree-vect-patterns.c (vect_recog_pow_pattern): Request
+ a GIMPLE_CALL with non-NULL lhs instead of GIMPLE_ASSIGN.
+ (vect_pattern_recog_1): Use is_gimple_call instead of comparing
+ gimple_code with GIMPLE_CALL.
+ * gimple.c (gimple_rhs_class_table): Use GIMPLE_SINGLE_RHS for
+ DOT_PROD_EXPR and VEC_COND_EXPR.
+ * tree-vect-transform.c (vect_get_slp_vect_defs): Use gimple_get_lhs
+ instead of gimple_assign_lhs.
+ (get_initial_def_for_induction): Use build_int_cst even for
+ pointers. Use POINTER_PLUS_EXPR for POINTER_TYPE_P (scalar_type).
+ (vect_get_vec_def_for_operand): Use is_gimple_call instead of
+ comparing gimple_code with GIMPLE_CALL.
+ (vectorizable_call): Likewise. Use gimple_call_lhs instead of
+ gimple_assign_lhs. Build a vector of arguments, use
+ gimple_build_call_vec.
+ (vect_get_vec_def_for_stmt_copy): Use gimple_get_lhs.
+ (vectorizable_live_operation): Handle GIMPLE_SINGLE_RHS operands.
+
+2008-07-11 Doug Kwan <dougkwan@google.com>
+
+ * gimple-dummy.c (vectorizable_induction, vectorizable_type_promotion,
+ vectorizable_type_demotion, vectorizable_conversion,
+ vectorizable_operation, vectorizable_assignment,
+ vectorizable_load, vectorizable_call, vectorizable_store,
+ vectorizable_condition, vectorizable_reduction,
+ vectorizable_live_operation, vectorizable_function,
+ vect_estimate_min_profitable_iters, vect_model_simple_cost,
+ vect_model_store_cost, vect_model_load_cost, vect_transform_loop):
+ Remove DUMMY_FNs.
+ * tree-ssa-loop.c (gate_tree_vectorize): Reenable vectorizer.
+ * tree-vectorizer.c (vect_is_simple_use): Fix handling of
+ GIMPLE_NOP.
+ * tree-vectorizer.h (vectorizable_load, vectorizable_store,
+ vectorizable_operation, vectorizable_type_promotion,
+ vectorizable_type_demotion, vectorizable_conversion,
+ vectorizable_assignment, vectorizable_call, vectorizable_condition,
+ vectorizable_live_operation, vectorizable_reduction,
+ vectorizable_induction): Adjust prototypes.
+ * tree-vect-transform.c (vectorizable_load, vectorizable_store,
+ vectorizable_operation, vectorizable_type_promotion,
+ vectorizable_type_demotion, vectorizable_conversion,
+ vectorizable_assignment, vectorizable_call, vectorizable_condition,
+ vectorizable_live_operation, vectorizable_reduction,
+ vectorizable_induction, vect_transform_stmt,
+ vect_create_data_ref_ptr, vect_create_addr_base_for_vector_ref,
+ vect_get_vec_def_for_operand, vect_init_vector,
+ vect_finish_stmt_generation, vect_create_epilog_for_reduction,
+ get_initial_def_for_reduction, cost_for_stmt,
+ vect_estimate_min_profitable_iters, vect_model_reduction_cost,
+ vect_cost_strided_group_size, vect_model_load_cost, bump_vector_ptr,
+ vect_get_constant_vectors, vect_get_slp_vect_defs,
+ vect_get_slp_defs, get_initial_def_for_induction,
+ vect_get_vec_def_for_stmt_copy, vect_get_vec_defs,
+ vectorizable_function, vect_gen_widened_results_half,
+ vect_permute_store_chain, vect_setup_realignment,
+ vect_permute_load_chain, vect_transform_strided_load,
+ vect_is_simple_cond, vect_build_loop_niters,
+ vect_generate_tmps_on_preheader, vect_update_ivs_after_vectorizer,
+ vect_do_peeling_for_loop_bound, vect_gen_niters_for_prolog_loop,
+ vect_do_peeling_for_alignment, vect_create_cond_for_align_checks,
+ vect_create_cond_for_alias_checks, vect_loop_versioning,
+ vect_remove_stores, vect_schedule_slp_instance,
+ vect_transform_loop): Tuplify.
+
+2008-07-10 Richard Guenther <rguenther@suse.de>
+
+ * gimple.h (gimple_assign_ssa_name_copy_p): Declare.
+ (gimple_has_lhs): New function.
+ * gimple.c (gimple_assign_ssa_name_copy_p): New function.
+ * tree-ssa-copy.c (propagate_tree_value_into_stmt): Remove
+ redundant gimple_set_location call.
+ * gimple-iterator.c (gsi_remove): Do not free stmt operands.
+ * tree-ssa-structalias.c (find_func_aliases): Correctly let
+ all things with pointers escape.
+ * tree-pass.h (TDF_RHS_ONLY): New flag.
+ * diagnostic.h (print_gimple_expr): Declare.
+ * gimple-pretty-print.c (print_gimple_expr): New function.
+ (dump_gimple_assign): Dump the RHS as expression if TDF_RHS_ONLY.
+ (dump_gimple_call): Likewise.
+ (dump_gimple_cond): Likewise.
+ * tree-ssa-propagate.c (fold_predicate_in): Use print_gimple_expr.
+ * tree-ssa-sccvn.c (visit_use): Use gimple_has_lhs.
+ Use print_gimple_expr. Handle tcc_expression correctly.
+
+2008-07-09 Jakub Jelinek <jakub@redhat.com>
+
+ * gimplify.c (struct gimplify_ctx): Move to tree-gimple.h.
+ (push_gimplify_context): Don't allocate bind_expr_stack,
+ temp_htab nor c itself here. Add c argument.
+ (pop_gimplify_context): Allow bind_expr_stack being NULL. Check
+ c->temp_htab instead of optimize whether htab_delete should be called.
+ Don't free c.
+ (gimple_push_bind_expr): Create bind_expr_stack lazily.
+ (lookup_tmp_var): Create temp_htab lazily.
+ (gimplify_scan_omp_clauses, gimplify_omp_parallel, gimplify_omp_task,
+ gimplify_body, force_gimple_operand): Adjust push_gimplify_context
+ callers.
+ * omp-low.c (lower_omp_sections, lower_omp_single, lower_omp_master,
+ lower_omp_ordered, lower_omp_critical, lower_omp_for,
+ create_task_copyfn, lower_omp_taskreg, execute_lower_omp):
+ * tree-ssa-ccp.c (gimplify_and_update_call_from_tree): Likewise.
+ * tree-sra.c (generate_element_init): Likewise.
+ * tree-mudflap.c (execute_mudflap_function_ops,
+ execute_mudflap_function_decls): Likewise.
+ * tree-inline.c (setup_one_parameter, optimize_inline_calls): Likewise.
+ * tree-gimple.h (struct gimplify_ctx): New type.
+ (push_gimplify_context): Adjust prototype.
+
+ * gimple.h (gimple_rhs_class_table): New extern decl.
+ (get_gimple_rhs_class): Change into inline.
+ * gimple.c (get_gimple_rhs_class): Removed.
+ (gimple_rhs_class_table): New variable.
+
+2008-07-09 Doug Kwan <dougkwan@google.com>
+ Diego Novillo <dnovillo@google.com>
+
+ * tree-ssa-ccp.c (fold_stmt_r): Remove gcc_unreachable
+ call from COND_EXPR handler.
+ * tree-if-conv.c: Tuplify.
+ * gimple.c (gimple_could_trap_p_1): Factor out of ...
+ (gimple_could_trap_p): ... here.
+ Call it.
+ (gimple_assign_rhs_could_trap_p): New.
+ * gimple.h (gimple_assign_rhs_could_trap_p): Declare.
+ * tree-ssa-operands.c (get_expr_operands): Handle
+ COND_EXPR.
+
+2008-07-08 Jakub Jelinek <jakub@redhat.com>
+
+ Merge with mainline @137633.
+
+ * configure.ac (ACX_PKGVERSION): Update revision merge string.
+ * configure: Regenerate.
+
+2008-07-08 Jakub Jelinek <jakub@redhat.com>
+
+ * tree-cfg.c (remove_useless_stmts_cond): Avoid calling
+ fold_binary.
+
+2008-07-07 Jakub Jelinek <jakub@redhat.com>
+
+ * gimple-pretty-print.c (dump_gimple_return): Don't print space
+ after return if return has no argument.
+ (dump_gimple_seq): Don't print newline after last statement in
+ the sequence.
+ (dump_gimple_fmt, dump_gimple_try, dump_gimple_omp_for,
+ dump_gimple_omp_single, dump_gimple_omp_sections,
+ dump_gimple_omp_block, dump_gimple_omp_critical,
+ dump_gimple_omp_parallel, dump_gimple_omp_task): Use
+ newline_and_indent after dump_gimple_seq instead of INDENT.
+ (dump_gimple_bind): Likewise. If there are no bind vars, don't
+ print two newlines before the sequence, just one.
+ * tree-cfg.c (dump_function_to_file): Fix dumping lowered gimple
+ before CFG is built.
+
+2008-07-07 Diego Novillo <dnovillo@google.com>
+
+ * tree-vrp.c (ssa_name_nonnegative_p): Tuplify.
+ (ssa_name_nonzero_p): Tuplify.
+ (extract_range_from_comparison): Tidy.
+ (vrp_evaluate_conditional_warnv_with_ops): Tidy.
+ (vrp_evaluate_conditional): Change STMT argument to gimple.
+ Update all users.
+ (simplify_stmt_for_jump_threading): Change WITHIN_STMT argument
+ to gimple.
+ Update all users.
+ (identify_jump_threads): Tidy.
+ * tree-tailcall.c (find_tail_calls): Remove stale FIXME note.
+ * tree.c (tree_node_structure): Likewise.
+ * tree.h (struct tree_base): Likewise.
+ (struct gimple_stmt): Likewise.
+ * builtins.c (expand_builtin_memcpy): Likewise.
+ (expand_builtin_memset_args): Likewise.
+ * tree-chrec.h (build_polynomial_chrec): Do not initialize VAL.
+ * tree-ssa-ccp.c (fold_stmt_r): Do not handle COND_EXPR.
+ (fold_stmt): Remove #if 0 code.
+ * tree-ssa-dom.c (EXTRA_DETAILS): Remove.
+ Update all users.
+ (hashable_expr_equal_p): Remove stale FIXME note.
+ (simplify_stmt_for_jump_threading): Convert WITHIN_STMT
+ argument to gimple. Update all users.
+ * tree-ssa-propagate.c: Include gimple.h
+ (get_rhs): Remove.
+ (set_rhs): Remove.
+ (fold_predicate_in): Tuplify.
+ * Makefile.in (tree-ssa-propagate.o): Add dependency on
+ GIMPLE_H.
+ * tree-ssa-propagate.h (get_rhs, set_rhs): Remove.
+ * tree-parloops.c (create_parallel_loop): Remove FIXME
+ tuples note.
+ * tree-eh.c (lookup_stmt_eh_region): Remove FIXME tuples
+ editorial note.
+ * cfgexpand.c (gimple_to_tree): Likewise.
+ * tree-ssa-dce.c (mark_stmt_if_obviously_necessary): Tidy.
+ Do not handle GIMPLE_BIND.
+ * tree-inline.c (remap_gimple_op_r): Remove stale FIXME notes.
+ * tree-optimize.c (execute_fixup_cfg): Likewise.
+ * tree-flow.h (struct tree_ann_common_d): Remove stale
+ FIXME tuples notes.
+ (tree_vrp_evaluate_conditional): Change last argument type to
+ gimple. Update all users.
+ (thread_across_edge): Likewise.
+ * gimple.c (gimple_has_side_effects): If any argument has
+ TREE_SIDE_EFFECTS set, assert that S has volatile operands.
+ (gimple_rhs_has_side_effects): Likewise.
+ * gimple.h (gimple_phi_capacity): Remove stale FIXME tuples note.
+ * tree-cfg.c (group_case_labels): Remove FIXME tuples note.
+ Assert that the new size is smaller than the old size.
+ (remove_useless_stmts_warn_notreached): Remove #if 0 code.
+ (remove_useless_stmts_cond): Remove stale FIXME tuples note.
+ (remove_useless_stmts_1): Likewise.
+ (verify_types_in_gimple_assign): Likewise.
+ * passes.c (init_optimization_passes): Re-enable
+ pass_ipa_increase_alignment.
+ * tree-ssa-threadedge.c
+ (record_temporary_equivalences_from_stmts_at_dest):
+ Change SIMPLIFY to accept two arguments of type gimple.
+ Update all users.
+ (simplify_control_stmt_condition): Likewise.
+ (thread_accross_edge): Likewise.
+ * tree-ssa-operands.c (add_call_clobber_ops): Re-enable
+ calls to ipa_reference_get_not_read_globals and
+ ipa_reference_get_not_written_global.
+
+2008-07-07 Aldy Hernandez <aldyh@redhat.com>
+
+ * tree-ssa-dom.c: Remove FIXME tuples.
+
+2008-07-07 Aldy Hernandez <aldyh@redhat.com>
+
+ * tree-cfg.c (verify_types_in_gimple_assign): Remove
+ FIXME tuples.
+
+2008-07-04 Jakub Jelinek <jakub@redhat.com>
+
+ * cfgexpand.c (gimple_to_tree) <case GIMPLE_CALL>: Copy
+ CALL_EXPR_VA_ARG_PACK.
+
+ * gimple.c (gimple_build_bind): Set gimple_bind_block rather
+ than gimple_block.
+ (gimple_copy) <case GIMPLE_BIND>: Don't unshare gimple_bind_block.
+
+ * gimple.h (GF_ASM_INPUT, GF_ASM_VOLATILE, GF_CALL_CANNOT_INLINE,
+ GF_CALL_FROM_TRUNK, GF_CALL_RETURN_SLOT_OPT, GF_CALL_TAILCALL,
+ GF_CALL_VA_ARG_PACK, GF_OMP_PARALLEL_COMBINED, GF_OMP_RETURN_NOWAIT,
+ GF_OMP_SECTION_LAST, GF_PREDICT_TAKEN): Change from static const ints
+ into enum values.
+ (struct gimple_statement_base): Move subcode after flags to make it
+ 16-bit aligned.
+
+ * tree-ssa-structalias.c (find_func_aliases): Handle ADDR_EXPR
+ as GIMPLE_SINGLE_RHS instead of GIMPLE_UNARY_RHS.
+
+ * tree-ssa-operands.c (get_expr_operands): Don't handle
+ OMP_FOR, OMP_PARALLEL, OMP_TASK, OMP_SECTIONS and PREDICT_EXPR
+ here.
+
+ * gimple.def (GIMPLE_PREDICT): New.
+ * gimple.h: Update comment above GF_* flags.
+ (GF_PREDICT_TAKEN): New.
+ (gimple_build_predict): New prototype.
+ (gimple_predict_predictor, gimple_predict_outcome,
+ gimple_predict_set_predictor, gimple_predict_set_outcome): New
+ inlines.
+ * gimple.c (gss_for_code): Handle GIMPLE_PREDICT.
+ (gimple_size, walk_gimple_op): Likewise.
+ (gimple_build_predict): New function.
+ * gimple-pretty-print.c (dump_gimple_stmt): Handle GIMPLE_PREDICT.
+ * predict.c (tree_bb_level_predictions): Likewise.
+ * cfgexpand.c (gimple_to_tree): Likewise.
+ * tree-inline.c (estimate_num_insns): Likewise.
+ * tree-ssa-dce.c (mark_stmt_if_obviously_necessary): Likewise.
+ * gimple-low.c (lower_stmt): Likewise.
+ * tree-cfg.c (verify_types_in_gimple_seq_2): Likewise.
+ (verify_types_in_gimple_stmt): Likewise. Don't handle PREDICT_EXPR.
+ * gimplify.c (gimplify_expr): Gimplify PREDICT_EXPR into
+ GIMPLE_PREDICT.
+ * expr.c (expand_expr_real): Don't handle PREDICT_EXPR.
+
+2008-07-04 Aldy Hernandez <aldyh@redhat.com>
+
+ * tree-ssa-forwprop.c (rhs_to_tree): Remove fixme.
+ (forward_propagate_into_cond): Add comment.
+ (forward_propagate_into_gimple_cond): Add comment.
+ (forward_propagate_addr_expr_1): Enable optimization.
+
+2008-07-04 David Edelsohn <edelsohn@gnu.org>
+
+ Revert:
+ * config/rs6000/rs6000.c (rs6000_gimplify_va_arg): Unshare t.
+
+ * config/rs6000/rs6000.c (rs6000_gimplify_va_arg): Unshare reg.
+
+2008-07-03 David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/rs6000.c (rs6000_gimplify_va_arg): Unshare t.
+
+2008-07-03 Doug Kwan <dougkwan@google.com>
+
+ * gimple-dummy.c (vectorizable_function): New dummy.
+ (vect_pattern_recog): Remove dummy.
+ * tree-vectorizer.h (vect_recog_func_ptr): Adjust types for tuples.
+ * tree-vect-patterns.c (File): Re-enable all code.
+ (widened_name_p): Tuplify.
+ (vect_recog_temp_ssa_var): New.
+ (vect_recog_dot_prod_pattern): Tuplify.
+ (vect_recog_widen_mult_pattern): Same.
+ (vect_recog_pow_pattern): Same.
+ (vect_recog_widen_sum_pattern): Same.
+ (vect_pattern_recog_1): Tuplify. Factor out code to create SSA
+ temporaries to vect_recog_temp_ssa_var. Remove code for building
+ assignment statement.
+ (vect_pattern_recog): Tuplify.
+
+2008-07-03 Janis Johnson <janis187@us.ibm.com>
+ David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/rs6000.c (rs6000_va_start): Unshare valist.
+ (rs6000_gimplify_va_arg): Unshare valist, reg, addr, ovf.
+
+2008-07-03 Jakub Jelinek <jakub@redhat.com>
+
+ * tree-inline.c (remap_gimple_op_r): Remap TREE_BLOCK of
+ expressions.
+
+ * tree-switch-conversion.c (gen_inbound_check): Force RHS to be
+ gimple operand. Use fold_build* instead of build*.
+ (build_arrays): Likewise. Convert RHS to LHS's type.
+
+ * tree-switch-conversion.c (struct switch_conv_info): Change
+ arr_ref_first and arr_ref_last to gimple.
+ (check_range, check_final_bb, gather_default_values,
+ build_constructors, build_one_array, build_arrays, gen_def_assign,
+ fix_phi_nodes, gen_inbound_check, process_switch, do_switchconv):
+ Tuplify.
+ (create_temp_arrays): Formatting.
+
+ * gimple.h (gimple_try_set_kind): New inline function.
+ * tree-eh.c (same_handler_p, optimize_double_finally,
+ refactor_eh_r, refactor_eh): Tuplify.
+ * passes.c (init_optimization_passes): Reenable pass_refactor_eh.
+
+2008-07-02 Jakub Jelinek <jakub@redhat.com>
+
+ * tree-parloops.c (struct reduction_info): Change reduc_stmt,
+ reduc_phi, keep_res and new_phi field types to gimple.
+ (struct elv_data): Add info field.
+ (reduction_phi, loop_parallel_p, take_address_of,
+ initialize_reductions, eliminate_local_variables_stmt,
+ eliminate_local_variables, expr_invariant_in_region_p,
+ separate_decls_in_region_name, separate_decls_in_region_stmt,
+ create_phi_for_local_result, create_call_for_reduction_1,
+ create_call_for_reduction, create_loads_for_reductions,
+ create_final_loads_for_reduction, create_stores_for_reduction,
+ create_loads_and_stores_for_name, separate_decls_in_region,
+ canonicalize_loop_ivs, transform_to_exit_first_loop,
+ create_parallel_loop, gen_parallel_loop,
+ loop_has_vector_phi_nodes, parallelize_loops): Tuplify.
+ * tree-cfg.c (gimple_duplicate_sese_tail): Tuplify.
+ (move_block_to_fn): Don't call gsi_next after calling
+ remove_phi_node.
+
+2008-07-02 Aldy Hernandez <aldyh@redhat.com>
+ Richard Guenther <rguenther@suse.de>
+
+ * tree-ssa-forwprop.c (can_propagate_from): Exclude loads
+ from decls explicitly.
+ (gate_forwprop): Enable.
+
+2008-07-02 Jakub Jelinek <jakub@redhat.com>
+
+ * tree-vectorizer.h (vinfo_for_stmt): Use htab_find_slot_with_hash.
+ (set_vinfo_for_stmt): Likewise. If info is NULL, delete entry from
+ hash table.
+ * tree-vectorizer.c (stmt_vec_info_eq, stmt_vec_info_hash): New
+ functions.
+ (init_stmt_vec_info_htab): Use them instead of htab_hash_pointer
+ and htab_eq_pointer.
+ (free_stmt_vec_info): Free stmt_info only after set_vinfo_for_stmt
+ call.
+
+ Merge with mainline @137346.
+
+ * configure.ac (ACX_PKGVERSION): Update revision merge string.
+ * configure: Regenerate.
+ * builtins.c (gimple_rewrite_call_expr): Fix -Wc++-compat and/or
+ -Wcast-qual warnings.
+ * gimple.c (gimple_alloc_stat, gimple_build_omp_for,
+ gimple_range_check_failed, gimple_copy): Likewise.
+ * tree-mudflap.c (mx_xfn_xform_decls): Likewise.
+ * tree-nested.c (convert_nonlocal_reference_stmt,
+ convert_local_reference_stmt): Likewise.
+ * gimple-iterator.c (gsi_insert_before_without_update,
+ gsi_insert_after_without_update): Likewise.
+ * tree-ssa-loop-im.c (init_lim_data, get_lim_data,
+ clear_lim_data): Likewise.
+ * tree-ssa-sccvn.c (vn_nary_op_insert_stmt): Likewise.
+ * tree-vrp.c (check_all_array_refs): Likewise.
+ * value-prof.c (histogram_eq): Likewise.
+ * cgraphbuild.c (record_reference): Don't handle OMP_PARALLEL
+ and OMP_TASK here.
+ (build_cgraph_edges): Handle GIMPLE_OMP_{PARALLEL,TASK}.
+ * cgraph.c (cgraph_add_new_function): Call gimple_register_cfg_hooks
+ instead of tree_register_cfg_hooks.
+ * omp-low.c (finalize_task_copyfn): Ensure the new function's
+ body is a gimple_seq with just GIMPLE_BIND in it.
+ (scan_omp_1_stmt): Fix -Wc++-compat and/or -Wcast-qual warnings.
+ * tree-cfg.c (move_stmt_op, have_similar_memory_accesses_1,
+ ref_base_address_1): Likewise.
+ (move_stmt_r): Handle gimple_block updating.
+ * tree-ssa-alias.c (update_alias_info_1): Tuplify.
+ (update_alias_info): Likewise.
+ * tree-switch-conversion.c: Stub out temporarily.
+
+2008-06-30 Aldy Hernandez <aldyh@redhat.com>
+
+ * tree-ssa-forwprop.c: Remove obsolete comment.
+ (get_prop_source_stmt): Wrap call to gimple_assign_lhs with a
+ TREE_TYPE.
+ (forward_propagate_comparison): Use build2 instead of
+ fold_binary.
+
+2008-06-27 Diego Novillo <dnovillo@google.com>
+
+ * cfgexpand.c (gimple_assign_rhs_to_tree): Factor out of ...
+ (gimple_to_tree): ... here.
+ Update comments referring to mainline merge.
+ * tree-ssa-ter.c: Tuplify.
+ * tree-outof-ssa.c (gimple_assign_rhs_to_tree): Declare.
+ (replace_use_variable): Call it.
+ (rewrite_trees): Tuplify.
+ (remove_ssa_form): Call it.
+ * gimple.h: Tidy some formatting.
+ * ipa-struct-reorg.c: Include gimple.h
+ * Makefile.in (ipa-struct-reorg.o): Add dependency on
+ GIMPLE_H.
+
+2008-06-27 Richard Guenther <rguenther@suse.de>
+
+ * tree-ssa-sccvn.c (vn_get_expr_for): New function.
+ (vuses_to_vec): Tuplify.
+ (copy_vuses_from_stmt): Likewise.
+ (vdefs_to_vec): Likewise.
+ (copy_vdefs_from_stmt): Likewise.
+ (shared_vuses_from_stmt): Likewise.
+ (copy_reference_ops_from_call): New function split out from
+ copy_reference_ops_from_ref.
+ (create_reference_ops_from_call): New function.
+ (shared_reference_ops_from_call): Likewise.
+ (get_def_ref_stmt_vuses): Tuplify.
+ (vn_reference_lookup): Likewise.
+ (vn_nary_op_lookup_stmt): New function.
+ (vn_nary_op_insert_stmt): Likewise.
+ (vn_phi_lookup): Tuplify.
+ (vn_phi_insert): Likewise.
+ (defs_to_varying): Likewise.
+ (visit_unary_op): Likewise.
+ (visit_binary_op): Likewise.
+ (visit_reference_op_call): New function.
+ (visit_reference_op_load): Tuplify.
+ (visit_reference_op_store): Likewise.
+ (visit_phi): Likewise.
+ (stmt_has_constants): New function.
+ (simplify_binary_expression): Tuplify.
+ (simplify_unary_expression): Likewise.
+ (try_to_simplify): Likewise.
+ (visit_use): Likewise.
+ (compare_ops): Likewise.
+ (DFS): Likewise.
+ (run_scc_vn): Likewise.
+ * tree-ssa-sccvn.h (shared_vuses_from_stmt): Adjust prototype.
+ (copy_vuses_from_stmt): Likewise.
+ (vn_get_expr_for): Declare.
+ (vn_nary_op_lookup_stmt): Likewise.
+ (vn_nary_op_insert_stmt): Likewise.
+ * tree-dfa.c (get_single_def_stmt): Tuplify.
+ (get_single_def_stmt_from_phi): Likewise.
+ (get_single_def_stmt_with_phi): Likewise.
+ * tree-ssa-pre.c (do_SCCVN_insertion): Use vn_get_expr_for.
+ (eliminate): Likewise.
+ (execute_pre): Enable SCCVN.
+ (gate_fre): Enable.
+ * tree-flow.h (get_single_def_stmt): Adjust prototype.
+ (get_single_def_stmt_from_phi): Likewise.
+ (get_single_def_stmt_with_phi): Likewise.
+ (vn_lookup_or_add_with_stmt): Likewise.
+ (vn_lookup_with_stmt): Likewise.
+ * gimple.c (gimple_fold): Fix.
+ * tree-vn.c (vn_add): Disable call to add_to_value.
+ (vn_add_with_vuses): Likewise.
+ (vn_lookup_with_stmt): Tuplify.
+ (vn_lookup_or_add_with_stmt): Likewise.
+
+2008-06-27 Aldy Hernandez <aldyh@redhat.com>
+
+ * gimple.c (gimple_cond_get_ops_from_tree): Handle TRUTH_NOT_EXPR.
+
+2008-06-25 Diego Novillo <dnovillo@google.com>
+
+ * gimple.h (enum gimple_rhs_class): Move from tree-gimple.h
+ (struct gimple_statement_base): Change CODE field to 8
+ bits.
+ Change SUBCODE field to 16 bits.
+ (gimple_set_subcode): Move to gimple.c.
+ (gimple_subcode): Remove.
+ (gimple_expr_type): Handle GIMPLE_ASSIGN, GIMPLE_CALL and
+ GIMPLE_COND explicitly.
+ Move earlier in the file.
+ (gimple_expr_code): New.
+ (gimple_omp_subcode): New.
+ (gimple_omp_set_subcode): New.
+ (gimple_omp_return_nowait_p): Call gimple_omp_subcode.
+ (gimple_omp_section_last_p): Likewise.
+ (gimple_omp_parallel_combined_p): Likewise.
+ (gimple_assign_rhs_code): New.
+ (gimple_assign_set_rhs_code): New.
+ (gimple_assign_cast_p): Call gimple_assign_rhs_code.
+ Handle VIEW_CONVERT_EXPR.
+ (gimple_call_tail_p): Access subcode field directly.
+ (gimple_call_cannot_inline_p): Likewise.
+ (gimple_call_return_slot_opt_p): Likewise.
+ (gimple_call_from_thunk_p): Likewise.
+ (gimple_call_va_arg_pack_p): Likewise.
+ (gimple_call_copy_flags): Likewise.
+ (gimple_cond_code): Likewise.
+ (gimple_cond_set_code): Likewise.
+ (gimple_cond_make_false): Likewise.
+ (gimple_cond_make_true): Likewise.
+ (gimple_asm_volatile_p): Likewise.
+ (gimple_asm_input_p): Likewise.
+ (gimple_eh_filter_must_not_throw): Likewise.
+ (gimple_eh_filter_set_must_not_throw): Likewise.
+ (gimple_try_kind): Likewise.
+ (gimple_try_catch_is_cleanup): Likewise.
+ (gimple_wce_cleanup_eh_only): Likewise.
+
+ * tree-vrp.c (simplify_div_or_mod_using_ranges): Call
+ gimple_assign_set_rhs_code instead of gimple_set_subcode.
+ (simplify_abs_using_ranges): Likewise.
+ * tree-complex.c (init_dont_simulate_again): Call
+ gimple_expr_code instead of gimple_subcode.
+ (complex_visit_stmt): Likewise.
+ (expand_complex_move): Call gimple_assign_rhs_code
+ instead of gimple_subcode.
+ (expand_complex_operations_1): Likewise.
+ * value-prof.c (gimple_divmod_fixed_value): Likewise.
+ (gimple_mod_pow2): Likewise.
+ (gimple_mod_subtract): Likewise.
+ (gimple_divmod_values_to_profile): Likewise.
+ * tree-ssa-alias-warnings.c (find_alias_site_helper):
+ Call gimple_assign_cast_p.
+ (already_warned_in_frontend_p): Likewise.
+ * gimple.def: Add comments warning about code orderings.
+ * omp-low.c (expand_omp_taskreg): Call gimple_omp_set_subcode.
+ (expand_omp_atomic_fetch_op): Call gimple_assign_rhs_code.
+ * tree-gimple.c (get_gimple_rhs_class): Move to gimple.c
+ (get_gimple_rhs_num_ops): Likewise.
+ (gimple_assign_rhs_code): Move to gimple.h.
+ * tree-gimple.h (enum gimple_rhs_class): Move to gimple.h.
+ * tree-ssa-ccp.c (fold_gimple_assign): Call
+ gimple_assign_rhs_code instead of gimple_subcode.
+ * tree-stdarg.c (va_list_counter_bump): Likewise.
+ (check_all_va_list_escapes): Likewise.
+ (execute_optimize_stdarg): Likewise.
+ * tree-ssa-math-opts.c (is_division_by): Likewise.
+ (replace_reciprocal): Likewise.
+ (execute_cse_reciprocals): Likewise.
+ (execute_convert_to_rsqrt): Likewise.
+ * tree-ssa-dom.c (initialize_hash_element): Likewise.
+ (simple_iv_increment_p): Likewise.
+ (gimple_assign_unary_useless_conversion_p): Likewise.
+ * tree-ssa-alias.c (is_escape_site): Call gimple_assign_cast_p.
+ * predict.c (expr_expected_value_1): Call gimple_assign_rhs_code
+ instead of gimple_subcode.
+ * tree-eh.c (tree_could_trap_p): Call gimple_expr_code
+ instead of gimple_subcode.
+ * ipa-type-escape.c (is_array_access_through_pointer_and_index):
+ Call gimple_assign_rhs_code instead of gimple_subcode.
+ (check_assign): Likewise.
+ * gimplify.c (gimplify_omp_parallel): Call gimple_omp_set_subcode
+ instead of gimple_set_subcode.
+ * tree-mudflap.c (mf_xform_derefs): Call gimple_assign_rhs_code
+ instead of gimple_subcode.
+ * tree-ssa-forwprop.c (get_prop_source_stmt): Likewise.
+ (can_propagate_from): Likewise.
+ (remove_prop_source_from_use): Likewise.
+ (forward_propagate_addr_into_variable_array): Likewise.
+ * tree-object-size.c (plus_stmt_object_size): Likewise.
+ (collect_object_sizes_for): Likewise.
+ (check_for_plus_in_loops_1): Likewise.
+ (check_for_plus_in_loops): Likewise.
+ * gimple.c (gimple_set_subcode): Move from gimple.h
+ (gimple_check_failed): Access subcode field directly.
+ (gimple_assign_single_p): Call gimple_assign_rhs_code
+ instead of gimple_subcode.
+ (gimple_assign_unary_nop_p): Likewise.
+ (gimple_get_lhs): Change argument type to const_gimple.
+ (gimple_could_trap_p): Call gimple_assign_rhs_code
+ instead of gimple_subcode.
+ (get_gimple_rhs_class): Move from tree-gimple.c.
+ (get_gimple_rhs_num_ops): Likewise.
+ * tree-ssa-structalias.c (update_alias_info): Call
+ gimple_assign_rhs_code instead of gimple_subcode.
+ (find_func_aliases): Likewise.
+ * tree-ssa-threadedge.c (record_temporary_equivalences_from_phis):
+ Likewise.
+
+2008-06-25 Doug Kwan <dougkwan@google.com>
+
+ * gimple-dummy.c: (vect_free_slp_tree) Remove dummy.
+ (vect_analyze_loop): Same.
+ (vectorizable_induction): New dummy.
+ (vectorizable_type_promotion): Same.
+ (vectorizable_type_demotion): Same.
+ (vectorizable_conversion): Same.
+ (vectorizable_operation): Same.
+ (vectorizable_assignment): Same.
+ (vectorizable_load): Same.
+ (vectorizable_call): Same.
+ (vectorizable_store): Same.
+ (vectorizable_condition): Same.
+ (vectorizable_reduction): Same.
+ (vectorizable_live_operation): Same.
+ (vect_estimate_min_profitable_iters): Same.
+ (vect_model_simple_cost): Same.
+ (vect_model_store_cost): Same.
+ (vect_model_load_cost): Same.
+ (vect_pattern_recog): Same.
+ * tree-vectorizer.h (struct _stmt_vec_info): Change fields FIRST_DR
+ and NEXT_DR from tree to gimple type.
+ (vectorizable_load): Change type of parameter STMT to gimple.
+ (vectorizable_store): Same.
+ (vectorizable_operation): Same.
+ (vectorizable_type_promotion): Same.
+ (vectorizable_type_demotion): Same.
+ (vectorizable_conversion): Same.
+ (vectorizable_assignment): Same.
+ (vectorizable_function): Same.
+ (vectorizable_call): Same.
+ (vectorizable_condition): Same.
+ (vectorizable_live_operation): Same.
+ (vectorizable_reduction): Same.
+ (vectorizable_induction): Same.
+ * tree-vect-analyze.c (File): Re-enable all previously disabled code.
+ (vect_determine_vectorization_factor): Tuplify.
+ (vect_analyze_operations): Same.
+ (exist_non_indexing_operands_for_use_p): Same.
+ (vect_analyze_scalar_cycles_1): Same.
+ (vect_insert_into_interleaving_chain): Same.
+ (vect_same_range_drs): Same.
+ (vect_compute_data_ref_alignment): Same.
+ (vect_verify_datarefs_alignment): Same.
+ (vector_alignment_reachable_p): Same.
+ (vect_enhance_data_refs_alignment): Same.
+ (vect_analyze_group_access): Same.
+ (vect_analyze_data_ref_access): Same.
+ (vect_free_slp_tree): Same.
+ (vect_get_and_check_slp_defs): Same.
+ (vect_build_slp_tree): Same.
+ (vect_print_slp_tree): Same.
+ (vect_mark_slp_stmts): Same.
+ (vect_analyze_slp_instance): Same.
+ (vect_analyze_slp): Same.
+ (vect_detect_hybrid_slp_stmts): Same.
+ (vect_analyze_data_refs): Same.
+ (vect_mark_relevant): Same.
+ (process_use): Same.
+ (vect_mark_stmts_to_be_vectorized): Same.
+ (vect_can_advance_ivs_p): Same.
+ (vect_get_loop_niters): Same.
+ (vect_analyze_loop_form): Same.
+
+2008-06-25 Diego Novillo <dnovillo@google.com>
+
+ * tree-vectorizer.c (hash_gimple_stmt): Remove.
+ (eq_gimple_stmt): Remove.
+ (init_stmt_vec_info_htab): Use htab_hash_pointer and
+ htab_eq_pointer for STMT_VEC_INFO_HTAB.
+
+2008-06-24 Doug Kwan <dougkwan@google.com>
+
+ * gimple-dummy.c (vect_set_verbosity_level): Remove.
+ (vectorize_loops): Same.
+ (vect_free_slp_tree): New dummy.
+ (vect_analyze_loop): Same.
+ (vect_transform_loop): Same.
+ * tree-vectorize.c (hashtab.h): New include.
+ (File): Re-enable all previously commented out code.
+ (stmt_vec_info_htab): New var.
+ (rename_variables_in_bb): Tuplify.
+ (slpeel_update_phis_for_duplicate_loop): Same.
+ (slpeel_update_phi_nodes_for_guard1): Same.
+ (slpeel_update_phi_nodes_for_guard2): Same.
+ (slpeel_make_loop_iterate_ntimes): Same.
+ (slpeel_tree_duplicate_loop_to_edge_cfg): Same.
+ (slpeel_add_loop_guard): Same.
+ (slpeel_can_duplicate_loop_p): Same.
+ (set_prologue_iterations): Same.
+ (find_loop_location): Same.
+ (new_stmt_vec_info): Same.
+ (hash_gimple_stmt): New function.
+ (init_stmt_vec_info_htab): New function.
+ (free_stmt_vec_info_htab): New function.
+ (free_stmt_vec_info): Replace statement info with hash table entry.
+ (new_loop_vec_info): Tuplify.
+ (destroy_loop_vec_info): Same.
+ (vect_supportable_dr_alignment): Same
+ (vect_is_simple_use): Same.
+ (supportable_widening_operation): Same.
+ (supportable_narrowing_operation): Same.
+ (report_vec_op): New function. Code factored out from ...
+ (vect_is_simple_reduction): Call it. Tuplify.
+ (vectorize_loops): Set up and tear down stmt_vec_info hash table.
+ * tree-vectorizer.h (struct _slp_tree): Change statement fields
+ (struct _loop_vec_info): Same.
+ (struct _stmt_vec_info):
+ (nested_in_vect_loop): Re-enable.
+ (init_stmt_vec_info_htab): New prototype.
+ (free_stmt_vec_info_htab): New prototype.
+ (vinfo_for_stmt): Use hash table instead of statement info.
+ (set_stmt_info): Remove.
+ (set_vinfo_for_stmt): New inline.
+ (is_pattern_stmt_p): Tuplify.
+ (vect_is_simple_use): Tuplify prototype.
+ (vect_is_simple_reduction): Same.
+ (supportable_widening_operation): Same.
+ (supportable_narrowing_operation): Same.
+ (new_stmt_vec_info): Same.
+ (free_stmt_vec_info): Same.
+ Makefile.in (tree-vectorize.o): Add HASTAB_H dependency.
+
+2008-06-22 Andrew Pinski <pinskia@gmail.com>
+
+ * gimple-pretty-print.c (dump_binary_rhs): Print out MIN_EXPR and
+ MAX_EXPR specially.
+
+2008-06-20 Doug Kwan <dougkwan@google.com>
+
+ * tree-loop-linear.c (File): Re-enable all previously disabled code.
+ (gather_interchange_stats): Tuplify.
+ (linear_transform_loops): Likewise.
+ * gimple-dummy.c (get_type): Remove unused dummy.
+ (ipa_add_method): Same.
+ (ipa_callsite_callee): Same.
+ (ipa_callsite_compute_count): Same.
+ (ipa_callsite_compute_param): Same.
+ (ipa_callsite_param): Same.
+ (ipa_callsite_param_count): Same.
+ (ipa_callsite_param_count_set): Same.
+ (ipa_edges_create): Same.
+ (ipa_edges_free): Same.
+ (ipa_free): Same.
+ (ipa_jf_get_info_type): Same.
+ (ipa_method_compute_modify): Same.
+ (ipa_method_compute_tree_map): Same.
+ (ipa_method_formal_compute_count): Same.
+ (ipa_method_formal_count): Same.
+ (ipa_method_formal_count_set): Same.
+ (ipa_method_get_tree): Same.
+ (ipa_method_modify_print): Same.
+ (ipa_method_tree_print): Same.
+ (ipa_methodlist_init): Same.
+ (ipa_methodlist_not_empty): Same.
+ (ipa_node_create): Same.
+ (ipa_nodes_create): Same.
+ (ipa_nodes_free): Same.
+ (ipa_remove_method): Same.
+ (vec_set_verbosity_level): Same.
+ * tree-ssa-loop.c (tree_linear_transform): Re-enable.
+
+2008-06-19 Jan Hubicka <jh@suse.cz>
+
+ * gimple.c (gimple_alloc): Annotate with MEM_STAT_INFO
+ (gimple_build_with_ops): Likewise.
+ (gimple_build_assign): Likewise.
+ (gimple_build_assign_with_ops): Likewise.
+ * gimple.h (gimple_build_assign, gimple_build_assign_with_ops):
+ Annotate with MEM_STAT_INFO.
+
+2008-06-17 Jan Hubicka <jh@suse.cz>
+
+ * config/i386.c (ix86_gimplify_va_arg): Fix sharing issue.
+
+2008-06-17 Jan Hubicka <jh@suse.cz>
+
+ * gimplify.c (gimplify_modify_expr): Unshare only returned value when
+ want_value is set instead of copying operands all the time.
+
+2008-06-17 Diego Novillo <dnovillo@google.com>
+
+ * tree-ssa-loop-niter.c (get_val_for): Fix FIXME note.
+
+2008-06-17 Steven Bosscher <stevenb.gcc@gmail.com>
+
+ * gimple-dummy.c (canonicalize_induction_variables): Remove dummy.
+ (remove_empty_loops): Likewise.
+ (tree_unroll_loops_completely): Likewise.
+ * tree-ssa-ivcanon.c (tree_num_loop_insns): Replace bsi with gsi.
+ (create_canonical_iv): Convert to tuples.
+ (try_unroll_loop_completely): Likewise.
+ (empty_loop_p): Likewise.
+ (remove_empty_loop): Likewise.
+ * tree-ssa-loop.c (tree_ssa_loop_ivcanon): Re-enable.
+ (tree_ssa_empty_loop): Likewise.
+ (tree_complete_unroll): Likewise.
+ (tree_complete_unroll_inner): Likewise.
+
+2008-06-16 Doug Kwan <dougkwan@google.com>
+
+ * tree-ssa-ifcombine.c (File): Re-enable all previously diabled code.
+ (bb_no_side_effects_p): Tuplify.
+ (same_phi_args_p): Likewise.
+ (get_name_for_bit_test): Likewise.
+ (operand_precision): New.
+ (integral_operand_p): New.
+ (recognize_single_bit_test): Tuplify.
+ (regcognize_bits_test): Tuplify.
+ (ifcombine_ifandif): Likewise.
+ (ifcombine_iforif): Likewise.
+ (tree_ssa_ifcombine): Likewise.
+ * passes.c: Re-enable pass_tree_ifcombine.
+
+2008-06-16 Doug Kwan <dougkwan@google.com>
+
+ * tree-ssa-loop-unswitch.c (File): Re-enable all previously disabled
+ code.
+ (tree_may_unswitch_on): Tuplify.
+ (simplify_using_entry_checks): Likewise.
+ (tree_unswitch_single_loop): Likewise.
+ * gimple-dummy.c (tree_ssa_unswitch_loops): Remove dummy.
+ * tree-ssa-loop.c (gate_tree_ssa_loop_unswitch): Re-enable.
+
+2008-06-16 Steven Bosscher <steven@gcc.gnu.org>
+
+ * tree-ssa-reassoc.c: Convrt to tuples.
+
+2008-06-15 Diego Novillo <dnovillo@google.com>
+
+ * tree-ssa-live.c (mark_all_vars_used_1): Mark as used
+ the TREE_BLOCK of any _EXPR node.
+
+2008-06-13 Doug Kwan <dougkwan@google.com>
+
+ * tree-mudflap.c (File): Re-enable previously disabled code.
+ (mf_decl_cache_locals): Tuplify.
+ (mf_build_check_statement_for): Likewise.
+ (mf_xform_derefs_1): Re-enable.
+ (mf_xform_derefs): Tuplify.
+ (execute_mudflap_function_decls): Likewise.
+ (mx_register_decls): Tuplify. Add a new formal parameter for
+ the location of newly generated statements. Change function to
+ return modified gimple sequence instead of of modifying in-place.
+ (mx_xfn_xform_decls): Tuplify.
+ (mf_xform_decls): Tuplify.
+ * passes.c (init_optimization_passes): Re-enable mudflap passes.
+
+2008-06-13 Jakub Jelinek <jakub@redhat.com>
+
+ Merge with mainline @136757.
+
+ * configure.ac (ACX_PKGVERSION): Update revision merge string.
+ * configure: Regenerate.
+
+2008-06-13 Doug Kwan <dougkwan@google.com>
+
+ * ipa-reference.c (scan_stmt_for_static_refs): Rename walk_subtrees
+ parameter to handled_ops_p and correct bug of using walk_tree callback
+ semantics.
+ * ipa-pure-const.c (scan_function_stmt): Likewise.
+ * tree-inline.c (mark_local_labes_stmt): Rename walk_subtrees
+ parameter to handle_ops_p.
+ (replace_locals_stmt): Likewise.
+
+2008-06-10 Steven Bosscher <steven@gcc.gnu.org>
+
+ * passes.c (init_optimization_passes): Re-enable pass_uncprop.
+ * tree-ssa-uncprop (associate_equivalences_with_edges): Convert
+ to tuples.
+ (uncprop_into_successor_phis): Likewise.
+
+2008-06-09 Diego Novillo <dnovillo@google.com>
+
+ * ipa-cp.c (cgraph_gate_cp): Fix 'FIXME tuples' note.
+ * cfg.c (compact_blocks): Likewise.
+ * dominance.c (free_dominance_info): Likewise.
+ * gimple-low.c (gimple_stmt_may_fallthru): Likewise
+ * c-gimplify.c (add_block_to_enclosing): Likewise.
+ * lambda-mat.c: Include tree-flow.h.
+ * lambda-trans.c: Likewise.
+ * Makefile.in (lambda-mat.o, lambda-trans.o): Add dependency
+ on $(TREE_FLOW_H).
+ * builtins.c (expand_builtin_setjmp_receiver): Remove #if 0 markers.
+ (fold_call_stmt): Call gimple_call_va_arg_pack_p.
+ * tree-gimple.h (gimple_bind_expr_stack): Declare.
+ * cgraphunit.c (update_call_expr): Do not try to access operand 0
+ of a FUNCTION_DECL.
+ * tree-ssa-loop-ivopts.c (stmt_invariant_in_loop_p): New.
+ * tree-flow.h (stmt_invariant_in_loop_p): Declare.
+ * gimple-dummy.c (remove_iv): Remove.
+ (gimple_stmt_may_fallthru):
+ * ipa-type-escape.c (check_tree): Call DECL_P before testing
+ DECL_INITIAL.
+ (check_assign): Do not access TREE_OPERAND 0 on the RHS
+ operand.
+ * gimplify.c (gimple_bind_expr_stack): New.
+ * gimple.h (struct gimple_statement_bind): Add more comments
+ for field BLOCK.
+ (gimple_cond_set_condition): New.
+ * gimple.c (gimple_cond_set_condition_from_tree): Call it.
+ (gimple_copy_no_def_use): Remove. Update all users.
+ (gimple_has_side_effects):
+ (gimple_rhs_has_side_effects):
+ * passes.c (init_optimization_passes): Enable
+ pass_release_ssa_names, pass_ipa_type_escape, pass_ipa_pta,
+ pass_ipa_struct_reorg, pass_record_bounds,
+ pass_late_warn_uninitialized and pass_rename_ssa_copies.
+
+ * lambda-code.c: Tuplify.
+ * ipa-struct-reorg.c: Tuplify.
+ * ipa-struct-reorg.h: Tuplify.
+
+2008-06-09 Jakub Jelinek <jakub@redhat.com>
+
+ * gimplify.c (gimplify_omp_for): Call gimple_omp_for_set_incr
+ with the RHS of the GIMPLE_MODIFY_STMT instead of the
+ GIMPLE_MODIFY_STMT itself.
+ * gimple-pretty-print.c (dump_gimple_omp_for): Adjust for it.
+ * tree-nested.c (walk_gimple_omp_for): Likewise.
+ * omp-low.c (extract_omp_for_data, lower_omp_for): Likewise.
+
+2008-06-09 Aldy Hernandez <aldyh@redhat.com>
+
+ * tree-ssa-forwprop.c (forward_propagate_into_cond): First argument is
+ a GSI.
+ (forward_propagate_addr_into_variable_array_index): Accept a GSI
+ instead of a gimple statement. Update accordingly.
+ (forward_propagate_addr_expr_1): Same.
+ (forward_propagate_addr_expr): Pass a GSI to
+ forward_propagate_addr_expr_1.
+ (simplify_not_neg_expr): Argument is a GSI.
+ Adjust accordingly.
+ (tree_ssa_forward_propagate_single_use_va): Pass GSI to
+ simplify_not_neg_expr and forward_propagate_into_cond.
+
+2008-06-09 Aldy Hernandez <aldyh@redhat.com>
+
+ * tree.h (IS_CONVERT_EXPR_P): New.
+ (CONVERT_EXPR_P): Use IS_CONVERT_EXPR_P.
+ * tree-ssa-forwprop.c (get_prop_dest_stmt): Convert to tuples.
+ (get_prop_source_stmt): Same.
+ (can_propagate_from): Same.
+ (remove_prop_source_from_use): Same.
+ (combine_cond_expr_cond): Same.
+ (forward_propagate_into_cond): Same.
+ (tidy_after_forward_propagate_addr): Same.
+ (forward_propagate_addr_into_variable_array_index): Same.
+ (forward_propagate_addr_expr_1): Same.
+ (forward_propagate_addr_expr): Same.
+ (forward_propagate_comparison): Same.
+ (simplify_not_neg_expr): Same.
+ (tree_ssa_forward_propagate_single_use_vars): Same.
+ (simplify_gimple_switch): Rename from -simplify_switch_expr.
+ (rhs_to_tree): New.
+ (forward_propagate_into_gimple_cond): New.
+ * Makefile.in (tree-ssa-forwprop.o): Depend on GIMPLE_H.
+ * passes.c (init_optimization_passes): Enable pass_forwprop.
+
+2008-06-09 Jakub Jelinek <jakub@redhat.com>
+
+ * tree.def (OMP_SECTIONS_SWITCH, OMP_ATOMIC_LOAD, OMP_ATOMIC_STORE):
+ Removed.
+ * tree-gimple.c (is_gimple_stmt): Don't handle them.
+ * gimplify.c (gimplify_expr): Likewise.
+ * tree-pretty-print.c (dump_generic_node): Likewise.
+ * tree-ssa-operands.c (get_expr_operands): Likewise.
+ * expr.c (expand_expr_real_1): Likewise.
+ * omp-low.c (expand_omp_atomic_pipeline): Adjust comment.
+
+2008-06-09 Jakub Jelinek <jakub@redhat.com>
+
+ Merge with mainline @136433.
+
+ * configure.ac (ACX_PKGVERSION): Update revision merge string.
+ * configure: Regenerate.
+
+2008-06-08 Diego Novillo <dnovillo@google.com>
+
+ Merge with mainline @136432.
+
+ * configure.ac (ACX_PKGVERSION): Update revision merge string.
+ * configure: Regenerate.
+
+2008-06-08 Diego Novillo <dnovillo@google.com>
+
+ * tree-call-cdce.c: Tuplify.
+
+2008-06-06 Diego Novillo <dnovillo@google.com>
+
+ http://gcc.gnu.org/ml/gcc-patches/2008-06/msg00353.html
+
+ * gimple.def: Add a third argument to all GIMPLE codes.
+ Update all users.
+ * calls.c (gimple_alloca_call_p): Fix comment.
+ * system.h (CONST_CAST_GIMPLE): Define.
+ * gimple.c (gimple_ops_offset_): Declare. Fill in from
+ third argument in gimple.def.
+ (gimple_set_stored_syms, gimple_set_loaded_syms): Move
+ from tree-ssa-operands.c
+ (gimple_alloc): Add argument NUM_OPS. Update all users.
+ Compute size by adding enough space for NUM_OPS operands.
+ (gimple_alloc_ops): Remove. Update all users.
+ (gimple_assign_set_rhs_from_tree): Change first argument
+ to gimple_stmt_iterator *. Update all users.
+ Allocate a new statement, if there are more operands that
+ can fit in the old one.
+ (gimple_assign_set_rhs_with_ops): Likewise.
+ (gimple_copy): Fix clearing of stores/loads sets in the
+ copied statement.
+ * gimple.h (struct gimple_statement_base): Remove fields
+ UNUSED_1, UNUSED_2, UNUSED_3.
+ Add fields MODIFIED, HAS_VOLATILE_OPS, REFERENCES_MEMORY_P,
+ UID and NUM_OPS.
+ Re-organize existing fields to eliminate holes on 64 bit
+ hosts.
+ Update all users.
+ (struct gimple_statement_with_ops_base): Define.
+ Factor out struct gimple_statement_with_ops. Include fields GSBASE,
+ ADDRESSES_TAKEN, DEF_OPS and USE_OPS.
+ (struct gimple_statement_with_ops): Include struct
+ gimple_statement_with_ops_base.
+ Remove field NUM_OPS.
+ (struct gimple_statement_with_memory_ops_base): Define.
+ Factor out of struct gimple_statement_with_memory_ops.
+ Include fields OPBASE, VDEF_OPS, VUSE_OPS, STORES and
+ LOADS.
+ Remove fields HAS_VOLATILE_OPS and REFERENCES_MEMORY_P.
+ (struct gimple_statement_with_memory_ops): Include
+ struct gimple_statement_with_memory_ops_base.
+ (struct gimple_statement_phi): Change size_t fields to
+ unsigned. Update all users.
+ (struct gimple_statement_asm): Include struct
+ gimple_statement_with_memory_ops_base.
+ Change fields NI and NO to unsigned char.
+ Change field NC to short.
+ Update all users.
+ Add field OP.
+ (struct gimple_statement_change_dynamic_type): Remove.
+ Update all users.
+ (union gimple_statement_d): Rename field WITH_OPS to GSOPS.
+ Rename field WITH_MEM_OPS to GSMEM.
+ Update all users.
+ (gimple_addresses_taken): New.
+ (gimple_addresses_taken_ptr): New.
+ (gimple_set_addresses_taken): New.
+ (gimple_num_ops): Move earlier.
+ (gimple_ops): Use gimple_ops_offset_ to compute address
+ of the operand vector.
+ (gimple_op): Call gimple_ops.
+ (gimple_op_ptr): Likewise.
+ (gimple_set_op): Likewise.
+ (gimple_switch_num_labels): Call gimple_num_ops.
+ (gimple_switch_set_num_labels): Call gimple_set_num_ops.
+ (gimple_switch_set_label): Call gimple_num_ops.
+ (gimple_return_retval_ptr): Likewise.
+ (gimple_return_retval): Likewise.
+ (gimple_set_retval): Likewise.
+ (gimple_cdt_new_type): Use operand 1.
+ (gimple_cdt_new_type_ptr): Likewise.
+ (gimple_cdt_set_new_type): Likewise.
+ * tree-cfg.c (gimple_block_ends_with_call_p): Use
+ CONST_CAST_BB.
+ * tree-ssa-operands.c (gimple_set_stored_syms,
+ gimple_set_loaded_syms): Declare.
+ * value-prof.c (gimple_divmod_fixed_value_transform,
+ gimple_mod_pow2_value_transform,
+ gimple_mod_subtract_transform): Change argument to
+ gimple_stmt_iterator *. Update all users.
+ * tree-ssa-ccp.c (fold_gimple_assign): Change parameter
+ to gimple_stmt_iterator *. Update all users
+
+2008-06-05 Jakub Jelinek <jakub@redhat.com>
+
+ * gimplify.c (gimplify_modify_expr_to_memcpy): Use gimplify_arg
+ for gimplification of call arguments.
+ (gimplify_modify_expr_to_memset): Likewise.
+
+2008-06-02 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/36389
+ * gimplify.c (gimplify_cond_expr): If one or both branches are
+ GOTO_EXPRs jumping to LABEL_DECLs, don't create unnecessary
+ extra LABEL_DECLs and jumps around.
+ * tree-cfg.c (remove_useless_stmts_cond): Set may_branch also
+ for GIMPLE_COND stmts.
+ * tree-eh.c (replace_goto_queue_cond_clause): Set label to
+ create_artificial_label () rather than LABEL_EXPR.
+
+2008-05-30 Diego Novillo <dnovillo@google.com>
+
+ * calls.c (gimple_alloca_call_p): Fix detection of
+ alloca() calls.
+
+2008-05-30 Diego Novillo <dnovillo@google.com>
+
+ * toplev.c: Include gimple.h.
+ (dump_memory_report): Call dump_gimple_statistics.
+ * Makefile.in (toplev.o): Add dependency on GIMPLE_H.
+ * gimple-low.c (pass_lower_cf): Restore disabled bits.
+ * tree-dfa.c (pass_referenced_vars): Likewise.
+ * cfgexpand.c (pass_expand): Likewise.
+ * tree-outof-ssa.c (pass_del_ssa): Likewise.
+ * gimple.c (gimple_alloc): Fix non-C99 declaration.
+ * gimplify.c (gimplify_function_tree): Remove calls to
+ dump_tree_statistics and dump_gimple_statistics.
+
+2008-05-30 Jakub Jelinek <jakub@redhat.com>
+
+ * omp-low.c (diagnose_omp_structured_block_errors): Temporarily
+ switch cfun to DECL_STRUCT_FUNCTION (fndecl).
+
+ * omp-low.c (scan_sharing_clauses): Call scan_omp on
+ OMP_CLAUSE_REDUCTION_GIMPLE_{INIT,MERGE} instead of
+ scan_omp_op on OMP_CLAUSE_REDUCTION_{INIT,MERGE}.
+ (lower_rec_input_clauses): Clear
+ OMP_CLAUSE_REDUCTION_GIMPLE_{INIT,MERGE} instead of
+ OMP_CLAUSE_REDUCTION_{INIT,MERGE}. Call lower_omp
+ on OMP_CLAUSE_REDUCTION_GIMPLE_MERGE before gimple_seq_add_seq
+ to replace all occurences of placeholder in the seq.
+ * gimplify.c (gimplify_scan_omp_clauses): Clear
+ OMP_CLAUSE_REDUCTION_{INIT,MERGE} after gimplifying it.
+
+ * tree-nested.c (init_tmp_var_with_call, init_tmp_var, save_tmp_var):
+ Only set location if not gsi_end_p.
+ (walk_gimple_omp_for): Avoid adding an empty statement to seq.
+
+ * tree-inline.c (remap_gimple_stmt): Remap body of
+ GIMPLE_OMP_{MASTER,ORDERED,SECTION,SECTIONS,SINGLE}.
+
+2008-05-28 Andrew Pinski <pinskia@gmail.com>
+
+ * gimple-pretty-print.c (dump_unary_rhs): Handle conversions correctly.
+ Handle PAREN_EXPR, ABS_EXPR, and NEGATE_EXPR.
+
+2008-05-29 Jakub Jelinek <jakub@redhat.com>
+
+ * omp-low.c (lower_omp_1): Handle regimplification of GIMPLE_ASM.
+ Fix GIMPLE_ASSIGN regimplification.
+ * gimple-pretty-print.c (dump_gimple_omp_sections,
+ dump_gimple_omp_block, dump_gimple_omp_critical): New functions.
+ (dump_gimple_omp_parallel): Formatting.
+ (dump_gimple_stmt): Handle remaining GIMPLE_OMP_* statements.
+
+2008-05-29 Aldy Hernandez <aldyh@redhat.com>
+
+ * tree-inline.c (remap_gimple_stmt): Handle GIMPLE_OMP_* cases.
+
+2008-05-29 Aldy Hernandez <aldyh@redhat.com>
+
+ * gimple-pretty-print.c (dump_gimple_stmt): Add cases for
+ GIMPLE_OMP_MASTER and GIMPLE_OMP_ORDERED.
+
+2008-05-29 Aldy Hernandez <aldyh@redhat.com>
+
+ * omp-low.c (expand_omp_parallel): Parse an assignment from an
+ ADDR_EXPR correctly.
+ * gimple-pretty-print.c (dump_gimple_omp_parallel): Print braces when
+ appropriate.
+
+2008-05-29 Jakub Jelinek <jakub@redhat.com>
+
+ * omp-low.c (lower_omp_1): Fix regimplification of GIMPLE_COND and
+ GIMPLE_CALL.
+
+2008-05-28 Jakub Jelinek <jakub@redhat.com>
+
+ * gimple.c (gimple_regimplify_operands): Don't call gimple_num_ops
+ twice. Write regimplified operand to the correct operand slot.
+ * gimplify.c (rhs_predicate_for): No longer static.
+ * tree-gimple.h (rhs_predicate_for): New prototype.
+ * omp-low.c (lower_omp_1): Don't call gimple_regimplify_operands,
+ instead forcefully gimplify_expr each operand with the right
+ predicate.
+
+ * gimple.h (gimple_omp_atomic_store_val_ptr,
+ gimple_omp_atomic_load_lhs_ptr, gimple_omp_atomic_load_rhs_ptr): New
+ inlines.
+ * gimple.c (walk_gimple_op): Handle GIMPLE_OMP_ATOMIC_LOAD and
+ GIMPLE_OMP_ATOMIC_STORE.
+ * omp-low.c (lower_omp_1): Handle GIMPLE_OMP_ATOMIC_LOAD.
+
+ * gimple-pretty-print.c (dump_gimple_omp_for): Don't indent twice
+ before gimple_omp_body, don't emit extra newline after it.
+ (dump_gimple_omp_single): Likewise.
+
+2008-05-27 Aldy Hernandez <aldyh@redhat.com>
+
+ * tree-nested.c (walk_omp_for): Rename to...
+ (walk_gimple_omp_for): Enable and convert to tuples.
+ (convert_nonlocal_reference_stmt): Enable call to walk_gimple_omp_for.
+ (convert_local_reference_stmt): Same.
+ * gimple.c (walk_gimple_op): Remove fixme note.
+
+2008-05-27 Diego Novillo <dnovillo@google.com>
+
+ * tree-gimple.c (get_gimple_rhs_class): Handle
+ POLYNOMIAL_CHREC.
+ * tree-cfg.c (verify_types_in_gimple_assign): Do not
+ check every operand against the LHS type for tcc_binary
+ expressions.
+
+2008-05-26 Diego Novillo <dnovillo@google.com>
+
+ Merge with mainline @135951.
+
+ * configure.ac (ACX_PKGVERSION): Update revision merge string.
+ * configure: Regenerate.
+
+2008-05-22 Aldy Hernandez <aldyh@redhat.com>
+
+ * tree-cfg.c (make_edges): Change OMP_SECTION to GIMPLE_OMP_SECTIONS.
+ Update comments.
+ (verify_types_in_gimple_stmt): Update comments.
+ (verify_stmt): Same.
+
+2008-05-21 Andreas Tobler <a.tobler@schweiz.org>
+
+ * ../configure: Regenerate with the correct autoconf version: 2.59.
+
+2008-05-21 Aldy Hernandez <aldyh@redhat.com>
+
+ * omp-low.c (lower_reduction_clauses): Generate OMP_ATOMIC_* directly.
+ Concatenate atomic code correctly.
+
+2008-05-20 Aldy Hernandez <aldyh@redhat.com>
+
+ * omp-low.c (WALK_SUBSTMTS): New.
+ (check_combined_parallel): Walk sub-statements.
+ (diagnose_sb_1): Same.
+ (diagnose_sb_2): Same.
+ Handle switch labels and return statements correctly.
+ * testsuite/gcc.dg/gomp/block-7.c: Adjust for new error message.
+ * testsuite/gcc.dg/gomp/block-2.c: Same.
+ * testsuite/gcc.dg/gomp/block-4.c: Same.
+ * testsuite/gcc.dg/gomp/block-6.c: Same.
+ * testsuite/gcc.dg/gomp/block-8.c: Same.
+ * testsuite/gcc.dg/gomp/block-1.c: Same.
+ * testsuite/gcc.dg/gomp/block-3.c: Same.
+ * testsuite/gcc.dg/gomp/block-5.c: Same.
+
+2008-05-20 Aldy Hernandez <aldyh@redhat.com>
+
+ * omp-low.c (lower_omp_single): Append to bind variables.
+ (lower_omp_master): Same.
+ (lower_omp_ordered): Same.
+ (lower_omp_critical): Same.
+ * gimplify.c (gimplify_modify_expr_to_memcpy): Make sure we are
+ fully gimplified.
+ (gimplify_omp_for): Same.
+ * gimple.h (gimple_bind_set_vars): New.
+
+2008-05-16 Andreas Tobler <a.tobler@schweiz.org>
+
+ * config/alpha/alpha.c (alpha_gimplify_va_arg): Adjust arguments.
+ * config/ia64/ia64.c (ia64_gimplify_va_arg): Likewise.
+ * config/pa/pa.c (hppa_gimplify_va_arg_expr): Likewise.
+ * config/m32c/m32c-protos.h (m32c_gimplify_va_arg_expr): Likewise.
+ * config/spu/spu.c (spu_gimplify_va_arg_expr): Likewise.
+ * config/stormy16/stormy16.c (xstormy16_gimplify_va_arg_expr): Likewise.
+ * config/xtensa/xtensa.c (xtensa_gimplify_va_arg_expr): Likewise.
+
+ * config/sparc/sparc.c (sparc_gimplify_va_arg): Adjust arguments.
+
+2008-05-16 Diego Novillo <dnovillo@google.com>
+
+ * tree-into-ssa.c (rewrite_uses_p): Fix return type.
+ * tree-vectorizer.h (nested_in_vect_loop_p): Add return value.
+ * tree-ssa-pre.c (execute_pre): Add return value.
+
+2008-05-15 Aldy Hernandez <aldyh@redhat.com>
+
+ * config/s390/s390.c (s390_gimplify_va_arg): Adjust for tuples.
+
+2008-05-15 Diego Novillo <dnovillo@google.com>
+
+ * Makefile.in (STRICT_WARN): Revert to mainline behaviour.
+ (builtins.o-warn, expr.o-warn, dse.o-warn,
+ ebitmap.o-warn, lower-subreg.o-warn, tree-chrec.o-warn,
+ tree-ssa-structalias.o-warn, varasm.o-warn): Remove.
+ * config/arm/arm.c (arm_return_in_memory): Fix return type.
+ * config/arm/arm-protos.h (arm_return_in_memory): Likewise.
+
+2008-05-15 Aldy Hernandez <aldyh@redhat.com>
+
+ * gimplify.c (gimplify_omp_for): Handle a MODIFY_EXPR in
+ gimple_omp_for_incr.
+ * cfgexpand.c (gimple_to_tree): Do not die on compile errors.
+
+2008-05-15 Aldy Hernandez <aldyh@redhat.com>
+
+ * omp-low.c (check_omp_nesting_restrictions): Fetch clauses from for.
+ (expand_omp_atomic): Parse GIMPLE_OMP_ATOMIC correctly.
+ (lower_omp_single_simple): Create GIMPLE_COND with both tlabel and
+ flabel.
+ (lower_omp_for): Make sure we have a body before look inside.
+ * gimple-low.c (lower_stmt): Add case for GIMPLE_OMP_SECTIONS_SWITCH.
+ * gimple-pretty-print.c (dump_gimple_omp_single): New.
+ (dump_gimple_stmt): Add case for GIMPLE_OMP_SINGLE.
+ * gimplify.c (gimplify_omp_workshare): Remove fixme. Enable code.
+ * gimple.c (gss_for_code): Add case for GIMPLE_OMP_{RETURN,
+ SECTIONS_SWITCH}.
+ (gimple_regimplify_operands): Do not regimplify GIMPLE_ASM
+ operands. Do not look inside empty operands.
+ * gimple.h (is_gimple_omp): Fix typo for GIMPLE_OMP_ATOMIC*.
+ * tree-cfg.c (make_edges): Rename OMP_SECTION to GIMPLE_OMP_SECTION.
+
+2008-05-14 Aldy Hernandez <aldyh@redhat.com>
+
+ * omp-low.c (optimize_omp_library_calls): Make sure statement is
+ a GIMPLE_CALL before we look inside of it.
+ * tree-cfg.c (move_stmt_op): Exit gracefully.
+
+2008-05-13 Aldy Hernandez <aldyh@redhat.com>
+
+ * omp-low.c (scan_omp_op): Remove walk_subtrees. Call walk_tree.
+ (scan_omp_for): Scan OMP body.
+ (scan_omp_1_stmt): Set handled_ops_p.
+ (expand_omp_parallel): Parse ADDR_EXPR correctly.
+ (diagnose_sb_1): Rename walk_subtrees to handled_ops_p and set
+ appropriately.
+ (diagnose_sb_2): Same.
+ * gimple-pretty-print.c (dump_gimple_omp_for): Print braces around
+ OMP body.
+ * tree-inline.c (estimate_num_insns): GIMPLE_OMP_CONTINUE does not
+ have a body.
+ * tree-cfg.c (move_stmt_op): Parse move_stmt_d out of data correctly.
+ (move_stmt_r): Rename walk_subtrees to handled_ops_p and set
+ appropriately.
+
+2008-05-12 Diego Novillo <dnovillo@google.com>
+
+ Merge with mainline @135126.
+
+ * configure.ac (ACX_PKGVERSION): Update revision merge string.
+ * configure: Regenerate.
+
+2008-05-11 Doug Kwan <dougkwan@google.com>
+
+ * gimplify.c (gimple_pop_condition): Clear
+ conditional_cleanups field after the associated gimple sequence has
+ been freed implicitly.
+ (gimplify_cleanup_point_expr): Clear conditional_cleanups field
+ of gimplfiy_ctxp after resetting the conditions field.
+ * gimple.h (gimple_call_return_type): Handle REFERENCE_TYPE like
+ POINTER_TYPE.
+
+2008-05-10 Kaz Kojima <kkojima@gcc.gnu.org>
+
+ * config/sh/sh.c (sh_gimplify_va_arg_expr): Change pre_p and
+ post_p types to gimple_seq *.
+
+2008-05-09 Aldy Hernandez <aldyh@redhat.com>
+
+ * omp-low.c (maybe_catch_exception): Return body when no exceptions.
+ (gate_lower_omp): Enable pass.
+ * gimple-low.c (lower_stmt): Add GIMPLE_OMP_ATOMIC_* cases.
+
+2008-05-08 Aldy Hernandez <aldyh@redhat.com>
+
+ * omp-low.c (extract_omp_for_data): Update comment.
+ (get_ws_args_for): Same.
+ (lower_send_shared_vars): Same.
+ (expand_omp_parallel): Same.
+ (expand_omp_for_static_nochunk): Same.
+ (expand_omp_for_static_chunk): Same.
+ (expand_omp_sections): Same.
+ (expand_omp_atomic_fetch_op): Same.
+ (expand_omp_atomic_pipeline): Same.
+ (build_omp_regions_1): Same.
+ (lower_omp_for): Same.
+ (expand_omp_atomic_mutex): Change OMP_ATOMIC_STORE to
+ GIMPLE_OMP_ATOMIC_STORE.
+ * gimple-pretty-print.c (dump_gimple_omp_parallel): Print child fn
+ and data_arg.
+ * tree-cfg.c (make_edges): Enable commented out code and convert
+ to tuples.
+ (replace_by_duplicate_decl): Same.
+ (replace_ssa_name): Same.
+ (move_stmt_r): Same.
+ (move_stmt_op): New.
+ (mark_virtual_ops_in_bb): Enable and convert to tuples.
+ (makr_virtual_ops_in_region): Same.
+ (move_block_to_fn): Convert to tuples.
+ (find_outermost_region_in_block): Enable and convert to tuples.
+ (move_sese_region_to_fn): Same.
+
+2008-05-05 Aldy Hernandez <aldyh@redhat.com>
+
+ * omp-low.c (expand_omp_parallel): Remove fixmes.
+ (expand_omp_for_static_chunk): Enable and tuplify code.
+ (expand_omp_sections): Remove fixmes. Tuplify.
+ (lower_omp_sections): Same.
+ (diagnose_sb_0): Remove fixme.
+ * tree-ssa.c (redirect_edge_var_map_dup): Fix typo in comment.
+ * gimple.c (gimple_size): Add case for GIMPLE_OMP_SECTIONS_SWITCH.
+ (gimple_build_omp_sections): New.
+ * gimple.h (gimple_build_omp_sections_switch): New prototype.
+
+2008-05-03 Aldy Hernandez <aldyh@redhat.com>
+
+ * omp-low.c (diagnose_sb_0): Tuplify and enable.
+ (diagnose_sb_1): Same.
+ (diagnose_sb_2): Same.
+ (diagnose_omp_structured_block_errors): Tuplify.
+ * gimple-dummy.c (DUMMY_FN): Remove
+ diagnose_omp_structured_block_errors.
+ * c-decl.c (c_gimple_diagnostics_recursively): Remove fixme
+ and enable call to diagnose_omp_structured_block_errors.
+ * Makefile.in (GTFILES): Add omp-low.c again.
+
+2008-05-02 Rafael Espindola <espindola@google.com>
+
+ * tree-gimple.c (is_gimple_condexpr): Do not allow
+ trapping comparisons.
+ * tree-eh.c (tree_could_trap_p): Fix handling of floating
+ point comparisons.
+
+2008-05-02 Doug Kwan <dougkwan@google.com>
+
+ * value-prof.c (gimple_divmod_fixed_value): Remove formal parameters
+ OPERATION, OP1 and OP2 and derive their values from parameter STMT
+ instead. Update prototype and caller.
+ (gimple_mod_pow2): Remove formal parameters OPERATION, OP1 and OP2
+ and derive their values from parameter STMT instead. Update prototype
+ and caller.
+ (gimple_mod_pow2_value_transform): Remove temporares OP, OP1 and OP2.
+ Use a new tempory LHS_TYPE to store assignment LHS type.
+ (gimple_mode_subtract): Remove formal parameters OPERATION, OP1 and OP2
+ and derive their values from parameter STMT instead. Update prototype
+ and caller. Fix a bug in a call to gimple_build_assign_with_ops.
+ (gimple_mod_subtract_transform): Remove temporares OP, OP1 and OP2.
+ Use a new tempory LHS_TYPE to store assignment LHS type.
+ (gimple_ic, gimple_indirect_call_to_profile): Fix bug in tree-code
+ tests.
+ * tree-profile.c (File): Re-enable all previously disabled code.
+ (tree_gen_edge_profiler): Tuplify.
+ (prepare_instrumented_value): Ditto.
+ (tree_gen_interval_profiler): Ditto.
+ (tree_gen_pow2_profiler): Ditto.
+ (tree_gen_one_value_profiler): Ditto.
+ (tree_gen_ic_profiler): Ditto.
+ (tree_gen_ic_func_profiler): Ditto.
+ (tree_gen_const_delta_profiler): Re-format formal parameters for
+ proper alignement.
+ (tree_gen_average_profiler): Tuplify.
+ (tree_gen_ior_profiler): Ditto.
+ (do_tree_profiling): Re-enable previously disabled code. Remove
+ FIXME.
+ (tree_profiling): Ditto.
+ * gimple.c (gimple_set_bb): Remove assertion.
+ * tree-cfg.c (change_bb_for_stmt): Remove. Redirect callers to
+ gimple_set_bb.
+ (gimple_merge_blocks): Call gimple_set_bb instead of
+ change_bb_for_stmt.
+ (gimple_split_block): Ditto.
+ (verify_stmts): Add code to check that label_to_block_map and labels
+ are consistent.
+
+2008-04-22 Rafael Espindola <espindola@google.com>
+
+ Merge with mainline @134843.
+
+ * configure.ac (ACX_PKGVERSION): Update revision merge string.
+ * configure: Regenerate.
+
+2008-05-01 Diego Novillo <dnovillo@google.com>
+
+ http://gcc.gnu.org/ml/gcc-patches/2008-05/msg00053.html
+
+ * tree-vrp.c (vrp_visit_phi_node): Cast variable I to int
+ for printing.
+ * cgraph.c (cgraph_release_function_body): Only call
+ gimple_set_body if NODE->DECL has a struct function.
+ * tree.c (make_node_stat): Do not call gimple_set_body.
+ * cp/Make-lang.in (cp/semantics.o): Add dependency on
+ $(GIMPLE_H).
+ * cp/semantics.c: Include gimple.h
+ (expand_or_defer_fn): Assert that FN has a gimple body.
+ * function.h (struct function): Add field GIMPLE_BODY.
+ * gimple.c (gimple_bodies_vec): Remove.
+ (gimple_bodies_map): Remove.
+ (gimple_set_body): Re-write to use GIMPLE_BODY in FN's
+ function object.
+ (gimple_body): Likewise.
+
+2008-05-01 Oleg Ryjkov <olegr@google.com>
+
+ http://gcc.gnu.org/ml/gcc-patches/2008-05/msg00053.html
+
+ * tree-eh.c (record_in_goto_queue, record_in_goto_queue_label):
+ New functions.
+ (maybe_record_in_goto_queue): Refactored and added support for
+ recording labels embedded in GIMPLE_CONDs.
+ (lower_catch, lower_cleanup): Fix 3 typos that were introduced
+ during the conversion to tuples.
+ (lower_eh_constructs_2): Call maybe_record_in_goto_queue for
+ GIMPLE_CONDs.
+
+2008-05-01 Rafael Espindola <espindola@google.com>
+
+ * gimple-pretty-print.c (dump_gimple_try): Print like trunk does.
+ (dump_gimple_catch): Print like trunk does.
+
+2008-05-01 Rafael Espindola <espindola@google.com>
+
+ * passes.c (gimple_verify_flow_info): Enable remaining
+ pass_rename_ssa_copies passes.
+
+2008-05-01 Rafael Espindola <espindola@google.com>
+
+ * tree-cfg.c (gimple_verify_flow_info): Handle switches with only the
+ default label.
+
+2008-04-30 Doug Kwan <dougkwan@google.com>
+
+ * cfgexpand.c (gimple_to_tree): Change code to annotate EH region
+ numbers only if numbers are greater than zero. Also propagate EH
+ region number to CALL_EXPRs nested in assignments.
+
+2008-04-29 Doug Kwan <dougkwan@google.com>
+
+ * tree-eh.c (lower_try_finally_dup_block): Call
+ copy_gimple_seq_and_replace_locals instead of gimple_seq_copy.
+ (optimize_double_finally): Add a note about replacing unsave_expr_now
+ with copy_gimple_seq_and_replace_locals.
+ * tree-inline.c (mark_local_labels_stmt, replace_locals_op,
+ replace_locals_stmt, copy_gimple_seq_and_replace_locals): New.
+ * tree-inline.h (copy_gimple_seq_and_replace_locals): New prototype.
+
+2008-04-29 Rafael Espindola <espindola@google.com>
+
+ * gimple-pretty-print.c (dump_gimple_return): Add missing space.
+ * tree-ssa-threadedge.c (simplify_control_stmt_condition): Fix type
+ of variable.
+
+2008-04-29 Rafael Espindola <espindola@google.com>
+
+ * gimple-pretty-print.c (pp_cfg_jump): add missing ";".
+
+2008-04-29 Rafael Espindola <espindola@google.com>
+
+ * gimple-pretty-print.c (dump_gimple_assign): print ";" at the end.
+ (dump_gimple_return):print ";" at the end.
+ (dump_gimple_call): print ";" at the end.
+ (dump_gimple_cond): use op_symbol_code instead of tree_code_name.
+ (pp_cfg_jump): print ";" at the end.
+
+2008-04-29 Rafael Espindola <espindola@google.com>
+
+ * ipa-cp.c (ipcp_driver): Disable.
+ * matrix-reorg.c (matrix_reorg): Comment body.
+ (gate_matrix_reorg): Disable.
+ * passes.c (init_optimization_passes): Enable first pass_merge_phi,
+ pass_ipa_cp and pass_ipa_matrix_reorg.
+
+2008-04-29 Doug Kwan <dougkwan@google.com>
+
+ * tree-eh.c (lower_catch): Fix bug of accessing sub-statements
+ using gimple_catch_handler. Fix bug of mixing up GIMPLE_GOTO and
+ GIMPLE_LABEL in statement building.
+ (lower_cleanup): Fix bug of mixing up gimple_try_clean and
+ gimple_try_eval.
+ (lower_cleanup): Use gimple codes instead of tree codes in switch
+ statement.
+ (tree-cfg.c): Add code to generate EH edges of GIMPLE_ASSIGN.
+
+2008-04-28 Diego Novillo <dnovillo@google.com>
+
+ http://gcc.gnu.org/ml/gcc-patches/2008-04/msg02051.html
+
+ * tree-ssa-phiprop.c (phiprop_insert_phi): Remove
+ OLD_ARG_CODE. Use TREE_CODE (ARG) instead.
+ Assert that NEW_VAR is a GIMPLE register.
+ (propagate_with_phi): Fix test of is_gimple_reg_type for
+ ARG.
+ Do not set subcode of USE_STMT to NOP_EXPR.
+
+2008-04-28 Doug Kwan <dougkwan@google.com>
+
+ * tree-inline.c (remap_gimple_op_r): Remove code to handle RESX_EXPR
+ region number remapping.
+ (remap_gimple_stmt): Add code to handle GIMPLE_RESX region number
+ remapping.
+
+2008-04-28 Rafael Espindola <espindola@google.com>
+
+ * cfgexpand.c (gimple_to_tree): Add support for switch stmts without
+ a default label.
+ * fold-const.c (tree_call_nonnegative_warnv_p): Remove the code
+ argument.
+ (tree_invalid_nonnegative_warnv_p): Update call to
+ tree_call_nonnegative_warnv_p.
+ * gimple.h (gimple_location_ptr): New.
+ * tree-flow.h (simplify_stmt_using_ranges): Change signature.
+ * tree-ssa-propagate.c (substitute_and_fold): Call
+ simplify_stmt_using_ranges.
+ * tree-vrp.c (struct assert_locus_d): Tuplify.
+ (switch_update): Tuplify.
+ (stmt_overflow_infinity): New.
+ (gimple_assign_nonnegative_warnv_p): New.
+ (gimple_call_nonnegative_warnv_p): New.
+ (gimple_stmt_nonnegative_warnv_p): New.
+ (gimple_assign_nonzero_warnv_p): New.
+ (gimple_stmt_nonzero_warnv_p): New.
+ (vrp_stmt_computes_nonzero): Tuplify.
+ (extract_range_basic): Tuplify.
+ (extract_range_from_expr): Tuplify. Rename to
+ extract_range_from_assignment.
+ (adjust_range_with_scev): Tuplify.
+ (vrp_var_may_overflow): Tuplify.
+ (build_assert_expr_for): Tuplify.
+ (fp_predicate): Tuplify.
+ (infer_value_range): Tuplify.
+ (dump_asserts_for): Tuplify.
+ (register_new_assert_for): Tuplify.
+ (register_edge_assert_for_2): Tuplify.
+ (register_edge_assert_for_1): Tuplify.
+ (register_edge_assert_for): Tuplify.
+ (find_conditional_asserts): Tuplify.
+ (find_switch_asserts): Tuplify.
+ (find_assert_locations): Tuplify.
+ (process_assert_insertions_for): Tuplify.
+ (process_assert_insertions): Tuplify.
+ (check_array_ref): Tuplify.
+ (search_for_addr_array): Tuplify.
+ (check_array_bounds): Tuplify.
+ (check_all_array_refs): Tuplify.
+ (remove_range_assertions): Tuplify.
+ (stmt_interesting_for_vrp): Tuplify.
+ (vrp_initialize): Tuplify.
+ (vrp_visit_assignment): Tuplify. Rename to vrp_visit_assignment_or_call.
+ (vrp_visit_cond_stmt): Tuplify.
+ (find_case_label_index): Tuplify.
+ (find_case_label_range): Tuplify.
+ (vrp_visit_switch_stmt): Tuplify.
+ (vrp_visit_stmt): Tuplify.
+ (vrp_visit_phi_node): Tuplify.
+ (simplify_div_or_mod_using_ranges): Tuplify.
+ (simplify_abs_using_ranges): Tuplify.
+ (simplify_cond_using_ranges): Tuplify.
+ (simplify_switch_using_ranges): Tuplify.
+ (simplify_stmt_using_ranges): Tuplify.
+ (simplify_stmt_for_jump_threading): Tuplify.
+ (identify_jump_threads): Tuplify.
+ (execute_vrp): Tuplify.
+ (gate_vrp): Enable.
+ * tree.h (tree_call_nonnegative_warnv_p): Remove the code argument.
+
+2008-04-28 Doug Kwan <dougkwan@google.com>
+
+ * cp/cp-gimplify.c (finish_bc_block): Tuplify.
+ (build_bc_goto): Renamed to get_bc_label. Return a label
+ only. Uupdate callers.
+ (get_bc_label): New
+ (gimplify_cp_loop): Tuplify. Also check COND for error_mark_node
+ before gimplifying it.
+ (gimplify_for_stmt): Tuplify.
+ (gimplify_while_stmt): Tuplify.
+ (gimplify_for_stmt): Tuplify.
+ (gimplify_do_stmt): Tuplify.
+ (gimplify_switch_stmt): Tuplify.
+ (cp_gimplify_omp_switch_stmt): Add temporary code to pop block
+ label stack.
+ (cp_gimplify_expr): Pass pre_p to gimplify_while_stmt,
+ gimplify_do_stmt and gimplify_switch_stmt. Tuplify
+ gimplification of CONTINUE_STMT and BREAK_STMT.
+
+2008-04-26 Rafael Espindola <espindola@google.com>
+
+ * gimple.c (gimple_build_assign_with_ops): Don't set SSA_NAME_DEF_STMT.
+ * gimple.h (gimple_assign_set_lhs): Set SSA_NAME_DEF_STMT.
+ (gimple_call_set_lhs): Set SSA_NAME_DEF_STMT.
+ * omp-low.c (expand_parallel_call): Don't set SSA_NAME_DEF_STMT if not
+ needed.
+ (expand_omp_for_generic): Same.
+ (expand_omp_for_static_nochunk): Same.
+ (expand_omp_for_static_chunk): Same.
+ (expand_omp_sections): Same.
+ (expand_omp_atomic_mutex): Same.
+ * predict.c (strip_builtin_expect): Same.
+ * tree-cfg.c (gimple_merge_blocks): Same.
+ * tree-inline.c (remap_ssa_name): Same.
+ (setup_one_parameter): Same.
+ * tree-predcom.c (replace_ref_with): Same.
+ (replace_ref_with): Same.
+ (initialize_root_vars_lm): Same.
+ (reassociate_to_the_same_stmt): Same.
+ * tree-scalar-evolution.c (scev_const_prop): Same.
+ * tree-ssa-loop-im.c (rewrite_reciprocal): Same.
+ * tree-ssa-loop-ivopts.c (rewrite_use_nonlinear_expr): Same.
+ * tree-ssa-loop-manip.c (create_iv): Same.
+ * tree-ssa-math-opts.c (execute_cse_sincos_1): Same.
+ * tree-ssa-phiopt.c (minmax_replacement): Same.
+ (abs_replacement): Same.
+
+2008-04-25 Diego Novillo <dnovillo@google.com>
+
+ http://gcc.gnu.org/ml/gcc-patches/2008-04/msg01965.html
+
+ * gimplify.c (annotate_all_with_location_after): New.
+ (gimplify_expr): Call it.
+
+2008-04-25 Diego Novillo <dnovillo@google.com>
+
+ Merge with mainline @134692.
+
+ * configure.ac (ACX_PKGVERSION): Update revision merge string.
+ * configure: Regenerate.
+
+2008-04-25 Doug Kwan <dougkwan@google.com>
+
+ * tree-inline.c (expand_call_inline): Save old call statement
+ and use it to look up correct EH region.
+
+2008-04-24 Doug Kwan <dougkwan@google.com>
+
+ * Makefile.in (STRICT_WARN): Remove -Wno-format and
+ -Wno-missing-format-attribute.
+ * gimplify.c (gimple_pop_condition): Remove redundant and incorrect
+ gimple_seq_free.
+ (gimplify_init_ctor_eval_range): Add a fall-through label for
+ GIMPLE_COND statement.
+
+2008-04-25 Rafael Espindola <espindola@google.com>
+
+ * tree-ssa-dom.c (avail_expr_eq): Return false if the hashes don't
+ match.
+
+2008-04-24 Oleg Ryjkov <olegr@google.com>
+
+ * gimplify.c (gimplify_expr): Fix the assertion that verifies validity
+ of parameters.
+ * tree-inline.c (estimate_num_insns): Handle
+ GIMPLE_CHANGE_DYNAMIC_TYPE.
+ * tree-cfg.c (verify_types_in_gimple_stmt): Likewise.
+
+2008-04-24 Rafael Espindola <espindola@google.com>
+
+ * tree-ssa-dom.c (initialize_hash_element): Fix the type of the code
+ variable.
+
+2008-04-23 Rafael Espindola <espindola@google.com>
+
+ * omp-low.c (gate_lower_omp): Return 0.
+ * passes.c (init_optimization_passes): Enable all passes whose
+ corresponding dump options are used in the testsuite.
+ * tree-loop-distribution.c (tree_loop_distribution): Comment body.
+ (gate_tree_loop_distribution): Return 0.
+ * tree-ssa-forwprop.c (tree_ssa_forward_propagate_single_use_vars):
+ Comment body.
+ (gate_forwprop): Return 0.
+ * tree-ssa-loop.c (gate_tree_ssa_loop_unswitch): Return 0.
+ (gate_tree_vectorize): Return 0.
+ (gate_tree_ssa_loop_ivcanon): Return 0.
+ (tree_ssa_empty_loop): Return 0.
+ (gate_tree_complete_unroll): Return 0.
+ * tree-ssa-pre.c (gate_fre): Return 0.
+ * tree-ssa-reassoc.c (execute_reassoc): Comment body.
+ (gate_tree_ssa_reassoc): Return 0.
+ * tree-stdarg.c (gate_optimize_stdarg): Return 0.
+ (execute_optimize_stdarg): Comment body.
+ * tree-vrp.c (execute_vrp): Comment body.
+ (gate_vrp): Return 0.
+
+2008-04-22 Aldy Hernandez <aldyh@redhat.com>
+
+ * omp-low.c (lower_omp_parallel): Add new argument to
+ gimple_omp_parallel_set_combined_p.
+ (lower_omp_1): Remove debugging code.
+ * gimple.h (gimple_omp_parallel_combined_p): Add new argument.
+
+2008-04-22 Rafael Espindola <espindola@google.com>
+
+ Merge with mainline @134552.
+
+ * configure.ac (ACX_PKGVERSION): Update revision merge string.
+ * configure: Regenerate.
+
+2008-04-21 Doug Kwan <dougkwan@google.com>
+
+ * tree-ssa-phiopt.c (FILE): Uncomment all previously disabled code.
+ (tree_ssa_phiopt): Remove FIXME and re-enable code.
+ (tree_ssa_cs_elim): Remove FIXME and re-enable code.
+ (tree_ssa_phiopt_worker): Tuplify.
+ (replace_phi_edge_with_variable): Tuplify.
+ (conditional_replacement): Tuplify and simplify optimization logic.
+ Construct a boolean tree and let fold and force_gimple_operand_gsi
+ do optimization and code genaration.
+ (value_replacement): Tuplify.
+ (minmax_replacement): Tuplify.
+ (abs_replacement): Tuplify.
+ (nt_init_block): Tuplify.
+ (cond_store_replacement): Tuplify.
+ * gimple.h (gimple_seq_singleton_p): Fix empty sequence bug.
+ * passes.c (init_optimization_passes): Re-enable pass_cselim
+ and pass_phiopt.
+
+2008-04-21 Diego Novillo <dnovillo@google.com>
+
+ * tree.c (make_node_stat): Clear gimple_body() for newly
+ created FUNCTION_DECLs.
+ * tree-gimple.c (rhs_predicate_for): Move to gimplify.c.
+ * tree-gimple.h (rhs_predicate_for): Remove declaration.
+ * gimple-pretty-print.c (dump_gimple_assign): Add support
+ for showing volatile operands.
+ (dump_gimple_call): Likewise.
+ Add support for showing __builtin_va_arg_pack, static
+ chains, return slot optimized and tail calls.
+ (dump_gimple_phi): Remove code to print memory symbols.
+ * gimplify.c (is_gimple_formal_tmp_or_call_rhs): New.
+ (is_gimple_mem_or_call_rhs): New.
+ (rhs_predicate_for): Call them.
+ (internal_get_tmp_var): Use is_gimple_formal_tmp_or_call_rhs as
+ the gimplification predicate.
+ Use the last statement in *PRE_P to get the temporary to
+ be updated when in SSA form.
+ (gimplify_bind_expr): Clear out *EXPR_P before returning.
+ (gimplify_call_expr): Do not build a GIMPLE_CALL if
+ WANT_VALUE is true.
+ Call gimple_build_call_from_tree if WANT_VALUE is false.
+ Remove local variable ARGS.
+ (gimplify_modify_expr): If after gimplification *FROM_P
+ is a CALL_EXPR, create a GIMPLE_CALL instead of a
+ GIMPLE_ASSIGN.
+ Document why the gimplification of the RHS should accept
+ CALL_EXPRs.
+ (gimplify_expr): Document where the generated statement
+ is stored.
+ Accept is_gimple_formal_tmp_or_call_rhs and
+ is_gimple_mem_or_call_rhs as gimplification predicates.
+ When gimplifying statements, clear out *EXPR_P before
+ returning.
+ When generating an rvalue, call is_gimple_formal_tmp_or_call_rhs
+ to test *EXPR_P.
+ * tree-dfa.c (mark_symbols_for_renaming): Remove
+ ATTRIBUTE_UNUSED.
+ * tree-flow.h (stmt_references_memory_p): Remove.
+ * gimple.c (gimple_build_call_from_tree): New.
+ * gimple.h (struct gimple_statement_with_memory_ops): Add
+ bitfield references_memory_p.
+ (gimple_build_call_from_tree): Declare.
+ (gimple_references_memory_p): Rename from
+ stmt_references_memory_p. Move here. Update all users.
+ (gimple_set_references_memory): New.
+ (gimple_assign_set_rhs1): When the assignment has more
+ than one operand on the RHS, assert that the operands are
+ gimple values.
+ (gimple_assign_set_rhs2): Assert that the operand is a
+ gimple value.
+ (gimple_call_set_return_slot_opt): Fix mask clearing.
+ (gimple_call_set_from_thunk): Likewise.
+ (gimple_call_set_va_arg_pack): Likewise.
+ * tree-cfg.c (dump_function_to_file): Do not indent when
+ doing a GIMPLE dump.
+ * tree-ssa-operands.c (add_virtual_operand): Call
+ gimple_set_references_memory.
+ (get_addr_dereference_operands): Likewise.
+ (get_tmr_operands): Likewise.
+ (maybe_add_call_clobbered_vops): Likewise.
+ (get_asm_expr_operands): Likewise.
+ (parse_ssa_operands): Likewise.
+ (build_ssa_operands): Likewise.
+ (stmt_references_memory_p): Remove.
+
+2008-04-21 Rafael Espindola <espindola@google.com>
+
+ Cherry pick http://gcc.gnu.org/ml/gcc-patches/2008-04/msg01213.html
+
+ * params.def (PARAM_MAX_FIELDS_FOR_FIELD_SENSITIVE): Set default
+ to zero, thus disable creation of SFTs.
+ * gcc.dg/tree-ssa/salias-1.c: Remove.
+ * gcc.dg/tree-ssa/pr26421.c: Adjust pattern.
+ * gcc.dg/tree-ssa/alias-15.c: Likewise.
+ * gcc.dg/tree-ssa/ssa-lim-3.c: Run at -O2.
+
+2008-04-20 Zdenek Dvorak <ook@ucw.cz>
+
+ * passes.c (init_optimization_passes): Enable pass_dce_loop.
+
+2008-04-20 Zdenek Dvorak <ook@ucw.cz>
+
+ * tree-data-ref.c (split_constant_offset_1): Use POINTER_PLUS_EXPR
+ for pointer addition.
+ (split_constant_offset): Set VAR to EXP before conversions are
+ stripped, when no offset is removed. Handle chrec_dont_know.
+ * tree-predcom.c: Tuplified.
+ * passes.c (init_optimization_passes): Enable pass_predcom.
+
+2008-04-18 Aldy Hernandez <aldyh@redhat.com>
+
+ * omp-low.c (lower_rec_input_clauses): Remove fixme and
+ ATTRIBUTE_UNUSED.
+ (lower_lastprivate_clauses): Same.
+ (lower_reduction_clauses): Same.
+ (lower_copyprivate_clauses): Same.
+ (lower_send_clauses): Same.
+ (lower_send_shared_vars): Same.
+ (maybe_catch_exception): Convert to tuples.
+ (lower_omp_sections): Same.
+ (lower_omp_single_simple): Same.
+ (lower_omp_single_copy): Same.
+ (lower_omp_single): Same.
+ (lower_omp_master): Same.
+ (lower_omp_ordered): Same.
+ (lower_omp_critical): Same.
+ (lower_omp_for_lastprivate): Same.
+ (lower_omp_for): Same.
+ (check_combined_parallel): Same.
+ (lower_omp_parallel): Same.
+ (lower_omp_1): Same.
+ (execute_lower_omp): Enable.
+ * gimple-dummy.c: Remove dummy functions for lower_omp_*.
+ * gimple-low.c (lower_omp_directive): Convert to tuples.
+ (lower_stmt): Remove fixme.
+ * gimple.h (gimple_seq_alloc_with_stmt): New.
+ (gimple_omp_section_set_last): New.
+ (gimple_omp_parallel_set_combined_p): New.
+ (gimple_bind_add_stmt): New.
+ (gimple_bind_add_seq): New.
+ * tree-cfg.c (verify_node_sharing): Fix typo in comment.
+
+2008-04-17 Oleg Ryjkov <olegr@google.com>
+
+ * Reverting forwprop patch.
+
+ 2008-04-16 Oleg Ryjkov <olegr@google.com>
+
+ * tree-ssa-forwprop.c (get_prop_dest_stmtm get_prop_source_stmt,
+ can_propagate_from, remove_prop_source_from_use,
+ tidy_after_forward_propagate_addr,
+ forward_propagate_addr_into_variable_array_index,
+ forward_propagate_addr_expr_1, forward_propagate_addr_expr,
+ forward_propagate_comparison, simplify_not_neg_expr,
+ simplify_switch_expr,
+ tree_ssa_forward_propagate_single_use_variables): Tuplified.
+ (forward_propagate_into_cond): Tuplified and moved some functionality
+ into forward_propagate_into_cond_gimple.
+ (rhs_to_tree, forward_propagate_into_cond_gimple): New functions.
+ * passes.c (init_optimization_passes): Enabled pass_forwprop.
+ * tree-cfg.c (find_taken_edge_cond_expr): Fixed comment.
+
+2008-04-16 Oleg Ryjkov <olegr@google.com>
+
+ * tree-ssa-forwprop.c (get_prop_dest_stmtm get_prop_source_stmt,
+ can_propagate_from, remove_prop_source_from_use,
+ tidy_after_forward_propagate_addr,
+ forward_propagate_addr_into_variable_array_index,
+ forward_propagate_addr_expr_1, forward_propagate_addr_expr,
+ forward_propagate_comparison, simplify_not_neg_expr,
+ simplify_switch_expr,
+ tree_ssa_forward_propagate_single_use_variables): Tuplified.
+ (forward_propagate_into_cond): Tuplified and moved some functionality
+ into forward_propagate_into_cond_gimple.
+ (rhs_to_tree, forward_propagate_into_cond_gimple): New functions.
+ * passes.c (init_optimization_passes): Enabled pass_forwprop.
+ * tree-cfg.c (find_taken_edge_cond_expr): Fixed comment.
+
+2008-04-16 Doug Kwan <dougkwan@google.com>
+
+ * Makefile.in (STRICT_WARN): Disable -Wmissing-format-attribute
+ and -Wformat temporarily for bootstrapping.
+ * lambda-code.c (invariant_in_loop_and_outer_loops): Comment out
+ to avoid defined-and-not-used warning.
+ * tree-cfg.c (gather_blocks_in_sese_region): Comment out to avoid
+ defined-and-not-used warning.
+
+2008-04-16 Doug Kwan <dougkwan@google.com>
+
+ * Makefile.in (GTFILES): Add back ipa-reference.h and ipa-reference.c.
+ * gimple-dummy.c (memory_identifier_string): Remove.
+ * ipa-cp.c (constant_val_insert): Tuplify.
+ * ipa-prop.c (File): Uncomment all previously disabled code.
+ (ipa_method_modify_stmt): Tuplify.
+ (ipa_method_compute_modify): Tuplify.
+ (ipa_callsite_tree): Renamed to ipa_callsite_stmt. Update callers.
+ (ipa_callsite_stmt): New.
+ (ipa_callsite_compute_count): Tuplify.
+ (ipa_callsite_compute_param): Tuplify.
+ * ipa-reference.c (File): Uncomment all previously disabled code.
+ (get_asm_stmt_operands): Tuplify.
+ (check_call): Tuplify. Also add code to handle assignment of
+ returned value.
+ (scan_for_static_refs): Remove. Tuplify body and split into two
+ new functions scan_stmt_for_static_refs and scan_op_for_static_refs.
+ Update callers.
+ (scan_stmt_for_static_refs): New. Split from scan_for_static_refs.
+ (scan_op_for_static_refs): New. Split from scan_for_static_refs.
+ (analyze_variable): Update walk_tree call.
+ (analyze_function): Tuplify.
+ * passes.c (init_optimization_passes): Re-enable pass_ipa_reference.
+ * tree-flow.h (struct function_ann_d): Uncomment field
+ ipa_reference_vars_info.
+
+2008-04-15 Doug Kwan <dougkwan@google.com>
+
+ * tree-eh.c (operation_could_trap_p): Fix filtering logic.
+
+2008-04-15 Bill Maddox <maddox@google.com>
+
+ * tree-ssa-dom.c: (degenerate_phi_result, remove_stmt_or_phi,
+ get_rhs_or_phi_arg, get_lhs_or_phi_result, propagate_rhs_into_lhs,
+ eliminate_const_or_copy, eliminate_degenerate_phis_1,
+ eliminate_degenerate_phis): Convert to tuples.
+ * passes.c (init_optimization_passes): Enable pass_phi_only_cprop.
+
+2008-04-15 Oleg Ryjkov <olegr@google.com>
+
+ * tree-ssa-dom.c (record_const_or_copy): Moving a variable declaration to
+ the top of a block.
+
+2008-04-15 Doug Kwan <dougkwan@google.com>
+
+ * tree-ssa-sink.c (File): Uncomment all previously disabled code.
+ (find_bb_for_arg): Tuplify.
+ (all_immediate_uses_sample_place): Tuplify.
+ (nearest_common_dominator_of_uses): Tuplify.
+ (statement_sink_location): Tuplify. Remove parameter tobb and update
+ caller.
+ (sink_code_in_bb): Tuplify.
+ * passes.c (init_optimization_passes): Re-enable pass_sink_code.
+
+2008-04-14 Bill Maddox <maddox@google.com>
+
+ * tree-ssa-threadupdate.c (remove_ctrl_stmt_and_useless_edge,
+ create_edge_and_update_destination_phis, redirection_block_p):
+ Convert to tuples.
+ * tree.c (iterative_hash_exprs_commutative): New function.
+ * tree.h (iterative_hash_exprs_commutative): Declare.
+ * tree-ssa_dom.c (enum expr_kind, struct hashable_expr,
+ struct cond_equivalence): New types.
+ (struct edge_info): Use struct cond_equivalence.
+ (avail_exprs_stack): Stack of expr_hash_elt*, not expressions.
+ (stmts_to_rescan): Use type gimple for statements.
+ (struct expr_hash_elt): Represent statement RHS with hashable_expr,
+ not a tree. Add unique stamp to each entry for efficient and reliable
+ element removal.
+ (struct eq_expr_value): Delete unused type.
+ (initialize_hash_element): Convert to tuples. Now applies
+ only to statements.
+ (initialize_expr_from_cond, initialize_hash_element_from_expr):
+ New functions. Replace former functionality of initialize_hash_element
+ for conditions presented as trees.
+ (hashable_expr_equal_p, iterative_hash_hashable_expr): New functions.
+ (print_expr_hash_elt): New function.
+ (free_expr_hash_elt): New function.
+ (tree_ssa_dominator_optimize): Convert to tuples
+ (canonicalize_comparison): Convert to tuples.
+ (remove_local_expressions_from_table): Use new avail_exprs_stack
+ representation. Add optional extra diagnostic details.
+ (simplify_stmt_for_jump_threading, dom_thread_across_edge,
+ dom_opt_finalize_block): Convert to tuples.
+ (record_cond, build_and_record_new_cond): Convert to tuples.
+ Use new hashable_expr type. Extra diagnostic details.
+ (record_const_or_copy_1): Extra diagnostic details.
+ (record_const_or_copy): Add assertion.
+ (simple_iv_increment_p, cprop_into_successor_phis, record_edge_info):
+ Convert to tuples.
+ (eliminate_redundant_computations): Convert to tuples.
+ Additional diagnostic details.
+ (gimple_assign_unary_useless_conversion_p): New function.
+ (record_equivalences_from_statement): Convert to tuples.
+ Additional diagnostic details.
+ (cprop_operand, cprop_into_stmt): Convert to tuples.
+ (optimize_stmt): Convert to tuples.
+ (lookup_avail_expr): Use hashable_expr. Additional diagnostic details.
+ (avail_expr_hash, avail_expr_eq): Use hashable_expr.
+ * tree-ssa-copy.c (may_propagate_copy_into_stmt,
+ propagate_tree_value_into_stmt): New functions.
+ * tree-flow.h: (may_propagate_copy_into_stmt,
+ propagate_tree_value_into_stmt): Declare.
+ (thread_across_edge): Change declaration of callback to accept a
+ gimple statement.
+ * gimple.c (gimple_call_flags): Declare argument as a constant.
+ (gimple_has_side_effects): Declare argument as a constant.
+ Examine function arguments for side-effects.
+ (gimple_rhs_has_side_effects): New function.
+ * gimple.h (gimple_call_flags): Declare argument as a constant.
+ (gimple_has_side_effects): Declare argument as a constant.
+ (gimple_rhs_has_side_effects): Declare new function.
+ (is_gimple_assign): New inline function.
+ (gimple_switch_index_ptr): New function.
+ * passes.c (init_optimization_passes): Enable pass_dominator.
+ * tree-ssa_threadedge.c (potentially_threadable_block,
+ lhs_of_dominating_assert, record_temporary_equivalences_from_phis):
+ Convert to tuples.
+ (fold_assignment_stmt): New function.
+ (record_temporary_equivalences_from_stmts_at_dest,
+ simplify_control_stmt_condition, thread_across_edge): Convert to tuples.
+
+2008-04-14 Doug Kwan <dougkwan@google.com>
+
+ * c-typeck.c (convert_for_assignment): Call c_common_unsigned_type
+
+2008-04-14 Doug Kwan <dougkwan@google.com>
+
+ * gimple-iterator.c (gsi_move_to_bb_end): Use gsi_last_bb
+ instead of calling both gsi_last and bb_seq.
+ * passes.c (init_optimization_passes): Re-eanble second tail-recursion
+ pass.
+
+2008-04-14 Doug Kwan <dougkwan@google.com>
+
+ * tree-nrv.c (dest_safe_for_nrv_p): Uncomment.
+ (execute_return_slot_opt): Tuplify.
+ * passes.c (init_optimization_passes): Re-enable pass_return_slot.
+
+2008-04-14 Aldy Hernandez <aldyh@redhat.com>
+
+ * tree-cfg.c (gimple_can_merge_blocks_p): Fix typo.
+ * omp-low.c (maybe_lookup_ctx): Uncomment and set ATTRIBUTE_UNUSED.
+ (lower_lastprivate_clauses): Same.
+ (lower_reduction_clauses): Same.
+ (lower_send_clauses): Same.
+ (expand_omp_for_generic): Uncomment and convert for tuples.
+ (expand_omp_for): Remove fixme.
+ (expand_omp_sections): Same.
+ (lower_omp_parallel): Partially convert for tuples.
+ (lower_omp_regimplify_p): Rename from lower_omp_2.
+ (lower_omp_1): Convert for tuples.
+ (lower_omp): Same.
+ (gimple-dummy.c): Add lower_omp_parallel, lower_omp_for,
+ lower_omp_sections, lower_omp_single, lower_omp_master,
+ lower_omp_ordered, lower_omp_critical.
+
+2008-04-13 Diego Novillo <dnovillo@google.com>
+
+ * tree-cfg.c (need_fake_edge_p): Initialize CALL_FLAGS.
+
+2008-04-12 Rafael Espindola <espindola@google.com>
+
+ Merge with mainline @134237.
+
+ * configure.ac (ACX_PKGVERSION): Update revision merge string.
+ * configure: Regenerate.
+
+2008-04-13 Rafael Espindola <espindola@google.com>
+
+ * config/extensions.m4: Add. Was missing from previous merge.
+
+2008-04-12 Rafael Espindola <espindola@google.com>
+
+ Merge with mainline @133860.
+
+ * configure.ac (ACX_PKGVERSION): Update revision merge string.
+ * configure: Regenerate.
+
+2008-04-11 Oleg Ryjkov <olegr@google.com>
+
+ * tree-sra.c (scalarize_use): Moving a variable declaration to
+ the top of a block.
+
+2008-04-11 Oleg Ryjkov <olegr@google.com>
+
+ * tree-sra.c (insert_edge_copies_seq): Removed unused variable.
+
+2008-04-11 Oleg Ryjkov <olegr@google.com>
+
+ * tree-sra.c (sra_build_assignment): Tuplified.
+ (mark_all_v_defs): Removed.
+ (mark_all_v_defs_seq, mark_all_v_defs_stmt): New functions.
+ (sra_walk_expr): Tuplified.
+ (sra_walk_tree_list): Removed.
+ (sra_walk_call_expr, sra_walk_gimple_asm,
+ sra_walk_gimple_modifY_stmt, ): Tuplified and renamed.
+ (sra_walk_gimple_call, sra_walk_gimple_asm,
+ sra_walk_gimple_assign): New names for tuplified functions.
+ (sra_walk_function, find_candidates_for_sra, scan_use, scan_copy,
+ scan_ldst, instantiate_element, decide_instantiations,
+ mark_all_v_defs_1, sra_build_assignment, sra_build_bf_assignment,
+ sra_build_elt_assignment, generate_copy_inout,
+ generate_element_copy, generate_element_zero,
+ generate_one_element_init, generate_element_init_1): Tuplified.
+ (insert_edge_copies): Removed.
+ (insert_edge_copies_seq): New function.
+ (sra_insert_before, sra_insert_after, sra_replace,
+ sra_explode_bitfield_assignment, sra_sync_for_bitfield_assignment,
+ scalarize_use, scalarize_copy, scalarize_init, mark_no_trap,
+ scalarize_ldst, scalarize_parms, scalarize_function): Tuplified.
+ (tree_sra, tree_sra_early): Enabled
+ (sra_init_cache): Removed extra space.
+ * tree-flow.h (insert_edge_copies_seq): New declaration.
+ * gimple.h (gimple_asm_input_op_ptr, gimple_asm_output_op_ptr,
+ gimple_return_retval_ptr): New functions.
+ * passes.c (init_optimization_passes): Enabled pass_sra,
+ pass_early_sra.
+
+2008-04-11 Doug Kwan <dougkwan@google.com>
+
+ * ipa-pure-const.c (get_asm_expr_operands): Tuplify.
+ (get_asm_expr_operands): Tuplify.
+ (check_call): Tuplify. Add code to handle return value assignment.
+ (scan_function): Remove. Original code is tuplified and split into
+ two new functions scan_function_op and scan_function_stmt.
+ (scan_function_op): New function.
+ (scan_function_stmt): New function.
+ (analyze_function): Tuplify and re-enable previously disabled code.
+ * passes.c (init_optimization_passes): Re-enable pass_ipa_pure_const.
+
+2008-04-11 Oleg Ryjkov <olegr@google.com>
+
+ * builtins.c (fold_call_stmt): Return the proper value.
+ * tree-ssa-ccp.c (maybe_fold_stmt_addition): Modify arguments to
+ allow this function to be called on a GIMPLE_ASSIGN.
+ (fold_stmt_r): Update the call to maybe_fold_stmt_addition.
+ (fold_gimple_assign): Manually call maybe_fold_stmt_addition to
+ fold a POINTER_PLUS_EXPR.
+
+2008-04-11 Doug Kwan <dougkwan@google.com>
+
+ * tree-ssa-phiprop.c (File): Uncomment all previously disabled code.
+ (struct phiprop_d): Change type of vop_stmt to gimple.
+ (phivn_valid_p): Tuplify.
+ (phiprop_insert_phi): Tuplify.
+ (propagate_with_phi): Tuplify.
+ (tree_ssa_phiprop_1): Tuplify.
+ (tree_ssa_phiprop): Tuplify.
+ * passes.c (init_optimization_passes): Re-enable pass_phiprop.
+
+2008-04-11 Rafael Espindola <espindola@google.com>
+
+ * tree-ssa-math-opts.c (execute_cse_sincos_1): fix warning.
+
+2008-04-10 Diego Novillo <dnovillo@google.com>
+
+ http://gcc.gnu.org/ml/gcc-patches/2008-04/msg00913.html
+
+ * ipa-inline.c (cgraph_clone_inlined_nodes): Change uses
+ of DECL_SAVED_TREE with gimple_body.
+ (cgraph_decide_inlining_incrementally): Likewise.
+ * gimple-iterator.c (gsi_insert_seq_before_without_update):
+ Do nothing if SEQ is NULL.
+ (gsi_insert_seq_after_without_update): Likewise.
+ * tree-ssa-live.c (mark_all_vars_used_1): Do not handle
+ EXPR trees.
+ (remove_unused_locals): Mark the gimple_block of every
+ statement as used.
+ * tree-inline.c (remap_gimple_stmt): Forward declare.
+ (remap_decls): Tidy comments.
+ (remap_gimple_seq): New.
+ (copy_gimple_bind): New.
+ (remap_gimple_stmt): Call it.
+ Handle High GIMPLE statements.
+ (copy_bb): Regimplify operands on COPY_GSI instead of
+ GSI.
+ (copy_cfg_body): Tidy.
+ (copy_generic_body): Remove unused function.
+ (clone_body): Tuplify.
+ * c-common.c (c_warn_unused_result): Remove assertion for
+ FUNCTION_TYPE.
+ * gimple.c (gimple_seq_copy): Rename from
+ gimple_seq_deep_copy. Update all users.
+ (walk_gimple_stmt): Assert that STMT has no substatements
+ in the default case.
+ (gimple_copy_1): Merge into gimple_copy.
+ (gimple_copy): Always do deep copying.
+ Handle statements with substatements.
+ (gimple_shallow_copy): Remove unused function.
+ (gimple_deep_copy): Remove. Update all users.
+ * gimple.h: Tidy comments and structure fields
+ everywhere.
+ (gimple_has_substatements): New.
+ (walk_stmt_fn): Change last argument to struct walk_stmt_info *.
+ Update all users.
+
+2008-04-10 Oleg Ryjkov <olegr@google.com>
+
+ * tree.h (struct tree_base): Added a new flag default_def_flag.
+ (SSA_NAME_IS_DEFAULT_DEF): Changed to use the new flag.
+
+2008-04-08 Doug Kwan <dougkwan@google.com>
+
+ * gimplify.c (gimple_push_cleanup): Initialize cleanup_stmts to NULL.
+
+2008-04-08 Doug Kwan <dougkwan@google.com>
+
+ * tree-tailcall.c (struct tailcall): Remove call_block and replace
+ call_bsi by call_gsi.
+ (independent_of_stmt_p): Change type of parameter 'at' to GIMPLE and
+ change all tree using code to GIMPLE using equivalent.
+ Remove parameter block_stmt_iterator type parameter bsi with
+ gimple_stmt_iterator type parameter gsi. Replace uses of bsi with
+ that of gsi in function body as appropriate.
+ (process_assignment): Remove parameter 'ass' and change type of
+ parameter 'stmt' to GIMPLE. Change all tree using code to GIMPLE
+ using equivalent.
+ (propagate_through_phis, eliminate_tail_call, optimize_tail_call):
+ Change all tree using code to GIMPLE using equivalent.
+ (find_tail_calls): Change all tree using code to GIMPLE using
+ equivalent. Remove code that handles GIMPLE_MODIFY_STMT containing
+ a CALL_EXPR.
+ (add_successor_phi_arg, adjust_return_value_with_ops,
+ update_accumulator_with_ops, adjust_accumulator_values,
+ create_tailcall_accumulator): New functions from refactoring of
+ duplicated logic.
+ (adjust_accumulator_values, adjust_return_value): Refactor.
+ (tree_optimize_tail_calls_1): Refactor and change all tree using code
+ to GIMPLE using equivalent. Remove code to reverse phi list.
+ * passes.c (init_optimization_passes): Re-enable pass_tail_recursion
+ and pass_tail_calls.
+
+2008-04-04 Doug Kwan <dougkwan@google.com>
+
+ * tree-ssa-math-opts.c (struct occurrence): Change field type of
+ recip_def_stmt to gimple.
+ (is_division_by): Tuplify.
+ (insert_reciprocals): Tuplify.
+ (replace_reciprocals): Tuplify.
+ (execute_cse_reciprocals_1): Tuplify.
+ (execute_cse_reciprocals): Tuplify.
+ (maybe_record_sincos): Use vector of gimples instead of vector of
+ trees.
+ (execute_cse_sincos_1): Tuplify. When adjusting recorded old call
+ sites, generate new gimple assign statements and remove old gimple
+ call statements.
+ (execute_cse_sincos): Tuplify.
+ (execute_convert_to_rsqrt): Tuplify.
+ * passes.c (init_optimization_passes): Enable pass_cse_sincos,
+ pass_cse_reciprocals and pass_convert_to_rsqrt.
+
+2008-04-04 Aldy Hernandez <aldyh@redhat.com>
+
+ * omp-low.c (gimple_build_cond_empty): New.
+ (expand_parallel_call): Convert COND_EXPR to GIMPLE_COND.
+ (expand_omp_for_generic): Same.
+ (expand_omp_for_static_nochunk): Same.
+ (expand_omp_for_static_chunk): Same.
+ (expand_omp_atomic_pipeline): Same.
+
+2008-04-04 Diego Novillo <dnovillo@google.com>
+
+ http://gcc.gnu.org/ml/gcc-patches/2008-04/msg00413.html
+
+ * tree-ssa-loop-im.c (movement_possibility): Return
+ MOVE_IMPOSSIBLE if that statement makes no assignment.
+ * tree-complex.c (get_component_ssa_name): Fix comment.
+ (set_component_ssa_name): Assert that COMP's definition
+ is LAST.
+ * cgraph.c (cgraph_update_edges_for_call_stmt): Tuplify.
+ (dump_cgraph_node): Likewise.
+ * tree.c (auto_var_in_fn_p): Fix comment.
+ * cgraphunit.c (verify_cgraph_node): Remove tuples hack
+ that avoided verifying nodes.
+ * gimple-pretty-print.c (dump_gimple_asm): Show the
+ volatile flag.
+
+ * gimple-dummy.c (optimize_inline_calls): Remove.
+ (tree_function_versioning): Remove.
+ (tree_versionalbe_function_p): Remove.
+ * ipa-inline.c (cgraph_clone_inlined_bodies): Re-format.
+ (cgraph_decide_inlining): Re-format.
+ (cgraph_decide_inlining_incrementally): Re-format.
+ (pass_ipa_inline): Re-format.
+ * gimplify.c (gimplify_call_expr): Carry all the
+ CALL_EXPR flags to the newly created GIMPLE_CALL.
+ (gimplify_asm_expr): Carry ASM_VOLATILE_P and ASM_INPUT_P
+ over to the new GIMPLE_ASM.
+ * tree-dfa.c (find_new_referenced_vars): Change argument
+ to gimple. Update all callers.
+ * cfgexpand.c (set_expr_location_r): New private.
+ (gimple_to_tree): Call it.
+ Set ASM_VOLATILE_P and ASM_INPUT_P for ASM_EXPRs.
+ Carry flags from GIMPLE_CALL for CALL_EXPRs.
+ Set TREE_BLOCK on the newly created expression.
+ * tree-inline.c: Tuplify.
+ * tree-inline.h: Tuplify.
+ * tree-optimize.c (execute_fixup_cfg): Tuplify.
+ * gimple.c (gimple_build_call_vec): Change second
+ argument type to VEC(tree, heap). Update all callers.
+ (gimple_build_assign_with_ops): If the LHS is an
+ SSA_NAME, set SSA_NAME_DEF_STMT on it.
+ (walk_gimple_seq): Change return type to gimple. Update
+ all users.
+ If walk_gimple_stmt returned a value, store it in
+ WI->CALLBACK_RESULT.
+ (walk_gimple_op): Walk gimple_call_chain_ptr() and
+ gimple_call_fn_ptr() for GIMPLE_CALL.
+ (walk_gimple_stmt): Add new local HANDLED_OPS.
+ If callback_stmt() sets HANDLED_OPS, return its return
+ value.
+ If any call to walk_gimple_seq returns a non-NULL value,
+ return WI->CALLBACK_RESULT.
+ (gimple_copy_1): New function.
+ (gimple_deep_copy): Rename from gimple_copy. Update all
+ users.
+ Call gimple_copy_1.
+ (gimple_shallow_copy): New.
+ (gimple_regimplify_operands): New.
+ * gimple.h (GF_ASM_INPUT): Define.
+ (GF_ASM_VOLATILE): Define.
+ (GF_CALL_CANNOT_INLINE): Define.
+ (GF_CALL_FROM_THUNK): Define.
+ (GF_CALL_RETURN_SLOT_OPT): Define.
+ (GF_CALL_VA_ARG_PACK): Define.
+ (gimple_stmt_iterator): Move earlier in the file.
+ (gimple_omp_return_nowait_p): Fix return expression.
+ (gimple_omp_section_last_p): Likewise.
+ (gimple_omp_parallel_combined_p): Likewise.
+ (gimple_call_noreturn_p): Likewise.
+ (gimple_call_nothrow_p): Likewise.
+ (gimple_asm_volatile_p): Likewise.
+ (gimple_try_catch_is_cleanup): Likewise.
+ (gimple_assign_set_rhs1): assert that RHS is a gimple
+ operand.
+ (is_gimple_call): New. Change all users that tested
+ gimple_code() == GIMPLE_CALL.
+ (gimple_call_fn_ptr): New.
+ (gimple_call_chain_ptr): New.
+ (gimple_call_set_chain): Accept NULL values for CHAIN.
+ (gimple_call_set_tail): Add bool argument specifying the
+ value of the flag. Update all users.
+ (gimple_asm_set_volatile): Likewise.
+ (gimple_call_set_cannot_inline): Rename from
+ gimple_call_mark_uninlinable. Add bool argument
+ specifying the value of the flag. Update all users.
+ (gimple_call_set_return_slot_opt): New.
+ (gimple_call_return_slot_opt_p): New.
+ (gimple_call_set_from_thunk): New.
+ (gimple_call_from_thunk_p): New.
+ (gimple_call_va_arg_pack_p): New.
+ (gimple_call_copy_flags): New.
+ (gimple_asm_set_input): New.
+ (gimple_asm_input_p): New.
+ (gimple_asm_clear_volatile): Remove.
+ (walk_stmt_fn): Add second argument bool *. Update all
+ users.
+ (struct walk_stmt_info): Add new field callback_result.
+ * tree-cfg.c (gimple_split_block): Tuplify.
+ (gimple_block_ends_with_condjump_p): Tuplify.
+ (need_fake_edge_p): Tuplify.
+ (gimple_flow_call_edges_add): Tuplify.
+ (gimple_purge_dead_abnormal_call_edges): Tuplify.
+ (gimple_purge_dead_eh_edges): Remove ATTRIBUTE_UNUSED.
+ (gimple_cfg_hooks): Add gimple_block_ends_with_condjump_p
+ and gimple_flow_call_edges_add
+ * passes.c (init_optimization_passes): Enable
+ pass_cleanup_cfg, pass_inline_parameters,
+ pass_ipa_inline and pass_apply_inline.
+ (execute_todo): Re-enable check for TODO_update_ssa_any
+ if need_ssa_update_p() returns true.
+ * tree-ssa-operands.c (ssa_operands_active): Return false
+ if cfun is NULL.
+
+
+2008-04-04 Rafael Espindola <espindola@google.com>
+
+ Merge with mainline @133632.
+
+ * configure.ac (ACX_PKGVERSION): Update revision merge string.
+ * configure: Regenerate.
+
+2008-04-04 Rafael Espindola <espindola@google.com>
+
+ Merge with mainline @133631.
+
+ * configure.ac (ACX_PKGVERSION): Update revision merge string.
+ * configure: Regenerate.
+
+2008-04-04 Rafael Espindola <espindola@google.com>
+
+ Merge with mainline @133630.
+
+ * configure.ac (ACX_PKGVERSION): Update revision merge string.
+ * configure: Regenerate.
+
+2008-04-03 Aldy Hernandez <aldyh@redhat.com>
+
+ * omp-low.c (expand_omp_sections): Use
+ gimple_omp_sections_control.
+ (lower_omp_sections): Same.
+ * gimplify.c (gimplify_omp_workshare): Adjust OMP clauses before
+ creating gimple tuple.
+ Add gimple tuple to sequence.
+ Set OMP_SECTIONS_CONTROL in newly created tuple.
+ * gimple.h (gimple_statement_omp_sections): Add control.
+ (gimple_omp_sections_control): New.
+ (gimple_omp_sections_control_ptr): New.
+ (gimple_omp_sections_set_control): New.
+
+2008-04-03 Oleg Ryjkov <olegr@google.com>
+
+ * tree-nested.c (convert_nl_goto_receiver): Changed to hadle gimple
+ statements instead of trees.
+ (lower_nested_functions): Pass convert_nl_goto_receiver as the first
+ parameter to walk_all_functions.
+
+2008-04-03 Rafael Espindola <espindola@google.com>
+
+ Merge with mainline @133624.
+
+ * configure.ac (ACX_PKGVERSION): Update revision merge string.
+ * configure: Regenerate.
+
+2008-04-03 Rafael Espindola <espindola@google.com>
+
+ Merge with mainline @133612.
+
+ * configure.ac (ACX_PKGVERSION): Update revision merge string.
+ * configure: Regenerate.
+
+2008-04-03 Aldy Hernandez <aldyh@redhat.com>
+
+ * tree-pretty-print.c (dump_generic_node): Remove
+ OMP_{RETURN,CONTINUE} cases.
+ * tree.h (OMP_RETURN_NOWAIT): Remove.
+ * omp-low.c (dump_omp_region): Rename OMP_{CONTINUE,RETURN} to
+ GIMPLE_OMP_{CONTINUE,RETURN}.
+ (expand_omp_for_generic): Handle new arguments to
+ GIMPLE_OMP_CONTINUE.
+ (expand_omp_for_static_nochunk): Same.
+ (expand_omp_for_static_chunk): Same.
+ (expand_omp_sections): Same.
+ (expand_omp): Rename all OMP_* to GIMPLE_OMP_*.
+ (lower_omp_sections): Rename OMP_CONTINUE to GIMPLE_OMP_CONTINUE.
+ (lower_omp_for): Same.
+ * tree-gimple.c (is_gimple_stmt): Remove OMP_{RETURN,CONTINUE}
+ cases.
+ * gsstruct.def: Add GSS_OMP_CONTINUE.
+ * gimple-pretty-print.c (dump_gimple_omp_continue): New.
+ (dump_gimple_omp_return): New.
+ (dump_gimple_stmt): Add cases for GIMPLE_OMP_{CONTINUE,RETURN}.
+ * gimplify.c (gimplify_expr): Remove cases for
+ OMP_{CONTINUE,RETURN}.
+ * tree.def (DEFTREECODE): Remove OMP_{RETURN,CONTINUE}.
+ * tree-cfgcleanup.c (cleanup_omp_return): Rename
+ OMP_SECTIONS_SWITCH to GIMPLE_OMP_SECTIONS_SWITCH.
+ * gimple.c (gss_for_code): GIMPLE_OMP_RETURN returns GSS_BASE.
+ GIMPLE_OMP_CONTINUE return GSS_OMP_CONTINUE.
+ (gimple_size): Adjust size of GIMPLE_OMP_{RETURN,CONTINUE}.
+ (gimple_build_omp_continue): Change arguments.
+ (walk_gimple_op): Walk GIMPLE_OMP_CONTINUE operands.
+ (walk_gimple_stmt): Remove GIMPLE_OMP_CONTINUE case.
+ * gimple.h (struct gimple_statement_omp_continue): New.
+ (union gimple_statement_d): Add gimple_omp_continue.
+ (gimple_build_omp_continue): Change argument types in prototype.
+ (gimple_omp_return_set_nowait): Rename OMP_RETURN to
+ GIMPLE_OMP_RETURN.
+ (gimple_omp_continue_control_def): New.
+ (gimple_omp_continue_control_def_ptr): New.
+ (gimple_omp_continue_set_control_def): New.
+ (gimple_omp_continue_control_use): New.
+ (gimple_omp_continue_control_use_ptr): New.
+ (gimple_omp_continue_set_control_use): New.
+ * tree-cfg.c (make_edges): Rename OMP_ to GIMPLE_OMP_.
+ (gimple_redirect_edge_and_branch): Same.
+ * tree-ssa-operands.c (get_expr_operands): Remove OMP_CONTINUE
+ case.
+
+2008-04-02 Doug Kwan <dougkwan@google.com>
+
+ * tree-complex.c (expand_complex_comparison): Set condition code
+ correctly for the NE_EXPR case.
+ * cfgexpand.c (gimple_to_tree): Generate assignment to return value
+ if necessary.
+
+2008-04-02 Rafael Espindola <espindola@google.com>
+
+ Merge with mainline @133597.
+
+ * configure.ac (ACX_PKGVERSION): Update revision merge string.
+ * configure: Regenerate.
+
+2008-04-02 Rafael Espindola <espindola@google.com>
+
+ Merge with mainline @133527.
+
+ * configure.ac (ACX_PKGVERSION): Update revision merge string.
+ * configure: Regenerate.
+
+2008-04-02 Rafael Espindola <espindola@google.com>
+
+ Merge with mainline @133519.
+
+ * configure.ac (ACX_PKGVERSION): Update revision merge string.
+ * configure: Regenerate.
+
+2008-04-02 Rafael Espindola <espindola@google.com>
+
+ Merge with mainline @133453.
+
+ * configure.ac (ACX_PKGVERSION): Update revision merge string.
+ * configure: Regenerate.
+
+2008-04-01 Doug Kwan <dougkwan@google.com>
+ Bill Maddox <maddox@google.com>.
+
+ * value-prof.c (interesting_stringop_to_profile_p) Call
+ validate_gimple_arglist instead of validate_arglist.
+ * tree.h (validate_arglist): New declaration.
+ * builtins.c (expand_builtin_setjmp_receiver, expand_builtin_longjmp,
+ expand_builtin_nonlocal_goto, expand_builtin_nonlocal_goto,
+ expand_builtin_update_setjmp_buf, expand_builtin_prefetch,
+ expand_builtin_apply, expand_builtin_return, expand_builtin_mathfn,
+ expand_builtin_mathfn_2, expand_builtin_mathfn_3,
+ expand_builtin_interclass_mathfn, expand_builtin_sincos,
+ expand_builtin_cexpi, expand_builtin_int_roundingfn,
+ expand_builtin_int_roundingfn_2, expand_builtin_pow,
+ expand_builtin_powi, expand_builtin_strlen, expand_builtin_strlen,
+ expand_builtin_strstr, expand_builtin_strchr, expand_builtin_strrchr,
+ expand_builtin_memcpy, expand_builtin_memcpy,
+ expand_builtin_mempcpy_args, expand_builtin_bcopy, expand_movstr,
+ expand_builtin_stpcpy, expand_builtin_strncpy, builtin_memset_gen_str,
+ expand_builtin_bzero, expand_builtin_memchr, expand_builtin_memcmp,
+ expand_builtin_strcmp, expand_builtin_strncmp, expand_builtin_strcat,
+ expand_builtin_strncat, expand_builtin_strspn, expand_builtin_alloca,
+ expand_builtin_bswap, expand_builtin_unop, expand_builtin_fputs,
+ expand_builtin_fabs, expand_builtin_copysign,
+ expand_builtin___clear_cache, expand_builtin_init_trampoline,
+ expand_builtin_adjust_trampoline, expand_builtin_signbit,
+ expand_builtin, validate_arg, expand_builtin_object_size,
+ expand_builtin_object_size, expand_builtin_memory_chk) Re-enable code
+ previously disabled for GIMPLE.
+ (expand_builtin_memcpy, expand_builtin_memset_args): Re-enable code
+ previously disabled for GIMPLE. Look up tree attribute for original
+ GIMPLE statement.
+ (validate_arglist): Use old interface of tree node instead of GIMPLE
+ statement.
+ (validate_gimple_arglist): New function.
+ * cfgexpand.c (gimple_to_tree): Set GIMPLE statement tree attribute
+ for builtin function calls.
+ * tree-flow.h (struct tree_ann_common_d): New field stmt.
+ * gimple.h (validate_gimple_arglist): New declaration.
+ (validate_arglist): Moved to tree.h.
+
+2008-03-31 Oleg Ryjkov <olegr@google.com>
+
+ * gimplify.c (gimplify_switch_expr): Verify the return value from
+ gimplify_expr.
+
+2008-03-31 Rafael Espindola <espindola@google.com>
+
+ Merge with mainline @133452.
+
+ * configure.ac (ACX_PKGVERSION): Update revision merge string.
+ * configure: Regenerate.
+
+2008-03-31 Rafael Espindola <espindola@google.com>
+
+ Merge with mainline @133440.
+
+ * configure.ac (ACX_PKGVERSION): Update revision merge string.
+ * configure: Regenerate.
+
+2008-03-31 Rafael Espindola <espindola@google.com>
+
+ Merge with mainline @133423.
+
+ * configure.ac (ACX_PKGVERSION): Update revision merge string.
+ * configure: Regenerate.
+
+2008-03-30 Rafael Espindola <espindola@google.com>
+
+ Merge with mainline @133342.
+
+ * configure.ac (ACX_PKGVERSION): Update revision merge string.
+ * configure: Regenerate.
+
+2008-03-28 Rafael Espindola <espindola@google.com>
+
+ Merge with mainline @133341.
+
+ * configure.ac (ACX_PKGVERSION): Update revision merge string.
+ * configure: Regenerate.
+
+2008-03-28 Oleg Ryjkov <olegr@google.com>
+
+ * tree-eh.c (replace_goto_queue_1): Do a deep copy of the replacement
+ sequence.
+ (maybe_record_in_goto_queue): Set is_label flag when recording
+ GIMPLE_GOTOs.
+ (do_return_redirection, do_return_redirection): Changed to set
+ cont_stmt.
+ (lower_try_finally_onedest): Fix the code that assumes that gotos
+ themselves(instead of the labels) are recorded in the goto_queue.
+ (lower_try_finally_copy): Likewise.
+ (lower_try_finally_switch): Likewise, also fix the VEC_* operations.
+ * gimple.h (gimple_build_switch): Fixed comment.
+
+2008-03-28 Doug Kwan <dougkwan@google.com>
+
+ * omp-low.c (expand_omp_sections): Fix build breakage due to an
+ uninitialized variable.
+
+2008-03-28 Rafael Espindola <espindola@google.com>
+
+ Merge with mainline @133315.
+
+ * configure.ac (ACX_PKGVERSION): Update revision merge string.
+ * configure: Regenerate.
+
+2008-03-28 Diego Novillo <dnovillo@google.com>
+
+ * omp-low.c (expand_omp_for_static_chunk): Initialize
+ V_MAIN and V_BACK.
+ (expand_omp_for): Initialize VIN.
+
+2008-03-28 Rafael Espindola <espindola@google.com>
+
+ Merge with mainline @133313.
+
+ * configure.ac (ACX_PKGVERSION): Update revision merge string.
+ * configure: Regenerate.
+
+2008-03-27 Doug Kwan <dougkwan@google.com>
+
+ * c-decl.c (merge_decls): Also copy gimple bodies of decls.
+ * gimplify.c (gimplify_call_expr): Do not exit early when
+ gimplifying __builtin_va_start().
+
+2008-03-27 Oleg Ryjkov <olegr@google.com>
+
+ * gimple.c (walk_gimple_op): Add a check for assignments with more
+ than one operand on the LHS.
+
+2008-03-27 Aldy Hernandez <aldyh@redhat.com>
+
+ * tree.c (empty_body_p): Remove.
+ * tree.h (empty_body_p): Remove prototype.
+ * omp-low.c (struct omp_context): Convert to tuples.
+ (struct omp_context): Comment and convert to tuples.
+ (scan_omp_op): New.
+ (is_parallel_ctx): Convert to tuples.
+ (extract_omp_for_data): Same.
+ (workshare_safe_to_combine_p): Same.
+ (get_ws_args_for): Same.
+ (determine_parallel_type): Same.
+ (use_pointer_for_field): Same.
+ (dump_omp_region): Same.
+ (debug_all_omp_regions): Same.
+ (new_omp_region): Same.
+ (new_omp_context): Same.
+ (scan_sharing_clauses): Same.
+ (create_omp_child_function): Same.
+ (scan_omp_parallel): Same.
+ (scan_omp_for): Same.
+ (scan_omp_sections): Same.
+ (scan_omp_single): Same.
+ (check_omp_nesting_restrictions): Same.
+ (scan_omp_1_op): New.
+ (scan_omp_1_stmt): Rename from scan_omp_1. Rewrite for tuples.
+ (scan_omp): Convert to tuples.
+ (build_omp_barrier): Same.
+ (maybe_lookup_ctx): Same.
+ (lower_rec_input_clauses): Same.
+ (lower_lastprivate_clauses): Same.
+ (lower_reduction_clauses): Same.
+ (lower_copyprivate_clauses): Same.
+ (lower_send_clauses): Same.
+ (lower_send_shared_vars): Same.
+ (expand_parallel_call): Same.
+ (remove_exit_barrier): Same.
+ (remove_exit_barriers): Same.
+ (optimize_omp_library_calls): Same.
+ (expand_omp_parallel): Same.
+ (expand_omp_for_generic): Comment out, and convert to tuples.
+ (expand_omp_for_static_nochunk): Convert to tuples.
+ (expand_omp_for_static_chunk): Same.
+ (expand_omp_for): Same.
+ (expand_omp_sections): Same.
+ (expand_omp_synch): Same.
+ (expand_omp_atomic_fetch_op): Same.
+ (expand_omp_atomic_pipeline): Same.
+ (expand_omp_atomic_mutex): Same.
+ (expand_omp_atomic): Same.
+ (expand_omp): Same.
+ (build_omp_regions_1): Same.
+ (execute_expand_omp): Enable.
+ (execute_lower_omp): Enable and convert to tuples.
+ * gimple-dummy.c (omp_reduction_init): Remove.
+ * tree-flow.h (struct omp_region): Convert 'type' to tuples.
+ (new_omp_region): Adjust prototype for tuples.
+ * gimple.c (empty_stmt_p): New.
+ (empty_body_p): New.
+ * gimple.h (empty_body_p): New prototype.
+ (gimple_has_location): Remove fixmes.
+ * tree-cfg.c (gimple_block_label): Remove ATTRIBUTE_UNUSED.
+
+2008-03-27 Rafael Espindola <espindola@google.com>
+
+ Merge with mainline @133311.
+
+ * configure.ac (ACX_PKGVERSION): Update revision merge string.
+ * configure: Regenerate.
+
+2008-03-27 Rafael Espindola <espindola@google.com>
+
+ * gcc/tree-nested.c (save_tmp_var): Use gsi_insert_after_without_update
+ instead of gsi_insert_after.
+
+2008-03-26 Jakub Staszak <kuba@et.pl>
+
+ * gimple.h (gimple_uid, gimple_set_uid): Defined.
+ (gimple_statement_base): Field UID added.
+ * tree-ssa-dse.c (execute_simple_dse): #if 0 removed, bitmap_empty_p
+ condition added. (memory_ssa_name_same, memory_address_same,
+ get_kill_of_stmt_lhs, dse_possible_dead_store_p, dse_optimize_stmt,
+ dse_record_phis, dse_finalize_block, tree_ssa_dse): Tuplified.
+ * passes.c (init_optimization_passes): pass_simple_dse and pass_dse
+ enabled.
+ * testsuite/gcc.dg/tree-ssa/ssa-dse-10.c: {dg-final} changed.
+ * testsuite/gcc.dg/tree-ssa/pr30375.c: {dg-final} changed.
+
+2008-03-26 Rafael Espindola <espindola@google.com>
+ * gcc/tree-ssa-operands.c (ssa_operands_active): Assert that cfun is
+ not NULL.
+ * gcc/tree-nested.c (init_tmp_var): Use
+ gsi_insert_before_without_update instead of gsi_insert_before.
+
+2008-03-25 Rafael Espindola <espindola@google.com>
+
+ Merge with mainline @133309.
+
+ * configure.ac (ACX_PKGVERSION): Update revision merge string.
+ * configure: Regenerate.
+
+2008-03-25 Rafael Espindola <espindola@google.com>
+
+ Merge with mainline @133306.
+
+ * configure.ac (ACX_PKGVERSION): Update revision merge string.
+ * configure: Regenerate.
+
+2008-03-25 Bill Maddox <maddox@google.com>
+
+ * tree-ssa-dom.c (loop_depth_of_name): Tuplify.
+ * tree-ssa-copy.c (stmt_may_generate_copy,
+ copy_prop_visit_assignment, copy_prop_visi_cond_stmt,
+ copy_prop_visit_stmt, copy_prop_visit_phi_node,
+ init_copy_prop, execute_copy_prop): Tuplify.
+ * passes.c (init_optimization_passes):
+ Enable pass_copy_prop.
+
+2008-03-25 Rafael Espindola <espindola@google.com>
+
+ Merge with mainline @133257.
+
+ * configure.ac (ACX_PKGVERSION): Update revision merge string.
+ * configure: Regenerate.
+
+2008-03-25 Oleg Ryjkov <olegr@google.com>
+
+ * gimple.c (gimple_build_bind): Added a new parameter - the
+ containing block.
+ * gimple.h (gimple_build_bind): Changed the header accordingly.
+ * gimplify.c (gimplify_bind_expr, gimplify_function_tree): Updated
+ the callers of gimple_build_bind.
+ (gimplify_body): Updated the call to gimple_build_bind and moved
+ the copying of block information into gimplify_bind_expr.
+
+2008-03-25 Rafael Espindola <espindola@google.com>
+
+ Merge with mainline @133255.
+
+ * configure.ac (ACX_PKGVERSION): Update revision merge string.
+ * configure: Regenerate.
+
+2008-03-25 Rafael Espindola <espindola@google.com>
+
+ Merge with mainline @133251.
+
+ * configure.ac (ACX_PKGVERSION): Update revision merge string.
+ * configure: Regenerate.
+
+2008-03-25 Rafael Espindola <espindola@google.com>
+
+ Merge with mainline @133250.
+
+ * configure.ac (ACX_PKGVERSION): Update revision merge string.
+ * configure: Regenerate.
+
+2008-03-24 Rafael Espindola <espindola@google.com>
+
+ Merge with mainline @133246.
+
+ * configure.ac (ACX_PKGVERSION): Update revision merge string.
+ * configure: Regenerate.
+
+2008-03-24 Rafael Espindola <espindola@google.com>
+
+ Merge with mainline @133222.
+
+ * configure.ac (ACX_PKGVERSION): Update revision merge string.
+ * configure: Regenerate.
+
+2008-03-24 Andrew Pinski <pinskia@gmail.com>
+
+ * passes.c (init_optimization_passes): Enable pass_split_crit_edges.
+
+2008-03-24 Rafael Espindola <espindola@google.com>
+
+ Merge with mainline @133169.
+
+ * configure.ac (ACX_PKGVERSION): Update revision merge string.
+ * configure: Regenerate.
+
+2008-03-21 Rafael Espindola <espindola@google.com>
+
+ Merge with mainline @133168.
+
+ * configure.ac (ACX_PKGVERSION): Update revision merge string.
+ * configure: Regenerate.
+
+2008-03-21 Rafael Espindola <espindola@google.com>
+
+ Merge with mainline @133167.
+
+ * configure.ac (ACX_PKGVERSION): Update revision merge string.
+ * configure: Regenerate.
+
+2008-03-20 Oleg Ryjkov <olegr@google.com>
+
+ * tree-eh.c (lower_try_finally): Correctly set the lowered sequence.
+
+2008-03-20 Jakub Staszak <kuba@et.pl>
+ Oleg Ryjkov <olegr@google.com>
+
+ * tree-ssa-sink.c (is_hidden_global_store): Tuplified.
+ * tree-ssa-dce.c (mark_stmt_necessary, mark_operand_necessary,
+ mark_stmt_if_obviously_necessary,
+ mark_control_dependent_edges_necessary,
+ find_obviously_necessary_stmts, propagate_necessity,
+ remove_dead_phis, eliminate_unnecessary_stmts, tree_dce_init,
+ tree_dce_done): Tuplified.
+ * tree-flow.h (is_hidden_global_store): Tuplified the declaration.
+ * passes.c (init_optimization_passes): Enabled pass_dce and
+ pass_cd_dce.
+
+2008-03-20 Oleg Ryjkov <olegr@google.com>
+
+ * tree-complex.c (init_dont_simulate_again, complex_visit_stmt,
+ update_complex_components, expand_complex_operations_1): Consider
+ GIMPLE_CALLs with a lhs, not only GIMPLE_ASSIGNs.
+ * gimplify.c (get_tmp_var_for): Removed.
+ (gimplify_call_expr): Remove call to get_tmp_var_for, set
+ gimple_register on a new lhs in some cases.
+
+2008-03-20 Rafael Espindola <espindola@google.com>
+
+ Merge with mainline @133162.
+
+ * configure.ac (ACX_PKGVERSION): Update revision merge string.
+ * configure: Regenerate.
+
+2008-03-20 Rafael Espindola <espindola@google.com>
+
+ Merge with mainline @133161.
+
+ * configure.ac (ACX_PKGVERSION): Update revision merge string.
+ * configure: Regenerate.
+
+2008-03-20 Rafael Espindola <espindola@google.com>
+
+ Merge with mainline @133140.
+
+ * configure.ac (ACX_PKGVERSION): Update revision merge string.
+ * configure: Regenerate.
+
+2008-03-20 Rafael Espindola <espindola@google.com>
+
+ Merge with mainline @133138.
+
+ * configure.ac (ACX_PKGVERSION): Update revision merge string.
+ * configure: Regenerate.
+
+2008-03-18 Bill Maddox <maddox@google.com>
+
+ * builtins.c (fold_builtin_object_size):
+ Enable call to compute_builtin_object_size, previously
+ stubbed out awaiting tuplification.
+ * tree-ssa-ccp.c (valid_gimple_rhs_p, valid_gimple_call_p,
+ move_ssa_defining_stmt_for_defs, update_call_from_tree):
+ Deleted, moved to tree-ssa-propagate.c.
+ (get_maxval_strlen): Use gimple_assign_single_p.
+ Handle assignment with unary NOP correctly.
+ * tree-ssa-propagate.c (valid_gimple_rhs_p, valid_gimple_call_p,
+ move_ssa_defining_stmt_for_defs, update_call_from_tree):
+ Moved here from tree-ssa-ccp.c.
+ * tree-ssa-propagate.h (valid_gimple_rhs_p, valid_gimple_call_p,
+ move_ssa_defining_stmt_for_defs, update_call_from_tree): Declared.
+ * gimple-dummy.c (compute_builtin_object_size): Removed dummy.
+ * tree_object_size.c (addr_object_size, alloc_object_size)
+ Tuplified.
+ (pass_through_call, compute_builtin_object_size): Tuplified.
+ (expr_object_size): Tuplified. Some cases broken out.
+ (plus_expr_object_size): Deleted.
+ (call_object_size, unknown_object_size, plus_stmt_object_size):
+ New functions. Handle cases broken out from expr_object_size.
+ (cond_expr_object_size): Fix comment.
+ (collect_object_sizes_for): Tuplify.
+ (check_for_plus_in_loops_1, check_for_plus_in_loops): Tuplify.
+ (compute_object_sizes): Tuplify.
+ * gimple.c (gimple_assign_single_p, gimple_assign_unary_nop_p):
+ New functions.
+ * gimple.h (gimple_assign_single_p, gimple_assign_unary_nop_p):
+ Declare.
+ * passes.c (init_optimization_passes): Enable pass_object_sizes.
+
+2008-03-18 Diego Novillo <dnovillo@google.com>
+ Oleg Ryjkov <olegr@google.com>
+
+ * gimplify.c (gimplify_body): Copy the block information from
+ the tree function body to gimple function body.
+ (gimplify_function_tree): Correctly wrap the function body
+ into the try/finally block if creating one.
+ * gimple.c (gimple_seq_has_side_effects): Removed.
+ * gimple.h (gimple_seq_has_side_effects): Removed declaration.
+ * tree-cfg.c (remove_useless_stmts_tf, remove_useless_stmts_tc):
+ Modified to use gimple_seq_empty_p instead of
+ gimple_seq_has_side_effects.
+
+2008-03-18 Aldy Hernandez <aldyh@redhat.com>
+
+ * gimple.c (walk_gimple_stmt): Collapse common code.
+ Add case for GIMPLE_WITH_CLEANUP_EXPR.
+
+2008-03-17 Zdenek Dvorak <ook@ucw.cz>
+
+ * gimple-iterator.c (gsi_for_stmt): Use gsi_start_phis.
+ (gsi_start_phis): New function.
+ * gimple.h (gsi_start_phis): Declare.
+ * tree-into-ssa.c (initialize_flags_in_bb, rewrite_initialize_block,
+ rewrite_add_phi_arguments, rewrite_update_init_block,
+ prepare_block_for_update): Use gsi_start_phis.
+ * tree-complex.c (init_dont_simulate_again, update_phi_components):
+ Ditto.
+ * tree-ssa-loop-manip.c (find_uses_to_rename_bb,
+ verify_loop_closed_ssa, split_loop_exit_edge,
+ tree_transform_and_unroll_loop): Ditto.
+ * tree-scalar-evolution.c (loop_closed_phi_def,
+ analyze_scalar_evolution_for_all_loop_phi_nodes, scev_const_prop):
+ Ditto.
+ * tree-phinodes.c (reserve_phi_args_for_new_edge, remove_phi_args):
+ Ditto.
+ * tree-ssa-copyrename.c (rename_ssa_copies): Ditto.
+ * tree-ssa-ccp.c (ccp_initialize): Ditto.
+ * tree-ssa-loop-ivopts.c (find_bivs, mark_bivs,
+ find_interesting_uses_outside, find_interesting_uses,
+ determine_set_costs): Ditto.
+ * tree-ssa-propagate.c (simulate_block, ssa_prop_init,
+ substitute_and_fold): Ditto.
+ * tree-ssa-alias.c (dump_points_to_info, create_structure_vars): Ditto.
+ * gimple-pretty-print.c (dump_phi_nodes): Ditto.
+ * tree-data-ref.c (stmts_from_loop): Ditto.
+ * tree-ssa-coalesce.c (build_ssa_conflict_graph,
+ create_outofssa_var_map, coalesce_partitions): Ditto.
+ * tree-dfa.c (collect_dfa_stats): Ditto.
+ * tree-cfgcleanup.c (phi_alternatives_equal, remove_forwarder_block,
+ remove_forwarder_block_with_phi, merge_phi_nodes): Ditto.
+ * tree-ssa-live.c (remove_unused_locals, calculate_live_on_exit,
+ verify_live_on_entry): Ditto.
+ * tree-ssa.c (ssa_redirect_edge, flush_pending_stmts, verify_ssa,
+ execute_late_warn_uninitialized, execute_update_addresses_taken):
+ Ditto.
+ * tree-outof-ssa.c (eliminate_build, eliminate_virtual_phis,
+ rewrite_trees, remove_ssa_form, insert_backedge_copies):
+ Ditto.
+ * cfgloop.c (find_subloop_latch_edge_by_ivs): Ditto.
+ * tree-ssa-structalias.c (compute_points_to_sets, ipa_pta_execute):
+ Ditto.
+ * tree-cfg.c (remove_phi_nodes_and_edges_for_unreachable_block,
+ reinstall_phi_args, verify_stmts, gimple_make_forwarder_block,
+ add_phi_args_after_copy_edge, gimple_lv_adjust_loop_header_phi):
+ Ditto.
+
+2008-03-16 Zdenek Dvorak <ook@ucw.cz>
+
+ * tree-ssa-loop-ivopts.c: Tuplify.
+ * gimple-dummy.c (multiplier_allowed_in_address_p, multiply_by_cost,
+ tree_ssa_iv_optimize): Removed.
+ * tree-ssa-phiopt.c (empty_block_p): Tuplify.
+ * gimple.h (gimple_cond_lhs_ptr, gimple_cond_rhs_ptr): New.
+ * passes.c (init_optimization_passes): Enable pass_iv_optimize.
+
+ * gimplify.c (gimplify_omp_workshare, gimplify_expr): Avoid using
+ uninitialized sequence.
+
+2008-03-13 Bill Maddox <maddox@google.com>
+
+ * tree.h (fold_call_stmt, gimple_fold_builtin_snprintf_chk):
+ Declare new functions.
+ * builtins.c (fold_builtin_object_size): Disable call to
+ compute_builtin_object_size, which has not been converted.
+ (gimple_rewrite_call_expr, gimple_fold_builtin_sprintf_chk,
+ gimple_fold_builtin_snprintf_chk, gimple_fold_builtin_varargs,
+ fold_call_stmt): New functions.
+ * tree-chrec.h (build_polynomial_chrec): Silence uninitialized
+ variable warning.
+ * tree-ssa-ccp.c (likely_value): Recognize additional cases
+ of constant values.
+ (surely_varying_stmt_p): Note that return statements are not
+ interesting to CCP as they no longer contain assignments.
+ (ccp_fold): Add missing spaces.
+ (valid_gimple_call_p): New function.
+ (get_maxval_strlen): Don't trip over unary operator.
+ (ccp_fold_builtin): Use fold_call_stmt and
+ gimple_fold_builtin_snprintf_chk. Enable disabled
+ call now that target has been converted for tuples.
+ Add missing spaces.
+ (move_ssa_defining_stmt_for_defs): New function.
+ (update_call_from_tree): New function.
+ (fold_gimple_call): Use update_call_from_tree.
+ (fold_stmt_inplace): Assert that operand folding tree
+ walk goes to completion, i.e., does not return non-null.
+ (optimize_stack_restore, optimize_stdarg_builtin):
+ Convert to tuples
+ (convert_to_gimple_builtin): Removed.
+ (gimplify_and_update_call_from_tree): New function.
+ Replaces convert_to_gimple_builtin.
+ (execute_fold_all_builtins): Convert to tuples.
+ * tree-ssa-propagate.c (replace_uses_in): Removed
+ replaced_address argument. Made function static.
+ (replace_vuses_in): Removed replaced_address argument.
+ (substitute_and_fold): Removed replaced_address boolean,
+ which was set but never examined.
+ * tree-ssa-propagate.h (replace_uses_in): Removed declaration.
+ * gimple-iterator.c (update_modified_stmt): Moved to
+ head of file to avoid a forward declaration.
+ (update_modified_stmts): New function.
+ (gsi_insert_seq_before_without_update,
+ gsi_insert_before_without_update,
+ gsi_insert_seq_after_without_update,
+ gsi_insert_after_without_update): New functions.
+ (gsi_insert_before, gsi_insert_seq_before,
+ gsi_insert_after, gsi_insert_seq_after): Call the
+ _without_update variants.
+ * gimplify.c (gimplify_seq_add_stmt, gimplify_seq_add_seq):
+ New functions.
+ (gimple_pop_condition, gimplify_return_expr, gimplify_loop_expr,
+ gimplify_switch_expr, gimplify_case_label_expr,
+ gimplify_self_mod_expr, gimplify_call_expr,
+ gimplify_modify_expr_to_memcpy, gimplify_modify_expr_to_memset,
+ gimplify_init_ctor_eval_range, gimpllify_modify_expr_complex_part,
+ gimplify_modify_expr, gimplify_asm_expr, gimplify_cleanup_point_expr,
+ gimple_push_cleanup, gimplify_omp_parallel, gimplify_omp_atomic,
+ gimplify_expr, gimplify_body, gimplify_function_tree): When adding
+ to statement sequences in the gimplifier, do not update operands.
+ * tree-dfa.c (find_new_referenced_vars): Convert to tuples.
+ * tree-flow.h (find_new_referenced_vars): Declare with new signature.
+ * gimple.h (gimple_return_set_retval): Fix argument validation.
+ (gsi_insert_seq_before_without_update,
+ gsi_insert_before_without_update,
+ gsi_insert_seq_after_without_update,
+ gsi_insert_after_without_update): Declare new functions.
+ * gimple.c (gimple_build_return): Rely on gimple_return_set_retval
+ to perform argument validation.
+ * passes.c (init_optimization_passes): Enable pass_fold_builtins.
+
+2008-03-13 Oleg Ryjkov <olegr@google.com>
+
+ * tree-cfg.c (gimplify_val): Removed.
+ (gimplify_build1, gimplify_build2, gimplify_build3): Use
+ force_gimple_operand_gsi instead of gimplify_val.
+ * tree-complex.c (extract_component): Use force_gimple_operand_gsi
+ instead of gimplify_val.
+ * tree-vect-generic.c (expand_vector_parallel): Ditto.
+
+2008-03-13 Diego Novillo <dnovillo@google.com>
+ Oleg Ryjkov <olegr@google.com>
+
+ * tree-ssa-operands.c (get_expr_operands): Handle FILTER_EXPR and
+ EXC_PTR_EXPR.
+
+2008-03-12 Diego Novillo <dnovillo@google.com>
+ Oleg Ryjkov <olegr@google.com>
+
+ * cfgexpand.c (gimple_to_tree): Record the correct type when
+ converting GIMPLE_CALL.
+
+2008-03-12 Zdenek Dvorak <ook@ucw.cz>
+
+ * tree-ssa-loop-im.c (stmt_cost, rewrite_bittest,
+ determine_invariantness_stmt, gather_mem_refs_stmt):
+ Use gimple_assign_rhs_code.
+ * cfgexpand.c (gimple_to_tree): Ditto.
+ * tree-inline.c (estimate_num_insns): Ditto.
+ * tree-vect-generic.c (expand_vector_operations_1): Ditto.
+ * tree-ssa-ccp.c (likely_value, ccp_fold, evaluate_stmt,
+ * gimple.c (gimple_fold, gimple_assign_set_rhs_with_ops): Ditto.
+ * tree-ssa-structalias.c (handle_ptr_arith): Ditto.
+ fold_gimple_assign): Ditto.
+ * value-prof.c (gimple_divmod_fixed_value_transform): Ditto.
+ * tree-ssa-loop-ch.c (copy_loop_headers): Ditto.
+ * tree-ssa-propagate.c (stmt_makes_single_load,
+ substitute_and_fold): Ditto.
+ * tree-ssa-loop-niter.c (chain_of_csts_start): Exclude memory loads.
+ (get_val_for): Assert that the statement is an assignment.
+ (derive_constant_upper_bound_assign,
+ expand_simple_operations): Use gimple_assign_rhs_code.
+ * tree-ssa-loop-manip.c (create_iv, ip_normal_pos,
+ standard_iv_increment_position, determine_exit_conditions,
+ tree_transform_and_unroll_loop): Tuplify.
+ * tree-scalar-evolution.c (interpret_expr): Fail for chrecs.
+ (interpret_gimple_assign, follow_ssa_edge_in_rhs): Use
+ gimple_assign_rhs_code.
+ * tree-gimple.c (gimple_assign_rhs_code): New function.
+ * tree-gimple.h (gimple_assign_rhs_code): Declare.
+ * tree-ssa-loop-ivopts.c (single_dom_exit): Enable.
+ * gimple-dummy.c (compute_data_dependences_for_loop, dump_ddrs,
+ free_data_refs, free_dependence_relations,
+ gimple_duplicate_loop_to_header_edge, tree_ssa_prefetch_arrays,
+ estimated_loop_iterations_int): Removed.
+ * tree-ssa-loop-ivcanon.c (tree_num_loop_insns): Tuplify.
+ * predict.c, tree-data-ref.c, tree-ssa-loop-prefetch.c: Tuplify.
+ * tree-data-ref.h (struct data_reference, struct rdg_vertex): Change
+ the type of stmt to gimple.
+ (get_references_in_stmt, create_data_ref, rdg_vertex_for_stmt,
+ stores_from_loop, remove_similar_memory_refs,
+ have_similar_memory_accesses): Declaration changed.
+ * gimple-iterator.c (gsi_insert_seq_on_edge_immediate): New.
+ * gimple-pretty-print.c (dump_gimple_assign): Dump nontemporal
+ move. Use gimple_assign_rhs_code.
+ (dump_unary_rhs, dump_binary_rhs): Use gimple_assign_rhs_code.
+ * gimplify.c (gimplify_modify_expr): Set lhs of the assignment to
+ the new SSA name.
+ * tree-ssa-coalesce.c (build_ssa_conflict_graph,
+ create_outofssa_var_map): Use gimple_assign_copy_p.
+ * tree-predcom.c (mark_virtual_ops_for_renaming): Enable.
+ * tree-inline.c (estimate_num_insns): Use gimple_assign_rhs_code.
+ * tree-flow.h (mark_virtual_ops_for_renaming): Declaration changed.
+ * gimple.h (struct gimple_statement_base): Change unused_4 flag
+ to nontemporal_move flag.
+ (gimple_assign_nontemporal_move_p, gimple_assign_set_nontemporal_move):
+ New functions.
+ (gsi_insert_seq_on_edge_immediate): Declare.
+ (gimple_assign_rhs2): Return NULL if the statement does not have two
+ operands.
+ (gimple_assign_subcode): Removed.
+ * tree-cfg.c (verify_types_in_gimple_assign): Use
+ gimple_assign_rhs_code.
+ (gimple_lv_adjust_loop_header_phi, gimple_lv_add_condition_to_bb):
+ Tuplify.
+ (gimple_cfg_hooks): Enable lv_add_condition_to_bb and
+ lv_adjust_loop_header_phi hooks.
+ * passes.c (init_optimization_passes): Enable pass_profile,
+ pass_check_data_deps and pass_loop_prefetch.
+
+2008-03-11 Diego Novillo <dnovillo@google.com>
+
+ * tree-ssa-operands.h: Added declaration of add_to_addressable_set.
+ * tree-ssa-operands.h (add_to_addressable_set): New function.
+ (gimple_add_to_addresses_taken): Moved most of the logic to
+ add_addressable_set.
+ * tree-ssa-structalias.c (update_alias_info): Record the variables
+ whose address is taken inside a phi node.
+
+2008-03-11 Aldy Hernandez <aldyh@redhat.com>
+
+ * tree-phinodes.c (allocate_phi_node): Update for tuples.
+ * gimplify.c (gimplify_function_tree): Dump memory stats.
+ * gimple.c: Declare gimple_alloc_counts, gimple_alloc_sizes,
+ and gimple_alloc_kind_names.
+ (gimple_alloc): Gather statistics for tuples.
+ (gimple_build_asm_1): Same.
+ (gimple_seq_alloc): Same.
+ (dump_gimple_statistics): New.
+ * gimple.h: Define gimple_alloc_kind.
+ (gimple_alloc_kind): New.
+ (dump_gimple_statistics): Protoize.
+ * tree-ssa-copy.c (replace_exp_1): Mark for_propagation as unused
+ (merged from mainline).
+
+2008-03-11 Diego Novillo <dnovillo@google.com>
+
+ Merge with mainline @133081.
+
+ * configure.ac (ACX_PKGVERSION): Update revision merge string.
+ * configure: Regenerate.
+
+2008-03-06 Diego Novillo <dnovillo@google.com>
+
+ Merge with mainline @132948
+
+ * configure.ac (ACX_PKGVERSION): Update revision merge string.
+ * configure: Regenerate.
+
+2008-03-06 Diego Novillo <dnovillo@google.com>
+
+ * config/rs6000/rs6000.c (rs6000_alloc_sdmode_stack_slot):
+ Call walk_gimple_op.
+ * tree-complex.c (expand_complex_div_wide): Call
+ split_block with STMT.
+
+2008-03-06 Diego Novillo <dnovillo@google.com>
+
+ * gimple.h (struct gimple_statement_base): Rename field
+ 'locus' to 'location'. Update all users.
+ (gimple_location): Rename from gimple_locus. Update all
+ users.
+ (gimple_set_location): Rename from gimple_set_locus.
+ Update all users.
+ (gimple_has_location): Rename from gimple_location_empty_p.
+ Change sign of return value. Update all users.
+ * gimplify.c (tree_annotate_all_with_location): Rename
+ from tree_annotate_all_with_locus.
+ (annotate_all_with_location): Rename from
+ annotate_all_with_locus.
+
+2008-03-05 Diego Novillo <dnovillo@google.com>
+
+ * gimple.c (gimple_set_lhs): Remove return keywords.
+
+2008-03-05 David Daney <ddaney@avtrex.com>
+
+ * builtins.c (expand_builtin___clear_cache): Disable call to
+ validate_arglist.
+ * config/mips/mips.c (mips_gimplify_va_arg_expr): Tuplify.
+
+2008-03-05 Bill Maddox <maddox@google.com>
+
+ * tree-ssa-ccp.c (dump_lattice_value, debug_lattice_value):
+ Re-enable functions #if'd out.
+ (test_default_value, likely_value, surely_varying_stmt_p,
+ ccp_initialize, ccp_visit_phi_node, ccp_fold, evaluate_stmt,
+ visit_assignment, visit_cond_stmt, ccp_visit_stmt):
+ Convert to tuples.
+ (fold_gimple_call): Don't trip over call that simplifies to
+ another call, not a constant.
+ * tree-ssa-propagate.c (ssa_prop_init): Initialize in-worklist
+ flag for phi nodes as well as statements.
+ (valid_gimple_expression_p): Add fixme comment to remove this.
+ function. It currently has static uses, but asserts when called.
+ (stmt_makes_single_load, stmt_makes_single_store):
+ Convert to tuples
+ (replace_phi_args_in): Convert to tuples. Fix typo in comment.
+ * gimple.c (gimple_copy_no_def_use, gimple_get_lhs,
+ gimple_set_lhs): New function.
+ * gimple.h (gimple_copy_no_def_use, gimple_get_lhs,
+ gimple_set_lhs): Declare new function.
+ * tree-cfg.c (replace_uses_by): Add comment regarding empty
+ operands.
+ * passes.c (init_optimization_passes): Enable pass_ccp and
+ pass_store_ccp.
+
+2008-03-05 David Daney <ddaney@avtrex.com>
+
+ * tree-phinodes.c (allocate_phi_node): Fix syntax errors from
+ previous commit.
+
+2008-03-05 Rafael Espindola <espindola@google.com>
+
+ * tree-phinodes.c (allocate_phi_node): free free_phinodes[bucket]
+ if empty.
+
+2008-03-05 Diego Novillo <dnovillo@google.com>
+
+ http://gcc.gnu.org/ml/gcc/2008-03/msg00256.html
+
+ * fold-const.c (tree_binary_nonnegative_warnv_p): Fix
+ invalid C90 declaration.
+ (tree_single_nonnegative_warnv_p): Likewise.
+ * gimplify.c (gimplify_bind_expr): Likewise.
+ (gimplify_return_expr): Likewise.
+
+2008-03-04 Zdenek Dvorak <ook@ucw.cz>
+
+ * tree-ssa-loop-niter.c, tree-scalar-evolution.c: Tuplified.
+ * tree-ssa-loop-manip.c (split_loop_exit_edge): Ditto.
+ * tree-chrec.c (chrec_fold_plus, chrec_apply, chrec_convert_1,
+ convert_affine_scev, chrec_convert_rhs, chrec_convert,
+ chrec_convert_aggressive): Pass statements as gimple.
+ * tree-scalar-evolution.h (get_loop_exit_condition, simple_iv):
+ Type changed.
+ * tree-chrec.h (chrec_convert, chrec_convert_rhs): Ditto.
+ * tree-ssa-loop-ivopts.c (abnormal_ssa_name_p,
+ idx_contains_abnormal_ssa_name_p, contains_abnormal_ssa_name_p,
+ expr_invariant_in_loop_p, tree_int_cst_sign_bit): Enabled.
+ * gimple-dummy.c (chrec_dont_know, chrec_known, chrec_not_analyzed_yet,
+ analyze_scalar_evolution, chrec_contains_symbols_defined_in_loop,
+ estimate_numbers_of_iterations, expr_invariant_in_loop_p,
+ free_numbers_of_iterations_estimates,
+ free_numbers_of_iterations_estimates_loop, get_loop_exit_condition,
+ instantiate_parameters, nowrap_type_p. scev_const_prop. scev_finalize,
+ scev_initialize, scev_probably_wraps_p, scev_reset,
+ tree_int_cst_sign_bit, number_of_iterations_exit, loop_niter_by_eval,
+ substitute_in_loop_info): Removed.
+ * tree-ssa-loop.c (tree_loop_optimizer_init): Merged into...
+ (tree_ssa_loop_init): ... here. Enable scev_initialize call.
+ (tree_ssa_loop_done): Enable scev finalization.
+ * gimple-iterator.c (gsi_insert_seq_nodes_before): Allow inserting
+ at the end of basic block.
+ (gsi_for_stmt): Handle phi nodes.
+ * cfgloop.h (struct nb_iter_bound): Change type of stmt field to gimple.
+ * tree-flow.h (scev_probably_wraps_p, convert_affine_scev,
+ stmt_dominates_stmt_p): Types changed.
+ * Makefile.in (gt-tree-scalar-evolution.h): Enable.
+ * gimple.c (extract_ops_from_tree): Export.
+ (gimple_copy): Do not share bitmaps.
+ * gimple.h (extract_ops_from_tree): Declare.
+ (gimple_call_set_lhs): Allow lhs to be NULL.
+ * tree-cfg.c (add_phi_args_after_copy_edge,
+ add_phi_args_after_copy_bb): Tuplify.
+ * passes.c (init_optimization_passes): Enable pass_ch, pass_scev_cprop.
+
+2008-03-04 Oleg Ryjkov <olegr@google.com>
+
+ * tree-ssa-dse.c (execute_simple_dse): Commented out.
+ * passes.c (init_optimization_passes): Disabling pass_simple_dse.
+
+2008-03-04 Bill Maddox <maddox@google.com>
+
+ * tree-cfg.c (remove_useless_stmts_1):
+ Correctly distinguish try-catch and try-finally.
+
+2008-03-04 Oleg Ryjkov <olegr@google.com>
+
+ * tree-ssa-dse.c (execute_simple_dse): Tuplified.
+ * gimplify.c (gimplify_return_expr): Copy the NO_WARNING flag
+ to the newly created expr from the tree.
+ * tree-cfg.c (gimplify_build1): Tuplified.
+ * passes.c (init_optimization_passes): Enabled
+ pass_warn_function_return, pass_update_address_taken,
+ pass_simple_dse and pass_build_alias passes.
+
+2008-03-04 Rafael Espindola <espindola@google.com>
+
+ * fold-const.c (tree_simple_nonnegative_warnv_p): New.
+ (tree_unary_nonnegative_warnv_p): New.
+ (tree_binary_nonnegative_warnv_p): New.
+ (tree_single_nonnegative_warnv_p): New.
+ (tree_invalid_nonnegative_warnv_p): New.
+ (tree_expr_nonnegative_warnv_p): Redefine in term of the new functions.
+
+2008-03-04 Aldy Hernandez <aldyh@redhat.com>
+
+ * gimple.c (walk_gimple_seq): Do not set wi->gsi.
+ (walk_gimple_stmt): Set wi->gsi.
+ * tree-cfg.c (verify_stmt): Use walk_gimple_op instead of
+ walk_gimple_stmt.
+ (verify_stmts): Same.
+
+2008-03-04 Diego Novillo <dnovillo@google.com>
+
+ http://gcc.gnu.org/ml/gcc-patches/2008-03/msg00219.html
+
+ * expr.c (expand_expr_real): Call lookup_expr_eh_region.
+ * tree-eh.c (lookup_stmt_eh_region_fn):
+ (lookup_stmt_eh_region): Fix comment.
+ (lookup_expr_eh_region): Handle missing cfun and missing
+ EH table.
+ (record_in_finally_tree): Fix comment.
+ (collect_finally_tree_1): Remove handler for
+ GIMPLE_SWITCH.
+ (maybe_record_in_goto_queue): Remove local variable
+ NEW_IS_LABEL.
+ Record GIMPLE_GOTOs instead of their label.
+ (verify_norecord_switch_expr): Retrieve the CASE_LABEL
+ from the case label expression.
+ (do_return_redirection): Change sign of assertion.
+ (lower_try_finally_onedest): Assert that
+ TF->GOTO_QUEUE[0] contains a GIMPLE statement.
+ (lower_try_finally_copy): Assert that Q contains a GIMPLE
+ statement.
+ (lower_try_finally_switch): Build a new GIMPLE label for
+ CONT_STMT.
+ (mark_eh_edge): Tuplify.
+ (verify_eh_edges): Tuplify.
+ (tree_can_throw_external): Remove unused function.
+ (optimize_double_finally): Remove #if 0.
+ * gimple-pretty-print.c (GIMPLE_NIY): Tidy.
+ (dump_gimple_resx): Fix format string for
+ dump_gimple_fmt.
+ * gimplify.c (gimplify_cleanup_point_expr): Initialize
+ BODY_SEQUENCE.
+ * calls.c (emit_call_1): Remove ATTRIBUTE_UNUSED markers.
+ * cfgexpand.c (gimple_to_tree) <GIMPLE_NOP>: Assign new
+ expression to T.
+ <GIMPLE_RESX>: Handle.
+ Always assign the value from lookup_stmt_eh_region to
+ ANN->RN.
+ * tree-cfg.c (start_recording_case_labels):
+ (recording_case_labels_p): Re-enable.
+ (get_cases_for_edge): Likewise.
+ (gimple_verify_flow_info): Re-enable call to
+ verify_eh_edges.
+ (gimple_redirect_edge_and_branch): Re-enable handling of
+ GIMPLE_SWITCH.
+ (gimple_block_ends_with_call_p): Tuplify.
+ (struct gimple_cfg_hooks): Enable block_ends_with_call_p
+ callback.
+
+2008-03-04 Rafael Espindola <espindola@google.com>
+
+ * fold-const.c (tree_unary_nonzero_warnv_p): New.
+ (tree_binary_nonzero_warnv_p): New.
+ (tree_single_nonzero_warnv_p): New.
+ (tree_expr_nonzero_warnv_p): Redefine using the new functions.
+
+2008-03-04 Aldy Hernandez <aldyh@redhat.com>
+
+ * gimple.c (walk_gimple_op): Update comment.
+ (walk_gimple_stmt): Same.
+
+2008-03-03 Aldy Hernandez <aldyh@redhat.com>
+
+ * cgraphbuild.c (build_cgraph_edges): Use walk_gimple_op instead of
+ walk_gimple_stmt.
+ * tree-ssa-alias-warnings.c (find_references_in_function): Same.
+ * tree-ssa-ccp.c (fold_stmt): Change walk_gimple_stmt call to
+ walk_gimple_op.
+ * tree-nrv.c (tree_nrv): Same.
+ * tree-ssa-alias.c (count_uses_and_derefs): Same.
+ * cfgexpand.c (discover_nonconstant_array_refs_r): Same.
+ * tree-nested.c (convert_nonlocal_reference_stmt): Make first
+ argument a GSI.
+ (convert_local_reference_op): Same.
+ (convert_nl_goto_reference): Same.
+ (convert_tramp_reference_stmt): Same.
+ (convert_gimple_call): Same.
+ * tree-inline.c (inline_forbidden_p_stmt): Same.
+ * tree-ssa.c (execute_early_warn_uninitialized): Change
+ walk_gimple_stmt call to walk_gimple_op.
+ * gimple.c (walk_gimple_seq): Pass GSI to walk_gimple_stmt.
+ (walk_gimple_stmt): Move operand walking code to...
+ (walk_gimple_op): ...here.
+ (walk_gimple_stmt): First argument is now a GSI.
+ * gimple.h: Change walk_stmt_fn argument to a GSI.
+ (walk_gimple_stmt): Make first argument is a GSI.
+ (walk_gimple_op): New prototype.
+ * tree-cfg.c (verify_stmt): Change argument to a GSI. Adjust
+ accordingly.
+
+2008-02-29 Zdenek Dvorak <ook@ucw.cz>
+
+ * tree-ssa-alias.c (is_escape_site): Detect pure/const functions
+ correctly.
+
+2008-02-28 Zdenek Dvorak <ook@ucw.cz>
+
+ * tree-ssa-loop-im.c: Tuplify.
+ * tree-ssa-loop-manip.c (add_exit_phis_edge, find_uses_to_rename_stmt,
+ find_uses_to_rename_bb, check_loop_closed_ssa_use,
+ check_loop_closed_ssa_stmt, verify_loop_closed_ssa): Ditto.
+ * gimple-dummy.c (rewrite_into_loop_closed_ssa, tree_ssa_lim,
+ verify_loop_closed_ssa, replace_exp): Removed.
+ * tree-ssa-loop.c (tree_ssa_loop_init, tree_ssa_loop_done): Comment
+ out scev initialization and finalization.
+ * gimple-iterator.c (gsi_remove): Rename remove_eh_info to
+ remove_permanently. Do not free operands if remove_permanently
+ is false.
+ (gimple_find_edge_insert_loc): Use gsi_last_bb.
+ * tree-eh.c (operation_could_trap_p): Factored out of ...
+ (tree_could_trap_p): ... here.
+ * tree-ssa-copy.c (replace_exp): Enable.
+ * tree-flow.h (movement_possibility): Declaration changed.
+ (operation_could_trap_p): Declare.
+ * Makefile.in (tree-ssa-loop-im.o): Add pointer-set.h dependency.
+ (gimple.o): Add FLAGS_H dependency.
+ * gimple.c: Include flags.h.
+ (gimple_could_trap_p): New function.
+ * gimple.h (gimple_could_trap_p): Declare.
+ * tree-cfg.c (replace_uses_by): Check that op is not null.
+ * passes.c (init_optimization_passes): Enable pass_lim.
+
+2008-02-28 Rafael Espindola <espindola@google.com>
+
+ * tree-outof-ssa.c (insert_backedge_copies): Don't build
+ uninitialized assignment.
+
+2008-02-28 Rafael Espindola <espindola@google.com>
+
+ * tree-dfa.c (dump_dfa_stats): cast dfa_stats.max_num_phi_args to long.
+
+2008-02-26 Diego Novillo <dnovillo@google.com>
+
+ * tree-ssa-copyrename.c (rename_ssa_copies): Do not mix
+ declarations with code.
+ * tree-ssa-coalesce.c (create_outofssa_var_map): Likewise.
+ * tree-dfa.c (dump_dfa_stats): Use %ld for
+ dfa_stats.max_num_phi_args.
+
+2008-02-26 Bill Maddox <maddox@google.com>
+
+ * tree-ssa-ccp.c (maybe_fold_stmt_addition):
+ Reinstated this function for tuples as-is.
+ (valid_gimple_rhs_p): New function. Mostly lifted from
+ valid_gimple_epxression_p, which is likely obsolete.
+ (fold_stmt_r): Reinstated commented-out cases for
+ tuples. Replaced call to obsolete function set_rhs.
+ (get_maxval_strlen): Convert to tuples.
+ (ccp_fold_builtin): Partial conversion to tuples.
+ (fold_gimple_assign): New function.
+ (fold_gimple_cond): New function.
+ (fold_gimple_call): New function.
+ (fold_stmt): Convert to tuples.
+ (fold_stmt_inplace): Convert to tuples.
+ * tree-ssa-propagate.c (substitute_and_fold):
+ Update call to fold_stmt for revised argument signature.
+ * gimple-dummy.c (fold_stmt): Removed dummy definition.
+ * gimplify.c (gimplify_call_expr): Removed obsolete
+ manipulation of TREE_NOTHROW flag.
+ * cfgexpand.c (gimple_to_tree): Set nothrow flag
+ of call expression based on call statement flags.
+ Handle GIMPLE_NOP statement.
+ * tree-flow.h (notice_special_calls, fold_stmt):
+ Update prototypes for tuples.
+ * gimple.c (gimple_cond_set_condition_from_tree):
+ New function.
+ (gimple_seq_has_side_effects): New function.
+ * gimple.h (gimple_cond_set_condition_from_tree,
+ gimple_seq_has_side_effects): New prototypes.
+ (gimple_call_nothrow_p): New function.
+ (gsi_stmt_ptr): Add comment regarding usage of this
+ function vs. gsi_replace.
+ * tree-cfg.c (struct rus_data): Convert to tuples.
+ (remove_useless_stmts_1, remove_useless_stmts_warn_notreached,
+ remove_useless_stmts_cond, remove_useless_stmts_tf,
+ remove_useless_stmts_tc, remove_useless_stmts_goto,
+ remove_useless_stmts_label, notice_special_calls,
+ remove_useless_stmts): Convert to tuples.
+ (update_call_expr_flags): Removed.
+ * passes.c (init_optimization_passes): Enable
+ pass_remove_useless_stmts.
+
+2008-02-25 Bill Maddox <maddox@google.com>
+
+ * tree-into-ssa.c (rewrite_initialize_block):
+ Avoid declaration following statement in block.
+ * tree-nrv.c (tree_nrv):
+ Avoid declaration following statement in block.
+ * tree-eh.c (collect_finally_tree): Fix typo in comment.
+ Avoid cast to union type.
+ (replace_goto_queue_cond_clause, replace_goto_queue_1,
+ maybe_record_in_goto_queue, verify_norecord_switch_expr,
+ lower_try_finally_fallthru_label): Avoid cast to union type.
+ * fortran/Make-lang.in: Add -Wno-missing-format-attribute
+ to fortran-warn options to avoid conflict with -Wno-format.
+ * gimplify.c (gimplify_switch_expr): Change assignment
+ to initialiation.
+ (gimplify_case_label_expr): Avoid declaration following
+ statement in block.
+ * tree-ssa-coalesce.c (create_outofssa_var_map): Avoid
+ declaration following statement in block.
+ * tree-ssa.c (ssa_redirect_edge, flush_pending_stmts):
+ Avoid declaration following statements in block.
+ * Makefile.in: Add -Wno-missing-format-attribute
+ to builtins.o-warn and expr.o-warn options to avoid conflict
+ with -Wno-format. Removed fortran/*-warn options, -Wno-format
+ and -Wno-uninitialized, which belong in fortran/Make-lang.in,
+ and are applied to all fortran files there.
+
+2008-02-25 Oleg Ryjkov <olegr@google.com>
+
+ http://gcc.gnu.org/ml/gcc-patches/2008-02/msg01236.html
+
+ * tree-ssa-copyrename.c: Include gimple.h
+ Tuplify.
+ * tree-ssa.c (warn_uninit): Pass &LOCUS to warning().
+ * passes.c (init_optimization_passes): Enable
+ pass_early_warn_uninitialized, pass_rebuild_cgraph_edges
+ and pass_early_inline.
+
+2008-02-25 Diego Novillo <dnovillo@google.com>
+
+ * Makefile.in (tree-ssa-copyrename.o): Add dependency on
+ gimple.h.
+
+2008-02-25 Diego Novillo <dnovillo@google.com>
+
+ * tree-cfgcleanup.c (tree_forwarder_block_p): Revert
+ previous change.
+
+2008-02-25 Diego Novillo <dnovillo@google.com>
+
+ http://gcc.gnu.org/ml/gcc-patches/2008-02/msg01217.html
+
+ * tree-ssa-alias-warnings.c: Tuplify.
+ * cgraphunit.c (cgraph_process_new_functions): Remove
+ calls to gimple_unreachable.
+ (cgraph_expand_function): Likewise.
+ * omp-low.c (execute_expand_omp): Return 0 after call to
+ gimple_unreachable.
+ * tree-scalar-evolution.c (scev_const_prop): Likewise.
+ (execute_lower_omp): Likewise.
+ * tree-ssa-dse.c (execute_simple_dse): Likewise.
+ * tree-ssa-dom.c (tree_ssa_dominator_optimize): Likewise.
+ (eliminate_degenerate_phis): Likewise.
+ * tree-ssa-propagate.c (get_rhs): Likewise.
+ (valid_gimple_expression_p): Likewise.
+ (set_rhs): Likewise.
+ (fold_predicate_in): Likewise.
+ * tree-nrv.c (execute_return_slot_opt): Likewise.
+ * predict.c (tree_estimate_probability): Likewise.
+ * tree-parloops.c (parallelize_loops): Likewise.
+ * tree-if-conv.c (main_tree_if_conversion): Likewise.
+ * tree-ssa-phiopt.c (tree_ssa_phiopt): Likewise.
+ (tree_ssa_cs_elim): Likewise.
+ * tree-sra.c (tree_sra): Likewise.
+ (tree_sra_early): Likewise.
+ * tree-predcom.c (tree_predictive_commoning): Likewise.
+ * tree-ssa-copy.c (execute_copy_prop): Likewise.
+ * lambda-code.c (gcc_loop_to_lambda_loop): Likewise.
+ (perfect_nest_p): Likewise.
+ (can_convert_to_perfect_nest): Likewise.
+ (perfect_nestify): Likewise.
+ * tree-optimize.c (execute_fixup_cfg): Likewise.
+ * tree-object-size.c (compute_object_sizes): Likewise.
+ * tree-cfg.c (remove_useless_stmts): Likewise.
+ (gimple_duplicate_sese_tail): Likewise.
+ (move_sese_region_to_fn): Likewise.
+ (gimple_purge_dead_abnormal_call_edges): Likewise.
+ (execute_warn_function_return): Likewise.
+ * value-prof.c (gimple_histogram_value): Remove calls to
+ gimple_unreachable.
+ (gimple_stringop_fixed_value): Likewise.
+ * tree-flow-inline.h (op_iter_next_use): Likewise.
+ * tree-dfa.c (dump_variable): Likewise.
+ * tree-ssa-copy.c (may_propagate_copy): Likewise.
+ (may_propagate_copy_into_asm): Likewise.
+ (merge_alias_info): Likewise.
+ (replace_exp_1): Likewise.
+ * tree-ssa.c (delete_tree_ssa): Likewise.
+ * tree-cfg.c (make_edges): Likewise.
+ (remove_useless_stmts): Likewise.
+ (gimple_duplicate_sese_tail): Likewise.
+ (move_sese_region_to_fn): Likewise.
+ (gimple_purge_dead_abnormal_call_edges): Likewise.
+ (execute_warn_function_return): Likewise.
+ * passes.c (finish_optimization_passes): Likewise.
+ (init_optimization_passes): Likewise.
+ * tree-ssa-operands.c (add_call_clobber_ops): Likewise.
+ * tree-eh.c (lookup_expr_eh_region): New.
+ (tree_can_throw_external): Return false after call to
+ gimple_unreachable.
+ (maybe_clean_or_replace_eh_stmt): Re-enable.
+ Call stmt_could_throw_p.
+ * expr.c (expand_expr_real): Call lookup_expr_eh_region.
+ * profile.c: Tuplify.
+ * calls.c: Include tree-flow.h.
+ (emit_call_1): Call lookup_expr_eh_region.
+ (expand_call): Likewise.
+ * cfgexpand.c (gimple_to_tree): Call SET_EXPR_LOCATION on
+ generated expression tree T.
+ Set EH region number on T's annotation.
+ * common.opt (fgimple-conversion=): Add RejectNegative
+ and Joined attributes.
+ * tree-inline.c (unsave_r): Abort if *TP is a
+ STATEMENT_LIST.
+ (unsave_expr_now): Re-enable.
+ * tree-flow.h (struct tree_ann_common_d): Add field RN.
+ * Makefile.in (builtins.o-warn): Add -Wno-format.
+ (expr.o-warn): Likewise.
+ (fortran/check.o-warn): Likewise.
+ (fortran/interface.o-warn): Likewise.
+ (fortran/resolve.o-warn): Likewise.
+ (fortran/simplify.o-warn): Likewise.
+ (fortran/target-memory.o-warn): Likewise.
+ (calls.o): Add dependency on tree-flow.h
+ * gimple.c (gimple_build_asm_1): Call ggc_alloc_string to
+ copy STRING.
+ * gimple.h (gimple_filename): New.
+ (gimple_lineno): New.
+ * passes.c (init_optimization_passes): Disable
+ pass_remove_useless_stmts pass_mudflap_1,
+ pass_warn_function_return and pass_lower_omp.
+ * config/rs6000/rs6000.c (rs6000_gimplify_va_arg): Tuplify.
+ (rs6000_alloc_sdmode_stack_slot): Likewise.
+ * tree-cfgcleanup.c (tree_forwarder_block_p): Fix test
+ for PHI_WANTED.
+
+2008-02-25 Rafael Espindola <espindola@google.com>
+
+ * tree-cfgcleanup.c (tree_forwarder_block_p): fix thinko.
+
+2008-02-24 Rafael Espindola <espindola@google.com>
+
+ * gimple-iterator.c (gsi_split_seq_before): Don't abort if at the
+ beginning.
+
+2008-02-23 Diego Novillo <dnovillo@google.com>
+
+ http://gcc.gnu.org/ml/gcc-patches/2008-02/msg01025.html
+
+ * gimplify.c (gimplify_one_sizepos): Call gimplify_expr with
+ STMT_P.
+
+2008-02-22 Zdenek Dvorak <ook@ucw.cz>
+
+ * gimple.c (gimple_assign_copy_p): Do not consider unary operations
+ to be copies.
+
+2008-02-22 Diego Novillo <dnovillo@google.com>
+
+ * Makefile.in (fortran/parse.o-warn,
+ fortran/simplify.o-warn): New.
+
+2008-02-22 Diego Novillo <dnovillo@google.com>
+
+ http://gcc.gnu.org/ml/gcc-patches/2008-02/msg00961.html
+
+ Revert
+
+ 2008-02-20 Zdenek Dvorak <ook@ucw.cz>
+
+ * tree-tailcall.c: Tuplify.
+ * gimplify.c (force_gimple_operand): Remove ATTRIBUTE_UNUSED.
+ * gimple.c (gimple_assign_copy_p): Do not
+ consider unary operations to be copies.
+ (copy_or_nop_cast_stmt_rhs): New.
+ * gimple.h (copy_or_nop_cast_stmt_rhs): Declare.
+
+2008-02-21 Rafael Espindola <espindola@google.com>
+
+ * gimple.h (gimple_cond_true_p): Define.
+ (gimple_cond_false_p): Define.
+ (gimple_cond_single_var_p): Define.
+
+2008-02-21 Rafael Espindola <espindola@google.com>
+
+ * tree-tailcall.c (adjust_accumulator_values): Check that a phi was
+ found.
+
+2008-02-21 Rafael Espindola <espindola@google.com>
+
+ * tree-tailcall.c (adjust_accumulator_values): Initialize phi.
+
+2008-02-20 Zdenek Dvorak <ook@ucw.cz>
+
+ * tree-tailcall.c: Tuplify.
+ * gimplify.c (force_gimple_operand): Remove ATTRIBUTE_UNUSED.
+ * gimple.c (gimple_assign_copy_p): Do not consider unary operations
+ to be copies.
+ (copy_or_nop_cast_stmt_rhs): New.
+ * gimple.h (copy_or_nop_cast_stmt_rhs): Declare.
+
+2008-02-20 Oleg Ryjkov <olegr@google.com>
+
+ * gimplify.c (gimplify_expr): Save locus into the right
+ sequence.
+
+2008-02-20 Rafael Espindola <espindola@google.com>
+
+ * passes.c (init_optimization_passes): Enable pass_mark_used_blocks
+ and pass_cleanup_cfg_post_optimizing.
+ * tree-optimize.c (execute_cleanup_cfg_post_optimizing): call cleanup_tree_cfg.
+
+2008-02-20 Rafael Espindola <espindola@google.com>
+
+ * passes.c (init_optimization_passes): Enable pass_nrv.
+ * tree-nrv.c (finalize_nrv_r): data is now a walk_stmt_info.
+ (tree_nrv): port to gimple.
+
+2008-02-19 Oleg Ryjkov <olegr@google.com>
+
+ * gimple-pretty-print.c: Introduce support for TDF_RAW
+ flag.
+ (dump_gimple_fmt): New function.
+ (dump_gimple_assign, dump_gimple_return): Update to print
+ RAW gimple.
+ (dump_gimple_call_args): New function.
+ (dump_gimple_call, dump_gimple_switch, dump_gimple_cond,
+ dump_gimple_label, dump_gimple_bind, dump_gimple_try):
+ Update to print RAW gimple.
+ (dump_gimple_catch, dump_gimple_eh_filter,
+ dump_gimple_resx): New functions.
+ (dump_gimple_omp_for, dump_gimple_asm, dump_gimple_phi):
+ Update to print RAW gimple.
+ (dump_gimple_omp_parallel, dump_gimple_omp_atomic_load,
+ dump_gimple_omp_atomic_store): New, code moved from
+ dump_gimple_stmt, then added support to print RAW gimple.
+ (gimple_dump_stmt): Some code refactored into helper
+ subroutines.
+ * tree-cfg.c(dump_function_to_file): Print RAW gimple when
+ TDF_RAW is set.
+
+2008-02-19 Diego Novillo <dnovillo@google.com>
+
+ http://gcc.gnu.org/ml/gcc-patches/2008-02/msg00793.html
+
+ * tree-complex.c (expand_complex_div_wide): Call gsi_bb.
+ * tree.h (std_gimplify_va_arg_expr): Change gimple_seq
+ arguments to gimple_seq *.
+ Update all users.
+ (gimplify_parameters): Change return type to gimple_seq.
+ Update all users.
+ * target.h (struct gcc_target)<gimplify_va_arg_expr>:
+ Change gimple_seq arguments to gimple_seq *.
+ Update all users.
+ * tree-phinodes.c (free_phinodes): Convert to VEC.
+ Update all users.
+ * omp-low.c (lower_rec_input_clauses): Change gimple_seq
+ arguments to gimple_seq *. Update all users.
+ (lower_reduction_clauses): Convert sub_list to
+ gimple_seq.
+ (lower_regimplify): Convert PRE to gimple_seq.
+ (lower_regimplify): Call gimple_seq_insert_before instead
+ of tsi_link_before.
+ * tree-gimple.h (get_initialized_tmp_var,
+ get_formal_tmp_var, gimplify_expr, gimplify_type_sizes,
+ gimplify_one_sizepos, gimplify_stmt, gimplify_and_add,
+ gimplify_va_arg_expr): Change gimple_seq arguments to
+ gimple_seq *. Update all users.
+ * gimple-iterator.c: Include value-prof.h.
+ (gsi_link_seq_before): Remove. Update all users.
+ (gsi_link_seq_after): Remove. Update all users.
+ (gsi_link_after): Remove. Update all users.
+ (gsi_link_before): Remove. Update all users.
+ (update_bb_for_stmts): New.
+ (gsi_insert_seq_nodes_before): New.
+ (gsi_insert_seq_nodes_after): New.
+ (gsi_insert_seq_before): Re-write. Call
+ gsi_insert_seq_nodes_before.
+ (gsi_insert_seq_after): Re-write. Call
+ gsi_insert_seq_nodes_after.
+ (gsi_replace): Re-enable EH updating.
+ (update_modified_stmt): Move earlier in the file.
+ (gsi_insert_after): Re-write. Call
+ gsi_insert_seq_nodes_after.
+ (gsi_insert_before): Re-write. Call
+ gsi_insert_seq_nodes_before.
+ (gsi_remove): Move from gimple.h. Re-write.
+ * langhooks.h (struct lang_hooks): Change gimple_seq
+ arguments for gimplify_expr to gimple_seq *.
+ Update all users.
+ * coretypes.h (struct gimple_seq_d): Rename from struct
+ gimple_sequence. Update all users.
+ (struct gimple_seq_node_d): New.
+ (gimple_seq_node): New.
+ (const_gimple_seq_node): New.
+ * tree-flow.h (force_gimple_operand): Change gimple_seq
+ argument to gimple_seq *. Update all users.
+ * c-common.h (c_gimplify_expr): Change gimple_seq
+ argument to gimple_seq *. Update all users.
+ * Makefile.in (build):
+ * gimple.c (gimple_seq_cache): New.
+ (gimple_seq_alloc): Take sequences from gimple_seq_cache,
+ if possible.
+ (gimple_seq_free): New.
+ (gimple_seq_add_stmt): Rename from gimple_seq_add.
+ Change gimple_seq argument to gimple_seq *. Update all users.
+ (gimple_seq_add_seq): Rename from gimple_seq_append.
+ Update all users.
+ (gimple_remove): Remove. Update all users.
+ (gimple_seq_reverse): Remove unused function.
+ (gimple_set_bb): Only update block-to-labels map if
+ CFUN->CFG exists.
+ * gimple.h (struct gimple_seq_node_d): New.
+ (struct gimple_seq_d): Change fields 'first' and 'last'
+ to type gimple_seq_node. Update all users.
+ Add field 'next_free'.
+ (gimple_seq_first): Change return type to
+ gimple_seq_node. Update all users.
+ (gimple_seq_first_stmt): New.
+ (gimple_seq_last): Change return type to gimple_seq_node.
+ Update all users.
+ (gimple_seq_last_stmt): New.
+ (gimple_seq_set_first): Change second argument to type
+ gimple_seq_node. Update all users.
+ (gimple_seq_set_last): Change second argument to type
+ gimple_seq_node. Update all users.
+ (gimple_seq_init): Remove. Update all users.
+ (struct gimple_statement_base): Remove field 'next' and
+ 'prev'. Update all users.
+ (struct gimple_statement_omp): Change fields of type
+ struct gimple_sequence to type gimple_seq. Update all
+ users.
+ (struct gimple_statement_bind): Likewise.
+ (struct gimple_statement_catch): Likewise.
+ (struct gimple_statement_eh_filter): Likewise.
+ (struct gimple_statement_try): Likewise.
+ (struct gimple_statement_wce): Likewise.
+ (struct gimple_statement_omp_for): Likewise.
+ (gimple_set_prev): Remove. Update all users.
+ (gimple_set_next): Remove. Update all users.
+ (gimple_next): Remove. Update all users.
+ (gimple_prev): Remove. Update all users.
+ (gimple_seq_bb): New.
+ (gimple_catch_handler_ptr): New.
+ (gimple_stmt_iterator): Remove field 'stmt'.
+ Add field 'ptr'. Update all users.
+ (gsi_remove): Move to gimple-iterator.c
+ * tree-cfg.c (pass_build_cfg): Re-enable PROP_gimple_leh.
+ * Makefile.in (builtins.o-warn, expr.o-warn, dse.o-warn,
+ ebitmap.o-warn, lower-subreg.o-warn, tree-chrec.o-warn):
+ Change -Wno-error to -Wno-uninitialized.
+
+2008-02-19 Rafael Espindola <espindola@google.com>
+
+ * tree-eh.c (collect_finally_tree): handle GIMPLE_SWITCH.
+
+2008-02-19 Aldy Hernandez <aldyh@redhat.com>
+
+ * gimple.h (gimple_cond_invert): Remove prototype.
+ (update_stmt_if_modified): Fix typo in comment.
+ * gimple.c (walk_gimple_asm): Fix typo in comment.
+
+2008-02-13 Bill Maddox <maddox@google.com>
+
+ * tree-inline.c (estimate_operator_cost):
+ Removed operators superseded by tuplified statement forms.
+ Small cosmetic reordering of a few switch cases.
+
+2008-02-13 Oleg Ryjkov <olegr@google.com>
+
+ * tree.h: New function declaration.
+ * gimple-dummy.c (tree_inlinable_function_p): Removed.
+ * ipa-inline.c (compute_inline_parameters): Removed
+ gcc_unreachable ().
+ * calls.c (gimple_alloca_call_p): New function.
+ * tree-inline.c (inline_forbidden_p_1): Split in two and removed.
+ (inline_forbidden_p_op, inline_forbidden_p_stmt): New functions.
+ (inline_forbidden_p): Tuplified.
+ (estimate_operator_cost): Added missing cases.
+ * passes.c (init_optimization_passes): Enabled pass_inline_parameters,
+ pass_ipa_function_and_variable_visibility, pass_ipa_early_inline,
+ pass_inline_parameters, pass_rebuild_cgraph_edges passes.
+
+2008-02-13 Diego Novillo <dnovillo@google.com>
+
+ http://gcc.gnu.org/ml/gcc-patches/2008-02/msg00459.html
+
+ * gimple.def (GIMPLE_TRY): Tidy comment.
+ * gimple-pretty-print.c (dump_gimple_stmt): Handle TDF_VOPS and
+ TDF_MEMSYMS.
+
+2008-02-13 Diego Novillo <dnovillo@google.com>
+
+ http://gcc.gnu.org/ml/gcc-patches/2008-02/msg00455.html
+
+ * tree-complex.c (update_complex_components): Handle
+ GIMPLE_CALL and GIMPLE_ASSIGN.
+ (expand_complex_libcall): Set SSA_NAME_DEF_STMT on LHS.
+ * tree-ssa-operands.c (maybe_add_call_clobbered_vops):
+ Rename from get_call_expr_operands. Update all users.
+ Convert to handle GIMPLE_CALL instead of CALL_EXPR.
+ (get_modify_stmt_operands): Remove. Update all users.
+ (get_expr_operands): Do not handle CALL_EXPR, COND_EXPR,
+ VEC_COND_EXPR, GIMPLE_MODIFY_STMT, BLOCK, EXC_PTR_EXPR
+ and FILTER_EXPR.
+ (parse_ssa_operands): Call maybe_add_call_clobbered_vops
+ after parsing operands if STMT is a GIMPLE_CALL.
+
+2008-02-12 Zdenek Dvorak <ook@ucw.cz>
+ Bill Maddox <maddox@google.com>
+
+ http://gcc.gnu.org/ml/gcc-patches/2008-02/msg00429.html
+
+ * tree-inline.h (estimate_num_insns_fn): Declare.
+ * cgraphunit.c (cgraph_process_new_functions):
+ Use estimate_num_insns_fn.
+ * ipa-inline.c (compute_inline_parameters): Ditto.
+ * gimple-dummy.c (estimate_move_cost, estimate_num_insns):
+ Removed.
+ * tree-inline.c (struct eni_data, estimate_num_insns_1):
+ Removed.
+ (estimate_num_insns): Rewritten.
+ (operation_cost, estimate_num_insns_fn): New functions.
+ * gimple.c (gimple_copy): Unshare operands. Update
+ operand caches.
+ * gimple.h (gimple_set_no_warning): New.
+ (gimple_cond_set_true_label, gimple_cond_set_false_label):
+ Allow setting the label to NULL.
+ * tree-ssa-operands.c (copy_virtual_operands): Handle statements
+ without virtual operands.
+
+2008-02-12 Zdenek Dvorak <ook@ucw.cz>
+
+ http://gcc.gnu.org/ml/gcc-patches/2008-02/msg00429.html
+
+ * tree-into-ssa.c (update_ssa): Remove ATTRIBUTE_UNUSED.
+ * tree-ssa-loop-ch.c: Tuplified.
+ * gimple-iterator.c (gsi_commit_one_edge_insert): Ditto.
+ * tree-cfg.c (gimple_redirect_edge_and_branch,
+ gimple_try_redirect_by_replacing_jump, gimple_merge_blocks,
+ gimple_block_label, gimple_redirect_edge_and_branch_force,
+ gimple_duplicate_bb): Ditto.
+ (make_cond_expr_edges): Remove the labels.
+ (cleanup_dead_labels): Handle conditions without labels.
+ (gimple_make_forwarder_block): Do not reverse the list
+ of phi nodes.
+ (gimple_duplicate_sese_region): Enable ssa updates.
+ (gimple_cfg_hooks): Enable edge redirection and bb duplication.
+ * gimple-pretty-print.c (dump_gimple_cond): Do not dump
+ branches if labels are null.
+ (dump_implicit_edges): Dump implicit GIMPLE_COND edges.
+
+2008-02-12 Diego Novillo <dnovillo@google.com>
+
+ http://gcc.gnu.org/ml/gcc-patches/2008-02/msg00429.html
+
+ * tree-vrp.c (range_includes_zero_p): Partially re-enable.
+ (ssa_name_nonnegative_p): Partially re-enable.
+ (ssa_name_nonzero_p): Likewise.
+ * gimple-dummy.c (ssa_name_nonzero_p): Remove.
+ (ssa_name_nonnegative_p): Remove.
+ * tree-cfg.c (gimple_split_block): Convert to tuples.
+
+2008-02-12 Aldy Hernandez <aldyh@redhat.com>
+
+ Merge with mainline @132177
+
+ * configure.ac (ACX_PKGVERSION): Update revision merge string.
+ * configure: Regenerate.
+
+2008-02-08 Diego Novillo <dnovillo@google.com>
+
+ http://gcc.gnu.org/ml/gcc-patches/2008-02/msg00273.html
+
+ * gimplify.c (gimplify_call_expr): Remove code to set
+ TREE_SIDE_EFFECTS.
+ * gimple.c (gimple_has_side_effects): New.
+ * gimple.h (gimple_has_side_effects): Declare.
+ * tree-cfg.c (stmt_can_make_abnormal_goto): Call.
+
+2008-02-07 Diego Novillo <dnovillo@google.com>
+
+ * gimple.h (gimple_call_num_args): Rename from
+ gimple_call_nargs. Update all users.
+
+2008-02-07 Aldy Hernandez <aldyh@redhat.com>
+
+ * gimplify.c: Remove various FIXMEs that have been resolved.
+
+2008-02-06 Aldy Hernandez <aldyh@redhat.com>
+
+ * gimple.def: Add GIMPLE_OMP_ATOMIC_{LOAD,STORE} entires.
+ * gsstruct.def: Add GSS_OMP_ATOMIC_{LOAD,STORE} entries.
+ * gimple-pretty-print.c (dump_gimple_stmt): Add case for
+ GIMPLE_OMP_ATOMIC_{LOAD,STORE}.
+ * gimplify.c (gimplify_omp_atomic): Enable and convert to tuples.
+ * tree.def: Add FIXME notes.
+ * gimple.c (gss_for_code): Add cases for
+ GIMPLE_OMP_ATOMIC_{LOAD,STORE}.
+ (gimple_size): Same.
+ (gimple_build_omp_atomic_load): New.
+ (gimple_build_omp_atomic_store): New.
+ * gimple.h (struct gimple_statement_omp_atomic_{load,store}): New.
+ (union gimple_statement_d): Add gimple_omp_atomic_{load,store}.
+ (gimple_omp_atomic_store_set_val): New.
+ (gimple_omp_atomic_store_val): New.
+ (gimple_omp_atomic_load_set_lhs): New.
+ (gimple_omp_atomic_load_lhs): New.
+ (gimple_omp_atomic_load_set_rhs): New.
+ (gimple_omp_atomic_load_rhs): New.
+ * tree-cfg.c (verify_types_in_gimple_seq_2): Add cases for
+ GIMPLE_OMP_ATOMIC_{LOAD,STORE}.
+
+2008-02-05 Diego Novillo <dnovillo@google.com>
+
+ http://gcc.gnu.org/ml/gcc-patches/2008-02/msg00161.html
+
+ * gimple-iterator.c (gsi_split_seq_after): Change
+ argument type to gimple_stmt_iterator. Update all users.
+ (gsi_for_stmt): Return gimple_stmt_iterator. Update all users.
+ (gimple_find_edge_insert_loc): Change GSI argument to
+ gimple_stmt_iterator. Update all users.
+ * gimple.c (gimple_seq_deep_copy): Change argument to gimple_seq.
+ Update all users.
+ * gimple.h (gsi_alloc): Remove. Update all users.
+ (gsi_start): Return gimple_stmt_iterator. Update all users.
+ (gsi_start_bb): Likewise.
+ (gsi_last): Likewise.
+ (gsi_last_bb): Likewise.
+ (gsi_end_p): Change argument to gimple_stmt_iterator.
+ Update all users.
+ (gsi_one_before_end_p): Likewise.
+ (gsi_stmt): Likewise.
+ (gsi_bb): Likewise.
+ (gsi_seq): Likewise.
+ (gsi_split_seq_after): Likewise.
+ (gsi_for_stmt): Likewise.
+ (gsi_after_labels): Return gimple_stmt_iterator. Update all users.
+
+2008-02-05 Aldy Hernandez <aldyh@redhat.com>
+
+ * gimple-pretty-print.c (dump_gimple_stmt): Print clauses for
+ GIMPLE_OMP_PARALLEL.
+ Handle GIMPLE_OMP_FOR.
+ (dump_gimple_omp_for): New.
+ * tree-pretty-print.c (dump_omp_clauses): Remove static.
+ * diagnostic.h (dump_omp_clauses): Add prototype.
+ * gimplify.c (gimplify_omp_for): Convert to tuples and enable.
+ (gimplify_omp_workshare): Same.
+ (gimplify_expr) [OMP_MASTER, OMP_ORDERED, OMP_CRITICAL]: Same.
+
+2008-02-04 Oleg Ryjkov <olegr@google.com>
+
+ * tree-gimple.c (get_gimple_rhs_class): Handle
+ FILTER_EXPR.
+ * tree-eh.c (union treemple): Declare.
+ Convert to tuples.
+ * except.c:
+ * except.h (lang_protect_cleanup_actions): Change return
+ type to 'gimple'. Update all users.
+ * tree-inline.c (count_insns_seq): New.
+ * tree-inline.h (count_insns_seq): Declare.
+ * gimple.c (gimple_seq_deep_copy): New.
+ * gimple.h (gimple_seq_deep_copy): Declare.
+ (gimple_singleton_p): New.
+ * passes.c (init_optimization_passes): Enable
+ pass_lower_eh.
+
+2008-02-02 Aldy Hernandez <aldyh@redhat.com>
+
+ * tree.h (OMP_CLAUSE_REDUCTION_GIMPLE_INIT): New.
+ (OMP_CLAUSE_REDUCTION_GIMPLE_MERGE): New.
+ (struct tree_omp_clause): Add gimple_reduction_{init,merge} fields.
+ * gimplify.c (gimplify_scan_omp_clauses): Gimplify reduction
+ init/merge fields into separate sequences.
+ (gimplify_and_add): Use gimplify_expr directly.
+ * omp-low.c (lower_rec_input_clauses): Extract reduction info from
+ gimple tuples in structure.
+ (lower_reduction_clauses): Same.
+
+2008-02-01 Diego Novillo <dnovillo@google.com>
+
+ http://gcc.gnu.org/ml/gcc-patches/2008-02/msg00036.html
+
+ * tree-complex.c (expand_complex_comparison): Set the RHS
+ of the new comparison to boolean_true_node.
+ * gimplify.c (gimplify_call_expr): Fix creation of new
+ GIMPLE_CALL. Create the vector of arguments in the same
+ order as the original expression.
+
+2008-02-01 Diego Novillo <dnovillo@google.com>
+
+ http://gcc.gnu.org/ml/gcc-patches/2008-02/msg00032.html
+
+ * tree-pas.h (struct tree_opt_pass): Remove field
+ WORKS_WITH_TUPLES_P. Adjust all users.
+ * opts.c (decode_options): Force -O0.
+ * cfgexpand.c (gimple_to_tree): Handle GIMPLE_RETURN,
+ GIMPLE_ASM, GIMPLE_CALL and GIMPLE_SWITCH.
+ Show unrecognized tuple when failing.
+ (expand_gimple_basic_block): Do not use
+ gimple_stmt_iterator to go through the statements in BB.
+ Handle GIMPLE_CALL instead of CALL_EXPR.
+ (gimple_expand_cfg): Rename from tree_expand_cfg. Update
+ all users.
+ Remove PROP_gimple_leh.
+ * gimple.c (walk_gimple_seq): Guard against WI == NULL.
+ * tree-cfg.c (execute_warn_function_return): Move #if 0
+ markers.
+ * passes.c (init_optimization_passes): Adjust #if 0
+ markers to execute pass_expand.
+ Guard more passes under #if 0.
+
+2008-02-01 Rafael Espindola <espindola@google.com>
+
+ * passes.c (init_optimization_passes): Enable pass_del_ssa.
+
+ * tree-outof-ssa.c (insert_copy_on_edge): Port to tuples.
+ (eliminate_build): Likewise.
+ (eliminate_virtual_phis): Likewise.
+ (rewrite_trees): Likewise. Remove stmt_ann_t ann.
+ (stmt_list): Changed from tree to gimple_seq.
+ (identical_copies_p): Port to tuples.
+ (identical_stmt_lists_p): Likewise.
+ (init_analyze_edges_for_bb): Likewise.
+ (fini_analyze_edges_for_bb): Likewise.
+ (process_single_block_loop_latch): Likewise.
+ (analyze_edges_for_bb): LIkewise.
+ (remove_ssa_form): Likewise.
+ (insert_backedge_copies):
+ (rewrite_out_of_ssa):Likewise.
+ (pass_del_ssa): flip works_with_tuples_p. Don't require PROP_alias.
+
+ * tree-ssa-coalesce.c (build_ssa_conflict_graph): Port to tuples.
+ (abnormal_corrupt): Port to tuples.
+ (fail_abnormal_edge_coalesce): Port to tuples.
+ (create_outofssa_var_map):Port to tuples.
+ (coalesce_partitions): Port to tuples.
+
+2008-02-01 Rafael Espindola <espindola@google.com>
+
+ * tree-ssa-operands.c (free_stmt_operands): Only free
+ with_ops.addresses_taken if stmt has ops.
+
+2008-01-31 Rafael Espindola <espindola@google.com>
+
+ * tree-optimize.c (pass_free_cfg_annotations): Flip
+ works_with_tuples_p.
+ * passes.c (init_optimization_passes): Enable
+ pass_free_cfg_annotations.
+
+2008-01-30 Diego Novillo <dnovillo@google.com>
+
+ http://gcc.gnu.org/ml/gcc-patches/2008-01/msg01461.html
+
+ * tree-into-ssa.c (compute_global_livein): Initialize
+ PHI with call to gsi_stmt.
+ (rewrite_update_init_block): Likewise.
+ * tree-complex.c (expand_complex_comparison): Initialize
+ TYPE.
+ (expand_complex_operations_1): Initialize BR and BI.
+ * ebitmap.h (ebitmap_iter_init): Initialize OURN.
+ * Makefile.in (dse.o-warn, ebitmap.o-warn,
+ lower-subreg.o-warn, tree-chrec.o-warn, varasm.o-warn):
+ New.
+
+2008-01-30 Rafael Espindola <espindola@google.com>
+
+ * gimplify.c (gimplify_scan_omp_clauses): Comment out
+ pop_gimplify_context calls
+
+2008-01-30 Rafael Espindola <espindola@google.com>
+
+ * gimple.h (gsi_after_labels): Add.
+
+2008-01-30 Rafael Espindola <espindola@google.com>
+
+ * Makefile.in (tree-complex.o): Uncomment gt-tree-vect-generic.h.
+ (GTFILES): Add tree-vect-generic.c.
+ * passes.c (init_optimization_passes): Enable pass_lower_vector.
+ * tree-vect-generic.c: uncomment all the file.
+ (elem_op_func): Use gimple_stmt_iterator instead of
+ block_stmt_iterator.
+ (tree_vec_extract): Likewise. Rename bsi to gsi.
+ (do_unop): Likewise.
+ (do_binop): Likewise.
+ (do_plus_minus): Likewise.
+ (do_negate): Likewise.
+ (expand_vector_piecewise): Likewise.
+ (expand_vector_parallel): Likewise.
+ (expand_vector_addition): Likewise.
+ (expand_vector_operation): Likewise. Remove "tree rhs" param. Add
+ "gimple assign" param. Use gimple_assign_rhs1|2 instead of
+ TREE_OPERAND.
+ (expand_vector_operations_1): Use gimple_stmt_iterator instead of
+ block_stmt_iterator. Rename bsi to gsi. Use gsi_stmt instead of
+ bsi_stmt. Use gimple_assign_* instead of GIMPLE_STMT_OPERAND. Use
+ gimple_assign_set_rhs_from_tree instead of setting *p_rhs.
+ (gate_expand_vector_operations): Use gimple_stmt_iterator instead
+ of block_stmt_iterator. Use gsi_* instead of bsi_*
+ (pass_lower_vector): flip works_with_tuples_p
+ (pass_lower_vector_ssa) flip works_with_tuples_
+
+2008-01-29 Rafael Espindola <espindola@google.com>
+
+ http://gcc.gnu.org/ml/gcc-patches/2008-01/msg01434.html
+
+ * gimple.c (gimple_assign_set_rhs_with_ops): Fix
+ allocation of operand vector.
+
+2008-01-29 Diego Novillo <dnovillo@google.com>
+
+ http://gcc.gnu.org/ml/gcc-patches/2008-01/msg01434.html
+
+ * tree-into-ssa.c (prepare_block_for_update): Initialize
+ PHI.
+ * tree.c (build_gimple_modify_stmt): Fix documentation.
+
+ * tree-complex.c: Convert to tuples.
+ (pass_lower_complex_O0): Re-enable.
+
+ * ipa-cp.c (constant_val_insert): Disable.
+ * tree-gimple.c (get_gimple_rhs_class): Handle SSA_NAME.
+
+ * tree-ssa-propagate.c: Fix documentation to refer to
+ prop_simulate_again_p.
+ (add_ssa_edge): Call prop_simulate_again_p.
+ (simulate_stmt): Likewise.
+ (simulate_block): Fix loop iterating over PHI nodes.
+ * tree-ssa-propagate.h (prop_set_simulate_again): New.
+ (prop_simulate_again_p): New.
+ * gimple-iterator.c (gsi_insert_seq_after): Re-write to
+ avoid use of gimple_stmt_iterator.
+ (gimple_find_edge_insert_loc): Move from tree-cfg.c.
+ Re-enable.
+ (gsi_commit_edge_inserts): Likewise.
+ (gsi_commit_one_edge_insert): Likewise.
+ (gsi_insert_on_edge): Likewise.
+ (gsi_insert_on_edge_immediate): Likewise.
+ (gsi_insert_seq_on_edge): New.
+ * gimplify.c (gimplify_cond_expr): Call
+ gimple_cond_get_ops_from_tree.
+ * tree-optimize.c (pass_all_optimizations): Enable.
+ * gimple.c (gimple_cond_get_ops_from_tree): New.
+ (gimple_build_cond_from_tree): New.
+ * basic-block.h (struct edge_def): Replace field
+ edge_def_insns.t with gimple_seq edge_def_insns.g.
+ Update all users.
+ * gimple.h (gimple_stmt_iterator):
+ * tree-cfg.c (change_bb_for_stmt):
+ * passes.c (init_optimization_passes): Move #if0 around
+ to disable passes in groups instead of individually.
+ (execute_function_todo): Re-enable call to update_ssa.
+
+2008-01-25 Aldy Hernandez <aldyh@redhat.com>
+
+ * gimple-pretty-print.c (dump_gimple_stmt): Handle
+ GIMPLE_OMP_PARALLEL.
+ * gimplify.c (pop_gimplify_context): Add comment.
+ (gimplify_and_return_first): New.
+ (gimplify_scan_omp_clauses): Remove unused 'gs'.
+ Remove #if 0.
+ (gimplify_omp_parallel): Convert to tuples.
+ (gimplify_omp_workshare): Remove redundant retval.
+ (gimplify_expr): Adapt to lack of retval for gimplify_omp_variable and
+ gimplify_omp_workshare.
+ Abort on OMP_ATOMIC_{LOAD,STORE} case.
+
+2008-01-21 Diego Novillo <dnovillo@google.com>
+
+ Merge with mainline @131695
+
+ * configure.ac (ACX_PKGVERSION): Update revision merge
+ string.
+ * configure: Regenerate.
+
+2008-01-15 Diego Novillo <dnovillo@google.com>
+
+ http://gcc.gnu.org/ml/gcc-patches/2008-01/msg00674.html
+
+ * tree-into-ssa.c (mark_def_sites): Force operand scan.
+ * gimple.def (GIMPLE_ASSIGN): Move into section of
+ statements with memory operands.
+ * gimple-dummy.c (remove_unused_locals): Remove.
+ * tree-flow-inline.h (noreturn_call_p,
+ mark_stmt_modified, update_stmt, update_stmt_if_modified,
+ stmt_modified_p): Remove.
+ * tree-ssa-live.c: Convert to tuples.
+ * gimple.c (gimple_set_modified): Replace
+ mark_stmt_modified. Update all callers.
+ (gimple_remove): Call free_stmt_operands.
+ * gimple.h: Include tree-ssa-operands.h
+ Move extern function declarations earlier in the file.
+ (GIMPLE_CHECK2): Remove.
+ (GIMPLE_RANGE_CHECK): Remove.
+ (struct gimple_statement_with_ops): Fix GTY markers.
+ (struct gimple_statement_with_memory_ops): Likewise.
+ (gimple_modified_p): Replace stmt_modifed_p. Update all
+ users.
+ (update_stmt): Move from tree-flow-inline.h. Update all
+ users.
+ (update_stmt_if_modified): Likewise.
+ (gimple_has_ops): Use range GIMPLE_COND ... GIMPLE_RETURN
+ (gimple_has_mem_ops): Use range GIMPLE_ASSIGN ... GIMPLE_RETURN
+ (gimple_num_ops): Call gimple_has_ops.
+ (gimple_ops): Likewise.
+ (gimple_op): Likewise.
+ (gimple_op_ptr): Likewise.
+ (gimple_set_op): Likewise.
+ (gimple_set_addresses_taken): Remove. Update all users.
+ (gimple_add_to_addresses_taken): Likewise.
+ (gimple_call_noreturn_p): Replace noreturn_call_p.
+ Update all users.
+ (gimple_phi_arg): Assert that INDEX is smaller than
+ CAPACITY.
+ * passes.c (init_optimization_passes): Enable
+ pass_referenced_vars, pass_reset_cc_flags and pass_build_ssa.
+ * tree-ssa-operands.c (gimple_set_stored_syms): Do not
+ free the STORES field if SYMS is empty.
+ (gimple_set_loaded_syms): Likewise.
+ (finalize_ssa_stmt_operands): Only call
+ finalize_ssa_vdefs and finalize_ssa_vuses if STMT has
+ memory operands.
+ (get_expr_operands): Handle CASE_LABEL_EXPR.
+ (free_stmt_operands): Free bitmaps ADDRESSES_TAKEN,
+ STORES and LOADS.
+ (gimple_add_to_addresses_taken): Rename from
+ add_to_addressable_set.
+
+2008-01-14 Aldy Hernandez <aldyh@redhat.com>
+
+ * tree-dfa.c (dump_dfa_stats): Add %z modifier to size_t argument.
+
+2008-01-11 Andrew MacLeod <amacleod@redhat.com>
+ Diego Novillo <dnovillo@google.com>
+
+ http://gcc.gnu.org/ml/gcc-patches/2008-01/msg00493.html
+
+ * tree.h (struct ssa_use_operand_d): Replace field STMT
+ with a union field LOC containing the fields STMT and
+ SSA_NAME.
+ Update all users.
+ * tree-flow.h (struct immediate_use_iterator_d): Document
+ how immediate use iteration works.
+
+2008-01-10 Diego Novillo <dnovillo@google.com>
+
+ http://gcc.gnu.org/ml/gcc-patches/2008-01/msg00444.html
+
+ * Makefile.in (tree-complex.o): Remove gt-tree-vect-generic.h
+
+2008-01-10 Diego Novillo <dnovillo@google.com>
+
+ http://gcc.gnu.org/ml/gcc-patches/2008-01/msg00436.html
+
+ * tree-ssa-operands.h (PHI_RESULT_PTR): Call
+ gimple_phi_result_ptr.
+ (PHI_ARG_DEF_PTR): Call gimple_phi_arg_imm_use_ptr.
+ (free_ssa_operands): Remove.
+ (copy_virtual_operands, create_ssa_artificial_load_stmt,
+ add_to_addressable_set, discard_stmt_changes,
+ FOR_EACH_PHI_OR_STMT_USE, FOR_EACH_PHI_OR_STMT_DEF): Convert
+ to use 'gimple'.
+ * tree-into-ssa.c: Convert to use 'gimple'.
+ (rewrite_uses_p): New. Use instead of REWRITE_THIS_STMT.
+ (set_rewrite_uses): New. Use instead of REWRITE_THIS_STMT.
+ (register_defs_p): New. Use instead of
+ REGISTER_DEFS_IN_THIS_STMT.
+ (set_register_defs): New. Use instead of
+ REGISTER_DEFS_IN_THIS_STMT.
+ (REWRITE_THIS_STMT): Remove.
+ (REGISTER_DEFS_IN_THIS_STMT): Remove.
+ * tree-pretty-print.c (dump_vops): Remove. Update all
+ users.
+ (dump_generic_node): Do not handle PHI_NODE.
+ * tree.c (tree_node_kind): Remove "phi_nodes" entry.
+ (tree_code_size): Do not handle PHI_NODE.
+ (tree_size): Likewise.
+ (make_node_stat): Likewise.
+ (tree_node_structure): Likewise.
+ (phi_node_elt_check_failed): Remove.
+ * tree.h (PHI_NODE_ELT_CHECK): Remove.
+ (PHI_RESULT_TREE): Remove.
+ (PHI_ARG_DEF_TREE): Remove.
+ (PHI_CHAIN): Remove.
+ (PHI_NUM_ARGS): Remove.
+ (PHI_ARG_CAPACITY): Remove.
+ (PHI_ARG_ELT): Remove.
+ (PHI_ARG_EDGE): Remove.
+ (PHI_BB): Remove.
+ (PHI_ARG_IMM_USE_NODE): Remove.
+ (struct tree_phi_node): Remove.
+ (union tree_node): Remove field 'phi'.
+ (release_phi_node): Change argument to gimple.
+ (duplicate_ssa_name): Change second argument to gimple.
+ (swap_tree_operands): Remove.
+ (enum tree_node_kind): Remove phi_kind entry.
+ * tree-phinodes.c: Convert to use gimple.
+ * tree-gimple.c (is_gimple_stmt): Do not handle PHI_NODE.
+ * cgraphunit.c (cgraph_process_new_functions): Call
+ gimple_unreachable to mark unconverted sections.
+ (verify_cgraph_node): Do not ICE if THIS_CFUN is NULL.
+ Convert statement verification to use gimple.
+ (cgraph_expand_function): Call gimple_unreachable to mark
+ unconverted sections.
+ * tree-ssa-propagate.c: Convert to use gimple.
+ (STMT_IN_SSA_EDGE_WORKLIST): Use flag GF_PLF_1 as marker.
+ (DONT_SIMULATE_AGAIN): Remove. Use gimple_visited.
+ * gimple-dummy.c: Remove converted functions.
+ * tree-ssa-alias.c (may_be_aliased): Re-enable.
+ * tree-flow-inline.h (gimple_phi_arg_imm_use_ptr): Rename
+ from get_phi_arg_def_ptr.
+ (bsi_start, bsi_after_labels, bsi_last, bsi_end_p,
+ bsi_next, bsi_prev, bsi_stmt, bsi_stmt_ptr): Remove.
+ * tree.def (PHI_NODE): Remove. Update most users.
+ * tree-dfa.c: Convert to use gimple.
+ * common.opt (fgimple-conversion): Default to 0.
+ * tree-ssa.c: Convert to use gimple.
+ * tree-optimize.c (pass_early_local_passes,
+ pass_all_early_optimization, pass_init_datastructures):
+ Enable.
+ * tree-flow.h (tree_ann_type): Remove STMT_ANN. Update
+ all users.
+ (struct stmt_ann_d): Remove. Update all users.
+ * Makefile.in (GIMPLE_H): Add tree-ssa-operands.h.
+ (tree-ssa-copy.o, tree-phi-nodes.o, tree-complex.o):
+ Re-enable.
+ * gimple.h (enum plf_mask): Define.
+ (GF_NO_WARNING): Remove
+ (bb_seq): Return NULL if BB->il.gimple is NULL.
+ (struct gimple_statement_base): Add bitfields no_warning,
+ visited, unused_1, unused_2, unused_3, unused_4 and plf.
+ (gimple_flags, gimple_set_flags, gimple_add_flag):
+ Remove. Update all users.
+ (gimple_set_visited): New.
+ (gimple_visited_p): New.
+ (gimple_set_plf): New.
+ (gimple_plf): New.
+ (gimple_has_volatile_ops): New.
+ (gimple_set_has_volatile_ops): New.
+ (gimple_addresses_taken): New.
+ (gimple_set_addresses_taken): New.
+ (gimple_add_to_addresses_taken): New.
+ (gimple_phi_result_ptr): New.
+ (gsi_stmt_ptr): New.
+ (gsi_bb): New.
+ (gsi_seq): New.
+ * tree-cfg.c (execute_build_cfg): Do not call
+ gimple_set_body after building the CFG.
+ (pass_build_cfg): Do not require PROP_gimple_leh.
+ (gimplify_val): Convert to gimple.
+ * passes.c (init_optimization_passes): Disable all of
+ pass_all_early_optimizations.
+ * tree-ssanames.c: Convert to gimple.
+ * tree-ssa-operands.c: Convert to gimple.
+ (gimple_set_stored_syms): New.
+ (gimple_set_loaded_syms): New.
+
+2008-01-03 Diego Novillo <dnovillo@google.com>
+
+ Merge with mainline @131303
+
+ * configure.ac (ACX_PKGVERSION): Update revision merge
+ string.
+ * configure: Regenerate.
+
+2007-12-20 Diego Novillo <dnovillo@google.com>
+
+ * Makefile.in (builtins.o-warn, expr.o-warn): Add
+ -Wno-error.
+
+2007-12-05 Diego Novillo <dnovillo@google.com>
+
+ http://gcc.gnu.org/ml/gcc-patches/2007-12/msg00221.html
+
+ * gimple.c (walk_gimple_asm): Guard against WI being
+ NULL.
+ (walk_gimple_stmt): Likewise.
+
+2007-12-05 Diego Novillo <dnovillo@google.com>
+
+ http://gcc.gnu.org/ml/gcc-patches/2007-12/msg00216.html
+
+ * tree.h (gimple_unreachable_1): Declare.
+ (gimple_unreachable): Define.
+ Replace calls to gcc_unreachable with gimple_unreachable
+ in unconverted code.
+ * gimple-dummy.c (gimple_unreachable_1): New function.
+ * common.opt (fgimple-only): Remove.
+ (fgimple-conversion): Define.
+ * Makefile.in (STRICT_WARN): Add -Wno-return-type.
+
+2007-11-30 Diego Novillo <dnovillo@google.com>
+
+ Merge with mainline @130470
+
+ * configure.ac (ACX_PKGVERSION): Update revision merge
+ string.
+ * configure: Regenerate.
+ * tree-inline.c (copy_decl_no_change,
+ copy_decl_for_dup_finish): Re-enable.
+
+2007-11-26 Aldy Hernandez <aldyh@redhat.com>
+
+ * gimple.h (gimple_bind_block): Update comment.
+
+2007-11-19 Diego Novillo <dnovillo@google.com>
+
+ Merge with mainline @130291.
+
+ * configure.ac (ACX_PKGVERSION): Update revision merge string.
+ * configure: Regenerate.
+
+2007-11-19 Diego Novillo <dnovillo@google.com>
+
+ * tree-flow-inline.h (get_lineno): Call IS_LOCATION_EMPTY
+ and LOCATION_LINE instead of accessing location fields
+ directly.
+ * gimple-low.c (lower_function_body): Use
+ UNKNOWN_LOCATION instead of unknown_location.
+
+2007-11-16 Diego Novillo <dnovillo@google.com>
+
+ * cgraph.c (cgraph_create_edge): Call gimple_body
+ instead of DECL_SAVED_TREE.
+ (dump_cgraph_node): Likewise.
+ * cgraphunit.c (verify_cgraph_node): Likewise.
+ (cgraph_analyze_functions): Likewise.
+ (cgraph_mark_functions_to_output): Likewise.
+ (cgraph_optimize): Likewise.
+ * tree-eh.c (lower_eh_constructs): Add notes for future
+ changes to calls to DECL_SAVED_TREE.
+ (refactor_eh_r): Likewise.
+ * cfgexpand.c (gimple_to_tree): New function.
+ (maybe_dump_rtl_for_gimple_stmt): Rename from
+ maybe_dump_rtl_for_tree_stmt. Convert to tuples.
+ (label_rtx_for_bb): Convert to tuples.
+ (expand_gimple_cond): Rename from
+ expand_gimple_cond_expr. Convert to tuples.
+ (expand_gimple_tailcall): Convert to tuples.
+ (expand_gimple_basic_block): Convert to tuples.
+ (discover_nonconstant_array_refs_r): Convert to tuples.
+ (discover_nonconstant_array_refs): Convert to tuples.
+ * tree-mudflap.c (execute_mudflap_function_decls): Add
+ deprecation comment for DECL_SAVED_TREE call.
+ * tree-inline.c (copy_generic_body): Call gimple_body
+ instead of DECL_SAVED_TREE.
+ (inlinable_function_p): Likewise.
+ (clone_body): Add deprecation comment for DECL_SAVED_TREE
+ call.
+ * tree-cfg.c (remove_useless_stmts_bind): Call
+ gimple_body instead of DECL_SAVED_TREE.
+ (remove_useless_stmts): Likewise.
+
+2007-11-10 Aldy Hernandez <aldyh@redhat.com>
+
+ * tree-cfg.c (verify_types_in_gimple_call): OBJ_TYPE_REF are allowed
+ as function types.
+
+ [objc]
+ * objc-act.c (objc_gimplify_expr): Change pre and post to sequences.
+ * objc-act.h (objc_gimplify_expr): Change prototype accordingly.
+
+ [testsuite]
+ * lib/objc.exp: Set -I regardless of libobjc.
+
+2007-11-10 Aldy Hernandez <aldyh@redhat.com>
+
+ * tree-gimple.h (tree_annotate_all_with_locus): New.
+ * gimple-dummy.c: Add omp_reduction_init and
+ diagnose_omp_structured_block_errors.
+ * gimplify.c (tree_should_carry_locus_p): New.
+ (tree_annotate_one_with_locus): New.
+ (tree_annotate_all_with_locus): New.
+
+2007-11-08 Diego Novillo <dnovillo@google.com>
+
+ Merge with mainline @129982
+
+ * configure.ac (ACX_PKGVERSION): Update revision merge string.
+ * configure: Regenerate.
+
+2007-11-01 Diego Novillo <dnovillo@google.com>
+
+ * cgraphbuild.c (initialize_inline_failed): Re-enable.
+ (build_cgraph_edges): Adapt to use tuples.
+ (pass_build_cgraph): Re-enable.
+ (rebuild_cgraph_edges): Adapt to use tuples.
+ * cgraph.c (cgraph_release_function_body): Also NULLify the
+ gimple body.
+ (debug_cgraph_node): New.
+ (debug_cgraph): New.
+ * cgraph.h (struct cgraph_edge): Change field CALL_STMT to
+ type gimple. Update all users.
+ * cgraphunit.c (cgraph_analyze_functions): If DECL does not
+ have a struct function entry, discard it.
+ * gimple.h (GF_CALL_CANNOT_INLINE): New.
+ (gimple_call_lhs_ptr): New.
+ (gimple_call_mark_uninlinable): New.
+ (gimple_call_cannot_inline_p): New.
+ (struct walk_stmt_info): Add field PSET.
+
+2007-11-01 Diego Novillo <dnovillo@google.com>
+
+ * tree-optimize.c (tree_rest_of_compilation): Call
+ gimple_set_body to remove the body if not inlining.
+ * gimple.c (walk_gimple_stmt): Update documentation.
+ Pass WI->PSET to every call to walk_tree.
+
+2007-11-01 Diego Novillo <dnovillo@google.com>
+
+ * langhooks.h (struct lang_hooks_for_callgraph): Remove third
+ argument from function pointer ANALYZE_EXPR. Update all
+ users.
+
+2007-10-30 Diego Novillo <dnovillo@google.com>
+
+ * gimple.c (gimple_build_omp_return): Call
+ gimple_omp_return_set_nowait if needed.
+ * gimple.h (GIMPLE_CHECK, GIMPLE_CHECK2, GIMPLE_RANGE_CHECK):
+ Move earlier in the file.
+ (GF_NO_WARNING): Change to static const unsigned.
+ (GF_CALL_TAILCALL): New.
+ (GF_OMP_PARALLEL_COMBINED): Rename from
+ OMP_PARALLEL_COMBINED_FLAG. Change to static const unsigned.
+ Update all users.
+ (GF_OMP_RETURN_NOWAIT): Rename from OMP_RETURN_NOWAIT_FLAG.
+ Change to static const unsigned.
+ Update all users.
+ (GF_OMP_SECTION_LAST): Rename from OMP_SECTION_LAST_FLAG.
+ Change to static const unsigned.
+ Update all users.
+ (gimple_omp_return_set_nowait): New.
+ (gimple_call_set_tail): New.
+ (gimple_call_tail_p): New.
+
+2007-10-30 Aldy Hernandez <aldyh@redhat.com>
+
+ * gimplify.c (get_tmp_var_for): Remove reference to IS_FORMAL in
+ opening comment.
+ (gimplify_return_expr): Return GS_ERROR if we have errored.
+ (gimplify_statement_list): Handle case where voidify_wrapper returns a
+ temporary.
+ (gimplify_call_expr): Return gracefully on error.
+ (gimplify_cond_expr): Same.
+ * gimple.h (gimple_call_return_type): Do not error on methods.
+
+2007-10-29 Diego Novillo <dnovillo@google.com>
+ Tom Tromey <tromey@redhat.com>
+
+ * gimple.h (gimple_locus): Update comment.
+ (gimple_set_locus): Likewise.
+ (gimple_locus_empty_p): Add support for mapped locations.
+
+2007-10-29 Diego Novillo <dnovillo@google.com>
+
+ * tree-optimize.c (execute_cleanup_cfg_pre_ipa): Re-enable.
+ * gimple.c (walk_gimple_asm): Tidy comment.
+
+2007-10-29 Aldy Hernandez <aldyh@redhat.com>
+
+ * tree-gimple.h (build_gimple_eh_filter_tree): Remove.
+ * gimplify.c (build_gimple_eh_filter_tree): Move from here...
+ * cp/cp-gimplify.c: ...to here.
+ (cp_gimplify_init_expr): Convert to tuples.
+ (gimplify_must_not_throw_expr): Make function return a
+ gimplify_status and convert to tuples.
+ (cp_gimplify_expr): Convert MUST_NOT_THROW_EXPR, INIT_EXPR, and
+ USING_STMT to tuples.
+
+2007-10-28 Aldy Hernandez <aldyh@redhat.com>
+
+ * gimplify.c (gimplify_body): Make work when body contains more than
+ a GIMPLE_BIND statement.
+
+2007-10-26 Diego Novillo <dnovillo@google.com>
+
+ Merge with mainline @129659.
+
+ * configure.ac (ACX_PKGVERSION): Update revision merge string.
+ * configure: Regenerate.
+
+2007-10-26 Diego Novillo <dnovillo@google.com>
+
+ * gimple-low.c (lower_builtin_setjmp): Pass ARG to first
+ call to gimple_build_call.
+
+2007-10-17 Aldy Hernandez <aldyh@redhat.com>
+
+ * tree-gimple.c (get_gimple_rhs_class): Add case for EXC_PTR_EXPR.
+ * gimplify.c (gimple_conditional_context): Enable.
+ (gimplify_cleanup_point_expr): Enable. Adjust for tuples.
+ (gimple_push_cleanup): Enable.
+ (gimplify_target_expr): Do not gimplify TARGET_EXPR_CLEANUP before
+ calling gimple_push_cleanup.
+ (gimplify_expr): Rename `try' to `try_'.
+ Enable CLEANUP_POINT_EXPR case.
+ Gimplify CATCH_EXPR and EH_FILTER_EXPR cases correctly.
+
+2007-10-17 Aldy Hernandez <aldyh@redhat.com>
+
+ * gimple.c (gimple_size): Handle GIMPLE_WITH_CLEANUP_EXPR.
+ * gimple.h (struct gimple_statement_catch): Make handler a structure,
+ not a pointer.
+ (struct gimple_statement_eh_filter): Make failure a structure, not a
+ pointer.
+ document EH_FILTER_MUST_NOT_THROW subcode flag.
+ (gimple_catch_handler): Handler is now a struct.
+ (gimple_catch_set_handler): Same.
+ (gimple_eh_filter_failure): Failure is now a struct.
+ (gimple_eh_filter_set_failure): Same.
+ (gimple_eh_filter_must_not_throw): New.
+ (gimple_eh_filter_set_must_not_throw): New.
+ (gsi_next): Update comment.
+ (gsi_prev): Same.
+ * tree-cfg.c (verify_types_in_gimple_seq_2): Handle GIMPLE_EH_FILTER.
+
+2007-10-18 Diego Novillo <dnovillo@google.com>
+
+ * gimple-iterator.c (gsi_delink): Remove.
+ * gimple.h (gsi_delink): Remove.
+
+2007-10-17 Diego Novillo <dnovillo@google.com>
+
+ * coretypes.h (const_gimple_seq): New typedef.
+ * gimple.h (gimple_seq_first): Constify argument.
+ (gimple_seq_last): Likewise.
+ (gimple_seq_copy): Likewise.
+ (gimple_seq_empty_p): Likewise.
+ (gimple_set_prev): Rename from set_gimple_prev.
+ Update all users.
+ (gimple_set_next): Rename from set_gimple_next.
+ Update all users.
+ (gimple_set_flags): Rename from set_gimple_flags.
+ Update all users.
+ (gimple_add_flag): Rename from add_gimple_flag.
+ Update all users.
+ (gimple_set_subcode): Rename from set_gimple_subcode.
+ Update all users.
+ (gimple_set_block): Rename from set_gimple_block.
+ Update all users.
+ (gimple_set_locus): Rename from set_gimple_locus.
+ Update all users.
+ (gimple_locus_empty_p): Constify argument.
+ (gimple_has_ops): Likewise.
+ (gimple_has_mem_ops): Likewise.
+ (gimple_def_ops): Likewise.
+ (gimple_set_def_ops): Rename from set_gimple_def_ops.
+ Update all users.
+ (gimple_use_ops): Constify argument.
+ (gimple_set_use_ops): Rename from set_gimple_use_ops.
+ Update all users.
+ (gimple_vuse_ops): Constify argument.
+ (gimple_set_vuse_ops): Rename from set_gimple_vuse_ops.
+ Update all users.
+ (gimple_vdef_ops): Constify argument.
+ (gimple_set_vdef_ops): Rename from set_gimple_vdef_ops.
+ Update all users.
+ (gimple_loaded_syms): Constify argument.
+ (gimple_stored_syms): Constify argument.
+ (gimple_modified): Constify argument.
+ (gimple_set_modified): Rename from set_gimple_modified.
+ Update all users.
+ (gimple_omp_return_nowait_p): Constify argument.
+ (gimple_omp_section_last_p): Constify argument.
+ (gimple_omp_parallel_combined_p): Constify argument.
+ (gimple_build_return): Rename from build_gimple_return.
+ Update all users.
+ (gimple_build_assign): Rename from build_gimple_assign.
+ Update all users.
+ (gimple_build_assign_with_ops): Rename from
+ build_gimple_assign_with_ops.
+ Update all users.
+ (gimple_build_call_vec): Rename from build_gimple_call_vec.
+ Update all users.
+ (gimple_build_call): Rename from build_gimple_call.
+ Update all users.
+ (gimple_build_cond): Rename from build_gimple_cond.
+ Update all users.
+ (gimple_build_label): Rename from build_gimple_label.
+ Update all users.
+ (gimple_build_goto): Rename from build_gimple_goto.
+ Update all users.
+ (gimple_build_nop): Rename from build_gimple_nop.
+ Update all users.
+ (gimple_build_asm): Rename from build_gimple_asm.
+ Update all users.
+ (gimple_build_asm_vec): Rename from build_gimple_asm_vec.
+ Update all users.
+ (gimple_build_catch): Rename from build_gimple_catch.
+ Update all users.
+ (gimple_build_eh_filter): Rename from build_gimple_eh_filter.
+ Update all users.
+ (gimple_build_try): Rename from build_gimple_try.
+ Update all users.
+ (gimple_build_wce): Rename from build_gimple_wce.
+ Update all users.
+ (gimple_build_resx): Rename from build_gimple_resx.
+ Update all users.
+ (gimple_build_switch): Rename from build_gimple_switch.
+ Update all users.
+ (gimple_build_switch_vec): Rename from
+ build_gimple_switch_vec. Update all users.
+ (gimple_build_omp_parallel): Rename from
+ build_gimple_omp_parallel. Update all users.
+ (gimple_build_omp_for): Rename from build_gimple_omp_for.
+ Update all users.
+ (gimple_build_omp_critical): Rename from
+ build_gimple_omp_critical.
+ Update all users.
+ (gimple_build_omp_section): Rename from
+ build_gimple_omp_section. Update all users.
+ (gimple_build_omp_continue): Rename from
+ build_gimple_omp_continue. Update all users.
+ (gimple_build_omp_master): Rename from
+ build_gimple_omp_master. Update all users.
+ (gimple_build_omp_ordered): Rename from
+ build_gimple_omp_ordered. Update all users.
+ (gimple_build_omp_sections): Rename from
+ build_gimple_omp_sections. Update all users.
+ (gimple_build_omp_single): Rename from
+ build_gimple_omp_single. Update all users.
+ (gimple_set_body): Rename from set_gimple_body. Update all
+ users.
+ (gimple_set_bb): Rename from set_gimple_bb. Update all users.
+ (is_gimple_operand): Constify argument.
+ (gimple_ops): Likewise.
+ (gimple_op_ptr): Likewise.
+ (gimple_call_lhs): Likewise.
+ (gimple_call_return_type): Likewise.
+ (gimple_call_chain): Likewise.
+ (gimple_call_arg_ptr): Likewise.
+ (gimple_cond_true_label): Likewise.
+ (gimple_bind_vars): Likewise.
+ (gimple_bind_set_body): Likewise.
+ (gimple_bind_block): Likewise.
+ (gimple_asm_ninputs): Likewise.
+ (gimple_asm_noutputs): Likewise.
+ (gimple_asm_nclobbers): Likewise.
+ (gimple_asm_input_op): Likewise.
+ (gimple_asm_output_op): Likewise.
+ (gimple_asm_clobber_op): Likewise.
+ (gimple_asm_string): Likewise.
+ (gimple_asm_volatile_p): Likewise.
+ (gimple_catch_types): Likewise.
+ (gimple_catch_handler): Likewise.
+ (gimple_eh_filter_types): Likewise.
+ (gimple_eh_filter_failure): Likewise.
+ (gimple_try_kind): Likewise.
+ (gimple_try_set_eval): Likewise.
+ (gimple_try_set_cleanup): Likewise.
+ (gimple_wce_set_cleanup): Likewise.
+ (gimple_wce_cleanup_eh_only): Likewise.
+ (gimple_phi_capacity): Likewise.
+ (gimple_phi_num_args): Likewise.
+ (gimple_phi_result): Likewise.
+ (gimple_resx_region): Likewise.
+ (gimple_switch_num_labels): Likewise.
+ (gimple_switch_label): Likewise.
+ (gimple_switch_default_label): Likewise.
+ (gimple_omp_set_body): Likewise.
+ (gimple_omp_critical_name): Likewise.
+ (gimple_omp_for_clauses): Likewise.
+ (gimple_omp_for_index): Likewise.
+ (gimple_omp_for_initial): Likewise.
+ (gimple_omp_for_final): Likewise.
+ (gimple_omp_for_incr): Likewise.
+ (gimple_omp_for_set_pre_body): Likewise.
+ (gimple_omp_parallel_clauses): Likewise.
+ (gimple_omp_parallel_child_fn): Likewise.
+ (gimple_omp_parallel_data_arg): Likewise.
+ (gimple_omp_single_clauses): Likewise.
+ (gimple_omp_sections_clauses): Likewise.
+ (gimple_omp_for_cond): Likewise.
+ (gimple_return_retval): Likewise.
+ (is_gimple_omp): Likewise.
+ (gimple_nop_p): Likewise.
+ (gimple_expr_type): Likewise.
+
+2007-10-17 Diego Novillo <dnovillo@google.com>
+
+ * tree-ssa-loop-manip.c (gimple_duplicate_loop_to_header_edge): Rename
+ from tree_duplicate_loop_to_header_edge.
+ Update all users.
+ * value-prof.c: Convert and enable all functions in the file.
+ (gimple_divmod_fixed_value): Rename from
+ tree_divmod_fixed_value.
+ (gimple_mod_pow2): Rename from tree_mod_pow2.
+ (gimple_mod_subtract): Rename from tree_mod_subtract.
+ (gimple_divmod_fixed_value_transform): Rename from
+ tree_divmod_fixed_value_transform.
+ (gimple_mod_pow2_value_transform): Rename from
+ tree_mod_pow2_value_transform.
+ (gimple_mod_subtract_transform): Rename from
+ tree_mod_subtract_transform.
+ (gimple_stringops_transform): Rename from tree_stringops_transform.
+ (gimple_ic_transform): Rename from tree_ic_transform.
+ Update all users.
+ * value-prof.h (gimple_register_value_prof_hooks): Rename from
+ tree_register_value_prof_hooks. Update all users.
+ * tree.h (OMP_DIRECTIVE_P): Remove. Update all users.
+ (validate_arglist): Move to gimple.h.
+ * builtins.c: (validate_arglist): Change first argument to
+ const_gimple. Disable most callers.
+ * gimple.def: Document all GIMPLE codes.
+ * tree-gimple.c (is_gimple_operand): New.
+ (get_gimple_rhs_class)<ADDR_EXPR>: Accept as a
+ GIMPLE_SINGLE_RHS.
+ <WITH_SIZE_EXPR>: Likewise.
+ (get_gimple_rhs_num_ops): New.
+ (is_gimple_call_addr): Tidy.
+ * tree-gimple.h (get_gimple_rhs_num_ops): Declare.
+ * gimple-dummy.c (free_histograms, stringop_block_profile):
+ Remove.
+ * gimple-low.c (lower_function_body): Tidy.
+ * predict.c (gimple_predicted_by_p): Rename from
+ tree_predicted_by_p. Update all users.
+ (gimple_predict_edge): Rename from tree_predict_edge. Update
+ all users.
+ * gimple-iterator.c (gsi_link_seq_after): Update documentation.
+ (gsi_link_after): Likewise.
+ * tree-eh.c (stmt_could_throw_1_p): New.
+ (stmt_could_throw_p): New.
+ * gimple-pretty-print.c (dump_unary_rhs): Print ADDR_EXPR as
+ a single operand.
+ (dump_gimple_switch): Support NULL case labels.
+ (dump_gimple_asm): Dump outputs first.
+ * gimplify.c (compare_case_labels): Make the default label
+ sort first.
+ (sort_case_labels): Do not special case the default label.
+ (gimplify_init_ctor_eval): Gimplify initializer expressions.
+ (gimplify_modify_expr): Unshare the operands before setting
+ them on the new GIMPLE_ASSIGN statement.
+ (gimplify_asm_expr): NULLify the chain on operands before
+ putting them on the input/output vectors.
+ * tree-cfgcleanup.c: Convert and enable CFG cleanup functions.
+ (cleanup_control_expr_graph): Call gimple_fold.
+ * tree-flow.h (gimple_block_label): Rename from
+ tree_block_label. Update all users.
+ (gimple_duplicate_sese_region): Rename from
+ tree_duplicate_sese_region. Update all users.
+ (gimple_duplicate_sese_tail): Rename from
+ tree_duplicate_sese_tail. Update all users.
+ (gimple_purge_dead_abnormal_call_edges): Rename from
+ tree_purge_dead_abnormal_call_edges. Update all users.
+ (gimple_purge_all_dead_eh_edges): Rename from
+ tree_purge_all_dead_eh_edges. Update all users.
+ (stmt_could_throw_p): Declare.
+ (add_stmt_to_eh_region_fn): Move from except.h.
+ (remove_stmt_from_eh_region_fn): Likewise.
+ (lookup_stmt_eh_region_fn): Likewise.
+ (lookup_stmt_eh_region): Likewise.
+ (verify_eh_edges): Likewise.
+ * Makefile.in (GIMPLE_H): Add dependencies on GGC_H, TM_H and
+ TARGET_H.
+ (ipa-inline.o): Add dependency on TREE_FLOW_H.
+ (out_object_file): Add dependency on TREE_GIMPLE_H.
+ * gimple.c (gimple_set_code): Rename from set_gimple_code.
+ (gimple_size): New.
+ (gimple_alloc): New.
+ (gimple_alloc_ops): New.
+ (build_gimple_with_ops): Call them.
+ (build_gimple_return): Only call gimple_return_set_retval if
+ RETVAL is not NULL.
+ (build_gimple_call): Validate argument FN.
+ (extract_ops_from_tree): New.
+ (build_gimple_assign_with_ops): New.
+ (build_gimple_assign): Call them.
+ (build_gimple_nop): Call gimple_alloc.
+ (build_gimple_bind): Likewise.
+ (build_gimple_asm_1): Tidy.
+ (build_gimple_asm_vec): Tidy.
+ (build_gimple_asm): Tidy.
+ (build_gimple_catch): Call gimple_alloc.
+ (build_gimple_eh_filter): Likewise.
+ (build_gimple_try): Likewise.
+ (build_gimple_wce): Likewise.
+ (build_gimple_phi): Remove.
+ (build_gimple_resx): Call gimple_alloc.
+ (build_gimple_switch_1): Tidy.
+ (build_gimple_switch): Tidy.
+ (build_gimple_omp_critical): Call gimple_alloc.
+ (build_gimple_omp_for): Likewise.
+ (build_gimple_omp_parallel): Likewise.
+ (build_gimple_omp_section): Likewise.
+ (build_gimple_omp_master): Likewise.
+ (build_gimple_omp_continue): Likewise.
+ (build_gimple_omp_ordered): Likewise.
+ (build_gimple_omp_return): Likewise.
+ (build_gimple_omp_sections): Likewise.
+ (build_gimple_omp_single): Likewise.
+ (gimple_check_failed): Change GS to const_gimple. Update all
+ users.
+ (gimple_range_check_failed): Likewise.
+ (walk_gimple_seq): Change return type to tree. Update all
+ users.
+ If the call to walk_gimple_stmt returns non-NULL,
+ return it immediately.
+ (walk_gimple_asm): Change return type to tree. Update all
+ users.
+ If the call to walk_tree returns non-NULL, return it.
+ (walk_gimple_stmt): Likewise.
+ (gimple_fold): New.
+ (gimple_assign_set_rhs_from_tree): New.
+ (gimple_assign_set_rhs_with_ops): New.
+ (gimple_copy): New.
+ * basic-block.h (gimple_predicted_by_p): Rename from
+ tree_predicted_by_p. Update all users.
+ (gimple_predict_edge): Rename from tree_predict_edge. Update
+ all users.
+ * gimple.h: Add documentation to all inline functions.
+ (gimple_seq_first): Return NULL if S is NULL.
+ (gimple_seq_last): Likewise.
+ (GF_ASM_VOLATILE): Define.
+ (GF_NO_WARNING): Rename from GIMPLE_NO_WARNING. Update all
+ users.
+ (build_gimple_assign_with_ops): Declare.
+ (build_gimple_asm): Change unsigned arguments to size_t.
+ Update all users.
+ (build_gimple_switch): Likewise.
+ (build_gimple_phi): Remove.
+ (validate_arglist): Declare.
+ (gimple_fold): Declare.
+ (gimple_assign_set_rhs_from_tree): Declare.
+ (gimple_assign_set_rhs_with_ops): Declare.
+ (gimple_copy): Declare.
+ (is_gimple_operand): Declare.
+ (gimple_num_ops): Change argument to const_gimple.
+ Return 0 if GS is not one of the statements that has tree
+ operands.
+ (gimple_ops): New.
+ (gimple_op): Change argument to const_gimple.
+ If GS is not a statement that has tree operands, return NULL.
+ (gimple_op_ptr): Likewise.
+ (gimple_assign_subcode): Change argument to const_gimple.
+ (gimple_assign_operand): Remove. Update all users.
+ (gimple_assign_set_operand): Remove. Update all users.
+ (gimple_assign_lhs): Change argument type to const_gimple.
+ (gimple_assign_rhs1): Likewise.
+ (gimple_assign_rhs2): Likewise.
+ (gimple_assign_set_rhs1): Assert that RHS is a valid operand.
+ (gimple_assign_set_rhs2): Likewise.
+ (gimple_call_lhs): Call gimple_op.
+ (gimple_call_set_lhs): Assert that LHS is a valid operand.
+ Call gimple_set_op.
+ (gimple_call_set_fn): New.
+ (gimple_call_fndecl): Change argument type to const_gimple.
+ Call gimple_call_fn.
+ (gimple_call_chain): Call gimple_op.
+ (gimple_call_set_chain): Assert that CHAIN is valid.
+ Call gimple_set_op.
+ (gimple_call_nargs): Change argument to const_gimple.
+ Call gimple_op.
+ (gimple_call_arg_ptr): Call gimple_op_ptr.
+ (gimple_call_set_arg): Assert that ARG is valid.
+ Call gimple_set_op.
+ (gimple_cond_code): Change argument to const_gimple.
+ (gimple_cond_lhs): Change argument to const_gimple.
+ (gimple_cond_set_lhs): Assert that the operand is valid.
+ Call gimple_set_op.
+ (gimple_cond_rhs): Change argument to const_gimple.
+ Call gimple_op.
+ (gimple_cond_true_label): Call gimple_op.
+ (gimple_cond_false_label): Likewise.
+ (gimple_label_label): Likewise.
+ (gimple_cond_set_true_label): Assert that the operand is
+ valid.
+ Call gimple_set_op.
+ (gimple_cond_set_false_label): Likewise.
+ (gimple_goto_dest): Change argument to const_gimple.
+ Call gimple_set_op.
+ (gimple_goto_set_dest): Assert that the operand is valid.
+ Call gimple_set_op.
+ (gimple_asm_ninputs): Change return type to size_t. Update
+ all users.
+ (gimple_asm_noutputs): Likewise.
+ (gimple_asm_nclobbers): Rename from gimple_asm_nclobbered.
+ Change return type to size_t.
+ Update all users.
+ (gimple_asm_set_input_op): Assert that the argument is
+ valid.
+ (gimple_asm_set_output_op): Likewise.
+ (gimple_asm_set_clobber_op): Likewise.
+ (gimple_asm_volatile_p): New.
+ (gimple_asm_set_volatile): New.
+ (gimple_asm_clear_volatile): New.
+ (gimple_phi_set_capacity): Remove.
+ (gimple_phi_set_nargs): Remove.
+ (gimple_expr_type): New.
+ (struct walk_stmt_info): Remove fields want_bind_expr and
+ want_return_expr. Update all users.
+ * tree-cfg.c: Convert all functions for CFG cleanup and
+ verification.
+ (gimple_redirect_edge_and_branch): Rename from
+ tree_redirect_edge_and_branch.
+ (gimple_try_redirect_by_replacing_jump): Rename from
+ tree_try_redirect_by_replacing_jump.
+ (gimple_verify_flow_info): Rename from tree_verify_flow_info.
+ (gimple_make_forwarder_block): Rename from
+ tree_make_forwarder_block.
+ (gimple_cfg2vcg): Rename from tree_cfg2vcg.
+ (gimple_merge_blocks): Rename from tree_merge_blocks.
+ (gimple_can_merge_blocks_p): Rename from tree_merge_blocks_p.
+ (gimple_can_remove_branch_p): Rename from tree_can_remove_branch_p.
+ (gimple_redirect_edge_and_branch): Rename from
+ tree_redirect_edge_and_branch.
+ (gimple_move_block_after): Rename from tree_move_block_after.
+ (gimple_predict_edge): Rename from tree_predict_edge.
+ (gimple_predicted_by_p): Rename from tree_predicted_by_p.
+ (gimple_duplicate_bb): Rename from tree_duplicate_bb.
+ (gimple_can_duplicate_bb_p): Rename from tree_can_duplicate_bb_p.
+ (gimple_split_edge): Rename from tree_split_edge.
+ (gimple_make_forwarder_block): Rename from tree_make_forwarder_block.
+ (gimple_block_ends_with_call_p): Rename from
+ tree_block_ends_with_call_p.
+ (gimple_block_ends_with_condjump_p): Rename from
+ tree_block_ends_with_condjump_p.
+ (gimple_flow_call_edges_add): Rename from
+ tree_flow_call_edges_add.
+ (gimple_execute_on_growing_pred): Rename from
+ tree_execute_on_growing_pred.
+ (gimple_execute_on_shrinking_pred): Rename from
+ tree_execute_on_shrinking_pred.
+ (gimple_duplicate_loop_to_header_edge): Rename from
+ tree_duplicate_loop_to_header_edge.
+ (gimple_lv_add_condition_to_bb): Rename from
+ tree_lv_add_condition_to_bb.
+ (gimple_lv_adjust_loop_header_phi): Rename from
+ tree_lv_adjust_loop_header_phi.
+ (struct pass_build_cfg): Enable TODO_verify_stmts and
+ TODO_cleanup_cfg.
+ * passes.c (execute_function_todo): Enable call to
+ cleanup_tree_cfg.
+
+2007-10-17 Aldy Hernandez <aldyh@redhat.com>
+
+ * gimple.def: Add GIMPLE_WITH_CLEANUP_EXPR.
+ * gsstruct.def: Add GSS_WCE.
+ * gimple-iterator.c (gsi_delink): New.
+ (gsi_split_seq_*): Update comment.
+ * gimple.c (gss_for_code): Handle GIMPLE_WCE. Adjust whitespace.
+ (build_gimple_wce): New.
+ * gimple.h (struct gimple_statement_wce): New.
+ (union gimple_statement_d): Add gimple_wce.
+ (build_gimple_wce): Protoize.
+ (gimple_wce_cleanup): New.
+ (gimple_wce_set_cleanup): New.
+ (gimple_wce_cleanup_eh_only): New.
+ (gimple_wce_set_cleanup_eh_only): New.
+ (gsi_delink): Protoize.
+
+2007-10-12 Aldy Hernandez <aldyh@redhat.com>
+
+ * Makefile.in (GIMPLE_H): Depend on TARGET_H.
+ * gimple.h (gsi_alloc): New.
+ (_ALLOC_GSI): Remove.
+ Replace _ALLOC_GSI uses by gsi_alloc.
+
+2007-10-12 Aldy Hernandez <aldyh@redhat.com>
+
+ * gimple.h (_ALLOC_GSI): New.
+ Use it throughout when allocating a new gimple_stmt_iterator.
+
+2007-10-11 Aldy Hernandez <aldyh@redhat.com>
+
+ Merge with mainline @129233.
+
+ * configure.ac (ACX_PKGVERSION): Update revision merge string.
+ * configure: Regenerate.
+
+2007-10-11 Aldy Hernandez <aldyh@redhat.com>
+
+ * cfg.c: Include tree-flow.h.
+ (remove_edge_raw): Call redirect_edge_var_map_clear.
+ (redirect_edge_succ_nodup): Call redirect_edge_var_map_dup.
+ * tree-flow-inline.h (redirect_edge_var_map_def): New.
+ (redirect_edge_var_map_result): New.
+ * tree-cfgcleanup.c (remove_forwarder_block_with_phi): Replace
+ PENDING_STMT use with redirect_edge_var_map_*.
+ * tree-ssa.c (edge_var_maps): New definition.
+ (redirect_edge_var_map_add): New.
+ (redirect_edge_var_map_clear): New.
+ (redirect_edge_var_map_dup): New.
+ (redirect_edge_var_map_vector): New.
+ (redirect_edge_var_map_destroy): New.
+ (ssa_redirect_edge): Replace PENDING_STMT use with
+ redirect_edge_var_map_*.
+ (flush_pending_stmts): Same.
+ (delete_tree_ssa): Destroy edge var map.
+ * tree-flow.h (struct _edge_var_map): New.
+ Define edge_var_map vector type.
+ Declare redirect_edge_var_map_* prototypes.
+ * Makefile.in (cfg.o): Depend on TREE_FLOW_H.
+ * tree-cfg.c (reinstall_phi_args): Replace
+ PENDING_STMT use with redirect_edge_var_map_*.
+
+2007-10-02 Diego Novillo <dnovillo@google.com>
+
+ Merge with mainline @128957.
+
+ * configure.ac (ACX_PKGVERSION): Update revision merge string.
+ * configure: Regenerate.
+
+2007-09-24 Diego Novillo <dnovillo@google.com>
+
+ Merge with mainline @128708.
+
+ * configure.ac (ACX_PKGVERSION): Update revision merge string.
+ * configure: Regenerate.
+
+2007-09-24 Diego Novillo <dnovillo@google.com>
+
+ * gimple.h (gimple_code): Change argument type to
+ const_gimple.
+ (gimple_flags): Likewise.
+ (gimple_subcode): Likewise.
+ (gimple_next): Likewise.
+ (gimple_prev): Likewise.
+ (gimple_bb): Likewise.
+ (gimple_block): Likewise.
+ (gimple_locus): Likewise.
+
+2007-09-15 Diego Novillo <dnovillo@google.com>
+
+ * gimple-iterator.c (gsi_replace): Call gsi_insert_before and
+ gsi_remove to do the replacement.
+ (gsi_insert_before): Take the basic block from the iterator.
+ (gsi_insert_after): Likewise.
+ * gimple-iterator.h: Move inside gimple.h.
+ * tree-eh.c (make_eh_edge, make_eh_edges): Enable.
+ * gimple-pretty-print.c (dump_gimple_seq, dump_gimple_cond,
+ dump_gimple_bind, dump_gimple_try): Do not handle TDF_DETAILS.
+ (dump_gimple_switch): Fix display of case labels.
+ (dump_gimple_stmt): Handle TDF_DIAGNOSTIC.
+ (pp_cfg_jump): New.
+ (dump_implicit_edges): New.
+ (gimple_dump_bb_buff): Call it.
+ * domwalk.c (walk_dominator_tree):
+ * gimplify.c (gimplify_switch_expr): Fix generation of
+ GIMPLE_SWITCH labels.
+ (gimplify_case_label_expr): Emit a label for CASE_LABEL
+ instead of the CASE_LABEL_EXPR.
+ * Makefile.in (GIMPLE_H): Add dependency on BASIC_BLOCK_H.
+ * gimple.c (walk_gimple_stmt): Reverse meaning of return value
+ of CALLBACK_STMT. Update all users.
+ Walk sub-statements of statements with bodies.
+ * gimple.h (GCC_GIMPLE_H): Rename from GCC_GIMPLE_IR_H.
+ Include vec.h, tm.h, hard-reg-set.h and basic-block.h.
+ (bb_seq, set_bb_seq): Move from tree-flow-inline.h
+ (gimple_label_set_label): Do not allow CASE_LABEL_EXPR.
+ (gsi_start_bb): New. Update all users that were calling
+ gsi_start (bb_seq ()).
+ (struct gimple_stmt_iterator): Add field 'bb'.
+ * tree-cfg.c (build_gimple_cfg): Enable.
+ (create_bb): Create a new sequence if the given one is NULL.
+ (make_gimple_switch_edges): Rename from make_switch_expr_edges.
+ Update all users.
+ (cleanup_dead_labels): Fix handling of GIMPLE_SWITCH.
+ (group_case_labels): Likewise.
+ (verify_types_in_gimple_stmt): Do not allow CASE_LABEL_EXPR in
+ a GIMPLE_LABEL.
+
+2007-09-13 Diego Novillo <dnovillo@google.com>
+
+ * tree-pretty-print.c (dump_symbols, dump_generic_bb,
+ dump_bb_header, dump_bb_end, dump_phi_nodes, pp_cfg_jump,
+ dump_implicit_edges, dump_generic_bb_buff): Remove.
+ * value-prof.c (histogram_eq): Enable.
+ (dump_histograms_for_stmt): Adapt to tuples.
+ * value-prof.h (struct):
+ * cfghooks.h (struct cfg_hooks)<dump_bb>: Add int argument.
+ Update all users.
+ * gimple-dummy.c (gimple_remove_stmt_histograms,
+ remove_stmt_from_eh_region): Remove.
+ * gimple-iterator.h (gsi_start): Support NULL sequences.
+ * tree-eh.c (add_stmt_to_eh_region): Enable.
+ (remove_stmt_from_eh_region): Enable.
+ (lookup_stmt_eh_region): Enable.
+ (tree_could_throw_p): Enable.
+ (stmt_can_throw_internal): Enable.
+ * gimple-pretty-print.c: Include value-prof.h
+ (dump_gimple_cond): Do not insert a newline initially.
+ (dump_gimple_bind): Likewise.
+ (dump_gimple_try): Likewise.
+ (dump_gimple_asm): Likewise.
+ (dump_symbols): Move from tree-pretty-print.c
+ (dump_gimple_phi): New.
+ (dump_gimple_stmt): Call it..
+ (dump_bb_header): Move from tree-pretty-print.c
+ (dump_bb_end): Likewise.
+ (dump_phi_nodes): Likewise.
+ (gimple_dump_bb_buff): New.
+ (gimple_dump_bb): New.
+ * Makefile.in (gimple-pretty-print.o): Add dependency
+ value-prof.h
+ * tree-cfg.c (fold_cond_expr_cond): Handle cases where
+ fold_binary returns NULL.
+ (make_cond_expr_edges): Take locus from the first statement of
+ the destination blocks.
+ (tree_dump_bb): Remove.
+ (gimple_debug_bb): Rename from debug_tree_bb.
+ Update all users.
+ (gimple_debug_bb_n): Rename from debug_tree_bb_n.
+ Update all users.
+ (gimple_debug_cfg): Rename from debug_tree_cfg.
+ Update all users.
+ (gimple_dump_cfg): Rename from dump_tree_cfg.
+ Update all users.
+ (is_ctrl_altering_stmt): Call gimple_call_flags to determine
+ whether the function is const/pure.
+ * tree-ssa-operands.c (stmt_references_memory_p): Enable.
+
+2007-09-11 Diego Novillo <dnovillo@google.com>
+
+ * tree.h (struct tree_ssa_name): Add field def_stmt.
+ (SSA_NAME_DEF_STMT): Return it.
+ * tree-phinodes.c (create_phi_node): Return gimple.
+ Update all callers.
+ (add_phi_args): Change PHI argument to gimple. Update all
+ callers.
+ (remove_phi_node): Call gimple_remove.
+ (phi_reverse): Remove. Update all users.
+ * tree-ssa-alias-warnings.c: Disable.
+ * input.h (IS_LOCATION_EMPTY): Fix comparison of LOCATION_LINE.
+ * fold-const.c: Include gimple.h.
+ (fold_undefer_overflow_warnings): Change type of argument STMT to
+ gimple. Update all users.
+ * cfghooks.h (struct cfg_hooks)<can_merge_blocks_p>: Change
+ arguments to basic_block. Update all users.
+ * tree-gimple.c (get_gimple_rhs_class): Change argument to
+ enum tree_code. Update all users. Move calls to
+ is_gimple_lvalue and is gimple_val...
+ (is_gimple_formal_tmp_rhs): ... here.
+ * tree-ssa-ccp.c (fold_stmt_r): Enable.
+ (fold_stmt): Enable.
+ (fold_stmt_inplace): Enable. Adapt to tuples.
+ * ipa-pure-const.c (analyze_function): Disable.
+ * tree-ssa-propagate.c (get_rhs): Adapt to tuples. Update all
+ users.
+ * gimple-dummy.c (ssa_operands_active): Remove dummy function.
+ (remove_stmt_from_eh_region, create_phi_node, add_phi_arg,
+ substitute_in_loop_info, release_defs, push_stmt_changes,
+ pop_stmt_changes, replace_exp): Add dummy functions.
+ * predict.c: Disable.
+ * gimple-iterator.c: Include tm.h and tree-flow.h
+ (gsi_delink): Remove. Update all users.
+ (update_modified_stmt): Move from tree-cfg.c.
+ (gsi_insert_before): New.
+ (gsi_insert_seq_before): New.
+ (gsi_insert_after): New.
+ (gsi_insert_seq_after): New.
+ (gsi_for_stmt): New.
+ (gsi_move_after): New.
+ (gsi_move_before): New.
+ (gsi_move_to_bb_end): New.
+ * gimple-iterator.h (gsi_remove): New.
+ * tree-eh.c (add_stmt_to_eh_region_fn): Add comment
+ (add_stmt_to_eh_region): Likewise.
+ (remove_stmt_from_eh_region_fn): Likewise.
+ (remove_stmt_from_eh_region): Likewise.
+ (lookup_stmt_eh_region_fn): Likewise.
+ (lookup_stmt_eh_region): Likewise.
+ (tree_could_throw_p): Likewise.
+ (stmt_can_throw_internal): Likewise.
+ (tree_can_throw_external): Likewise.
+ * gimple-pretty-print.c (op_gimple_cond): Remove. Update all
+ users.
+ * tree-affine.c (tree_to_aff_combination_expand): Disable.
+ * tree-flow-inline.h (op_iter_init_vdef): Call gimple_code
+ instead of TREE_CODE.
+ * gimplify.c (gimplify_cond_expr): Use enum tree_code instead
+ of enum gimple_cond as the subcode for GIMPLE_COND.
+ Do not switch around the conditional when the then clause is empty.
+ (tree_to_gimple_tuple): Remove. Update all users.
+ (gimplify_omp_for):
+ (force_gimple_operand_gsi): Rename from force_gimple_operand_bsi. Update all users.
+ * tree-dfa.c (find_referenced_vars): Disable.
+ (collect_dfa_stats): Likewise.
+ (collect_dfa_stats_r): Likewise.
+ * cfgexpand.c: Disable.
+ * tree-mudflap.c: Disable.
+ * print-tree.c: Include diagnostic.h.
+ (print_node): Call print_gimple_stmt when printing SSA_NAMEs.
+ * lambda-code.c: Disable.
+ * tree-profile.c (tree_init_edge_profiler): Disable.
+ (tree_gen_edge_profiler): Disable.
+ * tree-flow.h (block_stmt_iterator): Remove. Update all users.
+ (const_block_stmt_iterator): Likewise.
+ * Makefile.in (print-tree.o): Add dependency on $(DIAGNOSTIC_H).
+ (gimple-iterator.o): Add dependency on $(TREE_FLOW_H) and
+ value-prof.h.
+ (gimple.o): Likewise.
+ (fold-const.o): Add dependency on $(GIMPLE_H).
+ * gimple.c: Include tm.h, hard-reg-set.h, basic-block.h,
+ tree-flow.h and value-prof.h.
+ (build_gimple_with_ops): Do not allocate operands if NUM_OPS == 0.
+ (build_gimple_return): Remove argument RESULT_DECL_P. Update
+ all users.
+ (build_gimple_cond): Use enum tree_code instead of enum
+ gimple_cond as the subcode. Update all users.
+ (gimple_cond_invert): Remove. Update all users.
+ (walk_gimple_seq): Add arguments CALLBACK_STMT and
+ CALLBACK_OP. Update all users.
+ (walk_gimple_asm): Likewise.
+ (walk_gimple_stmt): Likewise.
+ (gimple_remove): New.
+ (gimple_seq_reverse): New.
+ (set_gimple_bb): New.
+ * gimple.h (gimple_statement_base): Split field 'flags' into
+ fields 'subcode' and 'flags'. Update all users.
+ (gimple_statement_with_ops): Rename field 'base' to
+ 'gsbase'. Update all users.
+ (gimple_statement_omp): Likewise.
+ (gimple_statement_bind): Likewise.
+ (gimple_statement_catch): Likewise.
+ (gimple_statement_eh_filter): Likewise.
+ (gimple_statement_phi): Likewise.
+ (gimple_statement_resx): Likewise.
+ (gimple_statement_try): Likewise.
+ (gimple_statement_omp_parallel): Likewise.
+ (enum gimple_cond): Remove. Update all users.
+ (GIMPLE_NO_WARNING): Define.
+ (set_gimple_flags): Assert that FLAGS fits in 8 bits.
+ (add_gimple_flag): Likewise.
+ (set_gimple_subcode): New. Use instead of set_gimple_flags
+ everywhere.
+ (gimple_subcode): New. Use instead of gimple_flags
+ everywhere.
+ (gimple_no_warning_p): New.
+ (gimple_cond_set_code): New.
+ (gimple_cond_make_false): New.
+ (gimple_cond_make_true): New.
+ (gimple_phi_num_args): Rename from gimple_phi_nargs. Update
+ all users.
+ * tree-cfg.c (build_gimple_cfg): Return immediately.
+ (set_bb_for_stmt): Remove. Move functionality to
+ set_gimple_bb. Update all users.
+ (factor_computed_gotos):
+ (bsi_for_stmt): Remove.
+ (bsi_insert_before): Remove.
+ (bsi_insert_seq_before): Remove.
+ (bsi_insert_after): Remove.
+ (bsi_insert_seq_after): Remove.
+ (bsi_remove): Remove.
+ (bsi_move_after): Remove.
+ (bsi_move_before): Remove.
+ (bsi_move_to_bb_end): Remove.
+ (bsi_replace): Remove.
+ (tree_verify_flow_info): Adapt to tuples.
+ (tree_make_forwarder_block): Likewise.
+ (tree_try_redirect_by_replacing_jump): Likewise.
+ (tree_redirect_edge_and_branch): Likewise.
+ (tree_purge_dead_eh_edges): Likewise.
+ (gimple_cfg_hooks): Enable some hooks.
+ * tree-ssanames.c (make_ssa_name): Change type of STMT to
+ gimple. Update all users.
+ * tree-ssa-operands.c (ssa_operands_active): Enable.
+
+2007-08-31 Diego Novillo <dnovillo@google.com>
+
+ * tree-gimple.c (is_gimple_addressable): Tidy.
+ * Makefile.in (tree-ssa-structalias.o): Disable dependency on
+ GTY header file.
+ (tree-ssa-propagate.o): Likewise.
+ (tree-phinodes.o): Likewise.
+ (tree-scalar-evolution.o): Likewise.
+ (tree-vect-generic.o): Likewise.
+ * gimple.h (struct gimple_statement_phi): Change type of
+ fields 'capacity' and 'nargs' to size_t.
+ Update all users.
+ * tree-cfg.c (verify_gimple_unary_expr): Remove. Update all
+ users.
+ (verify_gimple_binary_expr): Remove. Update all users.
+ (verify_types_in_gimple_min_lval): Rename from
+ verify_gimple_min_lval.
+ (verify_types_in_gimple_reference): Rename from
+ verify_gimple_reference.
+ (verify_gimple_tree_expr): Remove.
+ Move checks to verify_types_in_gimple_assign.
+ (verify_types_in_gimple_call): Rename from verify_gimple_call.
+ (verify_types_in_gimple_cond): Rename from verify_gimple_cond.
+ (verify_types_in_gimple_assign): Rename from verify_gimple_assign.
+ (verify_types_in_gimple_switch): Rename from verify_gimple_switch.
+ (verify_types_in_gimple_phi): New.
+ verify_types_in_gimple_return): Rename from
+ verify_gimple_return.
+ (verify_types_in_gimple_stmt): Rename from verify_gimple_stmt.
+ (verify_types_in_gimple_seq): Rename from verify_gimple_seq.
+
+2007-08-30 Chris Matthews <chrismatthews@google.com>
+ Diego Novillo <dnovillo@google.com>
+
+ * gimplify.c (gimplify_body): Call verify_gimple_seq if
+ ENABLE_TYPES_CHECKING is set.
+ * gimple.h (is_gimple_omp): New.
+ * tree-cfg.c (verify_gimple_tree_expr): Rename from
+ verify_gimple_expr.
+ Verify tree nodes that should disappear after conversion to
+ GIMPLE.
+ Do not handle COND_EXPR, CALL_EXPR.
+ (verify_gimple_modify_stmt): Remove.
+ (verify_gimple_call): New.
+ (verify_gimple_cond): New.
+ (verify_gimple_assign): New.
+ (verify_gimple_return): New.
+ (verify_gimple_switch): New.
+ (verify_gimple_stmt): Change input argument to type gimple.
+ Call new verifiers.
+ (verify_gimple_seq): Rename from verify_gimple_1.
+
+2007-08-30 Diego Novillo <dnovillo@google.com>
+
+ * gimple-low.c (gimple_try_catch_may_fallthru): Call
+ gimple_code instead of gimple_flags.
+ * gimple.c (set_gimple_body): Use gimple_seq instead of gimple
+ when accessing vector gimple_bodies_vec.
+ (gimple_body): Likewise.
+ (gimple_assign_copy_p): New.
+ * gimple.h (enum gimple_try_kind): New.
+ (GIMPLE_TRY_CATCH): Move inside enum gimple_try_kind.
+ (GIMPLE_TRY_FINALLY): Likewise.
+ (gimple_assign_copy_p): Declare.
+ (gimple_assign_rhs_code): New.
+ Update callers that used to call gimple_flags.
+ (gimple_cond_code): New.
+ Update callers that used to call gimple_flags.
+ (gimple_try_kind): New.
+ (gimple_nop_p): Tidy comment.
+ * gimple-pretty-print.c (dump_unary_rhs): New.
+ (dump_gimple_assign): Call it.
+
+2007-08-30 Diego Novillo <dnovillo@google.com>
+
+ * gimplify.c (gimplify_cond_expr): When gimplifying a ?: call
+ gimplify_stmt with the expression just built instead of the
+ original expression.
+ Use the correct labels when calling build_gimple_cond.
+
+
+2007-08-30 Diego Novillo <dnovillo@google.com>
+
+ * tree-vrp.c: Disable.
+ * tree-loop-linear.c: Disable.
+ * tree-into-ssa.c: Disable.
+ * tree-ssa-loop-im.c: Disable.
+ * tree-complex.c: Disable.
+ * cgraphbuild.c: Disable most functions.
+ * tree-ssa-threadupdate.c: Disable.
+ * tree-ssa-loop-niter.c: Disable.
+ * tree-pretty-print.c: Disable.
+ * tree-ssa-loop-unswitch.c: Disable.
+ * tree-ssa-loop-manip.c: Disable.
+ * value-prof.c: Disable.
+ * tree-tailcall.c: Disable.
+ * tree-ssa-loop-ch.c: Disable.
+ * tree-scalar-evolution.c: Disable.
+ * tree-phinodes.c: Disable.
+ * omp-low.c: Disable.
+ * tree-ssa-dse.c: Disable.
+ * ipa-reference.c: Disable.
+ * tree-ssa-uncprop.c: Disable.
+ * tree-ssa-sccvn.c: Disable.
+ * cgraphunit.c (verify_cgraph_node): Disable basic block traversal.
+ * tree-ssa-copyrename.c: Disable.
+ * tree-ssa-ccp.c: Disable most functions.
+ * tree-ssa-loop-ivopts.c: Disable.
+ * tree-stdarg.c: Disable.
+ * tree-ssa-math-opts.c: Disable.
+ * tree-ssa-dom.c: Disable most functions.
+ * tree-nrv.c: Disable.
+ * tree-ssa-propagate.c: Disable.
+ * gimple-dummy.c: New file.
+ * tree-ssa-alias.c: Disable most functions.
+ * tree-ssa-sink.c: Disable.
+ * expr.c (expand_expr_real): Disable call to
+ lookup_stmt_eh_region.
+ * tree-ssa-loop-ivcanon.c: Disable.
+ * predict.c (strip_builtin_expect): Disable.
+ (tree_predict_by_opcode): Disable.
+ (return_prediction): Disable.
+ (apply_return_prediction): Disable.
+ (tree_bb_level_predictions): Disable.
+ (tree_estimate_probability): Disable.
+ (predict_paths_leading_to): Disable.
+ * gimple-iterator.c (gsi_replace): Mark unused arguments with
+ ATTRIBUTE_UNUSED.
+ * tree-ssa-ifcombine.c: Disable.
+ * matrix-reorg.c: Disable.
+ * c-decl.c (c_gimple_diagnostics_recursively): Disable call to
+ diagnose_omp_structured_block_errors.
+ * tree-eh.c: Disable most functions.
+ * tree-vectorizer.c: Disable.
+ * tree-vectorizer.h (nested_in_vect_loop_p): Disable.
+ * ipa-type-escape.c: Disable.
+ * tree-if-conv.c: Disable.
+ * profile.c: Disable.
+ * tree-data-ref.c: Disable.
+ * tree-flow-inline.h (bsi_start): Set bsi.gsi to NULL if the
+ block is invalid.
+ (bsi_last): Likewise.
+ (op_iter_next_use): Disable call to PHI_ARG_DEF_PTR.
+ * tree-vect-analyze.c: Disable.
+ * gimplify.c (gimple_conditional_context): Disable.
+ (gimple_push_cleanup): Disable.
+ (gimplify_omp_parallel): Disable calls to
+ push_gimplify_context and pop_gimplify_context.
+ * tree-ssa-phiopt.c: Disable.
+ * calls.c (emit_call_1): Disable calls to lookup_stmt_eh_region.
+ (expand_call): Likewise.
+ (emit_library_call_value_1): Initialize low_to_save and
+ high_to_save.
+ * tree-ssa-coalesce.c: Disable.
+ * tree-dfa.c (make_rename_temp): Disable call to
+ mark_sym_for_renaming.
+ (find_new_referenced_vars_1): Likewise.
+ (collect_dfa_stats): Disable CFG iteration.
+ (collect_dfa_stats_r): Disable.
+ (mark_symbols_for_renaming): Disable.
+ * cfgexpand.c (maybe_dump_rtl_for_tree_stmt): Disable.
+ (label_rtx_for_bb): Disable.
+ (expand_gimple_cond_expr): Disable.
+ (expand_gimple_tailcall): Disable.
+ (expand_gimple_basic_block): Disable.
+ * tree-cfgcleanup.c: Disable.
+ * tree-ssa-pre.c: Disable.
+ * tree-ssa-live.c: Disable.
+ * tree-sra.c: Disable most functions..
+ * tree-predcom.c: Disable.
+ * tree-mudflap.c: Disable.
+ * ipa-prop.c: Disable.
+ * tree-ssa-copy.c (may_propagate_copy): Disable.
+ (propagate_value): Disable.
+ (execute_copy_prop): Disable.
+ (do_copy_prop): Disable.
+ (store_copy_prop): Disable.
+ * tree-ssa-forwprop.c: Disable.
+ * tree-ssa-dce.c: Disable.
+ * tree-vect-patterns.c: Disable.
+ * tree-ssa-ter.c: Disable.
+ * tree-ssa.c: Disable.
+ * lambda-code.c: Disable.
+ * tree-ssa-loop-prefetch.c: Disable.
+ * tree-inline.c: Disable most functions.
+ * tree-optimize.c (execute_fixup_cfg_pre_ipa): Disable.
+ (execute_fixup_cfg): Disable.
+ (execute_cleanup_cfg_post_optimizing): Disable.
+ (execute_fixup_cfg): Disable.
+ * tree-vect-transform.c: Disable.
+ * tree-object-size.c: Disable.
+ * tree-outof-ssa.c: Disable.
+ * cfgloop.c (find_subloop_latch_edge_by_profile): Disable.
+ (find_subloop_latch_edge_by_ivs): Disable.
+ * tree-profile.c: Disable most functions.
+ * c-gimplify.c (add_block_to_enclosing): Disable.
+ * tree-vect-generic.c: Disable.
+ * tree-flow.h (struct function_ann_d): Disable field
+ reference_vars_info.
+ * Makefile.in: Force -Werror even during stage 1.
+ (OBJS-common): Add gimple-dummy.o.
+ (GTFILES): Remove tree-scalar-evolution.c,
+ tree-ssa-propagate.c, tree-vect-generic.c,
+ tree-ssa-structalias.h, tree-ssa-structalias.c,
+ ipa-reference.h, omp-low.c, tree-phinodes.c, ipa-reference.c
+ * tree-ssa-structalias.c: Disable.
+ * tree-cfg.c: Disable most functions.
+ * passes.c (finish_optimization_passes): Disable call to
+ end_branch_prob.
+ (init_optimization_passes): Disable the registration of
+ several passes.
+ (execute_function_todo): Disable calls to update_ssa and
+ need_ssa_update_p.
+ * tree-ssa-reassoc.c: Disable.
+ * tree-ssanames.c: Disable.
+ * tree-ssa-threadedge.c: Disable.
+ * tree-ssa-operands.c: Disable.
+
+2007-08-29 Aldy Hernandez <aldyh@redhat.com>
+
+ * tree-ssa-operands.h (pop_stmt_changes, push_stmt_changes):
+ Argument is gimple.
+ (struct ssa_operand_iterator_d): Member phi_stmt is gimple.
+ * value-prof.c (gimple_add_histogram_value): Adjust for tuples.
+ (gimple_duplicate_stmt_histograms): Same.
+ * value-prof.h (gimple_add_histogram_value): Same.
+ (gimple_duplicate_stmt_histograms): Same.
+ * tree-flow-inline.h (clear_and_done_ssa_iter): Same.
+ (op_iter_init): Same.
+ (op_iter_init_phiuse): Same.
+ * tree-flow.h (stmt_references_memory_p): Same.
+ * tree-cfg.c (tree_can_merge_blocks_p): Same.
+ (remove_bb): Same.
+ (find_taken_edge): Same.
+ (tree_cfg2vcg): Same.
+ (first_stmt): Same.
+ (last_stmt): Same.
+ (bsi_move_after): Same.
+ (bsi_move_before): Same.
+ (tree_find_edge_insert_loc): Same.
+ Remove code handling a GIMPLE_MODIFY_STMT inside a RETURN_EXPR.
+ (delete_tree_cfg_annotations): Remove code to remove annotations.
+ * tree-ssa-operands.c (struct scb_d): Stmt_p is a gimple *.
+ (push_stmt_changes): Adjust for tuples.
+ (mark_difference_for_renaming): Same.
+ (pop_stmt_changes): Same.
+ (stmt_references_memory_p): Same.
+
+2007-08-29 Aldy Hernandez <aldyh@redhat.com>
+
+ * tree-ssa-operands.h: Remove DEF_OPS, USE_OPS, VUSE_OPS,
+ VDEF_OPS, LOADED_SYMS, STORED_SYMS.
+ * tree-pretty-print.c (dump_generic_node): Adjust accordingly.
+ (dump_vops): use gimple_v*_ops. Adjust accordingly.
+ * gimple.def: Add to comment.
+ * tree-ssa-alias.c (create_structure_vars): Adjust for tuples.
+ * tree-flow-inline.h (op_iter_init): Make stmt gimple. Use
+ gimple_*_ops functions.
+ (op_iter_init_use): Make stmt gimple.
+ (op_iter_init_def): Same.
+ (op_iter_init_vdef): Same.
+ (single_ssa_tree_operand): Same.
+ (single_ssa_use_operand): Same.
+ (single_ssa_def_operand): Same.
+ (zero_ssa_operands): Same.
+ (num_ssa_operands): Same.
+ (compare_ssa_operands_equal): Make stmt[12] gimple.
+ (link_use_stmts_after): Adjust for tuples.
+ * tree-ssa-structalias.c (update_alias_info): Use
+ gimple_stored_syms and gimple_loaded_syms.
+ * gimple.h (gimple_has_mem_ops): New.
+ (gimple_def_ops): New.
+ (set_gimple_def_ops): New.
+ (gimple_use_ops): New.
+ (set_gimple_use_ops): New.
+ (gimple_vuse_ops): New.
+ (set_gimple_vuse_ops): New.
+ (gimple_vdef_ops): New.
+ (set_gimple_vdef_ops): New.
+ (gimple_loaded_syms): New.
+ (gimple_stored_syms): New.
+ * tree-ssa-operands.c (finalize_ssa_defs): Adjust for tuples.
+ (copy_virtual_operands): Same.
+ (swap_tree_operands): Same.
+
+2007-08-28 Aldy Hernandez <aldyh@redhat.com>
+
+ * Revert the parts of Kaveh's constification patch.that duplicate
+ API calls.
+
+2007-08-27 Diego Novillo <dnovillo@google.com>
+
+ Merge with mainline @127831.
+
+ * configure.ac (ACX_PKGVERSION): Update revision merge string.
+ * configure: Regenerate.
+
+2007-08-25 Diego Novillo <dnovillo@google.com>
+
+ * tree.c (build_gimple_modify_stmt_stat): Add depecrate note.
+ * omp-low.c (scan_omp_1): Disable.
+ (scan_omp): Likewise.
+ (lower_omp_for): Likewise.
+ (lower_omp_parallel): Likewise.
+ (lower_omp_1): Likewise.
+ (lower_omp): Likewise.
+ (diagnose_sb_1): Likewise.
+ (diagnose_sb_2): Likewise.
+ (diagnose_omp_structured_block_errors): Likewise.
+ * tree-gimple.h (_TREE_GIMPLE_H): Rename from _TREE_SIMPLE_H.
+ (gimplify_body): Return the new GIMPLE body.
+ (struct walk_stmt_info): Move to gimple.h.
+ * gimple-low.c (lower_function_body): Assert that the function
+ body is a single GIMPLE_BIND statement.
+ Create a new gimple sequence to lower the existing body.
+ Replace the function body with the new lowered sequence.
+ (pass_lower_cf): Enable GIMPLE lowering.
+ (lower_omp_directive): Disable.
+ (lower_stmt): Do not call lower_omp_directive.
+ (gimple_stmt_may_fallthru): Factor out of ...
+ (gimple_seq_may_fallthru): ... here.
+ * gimple-iterator.c (gsi_replace): New.
+ * gimple-iterator.h (gsi_replace): Declare.
+ * gimple-pretty-print.c: Do not include gimple-iterator.h
+ * gimplify.c (gimplify_asm_expr): Tidy.
+ Store the whole TREE_LIST node in the inputs and outputs vectors.
+ (gimple_push_cleanup): Disable completely.
+ (gimplify_body): Return a GIMPLE_BIND holding the gimplified
+ body.
+ Update all users.
+ (gimplify_function_tree): Create a GIMPLE sequence to hold
+ the gimplified body.
+ * tree-flow.h (gimple_stmt_may_fallthru): Declare.
+ * Makefile.in (GIMPLE_H): Add gimple-iterator.h.
+
+2007-08-25 Diego Novillo <dnovillo@google.com>
+
+ * tree-nested.c: Re-implement to use GIMPLE tuples.
+ (init_tmp_var_with_call): New.
+ (init_tmp_var): Adapt to GIMPLE tuples.
+ (save_tmp_var): Likewise.
+ (convert_nl_goto_receiver): Likewise.
+ (finalize_nesting_tree_1): Likewise.
+ (gsi_gimplify_val): Likewise.
+ Rename from tsi_gimplify_val. Update all users.
+ (walk_asm_expr): Remove.
+ (walk_stmts): Remove.
+ (walk_body): Call walk_gimple_seq.
+ Add new argument callback_op. Update all users.
+ (walk_function): Add argument callback_op. Update all users.
+ (convert_nonlocal_reference_op): Rename from
+ convert_nonlocal_omp_reference. Update all users.
+ (convert_nonlocal_reference_stmt): New. Handle GIMPLE
+ statements that used to be tree nodes.
+ (convert_local_reference_op): Rename from
+ convert_local_reference. Update all users.
+ (convert_local_reference_stmt): New. Handle GIMPLE statements
+ that used to be tree nodes.
+ (convert_nl_goto_reference): Convert to walk_stmt_fn callback.
+ Update all users.
+ (convert_tramp_reference_op): Rename from
+ convert_tramp_reference. Update all users.
+ (convert_tramp_reference_stmt): New. Handle GIMPLE statements
+ that used to be tree nodes.
+ (convert_gimple_call): Rename from convert_call_expr. Convert
+ to be a walk_stmt_fn callback.
+ * gimple.c (gimple_seq_add): Rename from gimple_add. Update
+ all users.
+ (walk_gimple_seq): Rename from walk_seq_ops. Update all
+ users.
+ (walk_gimple_stmt): Rename from walk_tuple_ops. Update all
+ users.
+ Use two callback functions one for statements and another for
+ operands. If either is NULL do not invoke it.
+ Allow callbacks to replace operands.
+ (WALKIT): Remove.
+ (walk_gimple_asm): New.
+ * gimple.h: Include ggc.h
+ (gimple_seq_alloc): New. Use everywhere a GIMPLE sequence is
+ allocated.
+ (gimple_op_ptr): New.
+ (gimple_call_arg_ptr): New.
+ (gimple_catch_types_ptr): New.
+ (gimple_eh_filter_types_ptr): New.
+ (gimple_omp_critical_name_ptr): New.
+ (gimple_omp_for_clauses_ptr): New.
+ (gimple_omp_for_index_ptr): New.
+ (gimple_omp_for_initial_ptr): New.
+ (gimple_omp_for_final_ptr): New.
+ (gimple_omp_for_incr_ptr): New.
+ (gimple_omp_parallel_clauses_ptr): New.
+ (gimple_omp_parallel_child_fn_ptr): New.
+ (gimple_omp_parallel_data_arg_ptr): New.
+ (gimple_omp_single_clauses_ptr): New.
+ (gimple_omp_sections_clauses_ptr): New.
+ (walk_stmt_fn): New type.
+ (struct walk_stmt_info): Move from tree-gimple.h.
+ Rename field callback to callback_op.
+ Add new field callback_stmt.
+ Replace field tsi with gsi of type gimple_stmt_iterator.
+ (walk_gimple_seq): Declare.
+ (walk_gimple_stmt): Declare.
+ * tree-cfg.c (execute_build_cfg): Do not call
+ build_gimple_cfg.
+ (pass_build_cfg): Enable.
+ Disable TODO_verify_stmts and TODO_cleanup_cfg.
+
+2007-08-22 Aldy Hernandez <aldyh@redhat.com>
+
+ * tree-phinodes.c (reserve_phi_args_for_new_edge): Comment out
+ call to phi_nodes_ptr.
+ (remove_phi_node): Same.
+ * tree-flow-inline.h (get_lineno): Work with empty statements or
+ empty locations.
+ (phi_nodes_ptr): Remove.
+ (phi_arg_index_from_use): Adjust for tuples.
+ (bsi_stmt_ptr): Add ATTRIBUTE_UNUSED.
+ (op_iter_init): Remove assertion.
+ (next_imm_use_stmt): Change NULL_TREE to NULL.
+ * tree-dfa.c (mark_symbols_for_renaming): Adjust for tuples.
+ * tree-flow.h: Remove bb_for_stmt prototype.
+ (mark_symbols_for_renaming): Make argument gimple.
+
+2007-08-22 Aldy Hernandez <aldyh@redhat.com>
+
+ Change all instances of bb_for_stmt to gimple_bb throughout.
+
+ * gimple.h (gimple_omp_parallel_combined_p): New.
+ * tree-ssa-operands.h (update_stmt_operands): Argument is now
+ gimple.
+ * tree-ssa-threadupdate.c (rederiction_block_p): Use gimple_nop_p
+ instead of IS_EMPTY_STMT.
+ * tree-ssa-loop-niter.c: Disable use of COND_EXPR_COND.
+ * tree-pretty-print.c (dump_bb_header): Adjust for tuples.
+ * cgraph.c (cgraph_add_new_function): Rename
+ tree_register_cfg_hooks to gimple_register_cfg_hooks.
+ * value-prof.c (set_histogram_value): Stmt type is now gimple.
+ (gimple_histogram_value): Same.
+ (gimple_remove_histogram_value): Same.
+ (gimple_remove_stmt_histograms): Same.
+ * tree.h (struct ssa_use_operand_d): Same.
+ * value-prof.h (struct histogram_value_t): Same.
+ Change gimple_*histogram* prototypes to use gimple instead of
+ tree.
+ * ipa-cp.c (ipcp_insert_stage): Rename tree_register_cfg_hooks to
+ gimple_register_cfg_hooks.
+ * cfghooks.c (gimple_register_cfg_hooks): Rename from
+ tree_register_cfg_hooks. Initialize cfg_hooks to gimple_cfg_hooks.
+ (current_ir_type): Rename tree_cfg_hooks to gimple_cfg_hooks.
+ * input.h (IS_LOCATION_EMPTY): New.
+ * cfghooks.h: Rename tree_cfg_hooks to gimple_cfg_hooks. Rename
+ tree_register_cfg_hooks to gimple_register_cfg_hooks.
+ * omp-low.c (determine_parallel_type): Adjust for tuples.
+ (expand_omp_parallel): Rename bb_stmt_list to bb_seq.
+ (expand_omp_for_generic): Call gimple_omp_return_nowait_p.
+ (expand_omp_for_static_nochunk): Same.
+ (expand_omp_sections): Call gimple_omp_section_last_p.
+ (expand_omp_single): Comment out call to find_omp_clause.
+ Call gimple_omp_return_nowait_p.
+ * cgraphunit.c: Rename tree_register_cfg_hooks to
+ gimple_register_cfg_hooks.
+ * tree-ssa-propagate.c: Comment out non working code.
+ * matrix-reorg.c (matrix_reorg): Rename tree_register_cfg_hooks to
+ gimple_register_cfg_hooks.
+ * tree-eh.c (add_stmt_to_eh_region_fn): Change `t' type to gimple.
+ Adjust accordingly.
+ (add_stmt_to_eh_region): Same.
+ (remove_stmt_from_eh_region_fn): Same.
+ (remove_stmt_from_eh_region): Same.
+ (lookup_stmt_eh_region_fn): Same.
+ (lookup_stmt_eh_region): Same.
+ (make_eh_edges): Adjust for tuples.
+ (stmt_can_throw_internal): Rename from tree_can_throw_internal.
+ Adjust for tuples.
+ (maybe_clean_or_replace_eh_stmt): Arg types are now gimple.
+ * tree-vectorizer.c: Rename tree_register_cfg_hooks to
+ gimple_register_cfg_hooks.
+ * tree-if-conv.c (combine_blocks): Adjust for tuples.
+ * profile.c (branch_prob): Same.
+ * tree-flow-inline.h (bb_for_stmt): Remove.
+ (get_lineno): Adjust for tuples.
+ (noreturn_call_p): Same.
+ (mark_stmt_modified): Same.
+ (update_stmt): Same.
+ (update_stmt_if_modified): Same.
+ (stmt_modified_p): Same.
+ (link_imm_use_stmt): Same.
+ (relink_imm_use_stmt): Same.
+ (single_imm_use): Same.
+ (gimple_phi_arg_def): New.
+ (gimple_phi_arg_edge): New.
+ (phi_nodes): Adjust for tuples.
+ (phi_nodes_ptr): Same.
+ (set_phi_nodes): Same.
+ (bb_seq): Rename from bb_stmt_list and adjust for tuples.
+ (set_bb_seq): Rename from set_bb_stmt_list and adjust for tuples.
+ (bsi_start): Adjust for tuples.
+ (bsi_after_labels): Adjust for tuples.
+ (bsi_last): Same.
+ (bsi_next): Same.
+ (bsi_prev): Same.
+ (bsi_stmt): Same.
+ (bsi_stmt_ptr): Same.
+ (loop_containing_stmt): Same.
+ (delink_stmt_imm_use): Same.
+ (first_imm_use_stmt): Same.
+ (next_imm_use_stmt): Same.
+ * gimplify.c (force_gimple_operand_bsi): Same.
+ * coretypes.h (const_gimple): New.
+ * tree-ssa-phiopt.c (empty_block_p): Call gimple_nop_p.
+ (conditional_replacement): Comment out COND_EXPR_COND.
+ (value_replacement): Comment out COND_EXPR_COND.
+ (minmax_replacement): Same.
+ (abs_replacement): Same.
+ * except.h (*eh_region*): Change trees to gimple.
+ (struct throw_stmt_node): Change stmt type to gimple.
+ * cfgexpand.c (label_rtx_for_bb): Adjust for tuples.
+ (expand_gimple_cond_expr): Same.
+ (expand_gimple_basic_block): Same.
+ * tree-cfgcleanup.c (split_bbs_on_noreturn_calls): Same.
+ * tree-ssa-pre.c (realify_fake_stores): Comment out non working
+ code.
+ * tree-ssa-forwprop.c (propagate_with_phi): Rename
+ tree_can_throw_internal stmt_can_throw_internal.
+ * tree-inline.c (copy_edges_for_bb): Rename
+ tree_can_throw_internal to stmt_can_throw_internal.
+ (initialize_cfun): Same.
+ (copy_cfg_body): Same.
+ (gimple_expand_calls_inline): Same.
+ (make_nonlocal_label_edges): Rename tree_can_make_abnormal_goto to
+ stmt_can_make_abnormal_goto.
+ * tree-optimize.c (tree_lowering_passes): Rename
+ tree_register_cfg_hooks to gimple_register_cfg_hooks.
+ (tree_rest_of_compilation): Same.
+ * tree-flow.h (struct gimple_df): Make modified_noreturn_calls a
+ vector of gimple types.
+ Adjust prototypes for tuples.
+ (struct block_stmt_iterator): Make iterator a gimple iterator.
+ (enum bsi_iterator_update): Remove BSI_CHAIN_START and
+ BSI_CHAIN_END.
+ * Makefile.in (tree-cfg.o): Depend on GIMPLE_H.
+ (GTFILES): Move gimple.[hc] entries before tree-flow.h.
+ * basic-block.h (struct edge_def): Make goto_locus of type
+ location_t.
+ (union basic_block_il_dependent): Adjust for tuples.
+ (gimple_bb_info): Rename from tree_bb_info. Adjust for tuples.
+ * tree-cfg.c: Include gimple.h.
+ Adjust prototypes for tuples.
+ (build_gimple_cfg): Rename from build_tree_cfg. Adjust for
+ tuples.
+ (execute_build_cfg): Rename build_tree_cfg call to
+ build_gimple_cfg.
+ (factor_computed_gotos): Adjust for tuples.
+ (make_blocks): Same.
+ (create_bb): Same.
+ (fold_cond_expr_cond): Same.
+ (make_edges): Same.
+ (make_cond_expr_edges): Same.
+ (make_switch_expr_edges): Same.
+ (make_goto_expr_edges): Same.
+ (cleanup_dead_labels): Same.
+ (group_case_labels): Same.
+ (tree_can_merge_blocks_p): Same.
+ (replace_uses_by): Same.
+ (tree_merge_blocks): Same.
+ (is_ctrl): Same.
+ (is_ctrl_altering_stmt): Same.
+ (computed_goto_p): Same.
+ (simple_goto_p): Same.
+ (stmt_can_make_abnormal_goto): Rename from
+ tree_can_make_abnormal_goto.
+ Adjust for tuples.
+ (stmt_starts_bb_p): Adjust for tuples.
+ (stmt_ends_bb_p): Same.
+ (first_stmt): Same.
+ (last_stmt): Same.
+ (last_and_only_stmt): Same.
+ (set_bb_for_stmt): Same.
+ (change_bb_for_stmt): Same.
+ (bsi_for_stmt): Same.
+ (update_modified_stmt): Rename from update_modified_stmts.
+ Adjust for tuples.
+ Handle only one statement.
+ (bsi_insert_before): Adjust for tuples.
+ (bsi_insert_after): Same.
+ (bsi_insert_seq_before): New.
+ (bsi_insert_seq_after): New.
+ (bsi_remove): Ajust for tuples.
+ (bsi_replace): Same.
+ (verify_stmt): Same.
+ (gimple_split_block): Rename from tree_split_block.
+ Adjust for tuples.
+ (tree_purge_dead_abnormal_call_edges): Adjust for tuples.
+ (tree_cfg_hooks): Same.
+ * tree-ssa-operands.c (update_stmt_operands): Same.
+
+2007-08-22 Aldy Hernandez <aldyh@redhat.com>
+
+ * Makefile.in (TREE_GIMPLE_H): Depend on GIMPLE_H.
+ * gimple-iterator.h: Do not include gimple.h.
+ * gimple.h (OMP_SECTION_LAST_FLAG): New.
+ (gimple_omp_return_nowait_p): New.
+ (gimple_omp_section_last_p): New.
+ (gimple_switch_set_num_labels): New.
+ (gimple_nop_p): New.
+
+2007-08-17 Aldy Hernandez <aldyh@redhat.com>
+
+ Revert this change:
+
+ 2007-08-14 Aldy Hernandez <aldyh@redhat.com>
+
+ * gimple.c (gimple_call_flags): Make sure this is a GIMPLE_CALL.
+
+2007-08-14 Aldy Hernandez <aldyh@redhat.com>
+
+ * gimple-iterator.c (gsi_split_seq_after): New.
+ (gsi_split_seq_before): New.
+ * gimple-iterator.h: Prototype above two functions.
+
+2007-08-14 Aldy Hernandez <aldyh@redhat.com>
+
+ * gimple.h (gimple_has_ops): New.
+ (gimple_modified): New.
+ (set_gimple_modified): New.
+ (gimple_switch_default_label): Call gimple_switch_label.
+ (gimple_switch_set_default_label): Call gimple_switch_set_label.
+
+2007-08-14 Aldy Hernandez <aldyh@redhat.com>
+
+ * gimple.c (gimple_call_flags): Make sure this is a GIMPLE_CALL.
+
+2007-08-14 Diego Novillo <dnovillo@google.com>
+
+ Merge with mainline @127480.
+
+ * version.c (VERSUFFIX): Update.
+
+2007-08-09 Diego Novillo <dnovillo@google.com>
+
+ * gimple-low.c: Document conversion to Low GIMPLE.
+ * Makefile.in (gimple.o): Add dependency on gt-gimple.h
+ (GTFILES): Add gimple.c.
+ * gimple.c (gimple_bodies_vec): New.
+ (gimple_bodies_map): Rename from gimple_bodies.
+ (gss_for_code): Return GSS_ASM for GIMPLE_ASM.
+ (walk_tuple_ops): Handle GSS_ASM like GSS_WITH_OPS.
+ (set_gimple_body): Push body into gimple_bodies_vec and create
+ a mapping to array index in gimple_bodies_map.
+ (gimple_body): Corresponding changes to use gimple_bodies_map
+ and gimple_bodies_vec.
+ * gimple.h: Create VEC templates for gimple_seq.
+
+2007-08-08 Aldy Hernandez <aldy@quesejoda.com>
+
+ * gimple-low.c (struct return_statements_t): Declare.
+ (struct lower_data): Make return_statements a vector.
+ (lower_function_body): Adjust for tuples.
+ (pass_lower_cf): Add PROP_gimple_any to properties_required.
+ (lower_sequence): Rename from lower_stmt_body.
+ Adjust for tuples.
+ (lower_omp_directive): Adjust for tuples.
+ (lower_stmt): Same.
+ (lower_gimple_bind): Rename from lower_bind_expr.
+ Adjust for tuples.
+ (gimple_try_catch_may_fallthru): New.
+ (gimple_seq_may_fallthru): New.
+ (lower_gimple_return): Rename from lower_return_expr and adjust
+ for tuples.
+ (lower_builtin_setjmp): Adjust for tuples.
+ * gimple-iterator.c: New.
+ * gimple-iterator.h: Include gimple.h.
+ (enum gsi_iterator_update): Declare.
+ (gsi_link_seq_before): New prototype.
+ (gsi_link_before): Same.
+ (gsi_link_seq_after): Same.
+ (gsi_link_after): Same.
+ (gsi_delink): Same.
+ * gimplify.c (gimplify_body): Comment out verify_gimple_1 call.
+ * tree-flow.h (gimple_seq_may_fallthru): New prototype.
+ * Makefile.in (OBJS-common): Add gimple-iterator.o.
+ (gimple-iterator.o): New.
+ (gimple-pretty-print.o): Do not depend on gimple-iterator.h.
+ * gimple.c (set_gimple_prev): Move to gimple.h.
+ (set_gimple_next): Same.
+ (gimple_call_flags): New.
+ * gimple.h (struct gimple_sequence): Add GTY marker.
+ (struct gimple_statement_bind): Add block field.
+ (set_gimple_prev): New.
+ (set_gimple_next): New.
+ (gimple_call_flags): Protoize.
+ (gimple_call_fndecl): New.
+ (gimple_bind_block): New.
+ (gimple_bind_set_block): New.
+
+
+2007-08-08 Diego Novillo <dnovillo@google.com>
+
+ * gimple.h (GIMPLE_CHECK, GIMPLE_CHECK2, GIMPLE_RANGE_CHECK):
+ Do not return the checked statement. Update all users.
+ Enable on compilers other than GCC.
+
+2007-08-07 Chris Matthews <chrismatthews@google.com>
+
+ * gimple_iterator.h (gsi_start): Changed to produce a pointer instead of
+ struct. Updated clients.
+ (gsi_last): Same.
+ (gsi_end_p): Changed to operate on a pointer instead of struct. Updated
+ clients.
+ (gsi_one_before_end_p): Same.
+ (gsi_next): Same.
+ (gsi_prev): Same.
+ (gsi_stmt): Same.
+
+2007-08-07 Diego Novillo <dnovillo@google.com>
+
+ Merge with mainline @127277.
+
+ * version.c (VERSUFFIX): Update.
+
+2007-08-07 Diego Novillo <dnovillo@google.com>
+
+ * gimple.h (gimple_call_return): New.
+ * gimplify.c (get_tmp_var_for): Call it.
+
+2007-08-02 Chris Matthews <chrismatthews@google.com>
+
+ * gimplify.c (gimplify_asm_expr): Created new gimple tuple.
+ * gimple-pretty-printer.c (dump_gimple_asm): Added function to dump a
+ GIMPLE_ASM statement.
+ (dump_gimple_stmt): Updated to use the dump_gimple_asm function.
+ * gimple.c (gss_for_code): Made asm statements return as with_mem_ops.
+ (build_gimple_with_ops): Asm statements are added as a specal case for
+ allocation because they have extra fields that are not
+ allocated correctly in the current generic op allocator.
+ (build_gimple_asm_1): Added a helper function to setup the basics of a
+ GIMPLE_ASM tuple.
+ (build_gimple_asm_vec): Create a GIMPLE_ASM tuple from vector arguments.
+ (build_gimple_asm): Changed to call the new helper function.
+
+2007-08-03 Diego Novillo <dnovillo@google.com>
+
+ * gimple-pretty-print.c (INDENT): Tidy.
+ (dump_binary_rhs): New.
+ (dump_gimple_assign): Call it.
+ * gimplify.c (gimplify_modify_expr_complex_part): If the value
+ is not interesting, nullify *EXPR_P.
+ (gimplify_body): Do not add the sequence to the GIMPLE_BIND more
+ than once.
+
+2007-08-01 Diego Novillo <dnovillo@google.com>
+
+ * gimplify.c (gimplify_switch_expr): Remove switch_body_seq_.
+ Change switch_body_seq to struct gimple_sequence.
+ Adjust all uses.
+ Call gimplify_stmt instead of gimplify_statement_list
+ (gimplify_to_stmt_list): Remove.
+ Update all users.
+ * tree-mudflap.c: Include gimple.h
+ (mf_decl_cache_locals): Convert to emit GIMPLE.
+ (mf_build_check_statement_for): Add FIXME and unreachable
+ markers to convert to GIMPLE.
+ * Makefile.in (tree-mudflap.o): Depend on $(GIMPLE_H).
+ * config/i386/i386.c (ix86_gimplify_va_arg): Adapt to emit
+ GIMPLE.
+
+2007-08-01 Diego Novillo <dnovillo@google.com>
+
+ * gimplify.c (gimplify_switch_expr): Do not call sort_case_labels
+ if there are no labels other than 'default'.
+ * gimple.h (gimple_num_ops, gimple_op, gimple_set_op): Use
+ result of GIMPLE_RANGE_CHECK call.
+
+2007-08-01 Diego Novillo <dnovillo@google.com>
+
+ * DEV-PHASE: Revert to mainline version.
+ * version.c (VERSUFFIX): Add branch name and revision number
+ of latest mainline merge.
+
+2007-07-31 Diego Novillo <dnovillo@google.com>
+
+ Mainline merge (@127100).
+ * DEV-PHASE: Updated.
+
+2007-07-31 Diego Novillo <dnovillo@google.com>
+
+ * dominance.c (free_dominance_info): If there is no CFG,
+ do nothing.
+ * cfg.c (compact_blocks): Likewise.
+
+2007-07-30 Diego Novillo <dnovillo@google.com>
+
+ * gimplify.c (get_tmp_var_for): When creating a new temporary
+ for a GIMPLE_CALL, use the type returned by the function call
+ instead of the type of the function decl.
+ * gimple.c (build_gimple_return): Accept NULL and RESULT_DECL
+ return values.
+
+2007-07-30 Diego Novillo <dnovillo@google.com>
+
+ * gimplify.c (gimplify_init_constructor): If both sides
+ of the constructor are in GIMPLE form but the assignment
+ has not been emitted, emit it.
+
+2007-07-28 Diego Novillo <dnovillo@google.com>
+
+ * gimplify.c (gimplify_return_expr): Do not create a MODIFY_EXPR
+ as return argument
+ * gimple.c (build_gimple_return): Assert that the returned value
+ is a GIMPLE value.
+
+2007-07-27 Diego Novillo <dnovillo@google.com>
+
+ * tree-gimple.c (get_gimple_rhs_class): New.
+ (is_gimple_formal_tmp_rhs): Call it.
+ * tree-gimple.h (enum gimple_rhs_class): New.
+ * gimple-iterator.h (gsi_next): Assert that there is nothing
+ beyond the end of the sequence.
+ (gsi_prev): Assert that there is nothing before the start of
+ the sequence.
+ * gimplify.c (gimplify_switch_expr): Tidy creation of default label.
+ (gimplify_expr): Fix concatenation of internal sequences to PRE_P.
+ * gimple.c (get_num_ops_for): Remove. Update users.
+ (build_gimple_assign): Call get_gimple_rhs_class to determine
+ how many operands to allocate.
+ (gimple_add): Assert that GS does not have previous or next
+ statements.
+ (gimple_seq_append): Move from gimple.h.
+
+2007-07-27 Aldy Hernandez <aldy@quesejoda.com>
+
+ * cgraph.c: Fix line wrap.
+ * cgraph.h: Same.
+ * tree-pass.h (struct tree_opt_pass): Add works_with_tuples_p
+ field.
+ * cgraphunit.c (cgraph_analyze_functions): Remove check for
+ DECL_SAVED_TREE.
+ (cgraph_expand_function): Comment out TREE_ASM_WRITTEN assertion.
+ * tree-optimize.c (tree_lowering_passes): Comment out call to
+ compact_blocks.
+ * passes.c (execute_one_pass): Return if pass has not been
+ converted to tuples.
+ * tree-vrp.c, regrename.c, fwprop.c, tree-into-ssa.c,
+ tree-complex.c, see.c, cgraphbuild.c, tracer.c, cgraph.c,
+ postreload-gcse.c, postreload.c, tree-ssa-loop-ch.c,
+ tree-tailcall.c, tree-pass.h, ipa-cp.c, final.c, omp-low.c,
+ tree-ssa-dse.c, ipa-reference.c, tree-ssa-uncprop.c,
+ auto-inc-dec.c, reorg.c, tree-ssa-copyrename.c, tree-ssa-ccp.c,
+ df-core.c, mode-switching.c, tree-nomudflap.c, modulo-sched.c,
+ ipa-pure-const.c, cse.c, web.c, tree-stdarg.c,
+ tree-ssa-math-opts.c, tree-ssa-dom.c, tree-nrv.c,
+ tree-ssa-alias.c, loop-init.c, gimple-low.c, tree-ssa-sink.c,
+ ipa-inline.c, global.c, jump.c, ifcvt.c, predict.c,
+ tree-ssa-loop.c, recog.c, dse.c, tree-ssa-ifcombine.c,
+ matrix-reorg.c, c-decl.c, tree-eh.c, regmove.c, local-alloc.c,
+ function.c, tree-vectorizer.c, gcse.c, ipa-type-escape.c,
+ tree-if-conv.c, init-regs.c, ipa.c, tree-ssa-phiopt.c,
+ rtl-factoring.c, lower-subreg.c, bt-load.c, tree-dfa.c except.c,
+ emit-rtl.c, cfgexpand.c, tree-cfgcleanup.c, cfgcleanup.c,
+ tree-ssa-pre.c, tree-sra.c, tree-mudflap.c, tree-ssa-copy.c,
+ cfglayout.c, tree-ssa-forwprop.c, tree-ssa-dce.c, tree-ssa.c,
+ regclass.c, integrate.c, tree-optimize.c, tree-object-size.c,
+ combine.c, tree-outof-ssa.c, bb-reorder.c, stack-ptr-mod.c,
+ var-tracking.c, tree-profile.c, tree-vect-generic.c, reg-stack.c,
+ sched-rgn.c, tree-ssa-structalias.c, tree-cfg.c, passes.c,
+ tree-ssa-reassoc.c, combine-stack-adj.c, cfgrtl.c, dce.c,
+ tree-ssanames.c: Set works_with_tuples_p field to 0.
+
+2007-07-25 Diego Novillo <dnovillo@google.com>
+
+ * gimple.c: Use ENABLE_GIMPLE_CHECKING instead of
+ ENABLE_TREE_CHECKING.
+ (set_gimple_code): New.
+ (set_gimple_prev): New.
+ (set_gimple_next): New.
+ * gimple.h: Use ENABLE_GIMPLE_CHECKING instead of
+ ENABLE_TREE_CHECKING.
+ (gimple_code): Inline function replacement for GIMPLE_CODE.
+ (gimple_flags): Inline function replacement for GIMPLE_SUBCODE_FLAGS.
+ (gimple_next): Inline function replacement for GIMPLE_NEXT.
+ (gimple_prev): Inline function replacement for GIMPLE_PREV.
+ (gimple_locus): Inline function replacement for GIMPLE_LOCUS.
+ (gimple_locus_empty_p): Inline function replacement for
+ GIMPLE_LOCUS_EMPTY_P.
+ (struct gimple_statement_base): Rename field 'subcode_flags'
+ to 'flags'.
+ (set_gimple_flags): New.
+ (gimple_bb): New.
+ (set_gimple_bb): New.
+ (set_gimple_block): New.
+ (set_gimple_locus): New.
+ (add_gimple_flag): Rename from gimple_add_subcode_flag.
+
+2007-07-25 Diego Novillo <dnovillo@google.com>
+
+ * tree-gimple.h (build_gimple_eh_filter_tree): Rename from
+ gimple_build_eh_filter_tree.
+ * gimple.h (build_gimple_return): Rename from gimple_build_return.
+ (build_gimple_assign): Rename from gimple_build_assign.
+ (build_gimple_call_vec): Rename from gimple_build_call_vec.
+ (build_gimple_call): Rename from gimple_build_call.
+ (build_gimple_label): Rename from gimple_build_label.
+ (build_gimple_goto): Rename from gimple_build_goto.
+ (build_gimple_nop): Rename from gimple_build_nop.
+ (build_gimple_bind): Rename from gimple_build_bind.
+ (build_gimple_asm): Rename from gimple_build_asm.
+ (build_gimple_catch): Rename from gimple_build_catch.
+ (build_gimple_eh_filter): Rename from gimple_build_eh_filter.
+ (build_gimple_try): Rename from gimple_build_try.
+ (build_gimple_phi): Rename from gimple_build_phi.
+ (build_gimple_resx): Rename from gimple_build_resx.
+ (build_gimple_switch): Rename from gimple_build_switch.
+ (build_gimple_switch_vec): Rename from gimple_build_switch_vec.
+ (build_gimple_omp_parallel): Rename from gimple_build_omp_parallel.
+ (build_gimple_omp_for): Rename from gimple_build_omp_for.
+ (build_gimple_omp_critical): Rename from gimple_build_omp_critical.
+ (build_gimple_omp_section): Rename from gimple_build_omp_section.
+ (build_gimple_omp_continue): Rename from gimple_build_omp_continue.
+ (build_gimple_omp_master): Rename from gimple_build_omp_master.
+ (build_gimple_omp_return): Rename from gimple_build_omp_return.
+ (build_gimple_omp_ordered): Rename from gimple_build_omp_ordered.
+ (build_gimple_omp_sections): Rename from gimple_build_omp_sections.
+ (build_gimple_omp_single): Rename from gimple_build_omp_single.
+ Update all users.
+
+2007-07-24 Chris Matthews <chrismatthews@google.com>
+
+ * configure.ac: Added support for ENABLE_GIMPLE_CHECKING and the
+ --enable-checking=gimple flag.
+ * config.in: Same.
+ * configure: Regenerated.
+ * gimplify.c (cpt_same_type): Same.
+ (gimple_push_condition): Same.
+ (gimplify_addr_expr): Same.
+ (gimplify_expr): Same.
+ (gimplify_body): Same.
+ (check_pointer_types_r): Same.
+
+2007-07-24 Diego Novillo <dnovillo@google.com>
+
+ * gimple.def: Re-organize codes that take tree operands so
+ they are consecutive.
+ * gsstruct.def (GSS_LABEL, GSS_ASSIGN_BINARY, GSS_ASSIGN_UNARY_REG,
+ GSS_ASSIGN_UNARY_MEM, GSS_COND, GSS_GOTO, GSS_SWITCH, GSS_CALL,
+ GSS_RETURN): Remove. Update al users.
+ * gimple.c (gss_for_code): New.
+ (gimple_statement_structure): Call it.
+ (get_num_ops_for): New.
+ (gimple_build_with_ops): New.
+ (gimple_build_return, gimple_build_call_1, gimple_build_assign,
+ gimple_build_cond, gimple_build_label, gimple_build_goto,
+ gimple_build_switch_1, ): Call it.
+ (gss_for_assign): Remove. Update all users.
+ (gimple_check_failed): Do not assume that subcode is a valid tree
+ code.
+ (gimple_range_check_failed): New.
+ (walk_tuple_ops): Implement in terms of gimple_num_ops and
+ gimple_op when dealing with GSS_WITH_OPS and GSS_WITH_MEM_OPS
+ statements.
+ * gimple.h (struct gimple_statement_with_ops): Add fields 'num_ops'
+ and 'op'.
+ (struct gimple_statement_label, gimple_statement_assign_binary,
+ gimple_statement_assign_unary_reg, gimple_statement_assign_unary_mem,
+ gimple_statement_cond, gimple_statement_goto, gimple_statement_switch,
+ gimple_statement_call, gimple_statement_return): Remove.
+ Update all users.
+ (gimple_range_check_failed): Declare.
+ (GIMPLE_RANGE_CHECK): Define.
+ (gimple_num_ops): New.
+ (gimple_op): New.
+ (gimple_set_op): New.
+ (gimple_assign_rhs1): Rename from gimple_assign_binary_rhs1.
+ (gimple_assign_set_rhs1): Rename from gimple_assign_binary_set_rhs1.
+ (gimple_assign_rhs2): Rename from gimple_assign_binary_rhs2.
+ (gimple_assign_set_rhs2): Rename from gimple_assign_binary_set_rhs2.
+ (gimple_assign_unary_rhs): Remove. Update all users.
+ (gimple_assign_unary_set_rhs): Likewise.
+ (gimple_switch_num_labels): Rename from gimple_switch_nlabels.
+ (gimple_call_fn, gimple_call_lhs, gimple_call_chain,
+ gimple_call_set_chain, gimple_call_nargs, gimple_call_arg,
+ gimple_call_set_arg, gimple_cond_lhs, gimple_cond_set_lhs,
+ gimple_cond_rhs, gimple_cond_set_rhs, gimple_cond_true_label,
+ gimple_cond_false_label, gimple_cond_set_true_label,
+ gimple_cond_set_false_label, gimple_label_label,
+ gimple_label_set_label, gimple_goto_dest,
+ gimple_goto_set_dest, gimple_asm_input_op,
+ gimple_asm_set_input_op, gimple_asm_output_op,
+ gimple_asm_set_output_op, gimple_asm_clobber_op,
+ gimple_asm_set_clobber_op, gimple_switch_num_labels,
+ gimple_switch_index, gimple_switch_set_index,
+ gimple_switch_default_label, gimple_switch_set_default_label,
+ gimple_switch_label, gimple_switch_set_label,
+ gimple_return_retval, gimple_return_set_retval): Implement
+ using the array of operands in field 'with_ops'.
+ (gimple_asm_set_ninputs, gimple_asm_set_noutputs,
+ gimple_asm_set_nclobbered, gimple_asm_set_string): Remove.
+ Update all users.
+
+
+2007-07-24 Aldy Hernandez <aldyh@redhat.com>
+
+ * tree.c (get_callee_fndecl): Revert previous change.
+ * gimplify.c (gimplify_call_expr): Use result from
+ get_callee_fndecl if available.
+ * c-common.c (c_warn_unused_result): Do not use
+ get_callee_fndecl.
+ Add assertion.
+
+2007-07-24 Diego Novillo <dnovillo@google.com>
+
+ Merge with mainline (@126872)
+
+2007-07-23 Aldy Hernandez <aldyh@redhat.com>
+
+ * tree.c (get_callee_fndecl): Work when only the CALL_EXPR_FN has
+ been passed.
+ * c-common.c (c_warn_unused_result): Use get_callee_fndecl.
+
+2007-07-23 Aldy Hernandez <aldyh@redhat.com>
+
+ * c-decl.c: Include gimple.h.
+ (c_gimple_diagnostics_recursively): Call c_warn_unused_result with
+ tuplified body.
+ Exit if -fgimple-only.
+ * gimplify.c (gimplify_call_expr): Call gimple_build_call_vec with
+ the correct callee.
+ * c-gimplify.c (c_genericize): Remove exit.
+ * c-common.c: Include gimple.h.
+ (c_warn_unused_result): Tuplify.
+ * c-common.h (c_warn_unused_result): Protoize.
+ * Makefile.in (c-decl.o): Depend on GIMPLE_H.
+ (c-common.o): Same.
+ * gimple.c (gimple_build_catch): Handler is a sequence.
+ Adjust accordingly.
+ (gimple_build_eh_filter): Failure is a sequence.
+ Adjust accordingly.
+ (walk_tuple_ops): case GIMPLE_CATCH: Walk handler as a sequence.
+ case GIMPLE_EH_FILTER: Walkder failure as a sequence.
+ * gimple.h (gimple_statement_catch): Make handler a sequence.
+ (gimple_statement_eh_filter): Make failure a sequence.
+ (gimple_build_catch): Make second argument a sequence.
+ (gimple_build_eh_filter): Same.
+ (gimple_catch_handler): Return a sequence.
+ (gimple_catch_set_handler): Make second argument a sequence.
+ (gimple_eh_filter_failure): Return a sequence.
+ (gimple_eh_filter_set_failture): Make second argument a sequence.
+
+2007-07-20 Aldy Hernandez <aldyh@redhat.com>
+
+ * gimplify.c (gimplify_return_expr): Handle an empty ret_expr
+ gracefully.
+
+2007-07-19 Aldy Hernandez <aldyh@redhat.com>
+
+ * testsuite/gcc.dg/gimple/instrument.c: New.
+ * gimplify.c (gimplify_function_tree): Generate tuples for function
+ instrumentation.
+
+2007-07-18 Aldy Hernandez <aldyh@redhat.com>
+
+ * gimplify.c (gimple_add_tmp_var): Remove abort. Add comment.
+
+2007-07-18 Aldy Hernandez <aldyh@redhat.com>
+
+ * gimplify.c (gimple_add_tmp_var): Remove abort. Add comment.
+
+2007-07-18 Aldy Hernandez <aldyh@redhat.com>
+
+ * gimplify.c (gimplify_and_add): Remove unecessary temporary sequence.
+ Remove fixme. Add comment.
+ (gimplify_loop_expr): Tuplefy.
+ (gimplify_bind_expr): Streamline GIMPLE_TRY_FINALLY tuple.
+ (gimplify_expr): Tuplefy TRY_*_EXPR cases.
+ * gimple.c: Fix some spacing.
+ (gimple_build_try, gimple_omp_build_*): Handle empty sequences.
+ (gimple_push): Remove.
+ * gimple.h (gimple_push): Remove.
+
+2007-07-18 Aldy Hernandez <aldyh@redhat.com>
+
+ * tree-gimple.h (declare_vars): Update arguments.
+ * gimplify.c (pop_gimplify_context): Enable call to declare_vars.
+ (declare_vars): Convert to use tuples.
+ (gimple_add_tmp_var): Same.
+ * gimple.h (GIMPLE_BLOCK): New.
+
+2007-07-17 Chris Matthews <chrismatthews@google.com>
+
+ * gimplify.c (gs_build_eh_filter): Renamed to gs_build_eh_filter_tree
+ to avoid name conflict.
+ * gimple-pretty-print.c: Renamed to debug_gs_* to debug_gimple_*.
+ Updated all users.
+ * gimple.h: Renamed all functions with GS and gs prefixes to GIMPLE and
+ gimple, and updated users.
+ Renamed gs_seq_* functions to gimple_seq_*. Updated all users.
+ * gimple.def: Definitions changed to from GS_* to GIMPLE_*.
+
+2007-07-16 Chris Matthews <chrismatthews@google.com>
+
+ * gimple.c (gs_build_switch): Changed nlabels to represent total number
+ of labels including the default.
+ (gs_build_switch_1): Same.
+ (walk_tuple_ops): Same.
+ * gimple-pretty-print.c (dump_gs_switch): Same.
+
+2007-07-16 Aldy Hernandez <aldyh@redhat.com>
+
+ * gimplify.c (gimplify_ctx): Rename current_bind_expr_seq to
+ bind_expr_stack and make it a vector.
+ (push_gimplify_context): Adjust bind_expr_stack for vectors.
+ (pop_gimplify_context): Same.
+ (gimple_push_bind_expr): Same.
+ (gimple_pop_bind_expr): Same.
+ (gimple_current_bind_expr): Same.
+ (get_tmp_var_for): Use ``code''.
+ (gimplify_bind_expr): Remove comment.
+ (gimplify_case_label_expr): Add whitespace.
+ * gimple.c (gs_pop): Remove.
+ * gimple.h: Define vectors of a gimple type.
+ (gs_pop): Remove prototype.
+ * Makefile.in (GIMPLE_H): Add vec.h.
+
+2007-07-15 Diego Novillo <dnovillo@google.com>
+
+ * gimple.c: Rename from gimple-ir.c.
+ Update all users.
+ * gimple.h: Rename from gimple-ir.h.
+ Update all users.
+
+2007-07-15 Diego Novillo <dnovillo@google.com>
+
+ * gimple-ir.c (gimple_statement_structure): Remove code
+ after gcc_unreachable call.
+ * gimplify.c (get_tmp_var_for): New.
+ (gimplify_call_expr): Call it.
+
+2007-07-14 Aldy Hernandez <aldyh@redhat.com>
+
+ * testsuite/gcc.dg/gimple/with_size_expr.c: Check for GS_TRY.
+ * Makefile.in (gimple-ir.o): Add diagnostic.h dependency.
+ * gimple-pretty-print.c (dump_gs_call): Dump LHS if available.
+ (dump_gs_try): New.
+ (dump_gimple_stmt): Add case for GS_TRY.
+ * gimple-ir.c. Include diagnostic.h.
+ (gs_build_try): Cleanup and eval are sequences.
+ Remove catch_p and finally_p arguments. Add catch_finally argument.
+ (gs_omp_build_critical): Body is a gs_seq.
+ (gs_omp_build_parallel): Same.
+ (gs_omp_build_section): Same.
+ (gs_omp_build_master): Same.
+ (gs_omp_build_continue): Same.
+ (gs_omp_build_ordered): Same.
+ (gs_omp_build_sections): Same.
+ (gs_omp_build_single): Same.
+ (gs_omp_build_for): Body and pre_body is a gs_seq.
+ (gs_push): New.
+ (gs_pop): New.
+ (walk_tuple_ops): Walk GS_TRY tuples eval and cleanups correctly.
+ Dump tuple before we ICE.
+ * gimple-ir.h (gs_seq_copy): New.
+ (struct gimple_statement_try): Eval and cleanups are gs_seq's.
+ (gs_bind_set_body): Use gs_seq_copy.
+ (gs_try_eval): Return address of eval.
+ (gs_try_cleanup): Return address of cleanup.
+ (gs_try_set_eval): Use gs_seq_copy.
+ (gs_try_set_cleanup): Same.
+ (gs_omp_set_body): Same.
+ (gs_omp_for_set_pre_body): Same.
+ * gimplify.c (struct gimplify_ctx): Rename current_bind_expr to
+ current_bind_expr_seq, and make it a sequence.
+ (pop_gimplify_context): Adjust for current_bind_expr_seq.
+ (gimple_push_bind_expr): Same.
+ (gimple_pop_bind_expr): Same.
+ (gimple_current_bind_expr): Same.
+ (build_stack_save_restore): Generate tuples.
+ (gimplify_bind_expr): Same.
+
+2007-07-13 Diego Novillo <dnovillo@google.com>
+
+ * gimple-ir.c (gs_add): Swap arguments.
+ Update all users.
+ * gimple-ir.h (gs_seq_append): Likewise.
+
+2007-07-12 Diego Novillo <dnovillo@google.com>
+
+ * tree.c (create_artificial_label): Move from gimplify.c
+ (get_name): Likewise.
+ * tree.h (create_artificial_label, get_name): Move
+ declarations earlier in the file.
+ * diagnostic.h (dump_gimple_stmt, print_gimple_stmt,
+ dump_gimple_seq): Rearrange.
+ * tree-gimple.h (gimplify_function_tree): Move from tree.h.
+ * gimple-pretty-print.c (do_niy): Tidy.
+ (maybe_init_pretty_print): Add comment.
+ (newline_and_indent): Likewise.
+ Remove "gimpleir: " prefix.
+ (debug_gimple_stmt): Add comment.
+ (dump_gs_seq): Remove.
+ (dump_gimple_seq): Add argument SPC.
+ Update all users.
+ If FLAGS contains TDF_DETAILS, emit "gimpleir:" prefix.
+ (dump_gs_cond): If FLAGS contains TDF_DETAILS, emit
+ "gimpleir:" prefix.
+ (dump_gs_bind): Likewise.
+ * function.h (struct function): Remove field 'gimplified'.
+ * gimple-ir.c (gimple_bodies): New private variable.
+ (set_gimple_body): New.
+ (gimple_body): New.
+ * gimple-ir.h: Include pointer-set.h.
+ Add comment before data structure definitons.
+ (set_gimple_body): Declare.
+ (gimple_body): Declare.
+ * gimplify.c (create_artificial_label): Move to tree.c
+ (get_name): Likewise.
+ (gimplify_function_tree): Change return type to void.
+ Call set_gimple_body after gimplification and nullify
+ DECL_SAVED_TREE.
+ Update all callers.
+ * common.opt (fgimple-only): New option.
+ * tree-optimize.c (tree_rest_of_compilation): Do not nullify
+ DECL_SAVED_TREE.
+ * c-gimplify.c (c_genericize): Restore gimplification logic to
+ mainline version.
+ If -fgimple-only was given, exit.
+ * Makefile.in (GIMPLE_IR_H): Add pointer-set.h
+ * tree-cfg.c (execute_build_cfg): Nullify GIMPLE body after
+ building the CFG.
+ (dump_function_to_file): If DECL_SAVED_TREE is NULL dump the
+ GIMPLE body of the function.
+
+2007-07-12 Diego Novillo <dnovillo@google.com>
+
+ * omp-low.c (lower_regimplify): Use a local GIMPLE sequence to
+ hold the result from gimplification.
+ * tree-gimple.c (is_gimple_min_val): Reformat.
+ * tree-gimple.h (enum fallback_t): Document values.
+ (gimplify_expr): Remove IS_STATEMENT argument.
+ Update all users.
+ * langhooks.c (lhd_gimplify_expr): Likewise.
+ * gimplify.c (gimplify_statement_list): If a temporary
+ was returned from voidify_wrapper_expr abort to mark the failure.
+ (gimplify_expr): Remove argument IS_STATEMENT.
+ Update all users.
+ Assert that FALLBACK is used with the appropriate GIMPLE_TEST_F
+ Restore logic to use internal queue.
+ Do not abort if on return from gimplify_call_expr, *EXPR_P has
+ a CALL_EXPR.
+
+2007-07-12 Aldy Hernandez <aldyh@redhat.com>
+
+ * gimple-ir.c (gs_build_switch_1): Allocate one less tree.
+ (gs_build_switch_1): Offset labels by one.
+ (gs_switch_label): Same.
+ (gs_switch_set_label): Same.
+
+2007-07-12 Aldy Hernandez <aldyh@redhat.com>
+
+ * gimple-ir.c (walk_seq_ops): Rename from walk_tree_seq.
+ (walk_tuple_ops): Rename from walk_tree_tuple.
+ * gimple-ir.h, gimplify.c, gimple-ir.c: Rename all calls to
+ walk_tree_seq and walk_tree_tuple accordingly.
+
+2007-07-12 Aldy Hernandez <aldyh@redhat.com>
+
+ * gimple-ir.c (gs_build_switch_1): Fix spacing.
+ Allocate one more tree.
+ (gs_build_switch): Set labels starting at 1.
+ (walk_tree_seq): New.
+ (walk_tree_tuple): New.
+ * gimple-ir.h: Add prototypes for walk_tree_tuple and walk_tree_seq.
+ * gimplify.c (check_pointer_types_r): Uncomment.
+ (gimplify_body): Walk gimple sequence with check_pointer_types_r.
+
+2007-07-11 Chris Matthews <chrismatthews@google.com>
+
+ * tree-pretty-print.c (dump_generic_node): Removed space before default
+ label colon.
+ * tree.h (sort_case_labels): Moved to gimple-ir.h.
+ * gimplify.c (sort_case_labels): Changed to a vector instead of tree
+ vector.
+ (gimplify_switch_expr): Initial implementation with tuples.
+ (gimplify_expr): Changed gimplify_case_label_expr parameter.
+ (gimplify_case_label_expr): Added a gs_seq parameter, and put cases in
+ that.
+ (dump_gimple_stmt): Removed semicolon.
+ (dump_gs_label): Refactored from dump_gimple_expr.
+ (dump_gs_switch): Added.
+ (gs_build_switch_vec): Added.
+ * gimple-ir.c (gs_build_switch_1): Added.
+ (gs_build_switch): Refactored to use gs_build_switch_1.
+ (gs_build_switch_vec): Added.
+ * gs_switch.c: New test case.
+ * gs_switch1.c: New test case.
+ * gs_switch2.c: New test case.
+
+2007-07-05 Aldy Hernandez <aldyh@redhat.com>
+
+ * gimple-pretty-print.c (dump_gimple_stmt): Alphabetize cases.
+ Add case for GS_NOP.
+ * gimplify.c (gimplify_body): Handle null bodies.
+ Use GS_CODE instead of GS_SUBCODE_FLAGS.
+
+2007-07-05 Aldy Hernandez <aldyh@redhat.com>
+
+ * testsuite/gcc.dg/gimple/with_size_expr.c: Clean up dump.
+ * testsuite/gcc.dg/gimple/gs_bind.c: Clean up dump.
+ * gimplify.c (struct gimplify_ctx): Make current_bind_expr a tuple.
+ (pop_gimplify_context): Accept gimple.
+ Comment out call to declare_vars.
+ (gimple_current_bind_expr): Return gimple.
+ (unshare_all_trees): Remove.
+ (gimplify_self_mod_expr): Remove comment.
+ (gimplify_cleanup_point_expr): Correct typo in call to gs_seq_init.
+ (gimplify_body): Remove body local.
+ Build GS_BIND tuples when needed.
+ Do not call unshare_all_trees.
+ Call pop_gimplify_context with appropriate argument.
+ Comment out call to walk_tree.
+ * tree-pretty-print.c (print_declaration): Remove static.
+ * diagnostic.h (print_declaration): Prototype.
+ * tree-gimple.h (pop_gimplify_context): Accept gimple tuple.
+ (gimple_current_bind_expr): Return tuple.
+ * gimple-pretty-print.c (dump_gs_seq): New.
+ (dump_gs_bind): New.
+ (dump_gimple_stmt): Add case for GS_BIND. Print semi-colons after
+ each statement.
+
+2007-06-29 Aldy Hernandez <aldyh@redhat.com>
+
+ * gimplify.c (gimple_push_condition): Enable. Call gs_seq_init with
+ address.
+ (gimplify_cond_expr): Push and pop conditions. Use other GS_COND
+ predicates when appropriate
+
+2007-06-28 Aldy Hernandez <aldyh@redhat.com>
+
+ * testsuite/gcc.dg/gimple/gs_goto.c: New.
+ * testsuite/gcc.dg/gimple/gs_cond.c: New.
+ * tree-gimple.h (gimplify_stmt): Return bool.
+ * gimple-pretty-print.c (INDENT): New.
+ (newline_and_indent): New.
+ (op_gs_cond): New.
+ (dump_gs_cond): New.
+ (dump_gimple_stmt): New.
+ * gimple-ir.c (gs_cond_invert): New.
+ * gimple-ir.h (enum gs_cond): Add comment.
+ (gs_cond_invert): Protoize.
+ * gimplify.c (gimplify_cond_expr): Rewrite for tuples.
+ (gimplify_stmt): Return true if we added a statement to the queue.
+ (gimplify_expr): Enable gimplify_cond_expr.
+ Build tuples for GOTO_EXPRs and LABEL_EXPRs.
+
+2007-06-27 Aldy Hernandez <aldyh@redhat.com>
+
+ * gimple-ir.h (gs_seq_last): Return last statement.
+ * testsuite/gcc.dg/gimple/compound_expr.c: Add checks.
+ * testsuite/gcc.dg/gimple/gs_call.c: Same.
+ * testsuite/gcc.dg/gimple/constructors.c: Same.
+ * testsuite/gcc.dg/gimple/gs_assign.c: Same.
+
+2007-06-27 Aldy Hernandez <aldyh@redhat.com>
+
+ Put this patch back in.
+
+ 2007-06-22 Aldy Hernandez <aldyh@redhat.com>
+
+ * gimplify.c (gimplify_modify_expr): Return after a successful
+ call to gimplify_modify_expr_rhs.
+
+2007-06-26 Aldy Hernandez <aldyh@redhat.com>
+
+ * testsuite/gcc.dg/gimple/gimple.exp: Pass -fdump-tree-gimple-details
+ * testsuite/gcc.dg/gimple/compound_expr.c: Add dg-final.
+ * testsuite/gcc.dg/gimple/gs_return.c: Same.
+ * tree.h (gimplify_function_tree): Add return value.
+ * diagnostic.h (debug_c_tree): Move under tree-pretty-print.c section.
+ (dump_gimple_seq): New.
+ to tests.
+ * gimple-pretty-print.c (dump_gimple_seq): New.
+ * gimplify.c (gimplify_function_tree): Add return value.
+ Remove debug call and exit.
+ Comment out non-working code.
+ * c-gimplify.c (c_genericize): Dump gimple IR. Exit.
+
+2007-06-26 Diego Novillo <dnovillo@google.com>
+
+ * gimple-ir.c (gs_build_call_1): Fix formatting.
+
+2007-06-26 Diego Novillo <dnovillo@google.com>
+
+ * gimple-pretty-print.c (dump_gs_assign, dump_gs_return,
+ dump_gs_call): New functions.
+ (dump_gimple_stmt): Call them.
+ * gimple-ir.c (gs_build_call_1): Factor out of gs_build_call.
+ (gs_build_call): Call it.
+ (gs_build_call_vec): New function.
+ * gimple-ir.h (struct gimple_statement_call): Change type of
+ field 'nargs' to size_t. Update all users.
+ (gs_build_call_vec): Declare.
+ (gs_call_set_fn): Remove.
+ (gs_call_set_nargs): Remove.
+ * gimplify.c: Include "vec.h"
+ (gimplify_return_expr): Fix formatting
+ (gimplify_call_expr): Call gs_build_call_vec.
+ (gimplify_expr): Do not try to test if NULL expressions
+ are in GIMPLE form.
+ (gimplify_function_tree): Do not call debug_gimple_seq.
+ * Makefile.in (gimplify.o): Include vec.h
+
+2007-06-25 Chris Matthews <chrismatthews@google.com>
+
+ * gimplify.c (gimple_current_bind_expr): Changed to work with gs_seq
+ accessors
+ (gimplify_and_add): Same.
+ (annotate_all_with_locus): Same.
+ (gimplify_self_mod_expr): Same.
+ (gimplify_cleanup_point_expr): Same.
+ (gimplify_expr): Same.
+ (gimplify_body): Same.
+ (force_gimple_operand): Same.
+ (gimplify_init_ctor_eval_range): Added GS_ prefix.
+ * gimple-iterator.h (gsi_last): Changed to gs_seq accessors. Changed
+ gimple_stmt_iterator to use a gimple instead of gimple *.
+ (gsi_one_before_end_p): Same.
+ (gsi_start): Same.
+ * gimple-ir.h (gs_cond): Prepended GS_ to names.
+ (gs_seq_first): Replaced macro.
+ (gs_seq_last): Same.
+ (gs_seq_set_first): Same.
+ (gs_seq_set_last): Same.
+ (gs_seq_init): Same.
+ (gs_seq_empty_p): Same.
+ (gs_assign_operand) Changed opno to be a size_t to match set.
+ (gs_bind_body): Changed to use gs_seq.
+ (gs_bind_set_body): Changed to use gs_seq, and gs_seq_set_first, and last.
+ (gs_asm_ninputs): Renamed.
+ (gs_asm_noutputs): Renamed.
+ (gs_asm_nclobbered): Renamed.
+ (gs_asm_set_ninputs): Renamed.
+ (gs_asm_set_noutputs): Renamed.
+ (gs_asm_set_nclobbered): Renamed.
+ (gs_asm_set_input_op): Renamed.
+ (gs_asm_input_op): Renamed.
+ (gs_asm_set_output_op): Renamed.
+ (gs_asm_output_op): Renamed.
+ (gs_omp_body): Changed to use gs_seq.
+ (gs_omp_set_body): Changed to use gs_seq accessors.
+ (gs_omp_for_pre_body): Changed to use gs_seq.
+ (gs_omp_for_set_pre_body): Changed to use gs_seq accessors.
+ (gs_seq_append): Changed to use gs_seq accessors.
+ * gimple-ir.c (gs_add): Same.
+ (gs_build_asm): Changed argument names to match accessors, and changed
+ functions to new accessor names.
+ (gs_build_cond): Reformatted.
+ (gs_build_phi): Same.
+ (gs_build_try): Renamed args to try_p and catch_p.
+ (gs_build_omp_return): Change to correct arguments, and added a subcode
+ flag.
+ * function.c (gimplify-oaraneters): Changed to gs_seq accessors.
+
+2007-06-22 Aldy Hernandez <aldyh@redhat.com>
+
+ * gimplify.c (gimplify_modify_expr): Return after a successful
+ call to gimplify_modify_expr_rhs.
+
+2007-06-21 Aldy Hernandez <aldyh@redhat.com>
+
+ * gimple-ir.h (gs_assign_binary_rhs1): Add assertion for
+ GSS_ASSIGN_BINARY.
+ (gs_assign_binary_set_rhs1): Same.
+ (gs_assign_binary_rhs2): Same.
+ (gs_assign_binary_set_rhs2): Same.
+ (gs_assign_unary_rhs): Same.
+ (gs_assign_unary_set_rhs): Same.
+
+2007-06-21 Aldy Hernandez <aldyh@redhat.com>
+
+ * gcc.dg/gimple/gimple.exp: New.
+ * gcc.dg/gimple/compound_expr.c: New.
+ * gcc.dg/gimple/with_size_expr.c: New.
+ * gcc.dg/gimple/compound_expr.c: New.
+ * gcc.dg/gimple/gs_call.c: New.
+ * gcc.dg/gimple/constructors.c: New.
+ * gcc.dg/gimple/gs_return.c: New.
+ * gcc.dg/gimple/gs_assign.c: New.
+
+2007-06-21 Aldy Hernandez <aldyh@redhat.com>
+
+ * gimple-ir.c (gs_build_cond): Change order of arguments. Make labels
+ of type tree.
+ (gs_build_asm): Fix formatting.
+ * gimple-ir.h (gimple_statement_cond): Make labels of type tree.
+ (gs_build_cond): Change order and type of arguments.
+ (gs_build_asm): Fix formatting.
+ (gs_omp_build_for): Same.
+ (gs_assign_binary_rhs1): Remove assert.
+ (gs_assign_binary_set_rhs1): Same.
+ (gs_assign_binary_rhs2): Same.
+ (gs_assign_binary_set_rhs2): Same.
+ (gs_assign_unary_rhs): Same.
+ (gs_cond_true_label): Return a tree.
+ (gs_cond_set_true_label): Make label a tree.
+ (gs_cond_set_false_label): Make label a tree.
+ (gs_cond_false_label): Return a tree.
+ * gimplify.c (gimplify_init_ctor_eval_range): Build tuples.
+ (gimplify_init_ctor_eval): Same.
+ (gimplify_init_constructor): Enable. Adjust for tuples.
+ (gimplify_modify_expr_rhs): Uncomment call to
+ gimplify_init_constructor.
+
+2007-06-21 Diego Novillo <dnovillo@google.com>
+
+ * gimple.def: Rename from gs.def.
+ Adjust all users.
+
+2007-06-21 Diego Novillo <dnovillo@google.com>
+
+ * tree-pretty-print.c (pred_symbol_code, do_gs_niy,
+ debug_gimple_stmt, debug_gimple_seq, print_gimple_stmt,
+ dump_gimple_stmt): Move to gimple-pretty-print.c
+ * diagnostic.h: Add comment for functions in gimple-pretty-print.c
+ * gimple-pretty-print.c: New file.
+ * gimple-ir.c (gs_build_return): Fix spacing.
+ (gs_build_assign): Likewise.
+ * gimple-ir.h: Fix spacing.
+ (gs_assign_set_operand): Change OPNO to size_t.
+ Add assertions for OPNO's value.
+ (gs_assign_lhs): Rename from gs_assign_operand_lhs.
+ (gs_assign_binary_rhs1): Rename from gs_assign_operand_rhs.
+ Assert that GS is GSS_ASSIGN_BINARY
+ (gs_assign_binary_set_rhs1): Rename from gs_assign_set_rhs.
+ Assert that GS is GSS_ASSIGN_BINARY.
+ (gs_assign_binary_set_rhs2): Rename from gs_assign_set_rhs2.
+ Assert that GS is GSS_ASSIGN_BINARY.
+ (gs_assign_unary_rhs): New.
+ (gs_assign_unary_set_rhs): New.
+ (gs_call_fn, gs_call_lhs, gs_call_chain, gs_call_arg,
+ gs_cond_lhs, gs_cond_rhs, gs_label_label, gs_goto_dest,
+ gs_bind_vars, gs_asm_in_op, gs_asm_out_op, gs_asm_clobber_op,
+ gs_catch_types, gs_catch_handler, gs_eh_filter_types,
+ gs_eh_filter_failure, gs_try_eval, gs_try_cleanup,
+ gs_phi_result, gs_switch_index, gs_switch_default_label,
+ gs_switch_label,gs_omp_critical_name, gs_omp_for_clauses,
+ gs_omp_for_index, gs_omp_for_initial, gs_omp_for_final,
+ gs_omp_for_incr, gs_omp_parallel_clauses,
+ gs_omp_parallel_child_fn, gs_omp_parallel_data_arg,
+ gs_omp_single_clauses, gs_omp_sections_clauses,
+ gs_return_retval): Change return type to 'tree'.
+ * Makefile.in (OBJS-common): Add gimple-pretty-print.o.
+ (gimple-pretty-print.o): New rule.
+
+2007-06-20 Aldy Hernandez <aldyh@redhat.com>
+
+ * tree-pretty-print.c (dump_gimple_stmt): Change pred_symbol_code
+ to op_symbol_code.
+
+2007-06-19 Aldy Hernandez <aldyh@redhat.com>
+
+ * gimplify.c (gimplify_modify_expr_rhs): Enable. Adjust for tuples.
+ (gimplify_modify_expr): Call gimplify_modify_expr_rhs.
+ (gimplify_compound_expr): Enable. Adjust for tuples. Remove comment
+ that no longer applies.
+ (gimplify_expr): Enable call to gimplify_compound_expr.
+
+2007-06-18 Chris Matthews <chrismatthews@google.com>
+
+ * Makefile.in (GTFILES): Added gimeple-ir.h.
+
+ * gimple-ir.c (gs_build_return, gs_build_call, gs_build_assign):
+ Changed to use new accessors.
+ (gs_build_cond, gs_build_label, gs_build_goto,
+ gs_build_nop, gs_build_bind gs_build_asm, gs_build_catch,
+ gs_build_eh_filter, gs_build_try, gs_build_phi,
+ gs_build_resx, gs_build_switch, gs_omp_build_critical,
+ gs_omp_build_for, gs_omp_build_parallel,
+ gs_omp_build_section, gs_omp_build_master,
+ gs_omp_build_ordered, gs_omp_continue,
+ gs_omp_build_ordered, gs_omp_build_return,
+ gs_omp_build_sections, gs_omp_build_single): New
+ functions.
+
+ * gimple-ir.h (struct gimple_statement_switch): Changed
+ default label to be in labels[0].
+
+ (struct gimple_statement_asm): Corrected the allocation
+ length.
+
+ (enum gs_cond): New enum.
+ (gs_assign_set_operand): Changed to work with new accessors.
+ (gs_assign_operand_lhs, gs_assign_operand_rhs,
+ gs_assign_operand_set_lhs, gs_assign_set_rhs,
+ gs_assign_operand_rhs2, gs_assign_set_rhs2, gs_call_fn,
+ gs_call_set_fn, gs_call_lhs, gs_call_set_lhs,
+ gs_call_chain, gs_call_set_chain, gs_call_nargs,
+ gs_call_set_nargs, gs_call_arg, gs_call_set_arg,
+ gs_cond_lhs, gs_cond_set_lhs, gs_cond_rhs,
+ gs_cond_set_rhs, gs_cond_true_label,
+ gs_cond_set_true_label, gs_cond_set_false_label,
+ gs_cond_false_label, gs_label_label, gs_label_set_label,
+ gs_goto_dest, gs_goto_set_dest, gs_bind_vars,
+ gs_bind_set_vars, gs_bind_body, gs_bind_set_body,
+ gs_asm_ni, gs_asm_set_ni, gs_asm_no, gs_asm_set_no,
+ gs_asm_nc, gs_asm_set_nc, gs_asm_in_op, gs_asm_set_in_op,
+ gs_asm_out_op, gs_asm_set_out_op, gs_asm_clobber_op,
+ gs_asm_set_clobber_op, gs_asm_string, gs_asm_set_string,
+ gs_catch_types, gs_catch_handler, gs_catch_set_types,
+ gs_catch_set_handler, gs_eh_filter_types,
+ gs_eh_filter_failure, gs_eh_filter_set_types,
+ gs_eh_filter_set_failure, gs_try_eval, gs_try_cleanup,
+ gs_try_set_eval, gs_try_set_cleanup, gs_phi_capacity,
+ gs_phi_set_capacity, gs_phi_nargs, gs_phi_set_nargs,
+ gs_phi_result, gs_phi_set_result, gs_phi_arg,
+ gs_phi_set_arg, gs_resx_region, gs_resx_set_region,
+ gs_switch_nlabels, gs_switch_set_nlabels,
+ gs_switch_index, gs_switch_set_index,
+ gs_switch_default_label, gs_switch_set_default_label,
+ gs_switch_label, gs_switch_set_label, gs_omp_body,
+ gs_omp_set_body, gs_omp_critical_name,
+ gs_omp_critical_set_name, gs_omp_for_clauses,
+ gs_omp_for_set_clauses, gs_omp_for_index,
+ gs_omp_for_set_index, gs_omp_for_initial,
+ gs_omp_for_set_initial, gs_omp_for_final,
+ gs_omp_for_set_final, gs_omp_for_incr,
+ gs_omp_for_set_incr, gs_omp_for_pre_body,
+ gs_omp_for_set_pre_body, gs_omp_parallel_clauses,
+ gs_omp_parallel_set_clauses, gs_omp_parallel_child_fn,
+ gs_omp_parallel_set_child_fn, gs_omp_parallel_data_arg,
+ gs_omp_parallel_set_data_arg, gs_omp_single_clauses,
+ gs_omp_single_set_clauses, gs_omp_sections_clauses,
+ gs_omp_sections_set_clauses, gs_assign_omp_for_cond,
+ gs_omp_for_cond gs_return_set_retval,
+ gs_add_subcode_flag): New accessor functions.
+ (gs_return_retval): Renamed gs_return_operand_retval to match accessor
+ conventions.
+
+2007-05-31 Aldy Hernandez <aldyh@redhat.com>
+
+ * gimple-ir.c (gs_build_call): New.
+ * gimple-ir.h (GS_CALL_LHS): New.
+ (GS_CALL_FN): New.
+ (GS_CALL_CHAIN): New.
+ (GS_CALL_NARGS): New.
+ (GS_CALL_ARG): New.
+ (gs_call_lhs): New.
+ (gs_call_fn): New.
+ (gs_call_chain): New.
+ (gs_call_nargs): New.
+ (gs_call_arg): New.
+ * gimplify.c (gimplify_modify_expr_to_memcpy): Enable and rewrite for
+ tuples.
+ (gimplify_modify_expr_to_memset): Same.
+ (gimplify_statement_list): Same.
+ (gimplify_expr): Enable STATEMENT_LIST case.
+
+2007-05-29 Aldy Hernandez <aldyh@redhat.com>
+
+ Merged revisions 124007-125166 from mainline.
+
+2007-05-23 Aldy Hernandez <aldyh@redhat.com>
+
+ * builtins.c (std_gimplify_va_arg_expr): Add argument to gimplify_expr.
+ Remove seq argument.
+ (gimplify_va_arg_expr): Same.
+ * tree-gimple.h: Same.
+ * langhooks.c (lhd_gimplify_expr): Change pre_p and post_p types to
+ sequences.
+ * langhooks-def.h (lhd_gimplify_expr): Change
+ * langhooks.h (struct lang_hooks): Remove argument.
+ * gimplify.c (internal_get_tmp_var): Adjust calls to gimplify_expr
+ for new arguments.
+ (gimplify_switch_expr): Same.
+ (gimplify_var_or_parm_decl): Same.
+ (gimplify_compound_lval): Same.
+ (gimplify_self_mod_expr): Same.
+ (gimplify_arg): Same.
+ (gimplify_call_expr): Same.
+ (gimplify_init_ctor_preeval): Same.
+ (gimplify_init_constructor): Same.
+ (gimplify_modify_expr_rhs): Same.
+ (gimplify_modify_expr): Same.
+ (gimplify_save_expr): Same.
+ (gimplify_addr_expr): Same.
+ (gimplify_asm_expr): Same.
+ (gimplify_target_expr): Same.
+ (omp_check_private): Same.
+ (gimplify_scan_omp_clauses): Same.
+ (gimplify_omp_parallel): Same.
+ (gimplify_omp_for): Same.
+ (goa_stabilize_expr): Same.
+ (gimplify_omp_atomic): Same.
+ (gimplify_one_sizepos): Same.
+ (force_gimple_operand): Same.
+ (gimplify_expr): Remove seq_p argument. Add new is_statement
+ argument. Adjust accordingly. Make seq_p required.
+
+2007-05-07 Aldy Hernandez <aldyh@redhat.com>
+
+ * function.c (gimplify_parameters): Use new GS_SEQ_INIT definition.
+ * gimple-ir.h (GS_SEQ_INIT): Do not use C99 constructs.
+ * gimplify.c: Disable non working code throughout.
+ Pass additional call to gimplify_expr throughout.
+ (gimplify_ctx): Make conditional_cleanups a sequence.
+ (gimple_push_condition): Use GS_SEQ_EMPTY_P.
+ (gimple_pop_condition): Adapt for sequences.
+ (gimplify_and_add): Use gs_seq_append regardless of side effects.
+ (internal_get_tmp_var): Use sequences.
+ (get_formal_tmp_var): Same.
+ (get_initialized_tmp_var): Same.
+ (annotate_one_with_locus): Change GS_LOCUS to GS_LOCUS_EMPTY_P.
+ (gimplify_bind_expr): Use sequences.
+ Change append_to_statement_list to gimplify_and_add.
+ (gimplify_return_expr): Add gimplified code to pre_p.
+ (gimplify_decl_expr): New seq_p parameter.
+ (gimplify_loop_expr): Adapt for sequences.
+ Use gimplify_and_add instead of append_to_statement_list.
+ (gimplify_switch_expr): Same.
+ (gimplify_compound_lval): Use sequences.
+ (gimplify_self_mod_expr): Same.
+ Use gs_seq_append instead of append_to_statement_list.
+ (gimplify_arg): Use sequences.
+ (gimplify_call_expr): Same.
+ (gimplify_cond_expr): Use sequences.
+ (gimplify_init_ctor_preeval): Use sequences.
+ (gimplify_init_ctor_eval_range): Same.
+ Use gimplify_and_add instead of append_to_statement_list.
+ (gimplify_init_ctor_eval): Use sequences.
+ (gimplify_init_constructor): Same.
+ Remove one call to append_to_statement_list.
+ (gimplify_modify_expr_rhs): Use sequences.
+ (gimplify_modify_expr_complex_part): Use sequences.
+ Remove call to tree_to_gimple_tuple.
+ Build GS_ASSIGN tuple.
+ (gimplify_modify_expr): Use new argument. Use sequences.
+ Do not call append_to_statement_list.
+ Build GS_ASSIGN tuple.
+ Do not call tree_to_gimple_tuple.
+ Set *expr_p to NULL when we do not want the value.
+ (gimplify_compound_expr): Use sequences.
+ (gimplify_save_expr): Same.
+ (gimplify_addr_expr): Same.
+ (gimplify_asm_expr): Same.
+ (gimplify_cleanup_point_expr): Same.
+ (gimple_push_cleanup): Same.
+ Build GS_ASSIGN tuples.
+ (gimplify_target_expr): Use sequences.
+ (gimplify_scan_omp_clauses): Same.
+ Add argument to gimplify_stmt calls.
+ (gimplify_omp_parallel): Same.
+ (gimplify_omp_for): Use sequences.
+ (gimplify_omp_workshare): Same.
+ (goa_stabilize_expr): Same.
+ (gimplify_omp_atomic_pipeline): Same.
+ (gimplify_omp_atomic_mutex): Same.
+ (gimplify_omp_atomic): Same.
+ (gimplify_expr): Same.
+ Call GS_SEQ_INIT with argument.
+ Use new seq_p argument.
+ Do not call tree_to_gimple_tuple.
+ Pass additional argument to gimplify_decl_expr.
+ Do not pass seq_p argument to gimplify_return_expr.
+ Call gs_seq_append instead of append_to_statement_list.
+ Check that all statements have been converted to tuples.
+ Make pre_p and seq_p sequences coexist.
+ (gimplify_type_sizes): Use sequences.
+ (gimplify_one_sizepos): Same.
+ (gimplify_body): Make parm_stmts a sequence.
+ Add argument to seq_p.
+ (gimplify_function_tree): Call debug_gimple_seq.
+ (force_gimple_operand): Use sequences.
+ (force_gimple_operand_bsi): Use sequences.
+
+2007-05-04 Aldy Hernandez <aldyh@redhat.com>
+
+ * omp-low.c (build_omp_barrier): Adjust arguments for sequences.
+ (lower_rec_input_clauses): Disable non working code.
+ (lower_regimplify): Pass additional argument to gimplify_expr.
+ * tree-mudflap.c (mx_register_decls): Disable non working code.
+ * tree-inline.c (copy_bb): Disable non working code.
+ (setup_one_parameter): Same.
+ * tree-cfg.c (make_edges): Same.
+
+2007-05-04 Aldy Hernandez <aldyh@redhat.com>
+
+ * tree-gimple.h (get_initialized_tmp_var): Adjust prototype
+ for sequences.
+ (get_formal_tmp_var): Same.
+ (gimplify_type_sizes): Same.
+ (gimplify_one_sizepos): Same.
+ (gimplify_stmt): Same.
+ (gimplify_and_add): Same.
+ (gimplify_va_arg_expr): Same.
+ * langhooks.h (lang_hooks): Same.
+ * function.c (gimplify_parm_type): Adjust for sequences.
+ (gimplify_parameters): Same.
+ * c-gimplify.c (gimplify_compound_literal_expr): Same.
+ (c_gimplify_expr): Same.
+ * tree-flow.h (force_gimple_operand): Same.
+ * c-common.h (c_gimplify_expr): Adjust prototype for sequences.
+ * config/i386/i386.c (ix86_gimplify_va_arg): Adjust for sequences.
+ Change call to append_to_statement_list to gimplify_and_add.
+ Add parameter to gimplify_expr.
+
+2007-05-04 Aldy Hernandez <aldyh@redhat.com>
+
+ * gimple-ir.c (gs_code_name): Constify.
+ (gs_build_assign): New.
+ (gimple_statement_structure): Abstract code out to...
+ (gss_for_assign): ...here.
+ (gs_add): Set the last item correctly.
+ * gimple-ir.h (GS_LOCUS_EMPTY_P): New.
+ (GS_SEQ_INIT): Add a cast.
+ (gimple_statement_base): Make code a gs_code enum.
+ (gimple_statement_with_ops): Remove address_taken.
+ (GS_ASSIGN_BINARY_LHS): New.
+ (GS_ASSIGN_BINARY_RHS1): New.
+ (GS_ASSIGN_BINARY_RHS2): New.
+ (GS_ASSIGN_UNARY_REG_LHS): New.
+ (GS_ASSIGN_UNARY_REG_RHS): New.
+ (GS_ASSIGN_UNARY_MEM_LHS): New.
+ (GS_ASSIGN_UNARY_MEM_RHS): New.
+ (gs_seq_append): New.
+ Move gs_seq typedef to...
+ * coretypes.h: ...here.
+ * gimple-iterator.h (gsi_stmt_ptr): Add FIXME note.
+
+2007-05-04 Aldy Hernandez <aldyh@redhat.com>
+
+ * tree.h (std_gimplify_va_arg_expr): Change tree * to a sequence
+ in prototype.
+ (gimplify_parameters): Return a sequence.
+ * target.h (gimplify_va_arg_expr): Change tree * to a sequence.
+ * builtins.c (std_gimplify_va_arg_expr): Same.
+ Pass additional argument to gimplify_expr.
+ (gimplify_va_arg_expr): Change tree * to a sequence.
+ Change append_to_statement_list call to gimplify_and_add.
+ Pass additional argument to gimplify_expr calls.
+
+2007-05-04 Aldy Hernandez <aldyh@redhat.com>
+
+ * tree-pretty-print.c (do_gs_niy): New.
+ (debug_gimple_stmt): New.
+ (debug_gimple_seq): New.
+ (print_gimple_stmt): New.
+ (dump_gimple_stmt): New.
+ * diagnostic.h: Add prototypes for dump_gimple_stmt,
+ print_gimple_stmt, debug_gimple_stmt, debug_gimple_seq.
+
+2007-04-26 Aldy Hernandez <aldyh@redhat.com>
+
+ * tree-gimple.h (annotate_all_with_locus): First argument is now a
+ sequence.
+ * gimple-ir.h (GS_LOCUS): New.
+ (gimple_statement_base): Locus is of type location_t.
+ * gimplify.c (internal_get_tmp_var): Use sequences.
+ (should_carry_locus_p): Adjust for gimple ir.
+ (annotate_one_with_locus): Same.
+ (annotate_all_with_locus): Same.
+ (gimplify_stmt): Adjust for sequences.
+ (gimplify_expr): Same.
+
+2007-04-25 Aldy Hernandez <aldyh@redhat.com>
+
+ * gimple-ir.h (GS_SEQ_EMPTY_P): New.
+ Move gs_build_return, gs_add, and gimple_statement_structure
+ prototypes.
+ (gs_assign_operand): Fix typos in gss.
+ Include gimple-iterator.h.
+ * Makefile.in (GIMPLE_IR_H): Add gimple-iterator.h.
+ (TREE_GIMPLE_H): Same.
+
+2007-04-25 Aldy Hernandez <aldyh@redhat.com>
+
+ * gimple-iterator.h (gsi_one_before_end_p): Use GS_SEQ_LAST.
+
+2007-04-25 Aldy Hernandez <aldyh@redhat.com>
+
+ * gimple-iterator.h: New file.
+
+2007-04-23 Aldy Hernandez <aldyh@redhat.com>
+
+ * gimple-ir.c: New file.
+ * gimple-ir.h: New file.
+ * gsstruct.def: New file.
+ * gs.def: New file.
+ * gengtype.c (open_base_files): Add gimple-ir.h.
+ * tree-gimple.h: Include gimple-ir.h.
+ Add sequence to gimplify_expr and gimplify_body prototypes.
+ * gimplify.c: Include gimple-ir.h.
+ (gimplify_and_add): Adjust for gimple IR.
+ (gimplify_return_expr): Same.
+ (gimplify_stmt): Add seq_p argument.
+ (gimplify_expr): Add seq_p sequence and adjust accordingly.
+ (gimplify_body): Same.
+ * coretypes.h: Add gimple_statement_d and gimple definitions.
+ * Makefile.in (GIMPLE_IR_H): New.
+ (TREE_GIMPLE_H): Add gimple-ir.h.
+ (OBJS-common): Add gimple-ir.o.
+ (gimplify.o): Add GIMPLE_IR_H.
+ (gimple-ir.o): New.
+ (build/gencheck.o): Add gs.def.
+
+Local Variables:
+mode: change-log
+End:
diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
index 1c2bd7cba60..af19991cfd3 100644
--- a/gcc/DATESTAMP
+++ b/gcc/DATESTAMP
@@ -1 +1 @@
-20080704
+20080728
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 29bde08acf0..fed342eaab4 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -155,10 +155,9 @@ coverageexts = .{gcda,gcno}
# flags from configure. The user is free to explicitly turn these flags
# off if they wish.
# LOOSE_WARN are the warning flags to use when compiling something
-# which is only compiled with gcc, such as libgcc and the frontends
-# other than C.
+# which is only compiled with gcc, such as libgcc.
# STRICT_WARN are the additional warning flags to
-# apply to the back end and the C front end, which may be compiled
+# apply to the back end and some front ends, which may be compiled
# with other compilers.
LOOSE_WARN = @loose_warn@
STRICT_WARN = @strict_warn@
@@ -258,6 +257,22 @@ build_file_translate = @build_file_translate@
# Locate mkinstalldirs.
mkinstalldirs=$(SHELL) $(srcdir)/../mkinstalldirs
+# write_entries_to_file - writes each entry in a list
+# to the specified file. Entries are written in chunks of
+# $(write_entries_to_file_split) to accomodate systems with
+# severe command-line-length limitations.
+# Parameters:
+# $(1): variable containing entries to iterate over
+# $(2): output file
+write_entries_to_file_split = 50
+write_entries_to_file = $(shell rm -f $(2) || :) $(shell touch $(2)) \
+ $(foreach range, \
+ $(shell i=1; while test $$i -le $(words $(1)); do \
+ echo $$i; i=`expr $$i + $(write_entries_to_file_split)`; done), \
+ $(shell echo $(wordlist $(range), \
+ $(shell expr $(range) + $(write_entries_to_file_split) - 1), $(1)) \
+ | tr ' ' '\n' >> $(2)))
+
# --------
# UNSORTED
# --------
@@ -763,24 +778,28 @@ REVISION_s :=
endif
# Shorthand variables for dependency lists.
+TOPLEV_H = toplev.h input.h
TARGET_H = $(TM_H) target.h insn-modes.h
MACHMODE_H = machmode.h mode-classes.def insn-modes.h
HOOKS_H = hooks.h $(MACHMODE_H)
HOSTHOOKS_DEF_H = hosthooks-def.h $(HOOKS_H)
LANGHOOKS_DEF_H = langhooks-def.h $(HOOKS_H)
-TARGET_DEF_H = target-def.h $(HOOKS_H)
+TARGET_DEF_H = target-def.h $(HOOKS_H) targhooks.h
RTL_BASE_H = rtl.h rtl.def $(MACHMODE_H) reg-notes.def insn-notes.def \
- input.h $(REAL_H) statistics.h vec.h fixed-value.h alias.h
+ $(INPUT_H) $(REAL_H) statistics.h vec.h $(FIXED_VALUE_H) alias.h
+FIXED_VALUE_H = fixed-value.h $(MACHMODE_H) double-int.h
RTL_H = $(RTL_BASE_H) genrtl.h
PARAMS_H = params.h params.def
BUILTINS_DEF = builtins.def sync-builtins.def omp-builtins.def
TREE_H = tree.h all-tree.def tree.def c-common.def $(lang_tree_files) \
$(MACHMODE_H) tree-check.h $(BUILTINS_DEF) \
- input.h statistics.h vec.h treestruct.def $(HASHTAB_H) \
- double-int.h alias.h
-BASIC_BLOCK_H = basic-block.h bitmap.h sbitmap.h varray.h $(PARTITION_H) \
+ $(INPUT_H) statistics.h vec.h treestruct.def $(HASHTAB_H) \
+ double-int.h alias.h $(SYMTAB_H) options.h
+BASIC_BLOCK_H = basic-block.h $(BITMAP_H) sbitmap.h varray.h $(PARTITION_H) \
hard-reg-set.h $(PREDICT_H) vec.h $(FUNCTION_H) \
cfghooks.h $(OBSTACK_H)
+GIMPLE_H = gimple.h gimple.def gsstruct.def pointer-set.h vec.h \
+ $(GGC_H) $(BASIC_BLOCK_H) $(TM_H) $(TARGET_H) tree-ssa-operands.h
GCOV_IO_H = gcov-io.h gcov-iov.h auto-host.h
COVERAGE_H = coverage.h $(GCOV_IO_H)
DEMANGLE_H = $(srcdir)/../include/demangle.h
@@ -788,7 +807,7 @@ RECOG_H = recog.h
ALIAS_H = alias.h coretypes.h
EMIT_RTL_H = emit-rtl.h
FLAGS_H = flags.h options.h
-FUNCTION_H = function.h $(TREE_H) $(HASHTAB_H)
+FUNCTION_H = function.h $(TREE_H) $(HASHTAB_H) varray.h
EXPR_H = expr.h insn-config.h $(FUNCTION_H) $(RTL_H) $(FLAGS_H) $(TREE_H) $(MACHMODE_H) $(EMIT_RTL_H)
OPTABS_H = optabs.h insn-codes.h
REGS_H = regs.h varray.h $(MACHMODE_H) $(OBSTACK_H) $(BASIC_BLOCK_H) $(FUNCTION_H)
@@ -799,36 +818,39 @@ INTEGRATE_H = integrate.h $(VARRAY_H)
CFGLAYOUT_H = cfglayout.h $(BASIC_BLOCK_H)
CFGLOOP_H = cfgloop.h $(BASIC_BLOCK_H) $(RTL_H) vecprim.h double-int.h
IPA_UTILS_H = ipa-utils.h $(TREE_H) $(CGRAPH_H)
-IPA_REFERENCE_H = ipa-reference.h bitmap.h $(TREE_H)
+IPA_REFERENCE_H = ipa-reference.h $(BITMAP_H) $(TREE_H)
IPA_TYPE_ESCAPE_H = ipa-type-escape.h $(TREE_H)
-CGRAPH_H = cgraph.h $(TREE_H)
-DF_H = df.h bitmap.h $(BASIC_BLOCK_H) alloc-pool.h
+CGRAPH_H = cgraph.h $(TREE_H) $(BASIC_BLOCK_H)
+DF_H = df.h $(BITMAP_H) $(BASIC_BLOCK_H) alloc-pool.h
RESOURCE_H = resource.h hard-reg-set.h $(DF_H)
DDG_H = ddg.h sbitmap.h $(DF_H)
GCC_H = gcc.h version.h
-GGC_H = ggc.h gtype-desc.h
+GGC_H = ggc.h gtype-desc.h statistics.h
TIMEVAR_H = timevar.h timevar.def
-INSN_ATTR_H = insn-attr.h $(srcdir)/insn-addr.h $(srcdir)/varray.h
+INSN_ATTR_H = insn-attr.h $(INSN_ADDR_H) $(srcdir)/varray.h
+INSN_ADDR_H = $(srcdir)/insn-addr.h vecprim.h
C_COMMON_H = c-common.h $(SPLAY_TREE_H) $(CPPLIB_H) $(GGC_H)
C_PRAGMA_H = c-pragma.h $(CPPLIB_H)
-C_TREE_H = c-tree.h $(C_COMMON_H) toplev.h $(DIAGNOSTIC_H)
-SYSTEM_H = system.h hwint.h $(srcdir)/../include/libiberty.h
+C_TREE_H = c-tree.h $(C_COMMON_H) $(TOPLEV_H) $(DIAGNOSTIC_H)
+SYSTEM_H = system.h hwint.h $(srcdir)/../include/libiberty.h \
+ $(srcdir)/../include/safe-ctype.h $(srcdir)/../include/filenames.h
PREDICT_H = predict.h predict.def
CPPLIB_H = $(srcdir)/../libcpp/include/line-map.h \
$(srcdir)/../libcpp/include/cpplib.h
+INPUT_H = $(srcdir)/../libcpp/include/line-map.h input.h
DECNUM_H = $(DECNUM)/decContext.h $(DECNUM)/decDPD.h $(DECNUM)/decNumber.h \
$(DECNUMFMT)/decimal32.h $(DECNUMFMT)/decimal64.h \
$(DECNUMFMT)/decimal128.h $(DECNUMFMT)/decimal128Local.h
MKDEPS_H = $(srcdir)/../libcpp/include/mkdeps.h
-SYMTAB_H = $(srcdir)/../libcpp/include/symtab.h
+SYMTAB_H = $(srcdir)/../libcpp/include/symtab.h $(OBSTACK_H)
CPP_ID_DATA_H = $(CPPLIB_H) $(srcdir)/../libcpp/include/cpp-id-data.h
-TREE_DUMP_H = tree-dump.h $(SPLAY_TREE_H)
-TREE_GIMPLE_H = tree-gimple.h tree-iterator.h
+CPP_INTERNAL_H = $(srcdir)/../libcpp/internal.h $(CPP_ID_DATA_H)
+TREE_DUMP_H = tree-dump.h $(SPLAY_TREE_H) tree-pass.h
TREE_FLOW_H = tree-flow.h tree-flow-inline.h tree-ssa-operands.h \
- bitmap.h $(BASIC_BLOCK_H) hard-reg-set.h $(TREE_GIMPLE_H) \
+ $(BITMAP_H) $(BASIC_BLOCK_H) hard-reg-set.h $(GIMPLE_H) \
$(HASHTAB_H) $(CGRAPH_H) $(IPA_REFERENCE_H)
TREE_SSA_LIVE_H = tree-ssa-live.h $(PARTITION_H) vecprim.h
-PRETTY_PRINT_H = pretty-print.h input.h $(OBSTACK_H)
+PRETTY_PRINT_H = pretty-print.h $(INPUT_H) $(OBSTACK_H)
DIAGNOSTIC_H = diagnostic.h diagnostic.def $(PRETTY_PRINT_H) options.h
C_PRETTY_PRINT_H = c-pretty-print.h $(PRETTY_PRINT_H) $(C_COMMON_H) $(TREE_H)
SCEV_H = tree-scalar-evolution.h $(GGC_H) tree-chrec.h $(PARAMS_H)
@@ -840,6 +862,9 @@ REAL_H = real.h $(MACHMODE_H)
IRA_INT_H = ira.h ira-int.h $(CFGLOOP_H) alloc-pool.h
DBGCNT_H = dbgcnt.h dbgcnt.def
EBIMAP_H = ebitmap.h sbitmap.h
+IPA_PROP_H = ipa-prop.h $(TREE_H) vec.h $(CGRAPH_H)
+GSTAB_H = gstab.h stab.def
+BITMAP_H = bitmap.h $(HASHTAB_H) statistics.h
#
# Now figure out from those variables how to compile and link.
@@ -1068,7 +1093,10 @@ OBJS-common = \
gcse.o \
genrtl.o \
ggc-common.o \
+ gimple.o \
+ gimple-iterator.o \
gimple-low.o \
+ gimple-pretty-print.o \
gimplify.o \
global.o \
graph.o \
@@ -1166,7 +1194,6 @@ OBJS-common = \
tree-dfa.o \
tree-dump.o \
tree-eh.o \
- tree-gimple.o \
tree-if-conv.o \
tree-into-ssa.o \
tree-iterator.o \
@@ -1230,7 +1257,6 @@ OBJS-common = \
tree-vect-patterns.o \
tree-vect-transform.o \
tree-vectorizer.o \
- tree-vn.o \
tree-vrp.o \
tree.o \
value-prof.o \
@@ -1761,9 +1787,9 @@ s-crt0: $(CRT0_S) $(MCRT0_S) $(GCC_PASSES) $(CONFIG_H)
c-errors.o: c-errors.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
$(C_TREE_H) $(FLAGS_H) $(DIAGNOSTIC_H) $(TM_P_H)
c-parser.o : c-parser.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
- $(GGC_H) $(TIMEVAR_H) $(C_TREE_H) input.h $(FLAGS_H) toplev.h output.h \
- $(CPPLIB_H) gt-c-parser.h langhooks.h $(C_COMMON_H) $(C_PRAGMA_H) \
- vec.h $(TARGET_H)
+ $(GGC_H) $(TIMEVAR_H) $(C_TREE_H) $(INPUT_H) $(FLAGS_H) $(TOPLEV_H) output.h \
+ $(CPPLIB_H) gt-c-parser.h $(RTL_H) langhooks.h $(C_COMMON_H) $(C_PRAGMA_H) \
+ vec.h $(TARGET_H) $(CGRAPH_H)
srcextra: gcc.srcextra lang.srcextra
@@ -1776,15 +1802,15 @@ incpath.o: incpath.c incpath.h $(CONFIG_H) $(SYSTEM_H) $(CPPLIB_H) \
c-decl.o : c-decl.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
$(RTL_H) $(C_TREE_H) $(GGC_H) $(TARGET_H) $(FLAGS_H) $(FUNCTION_H) output.h \
- $(EXPR_H) debug.h toplev.h intl.h $(TM_P_H) $(TREE_INLINE_H) $(TIMEVAR_H) \
+ $(EXPR_H) debug.h $(TOPLEV_H) intl.h $(TM_P_H) $(TREE_INLINE_H) $(TIMEVAR_H) \
opts.h $(C_PRAGMA_H) gt-c-decl.h $(CGRAPH_H) $(HASHTAB_H) libfuncs.h \
except.h $(LANGHOOKS_DEF_H) $(TREE_DUMP_H) $(C_COMMON_H) $(CPPLIB_H) \
- $(DIAGNOSTIC_H) input.h langhooks.h $(TREE_GIMPLE_H) tree-mudflap.h \
- pointer-set.h
+ $(DIAGNOSTIC_H) $(INPUT_H) langhooks.h $(GIMPLE_H) tree-mudflap.h \
+ pointer-set.h $(BASIC_BLOCK_H) $(GIMPLE_H) tree-iterator.h
c-typeck.o : c-typeck.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(TREE_H) $(C_TREE_H) $(TARGET_H) $(FLAGS_H) intl.h output.h $(EXPR_H) \
- $(RTL_H) toplev.h $(TM_P_H) langhooks.h $(GGC_H) $(TREE_FLOW_H) \
- $(TREE_GIMPLE_H) tree-iterator.h
+ $(RTL_H) $(TOPLEV_H) $(TM_P_H) langhooks.h $(GGC_H) $(TREE_FLOW_H) \
+ $(GIMPLE_H) tree-iterator.h
c-lang.o : c-lang.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
$(C_TREE_H) $(DIAGNOSTIC_H) \
$(GGC_H) langhooks.h $(LANGHOOKS_DEF_H) $(C_COMMON_H) gtype-c.h \
@@ -1793,31 +1819,32 @@ stub-objc.o : stub-objc.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TREE_H) \
$(C_COMMON_H)
c-lex.o : c-lex.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
$(RTL_H) debug.h $(C_TREE_H) $(C_COMMON_H) $(REAL_H) $(SPLAY_TREE_H) \
- $(C_PRAGMA_H) input.h intl.h $(FLAGS_H) toplev.h output.h \
+ $(C_PRAGMA_H) $(INPUT_H) intl.h $(FLAGS_H) $(TOPLEV_H) output.h \
$(CPPLIB_H) $(TARGET_H) $(TIMEVAR_H) $(TM_P_H)
c-ppoutput.o : c-ppoutput.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
- $(C_COMMON_H) $(TREE_H) $(CPPLIB_H) $(srcdir)/../libcpp/internal.h \
- $(C_PRAGMA_H)
+ $(C_COMMON_H) $(TREE_H) $(CPPLIB_H) $(CPP_INTERNAL_H) $(C_PRAGMA_H)
c-objc-common.o : c-objc-common.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TM_H) $(TREE_H) $(C_TREE_H) $(RTL_H) insn-config.h $(INTEGRATE_H) \
- $(FUNCTION_H) $(FLAGS_H) toplev.h $(TREE_INLINE_H) $(DIAGNOSTIC_H) $(VARRAY_H) \
+ $(FUNCTION_H) $(FLAGS_H) $(TOPLEV_H) $(TREE_INLINE_H) $(DIAGNOSTIC_H) $(VARRAY_H) \
langhooks.h $(GGC_H) $(TARGET_H) $(C_PRETTY_PRINT_H) c-objc-common.h \
tree-mudflap.h
c-aux-info.o : c-aux-info.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
- $(C_TREE_H) $(FLAGS_H) toplev.h
+ $(C_TREE_H) $(FLAGS_H) $(TOPLEV_H)
c-convert.o : c-convert.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
- $(TREE_H) $(FLAGS_H) toplev.h $(C_COMMON_H) convert.h $(C_TREE_H) \
+ $(TREE_H) $(FLAGS_H) $(TOPLEV_H) $(C_COMMON_H) convert.h $(C_TREE_H) \
langhooks.h $(TARGET_H)
c-pragma.o: c-pragma.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
- $(TREE_H) $(FUNCTION_H) $(C_PRAGMA_H) toplev.h output.h $(GGC_H) $(TM_P_H) \
- $(C_COMMON_H) $(TARGET_H) gt-c-pragma.h $(CPPLIB_H) $(FLAGS_H)
-graph.o: graph.c $(SYSTEM_H) coretypes.h $(TM_H) toplev.h $(FLAGS_H) output.h \
- $(RTL_H) $(FUNCTION_H) hard-reg-set.h $(BASIC_BLOCK_H) graph.h $(OBSTACK_H)
+ $(TREE_H) $(FUNCTION_H) $(C_PRAGMA_H) $(TOPLEV_H) output.h $(GGC_H) $(TM_P_H) \
+ $(C_COMMON_H) $(TARGET_H) gt-c-pragma.h $(CPPLIB_H) $(FLAGS_H) $(DIAGNOSTIC_H) \
+ opts.h
+graph.o: graph.c $(SYSTEM_H) coretypes.h $(TM_H) $(TOPLEV_H) $(FLAGS_H) output.h \
+ $(RTL_H) $(FUNCTION_H) hard-reg-set.h $(BASIC_BLOCK_H) graph.h $(OBSTACK_H) \
+ $(CONFIG_H)
sbitmap.o: sbitmap.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(FLAGS_H) hard-reg-set.h $(BASIC_BLOCK_H) $(OBSTACK_H)
ebitmap.o: ebitmap.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
- $(EBITMAP_H)
-sparseset.o: sparseset.c $(SYSTEM_H) sparseset.h
+ $(EBITMAP_H) $(RTL_H) $(FLAGS_H) $(OBSTACK_H)
+sparseset.o: sparseset.c $(SYSTEM_H) sparseset.h $(CONFIG_H)
COLLECT2_OBJS = collect2.o tlink.o intl.o version.o
COLLECT2_LIBS = @COLLECT2_LIBS@
@@ -1839,26 +1866,28 @@ tlink.o: tlink.c $(DEMANGLE_H) $(HASHTAB_H) $(CONFIG_H) $(SYSTEM_H) coretypes.h
# A file used by all variants of C.
c-common.o : c-common.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
- $(OBSTACK_H) $(C_COMMON_H) $(FLAGS_H) toplev.h output.h $(C_PRAGMA_H) \
+ $(OBSTACK_H) $(C_COMMON_H) $(FLAGS_H) $(TOPLEV_H) output.h $(C_PRAGMA_H) \
$(GGC_H) $(EXPR_H) $(TM_P_H) builtin-types.def builtin-attrs.def \
$(DIAGNOSTIC_H) gt-c-common.h langhooks.h $(VARRAY_H) $(RTL_H) \
$(TARGET_H) $(C_TREE_H) tree-iterator.h langhooks.h tree-mudflap.h \
intl.h opts.h $(REAL_H) $(CPPLIB_H) $(TREE_INLINE_H) $(HASHTAB_H) \
- $(BUILTINS_DEF)
+ $(BUILTINS_DEF) $(CGRAPH_H) $(BASIC_BLOCK_H) $(TARGET_DEF_H) \
+ $(GIMPLE_H)
c-pretty-print.o : c-pretty-print.c $(C_PRETTY_PRINT_H) \
$(C_TREE_H) $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(REAL_H) \
$(DIAGNOSTIC_H) tree-iterator.h fixed-value.h
c-opts.o : c-opts.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
- $(TREE_H) $(C_PRAGMA_H) $(FLAGS_H) toplev.h langhooks.h \
+ $(TREE_H) $(C_PRAGMA_H) $(FLAGS_H) $(TOPLEV_H) langhooks.h \
$(TREE_INLINE_H) $(DIAGNOSTIC_H) intl.h debug.h $(C_COMMON_H) \
- opts.h options.h $(MKDEPS_H) incpath.h cppdefault.h $(TM_P_H)
+ opts.h options.h $(MKDEPS_H) incpath.h cppdefault.h $(TARGET_H) \
+ $(TM_P_H) $(VARRAY_H)
$(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) \
$< $(OUTPUT_OPTION) @TARGET_SYSTEM_ROOT_DEFINE@
c-cppbuiltin.o : c-cppbuiltin.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
- $(TREE_H) version.h $(C_COMMON_H) $(C_PRAGMA_H) $(FLAGS_H) toplev.h \
+ $(TREE_H) version.h $(C_COMMON_H) $(C_PRAGMA_H) $(FLAGS_H) $(TOPLEV_H) \
output.h except.h $(REAL_H) $(TARGET_H) $(TM_P_H) $(BASEVER)
$(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) -DBASEVER=$(BASEVER_s) \
$< $(OUTPUT_OPTION)
@@ -1866,31 +1895,32 @@ c-cppbuiltin.o : c-cppbuiltin.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
# A file used by all variants of C and some other languages.
attribs.o : attribs.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
- $(FLAGS_H) toplev.h output.h $(RTL_H) $(GGC_H) $(TM_P_H) \
+ $(FLAGS_H) $(TOPLEV_H) output.h $(RTL_H) $(GGC_H) $(TM_P_H) \
$(TARGET_H) langhooks.h $(CPPLIB_H)
c-format.o : c-format.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) langhooks.h \
- $(C_COMMON_H) $(FLAGS_H) toplev.h intl.h $(DIAGNOSTIC_H) alloc-pool.h \
+ $(C_COMMON_H) $(FLAGS_H) $(TOPLEV_H) intl.h $(DIAGNOSTIC_H) alloc-pool.h \
c-format.h
c-semantics.o : c-semantics.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
- $(TREE_H) $(FLAGS_H) toplev.h output.h $(RTL_H) $(GGC_H) \
+ $(TREE_H) $(FLAGS_H) $(TOPLEV_H) output.h $(RTL_H) $(GGC_H) \
$(PREDICT_H) $(TREE_INLINE_H) $(C_COMMON_H) except.h $(FUNCTION_H) \
- langhooks.h $(SPLAY_TREE_H) $(TIMEVAR_H) $(TREE_GIMPLE_H) \
- $(VARRAY_H)
+ langhooks.h $(SPLAY_TREE_H) $(TIMEVAR_H) $(GIMPLE_H) \
+ $(VARRAY_H) tree-iterator.h
c-dump.o : c-dump.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
$(C_TREE_H) $(TREE_DUMP_H)
c-pch.o : c-pch.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(CPPLIB_H) $(TREE_H) \
- $(C_COMMON_H) output.h toplev.h $(C_PRAGMA_H) $(GGC_H) debug.h \
- langhooks.h $(FLAGS_H) hosthooks.h version.h $(TARGET_H)
+ $(C_COMMON_H) output.h $(TOPLEV_H) $(C_PRAGMA_H) $(GGC_H) debug.h \
+ langhooks.h $(FLAGS_H) hosthooks.h version.h $(TARGET_H) opts.h
$(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) \
-DHOST_MACHINE=\"$(host)\" -DTARGET_MACHINE=\"$(target)\" \
$< $(OUTPUT_OPTION)
c-omp.o : c-omp.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
- $(FUNCTION_H) $(C_COMMON_H) toplev.h $(TREE_GIMPLE_H)
+ $(FUNCTION_H) $(C_COMMON_H) $(TOPLEV.H) $(GIMPLE_H) $(BITMAP_H) \
+ langhooks.h
# Language-independent files.
@@ -1947,7 +1977,8 @@ s-options-h: optionlist $(srcdir)/opt-functions.awk $(srcdir)/opth-gen.awk
$(SHELL) $(srcdir)/../move-if-change tmp-options.h options.h
$(STAMP) $@
-options.o: options.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) opts.h intl.h
+options.o: options.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TARGET_H) $(FLAGS_H) \
+ $(TM_H) opts.h intl.h
gcc-options.o: options.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) opts.h intl.h
$(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(OUTPUT_OPTION) -DGCC_DRIVER options.c
@@ -1966,20 +1997,22 @@ endif
-DBUGURL=$(BUGURL_s) -c $(srcdir)/version.c $(OUTPUT_OPTION)
gtype-desc.o: gtype-desc.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
- $(VARRAY_H) $(HASHTAB_H) $(SPLAY_TREE_H) bitmap.h $(TREE_H) $(RTL_H) \
- $(FUNCTION_H) insn-config.h $(EXPR_H) hard-reg-set.h $(BASIC_BLOCK_H) \
- cselib.h insn-addr.h $(OPTABS_H) libfuncs.h debug.h $(GGC_H) \
- $(CGRAPH_H) $(TREE_FLOW_H) reload.h $(CPP_ID_DATA_H)
+ $(VARRAY_H) $(HASHTAB_H) $(SPLAY_TREE_H) $(OBSTACK_H) $(BITMAP_H) \
+ input.h $(TREE_H) $(RTL_H) $(FUNCTION_H) insn-config.h $(EXPR_H) \
+ hard-reg-set.h $(BASIC_BLOCK_H) cselib.h $(INSN_ADDR_H) $(OPTABS_H) \
+ libfuncs.h debug.h $(GGC_H) $(CGRAPH_H) $(TREE_FLOW_H) reload.h \
+ $(CPP_ID_DATA_H) tree-chrec.h $(CFGLAYOUT_H) except.h output.h \
+ $(CFGLOOP_H)
ggc-common.o: ggc-common.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(GGC_H) \
- $(HASHTAB_H) toplev.h $(PARAMS_H) hosthooks.h $(HOSTHOOKS_DEF_H)
+ $(HASHTAB_H) $(TOPLEV_H) $(PARAMS_H) hosthooks.h $(HOSTHOOKS_DEF_H)
ggc-page.o: ggc-page.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) \
- $(FLAGS_H) toplev.h $(GGC_H) $(TIMEVAR_H) $(TM_P_H) $(PARAMS_H) $(TREE_FLOW_H)
+ $(FLAGS_H) $(TOPLEV_H) $(GGC_H) $(TIMEVAR_H) $(TM_P_H) $(PARAMS_H) $(TREE_FLOW_H)
ggc-zone.o: ggc-zone.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
- $(TREE_H) $(FLAGS_H) toplev.h $(GGC_H) $(TIMEVAR_H) $(TM_P_H) \
- $(PARAMS_H) bitmap.h $(VARRAY_H)
+ $(TREE_H) $(FLAGS_H) $(TOPLEV_H) $(GGC_H) $(TIMEVAR_H) $(TM_P_H) \
+ $(PARAMS_H) $(BITMAP_H) $(VARRAY_H)
ggc-none.o: ggc-none.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(GGC_H) \
$(BCONFIG_H)
@@ -1994,59 +2027,63 @@ prefix.o: prefix.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) prefix.h \
-c $(srcdir)/prefix.c $(OUTPUT_OPTION)
convert.o: convert.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
- $(FLAGS_H) convert.h toplev.h langhooks.h $(REAL_H) fixed-value.h
+ $(FLAGS_H) convert.h $(TOPLEV_H) langhooks.h $(REAL_H) fixed-value.h
double-int.o: double-int.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H)
langhooks.o : langhooks.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
- $(TREE_H) toplev.h $(TREE_INLINE_H) $(RTL_H) insn-config.h $(INTEGRATE_H) \
- langhooks.h $(LANGHOOKS_DEF_H) $(FLAGS_H) $(GGC_H) $(DIAGNOSTIC_H) intl.h \
- $(TREE_GIMPLE_H)
+ $(TREE_H) $(TOPLEV_H) $(TREE_INLINE_H) $(RTL_H) insn-config.h $(INTEGRATE_H) \
+ langhooks.h $(TARGET_H) $(LANGHOOKS_DEF_H) $(FLAGS_H) $(GGC_H) $(DIAGNOSTIC_H) \
+ intl.h $(GIMPLE_H)
tree.o : tree.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
all-tree.def $(FLAGS_H) $(FUNCTION_H) $(PARAMS_H) \
- toplev.h $(GGC_H) $(HASHTAB_H) $(TARGET_H) output.h $(TM_P_H) langhooks.h \
+ $(TOPLEV_H) $(GGC_H) $(HASHTAB_H) $(TARGET_H) output.h $(TM_P_H) langhooks.h \
$(REAL_H) gt-tree.h tree-iterator.h $(BASIC_BLOCK_H) $(TREE_FLOW_H) \
$(OBSTACK_H) pointer-set.h fixed-value.h
tree-dump.o: tree-dump.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
- $(TREE_H) langhooks.h toplev.h $(SPLAY_TREE_H) $(TREE_DUMP_H) \
+ $(TREE_H) langhooks.h $(TOPLEV_H) $(SPLAY_TREE_H) $(TREE_DUMP_H) \
tree-iterator.h tree-pass.h $(DIAGNOSTIC_H) $(REAL_H) fixed-value.h
tree-inline.o : tree-inline.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
- $(TREE_H) $(RTL_H) $(EXPR_H) $(FLAGS_H) $(PARAMS_H) input.h insn-config.h \
- $(VARRAY_H) $(HASHTAB_H) $(SPLAY_TREE_H) toplev.h \
- langhooks.h $(TREE_INLINE_H) $(CGRAPH_H) intl.h $(FUNCTION_H) $(TREE_GIMPLE_H) \
- debug.h $(DIAGNOSTIC_H) $(TREE_FLOW_H) tree-iterator.h tree-mudflap.h \
- ipa-prop.h value-prof.h $(TARGET_H) $(INTEGRATE_H)
+ $(TREE_H) $(RTL_H) $(EXPR_H) $(FLAGS_H) $(PARAMS_H) $(INPUT_H) insn-config.h \
+ $(VARRAY_H) $(HASHTAB_H) $(TOPLEV_H) langhooks.h $(TREE_INLINE_H) $(CGRAPH_H) \
+ intl.h $(FUNCTION_H) $(GGC_H) $(GIMPLE_H) \
+ debug.h $(DIAGNOSTIC_H) except.h $(TREE_FLOW_H) tree-iterator.h tree-mudflap.h \
+ $(IPA_PROP_H) value-prof.h tree-pass.h $(TARGET_H) $(INTEGRATE_H)
print-tree.o : print-tree.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
- $(GGC_H) langhooks.h $(REAL_H) tree-iterator.h fixed-value.h $(TREE_FLOW_H)
+ $(GGC_H) langhooks.h $(REAL_H) tree-iterator.h fixed-value.h \
+ $(DIAGNOSTIC_H) $(TREE_FLOW_H)
stor-layout.o : stor-layout.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
- $(TREE_H) $(PARAMS_H) $(FLAGS_H) $(FUNCTION_H) $(EXPR_H) $(RTL_H) \
+ $(TREE_H) $(PARAMS_H) $(FLAGS_H) $(FUNCTION_H) $(EXPR_H) output.h $(RTL_H) \
$(GGC_H) $(TM_P_H) $(TARGET_H) langhooks.h $(REGS_H) gt-stor-layout.h \
- toplev.h
+ $(TOPLEV_H)
tree-ssa-structalias.o: tree-ssa-structalias.c tree-ssa-structalias.h \
- $(SYSTEM_H) $(CONFIG_H) $(GGC_H) $(TREE_H) $(TREE_FLOW_H) \
- $(TM_H) coretypes.h $(CGRAPH_H) tree-pass.h $(TIMEVAR_H) \
- gt-tree-ssa-structalias.h $(PARAMS_H) $(ALIAS_H) pointer-set.h $(FUNCTION_H)
+ $(SYSTEM_H) $(CONFIG_H) coretypes.h $(TM_H) $(GGC_H) $(OBSTACK_H) $(BITMAP_H) \
+ $(FLAGS_H) $(RTL_H) $(TM_P_H) hard-reg-set.h $(BASIC_BLOCK_H) output.h errors.h \
+ $(DIAGNOSTIC_H) $(TREE_H) $(C_COMMON_H) $(TREE_FLOW_H) $(TREE_INLINE_H) varray.h \
+ $(C_TREE_H) $(GIMPLE_H) $(HASHTAB_H) $(FUNCTION_H) $(CGRAPH_H) tree-pass.h \
+ $(TIMEVAR_H) alloc-pool.h $(SPLAY_TREE_H) $(PARAMS_H) gt-tree-ssa-structalias.h \
+ $(CGRAPH_H) $(ALIAS_H) pointer-set.h
tree-ssa.o : tree-ssa.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
$(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) output.h $(DIAGNOSTIC_H) \
- toplev.h $(FUNCTION_H) $(TIMEVAR_H) $(TM_H) coretypes.h \
- $(TREE_DUMP_H) langhooks.h tree-pass.h $(BASIC_BLOCK_H) bitmap.h \
+ $(TOPLEV_H) $(FUNCTION_H) $(TIMEVAR_H) $(TM_H) coretypes.h \
+ $(TREE_DUMP_H) langhooks.h tree-pass.h $(BASIC_BLOCK_H) $(BITMAP_H) \
$(FLAGS_H) $(GGC_H) hard-reg-set.h $(HASHTAB_H) pointer-set.h \
- $(TREE_GIMPLE_H) $(TREE_INLINE_H) $(VARRAY_H)
+ $(GIMPLE_H) $(TREE_INLINE_H) $(VARRAY_H)
tree-into-ssa.o : tree-into-ssa.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
$(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) output.h $(DIAGNOSTIC_H) \
$(FUNCTION_H) $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) \
langhooks.h domwalk.h tree-pass.h $(GGC_H) $(PARAMS_H) $(BASIC_BLOCK_H) \
- bitmap.h $(CFGLOOP_H) $(FLAGS_H) hard-reg-set.h $(HASHTAB_H) \
- $(TREE_GIMPLE_H) $(TREE_INLINE_H) $(VARRAY_H) vecprim.h
+ $(BITMAP_H) $(CFGLOOP_H) $(FLAGS_H) hard-reg-set.h $(HASHTAB_H) \
+ $(GIMPLE_H) $(TREE_INLINE_H) $(VARRAY_H) vecprim.h
tree-ssa-ter.o : tree-ssa-ter.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
$(TREE_H) $(DIAGNOSTIC_H) $(TM_H) coretypes.h $(TREE_DUMP_H) \
- $(TREE_SSA_LIVE_H) bitmap.h
+ $(TREE_SSA_LIVE_H) $(BITMAP_H)
tree-ssa-coalesce.o : tree-ssa-coalesce.c $(TREE_FLOW_H) $(CONFIG_H) \
$(SYSTEM_H) $(TREE_H) $(DIAGNOSTIC_H) $(TM_H) coretypes.h $(TREE_DUMP_H) \
- $(TREE_SSA_LIVE_H) bitmap.h $(FLAGS_H) $(HASHTAB_H) toplev.h
+ $(TREE_SSA_LIVE_H) $(BITMAP_H) $(FLAGS_H) $(HASHTAB_H) $(TOPLEV_H)
tree-outof-ssa.o : tree-outof-ssa.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
$(TREE_H) $(DIAGNOSTIC_H) $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) \
- tree-pass.h $(TREE_SSA_LIVE_H) $(BASIC_BLOCK_H) bitmap.h $(GGC_H) toplev.h
+ tree-pass.h $(TREE_SSA_LIVE_H) $(BASIC_BLOCK_H) $(BITMAP_H) $(GGC_H) $(TOPLEV_H)
tree-ssa-dse.o : tree-ssa-dse.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TM_H) $(GGC_H) $(TREE_H) $(RTL_H) $(TM_P_H) $(BASIC_BLOCK_H) \
$(TREE_FLOW_H) tree-pass.h $(TREE_DUMP_H) domwalk.h $(FLAGS_H) \
@@ -2054,7 +2091,7 @@ tree-ssa-dse.o : tree-ssa-dse.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
tree-ssa-forwprop.o : tree-ssa-forwprop.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TM_H) $(GGC_H) $(TREE_H) $(RTL_H) $(TM_P_H) $(BASIC_BLOCK_H) \
$(TREE_FLOW_H) tree-pass.h $(TREE_DUMP_H) $(DIAGNOSTIC_H) $(TIMEVAR_H) \
- langhooks.h $(FLAGS_H)
+ langhooks.h $(FLAGS_H) $(GIMPLE_H)
tree-ssa-phiprop.o : tree-ssa-phiprop.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TM_H) $(GGC_H) $(TREE_H) $(RTL_H) $(TM_P_H) $(BASIC_BLOCK_H) \
$(TREE_FLOW_H) tree-pass.h $(TREE_DUMP_H) $(DIAGNOSTIC_H) $(TIMEVAR_H) \
@@ -2065,7 +2102,7 @@ tree-ssa-ifcombine.o : tree-ssa-ifcombine.c $(CONFIG_H) $(SYSTEM_H) \
tree-ssa-phiopt.o : tree-ssa-phiopt.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TM_H) $(GGC_H) $(TREE_H) $(RTL_H) $(TM_P_H) $(BASIC_BLOCK_H) \
$(TREE_FLOW_H) tree-pass.h $(TREE_DUMP_H) langhooks.h $(FLAGS_H) \
- $(DIAGNOSTIC_H) $(TIMEVAR_H)
+ $(DIAGNOSTIC_H) $(TIMEVAR_H) pointer-set.h domwalk.h
tree-nrv.o : tree-nrv.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TM_H) $(TREE_H) $(RTL_H) $(FUNCTION_H) $(BASIC_BLOCK_H) $(EXPR_H) \
$(DIAGNOSTIC_H) $(TREE_FLOW_H) $(TIMEVAR_H) $(TREE_DUMP_H) tree-pass.h \
@@ -2078,7 +2115,8 @@ tree-ssa-propagate.o : tree-ssa-propagate.c $(TREE_FLOW_H) $(CONFIG_H) \
$(SYSTEM_H) $(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) $(GGC_H) output.h \
$(DIAGNOSTIC_H) $(FUNCTION_H) $(TIMEVAR_H) $(TM_H) coretypes.h \
$(TREE_DUMP_H) $(BASIC_BLOCK_H) tree-pass.h langhooks.h \
- tree-ssa-propagate.h vec.h gt-tree-ssa-propagate.h $(FLAGS_H) $(VARRAY_H)
+ tree-ssa-propagate.h vec.h value-prof.h gt-tree-ssa-propagate.h $(FLAGS_H) \
+ $(VARRAY_H) $(GIMPLE_H)
tree-ssa-dom.o : tree-ssa-dom.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
$(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) $(GGC_H) output.h $(DIAGNOSTIC_H) \
$(FUNCTION_H) $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) \
@@ -2090,9 +2128,10 @@ tree-ssa-uncprop.o : tree-ssa-uncprop.c $(TREE_FLOW_H) $(CONFIG_H) \
$(TREE_DUMP_H) $(BASIC_BLOCK_H) domwalk.h tree-pass.h $(FLAGS_H) \
langhooks.h tree-ssa-propagate.h $(REAL_H)
tree-ssa-threadedge.o : tree-ssa-threadedge.c $(TREE_FLOW_H) $(CONFIG_H) \
- $(SYSTEM_H) $(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) $(GGC_H) output.h \
- $(DIAGNOSTIC_H) $(FUNCTION_H) $(TM_H) coretypes.h $(TREE_DUMP_H) \
- $(BASIC_BLOCK_H) $(FLAGS_H) tree-pass.h $(CFGLOOP_H)
+ $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) $(FLAGS_H) $(RTL_H) $(TM_P_H) $(GGC_H) \
+ $(BASIC_BLOCK_H) $(CFGLOOP_H) output.h $(EXPR_H) \
+ $(FUNCTION_H) $(DIAGNOSTIC_H) $(TIMEVAR_H) $(TREE_DUMP_H) $(TREE_FLOW_H) \
+ domwalk.h $(REAL_H) tree-pass.h tree-ssa-propagate.h langhooks.h $(PARAMS_H)
tree-ssa-threadupdate.o : tree-ssa-threadupdate.c $(TREE_FLOW_H) $(CONFIG_H) \
$(SYSTEM_H) $(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) $(GGC_H) output.h \
$(DIAGNOSTIC_H) $(FUNCTION_H) $(TM_H) coretypes.h $(TREE_DUMP_H) \
@@ -2101,63 +2140,61 @@ tree-ssanames.o : tree-ssanames.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TM_H) $(TREE_H) $(VARRAY_H) $(GGC_H) $(TREE_FLOW_H)
tree-phinodes.o : tree-phinodes.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TM_H) $(TREE_H) $(VARRAY_H) $(GGC_H) $(BASIC_BLOCK_H) $(TREE_FLOW_H) \
- gt-tree-phinodes.h $(RTL_H) toplev.h
+ gt-tree-phinodes.h $(RTL_H) $(TOPLEV.H) $(GIMPLE_H)
domwalk.o : domwalk.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(TREE_H) $(BASIC_BLOCK_H) $(TREE_FLOW_H) domwalk.h $(GGC_H)
tree-ssa-live.o : tree-ssa-live.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
$(TREE_H) $(DIAGNOSTIC_H) $(TM_H) coretypes.h $(TREE_DUMP_H) \
- $(TREE_SSA_LIVE_H) bitmap.h toplev.h
+ $(TREE_SSA_LIVE_H) $(BITMAP_H) $(TOPLEV_H) debug.h $(FLAGS_H)
tree-ssa-copyrename.o : tree-ssa-copyrename.c $(TREE_FLOW_H) $(CONFIG_H) \
$(SYSTEM_H) $(TREE_H) $(DIAGNOSTIC_H) $(FUNCTION_H) $(TIMEVAR_H) tree-pass.h \
$(TM_H) coretypes.h $(TREE_DUMP_H) $(TREE_SSA_LIVE_H) $(BASIC_BLOCK_H) \
- bitmap.h $(FLAGS_H) $(HASHTAB_H) langhooks.h $(TREE_GIMPLE_H) \
- $(TREE_INLINE_H)
+ $(BITMAP_H) $(FLAGS_H) $(HASHTAB_H) langhooks.h $(GIMPLE_H) \
+ $(TREE_INLINE_H) $(GIMPLE_H)
tree-ssa-pre.o : tree-ssa-pre.c $(TREE_FLOW_H) $(CONFIG_H) \
- $(SYSTEM_H) $(TREE_H) $(GGC_H) $(DIAGNOSTIC_H) $(TIMEVAR_H) \
- $(TM_H) coretypes.h $(TREE_DUMP_H) tree-pass.h $(FLAGS_H) $(CFGLOOP_H) \
- alloc-pool.h $(BASIC_BLOCK_H) bitmap.h $(HASHTAB_H) $(TREE_GIMPLE_H) \
- $(TREE_INLINE_H) tree-iterator.h tree-ssa-sccvn.h $(PARAMS_H)
+ $(SYSTEM_H) $(TREE_H) $(GGC_H) $(DIAGNOSTIC_H) $(TIMEVAR_H) $(FIBHEAP_H) \
+ $(TM_H) coretypes.h $(TREE_DUMP_H) tree-pass.h $(FLAGS_H) langhooks.h $(CFGLOOP_H) \
+ alloc-pool.h $(BASIC_BLOCK_H) $(BITMAP_H) $(HASHTAB_H) $(GIMPLE_H) \
+ $(TREE_INLINE_H) tree-iterator.h tree-ssa-sccvn.h $(PARAMS_H) \
+ $(DBGCNT_H)
tree-ssa-sccvn.o : tree-ssa-sccvn.c $(TREE_FLOW_H) $(CONFIG_H) \
- $(SYSTEM_H) $(TREE_H) $(GGC_H) $(DIAGNOSTIC_H) $(TIMEVAR_H) \
+ $(SYSTEM_H) $(TREE_H) $(GGC_H) $(DIAGNOSTIC_H) $(TIMEVAR_H) $(FIBHEAP_H) \
$(TM_H) coretypes.h $(TREE_DUMP_H) tree-pass.h $(FLAGS_H) $(CFGLOOP_H) \
- alloc-pool.h $(BASIC_BLOCK_H) bitmap.h $(HASHTAB_H) $(TREE_GIMPLE_H) \
+ alloc-pool.h $(BASIC_BLOCK_H) $(BITMAP_H) langhooks.h $(HASHTAB_H) $(GIMPLE_H) \
$(TREE_INLINE_H) tree-iterator.h tree-ssa-propagate.h tree-ssa-sccvn.h \
$(PARAMS_H)
-tree-vn.o : tree-vn.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(GGC_H) \
- $(TREE_H) $(TREE_FLOW_H) $(HASHTAB_H) langhooks.h tree-pass.h \
- $(TREE_DUMP_H) $(DIAGNOSTIC_H) tree-ssa-sccvn.h
tree-vrp.o : tree-vrp.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
$(TREE_FLOW_H) tree-pass.h $(TREE_DUMP_H) $(DIAGNOSTIC_H) $(GGC_H) \
$(BASIC_BLOCK_H) tree-ssa-propagate.h $(FLAGS_H) $(TREE_DUMP_H) \
- $(CFGLOOP_H) $(SCEV_H) tree-chrec.h $(TIMEVAR_H) toplev.h intl.h
+ $(CFGLOOP_H) tree-chrec.h $(TIMEVAR_H) $(TOPLEV_H) intl.h
tree-cfg.o : tree-cfg.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
$(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) $(GGC_H) $(FLAGS_H) output.h \
$(DIAGNOSTIC_H) $(FUNCTION_H) $(TIMEVAR_H) $(TM_H) coretypes.h \
$(TREE_DUMP_H) except.h langhooks.h $(CFGLOOP_H) tree-pass.h \
- $(CFGLAYOUT_H) $(BASIC_BLOCK_H) hard-reg-set.h toplev.h \
- tree-ssa-propagate.h $(TREE_INLINE_H)
+ $(CFGLAYOUT_H) $(BASIC_BLOCK_H) hard-reg-set.h $(TOPLEV_H) \
+ value-prof.h tree-ssa-propagate.h $(TREE_INLINE_H)
tree-cfgcleanup.o : tree-cfgcleanup.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
$(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) $(GGC_H) $(FLAGS_H) output.h \
- $(DIAGNOSTIC_H) toplev.h $(FUNCTION_H) $(TIMEVAR_H) $(TM_H) coretypes.h \
+ $(DIAGNOSTIC_H) $(TOPLEV_H) $(FUNCTION_H) $(TIMEVAR_H) $(TM_H) coretypes.h \
$(TREE_DUMP_H) except.h langhooks.h $(CFGLOOP_H) tree-pass.h \
- $(CFGLAYOUT_H) $(BASIC_BLOCK_H) hard-reg-set.h $(HASHTAB_H) toplev.h \
- tree-ssa-propagate.h
+ $(CFGLAYOUT_H) $(BASIC_BLOCK_H) hard-reg-set.h $(HASHTAB_H) $(TOPLEV_H) \
+ tree-ssa-propagate.h tree-scalar-evolution.h
rtl-factoring.o : rtl-factoring.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) \
- coretypes.h $(TM_H) $(BASIC_BLOCK_H) $(GGC_H) $(REGS_H) $(PARAMS_H) $(EXPR_H) \
- addresses.h $(TM_P_H) tree-pass.h $(TREE_FLOW_H) $(TIMEVAR_H) output.h \
- $(DF_H)
+ coretypes.h $(TM_H) $(BASIC_BLOCK_H) $(RESOURCE_H) $(GGC_H) $(REGS_H) \
+ $(PARAMS_H) $(EXPR_H) addresses.h $(TM_P_H) tree-pass.h $(TREE_FLOW_H) \
+ $(TIMEVAR_H) output.h $(DF_H)
tree-tailcall.o : tree-tailcall.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
$(RTL_H) $(TREE_H) $(TM_P_H) $(FUNCTION_H) $(TM_H) coretypes.h \
$(TREE_DUMP_H) $(DIAGNOSTIC_H) except.h tree-pass.h $(FLAGS_H) langhooks.h \
- $(BASIC_BLOCK_H) hard-reg-set.h
+ $(BASIC_BLOCK_H) hard-reg-set.h $(DBGCNT_H)
tree-ssa-sink.o : tree-ssa-sink.c $(TREE_FLOW_H) $(CONFIG_H) \
$(SYSTEM_H) $(TREE_H) $(GGC_H) $(DIAGNOSTIC_H) $(TIMEVAR_H) \
$(TM_H) coretypes.h $(TREE_DUMP_H) tree-pass.h $(FLAGS_H) alloc-pool.h \
- $(BASIC_BLOCK_H) bitmap.h $(CFGLOOP_H) $(FIBHEAP_H) $(HASHTAB_H) \
- langhooks.h $(REAL_H) $(TREE_GIMPLE_H) $(TREE_INLINE_H) tree-iterator.h
+ $(BASIC_BLOCK_H) $(BITMAP_H) $(CFGLOOP_H) $(FIBHEAP_H) $(HASHTAB_H) \
+ langhooks.h $(REAL_H) $(GIMPLE_H) $(TREE_INLINE_H) tree-iterator.h
tree-nested.o: tree-nested.c $(CONFIG_H) $(SYSTEM_H) $(TM_H) $(TREE_H) \
$(RTL_H) $(TM_P_H) $(FUNCTION_H) $(TREE_DUMP_H) $(TREE_INLINE_H) \
- tree-iterator.h $(TREE_GIMPLE_H) $(CGRAPH_H) $(EXPR_H) langhooks.h \
+ tree-iterator.h $(GIMPLE_H) $(CGRAPH_H) $(EXPR_H) langhooks.h \
$(GGC_H) gt-tree-nested.h coretypes.h $(TREE_FLOW_H) pointer-set.h
tree-if-conv.o: tree-if-conv.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(TREE_H) $(FLAGS_H) $(TIMEVAR_H) $(BASIC_BLOCK_H) $(TREE_FLOW_H) \
@@ -2165,26 +2202,25 @@ tree-if-conv.o: tree-if-conv.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(SCEV_H) tree-pass.h $(DIAGNOSTIC_H) $(TARGET_H) $(TREE_DUMP_H) \
$(VARRAY_H)
tree-iterator.o : tree-iterator.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) \
- coretypes.h $(GGC_H) tree-iterator.h $(TREE_GIMPLE_H) gt-tree-iterator.h
+ coretypes.h $(GGC_H) tree-iterator.h $(GIMPLE_H) gt-tree-iterator.h
tree-dfa.o : tree-dfa.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
$(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) $(GGC_H) output.h $(DIAGNOSTIC_H) \
$(TREE_INLINE_H) $(HASHTAB_H) pointer-set.h $(FLAGS_H) $(FUNCTION_H) \
$(TIMEVAR_H) convert.h $(TM_H) coretypes.h langhooks.h $(TREE_DUMP_H) \
tree-pass.h $(PARAMS_H) $(CGRAPH_H) $(BASIC_BLOCK_H) hard-reg-set.h \
- $(TREE_GIMPLE_H)
+ $(GIMPLE_H)
tree-ssa-operands.o : tree-ssa-operands.c $(TREE_FLOW_H) $(CONFIG_H) \
- $(SYSTEM_H) $(TREE_H) $(GGC_H) $(DIAGNOSTIC_H) errors.h $(TREE_INLINE_H) \
- $(FLAGS_H) $(FUNCTION_H) $(TM_H) $(TIMEVAR_H) tree-pass.h toplev.h \
+ $(SYSTEM_H) $(TREE_H) $(GGC_H) $(DIAGNOSTIC_H) $(TREE_INLINE_H) \
+ $(FLAGS_H) $(FUNCTION_H) $(TM_H) $(TIMEVAR_H) tree-pass.h $(TOPLEV_H) \
coretypes.h langhooks.h $(IPA_REFERENCE_H)
tree-eh.o : tree-eh.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
$(RTL_H) $(TREE_H) $(TM_H) $(FLAGS_H) $(FUNCTION_H) except.h langhooks.h \
$(GGC_H) tree-pass.h coretypes.h $(TIMEVAR_H) $(TM_P_H) pointer-set.h \
- $(TREE_DUMP_H) $(TREE_INLINE_H) tree-iterator.h toplev.h
-tree-ssa-loop.o : tree-ssa-loop.c $(TREE_FLOW_H) $(CONFIG_H) \
- $(SYSTEM_H) $(RTL_H) $(TREE_H) $(TM_P_H) $(CFGLOOP_H) \
- output.h $(DIAGNOSTIC_H) $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) \
- tree-pass.h $(FLAGS_H) $(TREE_INLINE_H) $(SCEV_H) $(BASIC_BLOCK_H) \
- hard-reg-set.h
+ $(TREE_DUMP_H) $(TREE_INLINE_H) tree-iterator.h $(TOPLEV_H)
+tree-ssa-loop.o : tree-ssa-loop.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
+ $(TREE_H) $(RTL_H) $(TM_P_H) hard-reg-set.h $(BASIC_BLOCK_H) output.h \
+ $(DIAGNOSTIC_H) $(TREE_FLOW_H) $(TREE_DUMP_H) tree-pass.h $(TIMEVAR_H) \
+ $(CFGLOOP_H) $(FLAGS_H) $(TREE_INLINE_H) tree-scalar-evolution.h
tree-ssa-loop-unswitch.o : tree-ssa-loop-unswitch.c $(TREE_FLOW_H) \
$(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) $(TM_P_H) $(CFGLOOP_H) \
domwalk.h $(PARAMS_H) output.h $(DIAGNOSTIC_H) $(TIMEVAR_H) $(TM_H) \
@@ -2198,7 +2234,7 @@ tree-ssa-address.o : tree-ssa-address.c $(TREE_FLOW_H) $(CONFIG_H) \
tree-ssa-loop-niter.o : tree-ssa-loop-niter.c $(TREE_FLOW_H) $(CONFIG_H) \
$(SYSTEM_H) $(RTL_H) $(TREE_H) $(TM_P_H) $(CFGLOOP_H) $(PARAMS_H) \
$(TREE_INLINE_H) output.h $(DIAGNOSTIC_H) $(TM_H) coretypes.h $(TREE_DUMP_H) \
- $(FLAGS_H) tree-pass.h $(SCEV_H) $(TREE_DATA_REF_H) $(BASIC_BLOCK_H) \
+ $(TOPLEV_H) $(FLAGS_H) tree-pass.h $(SCEV_H) $(TREE_DATA_REF_H) $(BASIC_BLOCK_H) \
$(GGC_H) hard-reg-set.h tree-chrec.h intl.h
tree-ssa-loop-ivcanon.o : tree-ssa-loop-ivcanon.c $(TREE_FLOW_H) $(CONFIG_H) \
$(SYSTEM_H) $(RTL_H) $(TREE_H) $(TM_P_H) $(CFGLOOP_H) $(PARAMS_H) \
@@ -2214,12 +2250,12 @@ tree-ssa-loop-prefetch.o: tree-ssa-loop-prefetch.c $(TREE_FLOW_H) $(CONFIG_H) \
output.h $(DIAGNOSTIC_H) $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) \
tree-pass.h $(GGC_H) $(RECOG_H) insn-config.h $(HASHTAB_H) $(SCEV_H) \
$(CFGLOOP_H) $(PARAMS_H) langhooks.h $(BASIC_BLOCK_H) hard-reg-set.h \
- tree-chrec.h toplev.h langhooks.h $(TREE_INLINE_H) $(TREE_DATA_REF_H) \
+ tree-chrec.h $(TOPLEV_H) langhooks.h $(TREE_INLINE_H) $(TREE_DATA_REF_H) \
$(OPTABS_H)
tree-predcom.o: tree-predcom.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(TM_P_H) \
$(CFGLOOP_H) $(TREE_FLOW_H) $(GGC_H) $(TREE_DATA_REF_H) $(SCEV_H) \
$(PARAMS_H) $(DIAGNOSTIC_H) tree-pass.h $(TM_H) coretypes.h tree-affine.h \
- tree-inline.h
+ $(TREE_INLINE_H)
tree-ssa-loop-ivopts.o : tree-ssa-loop-ivopts.c $(TREE_FLOW_H) $(CONFIG_H) \
$(SYSTEM_H) $(RTL_H) $(TREE_H) $(TM_P_H) $(CFGLOOP_H) $(EXPR_H) \
output.h $(DIAGNOSTIC_H) $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) \
@@ -2227,68 +2263,72 @@ tree-ssa-loop-ivopts.o : tree-ssa-loop-ivopts.c $(TREE_FLOW_H) $(CONFIG_H) \
$(CFGLOOP_H) $(PARAMS_H) langhooks.h $(BASIC_BLOCK_H) hard-reg-set.h \
tree-chrec.h $(VARRAY_H) tree-affine.h pointer-set.h $(TARGET_H)
tree-affine.o : tree-affine.c tree-affine.h $(CONFIG_H) pointer-set.h \
- $(SYSTEM_H) $(RTL_H) $(TREE_H) $(TM_P_H) $(TREE_GIMPLE_H) \
+ $(SYSTEM_H) $(RTL_H) $(TREE_H) $(TM_P_H) hard-reg-set.h $(GIMPLE_H) \
output.h $(DIAGNOSTIC_H) $(TM_H) coretypes.h $(TREE_DUMP_H) $(FLAGS_H)
tree-ssa-loop-manip.o : tree-ssa-loop-manip.c $(TREE_FLOW_H) $(CONFIG_H) \
- $(SYSTEM_H) $(RTL_H) $(TREE_H) $(TM_P_H) $(CFGLOOP_H) \
- output.h $(DIAGNOSTIC_H) $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) \
- tree-pass.h $(CFGLAYOUT_H) $(SCEV_H) $(BASIC_BLOCK_H) hard-reg-set.h \
+ $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) $(RTL_H) $(TM_P_H) hard-reg-set.h \
+ $(BASIC_BLOCK_H) output.h $(DIAGNOSTIC_H) $(TREE_FLOW_H) $(TREE_DUMP_H) \
+ $(TIMEVAR_H) $(CFGLOOP_H) tree-pass.h $(CFGLAYOUT_H) tree-scalar-evolution.h \
$(PARAMS_H) $(TREE_INLINE_H)
tree-ssa-loop-im.o : tree-ssa-loop-im.c $(TREE_FLOW_H) $(CONFIG_H) \
$(SYSTEM_H) $(RTL_H) $(TREE_H) $(TM_P_H) $(CFGLOOP_H) domwalk.h \
$(PARAMS_H) output.h $(DIAGNOSTIC_H) $(TIMEVAR_H) $(TM_H) coretypes.h \
$(TREE_DUMP_H) tree-pass.h $(FLAGS_H) $(REAL_H) $(BASIC_BLOCK_H) \
- hard-reg-set.h tree-ssa-propagate.h
-tree-ssa-math-opts.o : tree-ssa-math-opts.c $(TREE_FLOW_H) $(CONFIG_H) \
- $(SYSTEM_H) $(TREE_H) $(TIMEVAR_H) tree-pass.h $(TM_H) $(FLAGS_H) \
+ hard-reg-set.h pointer-set.h tree-affine.h tree-ssa-propagate.h
+tree-ssa-math-opts.o : tree-ssa-math-opts.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
+ $(TM_H) $(FLAGS_H) $(TREE_H) $(TREE_FLOW_H) $(REAL_H) $(TIMEVAR_H) tree-pass.h \
alloc-pool.h $(BASIC_BLOCK_H) $(TARGET_H)
tree-ssa-alias-warnings.o : tree-ssa-alias-warnings.c \
$(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) $(TREE_DUMP_H) \
- $(TREE_FLOW_H) $(PARAMS_H) $(FUNCTION_H) $(EXPR_H) toplev.h \
+ $(TREE_FLOW_H) $(PARAMS_H) $(FUNCTION_H) $(EXPR_H) $(TOPLEV_H) \
tree-ssa-structalias.h tree-ssa-propagate.h langhooks.h alloc-pool.h \
$(DIAGNOSTIC_H)
tree-ssa-alias.o : tree-ssa-alias.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
$(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) $(GGC_H) $(TREE_INLINE_H) $(FLAGS_H) \
$(FUNCTION_H) $(TIMEVAR_H) convert.h $(TM_H) coretypes.h langhooks.h \
$(TREE_DUMP_H) tree-pass.h $(PARAMS_H) $(BASIC_BLOCK_H) $(DIAGNOSTIC_H) \
- hard-reg-set.h $(TREE_GIMPLE_H) vec.h tree-ssa-structalias.h \
+ hard-reg-set.h $(GIMPLE_H) vec.h tree-ssa-structalias.h \
$(IPA_TYPE_ESCAPE_H) vecprim.h pointer-set.h alloc-pool.h
tree-ssa-reassoc.o : tree-ssa-reassoc.c $(TREE_FLOW_H) $(CONFIG_H) \
$(SYSTEM_H) $(TREE_H) $(GGC_H) $(DIAGNOSTIC_H) errors.h $(TIMEVAR_H) \
$(TM_H) coretypes.h $(TREE_DUMP_H) tree-pass.h $(FLAGS_H) tree-iterator.h\
- $(BASIC_BLOCK_H) $(TREE_GIMPLE_H) $(TREE_INLINE_H) vec.h \
+ $(BASIC_BLOCK_H) $(GIMPLE_H) $(TREE_INLINE_H) vec.h langhooks.h \
alloc-pool.h pointer-set.h $(CFGLOOP_H)
tree-optimize.o : tree-optimize.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
- $(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) $(GGC_H) output.h $(DIAGNOSTIC_H) \
- $(FLAGS_H) $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) toplev.h \
- $(FUNCTION_H) langhooks.h $(FLAGS_H) $(CGRAPH_H) $(TREE_INLINE_H) \
- tree-mudflap.h $(GGC_H) $(CGRAPH_H) tree-pass.h $(CFGLOOP_H) \
- $(BASIC_BLOCK_H) graph.h hard-reg-set.h
+ $(RTL_H) $(TREE_H) $(TM_P_H) hard-reg-set.h $(EXPR_H) $(GGC_H) output.h \
+ $(DIAGNOSTIC_H) $(BASIC_BLOCK_H) $(FLAGS_H) $(TIMEVAR_H) $(TM_H) coretypes.h \
+ $(TREE_DUMP_H) $(TOPLEV_H) $(FUNCTION_H) langhooks.h $(FLAGS_H) $(CGRAPH_H) \
+ $(TREE_INLINE_H) tree-mudflap.h $(GGC_H) graph.h $(CGRAPH_H) tree-pass.h \
+ $(CFGLOOP_H) except.h
+
c-gimplify.o : c-gimplify.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) \
- $(C_TREE_H) $(C_COMMON_H) $(DIAGNOSTIC_H) $(TREE_GIMPLE_H) $(VARRAY_H) \
- $(FLAGS_H) langhooks.h toplev.h $(RTL_H) $(TREE_FLOW_H) $(LANGHOOKS_DEF_H) \
+ $(C_TREE_H) $(C_COMMON_H) $(DIAGNOSTIC_H) $(GIMPLE_H) $(VARRAY_H) \
+ $(FLAGS_H) langhooks.h $(TOPLEV_H) $(RTL_H) $(TREE_FLOW_H) $(LANGHOOKS_DEF_H) \
$(TM_H) coretypes.h $(C_PRETTY_PRINT_H) $(CGRAPH_H) $(BASIC_BLOCK_H) \
hard-reg-set.h $(TREE_DUMP_H) $(TREE_INLINE_H)
-gimplify.o : gimplify.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) \
- $(DIAGNOSTIC_H) $(TREE_GIMPLE_H) $(TREE_INLINE_H) $(VARRAY_H) langhooks.h \
+gimplify.o : gimplify.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(GIMPLE_H) \
+ $(DIAGNOSTIC_H) $(GIMPLE_H) $(TREE_INLINE_H) $(VARRAY_H) langhooks.h \
$(LANGHOOKS_DEF_H) $(TREE_FLOW_H) $(CGRAPH_H) $(TIMEVAR_H) $(TM_H) \
coretypes.h except.h $(FLAGS_H) $(RTL_H) $(FUNCTION_H) $(EXPR_H) output.h \
- $(GGC_H) gt-gimplify.h $(HASHTAB_H) $(TARGET_H) toplev.h $(OPTABS_H) \
- $(REAL_H) $(SPLAY_TREE_H)
+ $(GGC_H) gt-gimplify.h $(HASHTAB_H) $(TARGET_H) $(TOPLEV_H) $(OPTABS_H) \
+ $(REAL_H) $(SPLAY_TREE_H) vec.h tree-iterator.h
+gimple-iterator.o : gimple-iterator.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
+ $(TREE_H) $(GIMPLE_H) $(TREE_FLOW_H) value-prof.h
gimple-low.o : gimple-low.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) \
- $(DIAGNOSTIC_H) $(TREE_GIMPLE_H) $(TREE_INLINE_H) $(VARRAY_H) langhooks.h \
+ $(DIAGNOSTIC_H) $(GIMPLE_H) $(TREE_INLINE_H) $(VARRAY_H) langhooks.h \
$(LANGHOOKS_DEF_H) $(TREE_FLOW_H) $(TIMEVAR_H) $(TM_H) coretypes.h \
except.h $(FLAGS_H) $(RTL_H) $(FUNCTION_H) $(EXPR_H) tree-pass.h \
- $(HASHTAB_H) toplev.h
+ $(HASHTAB_H) $(TOPLEV.H) tree-iterator.h
omp-low.o : omp-low.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
- $(RTL_H) $(TREE_GIMPLE_H) $(TREE_INLINE_H) langhooks.h $(DIAGNOSTIC_H) \
- $(TREE_FLOW_H) $(TIMEVAR_H) $(FLAGS_H) $(EXPR_H) toplev.h tree-pass.h \
- $(GGC_H) $(SPLAY_TREE_H) $(OPTABS_H) $(CFGLOOP_H)
+ $(RTL_H) $(GIMPLE_H) $(TREE_INLINE_H) langhooks.h $(DIAGNOSTIC_H) \
+ $(TREE_FLOW_H) $(TIMEVAR_H) $(FLAGS_H) $(EXPR_H) $(TOPLEV_H) tree-pass.h \
+ $(GGC_H) except.h $(SPLAY_TREE_H) $(OPTABS_H) $(CFGLOOP_H) \
+ tree-iterator.h
tree-browser.o : tree-browser.c tree-browser.def $(CONFIG_H) $(SYSTEM_H) \
$(TREE_H) $(TREE_INLINE_H) $(DIAGNOSTIC_H) $(HASHTAB_H) \
$(TM_H) coretypes.h
omega.o : omega.c omega.h $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
- errors.h $(GGC_H) $(TREE_H) $(DIAGNOSTIC_H) varray.h tree-pass.h
+ errors.h $(GGC_H) $(TREE_H) $(DIAGNOSTIC_H) varray.h tree-pass.h $(PARAMS_H)
tree-chrec.o: tree-chrec.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(GGC_H) $(TREE_H) $(REAL_H) $(SCEV_H) tree-pass.h $(PARAMS_H) \
$(DIAGNOSTIC_H) $(CFGLOOP_H) $(TREE_FLOW_H)
@@ -2304,22 +2344,23 @@ tree-data-ref.o: tree-data-ref.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
tree-vect-analyze.o: tree-vect-analyze.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TM_H) $(GGC_H) $(OPTABS_H) $(TREE_H) $(RECOG_H) $(BASIC_BLOCK_H) \
$(DIAGNOSTIC_H) $(TREE_FLOW_H) $(TREE_DUMP_H) $(TIMEVAR_H) $(CFGLOOP_H) \
- tree-vectorizer.h $(TREE_DATA_REF_H) $(SCEV_H) $(EXPR_H) tree-chrec.h
+ tree-vectorizer.h $(TREE_DATA_REF_H) $(SCEV_H) $(EXPR_H) tree-chrec.h \
+ $(TOPLEV_H) $(RECOG_H)
tree-vect-patterns.o: tree-vect-patterns.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
- $(TM_H) errors.h $(GGC_H) $(OPTABS_H) $(TREE_H) $(RTL_H) $(BASIC_BLOCK_H) \
- $(DIAGNOSTIC_H) $(TREE_FLOW_H) $(TREE_DUMP_H) $(TIMEVAR_H) $(CFGLOOP_H) \
- tree-vectorizer.h $(TREE_DATA_REF_H) $(EXPR_H) $(TARGET_H)
+ $(TM_H) $(GGC_H) $(TREE_H) $(TARGET_H) $(BASIC_BLOCK_H) $(DIAGNOSTIC_H) \
+ $(TREE_FLOW_H) $(TREE_DUMP_H) $(TIMEVAR_H) $(CFGLOOP_H) $(EXPR_H) \
+ $(OPTABS_H) $(PARAMS_H) $(TREE_DATA_REF_H) tree-vectorizer.h $(RECOG_H) $(TOPLEV_H)
tree-vect-transform.o: tree-vect-transform.c $(CONFIG_H) $(SYSTEM_H) \
coretypes.h $(TM_H) $(GGC_H) $(OPTABS_H) $(RECOG_H) $(TREE_H) $(RTL_H) \
$(BASIC_BLOCK_H) $(DIAGNOSTIC_H) $(TREE_FLOW_H) $(TREE_DUMP_H) \
$(TIMEVAR_H) $(CFGLOOP_H) $(TARGET_H) tree-pass.h $(EXPR_H) \
- tree-vectorizer.h $(TREE_DATA_REF_H) $(SCEV_H) langhooks.h toplev.h \
+ tree-vectorizer.h $(TREE_DATA_REF_H) $(SCEV_H) langhooks.h $(TOPLEV_H) \
tree-chrec.h
tree-vectorizer.o: tree-vectorizer.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TM_H) $(GGC_H) $(OPTABS_H) $(TREE_H) $(RTL_H) $(BASIC_BLOCK_H) \
$(DIAGNOSTIC_H) $(TREE_FLOW_H) $(TREE_DUMP_H) $(TIMEVAR_H) $(CFGLOOP_H) \
- tree-pass.h $(EXPR_H) tree-vectorizer.h $(TREE_DATA_REF_H) $(SCEV_H) \
- input.h $(TARGET_H) $(CFGLAYOUT_H) toplev.h tree-chrec.h
+ tree-pass.h $(EXPR_H) $(RECOG_H) tree-vectorizer.h $(TREE_DATA_REF_H) $(SCEV_H) \
+ $(INPUT_H) $(TARGET_H) $(CFGLAYOUT_H) $(TOPLEV_H) tree-chrec.h
tree-loop-linear.o: tree-loop-linear.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TM_H) $(GGC_H) $(OPTABS_H) $(TREE_H) $(RTL_H) $(BASIC_BLOCK_H) \
$(DIAGNOSTIC_H) $(TREE_FLOW_H) $(TREE_DUMP_H) $(TIMEVAR_H) $(CFGLOOP_H) \
@@ -2329,7 +2370,7 @@ tree-loop-distribution.o: tree-loop-distribution.c $(CONFIG_H) $(SYSTEM_H) coret
$(TM_H) $(GGC_H) $(OPTABS_H) $(TREE_H) $(RTL_H) $(BASIC_BLOCK_H) \
$(DIAGNOSTIC_H) $(TREE_FLOW_H) $(TREE_DUMP_H) $(TIMEVAR_H) $(CFGLOOP_H) \
tree-pass.h $(TREE_DATA_REF_H) $(SCEV_H) $(EXPR_H) \
- $(TARGET_H) tree-chrec.h tree-vectorizer.h
+ $(TARGET_H) tree-chrec.h langhooks.h tree-vectorizer.h
tree-parloops.o: tree-parloops.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(TREE_FLOW_H) $(TREE_H) $(RTL_H) $(CFGLOOP_H) $(TREE_DATA_REF_H) $(GGC_H) \
$(DIAGNOSTIC_H) tree-pass.h $(SCEV_H) langhooks.h gt-tree-parloops.h \
@@ -2338,57 +2379,61 @@ tree-stdarg.o: tree-stdarg.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(TREE_H) $(FUNCTION_H) $(DIAGNOSTIC_H) $(TREE_FLOW_H) tree-pass.h \
tree-stdarg.h $(TARGET_H) langhooks.h
tree-object-size.o: tree-object-size.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
- $(TM_H) $(TREE_H) $(DIAGNOSTIC_H) $(TREE_FLOW_H) tree-pass.h \
+ $(TM_H) $(TREE_H) $(TOPLEV_H) $(DIAGNOSTIC_H) $(TREE_FLOW_H) tree-pass.h \
tree-ssa-propagate.h
-tree-gimple.o : tree-gimple.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(EXPR_H) \
- $(RTL_H) $(TREE_GIMPLE_H) $(TM_H) coretypes.h bitmap.h $(GGC_H) \
- output.h $(TREE_FLOW_H)
+gimple.o : gimple.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TREE_H) \
+ $(GGC_H) $(GIMPLE_H) $(GIMPLE_H) $(DIAGNOSTIC_H) gt-gimple.h \
+ $(TREE_FLOW_H) value-prof.h $(FLAGS_H)
+gimple-pretty-print.o : gimple-pretty-print.c $(CONFIG_H) $(SYSTEM_H) \
+ $(TREE_H) $(DIAGNOSTIC_H) $(REAL_H) $(HASHTAB_H) $(TREE_FLOW_H) \
+ $(TM_H) coretypes.h tree-pass.h $(GIMPLE_H) value-prof.h
tree-mudflap.o : $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(TREE_INLINE_H) \
- $(TREE_GIMPLE_H) $(DIAGNOSTIC_H) $(HASHTAB_H) langhooks.h tree-mudflap.h \
+ $(GIMPLE_H) $(DIAGNOSTIC_H) $(HASHTAB_H) langhooks.h tree-mudflap.h \
$(TM_H) coretypes.h $(TREE_DUMP_H) tree-pass.h $(CGRAPH_H) $(GGC_H) \
gt-tree-mudflap.h $(BASIC_BLOCK_H) $(FLAGS_H) $(FUNCTION_H) hard-reg-set.h \
- $(RTL_H) $(TM_P_H) $(TREE_FLOW_H) toplev.h
+ $(RTL_H) $(TM_P_H) $(TREE_FLOW_H) $(TOPLEV.H) $(GIMPLE_H) tree-iterator.h
tree-nomudflap.o : $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(TREE_INLINE_H) \
- $(C_TREE_H) $(C_COMMON_H) $(TREE_GIMPLE_H) $(DIAGNOSTIC_H) $(HASHTAB_H) \
+ $(C_TREE_H) $(C_COMMON_H) $(GIMPLE_H) $(DIAGNOSTIC_H) $(HASHTAB_H) \
output.h $(VARRAY_H) langhooks.h tree-mudflap.h $(TM_H) coretypes.h \
- $(GGC_H) gt-tree-mudflap.h tree-pass.h toplev.h
+ $(GGC_H) gt-tree-mudflap.h tree-pass.h $(TOPLEV_H)
tree-pretty-print.o : tree-pretty-print.c $(CONFIG_H) $(SYSTEM_H) \
$(TREE_H) $(DIAGNOSTIC_H) $(REAL_H) $(HASHTAB_H) $(TREE_FLOW_H) \
$(TM_H) coretypes.h tree-iterator.h tree-chrec.h langhooks.h tree-pass.h \
value-prof.h fixed-value.h output.h
fold-const.o : fold-const.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
- $(TREE_H) $(FLAGS_H) $(REAL_H) toplev.h $(HASHTAB_H) $(EXPR_H) $(RTL_H) \
- $(GGC_H) $(TM_P_H) langhooks.h $(MD5_H) intl.h fixed-value.h
+ $(TREE_H) $(FLAGS_H) $(REAL_H) $(TOPLEV_H) $(HASHTAB_H) $(EXPR_H) $(RTL_H) \
+ $(GGC_H) $(TM_P_H) langhooks.h $(MD5_H) intl.h fixed-value.h $(TARGET_H) \
+ $(GIMPLE_H)
diagnostic.o : diagnostic.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
- $(TREE_H) version.h $(TM_P_H) $(FLAGS_H) input.h toplev.h intl.h \
+ $(TREE_H) version.h $(TM_P_H) $(FLAGS_H) $(INPUT_H) $(TOPLEV_H) intl.h \
$(DIAGNOSTIC_H) langhooks.h $(LANGHOOKS_DEF_H) diagnostic.def opts.h
-opts.o : opts.c opts.h options.h toplev.h $(CONFIG_H) $(SYSTEM_H) \
+opts.o : opts.c opts.h options.h $(TOPLEV_H) $(CONFIG_H) $(SYSTEM_H) \
coretypes.h $(TREE_H) $(TM_H) langhooks.h $(GGC_H) $(RTL_H) \
output.h $(DIAGNOSTIC_H) $(TM_P_H) $(INSN_ATTR_H) intl.h $(TARGET_H) \
- $(FLAGS_H) $(PARAMS_H) tree-pass.h $(DBGCNT_H) debug.h
+ $(FLAGS_H) $(PARAMS_H) tree-pass.h $(DBGCNT_H) debug.h varray.h
opts-common.o : opts-common.c opts.h $(CONFIG_H) $(SYSTEM_H) \
coretypes.h intl.h
targhooks.o : targhooks.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TREE_H) \
- $(EXPR_H) $(TM_H) $(RTL_H) $(TM_P_H) $(FUNCTION_H) output.h toplev.h \
+ $(EXPR_H) $(TM_H) $(RTL_H) $(TM_P_H) $(FUNCTION_H) output.h $(TOPLEV_H) \
$(MACHMODE_H) $(TARGET_DEF_H) $(TARGET_H) $(GGC_H) gt-targhooks.h \
- $(OPTABS_H)
+ $(OPTABS_H) $(RECOG_H) reload.h
toplev.o : toplev.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
- version.h $(RTL_H) $(FUNCTION_H) $(FLAGS_H) xcoffout.h input.h \
+ version.h $(RTL_H) $(FUNCTION_H) $(FLAGS_H) xcoffout.h $(INPUT_H) \
$(INSN_ATTR_H) output.h $(DIAGNOSTIC_H) debug.h insn-config.h intl.h \
- $(RECOG_H) Makefile toplev.h dwarf2out.h sdbout.h dbxout.h $(EXPR_H) \
+ $(RECOG_H) Makefile $(TOPLEV_H) dwarf2out.h sdbout.h dbxout.h $(EXPR_H) \
hard-reg-set.h $(BASIC_BLOCK_H) graph.h except.h $(REGS_H) $(TIMEVAR_H) \
value-prof.h $(PARAMS_H) $(TM_P_H) reload.h ira.h dwarf2asm.h $(TARGET_H) \
langhooks.h insn-flags.h $(CFGLAYOUT_H) $(CFGLOOP_H) hosthooks.h \
$(CGRAPH_H) $(COVERAGE_H) alloc-pool.h $(GGC_H) $(INTEGRATE_H) \
- $(CPPLIB_H) opts.h params.def tree-mudflap.h $(REAL_H) tree-pass.h
+ opts.h params.def tree-mudflap.h $(REAL_H) tree-pass.h $(GIMPLE_H)
$(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) \
-DTARGET_NAME=\"$(target_noncanonical)\" \
-c $(srcdir)/toplev.c $(OUTPUT_OPTION)
passes.o : passes.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
- $(RTL_H) $(FUNCTION_H) $(FLAGS_H) xcoffout.h input.h $(INSN_ATTR_H) output.h \
- $(DIAGNOSTIC_H) debug.h insn-config.h intl.h $(RECOG_H) toplev.h \
+ $(RTL_H) $(FUNCTION_H) $(FLAGS_H) xcoffout.h $(INPUT_H) $(INSN_ATTR_H) output.h \
+ $(DIAGNOSTIC_H) debug.h insn-config.h intl.h $(RECOG_H) $(TOPLEV_H) \
dwarf2out.h sdbout.h dbxout.h $(EXPR_H) hard-reg-set.h $(BASIC_BLOCK_H) \
graph.h except.h $(REGS_H) $(TIMEVAR_H) value-prof.h \
$(PARAMS_H) $(TM_P_H) reload.h dwarf2asm.h $(TARGET_H) \
@@ -2397,223 +2442,233 @@ passes.o : passes.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
$(GGC_H) $(INTEGRATE_H) $(CPPLIB_H) opts.h $(TREE_FLOW_H) $(TREE_INLINE_H) \
gt-passes.h $(DF_H) $(PREDICT_H)
-main.o : main.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) toplev.h
+main.o : main.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TOPLEV_H)
host-default.o : host-default.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
hosthooks.h $(HOSTHOOKS_DEF_H)
rtl-error.o: rtl-error.c $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
- $(INSN_ATTR_H) insn-config.h input.h toplev.h intl.h $(DIAGNOSTIC_H) \
- $(CONFIG_H)
+ $(INSN_ATTR_H) insn-config.h $(INPUT_H) $(TOPLEV_H) intl.h $(DIAGNOSTIC_H) \
+ $(CONFIG_H) varray.h
rtl.o : rtl.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
- $(GGC_H) $(BCONFIG_H) insn-notes.def reg-notes.def toplev.h $(REAL_H)
+ $(GGC_H) $(BCONFIG_H) insn-notes.def reg-notes.def $(TOPLEV_H) $(REAL_H)
print-rtl.o : print-rtl.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(RTL_H) $(TREE_H) hard-reg-set.h $(BASIC_BLOCK_H) $(FLAGS_H) \
$(BCONFIG_H) $(REAL_H)
-rtlanal.o : rtlanal.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) toplev.h \
+rtlanal.o : rtlanal.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TOPLEV_H) \
$(RTL_H) hard-reg-set.h $(TM_P_H) insn-config.h $(RECOG_H) $(REAL_H) \
$(FLAGS_H) $(REGS_H) output.h $(TARGET_H) $(FUNCTION_H) $(TREE_H) \
$(DF_H)
varasm.o : varasm.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
$(RTL_H) $(FLAGS_H) $(FUNCTION_H) $(EXPR_H) hard-reg-set.h $(REGS_H) \
- output.h $(C_PRAGMA_H) toplev.h xcoffout.h debug.h $(GGC_H) $(TM_P_H) \
+ output.h $(C_PRAGMA_H) $(TOPLEV_H) xcoffout.h debug.h $(GGC_H) $(TM_P_H) \
$(HASHTAB_H) $(TARGET_H) langhooks.h gt-varasm.h $(BASIC_BLOCK_H) \
- $(CFGLAYOUT_H) $(CGRAPH_H) tree-mudflap.h $(REAL_H)
+ $(CFGLAYOUT_H) $(CGRAPH_H) targhooks.h tree-mudflap.h $(REAL_H) tree-iterator.h
function.o : function.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
- $(TREE_H) $(CFGLAYOUT_H) $(TREE_GIMPLE_H) $(FLAGS_H) $(FUNCTION_H) $(EXPR_H) \
+ $(TREE_H) $(CFGLAYOUT_H) $(GIMPLE_H) $(FLAGS_H) $(FUNCTION_H) $(EXPR_H) \
$(OPTABS_H) libfuncs.h $(REGS_H) hard-reg-set.h insn-config.h $(RECOG_H) \
- output.h toplev.h except.h $(HASHTAB_H) $(GGC_H) $(TM_P_H) langhooks.h \
+ output.h $(TOPLEV_H) except.h $(HASHTAB_H) $(GGC_H) $(TM_P_H) langhooks.h \
gt-function.h $(TARGET_H) $(BASIC_BLOCK_H) $(INTEGRATE_H) $(PREDICT_H) \
- tree-pass.h $(DF_H) timevar.h vecprim.h
+ tree-pass.h $(DF_H) $(TIMEVAR_H) vecprim.h
statistics.o : statistics.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
- $(FLAGS_H) $(FUNCTION_H) $(HASHTAB_H) $(TREE_DUMP_H) tree-pass.h
+ tree-pass.h $(TREE_DUMP_H) $(HASHTAB_H) statistics.h $(TM_H) $(FUNCTION_H)
stmt.o : stmt.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(TREE_H) $(FLAGS_H) $(FUNCTION_H) insn-config.h hard-reg-set.h $(EXPR_H) \
- libfuncs.h except.h $(RECOG_H) toplev.h output.h $(GGC_H) $(TM_P_H) \
+ libfuncs.h except.h $(RECOG_H) $(TOPLEV_H) output.h $(GGC_H) $(TM_P_H) \
langhooks.h $(PREDICT_H) $(OPTABS_H) $(TARGET_H) $(MACHMODE_H) \
$(REGS_H) alloc-pool.h
except.o : except.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(TREE_H) $(FLAGS_H) except.h $(FUNCTION_H) $(EXPR_H) libfuncs.h \
langhooks.h insn-config.h hard-reg-set.h $(BASIC_BLOCK_H) output.h \
- dwarf2asm.h dwarf2out.h toplev.h $(HASHTAB_H) intl.h $(GGC_H) \
+ dwarf2asm.h dwarf2out.h $(TOPLEV_H) $(HASHTAB_H) intl.h $(GGC_H) \
gt-except.h $(CGRAPH_H) $(INTEGRATE_H) $(DIAGNOSTIC_H) dwarf2.h \
$(TARGET_H) $(TM_P_H) tree-pass.h $(TIMEVAR_H)
expr.o : expr.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(TREE_H) $(FLAGS_H) $(FUNCTION_H) $(REGS_H) $(EXPR_H) $(OPTABS_H) \
libfuncs.h $(INSN_ATTR_H) insn-config.h $(RECOG_H) output.h \
- typeclass.h hard-reg-set.h toplev.h hard-reg-set.h except.h reload.h \
+ typeclass.h hard-reg-set.h $(TOPLEV_H) hard-reg-set.h except.h reload.h \
$(GGC_H) langhooks.h intl.h $(TM_P_H) $(REAL_H) $(TARGET_H) \
tree-iterator.h gt-expr.h $(MACHMODE_H) $(TIMEVAR_H) $(TREE_FLOW_H) \
- tree-pass.h $(DF_H) $(DIAGNOSTIC_H)
+ tree-pass.h $(DF_H) $(DIAGNOSTIC_H) vecprim.h
dojump.o : dojump.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) \
$(FLAGS_H) $(FUNCTION_H) $(EXPR_H) $(OPTABS_H) $(INSN_ATTR_H) insn-config.h \
- langhooks.h $(GGC_H) gt-dojump.h
+ langhooks.h $(GGC_H) gt-dojump.h vecprim.h
builtins.o : builtins.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
- $(TREE_H) $(TREE_GIMPLE_H) $(FLAGS_H) $(TARGET_H) $(FUNCTION_H) $(REGS_H) \
+ $(TREE_H) $(GIMPLE_H) $(FLAGS_H) $(TARGET_H) $(FUNCTION_H) $(REGS_H) \
$(EXPR_H) $(OPTABS_H) insn-config.h $(RECOG_H) output.h typeclass.h \
- hard-reg-set.h toplev.h hard-reg-set.h except.h $(TM_P_H) $(PREDICT_H) \
+ hard-reg-set.h $(TOPLEV_H) hard-reg-set.h except.h $(TM_P_H) $(PREDICT_H) \
libfuncs.h $(REAL_H) langhooks.h $(BASIC_BLOCK_H) tree-mudflap.h \
- $(BUILTINS_DEF) $(MACHMODE_H) $(DIAGNOSTIC_H)
+ $(BUILTINS_DEF) $(MACHMODE_H) $(DIAGNOSTIC_H) $(TREE_FLOW_H) value-prof.h
calls.o : calls.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(TREE_H) $(FLAGS_H) $(EXPR_H) $(OPTABS_H) langhooks.h $(TARGET_H) \
- libfuncs.h $(REGS_H) toplev.h output.h $(FUNCTION_H) $(TIMEVAR_H) $(TM_P_H) \
- $(CGRAPH_H) except.h sbitmap.h $(DBGCNT_H)
+ libfuncs.h $(REGS_H) $(TOPLEV_H) output.h $(FUNCTION_H) $(TIMEVAR_H) $(TM_P_H) \
+ $(CGRAPH_H) except.h sbitmap.h $(DBGCNT_H) $(TREE_FLOW_H)
expmed.o : expmed.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) \
$(FLAGS_H) insn-config.h $(EXPR_H) $(OPTABS_H) $(RECOG_H) $(REAL_H) \
- toplev.h $(TM_P_H) langhooks.h $(DF_H) $(TARGET_H)
+ $(TOPLEV_H) $(TM_P_H) langhooks.h $(DF_H) $(TARGET_H)
explow.o : explow.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) \
$(FLAGS_H) hard-reg-set.h insn-config.h $(EXPR_H) $(OPTABS_H) $(RECOG_H) \
- toplev.h $(FUNCTION_H) $(GGC_H) $(TM_P_H) langhooks.h gt-explow.h \
+ $(TOPLEV_H) $(FUNCTION_H) $(GGC_H) $(TM_P_H) langhooks.h gt-explow.h \
$(TARGET_H) output.h
optabs.o : optabs.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(TREE_H) $(FLAGS_H) insn-config.h $(EXPR_H) $(OPTABS_H) libfuncs.h \
- $(RECOG_H) reload.h toplev.h $(GGC_H) $(REAL_H) $(TM_P_H) except.h \
+ $(RECOG_H) reload.h $(TOPLEV_H) $(GGC_H) $(REAL_H) $(TM_P_H) except.h \
gt-optabs.h $(BASIC_BLOCK_H) $(TARGET_H) $(FUNCTION_H)
dbxout.o : dbxout.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
$(RTL_H) $(FLAGS_H) $(REGS_H) debug.h $(TM_P_H) $(TARGET_H) $(FUNCTION_H) \
- langhooks.h insn-config.h reload.h gstab.h xcoffout.h output.h dbxout.h \
- toplev.h $(GGC_H) $(OBSTACK_H) $(EXPR_H) gt-dbxout.h
+ langhooks.h insn-config.h reload.h $(GSTAB_H) xcoffout.h output.h dbxout.h \
+ $(TOPLEV_H) $(GGC_H) $(OBSTACK_H) $(EXPR_H) gt-dbxout.h
debug.o : debug.c debug.h $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H)
sdbout.o : sdbout.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) debug.h \
$(TREE_H) $(GGC_H) $(RTL_H) $(REGS_H) $(FLAGS_H) insn-config.h \
- output.h toplev.h $(TM_P_H) gsyms.h langhooks.h $(TARGET_H) sdbout.h \
+ output.h $(TOPLEV_H) $(TM_P_H) gsyms.h langhooks.h $(TARGET_H) sdbout.h \
gt-sdbout.h reload.h $(VARRAY_H)
dwarf2out.o : dwarf2out.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(TREE_H) version.h $(RTL_H) dwarf2.h debug.h $(FLAGS_H) insn-config.h \
output.h $(DIAGNOSTIC_H) $(REAL_H) hard-reg-set.h $(REGS_H) $(EXPR_H) \
- libfuncs.h toplev.h dwarf2out.h reload.h $(GGC_H) except.h dwarf2asm.h \
+ libfuncs.h $(TOPLEV_H) dwarf2out.h reload.h $(GGC_H) except.h dwarf2asm.h \
$(TM_P_H) langhooks.h $(HASHTAB_H) gt-dwarf2out.h $(TARGET_H) $(CGRAPH_H) \
- $(MD5_H) input.h $(FUNCTION_H) $(VARRAY_H)
+ $(MD5_H) $(INPUT_H) $(FUNCTION_H) $(VARRAY_H)
dwarf2asm.o : dwarf2asm.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(FLAGS_H) $(RTL_H) $(TREE_H) output.h dwarf2asm.h $(TM_P_H) $(GGC_H) \
gt-dwarf2asm.h dwarf2.h $(SPLAY_TREE_H) $(TARGET_H)
vmsdbgout.o : vmsdbgout.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) version.h \
- $(RTL_H) $(FLAGS_H) output.h vmsdbg.h debug.h langhooks.h $(FUNCTION_H) $(TARGET_H)
+ $(FLAGS_H) $(RTL_H) output.h vmsdbg.h debug.h langhooks.h $(FUNCTION_H) $(TARGET_H)
xcoffout.o : xcoffout.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
- $(TREE_H) $(RTL_H) xcoffout.h $(FLAGS_H) toplev.h output.h dbxout.h \
- $(GGC_H) $(TARGET_H) debug.h gstab.h xcoff.h
+ $(TREE_H) $(RTL_H) xcoffout.h $(FLAGS_H) $(TOPLEV_H) output.h dbxout.h \
+ $(GGC_H) $(TARGET_H) debug.h $(GSTAB_H) xcoff.h
emit-rtl.o : emit-rtl.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(TREE_H) $(FLAGS_H) $(FUNCTION_H) $(REGS_H) insn-config.h $(RECOG_H) \
- $(GGC_H) $(EXPR_H) hard-reg-set.h bitmap.h toplev.h $(BASIC_BLOCK_H) \
+ $(GGC_H) $(EXPR_H) hard-reg-set.h $(BITMAP_H) $(TOPLEV_H) $(BASIC_BLOCK_H) \
$(HASHTAB_H) $(TM_P_H) debug.h langhooks.h tree-pass.h gt-emit-rtl.h \
$(REAL_H) $(DF_H)
real.o : real.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
- toplev.h $(TM_P_H) $(REAL_H)
+ $(TOPLEV_H) $(TM_P_H) $(REAL_H) dfp.h
dfp.o : dfp.c dfp.h $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
- toplev.h $(TM_P_H) $(REAL_H) $(DECNUM_H)
+ $(TOPLEV_H) $(TM_P_H) $(REAL_H) $(DECNUM_H)
fixed-value.o: fixed-value.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
- $(TREE_H) fixed-value.h $(REAL_H) toplev.h
+ $(TREE_H) fixed-value.h $(REAL_H) $(TOPLEV_H)
integrate.o : integrate.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(RTL_H) $(TREE_H) $(FLAGS_H) debug.h $(INTEGRATE_H) insn-config.h \
$(EXPR_H) $(REAL_H) $(REGS_H) intl.h $(FUNCTION_H) output.h $(RECOG_H) \
- except.h toplev.h $(PARAMS_H) $(TM_P_H) $(TARGET_H) langhooks.h \
+ except.h $(TOPLEV_H) $(PARAMS_H) $(TM_P_H) $(TARGET_H) langhooks.h \
gt-integrate.h $(GGC_H) tree-pass.h $(DF_H)
jump.o : jump.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(FLAGS_H) hard-reg-set.h $(REGS_H) insn-config.h $(RECOG_H) $(EXPR_H) \
$(REAL_H) except.h $(FUNCTION_H) tree-pass.h $(DIAGNOSTIC_H) \
- toplev.h $(INSN_ATTR_H) $(TM_P_H) reload.h $(PREDICT_H) \
+ $(TOPLEV_H) $(INSN_ATTR_H) $(TM_P_H) reload.h $(PREDICT_H) \
$(TIMEVAR_H) $(TARGET_H)
simplify-rtx.o : simplify-rtx.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(RTL_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) $(REAL_H) insn-config.h \
- $(RECOG_H) $(EXPR_H) toplev.h output.h $(FUNCTION_H) $(GGC_H) $(TM_P_H) \
+ $(RECOG_H) $(EXPR_H) $(TOPLEV_H) output.h $(FUNCTION_H) $(GGC_H) $(TM_P_H) \
$(TREE_H) $(TARGET_H)
cgraph.o : cgraph.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
- langhooks.h toplev.h $(FLAGS_H) $(GGC_H) $(TARGET_H) $(CGRAPH_H) \
+ langhooks.h $(TOPLEV_H) $(FLAGS_H) $(GGC_H) $(TARGET_H) $(CGRAPH_H) \
gt-cgraph.h output.h intl.h $(BASIC_BLOCK_H) debug.h $(HASHTAB_H) \
$(TREE_INLINE_H) $(VARRAY_H) $(TREE_DUMP_H) $(TREE_FLOW_H)
cgraphunit.o : cgraphunit.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
- $(TREE_H) langhooks.h $(TREE_INLINE_H) toplev.h $(FLAGS_H) $(GGC_H) \
- $(TARGET_H) $(CGRAPH_H) intl.h pointer-set.h $(FUNCTION_H) $(TREE_GIMPLE_H) \
+ $(TREE_H) langhooks.h $(TREE_INLINE_H) $(TOPLEV_H) $(FLAGS_H) $(GGC_H) \
+ $(TARGET_H) $(CGRAPH_H) intl.h pointer-set.h $(FUNCTION_H) $(GIMPLE_H) \
$(TREE_FLOW_H) tree-pass.h $(C_COMMON_H) debug.h $(DIAGNOSTIC_H) \
- $(FIBHEAP_H) output.h $(PARAMS_H) $(RTL_H) $(TIMEVAR_H) ipa-prop.h \
- gt-cgraphunit.h
+ $(FIBHEAP_H) output.h $(PARAMS_H) $(RTL_H) $(TIMEVAR_H) $(IPA_PROP_H) \
+ gt-cgraphunit.h tree-iterator.h
cgraphbuild.o : cgraphbuild.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
- $(TREE_H) langhooks.h $(CGRAPH_H) intl.h pointer-set.h $(TREE_GIMPLE_H) \
+ $(TREE_H) langhooks.h $(CGRAPH_H) intl.h pointer-set.h $(GIMPLE_H) \
$(TREE_FLOW_H) tree-pass.h
varpool.o : varpool.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
- $(TREE_H) langhooks.h $(TREE_INLINE_H) toplev.h $(FLAGS_H) $(GGC_H) \
- $(TARGET_H) $(CGRAPH_H) intl.h pointer-set.h $(FUNCTION_H) $(TREE_GIMPLE_H) \
- $(TREE_FLOW_H) tree-pass.h $(C_COMMON_H) debug.h $(DIAGNOSTIC_H) \
- $(FIBHEAP_H) output.h $(PARAMS_H) $(RTL_H) $(TIMEVAR_H) ipa-prop.h \
- gt-varpool.h
-ipa.o : ipa.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(CGRAPH_H)
-ipa-prop.o : ipa-prop.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
- langhooks.h $(GGC_H) $(TARGET_H) $(CGRAPH_H) ipa-prop.h \
- $(TREE_FLOW_H) $(TM_H) tree-pass.h $(FLAGS_H) $(TREE_H)
+ $(TREE_H) $(CGRAPH_H) langhooks.h $(DIAGNOSTIC_H) $(HASHTAB_H) \
+ $(GGC_H) $(TIMEVAR_H) debug.h $(TARGET_H) output.h $(GIMPLE_H) \
+ $(TREE_FLOW_H) gt-varpool.h
+ipa.o : ipa.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(CGRAPH_H) \
+ tree-pass.h $(TIMEVAR_H)
+ipa-prop.o : ipa-prop.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
+ langhooks.h $(GGC_H) $(TARGET_H) $(CGRAPH_H) $(IPA_PROP_H) $(DIAGNOSTIC_H) \
+ $(TREE_FLOW_H) $(TM_H) tree-pass.h $(FLAGS_H) $(TREE_H) $(TREE_INLINE_H) \
+ $(TIMEVAR_H)
ipa-cp.o : ipa-cp.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
- langhooks.h $(TARGET_H) $(CGRAPH_H) ipa-prop.h tree-inline.h tree-dump.h \
- $(TREE_FLOW_H) $(TM_H) tree-pass.h $(FLAGS_H) $(TREE_H) $(DIAGNOSTIC_H)
+ $(TREE_H) $(TARGET_H) $(CGRAPH_H) $(IPA_PROP_H) $(TREE_FLOW_H) tree-pass.h \
+ $(FLAGS_H) $(TIMEVAR_H) $(DIAGNOSTIC_H) $(TREE_DUMP_H) $(TREE_INLINE_H)
matrix-reorg.o : matrix-reorg.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
- $(TARGET_H) $(CGRAPH_H) $(TREE_FLOW_H) $(TM_H) tree-pass.h \
- $(FLAGS_H) $(TREE_H) $(DIAGNOSTIC_H)
+ $(TM_H) $(TREE_H) $(RTL_H) $(C_TREE_H) $(TREE_INLINE_H) $(TREE_FLOW_H) \
+ tree-flow-inline.h langhooks.h $(HASHTAB_H) $(TOPLEV_H) $(FLAGS_H) $(GGC_H) \
+ debug.h $(TARGET_H) $(CGRAPH_H) $(DIAGNOSTIC_H) $(TIMEVAR_H) $(PARAMS_H) \
+ $(FIBHEAP_H) $(C_COMMON_H) intl.h $(FUNCTION_H) $(BASIC_BLOCK_H) $(CFGLOOP_H) \
+ tree-iterator.h tree-pass.h opts.h $(TREE_DATA_REF_H) tree-chrec.h \
+ tree-scalar-evolution.h
ipa-inline.o : ipa-inline.c gt-ipa-inline.h $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(TREE_H) langhooks.h $(TREE_INLINE_H) $(FLAGS_H) $(CGRAPH_H) intl.h \
$(DIAGNOSTIC_H) $(FIBHEAP_H) $(PARAMS_H) $(TIMEVAR_H) tree-pass.h \
- $(COVERAGE_H) $(HASHTAB_H) $(RTL_H)
+ $(HASHTAB_H) $(COVERAGE_H) $(GGC_H) $(TREE_FLOW_H) $(RTL_H) $(IPA_PROP_H)
ipa-utils.o : ipa-utils.c $(IPA_UTILS_H) $(CONFIG_H) $(SYSTEM_H) \
coretypes.h $(TM_H) $(TREE_H) $(TREE_FLOW_H) $(TREE_INLINE_H) langhooks.h \
- pointer-set.h $(GGC_H) $(C_COMMON_H) $(TREE_GIMPLE_H) \
- $(CGRAPH_H) output.h $(FLAGS_H) tree-pass.h $(DIAGNOSTIC_H)
+ pointer-set.h $(GGC_H) $(C_COMMON_H) $(GIMPLE_H) \
+ $(CGRAPH_H) output.h $(FLAGS_H) tree-pass.h $(TIMEVAR_H) $(DIAGNOSTIC_H)
ipa-reference.o : ipa-reference.c $(CONFIG_H) $(SYSTEM_H) \
coretypes.h $(TM_H) $(TREE_H) $(TREE_FLOW_H) $(TREE_INLINE_H) langhooks.h \
pointer-set.h $(GGC_H) $(IPA_REFERENCE_H) $(IPA_UTILS_H) $(C_COMMON_H) \
- $(TREE_GIMPLE_H) $(CGRAPH_H) output.h $(FLAGS_H) tree-pass.h \
- $(DIAGNOSTIC_H) $(FUNCTION_H)
+ $(GIMPLE_H) $(CGRAPH_H) output.h $(FLAGS_H) tree-pass.h \
+ $(TIMEVAR_H) $(DIAGNOSTIC_H) $(FUNCTION_H)
ipa-pure-const.o : ipa-pure-const.c $(CONFIG_H) $(SYSTEM_H) \
coretypes.h $(TM_H) $(TREE_H) $(TREE_FLOW_H) $(TREE_INLINE_H) langhooks.h \
pointer-set.h $(GGC_H) $(IPA_UTILS_H) $(C_COMMON_H) $(TARGET_H) \
- $(TREE_GIMPLE_H) $(CGRAPH_H) output.h $(FLAGS_H) tree-pass.h $(DIAGNOSTIC_H)
+ $(GIMPLE_H) $(CGRAPH_H) output.h $(FLAGS_H) tree-pass.h $(TIMEVAR_H) \
+ $(DIAGNOSTIC_H)
ipa-type-escape.o : ipa-type-escape.c $(CONFIG_H) $(SYSTEM_H) \
coretypes.h $(TM_H) $(TREE_H) $(TREE_FLOW_H) $(TREE_INLINE_H) langhooks.h \
pointer-set.h $(GGC_H) $(IPA_TYPE_ESCAPE_H) $(IPA_UTILS_H) $(C_COMMON_H) \
- $(TREE_GIMPLE_H) $(CGRAPH_H) output.h $(FLAGS_H) tree-pass.h \
- $(DIAGNOSTIC_H) $(FUNCTION_H)
+ $(GIMPLE_H) $(CGRAPH_H) output.h $(FLAGS_H) tree-pass.h \
+ $(TIMEVAR_H) $(DIAGNOSTIC_H) $(FUNCTION_H)
ipa-struct-reorg.o: ipa-struct-reorg.c ipa-struct-reorg.h $(CONFIG_H) $(SYSTEM_H) \
- coretypes.h $(TM_H) $(RTL_H) $(TREE_H) $(FLAGS_H) output.h $(REGS_H) \
- $(EXPR_H) $(FUNCTION_H) toplev.h $(GGC_H) $(TARGET_H) langhooks.h $(COVERAGE_H) \
- libfuncs.h gt-coverage.h $(HASHTAB_H) $(IPA_TYPE_ESCAPE_H)
+ coretypes.h $(TM_H) $(GGC_H) $(TREE_H) $(RTL_H) $(GIMPLE_H) tree-inline.h \
+ $(TREE_FLOW_H) langhooks.h pointer-set.h $(HASHTAB_H) $(C_TREE_H) $(TOPLEV_H) \
+ $(FLAGS_H) debug.h $(TARGET_H) $(CGRAPH_H) $(DIAGNOSTIC_H) $(TIMEVAR_H) \
+ $(PARAMS_H) $(FIBHEAP_H) intl.h $(FUNCTION_H) $(BASIC_BLOCK_H) tree-iterator.h \
+ tree-pass.h opts.h $(IPA_TYPE_ESCAPE_H) $(TREE_DUMP_H) $(C_COMMON_H) \
+ $(GIMPLE_H)
coverage.o : coverage.c $(GCOV_IO_H) $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TM_H) $(RTL_H) $(TREE_H) $(FLAGS_H) output.h $(REGS_H) $(EXPR_H) \
- $(FUNCTION_H) toplev.h $(GGC_H) langhooks.h $(COVERAGE_H) gt-coverage.h \
- $(HASHTAB_H) $(CGRAPH_H) tree-iterator.h
+ $(FUNCTION_H) $(TOPLEV_H) $(GGC_H) langhooks.h $(COVERAGE_H) gt-coverage.h \
+ $(HASHTAB_H) tree-iterator.h $(CGRAPH_H) tree-pass.h gcov-io.c
cselib.o : cselib.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(REGS_H) hard-reg-set.h $(FLAGS_H) $(REAL_H) insn-config.h $(RECOG_H) \
- $(EMIT_RTL_H) toplev.h output.h $(FUNCTION_H) cselib.h $(GGC_H) $(TM_P_H) \
+ $(EMIT_RTL_H) $(TOPLEV_H) output.h $(FUNCTION_H) cselib.h $(GGC_H) $(TM_P_H) \
gt-cselib.h $(PARAMS_H) alloc-pool.h $(HASHTAB_H) $(TARGET_H)
cse.o : cse.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(REGS_H) \
- hard-reg-set.h $(FLAGS_H) insn-config.h $(RECOG_H) $(EXPR_H) toplev.h \
+ hard-reg-set.h $(FLAGS_H) insn-config.h $(RECOG_H) $(EXPR_H) $(TOPLEV_H) \
output.h $(FUNCTION_H) $(BASIC_BLOCK_H) $(GGC_H) $(TM_P_H) $(TIMEVAR_H) \
except.h $(TARGET_H) $(PARAMS_H) rtlhooks-def.h tree-pass.h $(REAL_H) \
$(DF_H) $(DBGCNT_H)
dce.o : dce.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(TREE_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) $(DF_H) cselib.h \
- $(DBGCNT_H) dce.h timevar.h tree-pass.h $(DBGCNT_H)
+ $(DBGCNT_H) dce.h $(TIMEVAR_H) tree-pass.h $(DBGCNT_H)
dse.o : dse.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(TREE_H) $(TM_P_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) insn-config.h \
- $(RECOG_H) $(EXPR_H) $(DF_H) cselib.h $(DBGCNT_H) timevar.h tree-pass.h \
+ $(RECOG_H) $(EXPR_H) $(DF_H) cselib.h $(DBGCNT_H) $(TIMEVAR_H) tree-pass.h \
alloc-pool.h $(ALIAS_H) dse.h $(OPTABS_H)
fwprop.o : fwprop.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
- toplev.h insn-config.h $(RECOG_H) $(FLAGS_H) $(OBSTACK_H) $(BASIC_BLOCK_H) \
- output.h $(DF_H) alloc-pool.h $(TIMEVAR_H) tree-pass.h
+ $(TOPLEV_H) insn-config.h $(RECOG_H) $(FLAGS_H) $(OBSTACK_H) $(BASIC_BLOCK_H) \
+ output.h $(DF_H) alloc-pool.h $(TIMEVAR_H) tree-pass.h $(TARGET_H) $(TM_P_H) \
+ $(CFGLOOP_H) $(EMIT_RTL_H)
web.o : web.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
- hard-reg-set.h $(FLAGS_H) $(BASIC_BLOCK_H) $(FUNCTION_H) output.h toplev.h \
+ hard-reg-set.h $(FLAGS_H) $(BASIC_BLOCK_H) $(FUNCTION_H) output.h $(TOPLEV_H) \
$(DF_H) $(OBSTACK_H) $(TIMEVAR_H) tree-pass.h
see.o : see.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
- hard-reg-set.h $(FLAGS_H) $(BASIC_BLOCK_H) $(FUNCTION_H) output.h toplev.h \
- $(DF_H) $(OBSTACK_H) $(TIMEVAR_H) tree-pass.h $(EXPR_H) dce.h
+ hard-reg-set.h $(FLAGS_H) $(BASIC_BLOCK_H) $(FUNCTION_H) output.h \
+ $(DF_H) $(OBSTACK_H) $(TIMEVAR_H) tree-pass.h $(RECOG_H) $(EXPR_H) $(SPLAY_TREE_H) \
+ $(HASHTAB_H) $(REGS_H) dce.h
gcse.o : gcse.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(REGS_H) hard-reg-set.h $(FLAGS_H) $(REAL_H) insn-config.h $(GGC_H) \
- $(RECOG_H) $(EXPR_H) $(BASIC_BLOCK_H) $(FUNCTION_H) output.h toplev.h \
+ $(RECOG_H) $(EXPR_H) $(BASIC_BLOCK_H) $(FUNCTION_H) output.h $(TOPLEV_H) \
$(TM_P_H) $(PARAMS_H) except.h gt-gcse.h $(TREE_H) cselib.h $(TIMEVAR_H) \
intl.h $(OBSTACK_H) tree-pass.h $(DF_H) $(DBGCNT_H)
resource.o : resource.c $(CONFIG_H) $(RTL_H) hard-reg-set.h $(SYSTEM_H) \
coretypes.h $(TM_H) $(REGS_H) $(FLAGS_H) output.h $(RESOURCE_H) $(DF_H) \
- $(FUNCTION_H) toplev.h $(INSN_ATTR_H) except.h $(PARAMS_H) $(TM_P_H)
+ $(FUNCTION_H) $(TOPLEV_H) $(INSN_ATTR_H) except.h $(PARAMS_H) $(TM_P_H)
lcm.o : lcm.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(REGS_H) \
hard-reg-set.h $(FLAGS_H) insn-config.h $(INSN_ATTR_H) $(RECOG_H) \
$(BASIC_BLOCK_H) $(TM_P_H) $(FUNCTION_H) output.h $(REAL_H)
@@ -2624,49 +2679,50 @@ mode-switching.o : mode-switching.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
tree-ssa-dce.o : tree-ssa-dce.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) \
$(RTL_H) $(TM_P_H) $(TREE_FLOW_H) $(DIAGNOSTIC_H) $(TIMEVAR_H) $(TM_H) \
coretypes.h $(TREE_DUMP_H) tree-pass.h $(FLAGS_H) $(BASIC_BLOCK_H) \
- $(GGC_H) hard-reg-set.h $(OBSTACK_H) $(TREE_GIMPLE_H) $(CFGLOOP_H) \
- $(SCEV_H)
+ $(GGC_H) hard-reg-set.h $(OBSTACK_H) $(GIMPLE_H) $(CFGLOOP_H) \
+ tree-scalar-evolution.h
tree-call-cdce.o : tree-call-cdce.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) \
$(RTL_H) $(TM_P_H) $(TREE_FLOW_H) $(DIAGNOSTIC_H) $(TIMEVAR_H) $(TM_H) \
coretypes.h $(TREE_DUMP_H) tree-pass.h $(FLAGS_H) $(BASIC_BLOCK_H) \
- $(GGC_H) hard-reg-set.h $(OBSTACK_H) $(TREE_GIMPLE_H)
+ $(GGC_H) hard-reg-set.h $(OBSTACK_H) $(GIMPLE_H)
tree-ssa-ccp.o : tree-ssa-ccp.c $(TREE_FLOW_H) $(CONFIG_H) \
$(SYSTEM_H) $(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) $(GGC_H) output.h \
$(DIAGNOSTIC_H) $(FUNCTION_H) $(TIMEVAR_H) $(TM_H) coretypes.h \
$(TREE_DUMP_H) $(BASIC_BLOCK_H) tree-pass.h langhooks.h \
- tree-ssa-propagate.h value-prof.h $(FLAGS_H) $(TARGET_H) toplev.h
+ tree-ssa-propagate.h value-prof.h $(FLAGS_H) $(TARGET_H) $(TOPLEV_H)
tree-sra.o : tree-sra.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(RTL_H) \
$(TM_P_H) $(TREE_FLOW_H) $(DIAGNOSTIC_H) $(TREE_INLINE_H) \
- $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) $(TREE_GIMPLE_H) \
+ $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) $(GIMPLE_H) \
langhooks.h tree-pass.h $(FLAGS_H) $(EXPR_H) $(BASIC_BLOCK_H) \
- bitmap.h $(GGC_H) hard-reg-set.h $(OBSTACK_H) $(PARAMS_H) $(TARGET_H)
+ $(BITMAP_H) $(GGC_H) hard-reg-set.h $(OBSTACK_H) $(PARAMS_H) $(TARGET_H)
tree-switch-conversion.o : tree-switch-conversion.c $(CONFIG_H) $(SYSTEM_H) \
$(TREE_H) $(TM_P_H) $(TREE_FLOW_H) $(DIAGNOSTIC_H) $(TREE_INLINE_H) \
- $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) $(TREE_GIMPLE_H) \
+ $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) $(GIMPLE_H) \
tree-pass.h $(FLAGS_H) $(EXPR_H) $(BASIC_BLOCK_H) output.h \
$(GGC_H) $(OBSTACK_H) $(PARAMS_H) $(CPPLIB_H) $(PARAMS_H)
tree-complex.o : tree-complex.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TREE_H) \
- $(TM_H) $(RTL_H) $(REAL_H) $(FLAGS_H) $(TREE_FLOW_H) $(TREE_GIMPLE_H) \
+ $(TM_H) $(RTL_H) $(REAL_H) $(FLAGS_H) $(TREE_FLOW_H) $(GIMPLE_H) \
tree-iterator.h tree-pass.h tree-ssa-propagate.h $(DIAGNOSTIC_H)
tree-vect-generic.o : tree-vect-generic.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) \
- $(TM_H) $(TREE_FLOW_H) $(TREE_GIMPLE_H) tree-iterator.h tree-pass.h \
+ $(TM_H) $(TREE_FLOW_H) $(GIMPLE_H) tree-iterator.h tree-pass.h \
$(FLAGS_H) $(OPTABS_H) $(RTL_H) $(MACHMODE_H) $(EXPR_H) \
langhooks.h $(FLAGS_H) $(DIAGNOSTIC_H) gt-tree-vect-generic.h $(GGC_H) \
coretypes.h insn-codes.h
df-core.o : df-core.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
insn-config.h $(RECOG_H) $(FUNCTION_H) $(REGS_H) alloc-pool.h \
- hard-reg-set.h $(BASIC_BLOCK_H) $(DF_H) bitmap.h sbitmap.h \
- $(TM_P_H) $(FLAGS_H) output.h tree-pass.h
+ hard-reg-set.h $(BASIC_BLOCK_H) $(DF_H) $(BITMAP_H) sbitmap.h $(TIMEVAR_H) \
+ $(TM_P_H) $(FLAGS_H) output.h tree-pass.h $(PARAMS_H)
df-problems.o : df-problems.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(RTL_H) insn-config.h $(RECOG_H) $(FUNCTION_H) $(REGS_H) alloc-pool.h \
- hard-reg-set.h $(BASIC_BLOCK_H) $(DF_H) bitmap.h sbitmap.h $(TM_P_H) \
- $(FLAGS_H) output.h except.h dce.h vecprim.h
+ hard-reg-set.h $(BASIC_BLOCK_H) $(DF_H) $(BITMAP_H) sbitmap.h $(TIMEVAR_H) \
+ $(TM_P_H) $(FLAGS_H) output.h except.h dce.h vecprim.h
df-scan.o : df-scan.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
insn-config.h $(RECOG_H) $(FUNCTION_H) $(REGS_H) alloc-pool.h \
- hard-reg-set.h $(BASIC_BLOCK_H) $(DF_H) bitmap.h sbitmap.h $(TM_P_H) \
- $(FLAGS_H) $(TARGET_H) $(TARGET_DEF_H) $(TREE_H) output.h tree-pass.h
+ hard-reg-set.h $(BASIC_BLOCK_H) $(DF_H) $(BITMAP_H) sbitmap.h $(TIMEVAR_H) \
+ $(TM_P_H) $(FLAGS_H) $(TARGET_H) $(TARGET_DEF_H) $(TREE_H) output.h \
+ tree-pass.h
df-byte-scan.o : df-byte-scan.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
- $(DF_H) output.h $(DBGCNT_H)
+ tm_p.h $(DF_H) output.h $(DBGCNT_H)
regstat.o : regstat.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(TM_P_H) $(FLAGS_H) $(REGS_H) output.h except.h hard-reg-set.h \
$(BASIC_BLOCK_H) $(TIMEVAR_H) $(DF_H)
@@ -2676,66 +2732,66 @@ var-tracking.o : var-tracking.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(REGS_H) $(EXPR_H) $(TIMEVAR_H) tree-pass.h
profile.o : profile.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(TREE_H) $(FLAGS_H) output.h $(REGS_H) $(EXPR_H) $(FUNCTION_H) \
- toplev.h $(COVERAGE_H) $(TREE_FLOW_H) value-prof.h cfghooks.h \
+ $(TOPLEV_H) $(COVERAGE_H) $(TREE_FLOW_H) value-prof.h cfghooks.h \
$(CFGLOOP_H) $(TIMEVAR_H) tree-pass.h
tree-profile.o : tree-profile.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TM_H) $(RTL_H) $(TREE_H) $(FLAGS_H) output.h $(REGS_H) $(EXPR_H) \
- $(FUNCTION_H) toplev.h $(COVERAGE_H) $(TREE_H) value-prof.h $(TREE_DUMP_H) \
+ $(FUNCTION_H) $(TOPLEV_H) $(COVERAGE_H) $(TREE_H) value-prof.h $(TREE_DUMP_H) \
tree-pass.h $(TREE_FLOW_H) $(TIMEVAR_H) $(GGC_H) gt-tree-profile.h $(CGRAPH_H)
value-prof.o : value-prof.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(BASIC_BLOCK_H) hard-reg-set.h value-prof.h $(EXPR_H) output.h $(FLAGS_H) \
$(RECOG_H) insn-config.h $(OPTABS_H) $(REGS_H) $(GGC_H) $(DIAGNOSTIC_H) \
$(TREE_H) $(COVERAGE_H) $(RTL_H) $(GCOV_IO_H) $(TREE_FLOW_H) \
- tree-flow-inline.h $(TIMEVAR_H) tree-pass.h
+ tree-flow-inline.h $(TIMEVAR_H) tree-pass.h $(TOPLEV_H) pointer-set.h
loop-doloop.o : loop-doloop.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(RTL_H) $(FLAGS_H) $(EXPR_H) hard-reg-set.h $(BASIC_BLOCK_H) $(TM_P_H) \
- toplev.h $(CFGLOOP_H) output.h $(PARAMS_H) $(TARGET_H)
+ $(TOPLEV_H) $(CFGLOOP_H) output.h $(PARAMS_H) $(TARGET_H)
alloc-pool.o : alloc-pool.c $(CONFIG_H) $(SYSTEM_H) alloc-pool.h $(HASHTAB_H)
auto-inc-dec.o : auto-inc-dec.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(TREE_H) $(RTL_H) $(TM_P_H) hard-reg-set.h $(BASIC_BLOCK_H) insn-config.h \
- $(REGS_H) $(FLAGS_H) output.h $(FUNCTION_H) except.h toplev.h $(RECOG_H) \
+ $(REGS_H) $(FLAGS_H) output.h $(FUNCTION_H) except.h $(TOPLEV_H) $(RECOG_H) \
$(EXPR_H) $(TIMEVAR_H) tree-pass.h $(DF_H) $(DBGCNT_H)
cfg.o : cfg.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(FLAGS_H) \
- $(REGS_H) hard-reg-set.h output.h toplev.h $(FUNCTION_H) except.h $(GGC_H) \
+ $(REGS_H) hard-reg-set.h output.h $(TOPLEV_H) $(FUNCTION_H) except.h $(GGC_H) \
$(TM_P_H) $(TIMEVAR_H) $(OBSTACK_H) $(TREE_H) alloc-pool.h \
- $(HASHTAB_H) $(DF_H) $(CFGLOOP_H) $(TREE_FLOW_H)
+ $(HASHTAB_H) $(DF_H) $(CFGLOOP_H) $(TREE_FLOW_H) tree-pass.h
cfghooks.o: cfghooks.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
- $(TREE_H) $(BASIC_BLOCK_H) $(TREE_FLOW_H) $(TIMEVAR_H) toplev.h $(CFGLOOP_H)
+ $(TREE_H) $(BASIC_BLOCK_H) $(TREE_FLOW_H) $(TIMEVAR_H) $(TOPLEV_H) $(CFGLOOP_H)
cfgexpand.o : cfgexpand.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
$(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) $(FUNCTION_H) $(TIMEVAR_H) $(TM_H) \
coretypes.h $(TREE_DUMP_H) except.h langhooks.h tree-pass.h $(RTL_H) \
- $(DIAGNOSTIC_H) toplev.h $(BASIC_BLOCK_H) $(FLAGS_H) debug.h $(PARAMS_H) \
- value-prof.h
+ $(DIAGNOSTIC_H) $(TOPLEV_H) $(BASIC_BLOCK_H) $(FLAGS_H) debug.h $(PARAMS_H) \
+ value-prof.h $(TREE_INLINE_H) $(TARGET_H)
cfgrtl.o : cfgrtl.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(FLAGS_H) insn-config.h $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h \
- output.h toplev.h $(FUNCTION_H) except.h $(TM_P_H) insn-config.h $(EXPR_H) \
+ output.h $(TOPLEV_H) $(FUNCTION_H) except.h $(TM_P_H) insn-config.h $(EXPR_H) \
$(CFGLAYOUT_H) $(CFGLOOP_H) $(OBSTACK_H) $(TARGET_H) $(TREE_H) \
- tree-pass.h $(DF_H)
+ tree-pass.h $(DF_H) $(GGC_H)
cfganal.o : cfganal.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(BASIC_BLOCK_H) hard-reg-set.h insn-config.h $(RECOG_H) $(TM_P_H) \
- $(TIMEVAR_H) $(OBSTACK_H) toplev.h vecprim.h
+ $(TIMEVAR_H) $(OBSTACK_H) $(TOPLEV_H) vecprim.h
cfgbuild.o : cfgbuild.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
- $(FLAGS_H) $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h output.h toplev.h \
+ $(FLAGS_H) $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h output.h $(TOPLEV_H) \
$(FUNCTION_H) except.h $(TIMEVAR_H) $(TREE_H)
cfgcleanup.o : cfgcleanup.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(RTL_H) $(TIMEVAR_H) hard-reg-set.h output.h $(FLAGS_H) $(RECOG_H) \
- toplev.h insn-config.h cselib.h $(TARGET_H) $(TM_P_H) $(PARAMS_H) \
+ $(TOPLEV_H) insn-config.h cselib.h $(TARGET_H) $(TM_P_H) $(PARAMS_H) \
$(REGS_H) $(EMIT_RTL_H) $(CFGLAYOUT_H) tree-pass.h $(CFGLOOP_H) $(EXPR_H) \
- $(DF_H) $(DBGCNT_H)
+ $(DF_H) $(DBGCNT_H) dce.h
cfgloop.o : cfgloop.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) coretypes.h $(TM_H) \
$(BASIC_BLOCK_H) hard-reg-set.h $(CFGLOOP_H) $(FLAGS_H) $(FUNCTION_H) \
- $(OBSTACK_H) toplev.h $(TREE_FLOW_H) $(TREE_H) pointer-set.h output.h \
+ $(OBSTACK_H) $(TOPLEV_H) $(TREE_FLOW_H) $(TREE_H) pointer-set.h output.h \
$(GGC_H)
cfgloopanal.o : cfgloopanal.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) \
$(BASIC_BLOCK_H) hard-reg-set.h $(CFGLOOP_H) $(EXPR_H) coretypes.h $(TM_H) \
$(OBSTACK_H) output.h graphds.h $(PARAMS_H)
-graphds.o : graphds.c graphds.h $(CONFIG_H) $(SYSTEM_H) bitmap.h $(OBSTACK_H) \
+graphds.o : graphds.c graphds.h $(CONFIG_H) $(SYSTEM_H) $(BITMAP_H) $(OBSTACK_H) \
coretypes.h vec.h vecprim.h
loop-iv.o : loop-iv.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(BASIC_BLOCK_H) \
hard-reg-set.h $(CFGLOOP_H) $(EXPR_H) coretypes.h $(TM_H) $(OBSTACK_H) \
- output.h intl.h $(DF_H) $(HASHTAB_H)
+ output.h intl.h $(TOPLEV_H) $(DF_H) $(HASHTAB_H)
loop-invariant.o : loop-invariant.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) \
- $(BASIC_BLOCK_H) hard-reg-set.h $(CFGLOOP_H) $(EXPR_H) coretypes.h \
+ $(BASIC_BLOCK_H) hard-reg-set.h $(CFGLOOP_H) $(EXPR_H) $(RECOG_H) coretypes.h \
$(TM_H) $(TM_P_H) $(FUNCTION_H) $(FLAGS_H) $(DF_H) $(OBSTACK_H) output.h \
$(HASHTAB_H) except.h
cfgloopmanip.o : cfgloopmanip.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) \
@@ -2752,45 +2808,45 @@ loop-unroll.o: loop-unroll.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TM_H) \
output.h $(EXPR_H) coretypes.h $(TM_H) $(HASHTAB_H) $(RECOG_H) \
$(OBSTACK_H)
dominance.o : dominance.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
- hard-reg-set.h $(BASIC_BLOCK_H) et-forest.h $(OBSTACK_H) toplev.h \
+ hard-reg-set.h $(BASIC_BLOCK_H) et-forest.h $(OBSTACK_H) $(TOPLEV_H) \
$(TIMEVAR_H) graphds.h vecprim.h pointer-set.h
et-forest.o : et-forest.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
et-forest.h alloc-pool.h $(BASIC_BLOCK_H)
combine.o : combine.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(FLAGS_H) $(FUNCTION_H) insn-config.h $(INSN_ATTR_H) $(REGS_H) $(EXPR_H) \
rtlhooks-def.h $(BASIC_BLOCK_H) $(RECOG_H) $(REAL_H) hard-reg-set.h \
- toplev.h $(TM_P_H) $(TREE_H) $(TARGET_H) output.h $(PARAMS_H) $(OPTABS_H) \
- insn-codes.h $(TIMEVAR_H) tree-pass.h $(DF_H)
+ $(TOPLEV_H) $(TM_P_H) $(TREE_H) $(TARGET_H) output.h $(PARAMS_H) $(OPTABS_H) \
+ insn-codes.h $(TIMEVAR_H) tree-pass.h $(DF_H) vecprim.h $(CGRAPH_H)
regclass.o : regclass.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
- hard-reg-set.h $(FLAGS_H) $(BASIC_BLOCK_H) $(REGS_H) insn-config.h \
- $(RECOG_H) reload.h $(REAL_H) toplev.h $(FUNCTION_H) output.h $(GGC_H) \
+ hard-reg-set.h $(FLAGS_H) $(BASIC_BLOCK_H) addresses.h $(REGS_H) insn-config.h \
+ $(RECOG_H) reload.h $(REAL_H) $(TOPLEV_H) $(FUNCTION_H) output.h $(GGC_H) \
$(TM_P_H) $(EXPR_H) $(TIMEVAR_H) gt-regclass.h $(HASHTAB_H) \
$(TARGET_H) tree-pass.h $(DF_H)
local-alloc.o : local-alloc.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(RTL_H) $(FLAGS_H) $(REGS_H) hard-reg-set.h insn-config.h $(RECOG_H) \
- output.h $(FUNCTION_H) $(INSN_ATTR_H) toplev.h except.h reload.h $(TM_P_H) \
+ output.h $(FUNCTION_H) $(INSN_ATTR_H) $(TOPLEV_H) except.h reload.h $(TM_P_H) \
$(GGC_H) $(INTEGRATE_H) $(TIMEVAR_H) tree-pass.h $(DF_H) $(DBGCNT_H)
bitmap.o : bitmap.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
- $(FLAGS_H) $(GGC_H) gt-bitmap.h bitmap.h $(OBSTACK_H)
+ $(FLAGS_H) $(GGC_H) gt-bitmap.h $(BITMAP_H) $(OBSTACK_H) $(HASHTAB_H)
global.o : global.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(FLAGS_H) reload.h $(FUNCTION_H) $(RECOG_H) $(REGS_H) hard-reg-set.h \
- insn-config.h output.h toplev.h $(TM_P_H) $(MACHMODE_H) tree-pass.h \
+ insn-config.h output.h $(TOPLEV_H) $(TM_P_H) $(MACHMODE_H) tree-pass.h \
$(TIMEVAR_H) vecprim.h $(DF_H) $(DBGCNT_H) $(RA_H)
ra-conflict.o : ra-conflict.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(FLAGS_H) reload.h $(FUNCTION_H) $(RECOG_H) $(REGS_H) hard-reg-set.h \
- insn-config.h output.h toplev.h $(TM_P_H) $(MACHMODE_H) tree-pass.h \
- $(TIMEVAR_H) vecprim.h $(DF_H) $(RA_H) sbitmap.h
+ insn-config.h output.h $(TOPLEV_H) $(TM_P_H) $(MACHMODE_H) tree-pass.h \
+ $(TIMEVAR_H) vecprim.h $(DF_H) $(RA_H) sbitmap.h sparseset.h
varray.o : varray.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(GGC_H) \
- $(HASHTAB_H) $(BCONFIG_H) $(VARRAY_H) toplev.h
+ $(HASHTAB_H) $(BCONFIG_H) $(VARRAY_H) $(TOPLEV_H)
vec.o : vec.c $(CONFIG_H) $(SYSTEM_H) coretypes.h vec.h $(GGC_H) \
- toplev.h
+ $(TOPLEV_H)
reload.o : reload.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(FLAGS_H) output.h $(EXPR_H) $(OPTABS_H) reload.h $(RECOG_H) \
- hard-reg-set.h insn-config.h $(REGS_H) $(FUNCTION_H) real.h toplev.h \
+ hard-reg-set.h insn-config.h $(REGS_H) $(FUNCTION_H) real.h $(TOPLEV_H) \
addresses.h $(TM_P_H) $(PARAMS_H) $(TARGET_H) $(REAL_H) $(DF_H)
reload1.o : reload1.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(EXPR_H) $(OPTABS_H) reload.h $(REGS_H) hard-reg-set.h insn-config.h \
- $(BASIC_BLOCK_H) $(RECOG_H) output.h $(FUNCTION_H) toplev.h $(TM_P_H) \
+ $(BASIC_BLOCK_H) $(RECOG_H) output.h $(FUNCTION_H) $(TOPLEV_H) $(TM_P_H) \
addresses.h except.h $(TREE_H) $(REAL_H) $(FLAGS_H) $(MACHMODE_H) \
$(OBSTACK_H) $(DF_H) $(TARGET_H) dse.h ira.h
rtlhooks.o : rtlhooks.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
@@ -2798,28 +2854,28 @@ rtlhooks.o : rtlhooks.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
postreload.o : postreload.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(RTL_H) $(REAL_H) $(FLAGS_H) $(EXPR_H) $(OPTABS_H) reload.h $(REGS_H) \
hard-reg-set.h insn-config.h $(BASIC_BLOCK_H) $(RECOG_H) output.h \
- $(FUNCTION_H) toplev.h cselib.h $(TM_P_H) except.h $(TREE_H) $(MACHMODE_H) \
- $(OBSTACK_H) $(TIMEVAR_H) tree-pass.h $(DF_H)
+ $(FUNCTION_H) $(TOPLEV_H) cselib.h $(TM_P_H) except.h $(TREE_H) $(MACHMODE_H) \
+ $(OBSTACK_H) $(TIMEVAR_H) tree-pass.h $(DF_H) $(DBGCNT_H)
postreload-gcse.o : postreload-gcse.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TM_H) $(RTL_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) insn-config.h \
- $(RECOG_H) $(EXPR_H) $(BASIC_BLOCK_H) $(FUNCTION_H) output.h toplev.h \
+ $(RECOG_H) $(EXPR_H) $(BASIC_BLOCK_H) $(FUNCTION_H) output.h $(TOPLEV_H) \
$(TM_P_H) except.h $(TREE_H) $(TARGET_H) $(HASHTAB_H) intl.h $(OBSTACK_H) \
$(PARAMS_H) $(TIMEVAR_H) tree-pass.h $(REAL_H) $(DBGCNT_H)
caller-save.o : caller-save.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(FLAGS_H) $(REGS_H) hard-reg-set.h insn-config.h $(BASIC_BLOCK_H) $(FUNCTION_H) \
- addresses.h $(RECOG_H) reload.h $(EXPR_H) toplev.h $(TM_P_H) $(DF_H) \
- output.h $(CFGLOOP_H) ira.h gt-caller-save.h
+ addresses.h $(RECOG_H) reload.h $(EXPR_H) $(TOPLEV_H) $(TM_P_H) $(DF_H) \
+ output.h $(CFGLOOP_H) ira.h gt-caller-save.h $(GGC_H)
bt-load.o : bt-load.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) except.h \
$(RTL_H) hard-reg-set.h $(REGS_H) $(TM_P_H) $(FIBHEAP_H) output.h $(EXPR_H) \
- $(TARGET_H) $(FLAGS_H) $(INSN_ATTR_H) $(FUNCTION_H) tree-pass.h toplev.h \
- $(DF_H) $(GGC_H)
+ $(TARGET_H) $(FLAGS_H) $(INSN_ATTR_H) $(FUNCTION_H) tree-pass.h $(TOPLEV_H) \
+ $(DF_H) vecprim.h $(RECOG_H)
reorg.o : reorg.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
conditions.h hard-reg-set.h $(BASIC_BLOCK_H) $(REGS_H) insn-config.h \
$(INSN_ATTR_H) except.h $(RECOG_H) $(FUNCTION_H) $(FLAGS_H) output.h \
- $(EXPR_H) toplev.h $(PARAMS_H) $(TM_P_H) $(OBSTACK_H) $(RESOURCE_H) \
+ $(EXPR_H) $(TOPLEV_H) $(PARAMS_H) $(TM_P_H) $(OBSTACK_H) $(RESOURCE_H) \
$(TIMEVAR_H) $(TARGET_H) tree-pass.h
alias.o : alias.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
- $(FLAGS_H) hard-reg-set.h $(BASIC_BLOCK_H) $(REGS_H) toplev.h output.h \
+ $(FLAGS_H) hard-reg-set.h $(BASIC_BLOCK_H) $(REGS_H) $(TOPLEV_H) output.h \
$(ALIAS_H) $(EMIT_RTL_H) $(GGC_H) $(FUNCTION_H) cselib.h $(TREE_H) $(TM_P_H) \
langhooks.h $(TARGET_H) gt-alias.h $(TIMEVAR_H) $(CGRAPH_H) \
$(SPLAY_TREE_H) $(VARRAY_H) $(IPA_TYPE_ESCAPE_H) $(DF_H) tree-pass.h
@@ -2831,7 +2887,7 @@ init-regs.o : init-regs.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(BASIC_BLOCK_H) $(FLAGS_H) $(DF_H)
ira-build.o: ira-build.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(TARGET_H) $(RTL_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) \
- insn-config.h $(RECOG_H) $(BASIC_BLOCK_H) toplev.h $(TM_P_H) \
+ insn-config.h $(RECOG_H) $(BASIC_BLOCK_H) $(TOPLEV_H) $(TM_P_H) \
$(PARAMS_H) $(DF_H) sparseset.h $(IRA_INT_H)
ira-costs.o: ira-costs.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(TARGET_H) $(RTL_H) insn-config.h $(RECOG_H) \
@@ -2840,141 +2896,141 @@ ira-costs.o: ira-costs.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(IRA_INT_H)
ira-conflicts.o: ira-conflicts.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(TARGET_H) $(RTL_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) \
- insn-config.h $(RECOG_H) $(BASIC_BLOCK_H) toplev.h $(TM_P_H) $(PARAMS_H) \
+ insn-config.h $(RECOG_H) $(BASIC_BLOCK_H) $(TOPLEV_H) $(TM_P_H) $(PARAMS_H) \
$(DF_H) sparseset.h $(IRA_INT_H)
ira-color.o: ira-color.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(TARGET_H) $(RTL_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) \
- $(EXPR_H) $(BASIC_BLOCK_H) toplev.h $(TM_P_H) $(PARAMS_H) \
+ $(EXPR_H) $(BASIC_BLOCK_H) $(TOPLEV_H) $(TM_P_H) $(PARAMS_H) \
$(DF_H) $(SPLAY_TREE_H) $(IRA_INT_H)
ira-emit.o: ira-emit.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(TARGET_H) $(RTL_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) \
- $(EXPR_H) $(BASIC_BLOCK_H) toplev.h $(TM_P_H) $(PARAMS_H) \
+ $(EXPR_H) $(BASIC_BLOCK_H) $(TOPLEV_H) $(TM_P_H) $(PARAMS_H) \
$(IRA_INT_H)
ira-lives.o: ira-lives.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(TARGET_H) $(RTL_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) \
- insn-config.h $(RECOG_H) $(BASIC_BLOCK_H) toplev.h $(TM_P_H) $(PARAMS_H) \
+ insn-config.h $(RECOG_H) $(BASIC_BLOCK_H) $(TOPLEV_H) $(TM_P_H) $(PARAMS_H) \
$(DF_H) sparseset.h $(IRA_INT_H)
ira.o: ira.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TARGET_H) $(TM_H) $(RTL_H) $(RECOG_H) \
$(REGS_H) hard-reg-set.h $(FLAGS_H) $(OBSTACK_H) \
- $(EXPR_H) $(BASIC_BLOCK_H) toplev.h $(TM_P_H) \
+ $(EXPR_H) $(BASIC_BLOCK_H) $(TOPLEV_H) $(TM_P_H) \
$(DF_H) $(IRA_INT_H) $(PARAMS_H) $(TIMEVAR_H) $(INTEGRATE_H) \
tree-pass.h output.h
regmove.o : regmove.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
insn-config.h $(TIMEVAR_H) tree-pass.h $(DF_H)\
$(RECOG_H) output.h $(REGS_H) hard-reg-set.h $(FLAGS_H) $(FUNCTION_H) \
- $(EXPR_H) $(BASIC_BLOCK_H) toplev.h $(TM_P_H) except.h reload.h
+ $(EXPR_H) $(BASIC_BLOCK_H) $(TOPLEV_H) $(TM_P_H) except.h reload.h
combine-stack-adj.o : combine-stack-adj.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TM_H) $(RTL_H) insn-config.h $(TIMEVAR_H) tree-pass.h \
$(RECOG_H) output.h $(REGS_H) hard-reg-set.h $(FLAGS_H) $(FUNCTION_H) \
- $(EXPR_H) $(BASIC_BLOCK_H) toplev.h $(TM_P_H) except.h reload.h
+ $(EXPR_H) $(BASIC_BLOCK_H) $(TOPLEV_H) $(TM_P_H) $(DF_H) except.h reload.h
ddg.o : ddg.c $(DDG_H) $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TARGET_H) \
- toplev.h $(RTL_H) $(TM_P_H) $(REGS_H) $(FUNCTION_H) \
+ $(TOPLEV_H) $(RTL_H) $(TM_P_H) $(REGS_H) $(FUNCTION_H) \
$(FLAGS_H) insn-config.h $(INSN_ATTR_H) except.h $(RECOG_H) \
- $(SCHED_INT_H) $(CFGLAYOUT_H) $(CFGLOOP_H) $(EXPR_H) bitmap.h \
+ $(SCHED_INT_H) $(CFGLAYOUT_H) $(CFGLOOP_H) $(EXPR_H) $(BITMAP_H) \
hard-reg-set.h sbitmap.h $(TM_H)
modulo-sched.o : modulo-sched.c $(DDG_H) $(CONFIG_H) $(CONFIG_H) $(SYSTEM_H) \
- coretypes.h $(TARGET_H) toplev.h $(RTL_H) $(TM_P_H) $(REGS_H) $(FUNCTION_H) \
+ coretypes.h $(TARGET_H) $(TOPLEV_H) $(RTL_H) $(TM_P_H) $(REGS_H) $(FUNCTION_H) \
$(FLAGS_H) insn-config.h $(INSN_ATTR_H) except.h $(RECOG_H) \
$(SCHED_INT_H) $(CFGLAYOUT_H) $(CFGLOOP_H) $(EXPR_H) $(PARAMS_H) \
- cfghooks.h $(GCOV_IO_H) hard-reg-set.h $(TM_H) timevar.h tree-pass.h \
+ cfghooks.h $(GCOV_IO_H) hard-reg-set.h $(TM_H) $(TIMEVAR_H) tree-pass.h \
$(DF_H) $(DBGCNT_H)
haifa-sched.o : haifa-sched.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(SCHED_INT_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) insn-config.h $(FUNCTION_H) \
- $(INSN_ATTR_H) toplev.h $(RECOG_H) except.h $(TM_P_H) $(TARGET_H) output.h \
+ $(INSN_ATTR_H) $(TOPLEV_H) $(RECOG_H) except.h $(TM_P_H) $(TARGET_H) output.h \
$(PARAMS_H) $(DBGCNT_H)
sched-deps.o : sched-deps.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(RTL_H) $(SCHED_INT_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) insn-config.h \
- $(FUNCTION_H) $(INSN_ATTR_H) toplev.h $(RECOG_H) except.h cselib.h \
- $(PARAMS_H) $(TM_P_H)
+ $(FUNCTION_H) $(INSN_ATTR_H) $(TOPLEV_H) $(RECOG_H) except.h cselib.h \
+ $(PARAMS_H) $(TM_P_H)
sched-rgn.o : sched-rgn.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(RTL_H) $(SCHED_INT_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) insn-config.h \
- $(FUNCTION_H) $(INSN_ATTR_H) toplev.h $(RECOG_H) except.h $(PARAMS_H) \
+ $(FUNCTION_H) $(INSN_ATTR_H) $(TOPLEV_H) $(RECOG_H) except.h $(PARAMS_H) \
$(TM_P_H) $(TARGET_H) $(CFGLAYOUT_H) $(TIMEVAR_H) tree-pass.h $(DBGCNT_H)
sched-ebb.o : sched-ebb.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(RTL_H) $(SCHED_INT_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) insn-config.h \
- $(FUNCTION_H) $(INSN_ATTR_H) toplev.h $(RECOG_H) except.h $(TM_P_H) \
- $(PARAMS_H) $(CFGLAYOUT_H) $(TARGET_H) output.h
+ $(FUNCTION_H) $(INSN_ATTR_H) $(TOPLEV_H) $(RECOG_H) except.h $(TM_P_H) \
+ $(PARAMS_H) $(CFGLAYOUT_H) $(TARGET_H) output.h
sched-vis.o : sched-vis.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(RTL_H) $(SCHED_INT_H) hard-reg-set.h $(BASIC_BLOCK_H) $(OBSTACK_H) \
- $(TM_P_H) $(REAL_H) toplev.h tree-pass.h
+ $(REAL_H) tree-pass.h
final.o : final.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(TREE_H) $(FLAGS_H) intl.h $(REGS_H) $(RECOG_H) conditions.h \
insn-config.h $(INSN_ATTR_H) $(FUNCTION_H) output.h hard-reg-set.h \
- except.h debug.h xcoffout.h toplev.h reload.h dwarf2out.h tree-pass.h \
+ except.h debug.h xcoffout.h $(TOPLEV_H) reload.h dwarf2out.h tree-pass.h \
$(BASIC_BLOCK_H) $(TM_P_H) $(TARGET_H) $(EXPR_H) $(CFGLAYOUT_H) dbxout.h \
$(TIMEVAR_H) $(CGRAPH_H) $(COVERAGE_H) $(REAL_H) $(DF_H) vecprim.h $(GGC_H) \
$(CFGLOOP_H) $(PARAMS_H)
recog.o : recog.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(FUNCTION_H) $(BASIC_BLOCK_H) $(REGS_H) $(RECOG_H) $(EXPR_H) \
- $(FLAGS_H) insn-config.h $(INSN_ATTR_H) toplev.h output.h reload.h \
+ $(FLAGS_H) insn-config.h $(INSN_ATTR_H) $(TOPLEV_H) output.h reload.h \
addresses.h $(TM_P_H) $(TIMEVAR_H) tree-pass.h hard-reg-set.h $(REAL_H) \
- $(DF_H) $(DBGCNT_H)
+ $(DF_H) $(DBGCNT_H) $(TARGET_H)
reg-stack.o : reg-stack.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(RTL_H) $(TREE_H) $(RECOG_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) \
- insn-config.h toplev.h reload.h $(FUNCTION_H) $(TM_P_H) $(GGC_H) \
- $(BASIC_BLOCK_H) output.h $(VARRAY_H) $(TIMEVAR_H) tree-pass.h \
- $(TARGET_H) vecprim.h $(DF_H)
+ insn-config.h $(TOPLEV_H) reload.h $(FUNCTION_H) $(TM_P_H) $(GGC_H) \
+ $(BASIC_BLOCK_H) $(CFGLAYOUT_H) output.h $(VARRAY_H) $(TIMEVAR_H) \
+ tree-pass.h $(TARGET_H) vecprim.h $(DF_H)
sreal.o: sreal.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) sreal.h
predict.o: predict.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(TREE_H) $(FLAGS_H) insn-config.h $(BASIC_BLOCK_H) $(REGS_H) \
- hard-reg-set.h output.h toplev.h $(RECOG_H) $(FUNCTION_H) except.h \
+ hard-reg-set.h output.h $(TOPLEV_H) $(RECOG_H) $(FUNCTION_H) except.h \
$(TM_P_H) $(PREDICT_H) sreal.h $(PARAMS_H) $(TARGET_H) $(CFGLOOP_H) \
$(COVERAGE_H) $(SCEV_H) $(GGC_H) predict.def $(TIMEVAR_H) $(TREE_DUMP_H) \
$(TREE_FLOW_H) tree-pass.h $(EXPR_H) pointer-set.h
-lists.o: lists.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) toplev.h \
+lists.o: lists.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TOPLEV_H) \
$(RTL_H) $(GGC_H) gt-lists.h
bb-reorder.o : bb-reorder.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(RTL_H) $(FLAGS_H) $(TIMEVAR_H) output.h $(CFGLAYOUT_H) $(FIBHEAP_H) \
$(TARGET_H) $(FUNCTION_H) $(TM_P_H) $(OBSTACK_H) $(EXPR_H) $(REGS_H) \
- $(PARAMS_H) toplev.h tree-pass.h
+ $(PARAMS_H) $(TOPLEV_H) tree-pass.h $(DF_H)
tracer.o : tracer.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(TREE_H) $(BASIC_BLOCK_H) hard-reg-set.h output.h $(CFGLAYOUT_H) \
$(FLAGS_H) $(TIMEVAR_H) $(PARAMS_H) $(COVERAGE_H) $(FIBHEAP_H) \
- tree-pass.h
+ tree-pass.h $(TREE_FLOW_H) $(TREE_INLINE_H)
cfglayout.o : cfglayout.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(RTL_H) $(TREE_H) insn-config.h $(BASIC_BLOCK_H) hard-reg-set.h output.h \
$(FUNCTION_H) $(CFGLAYOUT_H) $(CFGLOOP_H) $(TARGET_H) gt-cfglayout.h \
$(GGC_H) alloc-pool.h $(FLAGS_H) $(OBSTACK_H) tree-pass.h vecprim.h \
$(DF_H)
timevar.o : timevar.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
- $(TIMEVAR_H) $(FLAGS_H) intl.h toplev.h $(RTL_H) timevar.def
+ $(TIMEVAR_H) $(FLAGS_H) intl.h $(TOPLEV_H) $(RTL_H) timevar.def
regrename.o : regrename.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(RTL_H) insn-config.h $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h \
output.h $(RECOG_H) $(FUNCTION_H) $(OBSTACK_H) $(FLAGS_H) $(TM_P_H) \
- addresses.h reload.h toplev.h $(TIMEVAR_H) tree-pass.h $(DF_H)
+ addresses.h reload.h $(TOPLEV_H) $(TIMEVAR_H) tree-pass.h $(DF_H)
ifcvt.o : ifcvt.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
- $(REGS_H) toplev.h $(FLAGS_H) insn-config.h $(FUNCTION_H) $(RECOG_H) \
+ $(REGS_H) $(TOPLEV_H) $(FLAGS_H) insn-config.h $(FUNCTION_H) $(RECOG_H) \
$(TARGET_H) $(BASIC_BLOCK_H) $(EXPR_H) output.h except.h $(TM_P_H) \
$(REAL_H) $(OPTABS_H) $(CFGLOOP_H) hard-reg-set.h $(TIMEVAR_H) tree-pass.h \
$(DF_H) $(DBGCNT_H)
lambda-mat.o : lambda-mat.c $(LAMBDA_H) $(GGC_H) $(SYSTEM_H) $(CONFIG_H) \
- $(TM_H) coretypes.h $(TREE_H)
+ $(TM_H) coretypes.h $(TREE_H) $(TREE_FLOW_H)
lambda-trans.o: lambda-trans.c $(LAMBDA_H) $(GGC_H) $(SYSTEM_H) $(CONFIG_H) \
- $(TM_H) coretypes.h $(TARGET_H) $(TREE_H)
+ $(TM_H) coretypes.h $(TARGET_H) $(TREE_H) $(TREE_FLOW_H)
lambda-code.o: lambda-code.c $(LAMBDA_H) $(GGC_H) $(SYSTEM_H) $(CONFIG_H) \
$(TM_H) $(OPTABS_H) $(TREE_H) $(RTL_H) $(BASIC_BLOCK_H) \
$(DIAGNOSTIC_H) $(TREE_FLOW_H) $(TREE_DUMP_H) $(TIMEVAR_H) $(CFGLOOP_H) \
$(TREE_DATA_REF_H) $(SCEV_H) $(EXPR_H) coretypes.h $(TARGET_H) \
tree-chrec.h tree-pass.h vec.h vecprim.h $(OBSTACK_H) pointer-set.h
-params.o : params.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(PARAMS_H) toplev.h
+params.o : params.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(PARAMS_H) $(TOPLEV_H)
pointer-set.o: pointer-set.c pointer-set.h $(CONFIG_H) $(SYSTEM_H)
hooks.o: hooks.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(HOOKS_H)
pretty-print.o: $(CONFIG_H) $(SYSTEM_H) coretypes.h intl.h $(PRETTY_PRINT_H) \
$(TREE_H)
errors.o : errors.c $(CONFIG_H) $(SYSTEM_H) errors.h $(BCONFIG_H)
-dbgcnt.o: dbgcnt.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(DBGCNT_H) $(TM_H) \
- $(RTL_H) output.h
+dbgcnt.o: dbgcnt.c $(CONFIG_H) $(SYSTEM_H) coretypes.h errors.h $(DBGCNT_H) \
+ $(TM_H) $(RTL_H) output.h
lower-subreg.o : lower-subreg.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(MACHMODE_H) $(TM_H) $(RTL_H) $(TM_P_H) $(TIMEVAR_H) $(FLAGS_H) \
- insn-config.h $(BASIC_BLOCK_H) $(RECOG_H) $(OBSTACK_H) bitmap.h \
- $(EXPR_H) $(REGS_H) tree-pass.h $(DF_H)
+ insn-config.h $(BASIC_BLOCK_H) $(RECOG_H) $(OBSTACK_H) $(BITMAP_H) \
+ $(EXPR_H) except.h $(REGS_H) tree-pass.h $(DF_H)
$(out_object_file): $(out_file) $(CONFIG_H) coretypes.h $(TM_H) $(TREE_H) \
$(RTL_H) $(REGS_H) hard-reg-set.h insn-config.h conditions.h \
- output.h $(INSN_ATTR_H) $(SYSTEM_H) toplev.h $(TARGET_H) libfuncs.h \
+ output.h $(INSN_ATTR_H) $(SYSTEM_H) $(TOPLEV_H) $(TARGET_H) libfuncs.h \
$(TARGET_DEF_H) $(FUNCTION_H) $(SCHED_INT_H) $(TM_P_H) $(EXPR_H) \
- langhooks.h $(GGC_H) $(OPTABS_H) $(REAL_H) tm-constrs.h
+ langhooks.h $(GGC_H) $(OPTABS_H) $(REAL_H) tm-constrs.h $(GIMPLE_H)
$(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) \
$(out_file) $(OUTPUT_OPTION)
@@ -2983,7 +3039,7 @@ mips-tfile: mips-tfile.o version.o $(LIBDEPS)
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ mips-tfile.o version.o $(LIBS)
mips-tfile.o : mips-tfile.c $(CONFIG_H) $(RTL_H) $(SYSTEM_H) coretypes.h \
- $(TM_H) version.h $(srcdir)/../include/getopt.h gstab.h intl.h
+ $(TM_H) version.h $(srcdir)/../include/getopt.h $(GSTAB_H) intl.h
mips-tdump: mips-tdump.o version.o $(LIBDEPS)
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ mips-tdump.o version.o $(LIBS)
@@ -3025,40 +3081,41 @@ s-mddeps: $(md_file) $(MD_INCLUDES) build/genmddeps$(build_exeext)
# Header dependencies for generated source files.
genrtl.o : genrtl.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H)\
- $(GGC_H)
+ $(GGC_H) $(OBSTACK_H)
insn-attrtab.o : insn-attrtab.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TM_H) $(RTL_H) $(REGS_H) $(REAL_H) output.h $(INSN_ATTR_H) \
- insn-config.h toplev.h $(RECOG_H) $(TM_P_H) $(FLAGS_H)
+ insn-config.h $(TOPLEV_H) $(RECOG_H) $(TM_P_H) $(FLAGS_H)
insn-automata.o : insn-automata.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TM_H) $(RTL_H) $(REGS_H) $(REAL_H) output.h $(INSN_ATTR_H) \
- insn-config.h toplev.h $(RECOG_H) $(TM_P_H) $(FLAGS_H)
+ insn-config.h $(TOPLEV_H) $(RECOG_H) $(TM_P_H) $(FLAGS_H)
insn-emit.o : insn-emit.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
- $(RTL_H) $(EXPR_H) $(REAL_H) output.h insn-config.h $(OPTABS_H) \
- reload.h $(RECOG_H) toplev.h $(FUNCTION_H) $(FLAGS_H) hard-reg-set.h \
- $(RESOURCE_H) $(TM_P_H) $(BASIC_BLOCK_H) $(INTEGRATE_H) tm-constrs.h
+ $(RTL_H) $(TM_P_H) $(FUNCTION_H) $(EXPR_H) $(OPTABS_H) $(REAL_H) \
+ dfp.h $(FLAGS_H) output.h insn-config.h hard-reg-set.h $(RECOG_H) \
+ $(RESOURCE_H) reload.h $(TOPLEV_H) $(REGS_H) tm-constrs.h $(GGC_H) \
+ $(BASIC_BLOCK_H) $(INTEGRATE_H)
insn-extract.o : insn-extract.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
- $(TM_H) $(RTL_H) toplev.h insn-config.h $(RECOG_H)
+ $(TM_H) $(RTL_H) $(TOPLEV_H) insn-config.h $(RECOG_H)
insn-modes.o : insn-modes.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(MACHMODE_H) $(REAL_H)
insn-opinit.o : insn-opinit.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
- $(TM_H) $(RTL_H) insn-config.h $(FLAGS_H) $(RECOG_H) $(EXPR_H) \
- $(OPTABS_H) reload.h
+ $(TM_H) $(RTL_H) $(TM_P_H) insn-config.h $(FLAGS_H) $(RECOG_H) \
+ $(EXPR_H) $(OPTABS_H) reload.h
insn-output.o : insn-output.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TM_H) $(RTL_H) $(GGC_H) $(REGS_H) $(REAL_H) conditions.h \
hard-reg-set.h insn-config.h $(INSN_ATTR_H) $(EXPR_H) output.h \
- $(RECOG_H) $(FUNCTION_H) toplev.h $(FLAGS_H) insn-codes.h $(TM_P_H) \
+ $(RECOG_H) $(FUNCTION_H) $(TOPLEV_H) $(FLAGS_H) insn-codes.h $(TM_P_H) \
$(TARGET_H) tm-constrs.h
insn-peep.o : insn-peep.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
- $(RTL_H) $(REGS_H) output.h insn-config.h $(RECOG_H) except.h \
- $(FUNCTION_H) $(TM_P_H) $(REAL_H) tm-constrs.h
+ insn-config.h $(RTL_H) $(TM_P_H) $(REGS_H) output.h $(REAL_H) \
+ $(RECOG_H) except.h $(FUNCTION_H) $(TOPLEV_H) $(FLAGS_H) tm-constrs.h
insn-preds.o : insn-preds.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TM_H) $(RTL_H) $(TREE_H) insn-config.h $(RECOG_H) output.h \
$(FLAGS_H) $(FUNCTION_H) hard-reg-set.h $(RESOURCE_H) $(TM_P_H) \
- toplev.h reload.h $(REGS_H) $(REAL_H) tm-constrs.h
+ $(TOPLEV_H) reload.h $(REGS_H) $(REAL_H) tm-constrs.h
insn-recog.o : insn-recog.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TM_H) $(RTL_H) insn-config.h $(RECOG_H) output.h $(FLAGS_H) \
- $(FUNCTION_H) hard-reg-set.h $(RESOURCE_H) $(TM_P_H) toplev.h \
- reload.h $(REAL_H) tm-constrs.h
+ $(FUNCTION_H) hard-reg-set.h $(RESOURCE_H) $(TM_P_H) $(TOPLEV_H) \
+ reload.h $(REAL_H) $(REGS_H) tm-constrs.h
# For each of the files generated by running a generator program over
# the machine description, the following pair of static pattern rules
@@ -3198,6 +3255,7 @@ GTFILES = $(CPP_ID_DATA_H) $(srcdir)/input.h $(srcdir)/coretypes.h \
$(srcdir)/alias.c $(srcdir)/bitmap.c $(srcdir)/cselib.c $(srcdir)/cgraph.c \
$(srcdir)/ipa-prop.c $(srcdir)/ipa-cp.c $(srcdir)/ipa-inline.c $(srcdir)/matrix-reorg.c \
$(srcdir)/dbxout.c $(srcdir)/ipa-struct-reorg.c $(srcdir)/dwarf2out.c $(srcdir)/dwarf2asm.c \
+ $(srcdir)/tree-vect-generic.c \
$(srcdir)/dojump.c \
$(srcdir)/emit-rtl.c $(srcdir)/except.c $(srcdir)/explow.c $(srcdir)/expr.c \
$(srcdir)/function.c $(srcdir)/except.h \
@@ -3206,18 +3264,24 @@ GTFILES = $(CPP_ID_DATA_H) $(srcdir)/input.h $(srcdir)/coretypes.h \
$(srcdir)/reg-stack.c $(srcdir)/cfglayout.c $(srcdir)/cfglayout.h \
$(srcdir)/sdbout.c $(srcdir)/stor-layout.c \
$(srcdir)/stringpool.c $(srcdir)/tree.c $(srcdir)/varasm.c \
- $(srcdir)/tree-mudflap.c $(srcdir)/tree-flow.h $(srcdir)/tree-scalar-evolution.c \
+ $(srcdir)/gimple.h $(srcdir)/gimple.c \
+ $(srcdir)/tree-mudflap.c $(srcdir)/tree-flow.h \
$(srcdir)/tree-ssanames.c $(srcdir)/tree-eh.c $(srcdir)/tree-ssa-address.c \
- $(srcdir)/tree-phinodes.c $(srcdir)/tree-cfg.c \
- $(srcdir)/tree-dfa.c $(srcdir)/tree-ssa-propagate.c \
+ $(srcdir)/tree-cfg.c \
+ $(srcdir)/tree-dfa.c \
$(srcdir)/tree-iterator.c $(srcdir)/gimplify.c \
- $(srcdir)/tree-chrec.h $(srcdir)/tree-vect-generic.c \
+ $(srcdir)/tree-chrec.h \
+ $(srcdir)/tree-scalar-evolution.c \
$(srcdir)/tree-ssa-operands.h \
$(srcdir)/tree-profile.c $(srcdir)/tree-nested.c \
- $(srcdir)/ipa-reference.c $(srcdir)/tree-ssa-structalias.h \
- $(srcdir)/tree-ssa-structalias.c $(srcdir)/tree-parloops.c \
- $(srcdir)/omp-low.c $(srcdir)/varpool.c \
+ $(srcdir)/varpool.c \
+ $(srcdir)/tree-parloops.c \
+ $(srcdir)/omp-low.c \
$(srcdir)/targhooks.c $(out_file) $(srcdir)/passes.c $(srcdir)/cgraphunit.c \
+ $(srcdir)/tree-ssa-propagate.c \
+ $(srcdir)/tree-phinodes.c \
+ $(srcdir)/ipa-reference.c $(srcdir)/tree-ssa-structalias.h \
+ $(srcdir)/tree-ssa-structalias.c \
@all_gtfiles@
# Compute the list of GT header files from the corresponding C sources,
@@ -3238,20 +3302,12 @@ ALL_GTFILES_H := $(sort $(GTFILES_H) $(GTFILES_LANG_H))
# $(GTFILES) may be too long to put on a command line, so we have to
# write it out to a file (taking care not to do that in a way that
# overflows a command line!) and then have gengtype read the file in.
-# The extra blank line in this definition is crucial: it makes the
-# $(foreach ...) below expand to many lines instead of one.
-
-define echo_to_gi.list
-echo '$(gtyp)' >> tmp-gi.list
-
-endef
$(ALL_GTFILES_H) gtype-desc.c gtype-desc.h : s-gtype ; @true
gtyp-input.list: s-gtyp-input ; @true
s-gtyp-input: Makefile
- rm -f tmp-gi.list
- $(foreach gtyp, $(GTFILES), $(echo_to_gi.list))
+ @: $(call write_entries_to_file,$(GTFILES),tmp-gi.list)
$(SHELL) $(srcdir)/../move-if-change tmp-gi.list gtyp-input.list
$(STAMP) s-gtyp-input
@@ -3283,11 +3339,11 @@ build/read-rtl.o: read-rtl.c $(BCONFIG_H) $(SYSTEM_H) coretypes.h \
build/rtl.o: rtl.c $(BCONFIG_H) coretypes.h $(GTM_H) $(SYSTEM_H) \
$(RTL_H) $(REAL_H) $(GGC_H) errors.h
build/vec.o : vec.c $(BCONFIG_H) $(SYSTEM_H) coretypes.h vec.h \
- $(GGC_H) toplev.h
+ $(GGC_H) $(TOPLEV_H)
build/gencondmd.o : build/gencondmd.c $(BCONFIG_H) $(SYSTEM_H) \
coretypes.h $(GTM_H) insn-constants.h $(RTL_H) $(TM_P_H) \
$(FUNCTION_H) $(REGS_H) $(RECOG_H) $(REAL_H) output.h $(FLAGS_H) \
- $(RESOURCE_H) toplev.h reload.h except.h tm-constrs.h
+ $(RESOURCE_H) $(TOPLEV_H) reload.h except.h tm-constrs.h
# This pulls in tm-pred.h which contains inline functions wrapping up
# predicates from the back-end so those functions must be discarded.
# No big deal since gencondmd.c is a dummy file for non-GCC compilers.
@@ -3304,7 +3360,7 @@ build/genautomata.o : genautomata.c $(RTL_BASE_H) $(OBSTACK_H) \
$(BCONFIG_H) $(SYSTEM_H) coretypes.h $(GTM_H) errors.h vec.h \
$(HASHTAB_H) gensupport.h
build/gencheck.o : gencheck.c tree.def $(BCONFIG_H) $(GTM_H) \
- $(SYSTEM_H) coretypes.h $(lang_tree_files)
+ $(SYSTEM_H) coretypes.h $(lang_tree_files) gimple.def
build/genchecksum.o : genchecksum.c $(BCONFIG_H) $(SYSTEM_H) $(MD5_H)
build/gencodes.o : gencodes.c $(RTL_BASE_H) $(BCONFIG_H) $(SYSTEM_H) \
coretypes.h $(GTM_H) errors.h gensupport.h
@@ -3335,7 +3391,7 @@ build/genopinit.o : genopinit.c $(RTL_BASE_H) $(BCONFIG_H) $(SYSTEM_H) \
build/genoutput.o : genoutput.c $(RTL_BASE_H) $(BCONFIG_H) $(SYSTEM_H) \
coretypes.h $(GTM_H) errors.h gensupport.h
build/genpeep.o : genpeep.c $(RTL_BASE_H) $(BCONFIG_H) $(SYSTEM_H) \
- coretypes.h $(GTM_H) errors.h gensupport.h toplev.h
+ coretypes.h $(GTM_H) errors.h gensupport.h $(TOPLEV_H)
build/genpreds.o : genpreds.c $(RTL_BASE_H) $(BCONFIG_H) $(SYSTEM_H) \
coretypes.h $(GTM_H) errors.h gensupport.h $(OBSTACK_H)
build/genrecog.o : genrecog.c $(RTL_BASE_H) $(BCONFIG_H) $(SYSTEM_H) \
@@ -3484,7 +3540,7 @@ s-iov: build/gcov-iov$(build_exeext) $(BASEVER) $(DEVPHASE)
gcov.o: gcov.c gcov-io.c $(GCOV_IO_H) intl.h $(SYSTEM_H) coretypes.h $(TM_H) \
$(CONFIG_H) version.h
gcov-dump.o: gcov-dump.c gcov-io.c $(GCOV_IO_H) $(SYSTEM_H) coretypes.h \
- $(TM_H) $(CONFIG_H)
+ $(TM_H) $(CONFIG_H) version.h
GCOV_OBJS = gcov.o intl.o version.o errors.o
gcov$(exeext): $(GCOV_OBJS) $(LIBDEPS)
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index c2fb2dad0ae..a4859fd744e 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,3 +1,79 @@
+2008-07-28 Richard Guenther <rguenther@suse.de>
+
+ Merge from gimple-tuples-branch.
+
+ 2008-07-22 Olivier Hainque <hainque@adacore.com>
+
+ * gigi.h (end_subprog_body): New ELAB_P argument, saying if
+ this is called for an elab proc to be discarded if empty.
+ * utils.c (end_subprog_body): Honor ELAB_P.
+ (build_function_stub): Adjust call to end_subprog_body.
+ * trans.c (Subprogram_Body_to_gnu): Likewise.
+ (gigi): Reorganize processing of elab procs to prevent
+ gimplifying twice, using the new end_subprog_body argument.
+
+ 2008-07-19 Richard Guenther <rguenther@suse.de>
+
+ * Make-lang.in (trans.o): Add tree-iterator.h dependency.
+ (utils.o): Likewise.
+ * trans.c: Include tree-iterator.h.
+ (gnat_gimplify_expr): Adjust prototype. Fix typo.
+ (gnat_gimplify_stmt): Use SET_EXPR_LOCATION.
+ (set_expr_location_from_node): Likewise.
+ (gigi): Tuplify.
+ * ada-tree.h (union lang_tree_node): Use TREE_CHAIN instead
+ of GENERIC_NEXT.
+ * utils.c: Include tree-iterator.h.
+ * gigi.h (gnat_gimplify_expr): Adjust prototype.
+
+ 2008-07-18 Aldy Hernandez <aldyh@redhat.com>
+
+ * trans.c: Include gimple.h instead of tree-gimple.h.
+ * utils.c: Same.
+
+ 2008-07-14 Aldy Hernandez <aldyh@redhat.com>
+
+ * trans.c (gnat_gimplify_expr): Use gimplify_assign.
+
+2008-07-25 Jan Hubicka <jh@suse.cz>
+
+ * utils.c (end_subprog_body): Remove inline trees check.
+ * misc.c (gnat_post_options): Do not set flag_inline_trees.
+
+2008-07-25 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * raise-gcc.c: Move tsystem.h before tm.h.
+
+2008-07-20 Arnaud Charlet <charlet@adacore.com>
+
+ * gnathtml.pl: New file.
+
+2008-07-19 Olivier Hainque <hainque@adacore.com>
+
+ * targtyps.c (get_target_default_allocator_alignment): Use
+ MALLOC_ABI_ALIGNMENT.
+
+2008-07-17 Olivier Hainque <hainque@adacore.com>
+
+ * adaint.c (__MINGW32__ section): Include ctype.h and define
+ a fallback ISALPHA if IN_RTS.
+ (__gnat_is_absolute_path): Use ISALPHA instead of isalpha.
+
+2008-07-17 Olivier Hainque <hainque@adacore.com>
+
+ * utils.c (create_var_decl_1): Relax expectations on the PUBLIC_FLAG
+ argument, to apply to references in addition to definitions. Prevent
+ setting TREE_STATIC on externals.
+ (gnat_pushdecl): Always clear DECL_CONTEXT on public externals.
+
+2008-07-14 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
+
+ PR documentation/15479
+ * gnat_ugn.texi (@ovar): New macro, from autoconf.texi.
+ Replace backets around optional parameters with @ovar
+ where possible, use @r{[}, @r{]} otherwise.
+ Replace some @r, @i, and @emph with @var where appropriate.
+
2008-07-02 Eric Botcazou <ebotcazou@adacore.com>
* decl.c (make_type_from_size) <INTEGER_TYPE>: Fix typo and tidy up.
diff --git a/gcc/ada/Make-lang.in b/gcc/ada/Make-lang.in
index 4136ebe5dca..268fa7031fc 100644
--- a/gcc/ada/Make-lang.in
+++ b/gcc/ada/Make-lang.in
@@ -1106,13 +1106,13 @@ ada/trans.o : ada/trans.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(TREE_H) $(RTL_H) $(EXPR_H) $(FLAGS_H) $(FUNCTION_H) ada/ada.h except.h \
ada/types.h ada/atree.h ada/nlists.h ada/elists.h ada/uintp.h ada/sinfo.h \
ada/einfo.h ada/namet.h ada/snames.h ada/stringt.h ada/urealp.h ada/fe.h \
- $(ADA_TREE_H) ada/gigi.h gt-ada-trans.h
+ $(ADA_TREE_H) ada/gigi.h gt-ada-trans.h tree-iterator.h
ada/utils.o : ada/utils.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(TREE_H) $(FLAGS_H) $(EXPR_H) convert.h defaults.h langhooks.h \
ada/ada.h ada/types.h ada/atree.h ada/nlists.h ada/elists.h ada/sinfo.h \
ada/einfo.h ada/namet.h ada/stringt.h ada/uintp.h ada/fe.h $(ADA_TREE_H) \
- ada/gigi.h gt-ada-utils.h gtype-ada.h $(TARGET_H)
+ ada/gigi.h gt-ada-utils.h gtype-ada.h $(TARGET_H) tree-iterator.h
ada/utils2.o : ada/utils2.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(TREE_H) $(FLAGS_H) ada/ada.h ada/types.h ada/atree.h ada/nlists.h \
diff --git a/gcc/ada/ada-tree.h b/gcc/ada/ada-tree.h
index 044cea811b3..9c31e46f267 100644
--- a/gcc/ada/ada-tree.h
+++ b/gcc/ada/ada-tree.h
@@ -26,7 +26,7 @@
/* Ada uses the lang_decl and lang_type fields to hold a tree. */
union lang_tree_node
GTY((desc ("0"),
- chain_next ("(union lang_tree_node *)GENERIC_NEXT (&%h.t)")))
+ chain_next ("(union lang_tree_node *)TREE_CHAIN (&%h.t)")))
{
union tree_node GTY((tag ("0"))) t;
};
diff --git a/gcc/ada/adaint.c b/gcc/ada/adaint.c
index 8ace0a1c827..8f7bcab516f 100644
--- a/gcc/ada/adaint.c
+++ b/gcc/ada/adaint.c
@@ -85,7 +85,15 @@
#include "mingw32.h"
#include <sys/utime.h>
+
+/* For isalpha-like tests in the compiler, we're expected to resort to
+ safe-ctype.h/ISALPHA. This isn't available for the runtime library
+ build, so we fallback on ctype.h/isalpha there. */
+
+#ifdef IN_RTS
#include <ctype.h>
+#define ISALPHA isalpha
+#endif
#elif defined (__Lynx__)
@@ -1642,7 +1650,7 @@ __gnat_is_absolute_path (char *name, int length)
return (length != 0) &&
(*name == '/' || *name == DIR_SEPARATOR
#if defined (__EMX__) || defined (MSDOS) || defined (WINNT)
- || (length > 1 && isalpha (name[0]) && name[1] == ':')
+ || (length > 1 && ISALPHA (name[0]) && name[1] == ':')
#endif
);
#endif
diff --git a/gcc/ada/gigi.h b/gcc/ada/gigi.h
index 86ff090fdb0..aaf5e7f8d8f 100644
--- a/gcc/ada/gigi.h
+++ b/gcc/ada/gigi.h
@@ -233,8 +233,8 @@ extern tree gnat_to_gnu (Node_Id gnat_node);
extern void gnat_expand_stmt (tree gnu_stmt);
/* ??? missing documentation */
-extern int gnat_gimplify_expr (tree *expr_p, tree *pre_p,
- tree *post_p ATTRIBUTE_UNUSED);
+extern int gnat_gimplify_expr (tree *expr_p, gimple_seq *pre_p,
+ gimple_seq *post_p ATTRIBUTE_UNUSED);
/* Do the processing for the declaration of a GNAT_ENTITY, a type. If
a separate Freeze node exists, delay the bulk of the processing. Otherwise
@@ -668,10 +668,10 @@ extern tree create_label_decl (tree label_name);
appearing in the subprogram. */
extern void begin_subprog_body (tree subprog_decl);
-/* Finish the definition of the current subprogram and compile it all the way
- to assembler language output. BODY is the tree corresponding to
- the subprogram. */
-extern void end_subprog_body (tree body);
+/* Finish the definition of the current subprogram BODY and compile it all the
+ way to assembler language output. ELAB_P tells if this is called for an
+ elaboration routine, to be entirely discarded if empty. */
+extern void end_subprog_body (tree body, bool elab_p);
/* Build a template of type TEMPLATE_TYPE from the array bounds of ARRAY_TYPE.
EXPR is an expression that we can use to locate any PLACEHOLDER_EXPRs.
diff --git a/gcc/ada/gnat_ugn.texi b/gcc/ada/gnat_ugn.texi
index 3256c1c7f32..99f3c8631d4 100644
--- a/gcc/ada/gnat_ugn.texi
+++ b/gcc/ada/gnat_ugn.texi
@@ -98,6 +98,14 @@
@set PLATFORM OpenVMS
@end ifset
+@c @ovar(ARG)
+@c ----------
+@c The ARG is an optional argument. To be used for macro arguments in
+@c their documentation (@defmac).
+@macro ovar{varname}
+@r{[}@var{\varname\}@r{]}@c
+@end macro
+
@settitle @value{EDITION} User's Guide @value{PLATFORM}
@dircategory GNU Ada tools
@direntry
@@ -1005,7 +1013,7 @@ variables}.
@emph{Emphasis}.
@item
-[optional information or parameters]
+@r{[}optional information or parameters@r{]}
@item
Examples are described by text
@@ -2149,18 +2157,18 @@ alternative scheme for naming is specified by the use of
@smallexample @c ada
pragma Source_File_Name (
Spec_File_Name => FILE_NAME_PATTERN
- [,Casing => CASING_SPEC]
- [,Dot_Replacement => STRING_LITERAL]);
+ @r{[},Casing => CASING_SPEC@r{]}
+ @r{[},Dot_Replacement => STRING_LITERAL@r{]});
pragma Source_File_Name (
Body_File_Name => FILE_NAME_PATTERN
- [,Casing => CASING_SPEC]
- [,Dot_Replacement => STRING_LITERAL]);
+ @r{[},Casing => CASING_SPEC@r{]}
+ @r{[},Dot_Replacement => STRING_LITERAL@r{]});
pragma Source_File_Name (
Subunit_File_Name => FILE_NAME_PATTERN
- [,Casing => CASING_SPEC]
- [,Dot_Replacement => STRING_LITERAL]);
+ @r{[},Casing => CASING_SPEC@r{]}
+ @r{[},Dot_Replacement => STRING_LITERAL@r{]});
FILE_NAME_PATTERN ::= STRING_LITERAL
CASING_SPEC ::= Lowercase | Uppercase | Mixedcase
@@ -3669,7 +3677,7 @@ without generating code, then use the @option{-gnatc} switch.
The basic command for compiling a file containing an Ada unit is
@smallexample
-$ gcc -c [@var{switches}] @file{file name}
+$ gcc -c @ovar{switches} @file{file name}
@end smallexample
@noindent
@@ -3823,7 +3831,7 @@ See @ref{Stack Overflow Checking} for details.
Makes the compiler output stack usage information for the program, on a
per-function basis. See @ref{Static Stack Usage Analysis} for details.
-@item -fcallgraph-info[=su]
+@item -fcallgraph-info@r{[}=su@r{]}
@cindex @option{-fcallgraph-info} (@command{gcc})
Makes the compiler output callgraph information for the program, on a
per-file basis. The information is generated in the VCG format. It can
@@ -3894,9 +3902,9 @@ Specify a configuration pragma file
@end ifclear
(@pxref{The Configuration Pragmas Files}).
-@item ^-gnateD^/DATA_PREPROCESSING=^symbol[=value]
+@item ^-gnateD^/DATA_PREPROCESSING=^symbol@r{[}=@var{value}@r{]}
@cindex @option{-gnateD} (@command{gcc})
-Defines a symbol, associated with value, for preprocessing.
+Defines a symbol, associated with @var{value}, for preprocessing.
(@pxref{Integrated Preprocessing}).
@item -gnatef
@@ -4043,7 +4051,7 @@ Don't quit; generate @file{ALI} and tree files even if illegalities.
@cindex @option{-gnatr} (@command{gcc})
Treat pragma Restrictions as Restriction_Warnings.
-@item ^-gnatR[0/1/2/3[s]]^/REPRESENTATION_INFO^
+@item ^-gnatR@r{[}0@r{/}1@r{/}2@r{/}3@r{[}s@r{]]}^/REPRESENTATION_INFO^
@cindex @option{-gnatR} (@command{gcc})
Output representation information for declared types and objects.
@@ -4080,7 +4088,7 @@ Verbose mode. Full error output with source lines to @file{stdout}.
Control level of validity checking. See separate section describing
this feature.
-@item ^-gnatw@var{xxx}^/WARNINGS=(@var{option}[,@dots{}])^
+@item ^-gnatw@var{xxx}^/WARNINGS=(@var{option}@r{[},@dots{}@r{]})^
@cindex @option{^-gnatw^/WARNINGS^} (@command{gcc})
Warning mode where
^@var{xxx} is a string of option letters that^the list of options^ denotes
@@ -4160,7 +4168,7 @@ Inhibit the search of the default location for the GNAT Run Time
Library (RTL) ALI files.
@ifclear vms
-@item -O[@var{n}]
+@item -O@ovar{n}
@cindex @option{-O} (@command{gcc})
@var{n} controls the optimization level.
@@ -4196,7 +4204,7 @@ Equivalent to @option{/OPTIMIZE=NONE}.
This is the default behavior in the absence of an @option{/OPTIMIZE}
qualifier.
-@item /OPTIMIZE[=(keyword[,@dots{}])]
+@item /OPTIMIZE@r{[}=(keyword@r{[},@dots{}@r{]})@r{]}
@cindex @option{/OPTIMIZE} (@code{GNAT COMPILE})
Selects the level of optimization for your program. The supported
keywords are as follows:
@@ -5505,8 +5513,8 @@ The pragmas have the form:
@smallexample
@cartouche
- @b{pragma} Assert (@var{Boolean-expression} [,
- @var{static-string-expression}])
+ @b{pragma} Assert (@var{Boolean-expression} @r{[},
+ @var{static-string-expression}@r{]})
@b{pragma} Debug (@var{procedure call})
@end cartouche
@end smallexample
@@ -5527,7 +5535,7 @@ The @code{Debug} pragma causes @var{procedure} to be called. Note that
debugging procedures to be called between declarations.
@ifset vms
-@item /DEBUG[=debug-level]
+@item /DEBUG@r{[}=debug-level@r{]}
@itemx /NODEBUG
Specifies how much debugging information is to be included in
the resulting object file where 'debug-level' is one of the following:
@@ -6752,7 +6760,7 @@ If the switch @option{-gnatL} is used in conjunction with
in the expanded source (as comment lines with the original line number).
@table @code
-@item new @var{xxx} [storage_pool = @var{yyy}]
+@item new @var{xxx} @r{[}storage_pool = @var{yyy}@r{]}
Shows the storage pool being used for an allocator.
@item at end @var{procedure-name};
@@ -6778,14 +6786,14 @@ Combines the above two cases.
A division or multiplication of fixed-point values which are treated as
integers without any kind of scaling.
-@item free @var{expr} [storage_pool = @var{xxx}]
+@item free @var{expr} @r{[}storage_pool = @var{xxx}@r{]}
Shows the storage pool associated with a @code{free} statement.
@item [subtype or type declaration]
Used to list an equivalent declaration for an internally generated
type that is referenced elsewhere in the listing.
-@item freeze @var{type-name} [@var{actions}]
+@item freeze @var{type-name} @ovar{actions}
Shows the point at which @var{type-name} is frozen, with possible
associated actions to be performed at the freeze point.
@@ -6861,7 +6869,7 @@ Profile_Warnings, and pragma Restricted_Run_Time and pragma Ravenscar set
restriction warnings rather than restrictions.
@ifclear vms
-@item -gnatR[0|1|2|3[s]]
+@item -gnatR@r{[}0@r{|}1@r{|}2@r{|}3@r{[}s@r{]]}
@cindex @option{-gnatR} (@command{gcc})
This switch controls output from the compiler of a listing showing
representation information for declared types and objects. For
@@ -7168,7 +7176,7 @@ Examples of valid lines in a preprocessor data file:
-- list all symbols with their values.
@end smallexample
-@item ^-gnateD^/DATA_PREPROCESSING=^symbol[=value]
+@item ^-gnateD^/DATA_PREPROCESSING=^symbol@r{[}=value@r{]}
@cindex @option{-gnateD} (@command{gcc})
Define or redefine a preprocessing symbol, associated with value. If no value
is given on the command line, then the value of the symbol is @code{True}.
@@ -7475,14 +7483,14 @@ to be read by the @command{gnatlink} utility used to link the Ada application.
The form of the @code{gnatbind} command is
@smallexample
-$ gnatbind [@i{switches}] @i{mainprog}[.ali] [@i{switches}]
+$ gnatbind @ovar{switches} @var{mainprog}@r{[}.ali@r{]} @ovar{switches}
@end smallexample
@noindent
-where @file{@i{mainprog}.adb} is the Ada file containing the main program
+where @file{@var{mainprog}.adb} is the Ada file containing the main program
unit body. If no switches are specified, @code{gnatbind} constructs an Ada
package in two files whose names are
-@file{b~@i{mainprog}.ads}, and @file{b~@i{mainprog}.adb}.
+@file{b~@var{mainprog}.ads}, and @file{b~@var{mainprog}.adb}.
For example, if given the
parameter @file{hello.ali}, for a main program contained in file
@file{hello.adb}, the binder output files would be @file{b~hello.ads}
@@ -7618,20 +7626,20 @@ Check only, no generation of binder output file.
@cindex @option{^-C^/BIND_FILE=C^} (@command{gnatbind})
Generate binder program in C
-@item ^-d^/DEFAULT_STACK_SIZE=^@var{nn}[k|m]
-@cindex @option{^-d^/DEFAULT_STACK_SIZE=^@var{nn}[k|m]} (@command{gnatbind})
+@item ^-d^/DEFAULT_STACK_SIZE=^@var{nn}@r{[}k@r{|}m@r{]}
+@cindex @option{^-d^/DEFAULT_STACK_SIZE=^@var{nn}@r{[}k@r{|}m@r{]}} (@command{gnatbind})
This switch can be used to change the default task stack size value
to a specified size @var{nn}, which is expressed in bytes by default, or
in kilobytes when suffixed with @var{k} or in megabytes when suffixed
with @var{m}.
-In the absence of a [k|m] suffix, this switch is equivalent, in effect,
-to completing all task specs with
+In the absence of a @samp{@r{[}k@r{|}m@r{]}} suffix, this switch is equivalent,
+in effect, to completing all task specs with
@smallexample @c ada
pragma Storage_Size (nn);
@end smallexample
When they do not already have such a pragma.
-@item ^-D^/DEFAULT_SECONDARY_STACK_SIZE=^@var{nn}[k|m]
+@item ^-D^/DEFAULT_SECONDARY_STACK_SIZE=^@var{nn}@r{[}k@r{|}m@r{]}
@cindex @option{^-D^/DEFAULT_SECONDARY_STACK_SIZE=nnnnn^} (@command{gnatbind})
This switch can be used to change the default secondary stack size value
to a specified size @var{nn}, which is expressed in bytes by default, or
@@ -8448,8 +8456,8 @@ driver (see @ref{The GNAT Driver and Project Files}).
The form of the @command{gnatlink} command is
@smallexample
-$ gnatlink [@var{switches}] @var{mainprog}[.ali]
- [@var{non-Ada objects}] [@var{linker options}]
+$ gnatlink @ovar{switches} @var{mainprog}@r{[}.ali@r{]}
+ @ovar{non-Ada objects} @ovar{linker options}
@end smallexample
@noindent
@@ -8727,8 +8735,8 @@ dependencies, they will always be tracked exactly correctly by
The usual form of the @command{gnatmake} command is
@smallexample
-$ gnatmake [@var{switches}] @var{file_name}
- [@var{file_names}] [@var{mode_switches}]
+$ gnatmake @ovar{switches} @var{file_name}
+ @ovar{file_names} @ovar{mode_switches}
@end smallexample
@noindent
@@ -10266,7 +10274,7 @@ Note that @code{gnatelim} needs neither object nor ALI files.
@code{gnatelim} has the following command-line interface:
@smallexample
-$ gnatelim [options] name
+$ gnatelim @ovar{options} name
@end smallexample
@noindent
@@ -10417,7 +10425,7 @@ Generate a list of @code{Eliminate} pragmas
$ PIPE GNAT ELIM MAIN_PROG > GNAT.ADC
@end ifset
@ifclear vms
-$ gnatelim main_prog >[>] gnat.adc
+$ gnatelim main_prog >@r{[}>@r{]} gnat.adc
@end ifclear
@end smallexample
@@ -10665,8 +10673,8 @@ in which GNAT processes the ACVC tests.
The @code{gnatchop} command has the form:
@smallexample
-$ gnatchop switches @var{file name} [@var{file name} @var{file name} @dots{}]
- [@var{directory}]
+$ gnatchop switches @var{file name} @r{[}@var{file name} @dots{}@r{]}
+ @ovar{directory}
@end smallexample
@noindent
@@ -11089,8 +11097,8 @@ set of files.
The usual form of the @code{gnatname} command is
@smallexample
-$ gnatname [@var{switches}] @var{naming_pattern} [@var{naming_patterns}] \
- [--and @var{switches}] @var{naming_pattern} [@var{naming_patterns}]]
+$ gnatname @ovar{switches} @var{naming_pattern} @ovar{naming_patterns}
+ @r{[}--and @ovar{switches} @var{naming_pattern} @ovar{naming_patterns}@r{]}
@end smallexample
@noindent
@@ -14903,14 +14911,15 @@ use the @code{gnat} driver (see @ref{The GNAT Driver and Project Files}).
@noindent
The command invocation for @code{gnatxref} is:
@smallexample
-$ gnatxref [switches] sourcefile1 [sourcefile2 @dots{}]
+$ gnatxref @ovar{switches} @var{sourcefile1} @r{[}@var{sourcefile2} @dots{}@r{]}
@end smallexample
@noindent
where
-@table @code
-@item sourcefile1, sourcefile2
+@table @var
+@item sourcefile1
+@itemx sourcefile2
identifies the source files for which a report is to be generated. The
``with''ed units will be processed too. You must provide at least one file.
@@ -15034,17 +15043,17 @@ you can say @samp{gnatxref ^-ag^/ALL_FILES/IGNORE_LOCALS^} instead of
The command line for @code{gnatfind} is:
@smallexample
-$ gnatfind [switches] pattern[:sourcefile[:line[:column]]]
- [file1 file2 @dots{}]
+$ gnatfind @ovar{switches} @var{pattern}@r{[}:@var{sourcefile}@r{[}:@var{line}@r{[}:@var{column}@r{]]]}
+ @r{[}@var{file1} @var{file2} @dots{}]
@end smallexample
@noindent
where
-@table @code
+@table @var
@item pattern
An entity will be output only if it matches the regular expression found
-in @samp{pattern}, see @ref{Regular Expressions in gnatfind and gnatxref}.
+in @var{pattern}, see @ref{Regular Expressions in gnatfind and gnatxref}.
Omitting the pattern is equivalent to specifying @samp{*}, which
will match any entity. Note that if you do not provide a pattern, you
@@ -15056,8 +15065,8 @@ for matching purposes. At the current time there is no support for
@item sourcefile
@code{gnatfind} will look for references, bodies or declarations
-of symbols referenced in @file{sourcefile}, at line @samp{line}
-and column @samp{column}. See @ref{Examples of gnatfind Usage}
+of symbols referenced in @file{@var{sourcefile}}, at line @var{line}
+and column @var{column}. See @ref{Examples of gnatfind Usage}
for syntax examples.
@item line
@@ -15080,9 +15089,9 @@ directory whose name starts with @file{source} and whose extension is
@file{adb}.
The location of the spec of the entity will always be displayed, even if it
-isn't in one of @file{file1}, @file{file2},@enddots{} The occurrences
-of the entity in the separate units of the ones given on the command
-line will also be displayed.
+isn't in one of @file{@var{file1}}, @file{@var{file2}},@enddots{} The
+occurrences of the entity in the separate units of the ones given on the
+command line will also be displayed.
Note that if you specify at least one file in this part, @code{gnatfind} may
sometimes not be able to find the body of the subprograms.
@@ -15503,8 +15512,8 @@ $ gnatxref -v gnatfind.adb > tags
will generate the tags file for @code{gnatfind} itself (if the sources
are in the search path!).
-From @command{vi}, you can then use the command @samp{:tag @i{entity}}
-(replacing @i{entity} by whatever you are looking for), and vi will
+From @command{vi}, you can then use the command @samp{:tag @var{entity}}
+(replacing @var{entity} by whatever you are looking for), and vi will
display a new file with the corresponding declaration of entity.
@end ifclear
@@ -15614,7 +15623,7 @@ call @command{gnatpp} through the @command{gnat} driver
The @command{gnatpp} command has the form
@smallexample
-$ gnatpp [@var{switches}] @var{filename}
+$ gnatpp @ovar{switches} @var{filename}
@end smallexample
@noindent
@@ -15938,18 +15947,18 @@ The @option{GNAT}, @option{COMPACT}, and @option{UNCOMPACT} options for the
These switches allow control over line length and indentation.
@table @option
-@item ^-M@i{nnn}^/LINE_LENGTH_MAX=@i{nnn}^
+@item ^-M@var{nnn}^/LINE_LENGTH_MAX=@var{nnn}^
@cindex @option{^-M^/LINE_LENGTH^} (@command{gnatpp})
-Maximum line length, @i{nnn} from 32@dots{}256, the default value is 79
+Maximum line length, @var{nnn} from 32@dots{}256, the default value is 79
-@item ^-i@i{nnn}^/INDENTATION_LEVEL=@i{nnn}^
+@item ^-i@var{nnn}^/INDENTATION_LEVEL=@var{nnn}^
@cindex @option{^-i^/INDENTATION_LEVEL^} (@command{gnatpp})
-Indentation level, @i{nnn} from 1@dots{}9, the default value is 3
+Indentation level, @var{nnn} from 1@dots{}9, the default value is 3
-@item ^-cl@i{nnn}^/CONTINUATION_INDENT=@i{nnn}^
+@item ^-cl@var{nnn}^/CONTINUATION_INDENT=@var{nnn}^
@cindex @option{^-cl^/CONTINUATION_INDENT^} (@command{gnatpp})
Indentation level for continuation lines (relative to the line being
-continued), @i{nnn} from 1@dots{}9.
+continued), @var{nnn} from 1@dots{}9.
The default
value is one less then the (normal) indentation level, unless the
indentation is set to 1 (in which case the default value for continuation
@@ -15980,12 +15989,12 @@ insertion, so that the formatted source reflects the original.
@cindex @option{^-ff^/FORM_FEED_AFTER_PRAGMA_PAGE^} (@command{gnatpp})
Insert a Form Feed character after a pragma Page.
-@item ^-T@i{nnn}^/MAX_INDENT=@i{nnn}^
+@item ^-T@var{nnn}^/MAX_INDENT=@var{nnn}^
@cindex @option{^-T^/MAX_INDENT^} (@command{gnatpp})
Do not use an additional indentation level for @b{case} alternatives
-and variants if there are @i{nnn} or more (the default
+and variants if there are @var{nnn} or more (the default
value is 10).
-If @i{nnn} is 0, an additional indentation level is
+If @var{nnn} is 0, an additional indentation level is
used for @b{case} alternatives and variants regardless of their number.
@end table
@@ -16711,28 +16720,28 @@ through the @command{gnat} driver.
The @command{gnatmetric} command has the form
@smallexample
-$ gnatmetric [@i{switches}] @{@i{filename}@} [@i{-cargs gcc_switches}]
+$ gnatmetric @ovar{switches} @{@var{filename}@} @r{[}-cargs @var{gcc_switches}@r{]}
@end smallexample
@noindent
where
@itemize @bullet
@item
-@i{switches} specify the metrics to compute and define the destination for
+@var{switches} specify the metrics to compute and define the destination for
the output
@item
-Each @i{filename} is the name (including the extension) of a source
+Each @var{filename} is the name (including the extension) of a source
file to process. ``Wildcards'' are allowed, and
the file name may contain path information.
-If no @i{filename} is supplied, then the @i{switches} list must contain
+If no @var{filename} is supplied, then the @var{switches} list must contain
at least one
@option{-files} switch (@pxref{Other gnatmetric Switches}).
Including both a @option{-files} switch and one or more
-@i{filename} arguments is permitted.
+@var{filename} arguments is permitted.
@item
-@i{-cargs gcc_switches} is a list of switches for
+@samp{-cargs @var{gcc_switches}} is a list of switches for
@command{gcc}. They will be passed on to all compiler invocations made by
@command{gnatmetric} to generate the ASIS trees. Here you can provide
@option{^-I^/INCLUDE_DIRS=^} switches to form the source search path,
@@ -17476,7 +17485,7 @@ The @code{gnatkr} command has the form
@ifclear vms
@smallexample
-$ gnatkr @var{name} [@var{length}]
+$ gnatkr @var{name} @ovar{length}
@end smallexample
@end ifclear
@@ -17664,12 +17673,12 @@ all characters need to be in the ASCII set (no accented letters).
To call @code{gnatprep} use
@smallexample
-$ gnatprep [switches] infile outfile [deffile]
+$ gnatprep @ovar{switches} @var{infile} @var{outfile} @ovar{deffile}
@end smallexample
@noindent
where
-@table @code
+@table @var
@item switches
is an optional sequence of switches as described in the next section.
@@ -17810,11 +17819,11 @@ The preprocessor conditional inclusion commands have the form
@smallexample
@group
@cartouche
-#if @i{expression} [then]
+#if @i{expression} @r{[}then@r{]}
lines
-#elsif @i{expression} [then]
+#elsif @i{expression} @r{[}then@r{]}
lines
-#elsif @i{expression} [then]
+#elsif @i{expression} @r{[}then@r{]}
lines
@dots{}
#else
@@ -17950,7 +17959,7 @@ supplied configuration pragmas.
The @code{gnatlbr} command has the form
@smallexample
-$ GNAT LIBRARY /[CREATE | SET | DELETE]=directory [/CONFIG=file]
+$ GNAT LIBRARY /@r{[}CREATE@r{|}SET@r{|}DELETE@r{]}=directory @r{[}/CONFIG=file@r{]}
@end smallexample
@node Switches for gnatlbr
@@ -19637,7 +19646,7 @@ Solaris and Windows NT/2000/XP (x86).
The @code{gnatmem} command has the form
@smallexample
- $ gnatmem [switches] user_program
+ $ gnatmem @ovar{switches} user_program
@end smallexample
@noindent
@@ -20165,41 +20174,41 @@ driver (see @ref{The GNAT Driver and Project Files}).
Invoking @command{gnatcheck} on the command line has the form:
@smallexample
-$ gnatcheck [@i{switches}] @{@i{filename}@}
- [^-files^/FILES^=@{@i{arg_list_filename}@}]
- [-cargs @i{gcc_switches}] [-rules @i{rule_options}]
+$ gnatcheck @ovar{switches} @{@var{filename}@}
+ @r{[}^-files^/FILES^=@{@var{arg_list_filename}@}@r{]}
+ @r{[}-cargs @var{gcc_switches}@r{]} @r{[}-rules @var{rule_options}@r{]}
@end smallexample
@noindent
where
@itemize @bullet
@item
-@i{switches} specify the general tool options
+@var{switches} specify the general tool options
@item
-Each @i{filename} is the name (including the extension) of a source
+Each @var{filename} is the name (including the extension) of a source
file to process. ``Wildcards'' are allowed, and
the file name may contain path information.
@item
-Each @i{arg_list_filename} is the name (including the extension) of a text
+Each @var{arg_list_filename} is the name (including the extension) of a text
file containing the names of the source files to process, separated by spaces
or line breaks.
@item
-@i{gcc_switches} is a list of switches for
+@var{gcc_switches} is a list of switches for
@command{gcc}. They will be passed on to all compiler invocations made by
@command{gnatcheck} to generate the ASIS trees. Here you can provide
@option{^-I^/INCLUDE_DIRS=^} switches to form the source search path,
and use the @option{-gnatec} switch to set the configuration file.
@item
-@i{rule_options} is a list of options for controlling a set of
+@var{rule_options} is a list of options for controlling a set of
rules to be checked by @command{gnatcheck} (@pxref{gnatcheck Rule Options}).
@end itemize
@noindent
-Either a @i{filename} or an @i{arg_list_filename} must be supplied.
+Either a @file{@var{filename}} or an @file{@var{arg_list_filename}} must be supplied.
@menu
* Format of the Report File::
@@ -20322,22 +20331,22 @@ Turn all the rule checks ON.
Turn all the rule checks OFF.
@cindex @option{+R} (@command{gnatcheck})
-@item +R@i{rule_id[:param]}
+@item +R@var{rule_id}@r{[}:@var{param}@r{]}
Turn on the check for a specified rule with the specified parameter, if any.
-@i{rule_id} must be the identifier of one of the currently implemented rules
+@var{rule_id} must be the identifier of one of the currently implemented rules
(use @option{^-h^/HELP^} for the list of implemented rules). Rule identifiers
-are not case-sensitive. The @i{param} item must
+are not case-sensitive. The @var{param} item must
be a string representing a valid parameter(s) for the specified rule.
If it contains any space characters then this string must be enclosed in
quotation marks.
@cindex @option{-R} (@command{gnatcheck})
-@item -R@i{rule_id[:param]}
+@item -R@var{rule_id}@r{[}:@var{param}@r{]}
Turn off the check for a specified rule with the specified parameter, if any.
@cindex @option{-from} (@command{gnatcheck})
-@item -from=@i{rule_option_filename}
-Read the rule options from the text file @i{rule_option_filename}, referred as
+@item -from=@var{rule_option_filename}
+Read the rule options from the text file @var{rule_option_filename}, referred as
``rule file'' below.
@end table
@@ -20356,13 +20365,14 @@ The file may contain empty lines and Ada-style comments (comment
lines and end-of-line comments). The rule file has free format; that is,
you do not have to start a new rule option on a new line.
-A rule file may contain other @option{-from=@i{rule_option_filename}}
+A rule file may contain other @option{-from=@var{rule_option_filename}}
options, each such option being replaced with the content of the
corresponding rule file during the rule files processing. In case a
-cycle is detected (that is, @i{rule_file_1} reads rule options from
-@i{rule_file_2}, and @i{rule_file_2} reads (directly or indirectly)
-rule options from @i{rule_file_1}), the processing
-of rule files is interrupted and a part of their content is ignored.
+cycle is detected (that is, @file{@var{rule_file_1}} reads rule options
+from @file{@var{rule_file_2}}, and @file{@var{rule_file_2}} reads
+(directly or indirectly) rule options from @file{@var{rule_file_1}}),
+the processing of rule files is interrupted and a part of their content
+is ignored.
@node Adding the Results of Compiler Checks to gnatcheck Output
@@ -22010,12 +22020,12 @@ of @command{gnatstub} switches below.
@command{gnatstub} has the command-line interface of the form
@smallexample
-$ gnatstub [switches] filename [directory]
+$ gnatstub @ovar{switches} @var{filename} @ovar{directory}
@end smallexample
@noindent
where
-@table @emph
+@table @var
@item filename
is the name of the source file that contains a library unit declaration
for which a body must be created. The file name may contain the path
@@ -22285,7 +22295,7 @@ be able to click on any identifier and go to its declaration.
The command line is as follow:
@smallexample
-$ perl gnathtml.pl [^switches^options^] ada-files
+$ perl gnathtml.pl @ovar{^switches^options^} @var{ada-files}
@end smallexample
@noindent
@@ -22391,7 +22401,7 @@ is. The syntax of this line is:
Alternatively, you may run the script using the following command line:
@smallexample
-$ perl gnathtml.pl [switches] files
+$ perl gnathtml.pl @ovar{switches} @var{files}
@end smallexample
@ifset vms
@@ -24920,11 +24930,11 @@ HP Ada provides the following qualifiers to pass options to the linker
@item @option{/COMMAND}
-@item @option{/[NO]MAP}
+@item @option{/@r{[}NO@r{]}MAP}
-@item @option{/OUTPUT=@i{file-spec}}
+@item @option{/OUTPUT=@var{file-spec}}
-@item @option{/[NO]DEBUG} and @option{/[NO]TRACEBACK}
+@item @option{/@r{[}NO@r{]}DEBUG} and @option{/@r{[}NO@r{]}TRACEBACK}
@end itemize
@noindent
@@ -24932,11 +24942,11 @@ To pass options to the linker, GNAT provides the following
switches:
@itemize @bullet
-@item @option{/EXECUTABLE=@i{exec-name}}
+@item @option{/EXECUTABLE=@var{exec-name}}
@item @option{/VERBOSE}
-@item @option{/[NO]DEBUG} and @option{/[NO]TRACEBACK}
+@item @option{/@r{[}NO@r{]}DEBUG} and @option{/@r{[}NO@r{]}TRACEBACK}
@end itemize
@noindent
@@ -30940,12 +30950,12 @@ on the stack by the caller from right to left. The callee (and not the
caller) is in charge of cleaning the stack on routine exit. In addition,
the name of a routine with @code{Stdcall} calling convention is mangled by
adding a leading underscore (as for the @code{C} calling convention) and a
-trailing @code{@@}@code{@i{nn}}, where @i{nn} is the overall size (in
+trailing @code{@@}@code{@var{nn}}, where @var{nn} is the overall size (in
bytes) of the parameters passed to the routine.
The name to use on the Ada side when importing a C routine with a
@code{Stdcall} calling convention is the name of the C routine. The leading
-underscore and trailing @code{@@}@code{@i{nn}} are added automatically by
+underscore and trailing @code{@@}@code{@var{nn}} are added automatically by
the compiler. For instance the Win32 function:
@smallexample
@@ -30990,11 +31000,11 @@ pragma Import (Stdcall, Get_Val, Link_Name => "retrieve_val");
@noindent
then the imported routine is @code{retrieve_val}, that is, there is no
decoration at all. No leading underscore and no Stdcall suffix
-@code{@@}@code{@i{nn}}.
+@code{@@}@code{@var{nn}}.
@noindent
This is especially important as in some special cases a DLL's entry
-point name lacks a trailing @code{@@}@code{@i{nn}} while the exported
+point name lacks a trailing @code{@@}@code{@var{nn}} while the exported
name generated for a call has it.
@noindent
@@ -31256,21 +31266,21 @@ suffix) has the following structure:
@smallexample
@group
@cartouche
-[LIBRARY @i{name}]
-[DESCRIPTION @i{string}]
+@r{[}LIBRARY @var{name}@r{]}
+@r{[}DESCRIPTION @var{string}@r{]}
EXPORTS
- @i{symbol1}
- @i{symbol2}
+ @var{symbol1}
+ @var{symbol2}
@dots{}
@end cartouche
@end group
@end smallexample
@table @code
-@item LIBRARY @i{name}
+@item LIBRARY @var{name}
This section, which is optional, gives the name of the DLL.
-@item DESCRIPTION @i{string}
+@item DESCRIPTION @var{string}
This section, which is optional, gives a description string that will be
embedded in the import library.
@@ -31291,7 +31301,7 @@ EXPORTS
@end table
@noindent
-Note that you must specify the correct suffix (@code{@@}@code{@i{nn}})
+Note that you must specify the correct suffix (@code{@@}@code{@var{nn}})
(@pxref{Windows Calling Conventions}) for a Stdcall
calling convention function in the exported symbols list.
@@ -31319,12 +31329,12 @@ $ dll2def API.dll > API.def
@code{dll2def} is a very simple tool: it takes as input a DLL and prints
to standard output the list of entry points in the DLL. Note that if
some routines in the DLL have the @code{Stdcall} convention
-(@pxref{Windows Calling Conventions}) with stripped @code{@@}@i{nn}
+(@pxref{Windows Calling Conventions}) with stripped @code{@@}@var{nn}
suffix then you'll have to edit @file{api.def} to add it, and specify
@option{-k} to @command{gnatdll} when creating the import library.
@noindent
-Here are some hints to find the right @code{@@}@i{nn} suffix.
+Here are some hints to find the right @code{@@}@var{nn} suffix.
@enumerate
@item
@@ -31355,8 +31365,8 @@ $ gnatdll -e API.def -d API.dll
name of the DLL containing the services listed in the definition file
@file{API.dll}. The name of the static import library generated is
computed from the name of the definition file as follows: if the
-definition file name is @i{xyz}@code{.def}, the import library name will
-be @code{lib}@i{xyz}@code{.a}. Note that in the previous example option
+definition file name is @var{xyz}@code{.def}, the import library name will
+be @code{lib}@var{xyz}@code{.a}. Note that in the previous example option
@option{-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 (@pxref{Using gnatdll} for more information about @code{gnatdll}).
@@ -31833,23 +31843,23 @@ static import library for the DLL and the actual DLL. The form of the
@smallexample
@cartouche
-$ gnatdll [@var{switches}] @var{list-of-files} [-largs @var{opts}]
+$ gnatdll @ovar{switches} @var{list-of-files} @r{[}-largs @var{opts}@r{]}
@end cartouche
@end smallexample
@noindent
-where @i{list-of-files} is a list of ALI and object files. The object
+where @var{list-of-files} is a list of ALI and object files. The object
file list must be the exact list of objects corresponding to the non-Ada
sources whose services are to be included in the DLL. The ALI file list
must be the exact list of ALI files for the corresponding Ada sources
-whose services are to be included in the DLL. If @i{list-of-files} is
+whose services are to be included in the DLL. If @var{list-of-files} is
missing, only the static import library is generated.
@noindent
You may specify any of the following switches to @code{gnatdll}:
@table @code
-@item -a[@var{address}]
+@item -a@ovar{address}
@cindex @option{-a} (@code{gnatdll})
Build a non-relocatable DLL at @var{address}. If @var{address} is not
specified the default address @var{0x11000000} will be used. By default,
@@ -31901,10 +31911,10 @@ object files needed to build the DLL.
@item -k
@cindex @option{-k} (@code{gnatdll})
-Removes the @code{@@}@i{nn} suffix from the import library's exported
+Removes the @code{@@}@var{nn} suffix from the import library's exported
names, but keeps them for the link names. You must specify this
option if you want to use a @code{Stdcall} function in a DLL for which
-the @code{@@}@i{nn} suffix has been removed. This is the case for most
+the @code{@@}@var{nn} suffix has been removed. This is the case for most
of the Windows NT DLL for example. This option has no effect when
@option{-n} option is specified.
@@ -32052,7 +32062,7 @@ common @code{dlltool} switches. The form of the @code{dlltool} command
is
@smallexample
-$ dlltool [@var{switches}]
+$ dlltool @ovar{switches}
@end smallexample
@noindent
@@ -32076,7 +32086,7 @@ DLL in the static import library generated by @code{dlltool} with switch
@item -k
@cindex @option{-k} (@command{dlltool})
-Kill @code{@@}@i{nn} from exported names
+Kill @code{@@}@var{nn} from exported names
(@pxref{Windows Calling Conventions}
for a discussion about @code{Stdcall}-style symbols.
@@ -32089,7 +32099,7 @@ Prints the @code{dlltool} switches with a concise description.
Generate an export file @var{exportfile}. The export file contains the
export table (list of symbols in the DLL) and is used to create the DLL.
-@item --output-lib @i{libfile}
+@item --output-lib @var{libfile}
@cindex @option{--output-lib} (@command{dlltool})
Generate a static import library @var{libfile}.
@@ -32097,9 +32107,9 @@ Generate a static import library @var{libfile}.
@cindex @option{-v} (@command{dlltool})
Verbose mode.
-@item --as @i{assembler-name}
+@item --as @var{assembler-name}
@cindex @option{--as} (@command{dlltool})
-Use @i{assembler-name} as the assembler. The default is @code{as}.
+Use @var{assembler-name} as the assembler. The default is @code{as}.
@end table
@node GNAT and Windows Resources
diff --git a/gcc/ada/gnathtml.pl b/gcc/ada/gnathtml.pl
new file mode 100644
index 00000000000..9d893268055
--- /dev/null
+++ b/gcc/ada/gnathtml.pl
@@ -0,0 +1,1115 @@
+#! /usr/bin/env perl
+
+#-----------------------------------------------------------------------------
+#- --
+#- GNAT COMPILER COMPONENTS --
+#- --
+#- G N A T H T M L --
+#- --
+#- Copyright (C) 1998-2008, 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 2, 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. See the GNU General Public License --
+#- for more details. You should have received a copy of the GNU General --
+#- Public License distributed with GNAT; see file COPYING. If not, write --
+#- to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, --
+#- MA 02111-1307, USA. --
+#- --
+#- GNAT was originally developed by the GNAT team at New York University. --
+#- Extensive contributions were provided by Ada Core Technologies Inc. --
+#- --
+#-----------------------------------------------------------------------------
+
+## This script converts an Ada file (and its dependency files) to Html.
+## Keywords, comments and strings are color-hilighted. If the cross-referencing
+## information provided by Gnat (when not using the -gnatx switch) is found,
+## the html files will also have some cross-referencing features, i.e. if you
+## click on a type, its declaration will be displayed.
+##
+## To find more about the switches provided by this script, please use the
+## following command :
+## perl gnathtml.pl -h
+## You may also change the first line of this script to indicates where Perl is
+## installed on your machine, so that you can just type
+## gnathtml.pl -h
+##
+## Unless you supply another directory with the -odir switch, the html files
+## will be saved saved in a html subdirectory
+
+use Cwd 'abs_path';
+use File::Basename;
+
+### Print help if necessary
+sub print_usage
+{
+ print "Usage is:\n";
+ print " $0 [switches] main_file[.adb] main_file2[.adb] ...\n";
+ print " -83 : Use Ada83 keywords only (default is Ada95)\n";
+ print " -cc color : Choose the color for comments\n";
+ print " -d : Convert also the files which main_file depends on\n";
+ print " -D : same as -d, also looks for files in the standard library\n";
+ print " -f : Include cross-references for local entities too\n";
+ print " -absolute : Display absolute filenames in the headers\n";
+ print " -h : Print this help page\n";
+ print " -lnb : Display line numbers every nb lines\n";
+ print " -Idir : Specify library/object files search path\n";
+ print " -odir : Name of the directory where the html files will be\n";
+ print " saved. Default is 'html/'\n";
+ print " -pfile : Use file as a project file (.adp file)\n";
+ print " -sc color : Choose the color for symbol definitions\n";
+ print " -Tfile : Read the name of the files from file rather than the\n";
+ print " command line\n";
+ print " -ext ext : Choose the generated file names extension (default\n";
+ print " is htm)\n";
+ print "This program attemps to generate an html file from an Ada file\n";
+ exit;
+}
+
+### Parse the command line
+local ($ada83_mode) = 0;
+local ($prjfile) = "";
+local (@list_files) = ();
+local ($line_numbers) = 0;
+local ($dependencies) = 0;
+local ($standard_library) = 0;
+local ($output_dir) = "html";
+local ($xref_variable) = 0;
+local (@search_dir) = ('.');
+local ($tab_size) = 8;
+local ($comment_color) = "green";
+local ($symbol_color) = "red";
+local ($absolute) = 0;
+local ($fileext) = "htm";
+
+while ($_ = shift @ARGV)
+{
+ /^-83$/ && do { $ada83_mode = 1; };
+ /^-d$/ && do { $dependencies = 1; };
+ /^-D$/ && do { $dependencies = 1;
+ $standard_library = 1; };
+ /^-f$/ && do { $xref_variable = 1; };
+ /^-absolute$/ && do {$absolute = 1; };
+ /^-h$/ && do { &print_usage; };
+ /^[^-]/ && do { $_ .= ".adb" if (! /\.ad[bs]$/);
+ push (@list_files, $_); };
+
+ if (/^-o\s*(.*)$/)
+ {
+ $output_dir = ($1 eq "") ? shift @ARGV : $1;
+ chop $output_dir if ($output_dir =~ /\/$/);
+ &print_usage if ($output_dir =~ /^-/ || $output_dir eq "");
+ }
+
+ if (/^-T\s*(.*)$/)
+ {
+ my ($source_file) = ($1 eq "") ? shift @ARGV : $1;
+ local (*SOURCE);
+ open (SOURCE, "$source_file") || die "file not found: $source_file";
+ while (<SOURCE>) {
+ @files = split;
+ foreach (@files) {
+ $_ .= ".adb" if (! /\.ad[bs]$/);
+ push (@list_files, $_);
+ }
+ }
+ }
+
+ if (/^-cc\s*(.*)$/)
+ {
+ $comment_color = ($1 eq "") ? shift @ARGV : $1;
+ &print_usage if ($comment_color =~ /^-/ || $comment_color eq "");
+ }
+
+ if (/^-sc\s*(.*)$/)
+ {
+ $symbol_color = ($1 eq "") ? shift @ARGV : $1;
+ &print_usage if ($symbol_color =~ /^-/ || $symbol_color eq "");
+ }
+
+ if (/^-I\s*(.*)$/)
+ {
+ push (@search_dir, ($1 eq "") ? scalar (shift @ARGV) : $1);
+ }
+
+ if (/^-p\s*(.*)$/)
+ {
+ $prjfile = ($1 eq "") ? shift @ARGV : $1;
+ &print_usage if ($prjfile =~ /^-/ || $prjfile eq "");
+ }
+
+ if (/^-l\s*(.*)$/)
+ {
+ $line_numbers = ($1 eq "") ? shift @ARGV : $1;
+ &print_usage if ($line_numbers =~ /^-/ || $line_numbers eq "");
+ }
+
+ if (/^-ext\s*(.*)$/)
+ {
+ $fileext = ($1 eq "") ? shift @ARGV : $1;
+ &print_usage if ($fileext =~ /^-/ || $fileext eq "");
+ }
+}
+
+&print_usage if ($#list_files == -1);
+local (@original_list) = @list_files;
+
+## This regexp should match all the files from the standard library (and only them)
+## Note that at this stage the '.' in the file names has been replaced with __
+$standard_file_regexp="^([agis]-|ada__|gnat__|system__|interface__).*\$";
+
+local (@src_dir) = ();
+local (@obj_dir) = ();
+
+if ($standard_library) {
+ open (PIPE, "gnatls -v | ");
+ local ($mode) = "";
+ while (defined ($_ = <PIPE>)) {
+ chop;
+ s/^\s+//;
+ $_ = './' if (/<Current_Directory>/);
+ next if (/^$/);
+
+ if (/Source Search Path:/) {
+ $mode = 's';
+ }
+ elsif (/Object Search Path:/) {
+ $mode = 'o';
+ }
+ elsif ($mode eq 's') {
+ push (@src_dir, $_);
+ }
+ elsif ($mode eq 'o') {
+ push (@obj_dir, $_);
+ }
+ }
+ close (PIPE);
+}
+else
+{
+ push (@src_dir, "./");
+ push (@obj_dir, "./");
+}
+
+foreach (@list_files) {
+ local ($dir) = $_;
+ $dir =~ s/\/([^\/]+)$//;
+ push (@src_dir, $dir. '/');
+ push (@obj_dir, $dir. '/');
+}
+
+### Defines and compiles the Ada key words :
+local (@Ada_keywords) = ('abort', 'abs', 'accept', 'access', 'all', 'and',
+ 'array', 'at', 'begin', 'body', 'case', 'constant',
+ 'declare', 'delay', 'delta', 'digits', 'do', 'else',
+ 'elsif', 'end', 'entry', 'exception', 'exit', 'for',
+ 'function', 'generic', 'goto', 'if', 'in', 'is',
+ 'limited', 'loop', 'mod', 'new', 'not', 'null', 'of',
+ 'or', 'others', 'out', 'package', 'pragma', 'private',
+ 'procedure', 'raise', 'range', 'record', 'rem',
+ 'renames', 'return', 'reverse', 'select', 'separate',
+ 'subtype', 'task', 'terminate', 'then', 'type',
+ 'until', 'use', 'when', 'while', 'with', 'xor');
+local (@Ada95_keywords) = ('abstract', 'aliased', 'protected', 'requeue',
+ 'tagged');
+
+local (%keywords) = ();
+grep (++ $keywords{$_}, @Ada_keywords);
+grep (++ $keywords{$_}, @Ada95_keywords) unless ($ada83_mode);
+
+### Symbols declarations for the current file
+### format is (line_column => 1, ...)
+local (%symbols);
+
+### Symbols usage for the current file
+### format is ($adafile#$line_$column => $htmlfile#$linedecl_$columndecl, ...)
+local (%symbols_used);
+
+### the global index of all symbols
+### format is ($name => [[file, line, column], [file, line, column], ...])
+local (%global_index);
+
+#########
+## This function create the header of every html file.
+## These header is returned as a string
+## Params: - Name of the Ada file associated with this html file
+#########
+sub create_header
+{
+ local ($adafile) = shift;
+ local ($string) = "<HEAD><TITLE>$adafile</TITLE></HEAD>
+<BODY>\n";
+
+ if ($adafile ne "")
+ {
+ $string .= "<HR><DIV ALIGN=\"center\"><H1> File : $adafile "
+ . "</H1></DIV><HR>\n<PRE>";
+ }
+ return $string;
+}
+
+#########
+## Protect a string (or character) from the Html parser
+## Params: - the string to protect
+## Out: - the protected string
+#########
+sub protect_string
+{
+ local ($string) = shift;
+ $string =~ s/&/&amp;/g;
+ $string =~ s/</&lt;/g;
+ $string =~ s/>/&gt;/g;
+ return $string;
+}
+
+#########
+## This function creates the footer of the html file
+## The footer is returned as a string
+## Params : - Name of the Ada file associated with this html file
+#########
+sub create_footer
+{
+ local ($adafile) = shift;
+ local ($string) = "";
+ $string = "</PRE>" if ($adafile ne "");
+ return $string . "</BODY></HTML>\n";
+}
+
+#########
+## This function creates the string to use for comment output
+## Params : - the comment itself
+#########
+sub output_comment
+{
+ local ($comment) = &protect_string (shift);
+ return "<FONT COLOR=$comment_color><EM>--$comment</EM></FONT>";
+}
+
+########
+## This function creates the string to use for symbols output
+## Params : - the symbol to output
+## - the current line
+## - the current column
+########
+sub output_symbol
+{
+ local ($symbol) = &protect_string (shift);
+ local ($lineno) = shift;
+ local ($column) = shift;
+ return "<FONT COLOR=$symbol_color><A NAME=\"$lineno\_$column\">$symbol</A></FONT>";
+}
+
+########
+## This function creates the string to use for keyword output
+## Params : - the keyword to output
+########
+sub output_keyword
+{
+ local ($keyw) = shift;
+ return "<b>$keyw</b>";
+}
+
+########
+## This function outputs a line number
+## Params : - the line number to generate
+########
+sub output_line_number
+{
+ local ($no) = shift;
+ if ($no != -1)
+ {
+ return "<EM><FONT SIZE=-1>" . sprintf ("%4d ", $no) . "</FONT></EM>";
+ }
+ else
+ {
+ return "<FONT SIZE=-1> </FONT>";
+ }
+}
+
+########
+## Converts a character into the corresponding Ada type
+## This is based on the ali format (see lib-xref.adb) in the GNAT sources
+## Note: 'f' or 'K' should be returned in case a link from the body to the
+## spec needs to be generated.
+## Params : - the character to convert
+########
+sub to_type
+{
+ local ($char) = shift;
+ $char =~ tr/a-z/A-Z/;
+
+ return 'array' if ($char eq 'A');
+ return 'boolean' if ($char eq 'B');
+ return 'class' if ($char eq 'C');
+ return 'decimal' if ($char eq 'D');
+ return 'enumeration' if ($char eq 'E');
+ return 'floating point' if ($char eq 'F');
+ return 'signed integer' if ($char eq 'I');
+ # return 'generic package' if ($char eq 'K');
+ return 'block' if ($char eq 'L');
+ return 'modular integer' if ($char eq 'M');
+ return 'enumeration litteral' if ($char eq 'N');
+ return 'ordinary fixed point' if ($char eq 'O');
+ return 'access' if ($char eq 'P');
+ return 'label' if ($char eq 'Q');
+ return 'record' if ($char eq 'R');
+ return 'string' if ($char eq 'S');
+ return 'task' if ($char eq 'T');
+ return 'f' if ($char eq 'U');
+ return 'f' if ($char eq 'V');
+ return 'exception' if ($char eq 'X');
+ return 'entry' if ($char eq 'Y');
+ return "$char";
+}
+
+########
+## Changes a file name to be http compatible
+########
+sub http_string
+{
+ local ($str) = shift;
+ $str =~ s/\//__/g;
+ $str =~ s/\\/__/g;
+ $str =~ s/:/__/g;
+ $str =~ s/\./__/g;
+ return $str;
+}
+
+########
+## Creates the complete file-name, with directory
+## use the variables read in the .prj file
+## Params : - file name
+## RETURNS : the relative path_name to the file
+########
+sub get_real_file_name
+{
+ local ($filename) = shift;
+ local ($path) = $filename;
+
+ foreach (@src_dir)
+ {
+ if ( -r "$_$filename")
+ {
+ $path = "$_$filename";
+ last;
+ }
+ }
+
+ $path =~ s/^\.\///;
+ return $path if (substr ($path, 0, 1) ne '/');
+
+ ## We want to return relative paths only, so that the name of the HTML files
+ ## can easily be generated
+ local ($pwd) = `pwd`;
+ chop ($pwd);
+ local (@pwd) = split (/\//, $pwd);
+ local (@path) = split (/\//, $path);
+
+ while (@pwd)
+ {
+ if ($pwd [0] ne $path [0])
+ {
+ return '../' x ($#pwd + 1) . join ("/", @path);
+ }
+ shift @pwd;
+ shift @path;
+ }
+ return join ('/', @path);
+}
+
+########
+## Reads and parses .adp files
+## Params : - adp file name
+########
+sub parse_prj_file
+{
+ local ($filename) = shift;
+ local (@src) = ();
+ local (@obj) = ();
+
+ print "Parsing project file : $filename\n";
+
+ open (PRJ, $filename) || do { print " ... sorry, file not found\n";
+ return;
+ };
+ while (<PRJ>)
+ {
+ chop;
+ s/\/$//;
+ push (@src, $1 . "/") if (/^src_dir=(.*)/);
+ push (@obj, $1 . "/") if (/^obj_dir=(.*)/);
+ }
+ unshift (@src_dir, @src);
+ unshift (@obj_dir, @obj);
+ close (PRJ);
+}
+
+########
+## Finds a file in the search path
+## Params : - the name of the file
+## RETURNS : - the directory/file_name
+########
+sub find_file
+{
+ local ($filename) = shift;
+
+ foreach (@search_dir) {
+ if (-f "$_/$filename") {
+ return "$_/$filename";
+ }
+ }
+ return $filename;
+}
+
+########
+## Inserts a new reference in the list of references
+## Params: - Ref as it appears in the .ali file ($line$type$column)
+## - Current file for the reference
+## - Current offset to be added from the line (handling of
+## pragma Source_Reference)
+## - Current entity reference
+## Modifies: - %symbols_used
+########
+sub create_new_reference
+{
+ local ($ref) = shift;
+ local ($lastfile) = shift;
+ local ($offset) = shift;
+ local ($currentref) = shift;
+ local ($refline, $type, $refcol);
+
+ ## Do not generate references to the standard library files if we
+ ## do not generate the corresponding html files
+ return if (! $standard_library && $lastfile =~ /$standard_file_regexp/);
+
+ ($refline, $type, $extern, $refcol) = /(\d+)(.)(<[^>]+>)?(\d+)/;
+ $refline += $offset;
+
+ ## If we have a body, then we only generate the cross-reference from
+ ## the spec to the body if we have a subprogram (or a package)
+
+
+ if ($type eq "b")
+# && ($symbols {$currentref} eq 'f' || $symbols {$currentref} eq 'K'))
+ {
+ local ($cref_file, $cref) = ($currentref =~ /([^\#]+).$fileext\#(.+)/);
+
+ $symbols_used {"$cref_file#$cref"} = "$lastfile.$fileext#$refline\_$refcol";
+ $symbols_used {"$lastfile#$refline\_$refcol"} = $currentref;
+ $symbols {"$lastfile.$fileext#$refline\_$refcol"} = "body";
+ }
+
+ ## Do not generate cross-references for "e" and "t", since these point to the
+ ## semicolon that terminates the block -- irrelevant for gnathtml
+ ## "p" is also removed, since it is used for primitive subprograms
+ ## "d" is also removed, since it is used for discriminants
+ ## "i" is removed since it is used for implicit references
+ ## "z" is used for generic formals
+ ## "k" is for references to parent package
+ ## "=", "<", ">", "^" is for subprogram parameters
+
+ elsif ($type !~ /[eztpid=<>^k]/)
+ {
+ $symbols_used {"$lastfile#$refline\_$refcol"} = $currentref;
+ }
+}
+
+########
+## Parses the ali file associated with the current Ada file
+## Params : - the complete ali file name
+########
+sub parse_ali
+{
+ local ($filename) = shift;
+ local ($currentfile);
+ local ($currentref);
+ local ($lastfile);
+
+ # A file | line type column reference
+ local ($reference) = "(?:(?:\\d+\\|)?\\d+.\\d+|\\w+)";
+
+ # The following variable is used to represent the possible xref information
+ # output by GNAT when -gnatdM is used. It includes renaming references, and
+ # references to the parent type, as well as references to the generic parent
+
+ local ($typeref) = "(?:=$reference|<$reference>|\\{$reference\\}|\\($reference\\)|\\[$reference\\])?";
+
+ # The beginning of an entity declaration line in the ALI file
+ local ($decl_line) = "^(\\d+)(.)(\\d+)[ *]([\\w\\d.-]+|\"..?\")$typeref\\s+(\\S.*)?\$";
+
+ # Contains entries of the form [ filename source_reference_offset]
+ # Offset needs to be added to the lines read in the cross-references, and are
+ # used when the source comes from a gnatchop-ed file. See lib-write.ads, lines
+ # with ^D in the ALI file.
+ local (@reffiles) = ();
+
+ open (ALI, &find_file ($filename)) || do {
+ print "no ", &find_file ($filename), " file...\n";
+ return;
+ };
+ local (@ali) = <ALI>;
+ close (ALI);
+
+ undef %symbols;
+ undef %symbols_used;
+
+ foreach (@ali)
+ {
+ ## The format of D lines is
+ ## D source-name time-stamp checksum [subunit-name] line:file-name
+
+ if (/^D\s+([\w\d.-]+)\s+\S+ \S+(\s+\D[^: ]+)?( (\d+):(.*))?/)
+ {
+ # The offset will be added to each cross-reference line. If it is
+ # greater than 1, this means that we have a pragma Source_Reference,
+ # and this must not be counted in the xref information.
+ my ($file, $offset) = ($1, (defined $4) ? 2 - $4 : 0);
+
+ if ($dependencies)
+ {
+ push (@list_files, $1) unless (grep (/$file/, @list_files));
+ }
+ push (@reffiles, [&http_string (&get_real_file_name ($file)), $offset]);
+ }
+
+ elsif (/^X\s+(\d+)/)
+ {
+ $currentfile = $lastfile = $1 - 1;
+ }
+
+ elsif (defined $currentfile && /$decl_line/)
+ {
+ my ($line) = $1 + $reffiles[$currentfile][1];
+ next if (! $standard_library
+ && $reffiles[$currentfile][0] =~ /$standard_file_regexp/);
+ if ($xref_variable || $2 eq &uppercases ($2))
+ {
+ $currentref = $reffiles[$currentfile][0] . ".$fileext#$line\_$3";
+ $symbols {$currentref} = &to_type ($2);
+ $lastfile = $currentfile;
+
+ local ($endofline) = $5;
+
+ foreach (split (" ", $endofline))
+ {
+ (s/^(\d+)\|//) && do { $lastfile = $1 - 1; };
+ &create_new_reference
+ ($_, $reffiles[$lastfile][0],
+ $reffiles[$lastfile][1], $currentref);
+ }
+ }
+ else
+ {
+ $currentref = "";
+ }
+ }
+ elsif (/^\.\s(.*)/ && $reffiles[$currentfile][0] ne "" && $currentref ne "")
+ {
+ next if (! $standard_library
+ && $reffiles[$currentfile][0] =~ /$standard_file_regexp/);
+ foreach (split (" ", $1))
+ {
+ (s/^(\d+)\|//) && do { $lastfile = $1 - 1; };
+ &create_new_reference
+ ($_, $reffiles[$lastfile][0], $reffiles[$lastfile][1],
+ $currentref);
+ }
+ }
+ }
+}
+
+#########
+## Return the name of the ALI file to use for a given source
+## Params: - Name of the source file
+## return: Name and location of the ALI file
+#########
+
+sub ali_file_name {
+ local ($source) = shift;
+ local ($alifilename, $unitname);
+ local ($in_separate) = 0;
+
+ $source =~ s/\.ad[sb]$//;
+ $alifilename = $source;
+ $unitname = $alifilename;
+ $unitname =~ s/-/./g;
+
+ ## There are two reasons why we might not find the ALI file: either the
+ ## user did not generate them at all, or we are working on a separate unit.
+ ## Thus, we search in the parent's ALI file.
+
+ while ($alifilename ne "") {
+
+ ## Search in the object path
+ foreach (@obj_dir) {
+
+ ## Check if the ALI file does apply to the source file
+ ## We check the ^D lines, which have the following format:
+ ## D source-name time-stamp checksum [subunit-name] line:file-name
+
+ if (-r "$_$alifilename.ali") {
+ if ($in_separate) {
+ open (FILE, "$_$alifilename.ali");
+
+ if (grep (/^D \S+\s+\S+\s+\S+ $unitname/, <FILE>)) {
+ close FILE;
+ return "$_$alifilename.ali";
+
+ } else {
+ ## If the ALI file doesn't apply to the source file, we can
+ ## return now, since there won't be a parent ALI file above
+ ## anyway
+ close FILE;
+ return "$source.ali";
+ }
+ } else {
+ return "$_$alifilename.ali";
+ }
+ }
+ }
+
+ ## Get the parent's ALI file name
+
+ if (! ($alifilename =~ s/-[^-]+$//)) {
+ $alifilename = "";
+ }
+ $in_separate = 1;
+ }
+
+ return "$source.ali";
+}
+
+#########
+## Convert a path to an absolute path
+#########
+
+sub to_absolute
+{
+ local ($path) = shift;
+ local ($name, $suffix, $separator);
+ ($name,$path,$suffix) = fileparse ($path, ());
+ $path = &abs_path ($path);
+ $separator = substr ($path, 0, 1);
+ return $path . $separator . $name;
+}
+
+#########
+## This function outputs the html version of the file FILE
+## The output is send to FILE.htm.
+## Params : - Name of the file to convert (ends with .ads or .adb)
+#########
+sub output_file
+{
+ local ($filename_param) = shift;
+ local ($lineno) = 1;
+ local ($column);
+ local ($found);
+
+ local ($alifilename) = &ali_file_name ($filename_param);
+
+ $filename = &get_real_file_name ($filename_param);
+ $found = &find_file ($filename);
+
+ ## Read the whole file
+ open (FILE, $found) || do {
+ print $found, " not found ... skipping.\n";
+ return 0;
+ };
+ local (@file) = <FILE>;
+ close (FILE);
+
+ ## Parse the .ali file to find the cross-references
+ print "converting ", $filename, "\n";
+ &parse_ali ($alifilename);
+
+ ## Create and initialize the html file
+ open (OUTPUT, ">$output_dir/" . &http_string ($filename) . ".$fileext")
+ || die "Couldn't write $output_dir/" . &http_string ($filename)
+ . ".$fileext\n";
+
+ if ($absolute) {
+ print OUTPUT &create_header (&to_absolute ($found)), "\n";
+ } else {
+ print OUTPUT &create_header ($filename_param), "\n";
+ }
+
+ ## Print the file
+ $filename = &http_string ($filename);
+ foreach (@file)
+ {
+ local ($index);
+ local ($line) = $_;
+ local ($comment);
+
+ $column = 1;
+ chop ($line);
+
+ ## Print either the line number or a space if required
+ if ($line_numbers)
+ {
+ if ($lineno % $line_numbers == 0)
+ {
+ print OUTPUT &output_line_number ($lineno);
+ }
+ else
+ {
+ print OUTPUT &output_line_number (-1);
+ }
+ }
+
+ ## First, isolate any comment on the line
+ undef $comment;
+ $index = index ($line, '--');
+ if ($index != -1) {
+ $comment = substr ($line, $index + 2);
+ if ($index > 1)
+ {
+ $line = substr ($line, 0, $index);
+ }
+ else
+ {
+ undef $line;
+ }
+ }
+
+ ## Then print the line
+ if (defined $line)
+ {
+ $index = 0;
+ while ($index < length ($line))
+ {
+ local ($substring) = substr ($line, $index);
+
+ if ($substring =~ /^\t/)
+ {
+ print OUTPUT ' ' x ($tab_size - (($column - 1) % $tab_size));
+ $column += $tab_size - (($column - 1) % $tab_size);
+ $index ++;
+ }
+ elsif ($substring =~ /^(\w+)/
+ || $substring =~ /^("[^\"]*")/
+ || $substring =~ /^(\W)/)
+ {
+ local ($word) = $1;
+ $index += length ($word);
+
+ local ($lowercase) = $word;
+ $lowercase =~ tr/A-Z/a-z/;
+
+ if ($keywords{$lowercase})
+ {
+ print OUTPUT &output_keyword ($word);
+ }
+ elsif ($symbols {"$filename.$fileext#$lineno\_$column"})
+ {
+ ## A symbol can both have a link and be a reference for
+ ## another link, as is the case for bodies and
+ ## declarations
+
+ if ($symbols_used{"$filename#$lineno\_$column"})
+ {
+ print OUTPUT "<A HREF=\"",
+ $symbols_used{"$filename#$lineno\_$column"},
+ "\">", &protect_string ($word), "</A>";
+ print OUTPUT &output_symbol ('', $lineno, $column);
+ }
+ else
+ {
+ print OUTPUT &output_symbol ($word, $lineno, $column);
+ }
+
+ ## insert only functions into the global index
+
+ if ($symbols {"$filename.$fileext#$lineno\_$column"} eq 'f')
+ {
+ push (@{$global_index {$word}},
+ [$filename_param, $filename, $lineno, $column]);
+ }
+ }
+ elsif ($symbols_used{"$filename#$lineno\_$column"})
+ {
+ print OUTPUT "<A HREF=\"",
+ $symbols_used{"$filename#$lineno\_$column"},
+ "\">", &protect_string ($word), "</A>";
+ }
+ else
+ {
+ print OUTPUT &protect_string ($word);
+ }
+ $column += length ($word);
+ }
+ else
+ {
+ $index ++;
+ $column ++;
+ print OUTPUT &protect_string (substr ($substring, 0, 1));
+ }
+ }
+ }
+
+ ## Then output the comment
+ print OUTPUT &output_comment ($comment) if (defined $comment);
+ print OUTPUT "\n";
+
+ $lineno ++;
+ }
+
+ print OUTPUT &create_footer ($filename);
+ close (OUTPUT);
+ return 1;
+}
+
+#########
+## This function generates the global index
+#########
+sub create_index_file
+{
+ open (INDEX, ">$output_dir/index.$fileext") || die "couldn't write $output_dir/index.$fileext";
+
+ print INDEX <<"EOF";
+<HTML>
+<HEAD><TITLE>Source Browser</TITLE></HEAD>
+<FRAMESET COLS='250,*'>
+<NOFRAME>
+EOF
+ ;
+
+ local (@files) = &create_file_index;
+ print INDEX join ("\n", @files), "\n";
+
+ print INDEX "<HR>\n";
+ local (@functions) = &create_function_index;
+ print INDEX join ("\n", @functions), "\n";
+
+ print INDEX <<"EOF";
+</NOFRAME>
+<FRAMESET ROWS='50%,50%'>
+<FRAME NAME=files SRC=files.$fileext>
+<FRAME NAME=funcs SRC=funcs.$fileext>
+</FRAMESET>
+<FRAME NAME=main SRC=main.$fileext>
+</FRAMESET>
+</HTML>
+EOF
+ ;
+ close (INDEX);
+
+ open (MAIN, ">$output_dir/main.$fileext") || die "couldn't write $output_dir/main.$fileext";
+ print MAIN &create_header (""),
+ "<P ALIGN=right>",
+ "<A HREF=main.$fileext TARGET=_top>[No frame version is here]</A>",
+ "<P>",
+ join ("\n", @files), "\n<HR>",
+ join ("\n", @functions), "\n";
+
+ if ($dependencies) {
+ print MAIN "<HR>\n";
+ print MAIN "You should start your browsing with one of these files:\n";
+ print MAIN "<UL>\n";
+ foreach (@original_list) {
+ print MAIN "<LI><A HREF=", &http_string (&get_real_file_name ($_)),
+ ".$fileext>$_</A>\n";
+ }
+ }
+ print MAIN &create_footer ("");
+ close (MAIN);
+}
+
+#######
+## Convert to upper cases (did not exist in Perl 4)
+#######
+
+sub uppercases {
+ local ($tmp) = shift;
+ $tmp =~ tr/a-z/A-Z/;
+ return $tmp;
+}
+
+#######
+## This function generates the file_index
+## RETURN : - table with the html lines to be printed
+#######
+sub create_file_index
+{
+ local (@output) = ("<H2 ALIGN=CENTER>Files</H2>");
+
+
+ open (FILES, ">$output_dir/files.$fileext") || die "couldn't write $output_dir/files.$fileext";
+ print FILES &create_header (""), join ("\n", @output), "\n";
+
+
+ if ($#list_files > 20)
+ {
+ local ($last_letter) = '';
+ foreach (sort {&uppercases ($a) cmp &uppercases ($b)} @list_files)
+ {
+ next if ($_ eq "");
+ if (&uppercases (substr ($_, 0, 1)) ne $last_letter)
+ {
+ if ($last_letter ne '')
+ {
+ print INDEX_FILE "</UL></BODY></HTML>\n";
+ close (INDEX_FILE);
+ }
+ $last_letter = &uppercases (substr ($_, 0, 1));
+ open (INDEX_FILE, ">$output_dir/files/$last_letter.$fileext")
+ || die "couldn't write $output_dir/files/$last_letter.$fileext";
+ print INDEX_FILE <<"EOF";
+<HTML><HEAD><TITLE>$last_letter</TITLE></HEAD>
+<BODY>
+<H2>Files - $last_letter</H2>
+<A HREF=../files.$fileext TARGET=_self>[index]</A>
+<UL COMPACT TYPE=DISC>
+EOF
+ ;
+ local ($str) = "<A HREF=files/$last_letter.$fileext>[$last_letter]</A>";
+ push (@output, $str);
+ print FILES "$str\n";
+ }
+ print INDEX_FILE "<LI><A HREF=../",
+ &http_string (&get_real_file_name ($_)),
+ ".$fileext TARGET=main>$_</A>\n"; ## Problem with TARGET when in no_frame mode!
+ }
+
+ print INDEX_FILE "</UL></BODY></HTML>\n";
+ close INDEX_FILE;
+ }
+ else
+ {
+ push (@output, "<UL COMPACT TYPE=DISC>");
+ print FILES "<UL COMPACT TYPE=DISC>";
+ foreach (sort {&uppercases ($a) cmp &uppercases ($b)} @list_files)
+ {
+ next if ($_ eq "");
+ local ($ref) = &http_string (&get_real_file_name ($_));
+ push (@output, "<LI><A HREF=$ref.$fileext>$_</A>");
+ print FILES "<LI><A HREF=$ref.$fileext TARGET=main>$_</A>\n";
+ }
+ }
+
+ print FILES &create_footer ("");
+ close (FILES);
+
+ push (@output, "</UL>");
+ return @output;
+}
+
+#######
+## This function generates the function_index
+## RETURN : - table with the html lines to be printed
+#######
+sub create_function_index
+{
+ local (@output) = ("<H2 ALIGN=CENTER>Functions/Procedures</H2>");
+ local ($initial) = "";
+
+ open (FUNCS, ">$output_dir/funcs.$fileext") || die "couldn't write $output_dir/funcs.$fileext";
+ print FUNCS &create_header (""), join ("\n", @output), "\n";
+
+ ## If there are more than 20 entries, we just want to create some
+ ## submenus
+ if (scalar (keys %global_index) > 20)
+ {
+ local ($last_letter) = '';
+ foreach (sort {&uppercases ($a) cmp &uppercases ($b)} keys %global_index)
+ {
+ if (&uppercases (substr ($_, 0, 1)) ne $last_letter)
+ {
+ if ($last_letter ne '')
+ {
+ print INDEX_FILE "</UL></BODY></HTML>\n";
+ close (INDEX_FILE);
+ }
+
+ $last_letter = &uppercases (substr ($_, 0, 1));
+ $initial = $last_letter;
+ if ($initial eq '"')
+ {
+ $initial = "operators";
+ }
+ if ($initial ne '.')
+ {
+ open (INDEX_FILE, ">$output_dir/funcs/$initial.$fileext")
+ || die "couldn't write $output_dir/funcs/$initial.$fileext";
+ print INDEX_FILE <<"EOF";
+<HTML><HEAD><TITLE>$initial</TITLE></HEAD>
+<BODY>
+<H2>Functions - $initial</H2>
+<A HREF=../funcs.$fileext TARGET=_self>[index]</A>
+<UL COMPACT TYPE=DISC>
+EOF
+ ;
+ local ($str) = "<A HREF=funcs/$initial.$fileext>[$initial]</A>";
+ push (@output, $str);
+ print FUNCS "$str\n";
+ }
+ }
+ local ($ref);
+ local ($is_overloaded) = ($#{$global_index {$_}} > 0 ? 1 : 0);
+ foreach $ref (@{$global_index {$_}})
+ {
+ ($file, $full_file, $lineno, $column) = @{$ref};
+ local ($symbol) = ($is_overloaded ? "$_ - $file:$lineno" : $_);
+ print INDEX_FILE "<LI><A HREF=../$full_file.$fileext#$lineno\_$column TARGET=main>$symbol</A>";
+ }
+ }
+
+ print INDEX_FILE "</UL></BODY></HTML>\n";
+ close INDEX_FILE;
+ }
+ else
+ {
+ push (@output, "<UL COMPACT TYPE=DISC>");
+ print FUNCS "<UL COMPACT TYPE=DISC>";
+ foreach (sort {&uppercases ($a) cmp &uppercases ($b)} keys %global_index)
+ {
+ local ($ref);
+ local ($is_overloaded) = ($#{$global_index {$_}} > 0 ? 1 : 0);
+ foreach $ref (@{$global_index {$_}})
+ {
+ ($file, $full_file, $lineno, $column) = @{$ref};
+ local ($symbol) = ($is_overloaded ? "$_ - $file:$lineno" : $_);
+ push (@output, "<LI><A HREF=$full_file.$fileext#$lineno\_$column>$symbol</A>");
+ print FUNCS "<LI><A HREF=$full_file.$fileext#$lineno\_$column TARGET=main>$symbol</A>";
+ }
+ }
+ }
+
+ print FUNCS &create_footer ("");
+ close (FUNCS);
+
+ push (@output, "</UL>");
+ return (@output);
+}
+
+######
+## Main function
+######
+
+local ($index_file) = 0;
+
+mkdir ($output_dir, 0777) if (! -d $output_dir);
+mkdir ($output_dir."/files", 0777) if (! -d $output_dir."/files");
+mkdir ($output_dir."/funcs", 0777) if (! -d $output_dir."/funcs");
+
+&parse_prj_file ($prjfile) if ($prjfile);
+
+while ($index_file <= $#list_files)
+{
+ local ($file) = $list_files [$index_file];
+
+ if (&output_file ($file) == 0)
+ {
+ $list_files [$index_file] = "";
+ }
+ $index_file ++;
+}
+&create_index_file;
+
+$indexfile = "$output_dir/index.$fileext";
+$indexfile =~ s!//!/!g;
+print "You can now download the $indexfile file to see the ",
+ "created pages\n";
diff --git a/gcc/ada/misc.c b/gcc/ada/misc.c
index 85dd22e8bb3..006da96b2b7 100644
--- a/gcc/ada/misc.c
+++ b/gcc/ada/misc.c
@@ -340,12 +340,8 @@ gnat_post_options (const char **pfilename ATTRIBUTE_UNUSED)
/* ??? The warning machinery is outsmarted by Ada. */
warn_unused_parameter = 0;
- flag_inline_trees = 1;
-
if (!flag_no_inline)
flag_no_inline = 1;
- if (flag_inline_functions)
- flag_inline_trees = 2;
/* Force eliminate_unused_debug_types to 0 unless an explicit positive
-f has been passed. This forces the default to 0 for Ada, which might
diff --git a/gcc/ada/raise-gcc.c b/gcc/ada/raise-gcc.c
index bb25ea631d1..e2662e14f23 100644
--- a/gcc/ada/raise-gcc.c
+++ b/gcc/ada/raise-gcc.c
@@ -6,7 +6,7 @@
* *
* C Implementation File *
* *
- * Copyright (C) 1992-2007, Free Software Foundation, Inc. *
+ * Copyright (C) 1992-2008, 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- *
@@ -35,6 +35,7 @@
#ifdef IN_RTS
#include "tconfig.h"
+#include "tsystem.h"
/* In the top-of-tree GCC, tconfig does not include tm.h, but in GCC 3.2
it does. To avoid branching raise.c just for that purpose, we kludge by
looking for a symbol always defined by tm.h and if it's not defined,
@@ -43,7 +44,6 @@
#include "coretypes.h"
#include "tm.h"
#endif
-#include "tsystem.h"
#include <sys/stat.h>
#include <stdarg.h>
typedef char bool;
diff --git a/gcc/ada/targtyps.c b/gcc/ada/targtyps.c
index 79dafcaf2fe..c4e3299667d 100644
--- a/gcc/ada/targtyps.c
+++ b/gcc/ada/targtyps.c
@@ -164,17 +164,13 @@ get_target_maximum_default_alignment (void)
Stricter alignment requests trigger gigi's aligning_type circuitry for
objects allocated by the default allocator. */
-#ifndef MALLOC_ALIGNMENT
-#define MALLOC_ALIGNMENT BIGGEST_ALIGNMENT
-#endif
-
Pos
get_target_default_allocator_alignment (void)
{
/* ??? Need a way to get info about __gnat_malloc from here (whether
it is handy and what alignment it honors). */
- return MALLOC_ALIGNMENT / BITS_PER_UNIT;
+ return MALLOC_ABI_ALIGNMENT / BITS_PER_UNIT;
}
/* Standard'Maximum_Allowed_Alignment. Maximum alignment that we may
diff --git a/gcc/ada/trans.c b/gcc/ada/trans.c
index 89b10c695da..abc71f5e53e 100644
--- a/gcc/ada/trans.c
+++ b/gcc/ada/trans.c
@@ -40,7 +40,8 @@
#include "except.h"
#include "debug.h"
#include "output.h"
-#include "tree-gimple.h"
+#include "tree-iterator.h"
+#include "gimple.h"
#include "ada.h"
#include "types.h"
#include "atree.h"
@@ -356,7 +357,6 @@ gigi (Node_Id gnat_root, int max_gnat_node, int number_name,
for (info = elab_info_list; info; info = info->next)
{
tree gnu_body = DECL_SAVED_TREE (info->elab_proc);
- tree gnu_stmts;
/* Unshare SAVE_EXPRs between subprograms. These are not unshared by
the gimplifier for obvious reasons, but it turns out that we need to
@@ -368,30 +368,14 @@ gigi (Node_Id gnat_root, int max_gnat_node, int number_name,
an upstream bug for which we would not change the outcome. */
walk_tree_without_duplicates (&gnu_body, unshare_save_expr, NULL);
- /* Set the current function to be the elaboration procedure and gimplify
- what we have. */
- current_function_decl = info->elab_proc;
- gimplify_body (&gnu_body, info->elab_proc, true);
+ /* Process the function as others, but for indicating this is an
+ elab proc, to be discarded if empty, then propagate the status
+ up to the GNAT tree node. */
+ begin_subprog_body (info->elab_proc);
+ end_subprog_body (gnu_body, true);
- /* We should have a BIND_EXPR, but it may or may not have any statements
- in it. If it doesn't have any, we have nothing to do. */
- gnu_stmts = gnu_body;
- if (TREE_CODE (gnu_stmts) == BIND_EXPR)
- gnu_stmts = BIND_EXPR_BODY (gnu_stmts);
-
- /* If there are no statements, there is no elaboration code. */
- if (!gnu_stmts || !STATEMENT_LIST_HEAD (gnu_stmts))
- {
- Set_Has_No_Elaboration_Code (info->gnat_node, 1);
- cgraph_remove_node (cgraph_node (info->elab_proc));
- }
- else
- {
- /* Otherwise, compile the function. Note that we'll be gimplifying
- it twice, but that's fine for the nodes we use. */
- begin_subprog_body (info->elab_proc);
- end_subprog_body (gnu_body);
- }
+ if (empty_body_p (gimple_body (info->elab_proc)))
+ Set_Has_No_Elaboration_Code (info->gnat_node, 1);
}
/* We cannot track the location of errors past this point. */
@@ -2003,7 +1987,7 @@ Subprogram_Body_to_gnu (Node_Id gnat_node)
: Sloc (gnat_node)),
&DECL_STRUCT_FUNCTION (gnu_subprog_decl)->function_end_locus);
- end_subprog_body (gnu_result);
+ end_subprog_body (gnu_result, false);
/* Disconnect the trees for parameters that we made variables for from the
GNAT entities since these are unusable after we end the function. */
@@ -5334,7 +5318,8 @@ pop_stack (tree *gnu_stack_ptr)
/* Generate GIMPLE in place for the expression at *EXPR_P. */
int
-gnat_gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p ATTRIBUTE_UNUSED)
+gnat_gimplify_expr (tree *expr_p, gimple_seq *pre_p,
+ gimple_seq *post_p ATTRIBUTE_UNUSED)
{
tree expr = *expr_p;
tree op;
@@ -5419,14 +5404,14 @@ gnat_gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p ATTRIBUTE_UNUSED)
&& TREE_CODE_CLASS (TREE_CODE (op)) != tcc_constant)
{
tree new_var = create_tmp_var (TREE_TYPE (op), "A");
- tree mod = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (op), new_var, op);
+ gimple stmt;
TREE_ADDRESSABLE (new_var) = 1;
+ stmt = gimplify_assign (new_var, op, pre_p);
if (EXPR_HAS_LOCATION (op))
- SET_EXPR_LOCUS (mod, EXPR_LOCUS (op));
+ gimple_set_location (stmt, *EXPR_LOCUS (op));
- gimplify_and_add (mod, pre_p);
TREE_OPERAND (expr, 0) = new_var;
recompute_tree_invariant_for_addr_expr (expr);
return GS_ALL_DONE;
@@ -5494,7 +5479,7 @@ gnat_gimplify_stmt (tree *stmt_p)
append_to_statement_list (LOOP_STMT_UPDATE (stmt), stmt_p);
t = build1 (GOTO_EXPR, void_type_node, gnu_start_label);
- set_expr_location (t, DECL_SOURCE_LOCATION (gnu_end_label));
+ SET_EXPR_LOCATION (t, DECL_SOURCE_LOCATION (gnu_end_label));
append_to_statement_list (t, stmt_p);
append_to_statement_list (build1 (LABEL_EXPR, void_type_node,
@@ -6913,7 +6898,7 @@ set_expr_location_from_node (tree node, Node_Id gnat_node)
if (!Sloc_to_locus (Sloc (gnat_node), &locus))
return;
- set_expr_location (node, locus);
+ SET_EXPR_LOCATION (node, locus);
}
/* Return a colon-separated list of encodings contained in encoded Ada
diff --git a/gcc/ada/utils.c b/gcc/ada/utils.c
index 92e83487b80..cde8d4dd2f3 100644
--- a/gcc/ada/utils.c
+++ b/gcc/ada/utils.c
@@ -43,7 +43,8 @@
#include "function.h"
#include "cgraph.h"
#include "tree-inline.h"
-#include "tree-gimple.h"
+#include "tree-iterator.h"
+#include "gimple.h"
#include "tree-dump.h"
#include "pointer-set.h"
#include "langhooks.h"
@@ -418,9 +419,11 @@ gnat_poplevel ()
void
gnat_pushdecl (tree decl, Node_Id gnat_node)
{
- /* If at top level, there is no context. But PARM_DECLs always go in the
- level of its function. */
- if (global_bindings_p () && TREE_CODE (decl) != PARM_DECL)
+ /* If this decl is public external or at toplevel, there is no context.
+ But PARM_DECLs always go in the level of its function. */
+ if (TREE_CODE (decl) != PARM_DECL
+ && ((DECL_EXTERNAL (decl) && TREE_PUBLIC (decl))
+ || global_bindings_p ()))
DECL_CONTEXT (decl) = 0;
else
{
@@ -1471,9 +1474,9 @@ create_type_decl (tree type_name, tree type, struct attrib *attr_list,
CONST_FLAG is true if this variable is constant, in which case we might
return a CONST_DECL node unless CONST_DECL_ALLOWED_P is false.
- PUBLIC_FLAG is true if this definition is to be made visible outside of
- the current compilation unit. This flag should be set when processing the
- variable definitions in a package specification.
+ PUBLIC_FLAG is true if this is for a reference to a public entity or for a
+ definition to be made visible outside of the current compilation unit, for
+ instance variable definitions in a package specification.
EXTERN_FLAG is nonzero when processing an external variable declaration (as
opposed to a definition: no storage is to be allocated for the variable).
@@ -1549,7 +1552,7 @@ create_var_decl_1 (tree var_name, tree asm_name, tree type, tree var_init,
variable if and only if it's not external. If we are not at the top level
we allocate automatic storage unless requested not to. */
TREE_STATIC (var_decl)
- = public_flag || (global_bindings_p () ? !extern_flag : static_flag);
+ = !extern_flag && (public_flag || static_flag || global_bindings_p ());
if (asm_name && VAR_OR_FUNCTION_DECL_P (var_decl))
SET_DECL_ASSEMBLER_NAME (var_decl, asm_name);
@@ -2197,12 +2200,12 @@ gnat_genericize (tree fndecl)
pointer_set_destroy (p_set);
}
-/* Finish the definition of the current subprogram and compile it all the way
- to assembler language output. BODY is the tree corresponding to
- the subprogram. */
+/* Finish the definition of the current subprogram BODY and compile it all the
+ way to assembler language output. ELAB_P tells if this is called for an
+ elaboration routine, to be entirely discarded if empty. */
void
-end_subprog_body (tree body)
+end_subprog_body (tree body, bool elab_p)
{
tree fndecl = current_function_decl;
@@ -2215,8 +2218,7 @@ end_subprog_body (tree body)
/* Deal with inline. If declared inline or we should default to inline,
set the flag in the decl. */
- DECL_INLINE (fndecl)
- = DECL_DECLARED_INLINE_P (fndecl) || flag_inline_trees == 2;
+ DECL_INLINE (fndecl) = 1;
/* We handle pending sizes via the elaboration of types, so we don't
need to save them. */
@@ -2245,7 +2247,13 @@ end_subprog_body (tree body)
if (!DECL_CONTEXT (fndecl))
{
gnat_gimplify_function (fndecl);
- cgraph_finalize_function (fndecl, false);
+
+ /* If this is an empty elaboration proc, just discard the node.
+ Otherwise, compile further. */
+ if (elab_p && empty_body_p (gimple_body (fndecl)))
+ cgraph_remove_node (cgraph_node (fndecl));
+ else
+ cgraph_finalize_function (fndecl, false);
}
else
/* Register this function with cgraph just far enough to get it
@@ -3116,7 +3124,7 @@ build_function_stub (tree gnu_subprog, Entity_Id gnat_subprog)
gnat_poplevel ();
allocate_struct_function (gnu_stub_decl, false);
- end_subprog_body (gnu_body);
+ end_subprog_body (gnu_body, false);
}
/* Build a type to be used to represent an aliased object whose nominal
diff --git a/gcc/attribs.c b/gcc/attribs.c
index 3c60e8bd967..ba6a9e294c8 100644
--- a/gcc/attribs.c
+++ b/gcc/attribs.c
@@ -33,6 +33,7 @@ along with GCC; see the file COPYING3. If not see
#include "target.h"
#include "langhooks.h"
#include "hashtab.h"
+#include "c-common.h"
static void init_attributes (void);
@@ -232,6 +233,41 @@ decl_attributes (tree *node, tree attributes, int flags)
if (!attributes_initialized)
init_attributes ();
+ /* If this is a function and the user used #pragma GCC optimize, add the
+ options to the attribute((optimize(...))) list. */
+ if (TREE_CODE (*node) == FUNCTION_DECL && current_optimize_pragma)
+ {
+ tree cur_attr = lookup_attribute ("optimize", attributes);
+ tree opts = copy_list (current_optimize_pragma);
+
+ if (! cur_attr)
+ attributes
+ = tree_cons (get_identifier ("optimize"), opts, attributes);
+ else
+ TREE_VALUE (cur_attr) = chainon (opts, TREE_VALUE (cur_attr));
+ }
+
+ if (TREE_CODE (*node) == FUNCTION_DECL
+ && optimization_current_node != optimization_default_node
+ && !DECL_FUNCTION_SPECIFIC_OPTIMIZATION (*node))
+ DECL_FUNCTION_SPECIFIC_OPTIMIZATION (*node) = optimization_current_node;
+
+ /* If this is a function and the user used #pragma GCC option, add the
+ options to the attribute((option(...))) list. */
+ if (TREE_CODE (*node) == FUNCTION_DECL
+ && current_option_pragma
+ && targetm.target_option.valid_attribute_p (*node, NULL_TREE,
+ current_option_pragma, 0))
+ {
+ tree cur_attr = lookup_attribute ("option", attributes);
+ tree opts = copy_list (current_option_pragma);
+
+ if (! cur_attr)
+ attributes = tree_cons (get_identifier ("option"), opts, attributes);
+ else
+ TREE_VALUE (cur_attr) = chainon (opts, TREE_VALUE (cur_attr));
+ }
+
targetm.insert_attributes (*node, &attributes);
for (a = attributes; a; a = TREE_CHAIN (a))
diff --git a/gcc/basic-block.h b/gcc/basic-block.h
index 4aa864d66cf..ff6d0258191 100644
--- a/gcc/basic-block.h
+++ b/gcc/basic-block.h
@@ -122,7 +122,7 @@ struct edge_def GTY(())
/* Instructions queued on the edge. */
union edge_def_insns {
- tree GTY ((tag ("true"))) t;
+ gimple_seq GTY ((tag ("true"))) g;
rtx GTY ((tag ("false"))) r;
} GTY ((desc ("current_ir_type () == IR_GIMPLE"))) insns;
@@ -231,7 +231,7 @@ struct basic_block_def GTY((chain_next ("%h.next_bb"), chain_prev ("%h.prev_bb")
struct basic_block_def *next_bb;
union basic_block_il_dependent {
- struct tree_bb_info * GTY ((tag ("0"))) tree;
+ struct gimple_bb_info * GTY ((tag ("0"))) gimple;
struct rtl_bb_info * GTY ((tag ("1"))) rtl;
} GTY ((desc ("((%1.flags & BB_RTL) != 0)"))) il;
@@ -266,13 +266,13 @@ struct rtl_bb_info GTY(())
int visited;
};
-struct tree_bb_info GTY(())
+struct gimple_bb_info GTY(())
{
- /* Pointers to the first and last trees of the block. */
- tree stmt_list;
+ /* Sequence of statements in this block. */
+ gimple_seq seq;
- /* Chain of PHI nodes for this block. */
- tree phi_nodes;
+ /* PHI nodes for this block. */
+ gimple_seq phi_nodes;
};
typedef struct basic_block_def *basic_block;
@@ -383,7 +383,7 @@ struct control_flow_graph GTY(())
int x_last_basic_block;
/* Mapping of labels to their associated blocks. At present
- only used for the tree CFG. */
+ only used for the gimple CFG. */
VEC(basic_block,gc) *x_label_to_block_map;
enum profile_status {
@@ -831,9 +831,9 @@ extern bool maybe_hot_bb_p (const_basic_block);
extern bool maybe_hot_edge_p (edge);
extern bool probably_cold_bb_p (const_basic_block);
extern bool probably_never_executed_bb_p (const_basic_block);
-extern bool tree_predicted_by_p (const_basic_block, enum br_predictor);
+extern bool gimple_predicted_by_p (const_basic_block, enum br_predictor);
extern bool rtl_predicted_by_p (const_basic_block, enum br_predictor);
-extern void tree_predict_edge (edge, enum br_predictor, int);
+extern void gimple_predict_edge (edge, enum br_predictor, int);
extern void rtl_predict_edge (edge, enum br_predictor, int);
extern void predict_edge_def (edge, enum br_predictor, enum prediction);
extern void guess_outgoing_edge_probabilities (basic_block);
diff --git a/gcc/bt-load.c b/gcc/bt-load.c
index b0a7fdb4a21..2d4b3e0ad3e 100644
--- a/gcc/bt-load.c
+++ b/gcc/bt-load.c
@@ -301,31 +301,30 @@ add_btr_def (fibheap_t all_btr_defs, basic_block bb, int insn_luid, rtx insn,
unsigned int dest_reg, int other_btr_uses_before_def,
btr_def_group *all_btr_def_groups)
{
- btr_def this
- = XOBNEW (&migrate_btrl_obstack, struct btr_def_s);
- this->bb = bb;
- this->luid = insn_luid;
- this->insn = insn;
- this->btr = dest_reg;
- this->cost = basic_block_freq (bb);
- this->has_ambiguous_use = 0;
- this->other_btr_uses_before_def = other_btr_uses_before_def;
- this->other_btr_uses_after_use = 0;
- this->next_this_bb = NULL;
- this->next_this_group = NULL;
- this->uses = NULL;
- this->live_range = NULL;
- find_btr_def_group (all_btr_def_groups, this);
-
- fibheap_insert (all_btr_defs, -this->cost, this);
+ btr_def this_def = XOBNEW (&migrate_btrl_obstack, struct btr_def_s);
+ this_def->bb = bb;
+ this_def->luid = insn_luid;
+ this_def->insn = insn;
+ this_def->btr = dest_reg;
+ this_def->cost = basic_block_freq (bb);
+ this_def->has_ambiguous_use = 0;
+ this_def->other_btr_uses_before_def = other_btr_uses_before_def;
+ this_def->other_btr_uses_after_use = 0;
+ this_def->next_this_bb = NULL;
+ this_def->next_this_group = NULL;
+ this_def->uses = NULL;
+ this_def->live_range = NULL;
+ find_btr_def_group (all_btr_def_groups, this_def);
+
+ fibheap_insert (all_btr_defs, -this_def->cost, this_def);
if (dump_file)
fprintf (dump_file,
"Found target reg definition: sets %u { bb %d, insn %d }%s priority %d\n",
- dest_reg, bb->index, INSN_UID (insn), (this->group ? "" : ":not const"),
- this->cost);
+ dest_reg, bb->index, INSN_UID (insn),
+ (this_def->group ? "" : ":not const"), this_def->cost);
- return this;
+ return this_def;
}
/* Create a new target register user structure, for a use in block BB,
@@ -1274,7 +1273,7 @@ migrate_btr_def (btr_def def, int min_cost)
HARD_REG_SET btrs_live_in_range;
int btr_used_near_def = 0;
int def_basic_block_freq;
- basic_block try;
+ basic_block attempt;
int give_up = 0;
int def_moved = 0;
btr_user user;
@@ -1328,31 +1327,31 @@ migrate_btr_def (btr_def def, int min_cost)
def_basic_block_freq = basic_block_freq (def->bb);
- for (try = get_immediate_dominator (CDI_DOMINATORS, def->bb);
- !give_up && try && try != ENTRY_BLOCK_PTR && def->cost >= min_cost;
- try = get_immediate_dominator (CDI_DOMINATORS, try))
+ for (attempt = get_immediate_dominator (CDI_DOMINATORS, def->bb);
+ !give_up && attempt && attempt != ENTRY_BLOCK_PTR && def->cost >= min_cost;
+ attempt = get_immediate_dominator (CDI_DOMINATORS, attempt))
{
/* Try to move the instruction that sets the target register into
- basic block TRY. */
- int try_freq = basic_block_freq (try);
+ basic block ATTEMPT. */
+ int try_freq = basic_block_freq (attempt);
edge_iterator ei;
edge e;
- /* If TRY has abnormal edges, skip it. */
- FOR_EACH_EDGE (e, ei, try->succs)
+ /* If ATTEMPT has abnormal edges, skip it. */
+ FOR_EACH_EDGE (e, ei, attempt->succs)
if (e->flags & EDGE_COMPLEX)
break;
if (e)
continue;
if (dump_file)
- fprintf (dump_file, "trying block %d ...", try->index);
+ fprintf (dump_file, "trying block %d ...", attempt->index);
if (try_freq < def_basic_block_freq
|| (try_freq == def_basic_block_freq && btr_used_near_def))
{
int btr;
- augment_live_range (live_range, &btrs_live_in_range, def->bb, try,
+ augment_live_range (live_range, &btrs_live_in_range, def->bb, attempt,
flag_btr_bb_exclusive);
if (dump_file)
{
@@ -1363,7 +1362,7 @@ migrate_btr_def (btr_def def, int min_cost)
btr = choose_btr (btrs_live_in_range);
if (btr != -1)
{
- move_btr_def (try, btr, def, live_range, &btrs_live_in_range);
+ move_btr_def (attempt, btr, def, live_range, &btrs_live_in_range);
bitmap_copy(live_range, def->live_range);
btr_used_near_def = 0;
def_moved = 1;
@@ -1459,8 +1458,8 @@ migrate_btr_defs (enum reg_class btr_class, int allow_callee_save)
static void
branch_target_load_optimize (bool after_prologue_epilogue_gen)
{
- enum reg_class class = targetm.branch_target_register_class ();
- if (class != NO_REGS)
+ enum reg_class klass = targetm.branch_target_register_class ();
+ if (klass != NO_REGS)
{
/* Initialize issue_rate. */
if (targetm.sched.issue_rate)
@@ -1482,7 +1481,7 @@ branch_target_load_optimize (bool after_prologue_epilogue_gen)
/* Dominator info is also needed for migrate_btr_def. */
calculate_dominance_info (CDI_DOMINATORS);
- migrate_btr_defs (class,
+ migrate_btr_defs (klass,
(targetm.branch_target_register_callee_saved
(after_prologue_epilogue_gen)));
diff --git a/gcc/builtins.c b/gcc/builtins.c
index 731955b5699..288ad59717e 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -27,7 +27,7 @@ along with GCC; see the file COPYING3. If not see
#include "real.h"
#include "rtl.h"
#include "tree.h"
-#include "tree-gimple.h"
+#include "gimple.h"
#include "flags.h"
#include "regs.h"
#include "hard-reg-set.h"
@@ -98,8 +98,8 @@ static rtx expand_builtin_mathfn_3 (tree, rtx, rtx);
static rtx expand_builtin_interclass_mathfn (tree, rtx, rtx);
static rtx expand_builtin_sincos (tree);
static rtx expand_builtin_cexpi (tree, rtx, rtx);
-static rtx expand_builtin_int_roundingfn (tree, rtx, rtx);
-static rtx expand_builtin_int_roundingfn_2 (tree, rtx, rtx);
+static rtx expand_builtin_int_roundingfn (tree, rtx);
+static rtx expand_builtin_int_roundingfn_2 (tree, rtx);
static rtx expand_builtin_args_info (tree);
static rtx expand_builtin_next_arg (void);
static rtx expand_builtin_va_start (tree);
@@ -2464,11 +2464,10 @@ expand_builtin_cexpi (tree exp, rtx target, rtx subtarget)
do not need to worry about setting errno to EDOM.
If expanding via optab fails, lower expression to (int)(floor(x)).
EXP is the expression that is a call to the builtin function;
- if convenient, the result should be placed in TARGET. SUBTARGET may
- be used as the target for computing one of EXP's operands. */
+ if convenient, the result should be placed in TARGET. */
static rtx
-expand_builtin_int_roundingfn (tree exp, rtx target, rtx subtarget)
+expand_builtin_int_roundingfn (tree exp, rtx target)
{
convert_optab builtin_optab;
rtx op0, insns, tmp;
@@ -2511,7 +2510,7 @@ expand_builtin_int_roundingfn (tree exp, rtx target, rtx subtarget)
side-effects more the once. */
CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
- op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
+ op0 = expand_expr (arg, NULL, VOIDmode, EXPAND_NORMAL);
start_sequence ();
@@ -2592,11 +2591,10 @@ expand_builtin_int_roundingfn (tree exp, rtx target, rtx subtarget)
conversion (lrint).
Return 0 if a normal call should be emitted rather than expanding the
function in-line. EXP is the expression that is a call to the builtin
- function; if convenient, the result should be placed in TARGET.
- SUBTARGET may be used as the target for computing one of EXP's operands. */
+ function; if convenient, the result should be placed in TARGET. */
static rtx
-expand_builtin_int_roundingfn_2 (tree exp, rtx target, rtx subtarget)
+expand_builtin_int_roundingfn_2 (tree exp, rtx target)
{
convert_optab builtin_optab;
rtx op0, insns;
@@ -2635,7 +2633,7 @@ expand_builtin_int_roundingfn_2 (tree exp, rtx target, rtx subtarget)
side-effects more the once. */
CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
- op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
+ op0 = expand_expr (arg, NULL, VOIDmode, EXPAND_NORMAL);
start_sequence ();
@@ -3289,6 +3287,7 @@ expand_builtin_memcpy (tree exp, rtx target, enum machine_mode mode)
false, /*endp=*/0);
HOST_WIDE_INT expected_size = -1;
unsigned int expected_align = 0;
+ tree_ann_common_t ann;
if (result)
{
@@ -3310,7 +3309,10 @@ expand_builtin_memcpy (tree exp, rtx target, enum machine_mode mode)
if (src_align == 0)
return NULL_RTX;
- stringop_block_profile (exp, &expected_align, &expected_size);
+ ann = tree_common_ann (exp);
+ if (ann)
+ stringop_block_profile (ann->stmt, &expected_align, &expected_size);
+
if (expected_align < dest_align)
expected_align = dest_align;
dest_mem = get_memory_rtx (dest, len);
@@ -3885,6 +3887,7 @@ expand_builtin_memset_args (tree dest, tree val, tree len,
rtx dest_mem, dest_addr, len_rtx;
HOST_WIDE_INT expected_size = -1;
unsigned int expected_align = 0;
+ tree_ann_common_t ann;
dest_align = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
@@ -3892,7 +3895,10 @@ expand_builtin_memset_args (tree dest, tree val, tree len,
if (dest_align == 0)
return NULL_RTX;
- stringop_block_profile (orig_exp, &expected_align, &expected_size);
+ ann = tree_common_ann (orig_exp);
+ if (ann)
+ stringop_block_profile (ann->stmt, &expected_align, &expected_size);
+
if (expected_align < dest_align)
expected_align = dest_align;
@@ -4623,18 +4629,22 @@ expand_builtin_next_arg (void)
static tree
stabilize_va_list (tree valist, int needs_lvalue)
{
- if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
+ tree vatype = targetm.canonical_va_list_type (TREE_TYPE (valist));
+
+ gcc_assert (vatype != NULL_TREE);
+
+ if (TREE_CODE (vatype) == ARRAY_TYPE)
{
if (TREE_SIDE_EFFECTS (valist))
valist = save_expr (valist);
/* For this case, the backends will be expecting a pointer to
- TREE_TYPE (va_list_type_node), but it's possible we've
- actually been given an array (an actual va_list_type_node).
+ vatype, but it's possible we've actually been given an array
+ (an actual TARGET_CANONICAL_VA_LIST_TYPE (valist)).
So fix it. */
if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
{
- tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
+ tree p1 = build_pointer_type (TREE_TYPE (vatype));
valist = build_fold_addr_expr_with_type (valist, p1);
}
}
@@ -4647,7 +4657,7 @@ stabilize_va_list (tree valist, int needs_lvalue)
if (! TREE_SIDE_EFFECTS (valist))
return valist;
- pt = build_pointer_type (va_list_type_node);
+ pt = build_pointer_type (vatype);
valist = fold_build1 (ADDR_EXPR, pt, valist);
TREE_SIDE_EFFECTS (valist) = 1;
}
@@ -4668,6 +4678,49 @@ std_build_builtin_va_list (void)
return ptr_type_node;
}
+/* The "standard" abi va_list is va_list_type_node. */
+
+tree
+std_fn_abi_va_list (tree fndecl ATTRIBUTE_UNUSED)
+{
+ return va_list_type_node;
+}
+
+/* The "standard" type of va_list is va_list_type_node. */
+
+tree
+std_canonical_va_list_type (tree type)
+{
+ tree wtype, htype;
+
+ if (INDIRECT_REF_P (type))
+ type = TREE_TYPE (type);
+ else if (POINTER_TYPE_P (type) && POINTER_TYPE_P (TREE_TYPE(type)))
+ type = TREE_TYPE (type);
+ wtype = va_list_type_node;
+ htype = type;
+ /* Treat structure va_list types. */
+ if (TREE_CODE (wtype) == RECORD_TYPE && POINTER_TYPE_P (htype))
+ htype = TREE_TYPE (htype);
+ else if (TREE_CODE (wtype) == ARRAY_TYPE)
+ {
+ /* If va_list is an array type, the argument may have decayed
+ to a pointer type, e.g. by being passed to another function.
+ In that case, unwrap both types so that we can compare the
+ underlying records. */
+ if (TREE_CODE (htype) == ARRAY_TYPE
+ || POINTER_TYPE_P (htype))
+ {
+ wtype = TREE_TYPE (wtype);
+ htype = TREE_TYPE (htype);
+ }
+ }
+ if (TYPE_MAIN_VARIANT (wtype) == TYPE_MAIN_VARIANT (htype))
+ return va_list_type_node;
+
+ return NULL_TREE;
+}
+
/* The "standard" implementation of va_start: just assign `nextarg' to
the variable. */
@@ -4710,7 +4763,8 @@ expand_builtin_va_start (tree exp)
current (padded) address and increment by the (padded) size. */
tree
-std_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, tree *post_p)
+std_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p,
+ gimple_seq *post_p)
{
tree addr, t, type_size, rounded_size, valist_tmp;
unsigned HOST_WIDE_INT align, boundary;
@@ -4728,7 +4782,16 @@ std_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, tree *post_p)
type = build_pointer_type (type);
align = PARM_BOUNDARY / BITS_PER_UNIT;
- boundary = FUNCTION_ARG_BOUNDARY (TYPE_MODE (type), type) / BITS_PER_UNIT;
+ boundary = FUNCTION_ARG_BOUNDARY (TYPE_MODE (type), type);
+
+ /* When we align parameter on stack for caller, if the parameter
+ alignment is beyond PREFERRED_STACK_BOUNDARY, it will be
+ aligned at PREFERRED_STACK_BOUNDARY. We will match callee
+ here with caller. */
+ if (boundary > PREFERRED_STACK_BOUNDARY)
+ boundary = PREFERRED_STACK_BOUNDARY;
+
+ boundary /= BITS_PER_UNIT;
/* Hoist the valist value into a temporary for the moment. */
valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL);
@@ -4821,35 +4884,20 @@ dummy_object (tree type)
builtin function, but a very special sort of operator. */
enum gimplify_status
-gimplify_va_arg_expr (tree *expr_p, tree *pre_p, tree *post_p)
+gimplify_va_arg_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
{
- tree promoted_type, want_va_type, have_va_type;
+ tree promoted_type, have_va_type;
tree valist = TREE_OPERAND (*expr_p, 0);
tree type = TREE_TYPE (*expr_p);
tree t;
/* Verify that valist is of the proper type. */
- want_va_type = va_list_type_node;
have_va_type = TREE_TYPE (valist);
-
if (have_va_type == error_mark_node)
return GS_ERROR;
+ have_va_type = targetm.canonical_va_list_type (have_va_type);
- if (TREE_CODE (want_va_type) == ARRAY_TYPE)
- {
- /* If va_list is an array type, the argument may have decayed
- to a pointer type, e.g. by being passed to another function.
- In that case, unwrap both types so that we can compare the
- underlying records. */
- if (TREE_CODE (have_va_type) == ARRAY_TYPE
- || POINTER_TYPE_P (have_va_type))
- {
- want_va_type = TREE_TYPE (want_va_type);
- have_va_type = TREE_TYPE (have_va_type);
- }
- }
-
- if (TYPE_MAIN_VARIANT (want_va_type) != TYPE_MAIN_VARIANT (have_va_type))
+ if (have_va_type == NULL_TREE)
{
error ("first argument to %<va_arg%> not of type %<va_list%>");
return GS_ERROR;
@@ -4857,7 +4905,7 @@ gimplify_va_arg_expr (tree *expr_p, tree *pre_p, tree *post_p)
/* Generate a diagnostic for requesting data of a type that cannot
be passed through `...' due to type promotion at the call site. */
- else if ((promoted_type = lang_hooks.types.type_promotes_to (type))
+ if ((promoted_type = lang_hooks.types.type_promotes_to (type))
!= type)
{
static bool gave_help;
@@ -4878,7 +4926,7 @@ gimplify_va_arg_expr (tree *expr_p, tree *pre_p, tree *post_p)
Call abort to encourage the user to fix the program. */
inform ("if this code is reached, the program will abort");
t = build_call_expr (implicit_built_in_decls[BUILT_IN_TRAP], 0);
- append_to_statement_list (t, pre_p);
+ gimplify_and_add (t, pre_p);
/* This is dead code, but go ahead and finish so that the
mode of the result comes out right. */
@@ -4889,24 +4937,25 @@ gimplify_va_arg_expr (tree *expr_p, tree *pre_p, tree *post_p)
{
/* Make it easier for the backends by protecting the valist argument
from multiple evaluations. */
- if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
+ if (TREE_CODE (have_va_type) == ARRAY_TYPE)
{
/* For this case, the backends will be expecting a pointer to
- TREE_TYPE (va_list_type_node), but it's possible we've
- actually been given an array (an actual va_list_type_node).
+ TREE_TYPE (abi), but it's possible we've
+ actually been given an array (an actual TARGET_FN_ABI_VA_LIST).
So fix it. */
if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
{
- tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
+ tree p1 = build_pointer_type (TREE_TYPE (have_va_type));
valist = build_fold_addr_expr_with_type (valist, p1);
}
+
gimplify_expr (&valist, pre_p, post_p, is_gimple_val, fb_rvalue);
}
else
gimplify_expr (&valist, pre_p, post_p, is_gimple_min_lval, fb_lvalue);
if (!targetm.gimplify_va_arg_expr)
- /* FIXME:Once most targets are converted we should merely
+ /* FIXME: Once most targets are converted we should merely
assert this is non-null. */
return GS_ALL_DONE;
@@ -4945,9 +4994,11 @@ expand_builtin_va_copy (tree exp)
dst = stabilize_va_list (dst, 1);
src = stabilize_va_list (src, 0);
- if (TREE_CODE (va_list_type_node) != ARRAY_TYPE)
+ gcc_assert (cfun != NULL && cfun->decl != NULL_TREE);
+
+ if (TREE_CODE (targetm.fn_abi_va_list (cfun->decl)) != ARRAY_TYPE)
{
- t = build2 (MODIFY_EXPR, va_list_type_node, dst, src);
+ t = build2 (MODIFY_EXPR, targetm.fn_abi_va_list (cfun->decl), dst, src);
TREE_SIDE_EFFECTS (t) = 1;
expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
}
@@ -4958,8 +5009,8 @@ expand_builtin_va_copy (tree exp)
/* Evaluate to pointers. */
dstb = expand_expr (dst, NULL_RTX, Pmode, EXPAND_NORMAL);
srcb = expand_expr (src, NULL_RTX, Pmode, EXPAND_NORMAL);
- size = expand_expr (TYPE_SIZE_UNIT (va_list_type_node), NULL_RTX,
- VOIDmode, EXPAND_NORMAL);
+ size = expand_expr (TYPE_SIZE_UNIT (targetm.fn_abi_va_list (cfun->decl)),
+ NULL_RTX, VOIDmode, EXPAND_NORMAL);
dstb = convert_memory_address (Pmode, dstb);
srcb = convert_memory_address (Pmode, srcb);
@@ -4967,10 +5018,10 @@ expand_builtin_va_copy (tree exp)
/* "Dereference" to BLKmode memories. */
dstb = gen_rtx_MEM (BLKmode, dstb);
set_mem_alias_set (dstb, get_alias_set (TREE_TYPE (TREE_TYPE (dst))));
- set_mem_align (dstb, TYPE_ALIGN (va_list_type_node));
+ set_mem_align (dstb, TYPE_ALIGN (targetm.fn_abi_va_list (cfun->decl)));
srcb = gen_rtx_MEM (BLKmode, srcb);
set_mem_alias_set (srcb, get_alias_set (TREE_TYPE (TREE_TYPE (src))));
- set_mem_align (srcb, TYPE_ALIGN (va_list_type_node));
+ set_mem_align (srcb, TYPE_ALIGN (targetm.fn_abi_va_list (cfun->decl)));
/* Copy. */
emit_block_move (dstb, srcb, size, BLOCK_OP_NORMAL);
@@ -6164,7 +6215,7 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
CASE_FLT_FN (BUILT_IN_LLCEIL):
CASE_FLT_FN (BUILT_IN_LFLOOR):
CASE_FLT_FN (BUILT_IN_LLFLOOR):
- target = expand_builtin_int_roundingfn (exp, target, subtarget);
+ target = expand_builtin_int_roundingfn (exp, target);
if (target)
return target;
break;
@@ -6173,7 +6224,7 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
CASE_FLT_FN (BUILT_IN_LLRINT):
CASE_FLT_FN (BUILT_IN_LROUND):
CASE_FLT_FN (BUILT_IN_LLROUND):
- target = expand_builtin_int_roundingfn_2 (exp, target, subtarget);
+ target = expand_builtin_int_roundingfn_2 (exp, target);
if (target)
return target;
break;
@@ -7207,7 +7258,7 @@ fold_builtin_inf (tree type, int warn)
Thus we pedwarn to ensure this constraint violation is
diagnosed. */
if (!MODE_HAS_INFINITIES (TYPE_MODE (type)) && warn)
- pedwarn ("target format does not support infinity");
+ pedwarn (0, "target format does not support infinity");
real_inf (&real);
return build_real (type, real);
@@ -7251,7 +7302,7 @@ integer_valued_real_p (tree t)
case COMPOUND_EXPR:
case MODIFY_EXPR:
case BIND_EXPR:
- return integer_valued_real_p (GENERIC_TREE_OPERAND (t, 1));
+ return integer_valued_real_p (TREE_OPERAND (t, 1));
case PLUS_EXPR:
case MINUS_EXPR:
@@ -10531,7 +10582,7 @@ fold_builtin_n (tree fndecl, tree *args, int nargs, bool ignore)
}
if (ret)
{
- ret = build1 (NOP_EXPR, GENERIC_TREE_TYPE (ret), ret);
+ ret = build1 (NOP_EXPR, TREE_TYPE (ret), ret);
TREE_NO_WARNING (ret) = 1;
return ret;
}
@@ -10792,6 +10843,61 @@ validate_arg (const_tree arg, enum tree_code code)
/* This function validates the types of a function call argument list
against a specified list of tree_codes. If the last specifier is a 0,
that represents an ellipses, otherwise the last specifier must be a
+ VOID_TYPE.
+
+ This is the GIMPLE version of validate_arglist. Eventually we want to
+ completely convert builtins.c to work from GIMPLEs and the tree based
+ validate_arglist will then be removed. */
+
+bool
+validate_gimple_arglist (const_gimple call, ...)
+{
+ enum tree_code code;
+ bool res = 0;
+ va_list ap;
+ const_tree arg;
+ size_t i;
+
+ va_start (ap, call);
+ i = 0;
+
+ do
+ {
+ code = va_arg (ap, enum tree_code);
+ switch (code)
+ {
+ case 0:
+ /* This signifies an ellipses, any further arguments are all ok. */
+ res = true;
+ goto end;
+ case VOID_TYPE:
+ /* This signifies an endlink, if no arguments remain, return
+ true, otherwise return false. */
+ res = (i == gimple_call_num_args (call));
+ goto end;
+ default:
+ /* If no parameters remain or the parameter's code does not
+ match the specified code, return false. Otherwise continue
+ checking any remaining arguments. */
+ arg = gimple_call_arg (call, i++);
+ if (!validate_arg (arg, code))
+ goto end;
+ break;
+ }
+ }
+ while (1);
+
+ /* We need gotos here since we can only have one VA_CLOSE in a
+ function. */
+ end: ;
+ va_end (ap);
+
+ return res;
+}
+
+/* This function validates the types of a function call argument list
+ against a specified list of tree_codes. If the last specifier is a 0,
+ that represents an ellipses, otherwise the last specifier must be a
VOID_TYPE. */
bool
@@ -11398,6 +11504,7 @@ fold_builtin_fputs (tree arg0, tree arg1, bool ignore, bool unlocked, tree len)
/* Fold the next_arg or va_start call EXP. Returns true if there was an error
produced. False otherwise. This is done so that we don't output the error
or warning twice or three times. */
+
bool
fold_builtin_next_arg (tree exp, bool va_start_p)
{
@@ -13072,3 +13179,303 @@ do_mpfr_lgamma_r (tree arg, tree arg_sg, tree type)
return result;
}
#endif
+
+/* FIXME tuples.
+ The functions below provide an alternate interface for folding
+ builtin function calls presented as GIMPLE_CALL statements rather
+ than as CALL_EXPRs. The folded result is still expressed as a
+ tree. There is too much code duplication in the handling of
+ varargs functions, and a more intrusive re-factoring would permit
+ better sharing of code between the tree and statement-based
+ versions of these functions. */
+
+/* Construct a new CALL_EXPR using the tail of the argument list of STMT
+ along with N new arguments specified as the "..." parameters. SKIP
+ is the number of arguments in STMT to be omitted. This function is used
+ to do varargs-to-varargs transformations. */
+
+static tree
+gimple_rewrite_call_expr (gimple stmt, int skip, tree fndecl, int n, ...)
+{
+ int oldnargs = gimple_call_num_args (stmt);
+ int nargs = oldnargs - skip + n;
+ tree fntype = TREE_TYPE (fndecl);
+ tree fn = build1 (ADDR_EXPR, build_pointer_type (fntype), fndecl);
+ tree *buffer;
+ int i, j;
+ va_list ap;
+
+ buffer = XALLOCAVEC (tree, nargs);
+ va_start (ap, n);
+ for (i = 0; i < n; i++)
+ buffer[i] = va_arg (ap, tree);
+ va_end (ap);
+ for (j = skip; j < oldnargs; j++, i++)
+ buffer[i] = gimple_call_arg (stmt, j);
+
+ return fold (build_call_array (TREE_TYPE (fntype), fn, nargs, buffer));
+}
+
+/* Fold a call STMT to __{,v}sprintf_chk. Return NULL_TREE if
+ a normal call should be emitted rather than expanding the function
+ inline. FCODE is either BUILT_IN_SPRINTF_CHK or BUILT_IN_VSPRINTF_CHK. */
+
+static tree
+gimple_fold_builtin_sprintf_chk (gimple stmt, enum built_in_function fcode)
+{
+ tree dest, size, len, fn, fmt, flag;
+ const char *fmt_str;
+ int nargs = gimple_call_num_args (stmt);
+
+ /* Verify the required arguments in the original call. */
+ if (nargs < 4)
+ return NULL_TREE;
+ dest = gimple_call_arg (stmt, 0);
+ if (!validate_arg (dest, POINTER_TYPE))
+ return NULL_TREE;
+ flag = gimple_call_arg (stmt, 1);
+ if (!validate_arg (flag, INTEGER_TYPE))
+ return NULL_TREE;
+ size = gimple_call_arg (stmt, 2);
+ if (!validate_arg (size, INTEGER_TYPE))
+ return NULL_TREE;
+ fmt = gimple_call_arg (stmt, 3);
+ if (!validate_arg (fmt, POINTER_TYPE))
+ return NULL_TREE;
+
+ if (! host_integerp (size, 1))
+ return NULL_TREE;
+
+ len = NULL_TREE;
+
+ if (!init_target_chars ())
+ return NULL_TREE;
+
+ /* Check whether the format is a literal string constant. */
+ fmt_str = c_getstr (fmt);
+ if (fmt_str != NULL)
+ {
+ /* If the format doesn't contain % args or %%, we know the size. */
+ if (strchr (fmt_str, target_percent) == 0)
+ {
+ if (fcode != BUILT_IN_SPRINTF_CHK || nargs == 4)
+ len = build_int_cstu (size_type_node, strlen (fmt_str));
+ }
+ /* If the format is "%s" and first ... argument is a string literal,
+ we know the size too. */
+ else if (fcode == BUILT_IN_SPRINTF_CHK
+ && strcmp (fmt_str, target_percent_s) == 0)
+ {
+ tree arg;
+
+ if (nargs == 5)
+ {
+ arg = gimple_call_arg (stmt, 4);
+ if (validate_arg (arg, POINTER_TYPE))
+ {
+ len = c_strlen (arg, 1);
+ if (! len || ! host_integerp (len, 1))
+ len = NULL_TREE;
+ }
+ }
+ }
+ }
+
+ if (! integer_all_onesp (size))
+ {
+ if (! len || ! tree_int_cst_lt (len, size))
+ return NULL_TREE;
+ }
+
+ /* Only convert __{,v}sprintf_chk to {,v}sprintf if flag is 0
+ or if format doesn't contain % chars or is "%s". */
+ if (! integer_zerop (flag))
+ {
+ if (fmt_str == NULL)
+ return NULL_TREE;
+ if (strchr (fmt_str, target_percent) != NULL
+ && strcmp (fmt_str, target_percent_s))
+ return NULL_TREE;
+ }
+
+ /* If __builtin_{,v}sprintf_chk is used, assume {,v}sprintf is available. */
+ fn = built_in_decls[fcode == BUILT_IN_VSPRINTF_CHK
+ ? BUILT_IN_VSPRINTF : BUILT_IN_SPRINTF];
+ if (!fn)
+ return NULL_TREE;
+
+ return gimple_rewrite_call_expr (stmt, 4, fn, 2, dest, fmt);
+}
+
+/* Fold a call STMT to {,v}snprintf. Return NULL_TREE if
+ a normal call should be emitted rather than expanding the function
+ inline. FCODE is either BUILT_IN_SNPRINTF_CHK or
+ BUILT_IN_VSNPRINTF_CHK. If MAXLEN is not NULL, it is maximum length
+ passed as second argument. */
+
+tree
+gimple_fold_builtin_snprintf_chk (gimple stmt, tree maxlen,
+ enum built_in_function fcode)
+{
+ tree dest, size, len, fn, fmt, flag;
+ const char *fmt_str;
+
+ /* Verify the required arguments in the original call. */
+ if (gimple_call_num_args (stmt) < 5)
+ return NULL_TREE;
+ dest = gimple_call_arg (stmt, 0);
+ if (!validate_arg (dest, POINTER_TYPE))
+ return NULL_TREE;
+ len = gimple_call_arg (stmt, 1);
+ if (!validate_arg (len, INTEGER_TYPE))
+ return NULL_TREE;
+ flag = gimple_call_arg (stmt, 2);
+ if (!validate_arg (flag, INTEGER_TYPE))
+ return NULL_TREE;
+ size = gimple_call_arg (stmt, 3);
+ if (!validate_arg (size, INTEGER_TYPE))
+ return NULL_TREE;
+ fmt = gimple_call_arg (stmt, 4);
+ if (!validate_arg (fmt, POINTER_TYPE))
+ return NULL_TREE;
+
+ if (! host_integerp (size, 1))
+ return NULL_TREE;
+
+ if (! integer_all_onesp (size))
+ {
+ if (! host_integerp (len, 1))
+ {
+ /* If LEN is not constant, try MAXLEN too.
+ For MAXLEN only allow optimizing into non-_ocs function
+ if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
+ if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
+ return NULL_TREE;
+ }
+ else
+ maxlen = len;
+
+ if (tree_int_cst_lt (size, maxlen))
+ return NULL_TREE;
+ }
+
+ if (!init_target_chars ())
+ return NULL_TREE;
+
+ /* Only convert __{,v}snprintf_chk to {,v}snprintf if flag is 0
+ or if format doesn't contain % chars or is "%s". */
+ if (! integer_zerop (flag))
+ {
+ fmt_str = c_getstr (fmt);
+ if (fmt_str == NULL)
+ return NULL_TREE;
+ if (strchr (fmt_str, target_percent) != NULL
+ && strcmp (fmt_str, target_percent_s))
+ return NULL_TREE;
+ }
+
+ /* If __builtin_{,v}snprintf_chk is used, assume {,v}snprintf is
+ available. */
+ fn = built_in_decls[fcode == BUILT_IN_VSNPRINTF_CHK
+ ? BUILT_IN_VSNPRINTF : BUILT_IN_SNPRINTF];
+ if (!fn)
+ return NULL_TREE;
+
+ return gimple_rewrite_call_expr (stmt, 5, fn, 3, dest, len, fmt);
+}
+
+/* Builtins with folding operations that operate on "..." arguments
+ need special handling; we need to store the arguments in a convenient
+ data structure before attempting any folding. Fortunately there are
+ only a few builtins that fall into this category. FNDECL is the
+ function, EXP is the CALL_EXPR for the call, and IGNORE is true if the
+ result of the function call is ignored. */
+
+static tree
+gimple_fold_builtin_varargs (tree fndecl, gimple stmt, bool ignore ATTRIBUTE_UNUSED)
+{
+ enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
+ tree ret = NULL_TREE;
+
+ switch (fcode)
+ {
+ case BUILT_IN_SPRINTF_CHK:
+ case BUILT_IN_VSPRINTF_CHK:
+ ret = gimple_fold_builtin_sprintf_chk (stmt, fcode);
+ break;
+
+ case BUILT_IN_SNPRINTF_CHK:
+ case BUILT_IN_VSNPRINTF_CHK:
+ ret = gimple_fold_builtin_snprintf_chk (stmt, NULL_TREE, fcode);
+
+ default:
+ break;
+ }
+ if (ret)
+ {
+ ret = build1 (NOP_EXPR, TREE_TYPE (ret), ret);
+ TREE_NO_WARNING (ret) = 1;
+ return ret;
+ }
+ return NULL_TREE;
+}
+
+/* A wrapper function for builtin folding that prevents warnings for
+ "statement without effect" and the like, caused by removing the
+ call node earlier than the warning is generated. */
+
+tree
+fold_call_stmt (gimple stmt, bool ignore)
+{
+ tree ret = NULL_TREE;
+ tree fndecl = gimple_call_fndecl (stmt);
+ if (fndecl
+ && TREE_CODE (fndecl) == FUNCTION_DECL
+ && DECL_BUILT_IN (fndecl)
+ && !gimple_call_va_arg_pack_p (stmt))
+ {
+ int nargs = gimple_call_num_args (stmt);
+
+ /* FIXME: Don't use a list in this interface. */
+ if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
+ {
+ tree arglist = NULL_TREE;
+ int i;
+ for (i = nargs - 1; i >= 0; i--)
+ arglist = tree_cons (NULL_TREE, gimple_call_arg (stmt, i), arglist);
+ return targetm.fold_builtin (fndecl, arglist, ignore);
+ }
+ else
+ {
+ if (nargs <= MAX_ARGS_TO_FOLD_BUILTIN)
+ {
+ tree args[MAX_ARGS_TO_FOLD_BUILTIN];
+ int i;
+ for (i = 0; i < nargs; i++)
+ args[i] = gimple_call_arg (stmt, i);
+ ret = fold_builtin_n (fndecl, args, nargs, ignore);
+ }
+ if (!ret)
+ ret = gimple_fold_builtin_varargs (fndecl, stmt, ignore);
+ if (ret)
+ {
+ /* Propagate location information from original call to
+ expansion of builtin. Otherwise things like
+ maybe_emit_chk_warning, that operate on the expansion
+ of a builtin, will use the wrong location information. */
+ if (gimple_has_location (stmt))
+ {
+ tree realret = ret;
+ if (TREE_CODE (ret) == NOP_EXPR)
+ realret = TREE_OPERAND (ret, 0);
+ if (CAN_HAVE_LOCATION_P (realret)
+ && !EXPR_HAS_LOCATION (realret))
+ SET_EXPR_LOCATION (realret, gimple_location (stmt));
+ return realret;
+ }
+ return ret;
+ }
+ }
+ }
+ return NULL_TREE;
+}
diff --git a/gcc/c-common.c b/gcc/c-common.c
index 3a633843f73..caac53e7cdd 100644
--- a/gcc/c-common.c
+++ b/gcc/c-common.c
@@ -48,6 +48,7 @@ along with GCC; see the file COPYING3. If not see
#include "real.h"
#include "cgraph.h"
#include "target-def.h"
+#include "gimple.h"
#include "fixed-value.h"
cpp_reader *parse_in; /* Declared in c-pragma.h. */
@@ -574,6 +575,8 @@ static tree handle_warn_unused_result_attribute (tree *, tree, tree, int,
static tree handle_sentinel_attribute (tree *, tree, tree, int, bool *);
static tree handle_type_generic_attribute (tree *, tree, tree, int, bool *);
static tree handle_alloc_size_attribute (tree *, tree, tree, int, bool *);
+static tree handle_option_attribute (tree *, tree, tree, int, bool *);
+static tree handle_optimize_attribute (tree *, tree, tree, int, bool *);
static void check_function_nonnull (tree, int, tree *);
static void check_nonnull_arg (void *, tree, unsigned HOST_WIDE_INT);
@@ -581,6 +584,179 @@ static bool nonnull_check_p (tree, unsigned HOST_WIDE_INT);
static bool get_nonnull_operand (tree, unsigned HOST_WIDE_INT *);
static int resort_field_decl_cmp (const void *, const void *);
+/* Reserved words. The third field is a mask: keywords are disabled
+ if they match the mask.
+
+ Masks for languages:
+ C --std=c89: D_C99 | D_CXXONLY | D_OBJC | D_CXX_OBJC
+ C --std=c99: D_CXXONLY | D_OBJC
+ ObjC is like C except that D_OBJC and D_CXX_OBJC are not set
+ C++ --std=c98: D_CONLY | D_CXXOX | D_OBJC
+ C++ --std=c0x: D_CONLY | D_OBJC
+ ObjC++ is like C++ except that D_OBJC is not set
+
+ If -fno-asm is used, D_ASM is added to the mask. If
+ -fno-gnu-keywords is used, D_EXT is added. If -fno-asm and C in
+ C89 mode, D_EXT89 is added for both -fno-asm and -fno-gnu-keywords.
+ In C with -Wcxx-compat, we warn if D_CXXWARN is set. */
+
+const struct c_common_resword c_common_reswords[] =
+{
+ { "_Bool", RID_BOOL, D_CONLY },
+ { "_Complex", RID_COMPLEX, 0 },
+ { "_Decimal32", RID_DFLOAT32, D_CONLY | D_EXT },
+ { "_Decimal64", RID_DFLOAT64, D_CONLY | D_EXT },
+ { "_Decimal128", RID_DFLOAT128, D_CONLY | D_EXT },
+ { "_Fract", RID_FRACT, D_CONLY | D_EXT },
+ { "_Accum", RID_ACCUM, D_CONLY | D_EXT },
+ { "_Sat", RID_SAT, D_CONLY | D_EXT },
+ { "__FUNCTION__", RID_FUNCTION_NAME, 0 },
+ { "__PRETTY_FUNCTION__", RID_PRETTY_FUNCTION_NAME, 0 },
+ { "__alignof", RID_ALIGNOF, 0 },
+ { "__alignof__", RID_ALIGNOF, 0 },
+ { "__asm", RID_ASM, 0 },
+ { "__asm__", RID_ASM, 0 },
+ { "__attribute", RID_ATTRIBUTE, 0 },
+ { "__attribute__", RID_ATTRIBUTE, 0 },
+ { "__builtin_choose_expr", RID_CHOOSE_EXPR, D_CONLY },
+ { "__builtin_offsetof", RID_OFFSETOF, 0 },
+ { "__builtin_types_compatible_p", RID_TYPES_COMPATIBLE_P, D_CONLY },
+ { "__builtin_va_arg", RID_VA_ARG, 0 },
+ { "__complex", RID_COMPLEX, 0 },
+ { "__complex__", RID_COMPLEX, 0 },
+ { "__const", RID_CONST, 0 },
+ { "__const__", RID_CONST, 0 },
+ { "__decltype", RID_DECLTYPE, D_CXXONLY },
+ { "__extension__", RID_EXTENSION, 0 },
+ { "__func__", RID_C99_FUNCTION_NAME, 0 },
+ { "__has_nothrow_assign", RID_HAS_NOTHROW_ASSIGN, D_CXXONLY },
+ { "__has_nothrow_constructor", RID_HAS_NOTHROW_CONSTRUCTOR, D_CXXONLY },
+ { "__has_nothrow_copy", RID_HAS_NOTHROW_COPY, D_CXXONLY },
+ { "__has_trivial_assign", RID_HAS_TRIVIAL_ASSIGN, D_CXXONLY },
+ { "__has_trivial_constructor", RID_HAS_TRIVIAL_CONSTRUCTOR, D_CXXONLY },
+ { "__has_trivial_copy", RID_HAS_TRIVIAL_COPY, D_CXXONLY },
+ { "__has_trivial_destructor", RID_HAS_TRIVIAL_DESTRUCTOR, D_CXXONLY },
+ { "__has_virtual_destructor", RID_HAS_VIRTUAL_DESTRUCTOR, D_CXXONLY },
+ { "__is_abstract", RID_IS_ABSTRACT, D_CXXONLY },
+ { "__is_base_of", RID_IS_BASE_OF, D_CXXONLY },
+ { "__is_class", RID_IS_CLASS, D_CXXONLY },
+ { "__is_convertible_to", RID_IS_CONVERTIBLE_TO, D_CXXONLY },
+ { "__is_empty", RID_IS_EMPTY, D_CXXONLY },
+ { "__is_enum", RID_IS_ENUM, D_CXXONLY },
+ { "__is_pod", RID_IS_POD, D_CXXONLY },
+ { "__is_polymorphic", RID_IS_POLYMORPHIC, D_CXXONLY },
+ { "__is_union", RID_IS_UNION, D_CXXONLY },
+ { "__imag", RID_IMAGPART, 0 },
+ { "__imag__", RID_IMAGPART, 0 },
+ { "__inline", RID_INLINE, 0 },
+ { "__inline__", RID_INLINE, 0 },
+ { "__label__", RID_LABEL, 0 },
+ { "__null", RID_NULL, 0 },
+ { "__real", RID_REALPART, 0 },
+ { "__real__", RID_REALPART, 0 },
+ { "__restrict", RID_RESTRICT, 0 },
+ { "__restrict__", RID_RESTRICT, 0 },
+ { "__signed", RID_SIGNED, 0 },
+ { "__signed__", RID_SIGNED, 0 },
+ { "__thread", RID_THREAD, 0 },
+ { "__typeof", RID_TYPEOF, 0 },
+ { "__typeof__", RID_TYPEOF, 0 },
+ { "__volatile", RID_VOLATILE, 0 },
+ { "__volatile__", RID_VOLATILE, 0 },
+ { "asm", RID_ASM, D_ASM },
+ { "auto", RID_AUTO, 0 },
+ { "bool", RID_BOOL, D_CXXONLY },
+ { "break", RID_BREAK, 0 },
+ { "case", RID_CASE, 0 },
+ { "catch", RID_CATCH, D_CXX_OBJC },
+ { "char", RID_CHAR, 0 },
+ { "char16_t", RID_CHAR16, D_CXXONLY | D_CXX0X },
+ { "char32_t", RID_CHAR32, D_CXXONLY | D_CXX0X },
+ { "class", RID_CLASS, D_CXX_OBJC },
+ { "const", RID_CONST, 0 },
+ { "const_cast", RID_CONSTCAST, D_CXXONLY | D_CXXWARN },
+ { "continue", RID_CONTINUE, 0 },
+ { "decltype", RID_DECLTYPE, D_CXXONLY | D_CXX0X },
+ { "default", RID_DEFAULT, 0 },
+ { "delete", RID_DELETE, D_CXXONLY },
+ { "do", RID_DO, 0 },
+ { "double", RID_DOUBLE, 0 },
+ { "dynamic_cast", RID_DYNCAST, D_CXXONLY | D_CXXWARN },
+ { "else", RID_ELSE, 0 },
+ { "enum", RID_ENUM, 0 },
+ { "explicit", RID_EXPLICIT, D_CXXONLY },
+ { "export", RID_EXPORT, D_CXXONLY },
+ { "extern", RID_EXTERN, 0 },
+ { "false", RID_FALSE, D_CXXONLY },
+ { "float", RID_FLOAT, 0 },
+ { "for", RID_FOR, 0 },
+ { "friend", RID_FRIEND, D_CXXONLY },
+ { "goto", RID_GOTO, 0 },
+ { "if", RID_IF, 0 },
+ { "inline", RID_INLINE, D_EXT89 },
+ { "int", RID_INT, 0 },
+ { "long", RID_LONG, 0 },
+ { "mutable", RID_MUTABLE, D_CXXONLY | D_CXXWARN },
+ { "namespace", RID_NAMESPACE, D_CXXONLY },
+ { "new", RID_NEW, D_CXXONLY },
+ { "operator", RID_OPERATOR, D_CXXONLY },
+ { "private", RID_PRIVATE, D_CXX_OBJC },
+ { "protected", RID_PROTECTED, D_CXX_OBJC },
+ { "public", RID_PUBLIC, D_CXX_OBJC },
+ { "register", RID_REGISTER, 0 },
+ { "reinterpret_cast", RID_REINTCAST, D_CXXONLY | D_CXXWARN },
+ { "restrict", RID_RESTRICT, D_CONLY | D_C99 },
+ { "return", RID_RETURN, 0 },
+ { "short", RID_SHORT, 0 },
+ { "signed", RID_SIGNED, 0 },
+ { "sizeof", RID_SIZEOF, 0 },
+ { "static", RID_STATIC, 0 },
+ { "static_assert", RID_STATIC_ASSERT, D_CXXONLY | D_CXX0X | D_CXXWARN },
+ { "static_cast", RID_STATCAST, D_CXXONLY | D_CXXWARN },
+ { "struct", RID_STRUCT, 0 },
+ { "switch", RID_SWITCH, 0 },
+ { "template", RID_TEMPLATE, D_CXXONLY },
+ { "this", RID_THIS, D_CXXONLY },
+ { "throw", RID_THROW, D_CXX_OBJC },
+ { "true", RID_TRUE, D_CXXONLY },
+ { "try", RID_TRY, D_CXX_OBJC },
+ { "typedef", RID_TYPEDEF, 0 },
+ { "typename", RID_TYPENAME, D_CXXONLY },
+ { "typeid", RID_TYPEID, D_CXXONLY },
+ { "typeof", RID_TYPEOF, D_ASM | D_EXT },
+ { "union", RID_UNION, 0 },
+ { "unsigned", RID_UNSIGNED, 0 },
+ { "using", RID_USING, D_CXXONLY },
+ { "virtual", RID_VIRTUAL, D_CXXONLY },
+ { "void", RID_VOID, 0 },
+ { "volatile", RID_VOLATILE, 0 },
+ { "wchar_t", RID_WCHAR, D_CXXONLY },
+ { "while", RID_WHILE, 0 },
+ /* These Objective-C keywords are recognized only immediately after
+ an '@'. */
+ { "compatibility_alias", RID_AT_ALIAS, D_OBJC },
+ { "defs", RID_AT_DEFS, D_OBJC },
+ { "encode", RID_AT_ENCODE, D_OBJC },
+ { "end", RID_AT_END, D_OBJC },
+ { "implementation", RID_AT_IMPLEMENTATION, D_OBJC },
+ { "interface", RID_AT_INTERFACE, D_OBJC },
+ { "protocol", RID_AT_PROTOCOL, D_OBJC },
+ { "selector", RID_AT_SELECTOR, D_OBJC },
+ { "finally", RID_AT_FINALLY, D_OBJC },
+ { "synchronized", RID_AT_SYNCHRONIZED, D_OBJC },
+ /* These are recognized only in protocol-qualifier context
+ (see above) */
+ { "bycopy", RID_BYCOPY, D_OBJC },
+ { "byref", RID_BYREF, D_OBJC },
+ { "in", RID_IN, D_OBJC },
+ { "inout", RID_INOUT, D_OBJC },
+ { "oneway", RID_ONEWAY, D_OBJC },
+ { "out", RID_OUT, D_OBJC },
+};
+
+const unsigned int num_c_common_reswords =
+ sizeof c_common_reswords / sizeof (struct c_common_resword);
+
/* Table of machine-independent attributes common to all C-like languages. */
const struct attribute_spec c_common_attribute_table[] =
{
@@ -684,6 +860,10 @@ const struct attribute_spec c_common_attribute_table[] =
handle_error_attribute },
{ "error", 1, 1, true, false, false,
handle_error_attribute },
+ { "option", 1, -1, true, false, false,
+ handle_option_attribute },
+ { "optimize", 1, -1, true, false, false,
+ handle_optimize_attribute },
{ NULL, 0, 0, false, false, false, NULL }
};
@@ -868,7 +1048,7 @@ fname_decl (unsigned int rid, tree id)
input_location = saved_location;
}
if (!ix && !current_function_decl)
- pedwarn ("%qD is not defined outside of function scope", decl);
+ pedwarn (0, "%qD is not defined outside of function scope", decl);
return decl;
}
@@ -917,7 +1097,8 @@ fix_string_type (tree value)
separate the %d from the 'C'. 'ISO' should not be
translated, but it may be moved after 'C%d' in languages
where modifiers follow nouns. */
- pedwarn ("string length %qd is greater than the length %qd "
+ pedwarn (OPT_Woverlength_strings,
+ "string length %qd is greater than the length %qd "
"ISO C%d compilers are required to support",
nchars - 1, nchars_max, relevant_std);
}
@@ -964,7 +1145,7 @@ constant_expression_warning (tree value)
|| TREE_CODE (value) == VECTOR_CST
|| TREE_CODE (value) == COMPLEX_CST)
&& TREE_OVERFLOW (value))
- pedwarn ("overflow in constant expression");
+ pedwarn (OPT_Woverflow, "overflow in constant expression");
}
/* The same as above but print an unconditional error. */
@@ -1069,8 +1250,13 @@ warn_logical_operator (enum tree_code code, tree arg1, tree
bool
strict_aliasing_warning (tree otype, tree type, tree expr)
{
- if (!(flag_strict_aliasing && POINTER_TYPE_P (type)
- && POINTER_TYPE_P (otype) && !VOID_TYPE_P (TREE_TYPE (type))))
+ if (!(flag_strict_aliasing
+ && POINTER_TYPE_P (type)
+ && POINTER_TYPE_P (otype)
+ && !VOID_TYPE_P (TREE_TYPE (type)))
+ /* If the type we are casting to is a ref-all pointer
+ dereferencing it is always valid. */
+ || TYPE_REF_CAN_ALIAS_ALL (type))
return false;
if ((warn_strict_aliasing > 1) && TREE_CODE (expr) == ADDR_EXPR
@@ -1177,7 +1363,7 @@ check_main_parameter_types (tree decl)
{
case 1:
if (TYPE_MAIN_VARIANT (type) != integer_type_node)
- pedwarn ("first argument of %q+D should be %<int%>", decl);
+ pedwarn (0, "first argument of %q+D should be %<int%>", decl);
break;
case 2:
@@ -1185,8 +1371,8 @@ check_main_parameter_types (tree decl)
|| TREE_CODE (TREE_TYPE (type)) != POINTER_TYPE
|| (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (type)))
!= char_type_node))
- pedwarn ("second argument of %q+D should be %<char **%>",
- decl);
+ pedwarn (0, "second argument of %q+D should be %<char **%>",
+ decl);
break;
case 3:
@@ -1194,8 +1380,8 @@ check_main_parameter_types (tree decl)
|| TREE_CODE (TREE_TYPE (type)) != POINTER_TYPE
|| (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (type)))
!= char_type_node))
- pedwarn ("third argument of %q+D should probably be "
- "%<char **%>", decl);
+ pedwarn (0, "third argument of %q+D should probably be "
+ "%<char **%>", decl);
break;
}
}
@@ -1204,7 +1390,7 @@ check_main_parameter_types (tree decl)
argument because it's only mentioned in an appendix of the
standard. */
if (argct > 0 && (argct < 2 || argct > 3))
- pedwarn ("%q+D takes only zero or two arguments", decl);
+ pedwarn (0, "%q+D takes only zero or two arguments", decl);
}
/* True if pointers to distinct types T1 and T2 can be converted to
@@ -2895,20 +3081,20 @@ pointer_int_sum (enum tree_code resultcode, tree ptrop, tree intop)
if (TREE_CODE (TREE_TYPE (result_type)) == VOID_TYPE)
{
- if (pedantic || warn_pointer_arith)
- pedwarn ("pointer of type %<void *%> used in arithmetic");
+ pedwarn (pedantic ? OPT_pedantic : OPT_Wpointer_arith,
+ "pointer of type %<void *%> used in arithmetic");
size_exp = integer_one_node;
}
else if (TREE_CODE (TREE_TYPE (result_type)) == FUNCTION_TYPE)
{
- if (pedantic || warn_pointer_arith)
- pedwarn ("pointer to a function used in arithmetic");
+ pedwarn (pedantic ? OPT_pedantic : OPT_Wpointer_arith,
+ "pointer to a function used in arithmetic");
size_exp = integer_one_node;
}
else if (TREE_CODE (TREE_TYPE (result_type)) == METHOD_TYPE)
{
- if (pedantic || warn_pointer_arith)
- pedwarn ("pointer to member function used in arithmetic");
+ pedwarn (pedantic ? OPT_pedantic : OPT_Wpointer_arith,
+ "pointer to member function used in arithmetic");
size_exp = integer_one_node;
}
else
@@ -3291,10 +3477,6 @@ c_common_get_alias_set (tree t)
|| t == unsigned_char_type_node)
return 0;
- /* If it has the may_alias attribute, it can alias anything. */
- if (lookup_attribute ("may_alias", TYPE_ATTRIBUTES (t)))
- return 0;
-
/* The C standard specifically allows aliasing between signed and
unsigned variants of the same type. We treat the signed
variant as canonical. */
@@ -3420,7 +3602,8 @@ c_sizeof_or_alignof_type (tree type, bool is_sizeof, int complain)
if (is_sizeof)
{
if (complain && (pedantic || warn_pointer_arith))
- pedwarn ("invalid application of %<sizeof%> to a function type");
+ pedwarn (pedantic ? OPT_pedantic : OPT_Wpointer_arith,
+ "invalid application of %<sizeof%> to a function type");
else if (!complain)
return error_mark_node;
value = size_one_node;
@@ -3432,7 +3615,8 @@ c_sizeof_or_alignof_type (tree type, bool is_sizeof, int complain)
{
if (type_code == VOID_TYPE
&& complain && (pedantic || warn_pointer_arith))
- pedwarn ("invalid application of %qs to a void type", op_name);
+ pedwarn (pedantic ? OPT_pedantic : OPT_Wpointer_arith,
+ "invalid application of %qs to a void type", op_name);
else if (!complain)
return error_mark_node;
value = size_one_node;
@@ -4002,6 +4186,20 @@ c_common_nodes_and_builtins (void)
lang_hooks.decls.pushdecl
(build_decl (TYPE_DECL, get_identifier ("__builtin_va_list"),
va_list_type_node));
+#ifdef TARGET_ENUM_VA_LIST
+ {
+ int l;
+ const char *pname;
+ tree ptype;
+ for (l = 0; TARGET_ENUM_VA_LIST (l, &pname, &ptype); ++l)
+ {
+ lang_hooks.decls.pushdecl
+ (build_decl (TYPE_DECL, get_identifier (pname),
+ ptype));
+
+ }
+ }
+#endif
if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
{
@@ -4284,8 +4482,9 @@ c_add_case_label (splay_tree cases, tree cond, tree orig_type,
}
/* Case ranges are a GNU extension. */
- if (high_value && pedantic)
- pedwarn ("range expressions in switch statements are non-standard");
+ if (high_value)
+ pedwarn (OPT_pedantic,
+ "range expressions in switch statements are non-standard");
type = TREE_TYPE (cond);
if (low_value)
@@ -4598,8 +4797,7 @@ finish_label_address_expr (tree label)
{
tree result;
- if (pedantic)
- pedwarn ("taking the address of a label is non-standard");
+ pedwarn (OPT_pedantic, "taking the address of a label is non-standard");
if (label == error_mark_node)
return error_mark_node;
@@ -4707,6 +4905,8 @@ c_stddef_cpp_builtins(void)
builtin_define_with_value ("__WINT_TYPE__", WINT_TYPE, 0);
builtin_define_with_value ("__INTMAX_TYPE__", INTMAX_TYPE, 0);
builtin_define_with_value ("__UINTMAX_TYPE__", UINTMAX_TYPE, 0);
+ builtin_define_with_value ("__CHAR16_TYPE__", CHAR16_TYPE, 0);
+ builtin_define_with_value ("__CHAR32_TYPE__", CHAR32_TYPE, 0);
}
static void
@@ -4837,7 +5037,7 @@ handle_noreturn_attribute (tree *node, tree name, tree ARG_UNUSED (args),
static tree
handle_hot_attribute (tree *node, tree name, tree ARG_UNUSED (args),
- int ARG_UNUSED (flags), bool *no_add_attrs)
+ int ARG_UNUSED (flags), bool *no_add_attrs)
{
if (TREE_CODE (*node) == FUNCTION_DECL)
{
@@ -4847,8 +5047,34 @@ handle_hot_attribute (tree *node, tree name, tree ARG_UNUSED (args),
name, "cold");
*no_add_attrs = true;
}
- /* Do nothing else, just set the attribute. We'll get at
- it later with lookup_attribute. */
+ else
+ {
+ tree old_opts = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (*node);
+
+ /* If we are not at -O3, but are optimizing, turn on -O3
+ optimizations just for this one function. */
+ if (((optimize > 0 && optimize < 3) || optimize_size)
+ && targetm.target_option.hot_attribute_sets_optimization
+ && (!old_opts || old_opts == optimization_default_node))
+ {
+ /* Create the hot optimization node if needed. */
+ if (!optimization_hot_node)
+ {
+ struct cl_optimization current_options;
+ static const char *os_argv[] = { NULL, "-O3", NULL };
+
+ cl_optimization_save (&current_options);
+ decode_options (2, os_argv);
+ optimization_hot_node = build_optimization_node ();
+ cl_optimization_restore (&current_options);
+ }
+
+ DECL_FUNCTION_SPECIFIC_OPTIMIZATION (*node)
+ = optimization_hot_node;
+ }
+ /* Most of the rest of the hot processing is done later with
+ lookup_attribute. */
+ }
}
else
{
@@ -4873,8 +5099,34 @@ handle_cold_attribute (tree *node, tree name, tree ARG_UNUSED (args),
name, "hot");
*no_add_attrs = true;
}
- /* Do nothing else, just set the attribute. We'll get at
- it later with lookup_attribute. */
+ else
+ {
+ tree old_opts = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (*node);
+
+ /* If we are optimizing, but not optimizing for space, turn on -Os
+ optimizations just for this one function. */
+ if (optimize && !optimize_size
+ && targetm.target_option.cold_attribute_sets_optimization
+ && (!old_opts || old_opts == optimization_default_node))
+ {
+ /* Create the cold optimization node if needed. */
+ if (!optimization_cold_node)
+ {
+ struct cl_optimization current_options;
+ static const char *os_argv[] = { NULL, "-Os", NULL };
+
+ cl_optimization_save (&current_options);
+ decode_options (2, os_argv);
+ optimization_cold_node = build_optimization_node ();
+ cl_optimization_restore (&current_options);
+ }
+
+ DECL_FUNCTION_SPECIFIC_OPTIMIZATION (*node)
+ = optimization_cold_node;
+ }
+ /* Most of the rest of the cold processing is done later with
+ lookup_attribute. */
+ }
}
else
{
@@ -6572,6 +6824,186 @@ handle_type_generic_attribute (tree *node, tree ARG_UNUSED (name),
return NULL_TREE;
}
+
+/* For handling "option" attribute. arguments as in
+ struct attribute_spec.handler. */
+
+static tree
+handle_option_attribute (tree *node, tree name, tree args, int flags,
+ bool *no_add_attrs)
+{
+ /* Ensure we have a function type. */
+ if (TREE_CODE (*node) != FUNCTION_DECL)
+ {
+ warning (OPT_Wattributes, "%qE attribute ignored", name);
+ *no_add_attrs = true;
+ }
+ else if (targetm.target_option.valid_attribute_p
+ == default_target_option_valid_attribute_p)
+ {
+ warning (OPT_Wattributes,
+ "%qE attribute is not supported on this machine",
+ name);
+ *no_add_attrs = true;
+ }
+ else if (! targetm.target_option.valid_attribute_p (*node, name, args,
+ flags))
+ *no_add_attrs = true;
+
+ return NULL_TREE;
+}
+
+/* Arguments being collected for optimization. */
+typedef const char *const_char_p; /* For DEF_VEC_P. */
+DEF_VEC_P(const_char_p);
+DEF_VEC_ALLOC_P(const_char_p, gc);
+static GTY(()) VEC(const_char_p, gc) *optimize_args;
+
+
+/* Inner function to convert a TREE_LIST to argv string to parse the optimize
+ options in ARGS. ATTR_P is true if this is for attribute(optimize), and
+ false for #pragma GCC optimize. */
+
+bool
+parse_optimize_options (tree args, bool attr_p)
+{
+ bool ret = true;
+ unsigned opt_argc;
+ unsigned i;
+ const char **opt_argv;
+ tree ap;
+
+ /* Build up argv vector. Just in case the string is stored away, use garbage
+ collected strings. */
+ VEC_truncate (const_char_p, optimize_args, 0);
+ VEC_safe_push (const_char_p, gc, optimize_args, NULL);
+
+ for (ap = args; ap != NULL_TREE; ap = TREE_CHAIN (ap))
+ {
+ tree value = TREE_VALUE (ap);
+
+ if (TREE_CODE (value) == INTEGER_CST)
+ {
+ char buffer[20];
+ sprintf (buffer, "-O%ld", (long) TREE_INT_CST_LOW (value));
+ VEC_safe_push (const_char_p, gc, optimize_args, ggc_strdup (buffer));
+ }
+
+ else if (TREE_CODE (value) == STRING_CST)
+ {
+ /* Split string into multiple substrings. */
+ size_t len = TREE_STRING_LENGTH (value);
+ char *p = ASTRDUP (TREE_STRING_POINTER (value));
+ char *end = p + len;
+ char *comma;
+ char *next_p = p;
+
+ while (next_p != NULL)
+ {
+ size_t len2;
+ char *q, *r;
+
+ p = next_p;
+ comma = strchr (p, ',');
+ if (comma)
+ {
+ len2 = comma - p;
+ *comma = '\0';
+ next_p = comma+1;
+ }
+ else
+ {
+ len2 = end - p;
+ next_p = NULL;
+ }
+
+ r = q = (char *) ggc_alloc (len2 + 3);
+
+ /* If the user supplied -Oxxx or -fxxx, only allow -Oxxx or -fxxx
+ options. */
+ if (*p == '-' && p[1] != 'O' && p[1] != 'f')
+ {
+ ret = false;
+ if (attr_p)
+ warning (OPT_Wattributes,
+ "Bad option %s to optimize attribute.", p);
+ else
+ warning (OPT_Wpragmas,
+ "Bad option %s to pragma attribute", p);
+ continue;
+ }
+
+ if (*p != '-')
+ {
+ *r++ = '-';
+
+ /* Assume that Ox is -Ox, a numeric value is -Ox, a s by
+ itself is -Os, and any other switch begins with a -f. */
+ if ((*p >= '0' && *p <= '9')
+ || (p[0] == 's' && p[1] == '\0'))
+ *r++ = 'O';
+ else if (*p != 'O')
+ *r++ = 'f';
+ }
+
+ memcpy (r, p, len2);
+ r[len2] = '\0';
+ VEC_safe_push (const_char_p, gc, optimize_args, q);
+ }
+
+ }
+ }
+
+ opt_argc = VEC_length (const_char_p, optimize_args);
+ opt_argv = (const char **) alloca (sizeof (char *) * (opt_argc + 1));
+
+ for (i = 1; i < opt_argc; i++)
+ opt_argv[i] = VEC_index (const_char_p, optimize_args, i);
+
+ /* Now parse the options. */
+ decode_options (opt_argc, opt_argv);
+
+ VEC_truncate (const_char_p, optimize_args, 0);
+ return ret;
+}
+
+/* For handling "optimize" attribute. arguments as in
+ struct attribute_spec.handler. */
+
+static tree
+handle_optimize_attribute (tree *node, tree name, tree args,
+ int ARG_UNUSED (flags), bool *no_add_attrs)
+{
+ /* Ensure we have a function type. */
+ if (TREE_CODE (*node) != FUNCTION_DECL)
+ {
+ warning (OPT_Wattributes, "%qE attribute ignored", name);
+ *no_add_attrs = true;
+ }
+ else
+ {
+ struct cl_optimization cur_opts;
+ tree old_opts = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (*node);
+
+ /* Save current options. */
+ cl_optimization_save (&cur_opts);
+
+ /* If we previously had some optimization options, use them as the
+ default. */
+ if (old_opts)
+ cl_optimization_restore (TREE_OPTIMIZATION (old_opts));
+
+ /* Parse options, and update the vector. */
+ parse_optimize_options (args, true);
+ DECL_FUNCTION_SPECIFIC_OPTIMIZATION (*node)
+ = build_optimization_node ();
+
+ /* Restore current options. */
+ cl_optimization_restore (&cur_opts);
+ }
+
+ return NULL_TREE;
+}
/* Check for valid arguments being passed to a function.
ATTRS is a list of attributes. There are NARGS arguments in the array
@@ -6945,71 +7377,67 @@ c_parse_error (const char *gmsgid, enum cpp_ttype token, tree value)
inlining, so we don't have to worry about that. */
void
-c_warn_unused_result (tree *top_p)
+c_warn_unused_result (gimple_seq seq)
{
- tree t = *top_p;
- tree_stmt_iterator i;
tree fdecl, ftype;
+ gimple_stmt_iterator i;
- switch (TREE_CODE (t))
+ for (i = gsi_start (seq); !gsi_end_p (i); gsi_next (&i))
{
- case STATEMENT_LIST:
- for (i = tsi_start (*top_p); !tsi_end_p (i); tsi_next (&i))
- c_warn_unused_result (tsi_stmt_ptr (i));
- break;
-
- case COND_EXPR:
- c_warn_unused_result (&COND_EXPR_THEN (t));
- c_warn_unused_result (&COND_EXPR_ELSE (t));
- break;
- case BIND_EXPR:
- c_warn_unused_result (&BIND_EXPR_BODY (t));
- break;
- case TRY_FINALLY_EXPR:
- case TRY_CATCH_EXPR:
- c_warn_unused_result (&TREE_OPERAND (t, 0));
- c_warn_unused_result (&TREE_OPERAND (t, 1));
- break;
- case CATCH_EXPR:
- c_warn_unused_result (&CATCH_BODY (t));
- break;
- case EH_FILTER_EXPR:
- c_warn_unused_result (&EH_FILTER_FAILURE (t));
- break;
+ gimple g = gsi_stmt (i);
- case CALL_EXPR:
- if (TREE_USED (t))
- break;
-
- /* This is a naked call, as opposed to a CALL_EXPR nested inside
- a MODIFY_EXPR. All calls whose value is ignored should be
- represented like this. Look for the attribute. */
- fdecl = get_callee_fndecl (t);
- if (fdecl)
- ftype = TREE_TYPE (fdecl);
- else
+ switch (gimple_code (g))
{
- ftype = TREE_TYPE (CALL_EXPR_FN (t));
- /* Look past pointer-to-function to the function type itself. */
- ftype = TREE_TYPE (ftype);
- }
+ case GIMPLE_BIND:
+ c_warn_unused_result (gimple_bind_body (g));
+ break;
+ case GIMPLE_TRY:
+ c_warn_unused_result (gimple_try_eval (g));
+ c_warn_unused_result (gimple_try_cleanup (g));
+ break;
+ case GIMPLE_CATCH:
+ c_warn_unused_result (gimple_catch_handler (g));
+ break;
+ case GIMPLE_EH_FILTER:
+ c_warn_unused_result (gimple_eh_filter_failure (g));
+ break;
- if (lookup_attribute ("warn_unused_result", TYPE_ATTRIBUTES (ftype)))
- {
- if (fdecl)
- warning (0, "%Hignoring return value of %qD, "
- "declared with attribute warn_unused_result",
- EXPR_LOCUS (t), fdecl);
+ case GIMPLE_CALL:
+ if (gimple_call_lhs (g))
+ break;
+
+ /* This is a naked call, as opposed to a GIMPLE_CALL with an
+ LHS. All calls whose value is ignored should be
+ represented like this. Look for the attribute. */
+ fdecl = gimple_call_fn (g);
+ if (TREE_CODE (fdecl) == FUNCTION_DECL)
+ ftype = TREE_TYPE (fdecl);
else
- warning (0, "%Hignoring return value of function "
- "declared with attribute warn_unused_result",
- EXPR_LOCUS (t));
- }
- break;
+ {
+ ftype = TREE_TYPE (fdecl);
+ /* Look past pointer-to-function to the function type itself. */
+ ftype = TREE_TYPE (ftype);
+ }
- default:
- /* Not a container, not a call, or a call whose value is used. */
- break;
+ if (lookup_attribute ("warn_unused_result", TYPE_ATTRIBUTES (ftype)))
+ {
+ location_t loc = gimple_location (g);
+
+ if (fdecl)
+ warning (0, "%Hignoring return value of %qD, "
+ "declared with attribute warn_unused_result",
+ &loc, fdecl);
+ else
+ warning (0, "%Hignoring return value of function "
+ "declared with attribute warn_unused_result",
+ &loc);
+ }
+ break;
+
+ default:
+ /* Not a container, not a call, or a call whose value is used. */
+ break;
+ }
}
}
diff --git a/gcc/c-common.h b/gcc/c-common.h
index 7fd2242c352..1ff5d665532 100644
--- a/gcc/c-common.h
+++ b/gcc/c-common.h
@@ -74,6 +74,10 @@ enum rid
RID_DFLOAT32, RID_DFLOAT64, RID_DFLOAT128,
RID_FRACT, RID_ACCUM,
+ /* This means to warn that this is a C++ keyword, and then treat it
+ as a normal identifier. */
+ RID_CXX_COMPAT_WARN,
+
/* Too many ways of getting the name of a function as a string */
RID_FUNCTION_NAME, RID_PRETTY_FUNCTION_NAME, RID_C99_FUNCTION_NAME,
@@ -184,6 +188,8 @@ enum c_tree_index
CTI_MAX
};
+#define C_CPP_HASHNODE(id) \
+ (&(((struct c_common_identifier *) (id))->node))
#define C_RID_CODE(id) \
((enum rid) (((struct c_common_identifier *) (id))->node.rid_code))
#define C_SET_RID_CODE(id, code) \
@@ -197,6 +203,36 @@ struct c_common_identifier GTY(())
struct cpp_hashnode node;
};
+/* An entry in the reserved keyword table. */
+
+struct c_common_resword
+{
+ const char *const word;
+ ENUM_BITFIELD(rid) const rid : 16;
+ const unsigned int disable : 16;
+};
+
+/* Disable mask. Keywords are disabled if (reswords[i].disable &
+ mask) is _true_. Thus for keywords which are present in all
+ languages the disable field is zero. */
+
+#define D_CONLY 0x001 /* C only (not in C++). */
+#define D_CXXONLY 0x002 /* C++ only (not in C). */
+#define D_C99 0x004 /* In C, C99 only. */
+#define D_CXX0X 0x008 /* In C++, C++0X only. */
+#define D_EXT 0x010 /* GCC extension. */
+#define D_EXT89 0x020 /* GCC extension incorporated in C99. */
+#define D_ASM 0x040 /* Disabled by -fno-asm. */
+#define D_OBJC 0x080 /* In Objective C and neither C nor C++. */
+#define D_CXX_OBJC 0x100 /* In Objective C, and C++, but not C. */
+#define D_CXXWARN 0x200 /* In C warn with -Wcxx-compat. */
+
+/* The reserved keyword table. */
+extern const struct c_common_resword c_common_reswords[];
+
+/* The number of items in the reserved keyword table. */
+extern const unsigned int num_c_common_reswords;
+
#define char16_type_node c_global_trees[CTI_CHAR16_TYPE]
#define char32_type_node c_global_trees[CTI_CHAR32_TYPE]
#define wchar_type_node c_global_trees[CTI_WCHAR_TYPE]
@@ -834,6 +870,7 @@ extern tree c_staticp (tree);
extern void init_c_lex (void);
extern void c_cpp_builtins (cpp_reader *);
+extern void c_cpp_builtins_optimize_pragma (cpp_reader *, tree, tree);
/* Positive if an implicit `extern "C"' scope has just been entered;
negative if such a scope has just been exited. */
@@ -860,7 +897,7 @@ extern void dump_time_statistics (void);
extern bool c_dump_tree (void *, tree);
-extern void c_warn_unused_result (tree *);
+extern void c_warn_unused_result (gimple_seq);
extern void verify_sequence_points (tree);
@@ -889,10 +926,9 @@ extern void warn_about_parentheses (enum tree_code, enum tree_code,
extern void warn_for_unused_label (tree label);
extern void warn_for_div_by_zero (tree divisor);
-
/* In c-gimplify.c */
extern void c_genericize (tree);
-extern int c_gimplify_expr (tree *, tree *, tree *);
+extern int c_gimplify_expr (tree *, gimple_seq *, gimple_seq *);
extern tree c_build_bind_expr (tree, tree);
/* In c-pch.c */
@@ -908,6 +944,8 @@ extern void c_common_print_pch_checksum (FILE *f);
/* In *-checksum.c */
extern const unsigned char executable_checksum[16];
+/* In c-cppbuiltin.c */
+extern void builtin_define_std (const char *macro);
extern void builtin_define_with_value (const char *, const char *, int);
extern void c_stddef_cpp_builtins (void);
extern void fe_file_change (const struct line_map *);
diff --git a/gcc/c-cppbuiltin.c b/gcc/c-cppbuiltin.c
index 82bd5c27313..57d00580d24 100644
--- a/gcc/c-cppbuiltin.c
+++ b/gcc/c-cppbuiltin.c
@@ -405,6 +405,58 @@ builtin_define_stdint_macros (void)
builtin_define_type_max ("__INTMAX_MAX__", intmax_type_node, intmax_long);
}
+/* Adjust the optimization macros when a #pragma GCC optimization is done to
+ reflect the current level. */
+void
+c_cpp_builtins_optimize_pragma (cpp_reader *pfile, tree prev_tree,
+ tree cur_tree)
+{
+ struct cl_optimization *prev = TREE_OPTIMIZATION (prev_tree);
+ struct cl_optimization *cur = TREE_OPTIMIZATION (cur_tree);
+ bool prev_fast_math;
+ bool cur_fast_math;
+
+ /* -undef turns off target-specific built-ins. */
+ if (flag_undef)
+ return;
+
+ /* Other target-independent built-ins determined by command-line
+ options. */
+ if (!prev->optimize_size && cur->optimize_size)
+ cpp_define (pfile, "__OPTIMIZE_SIZE__");
+ else if (prev->optimize_size && !cur->optimize_size)
+ cpp_undef (pfile, "__OPTIMIZE_SIZE__");
+
+ if (!prev->optimize && cur->optimize)
+ cpp_define (pfile, "__OPTIMIZE__");
+ else if (prev->optimize && !cur->optimize)
+ cpp_undef (pfile, "__OPTIMIZE__");
+
+ prev_fast_math = fast_math_flags_struct_set_p (prev);
+ cur_fast_math = fast_math_flags_struct_set_p (cur);
+ if (!prev_fast_math && cur_fast_math)
+ cpp_define (pfile, "__FAST_MATH__");
+ else if (prev_fast_math && !cur_fast_math)
+ cpp_undef (pfile, "__FAST_MATH__");
+
+ if (!prev->flag_signaling_nans && cur->flag_signaling_nans)
+ cpp_define (pfile, "__SUPPORT_SNAN__");
+ else if (prev->flag_signaling_nans && !cur->flag_signaling_nans)
+ cpp_undef (pfile, "__SUPPORT_SNAN__");
+
+ if (!prev->flag_finite_math_only && cur->flag_finite_math_only)
+ {
+ cpp_undef (pfile, "__FINITE_MATH_ONLY__");
+ cpp_define (pfile, "__FINITE_MATH_ONLY__=1");
+ }
+ else if (!prev->flag_finite_math_only && cur->flag_finite_math_only)
+ {
+ cpp_undef (pfile, "__FINITE_MATH_ONLY__");
+ cpp_define (pfile, "__FINITE_MATH_ONLY__=0");
+ }
+}
+
+
/* Hook that registers front end and target-specific built-ins. */
void
c_cpp_builtins (cpp_reader *pfile)
diff --git a/gcc/c-decl.c b/gcc/c-decl.c
index 18ad11901f9..bdb68199351 100644
--- a/gcc/c-decl.c
+++ b/gcc/c-decl.c
@@ -52,7 +52,8 @@ along with GCC; see the file COPYING3. If not see
#include "c-pragma.h"
#include "langhooks.h"
#include "tree-mudflap.h"
-#include "tree-gimple.h"
+#include "gimple.h"
+#include "tree-iterator.h"
#include "diagnostic.h"
#include "tree-dump.h"
#include "cgraph.h"
@@ -61,6 +62,7 @@ along with GCC; see the file COPYING3. If not see
#include "except.h"
#include "langhooks-def.h"
#include "pointer-set.h"
+#include "gimple.h"
/* In grokdeclarator, distinguish syntactic contexts of declarators. */
enum decl_context
@@ -248,7 +250,7 @@ extern char C_SIZEOF_STRUCT_LANG_IDENTIFIER_isnt_accurate
union lang_tree_node
GTY((desc ("TREE_CODE (&%h.generic) == IDENTIFIER_NODE"),
- chain_next ("TREE_CODE (&%h.generic) == INTEGER_TYPE ? (union lang_tree_node *) TYPE_NEXT_VARIANT (&%h.generic) : ((union lang_tree_node *) GENERIC_NEXT (&%h.generic))")))
+ chain_next ("TREE_CODE (&%h.generic) == INTEGER_TYPE ? (union lang_tree_node *) TYPE_NEXT_VARIANT (&%h.generic) : ((union lang_tree_node *) TREE_CHAIN (&%h.generic))")))
{
union tree_node GTY ((tag ("0"),
desc ("tree_node_structure (&%h)")))
@@ -445,7 +447,7 @@ c_print_identifier (FILE *file, tree node, int indent)
print_node (file, "symbol", I_SYMBOL_DECL (node), indent + 4);
print_node (file, "tag", I_TAG_DECL (node), indent + 4);
print_node (file, "label", I_LABEL_DECL (node), indent + 4);
- if (C_IS_RESERVED_WORD (node))
+ if (C_IS_RESERVED_WORD (node) && C_RID_CODE (node) != RID_CXX_COMPAT_WARN)
{
tree rid = ridpointers[C_RID_CODE (node)];
indent_to (file, indent + 4);
@@ -786,7 +788,7 @@ pop_scope (void)
&& TREE_PUBLIC (p)
&& !DECL_INITIAL (p)
&& !flag_gnu89_inline)
- pedwarn ("inline function %q+D declared but never defined", p);
+ pedwarn (0, "inline function %q+D declared but never defined", p);
goto common_symbol;
@@ -1223,7 +1225,7 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
&& TYPE_MAIN_VARIANT (TREE_TYPE (newtype)) == integer_type_node
&& C_FUNCTION_IMPLICIT_INT (newdecl) && !DECL_INITIAL (olddecl))
{
- pedwarn ("conflicting types for %q+D", newdecl);
+ pedwarn (0, "conflicting types for %q+D", newdecl);
/* Make sure we keep void as the return type. */
TREE_TYPE (newdecl) = *newtypep = newtype = oldtype;
C_FUNCTION_IMPLICIT_INT (newdecl) = 0;
@@ -1236,7 +1238,7 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
&& TYPE_MAIN_VARIANT (TREE_TYPE (oldtype)) == integer_type_node
&& C_DECL_IMPLICIT (olddecl) && !DECL_INITIAL (olddecl))
{
- pedwarn ("conflicting types for %q+D", newdecl);
+ pedwarn (0, "conflicting types for %q+D", newdecl);
/* Make sure we keep void as the return type. */
TREE_TYPE (olddecl) = *oldtypep = oldtype = newtype;
pedwarned = true;
@@ -1258,7 +1260,10 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
header. (Conflicting redeclarations were handled above.) */
if (TREE_CODE (newdecl) == TYPE_DECL)
{
- if (DECL_IN_SYSTEM_HEADER (newdecl) || DECL_IN_SYSTEM_HEADER (olddecl))
+ if (DECL_IN_SYSTEM_HEADER (newdecl)
+ || DECL_IN_SYSTEM_HEADER (olddecl)
+ || TREE_NO_WARNING (newdecl)
+ || TREE_NO_WARNING (olddecl))
return true; /* Allow OLDDECL to continue in use. */
error ("redefinition of typedef %q+D", newdecl);
@@ -1512,30 +1517,6 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
"noinline follows inline declaration ", newdecl);
warned = true;
}
-
- /* Inline declaration after use or definition.
- ??? Should we still warn about this now we have unit-at-a-time
- mode and can get it right?
- Definitely don't complain if the decls are in different translation
- units.
- C99 permits this, so don't warn in that case. (The function
- may not be inlined everywhere in function-at-a-time mode, but
- we still shouldn't warn.) */
- if (DECL_DECLARED_INLINE_P (newdecl) && !DECL_DECLARED_INLINE_P (olddecl)
- && same_translation_unit_p (olddecl, newdecl)
- && flag_gnu89_inline)
- {
- if (TREE_USED (olddecl))
- {
- warning (0, "%q+D declared inline after being called", olddecl);
- warned = true;
- }
- else if (DECL_INITIAL (olddecl))
- {
- warning (0, "%q+D declared inline after its definition", olddecl);
- warned = true;
- }
- }
}
else /* PARM_DECL, VAR_DECL */
{
@@ -1585,7 +1566,7 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
/* Report location of previous decl/defn in a consistent manner. */
if (warned || pedwarned)
- locate_old_decl (olddecl, pedwarned ? pedwarn : warning0);
+ locate_old_decl (olddecl, pedwarned ? pedwarn0 : warning0);
#undef DECL_EXTERN_INLINE
@@ -1676,12 +1657,21 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype)
if (TREE_DEPRECATED (newdecl))
TREE_DEPRECATED (olddecl) = 1;
- /* Keep source location of definition rather than declaration and of
- prototype rather than non-prototype unless that prototype is
- built-in. */
- if ((DECL_INITIAL (newdecl) == 0 && DECL_INITIAL (olddecl) != 0)
- || (old_is_prototype && !new_is_prototype
- && !C_DECL_BUILTIN_PROTOTYPE (olddecl)))
+ /* If a decl is in a system header and the other isn't, keep the one on the
+ system header. Otherwise, keep source location of definition rather than
+ declaration and of prototype rather than non-prototype unless that
+ prototype is built-in. */
+ if (CODE_CONTAINS_STRUCT (TREE_CODE (olddecl), TS_DECL_WITH_VIS)
+ && DECL_IN_SYSTEM_HEADER (olddecl)
+ && !DECL_IN_SYSTEM_HEADER (newdecl) )
+ DECL_SOURCE_LOCATION (newdecl) = DECL_SOURCE_LOCATION (olddecl);
+ else if (CODE_CONTAINS_STRUCT (TREE_CODE (olddecl), TS_DECL_WITH_VIS)
+ && DECL_IN_SYSTEM_HEADER (newdecl)
+ && !DECL_IN_SYSTEM_HEADER (olddecl))
+ DECL_SOURCE_LOCATION (olddecl) = DECL_SOURCE_LOCATION (newdecl);
+ else if ((DECL_INITIAL (newdecl) == 0 && DECL_INITIAL (olddecl) != 0)
+ || (old_is_prototype && !new_is_prototype
+ && !C_DECL_BUILTIN_PROTOTYPE (olddecl)))
DECL_SOURCE_LOCATION (newdecl) = DECL_SOURCE_LOCATION (olddecl);
/* Merge the initialization information. */
@@ -1697,12 +1687,6 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype)
if (CODE_CONTAINS_STRUCT (TREE_CODE (olddecl), TS_DECL_WITH_VIS))
{
- /* Merge the unused-warning information. */
- if (DECL_IN_SYSTEM_HEADER (olddecl))
- DECL_IN_SYSTEM_HEADER (newdecl) = 1;
- else if (DECL_IN_SYSTEM_HEADER (newdecl))
- DECL_IN_SYSTEM_HEADER (olddecl) = 1;
-
/* Merge the section attribute.
We want to issue an error if the sections conflict but that
must be done later in decl_attributes since we are called
@@ -1795,9 +1779,9 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype)
if (new_is_definition && DECL_INITIAL (olddecl))
{
if (TREE_USED (olddecl)
- /* In unit-at-a-time mode we never inline re-defined extern
- inline functions. */
- && !flag_unit_at_a_time
+ /* We never inline re-defined extern inline functions.
+ FIXME: This would be better handled by keeping both functions
+ as separate declarations. */
&& cgraph_function_possibly_inlined_p (olddecl))
(*debug_hooks->outlining_inline_function) (olddecl);
@@ -1836,6 +1820,17 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype)
= C_DECL_BUILTIN_PROTOTYPE (olddecl);
}
+ /* Preserve function specific target and optimization options */
+ if (DECL_FUNCTION_SPECIFIC_TARGET (olddecl)
+ && !DECL_FUNCTION_SPECIFIC_TARGET (newdecl))
+ DECL_FUNCTION_SPECIFIC_TARGET (newdecl)
+ = DECL_FUNCTION_SPECIFIC_TARGET (olddecl);
+
+ if (DECL_FUNCTION_SPECIFIC_OPTIMIZATION (olddecl)
+ && !DECL_FUNCTION_SPECIFIC_OPTIMIZATION (newdecl))
+ DECL_FUNCTION_SPECIFIC_OPTIMIZATION (newdecl)
+ = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (olddecl);
+
/* Also preserve various other info from the definition. */
if (!new_is_definition)
{
@@ -1843,6 +1838,7 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype)
DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl);
DECL_STRUCT_FUNCTION (newdecl) = DECL_STRUCT_FUNCTION (olddecl);
DECL_SAVED_TREE (newdecl) = DECL_SAVED_TREE (olddecl);
+ gimple_set_body (newdecl, gimple_body (olddecl));
DECL_ARGUMENTS (newdecl) = DECL_ARGUMENTS (olddecl);
/* Set DECL_INLINE on the declaration if we've got a body
@@ -1877,6 +1873,10 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype)
sizeof (struct tree_decl_common) - sizeof (struct tree_common));
switch (TREE_CODE (olddecl))
{
+ case FUNCTION_DECL:
+ gimple_set_body (olddecl, gimple_body (newdecl));
+ /* fall through */
+
case FIELD_DECL:
case VAR_DECL:
case PARM_DECL:
@@ -1884,7 +1884,6 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype)
case RESULT_DECL:
case CONST_DECL:
case TYPE_DECL:
- case FUNCTION_DECL:
memcpy ((char *) olddecl + sizeof (struct tree_decl_common),
(char *) newdecl + sizeof (struct tree_decl_common),
tree_code_size (TREE_CODE (olddecl)) - sizeof (struct tree_decl_common));
@@ -2339,7 +2338,8 @@ implicit_decl_warning (tree id, tree olddecl)
if (warn_implicit_function_declaration)
{
if (flag_isoc99)
- pedwarn (G_("implicit declaration of function %qE"), id);
+ pedwarn (OPT_Wimplicit_function_declaration,
+ G_("implicit declaration of function %qE"), id);
else
warning (OPT_Wimplicit_function_declaration,
G_("implicit declaration of function %qE"), id);
@@ -2891,7 +2891,7 @@ shadow_tag_warned (const struct c_declspecs *declspecs, int warned)
if (warned != 1 && code != ENUMERAL_TYPE)
/* Empty unnamed enum OK */
{
- pedwarn ("unnamed struct/union that defines no instances");
+ pedwarn (0, "unnamed struct/union that defines no instances");
warned = 1;
}
}
@@ -2899,8 +2899,8 @@ shadow_tag_warned (const struct c_declspecs *declspecs, int warned)
&& declspecs->storage_class != csc_none)
{
if (warned != 1)
- pedwarn ("empty declaration with storage class specifier "
- "does not redeclare tag");
+ pedwarn (0, "empty declaration with storage class specifier "
+ "does not redeclare tag");
warned = 1;
pending_xref_error ();
}
@@ -2910,8 +2910,8 @@ shadow_tag_warned (const struct c_declspecs *declspecs, int warned)
|| declspecs->restrict_p))
{
if (warned != 1)
- pedwarn ("empty declaration with type qualifier "
- "does not redeclare tag");
+ pedwarn (0, "empty declaration with type qualifier "
+ "does not redeclare tag");
warned = 1;
pending_xref_error ();
}
@@ -2931,14 +2931,14 @@ shadow_tag_warned (const struct c_declspecs *declspecs, int warned)
{
if (warned != 1 && !in_system_header)
{
- pedwarn ("useless type name in empty declaration");
+ pedwarn (0, "useless type name in empty declaration");
warned = 1;
}
}
}
else if (warned != 1 && !in_system_header && declspecs->typedef_p)
{
- pedwarn ("useless type name in empty declaration");
+ pedwarn (0, "useless type name in empty declaration");
warned = 1;
}
@@ -2985,7 +2985,7 @@ shadow_tag_warned (const struct c_declspecs *declspecs, int warned)
if (warned != 1)
{
if (!found_tag)
- pedwarn ("empty declaration");
+ pedwarn (0, "empty declaration");
}
}
@@ -3048,13 +3048,13 @@ build_array_declarator (tree expr, struct c_declspecs *quals, bool static_p,
}
declarator->u.array.static_p = static_p;
declarator->u.array.vla_unspec_p = vla_unspec_p;
- if (pedantic && !flag_isoc99)
+ if (!flag_isoc99)
{
if (static_p || quals != NULL)
- pedwarn ("ISO C90 does not support %<static%> or type "
+ pedwarn (OPT_pedantic, "ISO C90 does not support %<static%> or type "
"qualifiers in parameter array declarators");
if (vla_unspec_p)
- pedwarn ("ISO C90 does not support %<[*]%> array declarators");
+ pedwarn (OPT_pedantic, "ISO C90 does not support %<[*]%> array declarators");
}
if (vla_unspec_p)
{
@@ -3310,8 +3310,8 @@ start_decl (struct c_declarator *declarator, struct c_declspecs *declspecs,
&& !TREE_READONLY (decl)
&& DECL_DECLARED_INLINE_P (current_function_decl)
&& DECL_EXTERNAL (current_function_decl))
- pedwarn ("%q+D is static but declared in inline function %qD "
- "which is not static", decl, current_function_decl);
+ pedwarn (0, "%q+D is static but declared in inline function %qD "
+ "which is not static", decl, current_function_decl);
/* Add this decl to the current scope.
TEM may equal DECL or it may be a previous decl of the same name. */
@@ -3600,10 +3600,6 @@ finish_decl (tree decl, tree init, tree asmspec_tree)
}
}
- /* If this was marked 'used', be sure it will be output. */
- if (!flag_unit_at_a_time && lookup_attribute ("used", DECL_ATTRIBUTES (decl)))
- mark_decl_referenced (decl);
-
if (TREE_CODE (decl) == TYPE_DECL)
{
if (!DECL_FILE_SCOPE_P (decl)
@@ -3688,7 +3684,7 @@ mark_forward_parm_decls (void)
if (pedantic && !current_scope->warned_forward_parm_decls)
{
- pedwarn ("ISO C forbids forward parameter declarations");
+ pedwarn (OPT_pedantic, "ISO C forbids forward parameter declarations");
current_scope->warned_forward_parm_decls = true;
}
@@ -3835,12 +3831,11 @@ check_bitfield_type_and_width (tree *type, tree *width, const char *orig_name)
}
type_mv = TYPE_MAIN_VARIANT (*type);
- if (pedantic
- && !in_system_header
+ if (!in_system_header
&& type_mv != integer_type_node
&& type_mv != unsigned_type_node
&& type_mv != boolean_type_node)
- pedwarn ("type of bit-field %qs is a GCC extension", name);
+ pedwarn (OPT_pedantic, "type of bit-field %qs is a GCC extension", name);
max_width = TYPE_PRECISION (*type);
@@ -3870,28 +3865,27 @@ check_bitfield_type_and_width (tree *type, tree *width, const char *orig_name)
static void
warn_variable_length_array (const char *name, tree size)
{
- int ped = !flag_isoc99 && pedantic && warn_vla != 0;
int const_size = TREE_CONSTANT (size);
- if (ped)
+ if (!flag_isoc99 && pedantic && warn_vla != 0)
{
if (const_size)
{
if (name)
- pedwarn ("ISO C90 forbids array %qs whose size "
+ pedwarn (OPT_Wvla, "ISO C90 forbids array %qs whose size "
"can%'t be evaluated",
name);
else
- pedwarn ("ISO C90 forbids array whose size "
+ pedwarn (OPT_Wvla, "ISO C90 forbids array whose size "
"can%'t be evaluated");
}
else
{
if (name)
- pedwarn ("ISO C90 forbids variable length array %qs",
+ pedwarn (OPT_Wvla, "ISO C90 forbids variable length array %qs",
name);
else
- pedwarn ("ISO C90 forbids variable length array");
+ pedwarn (OPT_Wvla, "ISO C90 forbids variable length array");
}
}
else if (warn_vla > 0)
@@ -4052,8 +4046,9 @@ grokdeclarator (const struct c_declarator *declarator,
if ((warn_implicit_int || warn_return_type || flag_isoc99)
&& funcdef_flag)
warn_about_return_type = 1;
- else if (warn_implicit_int || flag_isoc99)
- pedwarn_c99 ("type defaults to %<int%> in declaration of %qs", name);
+ else
+ pedwarn_c99 (flag_isoc99 ? 0 : OPT_Wimplicit_int,
+ "type defaults to %<int%> in declaration of %qs", name);
}
/* Adjust the type if a bit-field is being declared,
@@ -4061,7 +4056,7 @@ grokdeclarator (const struct c_declarator *declarator,
"signed". */
if (bitfield && !flag_signed_bitfields && !declspecs->explicit_signed_p
&& TREE_CODE (type) == INTEGER_TYPE)
- type = c_common_unsigned_type (type);
+ type = unsigned_type_for (type);
/* Figure out the type qualifiers for the declaration. There are
two ways a declaration can become qualified. One is something
@@ -4081,11 +4076,11 @@ grokdeclarator (const struct c_declarator *declarator,
if (pedantic && !flag_isoc99)
{
if (constp > 1)
- pedwarn ("duplicate %<const%>");
+ pedwarn (OPT_pedantic, "duplicate %<const%>");
if (restrictp > 1)
- pedwarn ("duplicate %<restrict%>");
+ pedwarn (OPT_pedantic, "duplicate %<restrict%>");
if (volatilep > 1)
- pedwarn ("duplicate %<volatile%>");
+ pedwarn (OPT_pedantic, "duplicate %<volatile%>");
}
if (!flag_gen_aux_info && (TYPE_QUALS (element_type)))
type = TYPE_MAIN_VARIANT (type);
@@ -4102,9 +4097,9 @@ grokdeclarator (const struct c_declarator *declarator,
|| storage_class == csc_register
|| storage_class == csc_typedef))
{
- if (storage_class == csc_auto
- && (pedantic || current_scope == file_scope))
- pedwarn ("function definition declared %<auto%>");
+ if (storage_class == csc_auto)
+ pedwarn ((current_scope == file_scope) ? 0 : OPT_pedantic,
+ "function definition declared %<auto%>");
if (storage_class == csc_register)
error ("function definition declared %<register%>");
if (storage_class == csc_typedef)
@@ -4160,7 +4155,7 @@ grokdeclarator (const struct c_declarator *declarator,
if (storage_class == csc_auto)
error ("file-scope declaration of %qs specifies %<auto%>", name);
if (pedantic && storage_class == csc_register)
- pedwarn ("file-scope declaration of %qs specifies %<register%>", name);
+ pedwarn (OPT_pedantic, "file-scope declaration of %qs specifies %<register%>", name);
}
else
{
@@ -4273,7 +4268,7 @@ grokdeclarator (const struct c_declarator *declarator,
}
if (pedantic && !in_system_header && flexible_array_type_p (type))
- pedwarn ("invalid use of structure with flexible array member");
+ pedwarn (OPT_pedantic, "invalid use of structure with flexible array member");
if (size == error_mark_node)
type = error_mark_node;
@@ -4298,7 +4293,7 @@ grokdeclarator (const struct c_declarator *declarator,
}
if (pedantic && integer_zerop (size))
- pedwarn ("ISO C forbids zero-size array %qs", name);
+ pedwarn (OPT_pedantic, "ISO C forbids zero-size array %qs", name);
if (TREE_CODE (size) == INTEGER_CST)
{
@@ -4370,7 +4365,7 @@ grokdeclarator (const struct c_declarator *declarator,
else if (decl_context == FIELD)
{
if (pedantic && !flag_isoc99 && !in_system_header)
- pedwarn ("ISO C90 does not support flexible array members");
+ pedwarn (OPT_pedantic, "ISO C90 does not support flexible array members");
/* ISO C99 Flexible array members are effectively
identical to GCC's zero-length array extension. */
@@ -4515,7 +4510,7 @@ grokdeclarator (const struct c_declarator *declarator,
function definitions in ISO C; GCC used to used
them for noreturn functions. */
if (VOID_TYPE_P (type) && really_funcdef)
- pedwarn ("function definition has qualified void return type");
+ pedwarn (0, "function definition has qualified void return type");
else
warning (OPT_Wignored_qualifiers,
"type qualifiers ignored on function return type");
@@ -4547,7 +4542,7 @@ grokdeclarator (const struct c_declarator *declarator,
if (pedantic && TREE_CODE (type) == FUNCTION_TYPE
&& type_quals)
- pedwarn ("ISO C forbids qualified function types");
+ pedwarn (OPT_pedantic, "ISO C forbids qualified function types");
if (type_quals)
type = c_build_qualified_type (type, type_quals);
size_varies = 0;
@@ -4628,7 +4623,7 @@ grokdeclarator (const struct c_declarator *declarator,
tree decl;
if (pedantic && TREE_CODE (type) == FUNCTION_TYPE
&& type_quals)
- pedwarn ("ISO C forbids qualified function types");
+ pedwarn (OPT_pedantic, "ISO C forbids qualified function types");
if (type_quals)
type = c_build_qualified_type (type, type_quals);
decl = build_decl (TYPE_DECL, declarator->u.id, type);
@@ -4636,7 +4631,7 @@ grokdeclarator (const struct c_declarator *declarator,
if (declspecs->explicit_signed_p)
C_TYPEDEF_EXPLICITLY_SIGNED (decl) = 1;
if (declspecs->inline_p)
- pedwarn ("typedef %q+D declared %<inline%>", decl);
+ pedwarn (0, "typedef %q+D declared %<inline%>", decl);
return decl;
}
@@ -4651,7 +4646,7 @@ grokdeclarator (const struct c_declarator *declarator,
&& !declspecs->inline_p);
if (pedantic && TREE_CODE (type) == FUNCTION_TYPE
&& type_quals)
- pedwarn ("ISO C forbids const or volatile function types");
+ pedwarn (OPT_pedantic, "ISO C forbids const or volatile function types");
if (type_quals)
type = c_build_qualified_type (type, type_quals);
return type;
@@ -4661,7 +4656,8 @@ grokdeclarator (const struct c_declarator *declarator,
&& variably_modified_type_p (type, NULL_TREE))
{
/* C99 6.7.2.1p8 */
- pedwarn ("a member of a structure or union cannot have a variably modified type");
+ pedwarn (OPT_pedantic,
+ "a member of a structure or union cannot have a variably modified type");
}
/* Aside from typedefs and type names (handle above),
@@ -4714,8 +4710,8 @@ grokdeclarator (const struct c_declarator *declarator,
}
else if (TREE_CODE (type) == FUNCTION_TYPE)
{
- if (pedantic && type_quals)
- pedwarn ("ISO C forbids qualified function types");
+ if (type_quals)
+ pedwarn (OPT_pedantic, "ISO C forbids qualified function types");
if (type_quals)
type = c_build_qualified_type (type, type_quals);
type = build_pointer_type (type);
@@ -4741,7 +4737,7 @@ grokdeclarator (const struct c_declarator *declarator,
DECL_ARG_TYPE (decl) = promoted_type;
if (declspecs->inline_p)
- pedwarn ("parameter %q+D declared %<inline%>", decl);
+ pedwarn (0, "parameter %q+D declared %<inline%>", decl);
}
else if (decl_context == FIELD)
{
@@ -4787,10 +4783,7 @@ grokdeclarator (const struct c_declarator *declarator,
GCC allows 'auto', perhaps with 'inline', to support
nested functions. */
if (storage_class == csc_auto)
- {
- if (pedantic)
- pedwarn ("invalid storage class for function %qs", name);
- }
+ pedwarn (OPT_pedantic, "invalid storage class for function %qs", name);
else if (storage_class == csc_static)
{
error ("invalid storage class for function %qs", name);
@@ -4806,7 +4799,8 @@ grokdeclarator (const struct c_declarator *declarator,
decl = build_decl_attribute_variant (decl, decl_attr);
if (pedantic && type_quals && !DECL_IN_SYSTEM_HEADER (decl))
- pedwarn ("ISO C forbids qualified function types");
+ pedwarn (OPT_pedantic,
+ "ISO C forbids qualified function types");
/* GNU C interprets a volatile-qualified function type to indicate
that the function does not return. */
@@ -4848,7 +4842,7 @@ grokdeclarator (const struct c_declarator *declarator,
if (flag_hosted && MAIN_NAME_P (declarator->u.id))
{
if (declspecs->inline_p)
- pedwarn ("cannot inline function %<main%>");
+ pedwarn (0, "cannot inline function %<main%>");
}
else if (declspecs->inline_p)
{
@@ -4862,10 +4856,7 @@ grokdeclarator (const struct c_declarator *declarator,
if (initialized)
DECL_INLINE (decl) = 1;
}
- /* If -finline-functions, assume it can be inlined. This does
- two things: let the function be deferred until it is actually
- needed, and let dwarf2 know that the function is inlinable. */
- else if (flag_inline_trees == 2 && initialized)
+ else if (initialized)
DECL_INLINE (decl) = 1;
}
else
@@ -4901,7 +4892,7 @@ grokdeclarator (const struct c_declarator *declarator,
C_DECL_VARIABLE_SIZE (decl) = 1;
if (declspecs->inline_p)
- pedwarn ("variable %q+D declared %<inline%>", decl);
+ pedwarn (0, "variable %q+D declared %<inline%>", decl);
/* At file scope, an initialized extern declaration may follow
a static declaration. In that case, DECL_EXTERNAL will be
@@ -5009,7 +5000,7 @@ grokparms (struct c_arg_info *arg_info, bool funcdef_flag)
else if (arg_types && TREE_CODE (TREE_VALUE (arg_types)) == IDENTIFIER_NODE)
{
if (!funcdef_flag)
- pedwarn ("parameter names (without types) in function declaration");
+ pedwarn (0, "parameter names (without types) in function declaration");
arg_info->parms = arg_info->types;
arg_info->types = 0;
@@ -5423,11 +5414,10 @@ grokfield (struct c_declarator *declarator, struct c_declspecs *declspecs,
}
if (!ok)
{
- pedwarn ("declaration does not declare anything");
+ pedwarn (0, "declaration does not declare anything");
return NULL_TREE;
}
- if (pedantic)
- pedwarn ("ISO C doesn%'t support unnamed structs/unions");
+ pedwarn (OPT_pedantic, "ISO C doesn%'t support unnamed structs/unions");
}
value = grokdeclarator (declarator, declspecs, FIELD, false,
@@ -5526,16 +5516,16 @@ finish_struct (tree t, tree fieldlist, tree attributes)
if (TREE_CODE (t) == UNION_TYPE)
{
if (fieldlist)
- pedwarn ("union has no named members");
+ pedwarn (OPT_pedantic, "union has no named members");
else
- pedwarn ("union has no members");
+ pedwarn (OPT_pedantic, "union has no members");
}
else
{
if (fieldlist)
- pedwarn ("struct has no named members");
+ pedwarn (OPT_pedantic, "struct has no named members");
else
- pedwarn ("struct has no members");
+ pedwarn (OPT_pedantic, "struct has no members");
}
}
}
@@ -5614,7 +5604,8 @@ finish_struct (tree t, tree fieldlist, tree attributes)
if (pedantic && !in_system_header && TREE_CODE (t) == RECORD_TYPE
&& flexible_array_type_p (TREE_TYPE (x)))
- pedwarn ("%Jinvalid use of structure with flexible array member", x);
+ pedwarn (OPT_pedantic,
+ "%Jinvalid use of structure with flexible array member", x);
if (DECL_NAME (x))
saw_named_field = 1;
@@ -5999,7 +5990,7 @@ build_enumerator (struct c_enum_contents *the_enum, tree name, tree value)
if (pedantic && !int_fits_type_p (value, integer_type_node))
{
- pedwarn ("ISO C restricts enumerator values to range of %<int%>");
+ pedwarn (OPT_pedantic, "ISO C restricts enumerator values to range of %<int%>");
/* XXX This causes -pedantic to change the meaning of the program.
Remove? -zw 2004-03-15 */
value = convert (integer_type_node, value);
@@ -6115,7 +6106,9 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator,
}
if (warn_about_return_type)
- pedwarn_c99 ("return type defaults to %<int%>");
+ pedwarn_c99 (flag_isoc99 ? 0
+ : (warn_return_type ? OPT_Wreturn_type : OPT_Wimplicit_int),
+ "return type defaults to %<int%>");
/* Make the init_value nonzero so pushdecl knows this is not tentative.
error_mark_node is replaced below (in pop_scope) with the BLOCK. */
@@ -6236,12 +6229,12 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator,
{
if (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (decl1)))
!= integer_type_node)
- pedwarn ("return type of %q+D is not %<int%>", decl1);
+ pedwarn (OPT_Wmain, "return type of %q+D is not %<int%>", decl1);
check_main_parameter_types(decl1);
if (!TREE_PUBLIC (decl1))
- pedwarn ("%q+D is normally a non-static function", decl1);
+ pedwarn (OPT_Wmain, "%q+D is normally a non-static function", decl1);
}
/* Record the decl so that the function name is defined.
@@ -6389,7 +6382,7 @@ store_parm_decls_oldstyle (tree fndecl, const struct c_arg_info *arg_info)
warn_if_shadowing (decl);
if (flag_isoc99)
- pedwarn ("type of %q+D defaults to %<int%>", decl);
+ pedwarn (0, "type of %q+D defaults to %<int%>", decl);
else
warning (OPT_Wmissing_parameter_type, "type of %q+D defaults to %<int%>", decl);
}
@@ -6500,22 +6493,19 @@ store_parm_decls_oldstyle (tree fndecl, const struct c_arg_info *arg_info)
< TYPE_PRECISION (integer_type_node))
DECL_ARG_TYPE (parm) = integer_type_node;
- if (pedantic)
+ /* ??? Is it possible to get here with a
+ built-in prototype or will it always have
+ been diagnosed as conflicting with an
+ old-style definition and discarded? */
+ if (current_function_prototype_built_in)
+ warning (OPT_pedantic, "promoted argument %qD "
+ "doesn%'t match built-in prototype", parm);
+ else
{
- /* ??? Is it possible to get here with a
- built-in prototype or will it always have
- been diagnosed as conflicting with an
- old-style definition and discarded? */
- if (current_function_prototype_built_in)
- warning (0, "promoted argument %qD "
- "doesn%'t match built-in prototype", parm);
- else
- {
- pedwarn ("promoted argument %qD "
- "doesn%'t match prototype", parm);
- pedwarn ("%Hprototype declaration",
- &current_function_prototype_locus);
- }
+ pedwarn (OPT_pedantic, "promoted argument %qD "
+ "doesn%'t match prototype", parm);
+ pedwarn (OPT_pedantic, "%Hprototype declaration",
+ &current_function_prototype_locus);
}
}
else
@@ -6650,9 +6640,10 @@ static void
c_gimple_diagnostics_recursively (tree fndecl)
{
struct cgraph_node *cgn;
+ gimple_seq body = gimple_body (fndecl);
/* Handle attribute((warn_unused_result)). Relies on gimple input. */
- c_warn_unused_result (&DECL_SAVED_TREE (fndecl));
+ c_warn_unused_result (body);
/* Notice when OpenMP structured block constraints are violated. */
if (flag_openmp)
@@ -6707,7 +6698,7 @@ finish_function (void)
/* If warn_main is 1 (-Wmain) or 2 (-Wall), we have already warned.
If warn_main is -1 (-Wno-main) we don't want to be warned. */
if (!warn_main)
- pedwarn ("return type of %q+D is not %<int%>", fndecl);
+ pedwarn (0, "return type of %q+D is not %<int%>", fndecl);
}
else
{
@@ -6740,9 +6731,9 @@ finish_function (void)
&& !MAIN_NAME_P (DECL_NAME (fndecl))
/* Or if they didn't actually specify a return type. */
&& !C_FUNCTION_IMPLICIT_INT (fndecl)
- /* Normally, with -Wreturn-type, flow will complain. Unless we're an
- inline function, as we might never be compiled separately. */
- && DECL_INLINE (fndecl))
+ /* Normally, with -Wreturn-type, flow will complain, but we might
+ optimize out static functions. */
+ && !TREE_PUBLIC (fndecl))
{
warning (OPT_Wreturn_type,
"no return statement in function returning non-void");
@@ -7158,8 +7149,8 @@ declspecs_add_qual (struct c_declspecs *specs, tree qual)
default:
gcc_unreachable ();
}
- if (dupe && pedantic && !flag_isoc99)
- pedwarn ("duplicate %qE", qual);
+ if (dupe && !flag_isoc99)
+ pedwarn (OPT_pedantic, "duplicate %qE", qual);
return specs;
}
@@ -7177,7 +7168,9 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec)
specs->deprecated_p = true;
/* Handle type specifier keywords. */
- if (TREE_CODE (type) == IDENTIFIER_NODE && C_IS_RESERVED_WORD (type))
+ if (TREE_CODE (type) == IDENTIFIER_NODE
+ && C_IS_RESERVED_WORD (type)
+ && C_RID_CODE (type) != RID_CXX_COMPAT_WARN)
{
enum rid i = C_RID_CODE (type);
if (specs->type)
@@ -7205,9 +7198,8 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec)
"declaration specifiers");
break;
}
- if (pedantic && !flag_isoc99 && !in_system_header
- && warn_long_long)
- pedwarn ("ISO C90 does not support %<long long%>");
+ if (pedantic && !flag_isoc99 && !in_system_header)
+ pedwarn (OPT_Wlong_long, "ISO C90 does not support %<long long%>");
specs->long_long_p = 1;
break;
}
@@ -7330,8 +7322,8 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec)
break;
case RID_COMPLEX:
dupe = specs->complex_p;
- if (pedantic && !flag_isoc99 && !in_system_header)
- pedwarn ("ISO C90 does not support complex types");
+ if (!flag_isoc99 && !in_system_header)
+ pedwarn (OPT_pedantic, "ISO C90 does not support complex types");
if (specs->typespec_word == cts_void)
error ("both %<complex%> and %<void%> in "
"declaration specifiers");
@@ -7361,8 +7353,7 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec)
break;
case RID_SAT:
dupe = specs->saturating_p;
- if (pedantic)
- pedwarn ("ISO C does not support saturating types");
+ pedwarn (OPT_pedantic, "ISO C does not support saturating types");
if (specs->typespec_word == cts_void)
error ("both %<_Sat%> and %<void%> in "
"declaration specifiers");
@@ -7559,8 +7550,8 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec)
}
if (!targetm.decimal_float_supported_p ())
error ("decimal floating point not supported for this target");
- if (pedantic)
- pedwarn ("ISO C does not support decimal floating point");
+ pedwarn (OPT_pedantic,
+ "ISO C does not support decimal floating point");
return specs;
case RID_FRACT:
case RID_ACCUM:
@@ -7580,8 +7571,8 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec)
}
if (!targetm.fixed_point_supported_p ())
error ("fixed-point types not supported for this target");
- if (pedantic)
- pedwarn ("ISO C does not support fixed-point types");
+ pedwarn (OPT_pedantic,
+ "ISO C does not support fixed-point types");
return specs;
default:
/* ObjC reserved word "id", handled below. */
@@ -7767,9 +7758,9 @@ finish_declspecs (struct c_declspecs *specs)
else if (specs->complex_p)
{
specs->typespec_word = cts_double;
- if (pedantic)
- pedwarn ("ISO C does not support plain %<complex%> meaning "
- "%<double complex%>");
+ pedwarn (OPT_pedantic,
+ "ISO C does not support plain %<complex%> meaning "
+ "%<double complex%>");
}
else
{
@@ -7812,8 +7803,8 @@ finish_declspecs (struct c_declspecs *specs)
specs->type = char_type_node;
if (specs->complex_p)
{
- if (pedantic)
- pedwarn ("ISO C does not support complex integer types");
+ pedwarn (OPT_pedantic,
+ "ISO C does not support complex integer types");
specs->type = build_complex_type (specs->type);
}
break;
@@ -7838,8 +7829,8 @@ finish_declspecs (struct c_declspecs *specs)
: integer_type_node);
if (specs->complex_p)
{
- if (pedantic)
- pedwarn ("ISO C does not support complex integer types");
+ pedwarn (OPT_pedantic,
+ "ISO C does not support complex integer types");
specs->type = build_complex_type (specs->type);
}
break;
@@ -7989,7 +7980,7 @@ c_write_global_declarations_1 (tree globals)
&& !TREE_PUBLIC (decl)
&& C_DECL_USED (decl))
{
- pedwarn ("%q+F used but never defined", decl);
+ pedwarn (0, "%q+F used but never defined", decl);
TREE_NO_WARNING (decl) = 1;
}
diff --git a/gcc/c-errors.c b/gcc/c-errors.c
index dc47b764f39..8adeeeb3538 100644
--- a/gcc/c-errors.c
+++ b/gcc/c-errors.c
@@ -31,7 +31,7 @@ along with GCC; see the file COPYING3. If not see
/* Issue an ISO C99 pedantic warning MSGID. */
void
-pedwarn_c99 (const char *gmsgid, ...)
+pedwarn_c99 (int opt, const char *gmsgid, ...)
{
diagnostic_info diagnostic;
va_list ap;
@@ -39,6 +39,7 @@ pedwarn_c99 (const char *gmsgid, ...)
va_start (ap, gmsgid);
diagnostic_set_info (&diagnostic, gmsgid, &ap, input_location,
flag_isoc99 ? pedantic_warning_kind () : DK_WARNING);
+ diagnostic.option_index = opt;
report_diagnostic (&diagnostic);
va_end (ap);
}
@@ -49,7 +50,7 @@ pedwarn_c99 (const char *gmsgid, ...)
(There is no flag_c90.) */
void
-pedwarn_c90 (const char *gmsgid, ...)
+pedwarn_c90 (int opt, const char *gmsgid, ...)
{
diagnostic_info diagnostic;
va_list ap;
@@ -57,6 +58,7 @@ pedwarn_c90 (const char *gmsgid, ...)
va_start (ap, gmsgid);
diagnostic_set_info (&diagnostic, gmsgid, &ap, input_location,
flag_isoc99 ? DK_WARNING : pedantic_warning_kind ());
+ diagnostic.option_index = opt;
report_diagnostic (&diagnostic);
va_end (ap);
}
diff --git a/gcc/c-format.c b/gcc/c-format.c
index fa28763028f..9d20d12b97b 100644
--- a/gcc/c-format.c
+++ b/gcc/c-format.c
@@ -2262,7 +2262,7 @@ check_format_types (format_wanted_type *types, const char *format_start,
&& TREE_CODE (cur_type) == INTEGER_TYPE
&& (!pedantic || i == 0 || (i == 1 && char_type_flag))
&& (TYPE_UNSIGNED (wanted_type)
- ? wanted_type == c_common_unsigned_type (cur_type)
+ ? wanted_type == unsigned_type_for (cur_type)
: wanted_type == c_common_signed_type (cur_type)))
continue;
/* Likewise, "signed char", "unsigned char" and "char" are
diff --git a/gcc/c-gimplify.c b/gcc/c-gimplify.c
index 12292a7e591..342848acd29 100644
--- a/gcc/c-gimplify.c
+++ b/gcc/c-gimplify.c
@@ -31,7 +31,7 @@ along with GCC; see the file COPYING3. If not see
#include "varray.h"
#include "c-tree.h"
#include "c-common.h"
-#include "tree-gimple.h"
+#include "gimple.h"
#include "hard-reg-set.h"
#include "basic-block.h"
#include "tree-flow.h"
@@ -104,7 +104,6 @@ c_genericize (tree fndecl)
/* Go ahead and gimplify for now. */
gimplify_function_tree (fndecl);
- /* Dump the genericized tree IR. */
dump_function (TDI_generic, fndecl);
/* Genericize all nested functions now. We do things in this order so
@@ -118,14 +117,16 @@ c_genericize (tree fndecl)
static void
add_block_to_enclosing (tree block)
{
+ unsigned i;
tree enclosing;
+ gimple bind;
+ VEC(gimple, heap) *stack = gimple_bind_expr_stack ();
- for (enclosing = gimple_current_bind_expr ();
- enclosing; enclosing = TREE_CHAIN (enclosing))
- if (BIND_EXPR_BLOCK (enclosing))
+ for (i = 0; VEC_iterate (gimple, stack, i, bind); i++)
+ if (gimple_bind_block (bind))
break;
- enclosing = BIND_EXPR_BLOCK (enclosing);
+ enclosing = gimple_bind_block (bind);
BLOCK_SUBBLOCKS (enclosing) = chainon (BLOCK_SUBBLOCKS (enclosing), block);
}
@@ -178,7 +179,7 @@ c_build_bind_expr (tree block, tree body)
decl instead. */
static enum gimplify_status
-gimplify_compound_literal_expr (tree *expr_p, tree *pre_p)
+gimplify_compound_literal_expr (tree *expr_p, gimple_seq *pre_p)
{
tree decl_s = COMPOUND_LITERAL_EXPR_DECL_STMT (*expr_p);
tree decl = DECL_EXPR_DECL (decl_s);
@@ -249,10 +250,12 @@ optimize_compound_literals_in_ctor (tree orig_ctor)
return ctor;
}
-/* Do C-specific gimplification. Args are as for gimplify_expr. */
+/* Do C-specific gimplification on *EXPR_P. PRE_P and POST_P are as in
+ gimplify_expr. */
int
-c_gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p ATTRIBUTE_UNUSED)
+c_gimplify_expr (tree *expr_p, gimple_seq *pre_p,
+ gimple_seq *post_p ATTRIBUTE_UNUSED)
{
enum tree_code code = TREE_CODE (*expr_p);
diff --git a/gcc/c-lex.c b/gcc/c-lex.c
index 3c2c225c59f..e49e3319c3f 100644
--- a/gcc/c-lex.c
+++ b/gcc/c-lex.c
@@ -239,7 +239,6 @@ fe_file_change (const struct line_map *new_map)
}
update_header_times (new_map->to_file);
- in_system_header = new_map->sysp != 0;
input_location = new_map->start_location;
}
@@ -588,8 +587,8 @@ interpret_integer (const cpp_token *token, unsigned int flags)
if (itk > itk_unsigned_long
&& (flags & CPP_N_WIDTH) != CPP_N_LARGE
&& !in_system_header && !flag_isoc99)
- pedwarn ("integer constant is too large for %qs type",
- (flags & CPP_N_UNSIGNED) ? "unsigned long" : "long");
+ pedwarn (0, "integer constant is too large for %qs type",
+ (flags & CPP_N_UNSIGNED) ? "unsigned long" : "long");
value = build_int_cst_wide (type, integer.low, integer.high);
@@ -642,8 +641,8 @@ interpret_float (const cpp_token *token, unsigned int flags)
return error_mark_node;
}
- else if (pedantic)
- pedwarn ("non-standard suffix on floating constant");
+ else
+ pedwarn (OPT_pedantic, "non-standard suffix on floating constant");
type = c_common_type_for_mode (mode, 0);
gcc_assert (type);
@@ -685,7 +684,7 @@ interpret_float (const cpp_token *token, unsigned int flags)
if (REAL_VALUE_ISINF (real))
{
if (!MODE_HAS_INFINITIES (TYPE_MODE (type)))
- pedwarn ("floating constant exceeds range of %qT", type);
+ pedwarn (0, "floating constant exceeds range of %qT", type);
else
warning (OPT_Woverflow, "floating constant exceeds range of %qT", type);
}
diff --git a/gcc/c-omp.c b/gcc/c-omp.c
index 1da71d27b9c..7da659cc9fb 100644
--- a/gcc/c-omp.c
+++ b/gcc/c-omp.c
@@ -29,7 +29,7 @@ along with GCC; see the file COPYING3. If not see
#include "function.h"
#include "c-common.h"
#include "toplev.h"
-#include "tree-gimple.h"
+#include "gimple.h"
#include "bitmap.h"
#include "langhooks.h"
diff --git a/gcc/c-opts.c b/gcc/c-opts.c
index 33d0e6bed26..258101c39cf 100644
--- a/gcc/c-opts.c
+++ b/gcc/c-opts.c
@@ -1018,13 +1018,9 @@ c_common_post_options (const char **pfilename)
C_COMMON_OVERRIDE_OPTIONS;
#endif
- flag_inline_trees = 1;
-
/* Use tree inlining. */
if (!flag_no_inline)
flag_no_inline = 1;
- if (flag_inline_functions)
- flag_inline_trees = 2;
/* By default we use C99 inline semantics in GNU99 or C99 mode. C99
inline semantics are not supported in GNU89 or C89 mode. */
@@ -1033,14 +1029,6 @@ c_common_post_options (const char **pfilename)
else if (!flag_gnu89_inline && !flag_isoc99)
error ("-fno-gnu89-inline is only supported in GNU99 or C99 mode");
- /* If we are given more than one input file, we must use
- unit-at-a-time mode. */
- if (num_in_fnames > 1)
- flag_unit_at_a_time = 1;
-
- if (pch_file && !flag_unit_at_a_time)
- sorry ("Precompiled headers require -funit-at-a-time");
-
/* Default to ObjC sjlj exception handling if NeXT runtime. */
if (flag_objc_sjlj_exceptions < 0)
flag_objc_sjlj_exceptions = flag_next_runtime;
@@ -1091,12 +1079,7 @@ c_common_post_options (const char **pfilename)
if (c_dialect_cxx ())
{
if (!flag_no_inline)
- {
- flag_inline_trees = 1;
- flag_no_inline = 1;
- }
- if (flag_inline_functions)
- flag_inline_trees = 2;
+ flag_no_inline = 1;
}
/* In C, -Wconversion enables -Wsign-conversion (unless disabled
diff --git a/gcc/c-parser.c b/gcc/c-parser.c
index 45aff80d6c0..a2ea45f6a78 100644
--- a/gcc/c-parser.c
+++ b/gcc/c-parser.c
@@ -59,131 +59,6 @@ along with GCC; see the file COPYING3. If not see
#include "cgraph.h"
-/* The reserved keyword table. */
-struct resword
-{
- const char *word;
- ENUM_BITFIELD(rid) rid : 16;
- unsigned int disable : 16;
-};
-
-/* Disable mask. Keywords are disabled if (reswords[i].disable &
- mask) is _true_. */
-#define D_C89 0x01 /* not in C89 */
-#define D_EXT 0x02 /* GCC extension */
-#define D_EXT89 0x04 /* GCC extension incorporated in C99 */
-#define D_OBJC 0x08 /* Objective C only */
-
-static const struct resword reswords[] =
-{
- { "_Bool", RID_BOOL, 0 },
- { "_Complex", RID_COMPLEX, 0 },
- { "_Decimal32", RID_DFLOAT32, D_EXT },
- { "_Decimal64", RID_DFLOAT64, D_EXT },
- { "_Decimal128", RID_DFLOAT128, D_EXT },
- { "_Fract", RID_FRACT, D_EXT },
- { "_Accum", RID_ACCUM, D_EXT },
- { "_Sat", RID_SAT, D_EXT },
- { "__FUNCTION__", RID_FUNCTION_NAME, 0 },
- { "__PRETTY_FUNCTION__", RID_PRETTY_FUNCTION_NAME, 0 },
- { "__alignof", RID_ALIGNOF, 0 },
- { "__alignof__", RID_ALIGNOF, 0 },
- { "__asm", RID_ASM, 0 },
- { "__asm__", RID_ASM, 0 },
- { "__attribute", RID_ATTRIBUTE, 0 },
- { "__attribute__", RID_ATTRIBUTE, 0 },
- { "__builtin_choose_expr", RID_CHOOSE_EXPR, 0 },
- { "__builtin_offsetof", RID_OFFSETOF, 0 },
- { "__builtin_types_compatible_p", RID_TYPES_COMPATIBLE_P, 0 },
- { "__builtin_va_arg", RID_VA_ARG, 0 },
- { "__complex", RID_COMPLEX, 0 },
- { "__complex__", RID_COMPLEX, 0 },
- { "__const", RID_CONST, 0 },
- { "__const__", RID_CONST, 0 },
- { "__extension__", RID_EXTENSION, 0 },
- { "__func__", RID_C99_FUNCTION_NAME, 0 },
- { "__imag", RID_IMAGPART, 0 },
- { "__imag__", RID_IMAGPART, 0 },
- { "__inline", RID_INLINE, 0 },
- { "__inline__", RID_INLINE, 0 },
- { "__label__", RID_LABEL, 0 },
- { "__real", RID_REALPART, 0 },
- { "__real__", RID_REALPART, 0 },
- { "__restrict", RID_RESTRICT, 0 },
- { "__restrict__", RID_RESTRICT, 0 },
- { "__signed", RID_SIGNED, 0 },
- { "__signed__", RID_SIGNED, 0 },
- { "__thread", RID_THREAD, 0 },
- { "__typeof", RID_TYPEOF, 0 },
- { "__typeof__", RID_TYPEOF, 0 },
- { "__volatile", RID_VOLATILE, 0 },
- { "__volatile__", RID_VOLATILE, 0 },
- { "asm", RID_ASM, D_EXT },
- { "auto", RID_AUTO, 0 },
- { "break", RID_BREAK, 0 },
- { "case", RID_CASE, 0 },
- { "char", RID_CHAR, 0 },
- { "const", RID_CONST, 0 },
- { "continue", RID_CONTINUE, 0 },
- { "default", RID_DEFAULT, 0 },
- { "do", RID_DO, 0 },
- { "double", RID_DOUBLE, 0 },
- { "else", RID_ELSE, 0 },
- { "enum", RID_ENUM, 0 },
- { "extern", RID_EXTERN, 0 },
- { "float", RID_FLOAT, 0 },
- { "for", RID_FOR, 0 },
- { "goto", RID_GOTO, 0 },
- { "if", RID_IF, 0 },
- { "inline", RID_INLINE, D_EXT89 },
- { "int", RID_INT, 0 },
- { "long", RID_LONG, 0 },
- { "register", RID_REGISTER, 0 },
- { "restrict", RID_RESTRICT, D_C89 },
- { "return", RID_RETURN, 0 },
- { "short", RID_SHORT, 0 },
- { "signed", RID_SIGNED, 0 },
- { "sizeof", RID_SIZEOF, 0 },
- { "static", RID_STATIC, 0 },
- { "struct", RID_STRUCT, 0 },
- { "switch", RID_SWITCH, 0 },
- { "typedef", RID_TYPEDEF, 0 },
- { "typeof", RID_TYPEOF, D_EXT },
- { "union", RID_UNION, 0 },
- { "unsigned", RID_UNSIGNED, 0 },
- { "void", RID_VOID, 0 },
- { "volatile", RID_VOLATILE, 0 },
- { "while", RID_WHILE, 0 },
- /* These Objective-C keywords are recognized only immediately after
- an '@'. */
- { "class", RID_AT_CLASS, D_OBJC },
- { "compatibility_alias", RID_AT_ALIAS, D_OBJC },
- { "defs", RID_AT_DEFS, D_OBJC },
- { "encode", RID_AT_ENCODE, D_OBJC },
- { "end", RID_AT_END, D_OBJC },
- { "implementation", RID_AT_IMPLEMENTATION, D_OBJC },
- { "interface", RID_AT_INTERFACE, D_OBJC },
- { "private", RID_AT_PRIVATE, D_OBJC },
- { "protected", RID_AT_PROTECTED, D_OBJC },
- { "protocol", RID_AT_PROTOCOL, D_OBJC },
- { "public", RID_AT_PUBLIC, D_OBJC },
- { "selector", RID_AT_SELECTOR, D_OBJC },
- { "throw", RID_AT_THROW, D_OBJC },
- { "try", RID_AT_TRY, D_OBJC },
- { "catch", RID_AT_CATCH, D_OBJC },
- { "finally", RID_AT_FINALLY, D_OBJC },
- { "synchronized", RID_AT_SYNCHRONIZED, D_OBJC },
- /* These are recognized only in protocol-qualifier context
- (see above) */
- { "bycopy", RID_BYCOPY, D_OBJC },
- { "byref", RID_BYREF, D_OBJC },
- { "in", RID_IN, D_OBJC },
- { "inout", RID_INOUT, D_OBJC },
- { "oneway", RID_ONEWAY, D_OBJC },
- { "out", RID_OUT, D_OBJC },
-};
-#define N_reswords (sizeof reswords / sizeof (struct resword))
-
/* Initialization routine for this file. */
void
@@ -193,24 +68,41 @@ c_parse_init (void)
identifiers. */
unsigned int i;
tree id;
- int mask = (flag_isoc99 ? 0 : D_C89)
- | (flag_no_asm ? (flag_isoc99 ? D_EXT : D_EXT|D_EXT89) : 0);
+ int mask = 0;
+ mask |= D_CXXONLY;
+ if (!flag_isoc99)
+ mask |= D_C99;
+ if (flag_no_asm)
+ {
+ mask |= D_ASM | D_EXT;
+ if (!flag_isoc99)
+ mask |= D_EXT89;
+ }
if (!c_dialect_objc ())
- mask |= D_OBJC;
+ mask |= D_OBJC | D_CXX_OBJC;
ridpointers = GGC_CNEWVEC (tree, (int) RID_MAX);
- for (i = 0; i < N_reswords; i++)
+ for (i = 0; i < num_c_common_reswords; i++)
{
/* If a keyword is disabled, do not enter it into the table
and so create a canonical spelling that isn't a keyword. */
- if (reswords[i].disable & mask)
- continue;
+ if (c_common_reswords[i].disable & mask)
+ {
+ if (warn_cxx_compat
+ && (c_common_reswords[i].disable & D_CXXWARN))
+ {
+ id = get_identifier (c_common_reswords[i].word);
+ C_SET_RID_CODE (id, RID_CXX_COMPAT_WARN);
+ C_IS_RESERVED_WORD (id) = 1;
+ }
+ continue;
+ }
- id = get_identifier (reswords[i].word);
- C_SET_RID_CODE (id, reswords[i].rid);
+ id = get_identifier (c_common_reswords[i].word);
+ C_SET_RID_CODE (id, c_common_reswords[i].rid);
C_IS_RESERVED_WORD (id) = 1;
- ridpointers [(int) reswords[i].rid] = id;
+ ridpointers [(int) c_common_reswords[i].rid] = id;
}
}
@@ -257,8 +149,6 @@ typedef struct c_token GTY (())
/* If this token is a CPP_PRAGMA, this indicates the pragma that
was seen. Otherwise it is PRAGMA_NONE. */
ENUM_BITFIELD (pragma_kind) pragma_kind : 7;
- /* True if this token is from a system header. */
- BOOL_BITFIELD in_system_header : 1;
/* The value associated with this token, if any. */
tree value;
/* The location at which this token was found. */
@@ -314,7 +204,6 @@ c_lex_one_token (c_parser *parser, c_token *token)
token->id_kind = C_ID_NONE;
token->keyword = RID_MAX;
token->pragma_kind = PRAGMA_NONE;
- token->in_system_header = in_system_header;
switch (token->type)
{
@@ -330,9 +219,16 @@ c_lex_one_token (c_parser *parser, c_token *token)
{
enum rid rid_code = C_RID_CODE (token->value);
- if (c_dialect_objc ())
+ if (rid_code == RID_CXX_COMPAT_WARN)
{
- if (!OBJC_IS_AT_KEYWORD (rid_code)
+ warning (OPT_Wc___compat,
+ "%Hidentifier %qs conflicts with C++ keyword",
+ &token->location,
+ IDENTIFIER_POINTER (token->value));
+ }
+ else if (c_dialect_objc ())
+ {
+ if (!objc_is_reserved_word (token->value)
&& (!OBJC_IS_PQ_KEYWORD (rid_code)
|| parser->objc_pq_context))
{
@@ -646,7 +542,6 @@ c_parser_set_source_position_from_token (c_token *token)
if (token->type != CPP_EOF)
{
input_location = token->location;
- in_system_header = token->in_system_header;
}
}
@@ -1065,9 +960,8 @@ c_parser_translation_unit (c_parser *parser)
{
if (c_parser_next_token_is (parser, CPP_EOF))
{
- if (pedantic)
- pedwarn ("%HISO C forbids an empty translation unit",
- &c_parser_peek_token (parser)->location);
+ pedwarn (OPT_pedantic, "%HISO C forbids an empty translation unit",
+ &c_parser_peek_token (parser)->location);
}
else
{
@@ -1129,7 +1023,7 @@ c_parser_external_declaration (c_parser *parser)
gcc_assert (c_dialect_objc ());
c_parser_objc_class_definition (parser);
break;
- case RID_AT_CLASS:
+ case RID_CLASS:
gcc_assert (c_dialect_objc ());
c_parser_objc_class_declaration (parser);
break;
@@ -1151,9 +1045,9 @@ c_parser_external_declaration (c_parser *parser)
}
break;
case CPP_SEMICOLON:
- if (pedantic)
- pedwarn ("%HISO C does not allow extra %<;%> outside of a function",
- &c_parser_peek_token (parser)->location);
+ pedwarn (OPT_pedantic,
+ "%HISO C does not allow extra %<;%> outside of a function",
+ &c_parser_peek_token (parser)->location);
c_parser_consume_token (parser);
break;
case CPP_PRAGMA:
@@ -1267,7 +1161,7 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok, bool empty_ok,
else
{
shadow_tag_warned (specs, 1);
- pedwarn ("%Hempty declaration", &here);
+ pedwarn (0, "%Hempty declaration", &here);
}
c_parser_consume_token (parser);
return;
@@ -1303,8 +1197,8 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok, bool empty_ok,
if (!diagnosed_no_specs && !specs->declspecs_seen_p)
{
diagnosed_no_specs = true;
- pedwarn ("%Hdata definition has no type or storage class",
- &here);
+ pedwarn (0, "%Hdata definition has no type or storage class",
+ &here);
}
/* Having seen a data definition, there cannot now be a
function definition. */
@@ -1373,8 +1267,7 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok, bool empty_ok,
/* Function definition (nested or otherwise). */
if (nested)
{
- if (pedantic)
- pedwarn ("%HISO C forbids nested functions", &here);
+ pedwarn (OPT_pedantic, "%HISO C forbids nested functions", &here);
c_push_function_context ();
}
if (!start_function (specs, declarator, all_prefix_attrs))
@@ -1768,8 +1661,9 @@ c_parser_enum_specifier (c_parser *parser)
}
if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
{
- if (seen_comma && pedantic && !flag_isoc99)
- pedwarn ("%Hcomma at end of enumerator list", &comma_loc);
+ if (seen_comma && !flag_isoc99)
+ pedwarn (OPT_pedantic, "%Hcomma at end of enumerator list",
+ &comma_loc);
c_parser_consume_token (parser);
break;
}
@@ -1800,7 +1694,8 @@ c_parser_enum_specifier (c_parser *parser)
if (pedantic && !COMPLETE_TYPE_P (ret.spec))
{
gcc_assert (ident);
- pedwarn ("%HISO C forbids forward references to %<enum%> types",
+ pedwarn (OPT_pedantic,
+ "%HISO C forbids forward references to %<enum%> types",
&ident_loc);
}
return ret;
@@ -1925,9 +1820,9 @@ c_parser_struct_or_union_specifier (c_parser *parser)
/* Parse any stray semicolon. */
if (c_parser_next_token_is (parser, CPP_SEMICOLON))
{
- if (pedantic)
- pedwarn ("%Hextra semicolon in struct or union specified",
- &c_parser_peek_token (parser)->location);
+ pedwarn (OPT_pedantic,
+ "%Hextra semicolon in struct or union specified",
+ &c_parser_peek_token (parser)->location);
c_parser_consume_token (parser);
continue;
}
@@ -1955,8 +1850,8 @@ c_parser_struct_or_union_specifier (c_parser *parser)
else
{
if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
- pedwarn ("%Hno semicolon at end of struct or union",
- &c_parser_peek_token (parser)->location);
+ pedwarn (0, "%Hno semicolon at end of struct or union",
+ &c_parser_peek_token (parser)->location);
else
{
c_parser_error (parser, "expected %<;%>");
@@ -2047,9 +1942,9 @@ c_parser_struct_declaration (c_parser *parser)
tree ret;
if (!specs->type_seen_p)
{
- if (pedantic)
- pedwarn ("%HISO C forbids member declarations with no members",
- &decl_loc);
+ pedwarn (OPT_pedantic,
+ "%HISO C forbids member declarations with no members",
+ &decl_loc);
shadow_tag_warned (specs, pedantic);
ret = NULL_TREE;
}
@@ -3102,8 +2997,8 @@ c_parser_braced_init (c_parser *parser, tree type, bool nested_p)
really_start_incremental_init (type);
if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
{
- if (pedantic)
- pedwarn ("%HISO C forbids empty initializer braces", &brace_loc);
+ pedwarn (OPT_pedantic, "%HISO C forbids empty initializer braces",
+ &brace_loc);
}
else
{
@@ -3147,12 +3042,10 @@ c_parser_initelt (c_parser *parser)
{
/* Old-style structure member designator. */
set_init_label (c_parser_peek_token (parser)->value);
- if (pedantic)
- {
- /* Use the colon as the error location. */
- pedwarn ("%Hobsolete use of designated initializer with %<:%>",
- &c_parser_peek_2nd_token (parser)->location);
- }
+ /* Use the colon as the error location. */
+ pedwarn (OPT_pedantic,
+ "%Hobsolete use of designated initializer with %<:%>",
+ &c_parser_peek_2nd_token (parser)->location);
c_parser_consume_token (parser);
c_parser_consume_token (parser);
}
@@ -3280,8 +3173,9 @@ c_parser_initelt (c_parser *parser)
{
c_parser_consume_token (parser);
set_init_index (first, second);
- if (pedantic && second)
- pedwarn ("%HISO C forbids specifying range of "
+ if (second)
+ pedwarn (OPT_pedantic,
+ "%HISO C forbids specifying range of "
"elements to initialize", &ellipsis_loc);
}
else
@@ -3293,8 +3187,9 @@ c_parser_initelt (c_parser *parser)
{
if (c_parser_next_token_is (parser, CPP_EQ))
{
- if (pedantic && !flag_isoc99)
- pedwarn ("%HISO C90 forbids specifying subobject "
+ if (!flag_isoc99)
+ pedwarn (OPT_pedantic,
+ "%HISO C90 forbids specifying subobject "
"to initialize", &des_loc);
c_parser_consume_token (parser);
}
@@ -3302,10 +3197,10 @@ c_parser_initelt (c_parser *parser)
{
if (des_seen == 1)
{
- if (pedantic)
- pedwarn ("%Hobsolete use of designated initializer "
- "without %<=%>",
- &c_parser_peek_token (parser)->location);
+ pedwarn (OPT_pedantic,
+ "%Hobsolete use of designated initializer "
+ "without %<=%>",
+ &c_parser_peek_token (parser)->location);
}
else
{
@@ -3456,8 +3351,7 @@ c_parser_compound_statement_nostart (c_parser *parser)
}
c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
}
- if (pedantic)
- pedwarn ("%HISO C forbids label declarations", &err_loc);
+ pedwarn (OPT_pedantic, "%HISO C forbids label declarations", &err_loc);
}
/* We must now have at least one statement, label or declaration. */
if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
@@ -3487,10 +3381,11 @@ c_parser_compound_statement_nostart (c_parser *parser)
{
last_label = false;
c_parser_declaration_or_fndef (parser, true, true, true, true);
- if (last_stmt
- && ((pedantic && !flag_isoc99)
- || warn_declaration_after_statement))
- pedwarn_c90 ("%HISO C90 forbids mixed declarations and code",
+ if (last_stmt)
+ pedwarn_c90 ((pedantic && !flag_isoc99)
+ ? OPT_pedantic
+ : OPT_Wdeclaration_after_statement,
+ "%HISO C90 forbids mixed declarations and code",
&loc);
last_stmt = false;
}
@@ -3515,10 +3410,11 @@ c_parser_compound_statement_nostart (c_parser *parser)
/* Following the old parser, __extension__ does not
disable this diagnostic. */
restore_extension_diagnostics (ext);
- if (last_stmt
- && ((pedantic && !flag_isoc99)
- || warn_declaration_after_statement))
- pedwarn_c90 ("%HISO C90 forbids mixed declarations and code",
+ if (last_stmt)
+ pedwarn_c90 ((pedantic && !flag_isoc99)
+ ? OPT_pedantic
+ : OPT_Wdeclaration_after_statement,
+ "%HISO C90 forbids mixed declarations and code",
&loc);
last_stmt = false;
}
@@ -3830,7 +3726,7 @@ c_parser_statement_after_labels (c_parser *parser)
case RID_ASM:
stmt = c_parser_asm_statement (parser);
break;
- case RID_AT_THROW:
+ case RID_THROW:
gcc_assert (c_dialect_objc ());
c_parser_consume_token (parser);
if (c_parser_next_token_is (parser, CPP_SEMICOLON))
@@ -3845,7 +3741,7 @@ c_parser_statement_after_labels (c_parser *parser)
goto expect_semicolon;
}
break;
- case RID_AT_TRY:
+ case RID_TRY:
gcc_assert (c_dialect_objc ());
c_parser_objc_try_catch_statement (parser);
break;
@@ -4525,9 +4421,9 @@ c_parser_conditional_expression (c_parser *parser, struct c_expr *after)
c_parser_consume_token (parser);
if (c_parser_next_token_is (parser, CPP_COLON))
{
- if (pedantic)
- pedwarn ("%HISO C forbids omitting the middle term of a ?: expression",
- &c_parser_peek_token (parser)->location);
+ pedwarn (OPT_pedantic,
+ "%HISO C forbids omitting the middle term of a ?: expression",
+ &c_parser_peek_token (parser)->location);
/* Make sure first operand is calculated only once. */
exp1.value = save_expr (default_conversion (cond.value));
cond.value = c_objc_common_truthvalue_conversion (exp1.value);
@@ -5229,9 +5125,8 @@ c_parser_postfix_expression (c_parser *parser)
c_parser_compound_statement_nostart (parser);
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
"expected %<)%>");
- if (pedantic)
- pedwarn ("%HISO C forbids braced-groups within expressions",
- &here);
+ pedwarn (OPT_pedantic,
+ "%HISO C forbids braced-groups within expressions", &here);
expr.value = c_finish_stmt_expr (stmt);
expr.original_code = ERROR_MARK;
}
@@ -5591,8 +5486,9 @@ c_parser_postfix_expression_after_paren_type (c_parser *parser,
finish_init ();
maybe_warn_string_init (type, init);
- if (pedantic && !flag_isoc99)
- pedwarn ("%HISO C90 forbids compound literals", &start_loc);
+ if (!flag_isoc99)
+ pedwarn (OPT_pedantic, "%HISO C90 forbids compound literals",
+ &start_loc);
expr.value = build_compound_literal (type, init.value);
expr.original_code = ERROR_MARK;
return c_parser_postfix_expression_after_primary (parser, expr);
@@ -5630,6 +5526,8 @@ c_parser_postfix_expression_after_primary (c_parser *parser,
"expected %<)%>");
expr.value = build_function_call (expr.value, exprlist);
expr.original_code = ERROR_MARK;
+ if (warn_disallowed_functions)
+ warn_if_disallowed_function_p (expr.value);
break;
case CPP_DOT:
/* Structure element reference. */
@@ -5891,9 +5789,9 @@ c_parser_objc_class_instance_variables (c_parser *parser)
/* Parse any stray semicolon. */
if (c_parser_next_token_is (parser, CPP_SEMICOLON))
{
- if (pedantic)
- pedwarn ("%Hextra semicolon in struct or union specified",
- &c_parser_peek_token (parser)->location);
+ pedwarn (OPT_pedantic,
+ "%Hextra semicolon in struct or union specified",
+ &c_parser_peek_token (parser)->location);
c_parser_consume_token (parser);
continue;
}
@@ -5904,19 +5802,19 @@ c_parser_objc_class_instance_variables (c_parser *parser)
break;
}
/* Parse any objc-visibility-spec. */
- if (c_parser_next_token_is_keyword (parser, RID_AT_PRIVATE))
+ if (c_parser_next_token_is_keyword (parser, RID_PRIVATE))
{
c_parser_consume_token (parser);
objc_set_visibility (2);
continue;
}
- else if (c_parser_next_token_is_keyword (parser, RID_AT_PROTECTED))
+ else if (c_parser_next_token_is_keyword (parser, RID_PROTECTED))
{
c_parser_consume_token (parser);
objc_set_visibility (0);
continue;
}
- else if (c_parser_next_token_is_keyword (parser, RID_AT_PUBLIC))
+ else if (c_parser_next_token_is_keyword (parser, RID_PUBLIC))
{
c_parser_consume_token (parser);
objc_set_visibility (1);
@@ -5951,7 +5849,7 @@ static void
c_parser_objc_class_declaration (c_parser *parser)
{
tree list = NULL_TREE;
- gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_CLASS));
+ gcc_assert (c_parser_next_token_is_keyword (parser, RID_CLASS));
c_parser_consume_token (parser);
/* Any identifiers, including those declared as type names, are OK
here. */
@@ -6109,9 +6007,9 @@ c_parser_objc_method_definition (c_parser *parser)
if (c_parser_next_token_is (parser, CPP_SEMICOLON))
{
c_parser_consume_token (parser);
- if (pedantic)
- pedwarn ("%Hextra semicolon in method definition specified",
- &c_parser_peek_token (parser)->location);
+ pedwarn (OPT_pedantic,
+ "%Hextra semicolon in method definition specified",
+ &c_parser_peek_token (parser)->location);
}
if (!c_parser_next_token_is (parser, CPP_OPEN_BRACE))
{
@@ -6147,10 +6045,9 @@ c_parser_objc_methodprotolist (c_parser *parser)
switch (c_parser_peek_token (parser)->type)
{
case CPP_SEMICOLON:
- if (pedantic)
- pedwarn ("%HISO C does not allow extra %<;%> "
- "outside of a function",
- &c_parser_peek_token (parser)->location);
+ pedwarn (OPT_pedantic, "%HISO C does not allow extra %<;%> "
+ "outside of a function",
+ &c_parser_peek_token (parser)->location);
c_parser_consume_token (parser);
break;
case CPP_PLUS:
@@ -6388,12 +6285,12 @@ c_parser_objc_try_catch_statement (c_parser *parser)
{
location_t loc;
tree stmt;
- gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_TRY));
+ gcc_assert (c_parser_next_token_is_keyword (parser, RID_TRY));
c_parser_consume_token (parser);
loc = c_parser_peek_token (parser)->location;
stmt = c_parser_compound_statement (parser);
objc_begin_try_stmt (loc, stmt);
- while (c_parser_next_token_is_keyword (parser, RID_AT_CATCH))
+ while (c_parser_next_token_is_keyword (parser, RID_CATCH))
{
struct c_parm *parm;
c_parser_consume_token (parser);
diff --git a/gcc/c-pch.c b/gcc/c-pch.c
index 0da17f7f24b..3fde4611fab 100644
--- a/gcc/c-pch.c
+++ b/gcc/c-pch.c
@@ -45,7 +45,6 @@ static const struct c_pch_matching
const char *flag_name;
} pch_matching[] = {
{ &flag_exceptions, "-fexceptions" },
- { &flag_unit_at_a_time, "-funit-at-a-time" }
};
enum {
@@ -93,10 +92,10 @@ static const char *
get_ident (void)
{
static char result[IDENT_LENGTH];
- static const char template[IDENT_LENGTH] = "gpch.013";
+ static const char templ[IDENT_LENGTH] = "gpch.013";
static const char c_language_chars[] = "Co+O";
- memcpy (result, template, IDENT_LENGTH);
+ memcpy (result, templ, IDENT_LENGTH);
result[4] = c_language_chars[c_language];
return result;
diff --git a/gcc/c-pragma.c b/gcc/c-pragma.c
index e7bb928c8a9..b2bbfae8276 100644
--- a/gcc/c-pragma.c
+++ b/gcc/c-pragma.c
@@ -866,6 +866,346 @@ handle_pragma_diagnostic(cpp_reader *ARG_UNUSED(dummy))
GCC_BAD ("unknown option after %<#pragma GCC diagnostic%> kind");
}
+/* Stack of the #pragma GCC options created with #pragma GCC option push. */
+static GTY(()) VEC(tree,gc) *option_stack;
+
+/* Parse #pragma GCC option (xxx) to set target specific options. */
+static void
+handle_pragma_option(cpp_reader *ARG_UNUSED(dummy))
+{
+ enum cpp_ttype token;
+ const char *name;
+ tree x;
+ bool close_paren_needed_p = false;
+
+ if (cfun)
+ {
+ error ("#pragma GCC option is not allowed inside functions");
+ return;
+ }
+
+ if (!targetm.target_option.pragma_parse)
+ {
+ error ("#pragma GCC option is not supported for this system");
+ return;
+ }
+
+ token = pragma_lex (&x);
+ if (token == CPP_OPEN_PAREN)
+ {
+ close_paren_needed_p = true;
+ token = pragma_lex (&x);
+ }
+
+ if (token == CPP_NAME)
+ {
+ bool call_pragma_parse_p = false;
+ bool ok_p;
+
+ name = IDENTIFIER_POINTER (x);
+ if (strcmp (name, "reset") == 0)
+ {
+ current_option_pragma = NULL_TREE;
+ call_pragma_parse_p = true;
+ }
+
+ else if (strcmp (name, "push") == 0)
+ VEC_safe_push (tree, gc, option_stack,
+ copy_list (current_option_pragma));
+
+ else if (strcmp (name, "pop") == 0)
+ {
+ int len = VEC_length (tree, option_stack);
+ if (len == 0)
+ {
+ GCC_BAD ("%<#pragma GCC option pop%> without a %<#pragma GCC "
+ "option push%>");
+ return;
+ }
+ else
+ {
+ VEC_truncate (tree, option_stack, len-1);
+ current_option_pragma = ((len > 1)
+ ? VEC_last (tree, option_stack)
+ : NULL_TREE);
+
+ call_pragma_parse_p = true;
+ }
+ }
+
+ else
+ {
+ GCC_BAD ("%<#pragma GCC option%> is not a string or "
+ "push/pop/reset");
+ return;
+ }
+
+ token = pragma_lex (&x);
+ if (close_paren_needed_p)
+ {
+ if (token == CPP_CLOSE_PAREN)
+ token = pragma_lex (&x);
+ else
+ GCC_BAD ("%<#pragma GCC option ([push|pop|reset])%> does not "
+ "have a final %<)%>.");
+ }
+
+ if (token != CPP_EOF)
+ {
+ GCC_BAD ("%<#pragma GCC option [push|pop|reset]%> is badly "
+ "formed");
+ return;
+ }
+
+ /* See if we need to call the pragma_parse hook. This must occur at the
+ end after processing all of the tokens, or we may get spurious errors
+ when we define or undef macros. */
+ ok_p = targetm.target_option.pragma_parse (current_option_pragma);
+ gcc_assert (ok_p);
+ }
+
+ else if (token != CPP_STRING)
+ {
+ GCC_BAD ("%<#pragma GCC option%> is not a string or push/pop/reset");
+ return;
+ }
+
+ /* Strings are user options. */
+ else
+ {
+ tree args = NULL_TREE;
+
+ do
+ {
+ /* Build up the strings now as a tree linked list. Skip empty
+ strings. */
+ if (TREE_STRING_LENGTH (x) > 0)
+ args = tree_cons (NULL_TREE, x, args);
+
+ token = pragma_lex (&x);
+ while (token == CPP_COMMA)
+ token = pragma_lex (&x);
+ }
+ while (token == CPP_STRING);
+
+ if (close_paren_needed_p)
+ {
+ if (token == CPP_CLOSE_PAREN)
+ token = pragma_lex (&x);
+ else
+ GCC_BAD ("%<#pragma GCC option (string [,string]...)%> does "
+ "not have a final %<)%>.");
+ }
+
+ if (token != CPP_EOF)
+ {
+ error ("#pragma GCC option string... is badly formed");
+ return;
+ }
+
+ /* put arguments in the order the user typed them. */
+ args = nreverse (args);
+
+ if (targetm.target_option.pragma_parse (args))
+ current_option_pragma = args;
+ }
+}
+
+/* Stack of the #pragma GCC optimize options created with #pragma GCC optimize
+ push. */
+static GTY(()) VEC(tree,gc) *optimize_stack;
+
+/* Handle #pragma GCC optimize to set optimization options. */
+static void
+handle_pragma_optimize(cpp_reader *ARG_UNUSED(dummy))
+{
+ enum cpp_ttype token;
+ const char *name;
+ tree x;
+ bool close_paren_needed_p = false;
+ tree optimization_previous_node = optimization_current_node;
+
+ if (cfun)
+ {
+ error ("#pragma GCC optimize is not allowed inside functions");
+ return;
+ }
+
+ token = pragma_lex (&x);
+ if (token == CPP_OPEN_PAREN)
+ {
+ close_paren_needed_p = true;
+ token = pragma_lex (&x);
+ }
+
+ if (token == CPP_NAME)
+ {
+ bool call_opt_p = false;
+
+ name = IDENTIFIER_POINTER (x);
+ if (strcmp (name, "reset") == 0)
+ {
+ struct cl_optimization *def
+ = TREE_OPTIMIZATION (optimization_default_node);
+ current_optimize_pragma = NULL_TREE;
+ optimization_current_node = optimization_default_node;
+ cl_optimization_restore (def);
+ call_opt_p = true;
+ }
+
+ else if (strcmp (name, "push") == 0)
+ VEC_safe_push (tree, gc, optimize_stack, current_optimize_pragma);
+
+ else if (strcmp (name, "pop") == 0)
+ {
+ int len = VEC_length (tree, optimize_stack);
+ if (len == 0)
+ {
+ GCC_BAD ("%<#pragma GCC optimize pop%> without a %<#pragma "
+ "GCC optimize push%>");
+ return;
+ }
+ else
+ {
+ VEC_truncate (tree, optimize_stack, len-1);
+ current_optimize_pragma
+ = ((len > 1)
+ ? VEC_last (tree, optimize_stack)
+ : NULL_TREE);
+
+ call_opt_p = true;
+ if (current_optimize_pragma)
+ {
+ bool ok_p
+ = parse_optimize_options (current_optimize_pragma, false);
+ gcc_assert (ok_p); /* should be parsed previously. */
+ optimization_current_node = build_optimization_node ();
+ }
+ else
+ {
+ struct cl_optimization *opt
+ = TREE_OPTIMIZATION (optimization_default_node);
+ optimization_current_node = optimization_default_node;
+ cl_optimization_restore (opt);
+ }
+ }
+ }
+
+ else
+ {
+ GCC_BAD ("%<#pragma GCC optimize%> is not a string or "
+ "push/pop/reset");
+ return;
+ }
+
+ token = pragma_lex (&x);
+ if (close_paren_needed_p)
+ {
+ if (token == CPP_CLOSE_PAREN)
+ token = pragma_lex (&x);
+ else
+ GCC_BAD ("%<#pragma GCC optimize ([push|pop|reset])%> does not "
+ "have a final %<)%>.");
+ }
+
+ if (token != CPP_EOF)
+ {
+ GCC_BAD ("%<#pragma GCC optimize [push|pop|reset]%> is badly "
+ "formed");
+ return;
+ }
+
+ if (call_opt_p &&
+ (optimization_previous_node != optimization_current_node))
+ c_cpp_builtins_optimize_pragma (parse_in,
+ optimization_previous_node,
+ optimization_current_node);
+
+ }
+
+ else if (token != CPP_STRING && token != CPP_NUMBER)
+ {
+ GCC_BAD ("%<#pragma GCC optimize%> is not a string, number, or "
+ "push/pop/reset");
+ return;
+ }
+
+ /* Strings/numbers are user options. */
+ else
+ {
+ tree args = NULL_TREE;
+
+ do
+ {
+ /* Build up the numbers/strings now as a list. */
+ if (token != CPP_STRING || TREE_STRING_LENGTH (x) > 0)
+ args = tree_cons (NULL_TREE, x, args);
+
+ token = pragma_lex (&x);
+ while (token == CPP_COMMA)
+ token = pragma_lex (&x);
+ }
+ while (token == CPP_STRING || token == CPP_NUMBER);
+
+ if (close_paren_needed_p)
+ {
+ if (token == CPP_CLOSE_PAREN)
+ token = pragma_lex (&x);
+ else
+ GCC_BAD ("%<#pragma GCC optimize (string [,string]...)%> does "
+ "not have a final %<)%>.");
+ }
+
+ if (token != CPP_EOF)
+ {
+ error ("#pragma GCC optimize string... is badly formed");
+ return;
+ }
+
+ /* put arguments in the order the user typed them. */
+ args = nreverse (args);
+
+ parse_optimize_options (args, false);
+ optimization_current_node = build_optimization_node ();
+ c_cpp_builtins_optimize_pragma (parse_in,
+ optimization_previous_node,
+ optimization_current_node);
+ }
+}
+
+/* Print a plain user-specified message. */
+
+static void
+handle_pragma_message (cpp_reader *ARG_UNUSED(dummy))
+{
+ enum cpp_ttype token;
+ tree x, message = 0;
+
+ token = pragma_lex (&x);
+ if (token == CPP_OPEN_PAREN)
+ {
+ token = pragma_lex (&x);
+ if (token == CPP_STRING)
+ message = x;
+ else
+ GCC_BAD ("expected a string after %<#pragma message%>");
+ if (pragma_lex (&x) != CPP_CLOSE_PAREN)
+ GCC_BAD ("malformed %<#pragma message%>, ignored");
+ }
+ else if (token == CPP_STRING)
+ message = x;
+ else
+ GCC_BAD ("expected a string after %<#pragma message%>");
+
+ gcc_assert (message);
+
+ if (pragma_lex (&x) != CPP_EOF)
+ warning (OPT_Wpragmas, "junk at end of %<#pragma message%>");
+
+ if (TREE_STRING_LENGTH (message) > 1)
+ inform ("#pragma message: %s", TREE_STRING_POINTER (message));
+}
+
/* A vector of registered pragma callbacks. */
DEF_VEC_O (pragma_handler);
@@ -1028,10 +1368,14 @@ init_pragma (void)
#endif
c_register_pragma ("GCC", "diagnostic", handle_pragma_diagnostic);
+ c_register_pragma ("GCC", "option", handle_pragma_option);
+ c_register_pragma ("GCC", "optimize", handle_pragma_optimize);
c_register_pragma_with_expansion (0, "redefine_extname", handle_pragma_redefine_extname);
c_register_pragma (0, "extern_prefix", handle_pragma_extern_prefix);
+ c_register_pragma_with_expansion (0, "message", handle_pragma_message);
+
#ifdef REGISTER_TARGET_PRAGMAS
REGISTER_TARGET_PRAGMAS ();
#endif
diff --git a/gcc/c-pretty-print.c b/gcc/c-pretty-print.c
index 4386c392c9f..67a466ba749 100644
--- a/gcc/c-pretty-print.c
+++ b/gcc/c-pretty-print.c
@@ -1852,14 +1852,13 @@ static void
pp_c_assignment_expression (c_pretty_printer *pp, tree e)
{
if (TREE_CODE (e) == MODIFY_EXPR
- || TREE_CODE (e) == GIMPLE_MODIFY_STMT
|| TREE_CODE (e) == INIT_EXPR)
{
- pp_c_unary_expression (pp, GENERIC_TREE_OPERAND (e, 0));
+ pp_c_unary_expression (pp, TREE_OPERAND (e, 0));
pp_c_whitespace (pp);
pp_equal (pp);
pp_space (pp);
- pp_c_expression (pp, GENERIC_TREE_OPERAND (e, 1));
+ pp_c_expression (pp, TREE_OPERAND (e, 1));
}
else
pp_c_conditional_expression (pp, e);
@@ -2007,7 +2006,6 @@ pp_c_expression (c_pretty_printer *pp, tree e)
break;
case MODIFY_EXPR:
- case GIMPLE_MODIFY_STMT:
case INIT_EXPR:
pp_assignment_expression (pp, e);
break;
diff --git a/gcc/c-semantics.c b/gcc/c-semantics.c
index c7933beea1b..62faee54ea8 100644
--- a/gcc/c-semantics.c
+++ b/gcc/c-semantics.c
@@ -43,7 +43,8 @@ along with GCC; see the file COPYING3. If not see
#include "timevar.h"
#include "predict.h"
#include "tree-inline.h"
-#include "tree-gimple.h"
+#include "gimple.h"
+#include "tree-iterator.h"
#include "langhooks.h"
/* Create an empty statement tree rooted at T. */
diff --git a/gcc/c-tree.h b/gcc/c-tree.h
index 14df0444377..d3e3695341c 100644
--- a/gcc/c-tree.h
+++ b/gcc/c-tree.h
@@ -563,7 +563,7 @@ extern tree c_cast_expr (struct c_type_name *, tree);
extern tree build_c_cast (tree, tree);
extern void store_init_value (tree, tree);
extern void error_init (const char *);
-extern void pedwarn_init (const char *);
+extern void pedwarn_init (int opt, const char *);
extern void maybe_warn_string_init (tree, struct c_expr);
extern void start_init (tree, tree, int);
extern void finish_init (void);
@@ -640,7 +640,7 @@ extern void c_write_global_declarations (void);
#define ATTRIBUTE_GCC_CDIAG(m, n) ATTRIBUTE_NONNULL(m)
#endif
-extern void pedwarn_c90 (const char *, ...) ATTRIBUTE_GCC_CDIAG(1,2);
-extern void pedwarn_c99 (const char *, ...) ATTRIBUTE_GCC_CDIAG(1,2);
+extern void pedwarn_c90 (int opt, const char *, ...) ATTRIBUTE_GCC_CDIAG(2,3);
+extern void pedwarn_c99 (int opt, const char *, ...) ATTRIBUTE_GCC_CDIAG(2,3);
#endif /* ! GCC_C_TREE_H */
diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c
index 6b7594e6a26..160229ad8b8 100644
--- a/gcc/c-typeck.c
+++ b/gcc/c-typeck.c
@@ -42,7 +42,7 @@ along with GCC; see the file COPYING3. If not see
#include "ggc.h"
#include "target.h"
#include "tree-iterator.h"
-#include "tree-gimple.h"
+#include "gimple.h"
#include "tree-flow.h"
/* Possible cases of implicit bad conversions. Used to select
@@ -470,8 +470,8 @@ composite_type (tree t1, tree t2)
{
TREE_VALUE (n) = composite_type (TREE_TYPE (memb),
TREE_VALUE (p2));
- if (pedantic)
- pedwarn ("function types not truly compatible in ISO C");
+ pedwarn (OPT_pedantic,
+ "function types not truly compatible in ISO C");
goto parm_done;
}
}
@@ -495,8 +495,8 @@ composite_type (tree t1, tree t2)
{
TREE_VALUE (n) = composite_type (TREE_TYPE (memb),
TREE_VALUE (p1));
- if (pedantic)
- pedwarn ("function types not truly compatible in ISO C");
+ pedwarn (OPT_pedantic,
+ "function types not truly compatible in ISO C");
goto parm_done;
}
}
@@ -1039,8 +1039,8 @@ comp_target_types (tree ttl, tree ttr)
mvr = TYPE_MAIN_VARIANT (mvr);
val = comptypes (mvl, mvr);
- if (val == 2 && pedantic)
- pedwarn ("types are not quite compatible");
+ if (val == 2)
+ pedwarn (OPT_pedantic, "types are not quite compatible");
return val;
}
@@ -1363,7 +1363,7 @@ function_types_compatible_p (const_tree f1, const_tree f2)
/* 'volatile' qualifiers on a function's return type used to mean
the function is noreturn. */
if (TYPE_VOLATILE (ret1) != TYPE_VOLATILE (ret2))
- pedwarn ("function return types not compatible due to %<volatile%>");
+ pedwarn (0, "function return types not compatible due to %<volatile%>");
if (TYPE_VOLATILE (ret1))
ret1 = build_qualified_type (TYPE_MAIN_VARIANT (ret1),
TYPE_QUALS (ret1) & ~TYPE_QUAL_VOLATILE);
@@ -2115,9 +2115,11 @@ build_array_ref (tree array, tree index)
while (TREE_CODE (foo) == COMPONENT_REF)
foo = TREE_OPERAND (foo, 0);
if (TREE_CODE (foo) == VAR_DECL && C_DECL_REGISTER (foo))
- pedwarn ("ISO C forbids subscripting %<register%> array");
+ pedwarn (OPT_pedantic,
+ "ISO C forbids subscripting %<register%> array");
else if (!flag_isoc99 && !lvalue_p (foo))
- pedwarn ("ISO C90 forbids subscripting non-lvalue array");
+ pedwarn (OPT_pedantic,
+ "ISO C90 forbids subscripting non-lvalue array");
}
type = TREE_TYPE (TREE_TYPE (array));
@@ -2191,8 +2193,6 @@ build_external_ref (tree id, int fun, location_t loc)
/* Recursive call does not count as usage. */
if (ref != current_function_decl)
{
- if (!skip_evaluation)
- assemble_external (ref);
TREE_USED (ref) = 1;
}
@@ -2233,8 +2233,8 @@ build_external_ref (tree id, int fun, location_t loc)
&& (TREE_CODE (ref) != VAR_DECL || TREE_STATIC (ref))
&& ! TREE_PUBLIC (ref)
&& DECL_CONTEXT (ref) != current_function_decl)
- pedwarn ("%H%qD is static but used in inline function %qD "
- "which is not static", &loc, ref, current_function_decl);
+ pedwarn (0, "%H%qD is static but used in inline function %qD "
+ "which is not static", &loc, ref, current_function_decl);
return ref;
}
@@ -2458,7 +2458,7 @@ build_function_call (tree function, tree params)
if (TREE_CONSTANT (result)
&& (name == NULL_TREE
|| strncmp (IDENTIFIER_POINTER (name), "__builtin_", 10) != 0))
- pedwarn_init ("initializer element is not constant");
+ pedwarn_init (0, "initializer element is not constant");
}
else
result = fold_build_call_array (TREE_TYPE (fntype),
@@ -2802,13 +2802,12 @@ pointer_diff (tree op0, tree op1)
tree con0, con1, lit0, lit1;
tree orig_op1 = op1;
- if (pedantic || warn_pointer_arith)
- {
- if (TREE_CODE (target_type) == VOID_TYPE)
- pedwarn ("pointer of type %<void *%> used in subtraction");
- if (TREE_CODE (target_type) == FUNCTION_TYPE)
- pedwarn ("pointer to a function used in subtraction");
- }
+ if (TREE_CODE (target_type) == VOID_TYPE)
+ pedwarn (pedantic ? OPT_pedantic : OPT_Wpointer_arith,
+ "pointer of type %<void *%> used in subtraction");
+ if (TREE_CODE (target_type) == FUNCTION_TYPE)
+ pedwarn (pedantic ? OPT_pedantic : OPT_Wpointer_arith,
+ "pointer to a function used in subtraction");
/* If the conversion to ptrdiff_type does anything like widening or
converting a partial to an integral mode, we get a convert_expression
@@ -2950,8 +2949,8 @@ build_unary_op (enum tree_code code, tree xarg, int flag)
else if (typecode == COMPLEX_TYPE)
{
code = CONJ_EXPR;
- if (pedantic)
- pedwarn ("ISO C does not support %<~%> for complex conjugation");
+ pedwarn (OPT_pedantic,
+ "ISO C does not support %<~%> for complex conjugation");
if (!noconvert)
arg = default_conversion (arg);
}
@@ -3022,9 +3021,8 @@ build_unary_op (enum tree_code code, tree xarg, int flag)
{
tree real, imag;
- if (pedantic)
- pedwarn ("ISO C does not support %<++%> and %<--%>"
- " on complex types");
+ pedwarn (OPT_pedantic, "ISO C does not support %<++%> and %<--%>"
+ " on complex types");
arg = stabilize_reference (arg);
real = build_unary_op (REALPART_EXPR, arg, 1);
@@ -3069,14 +3067,15 @@ build_unary_op (enum tree_code code, tree xarg, int flag)
else
error ("decrement of pointer to unknown structure");
}
- else if ((pedantic || warn_pointer_arith)
- && (TREE_CODE (TREE_TYPE (result_type)) == FUNCTION_TYPE
- || TREE_CODE (TREE_TYPE (result_type)) == VOID_TYPE))
+ else if (TREE_CODE (TREE_TYPE (result_type)) == FUNCTION_TYPE
+ || TREE_CODE (TREE_TYPE (result_type)) == VOID_TYPE)
{
if (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR)
- pedwarn ("wrong type argument to increment");
+ pedwarn (pedantic ? OPT_pedantic : OPT_Wpointer_arith,
+ "wrong type argument to increment");
else
- pedwarn ("wrong type argument to decrement");
+ pedwarn (pedantic ? OPT_pedantic : OPT_Wpointer_arith,
+ "wrong type argument to decrement");
}
inc = c_size_in_bytes (TREE_TYPE (result_type));
@@ -3351,7 +3350,7 @@ c_mark_addressable (tree exp)
("global register variable %qD used in nested function", x);
return false;
}
- pedwarn ("register variable %qD used in nested function", x);
+ pedwarn (0, "register variable %qD used in nested function", x);
}
else if (C_DECL_REGISTER (x))
{
@@ -3458,8 +3457,9 @@ build_conditional_expr (tree ifexp, tree op1, tree op2)
}
else if (code1 == VOID_TYPE || code2 == VOID_TYPE)
{
- if (pedantic && (code1 != VOID_TYPE || code2 != VOID_TYPE))
- pedwarn ("ISO C forbids conditional expr with only one void side");
+ if (code1 != VOID_TYPE || code2 != VOID_TYPE)
+ pedwarn (OPT_pedantic,
+ "ISO C forbids conditional expr with only one void side");
result_type = void_type_node;
}
else if (code1 == POINTER_TYPE && code2 == POINTER_TYPE)
@@ -3472,30 +3472,30 @@ build_conditional_expr (tree ifexp, tree op1, tree op2)
result_type = qualify_type (type1, type2);
else if (VOID_TYPE_P (TREE_TYPE (type1)))
{
- if (pedantic && TREE_CODE (TREE_TYPE (type2)) == FUNCTION_TYPE)
- pedwarn ("ISO C forbids conditional expr between "
+ if (TREE_CODE (TREE_TYPE (type2)) == FUNCTION_TYPE)
+ pedwarn (OPT_pedantic, "ISO C forbids conditional expr between "
"%<void *%> and function pointer");
result_type = build_pointer_type (qualify_type (TREE_TYPE (type1),
TREE_TYPE (type2)));
}
else if (VOID_TYPE_P (TREE_TYPE (type2)))
{
- if (pedantic && TREE_CODE (TREE_TYPE (type1)) == FUNCTION_TYPE)
- pedwarn ("ISO C forbids conditional expr between "
+ if (TREE_CODE (TREE_TYPE (type1)) == FUNCTION_TYPE)
+ pedwarn (OPT_pedantic, "ISO C forbids conditional expr between "
"%<void *%> and function pointer");
result_type = build_pointer_type (qualify_type (TREE_TYPE (type2),
TREE_TYPE (type1)));
}
else
{
- pedwarn ("pointer type mismatch in conditional expression");
+ pedwarn (0, "pointer type mismatch in conditional expression");
result_type = build_pointer_type (void_type_node);
}
}
else if (code1 == POINTER_TYPE && code2 == INTEGER_TYPE)
{
if (!null_pointer_constant_p (orig_op2))
- pedwarn ("pointer/integer type mismatch in conditional expression");
+ pedwarn (0, "pointer/integer type mismatch in conditional expression");
else
{
op2 = null_pointer_node;
@@ -3505,7 +3505,7 @@ build_conditional_expr (tree ifexp, tree op1, tree op2)
else if (code2 == POINTER_TYPE && code1 == INTEGER_TYPE)
{
if (!null_pointer_constant_p (orig_op1))
- pedwarn ("pointer/integer type mismatch in conditional expression");
+ pedwarn (0, "pointer/integer type mismatch in conditional expression");
else
{
op1 = null_pointer_node;
@@ -3616,12 +3616,10 @@ build_c_cast (tree type, tree expr)
if (type == TYPE_MAIN_VARIANT (TREE_TYPE (value)))
{
- if (pedantic)
- {
- if (TREE_CODE (type) == RECORD_TYPE
- || TREE_CODE (type) == UNION_TYPE)
- pedwarn ("ISO C forbids casting nonscalar to the same type");
- }
+ if (TREE_CODE (type) == RECORD_TYPE
+ || TREE_CODE (type) == UNION_TYPE)
+ pedwarn (OPT_pedantic,
+ "ISO C forbids casting nonscalar to the same type");
}
else if (TREE_CODE (type) == UNION_TYPE)
{
@@ -3637,8 +3635,7 @@ build_c_cast (tree type, tree expr)
{
tree t;
- if (pedantic)
- pedwarn ("ISO C forbids casts to union type");
+ pedwarn (OPT_pedantic, "ISO C forbids casts to union type");
t = digest_init (type,
build_constructor_single (type, field, value),
true, 0);
@@ -3749,7 +3746,8 @@ build_c_cast (tree type, tree expr)
&& TREE_CODE (otype) == POINTER_TYPE
&& TREE_CODE (TREE_TYPE (otype)) == FUNCTION_TYPE
&& TREE_CODE (TREE_TYPE (type)) != FUNCTION_TYPE)
- pedwarn ("ISO C forbids conversion of function pointer to object pointer type");
+ pedwarn (OPT_pedantic, "ISO C forbids "
+ "conversion of function pointer to object pointer type");
if (pedantic
&& TREE_CODE (type) == POINTER_TYPE
@@ -3757,7 +3755,8 @@ build_c_cast (tree type, tree expr)
&& TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE
&& TREE_CODE (TREE_TYPE (otype)) != FUNCTION_TYPE
&& !null_pointer_constant_p (value))
- pedwarn ("ISO C forbids conversion of object pointer to function pointer type");
+ pedwarn (OPT_pedantic, "ISO C forbids "
+ "conversion of object pointer to function pointer type");
ovalue = value;
value = convert (type, value);
@@ -3953,19 +3952,19 @@ convert_for_assignment (tree type, tree rhs, enum impl_conv errtype,
switch (errtype) \
{ \
case ic_argpass: \
- pedwarn (AR, parmnum, rname); \
+ pedwarn (0, AR, parmnum, rname); \
break; \
case ic_argpass_nonproto: \
- warning (0, AR, parmnum, rname); \
+ warning (0, AR, parmnum, rname); \
break; \
case ic_assign: \
- pedwarn (AS); \
+ pedwarn (0, AS); \
break; \
case ic_init: \
- pedwarn (IN); \
+ pedwarn (0, IN); \
break; \
case ic_return: \
- pedwarn (RE); \
+ pedwarn (0, RE); \
break; \
default: \
gcc_unreachable (); \
@@ -4172,8 +4171,9 @@ convert_for_assignment (tree type, tree rhs, enum impl_conv errtype,
memb = marginal_memb;
}
- if (pedantic && (!fundecl || !DECL_IN_SYSTEM_HEADER (fundecl)))
- pedwarn ("ISO C prohibits argument conversion to union type");
+ if (!fundecl || !DECL_IN_SYSTEM_HEADER (fundecl))
+ pedwarn (OPT_pedantic,
+ "ISO C prohibits argument conversion to union type");
rhs = fold_convert (TREE_TYPE (memb), rhs);
return build_constructor_single (type, memb, rhs);
@@ -4618,19 +4618,20 @@ error_init (const char *msgid)
error ("(near initialization for %qs)", ofwhat);
}
-/* Issue a pedantic warning for a bad initializer component.
- MSGID identifies the message.
- The component name is taken from the spelling stack. */
+/* Issue a pedantic warning for a bad initializer component. OPT is
+ the option OPT_* (from options.h) controlling this warning or 0 if
+ it is unconditionally given. MSGID identifies the message. The
+ component name is taken from the spelling stack. */
void
-pedwarn_init (const char *msgid)
+pedwarn_init (int opt, const char *msgid)
{
char *ofwhat;
- pedwarn ("%s", _(msgid));
+ pedwarn (opt, "%s", _(msgid));
ofwhat = print_spelling ((char *) alloca (spelling_length () + 1));
if (*ofwhat)
- pedwarn ("(near initialization for %qs)", ofwhat);
+ pedwarn (opt, "(near initialization for %qs)", ofwhat);
}
/* Issue a warning for a bad initializer component.
@@ -4661,7 +4662,8 @@ maybe_warn_string_init (tree type, struct c_expr expr)
&& TREE_CODE (type) == ARRAY_TYPE
&& TREE_CODE (expr.value) == STRING_CST
&& expr.original_code != STRING_CST)
- pedwarn_init ("array initialized from parenthesized string constant");
+ pedwarn_init (OPT_pedantic,
+ "array initialized from parenthesized string constant");
}
/* Digest the parser output INIT as an initializer for type TYPE.
@@ -4704,48 +4706,57 @@ digest_init (tree type, tree init, bool strict_string, int require_constant)
|| typ1 == signed_char_type_node
|| typ1 == unsigned_char_type_node);
bool wchar_array = !!comptypes (typ1, wchar_type_node);
- if (char_array || wchar_array)
+ bool char16_array = !!comptypes (typ1, char16_type_node);
+ bool char32_array = !!comptypes (typ1, char32_type_node);
+
+ if (char_array || wchar_array || char16_array || char32_array)
{
struct c_expr expr;
- bool char_string;
+ tree typ2 = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (inside_init)));
expr.value = inside_init;
expr.original_code = (strict_string ? STRING_CST : ERROR_MARK);
maybe_warn_string_init (type, expr);
- char_string
- = (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (inside_init)))
- == char_type_node);
-
if (comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (inside_init)),
TYPE_MAIN_VARIANT (type)))
return inside_init;
- if (!wchar_array && !char_string)
+ if (char_array)
{
- error_init ("char-array initialized from wide string");
- return error_mark_node;
+ if (typ2 != char_type_node)
+ {
+ error_init ("char-array initialized from wide string");
+ return error_mark_node;
+ }
}
- if (char_string && !char_array)
+ else
{
- error_init ("wchar_t-array initialized from non-wide string");
- return error_mark_node;
+ if (typ2 == char_type_node)
+ {
+ error_init ("wide character array initialized from non-wide "
+ "string");
+ return error_mark_node;
+ }
+ else if (!comptypes(typ1, typ2))
+ {
+ error_init ("wide character array initialized from "
+ "incompatible wide string");
+ return error_mark_node;
+ }
}
TREE_TYPE (inside_init) = type;
if (TYPE_DOMAIN (type) != 0
&& TYPE_SIZE (type) != 0
&& TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
- /* Subtract 1 (or sizeof (wchar_t))
+ /* Subtract the size of a single (possibly wide) character
because it's ok to ignore the terminating null char
that is counted in the length of the constant. */
&& 0 > compare_tree_int (TYPE_SIZE_UNIT (type),
TREE_STRING_LENGTH (inside_init)
- - ((TYPE_PRECISION (typ1)
- != TYPE_PRECISION (char_type_node))
- ? (TYPE_PRECISION (wchar_type_node)
- / BITS_PER_UNIT)
- : 1)))
- pedwarn_init ("initializer-string for array of chars is too long");
+ - (TYPE_PRECISION (typ1)
+ / BITS_PER_UNIT)))
+ pedwarn_init (0, "initializer-string for array of chars is too long");
return inside_init;
}
@@ -4860,7 +4871,7 @@ digest_init (tree type, tree init, bool strict_string, int require_constant)
if (inside_init == error_mark_node)
error_init ("initializer element is not constant");
else
- pedwarn_init ("initializer element is not constant");
+ pedwarn_init (OPT_pedantic, "initializer element is not constant");
if (flag_pedantic_errors)
inside_init = error_mark_node;
}
@@ -5533,8 +5544,8 @@ pop_init_level (int implicit)
if (constructor_depth > 2)
error_init ("initialization of flexible array member in a nested context");
- else if (pedantic)
- pedwarn_init ("initialization of a flexible array member");
+ else
+ pedwarn_init (OPT_pedantic, "initialization of a flexible array member");
/* We have already issued an error message for the existence
of a flexible array member not at the end of the structure.
@@ -6092,15 +6103,7 @@ set_nonincremental_init_from_string (tree str)
gcc_assert (TREE_CODE (constructor_type) == ARRAY_TYPE);
- if (TYPE_PRECISION (TREE_TYPE (TREE_TYPE (str)))
- == TYPE_PRECISION (char_type_node))
- wchar_bytes = 1;
- else
- {
- gcc_assert (TYPE_PRECISION (TREE_TYPE (TREE_TYPE (str)))
- == TYPE_PRECISION (wchar_type_node));
- wchar_bytes = TYPE_PRECISION (wchar_type_node) / BITS_PER_UNIT;
- }
+ wchar_bytes = TYPE_PRECISION (TREE_TYPE (TREE_TYPE (str))) / BITS_PER_UNIT;
charwidth = TYPE_PRECISION (char_type_node);
type = TREE_TYPE (constructor_type);
p = TREE_STRING_POINTER (str);
@@ -6279,7 +6282,7 @@ output_init_element (tree value, bool strict_string, tree type, tree field,
value = error_mark_node;
}
else if (require_constant_elements)
- pedwarn ("initializer element is not computable at load time");
+ pedwarn (0, "initializer element is not computable at load time");
}
/* If this field is empty (and not at the end of structure),
@@ -6606,7 +6609,7 @@ process_init_element (struct c_expr value)
if (constructor_fields == 0)
{
- pedwarn_init ("excess elements in struct initializer");
+ pedwarn_init (0, "excess elements in struct initializer");
break;
}
@@ -6689,7 +6692,7 @@ process_init_element (struct c_expr value)
if (constructor_fields == 0)
{
- pedwarn_init ("excess elements in union initializer");
+ pedwarn_init (0, "excess elements in union initializer");
break;
}
@@ -6776,7 +6779,7 @@ process_init_element (struct c_expr value)
&& (tree_int_cst_lt (constructor_max_index, constructor_index)
|| integer_all_onesp (constructor_max_index)))
{
- pedwarn_init ("excess elements in array initializer");
+ pedwarn_init (0, "excess elements in array initializer");
break;
}
@@ -6806,7 +6809,7 @@ process_init_element (struct c_expr value)
always have a fixed size derived from their type. */
if (tree_int_cst_lt (constructor_max_index, constructor_index))
{
- pedwarn_init ("excess elements in vector initializer");
+ pedwarn_init (0, "excess elements in vector initializer");
break;
}
@@ -6830,7 +6833,7 @@ process_init_element (struct c_expr value)
else if (constructor_type != error_mark_node
&& constructor_fields == 0)
{
- pedwarn_init ("excess elements in scalar initializer");
+ pedwarn_init (0, "excess elements in scalar initializer");
break;
}
else
@@ -7061,8 +7064,7 @@ c_finish_goto_label (tree label)
tree
c_finish_goto_ptr (tree expr)
{
- if (pedantic)
- pedwarn ("ISO C forbids %<goto *expr;%>");
+ pedwarn (OPT_pedantic, "ISO C forbids %<goto *expr;%>");
expr = convert (ptr_type_node, expr);
return add_stmt (build1 (GOTO_EXPR, void_type_node, expr));
}
@@ -7085,7 +7087,8 @@ c_finish_return (tree retval)
if ((warn_return_type || flag_isoc99)
&& valtype != 0 && TREE_CODE (valtype) != VOID_TYPE)
{
- pedwarn_c99 ("%<return%> with no value, in "
+ pedwarn_c99 (flag_isoc99 ? 0 : OPT_Wreturn_type,
+ "%<return%> with no value, in "
"function returning non-void");
no_warning = true;
}
@@ -7094,9 +7097,10 @@ c_finish_return (tree retval)
{
current_function_returns_null = 1;
if (TREE_CODE (TREE_TYPE (retval)) != VOID_TYPE)
- pedwarn ("%<return%> with a value, in function returning void");
- else if (pedantic)
- pedwarn ("ISO C forbids %<return%> with expression, in function returning void");
+ pedwarn (0, "%<return%> with a value, in function returning void");
+ else
+ pedwarn (OPT_pedantic, "ISO C forbids "
+ "%<return%> with expression, in function returning void");
}
else
{
@@ -8166,20 +8170,20 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
whose value is 0 but which isn't a valid null ptr const. */
if (pedantic && !null_pointer_constant_p (orig_op0)
&& TREE_CODE (tt1) == FUNCTION_TYPE)
- pedwarn ("ISO C forbids comparison of %<void *%>"
- " with function pointer");
+ pedwarn (OPT_pedantic, "ISO C forbids "
+ "comparison of %<void *%> with function pointer");
}
else if (VOID_TYPE_P (tt1))
{
if (pedantic && !null_pointer_constant_p (orig_op1)
&& TREE_CODE (tt0) == FUNCTION_TYPE)
- pedwarn ("ISO C forbids comparison of %<void *%>"
- " with function pointer");
+ pedwarn (OPT_pedantic, "ISO C forbids "
+ "comparison of %<void *%> with function pointer");
}
else
/* Avoid warning about the volatile ObjC EH puts on decls. */
if (!objc_ok)
- pedwarn ("comparison of distinct pointer types lacks a cast");
+ pedwarn (0, "comparison of distinct pointer types lacks a cast");
if (result_type == NULL_TREE)
result_type = ptr_type_node;
@@ -8203,12 +8207,12 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
{
result_type = type0;
- pedwarn ("comparison between pointer and integer");
+ pedwarn (0, "comparison between pointer and integer");
}
else if (code0 == INTEGER_TYPE && code1 == POINTER_TYPE)
{
result_type = type1;
- pedwarn ("comparison between pointer and integer");
+ pedwarn (0, "comparison between pointer and integer");
}
break;
@@ -8229,38 +8233,42 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
result_type = common_pointer_type (type0, type1);
if (!COMPLETE_TYPE_P (TREE_TYPE (type0))
!= !COMPLETE_TYPE_P (TREE_TYPE (type1)))
- pedwarn ("comparison of complete and incomplete pointers");
- else if (pedantic
- && TREE_CODE (TREE_TYPE (type0)) == FUNCTION_TYPE)
- pedwarn ("ISO C forbids ordered comparisons of pointers to functions");
+ pedwarn (0, "comparison of complete and incomplete pointers");
+ else if (TREE_CODE (TREE_TYPE (type0)) == FUNCTION_TYPE)
+ pedwarn (OPT_pedantic, "ISO C forbids "
+ "ordered comparisons of pointers to functions");
}
else
{
result_type = ptr_type_node;
- pedwarn ("comparison of distinct pointer types lacks a cast");
+ pedwarn (0, "comparison of distinct pointer types lacks a cast");
}
}
else if (code0 == POINTER_TYPE && null_pointer_constant_p (orig_op1))
{
result_type = type0;
- if (pedantic || extra_warnings)
- pedwarn ("ordered comparison of pointer with integer zero");
+ if (pedantic)
+ pedwarn (OPT_pedantic,
+ "ordered comparison of pointer with integer zero");
+ else if (extra_warnings)
+ warning (OPT_Wextra,
+ "ordered comparison of pointer with integer zero");
}
else if (code1 == POINTER_TYPE && null_pointer_constant_p (orig_op0))
{
result_type = type1;
- if (pedantic)
- pedwarn ("ordered comparison of pointer with integer zero");
+ pedwarn (OPT_pedantic,
+ "ordered comparison of pointer with integer zero");
}
else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
{
result_type = type0;
- pedwarn ("comparison between pointer and integer");
+ pedwarn (0, "comparison between pointer and integer");
}
else if (code0 == INTEGER_TYPE && code1 == POINTER_TYPE)
{
result_type = type1;
- pedwarn ("comparison between pointer and integer");
+ pedwarn (0, "comparison between pointer and integer");
}
break;
diff --git a/gcc/caller-save.c b/gcc/caller-save.c
index a1a52c65b41..e5ff04f08f1 100644
--- a/gcc/caller-save.c
+++ b/gcc/caller-save.c
@@ -37,7 +37,6 @@ along with GCC; see the file COPYING3. If not see
#include "addresses.h"
#include "output.h"
#include "cfgloop.h"
-#include "ira.h"
#include "df.h"
#include "ggc.h"
@@ -2359,7 +2358,7 @@ insert_restore (struct insn_chain *chain, int before_p, int regno,
rtx pat = NULL_RTX;
int code;
unsigned int numregs = 0;
- struct insn_chain *new;
+ struct insn_chain *new_chain;
rtx mem;
/* A common failure mode if register status is not correct in the
@@ -2414,19 +2413,19 @@ insert_restore (struct insn_chain *chain, int before_p, int regno,
gen_rtx_REG (GET_MODE (mem),
regno), mem);
code = reg_restore_code (regno, GET_MODE (mem));
- new = insert_one_insn (chain, before_p, code, pat);
- new->saved_pseudo_regno = save_pseudo[regno];
+ new_chain = insert_one_insn (chain, before_p, code, pat);
+ new_chain->saved_pseudo_regno = save_pseudo[regno];
if (dump_file != NULL)
fprintf (dump_file, "inserting restore insn %u for pseudo %d %s %u\n",
- INSN_UID (new->insn), save_pseudo[regno],
+ INSN_UID (new_chain->insn), save_pseudo[regno],
before_p ? "before" : "after", INSN_UID (chain->insn));
/* Clear status for all registers we restored. */
for (k = 0; k < i; k++)
{
CLEAR_HARD_REG_BIT (hard_regs_saved, regno + k);
- SET_REGNO_REG_SET (&new->dead_or_set, regno + k);
+ SET_REGNO_REG_SET (&new_chain->dead_or_set, regno + k);
n_regs_saved--;
}
@@ -2446,7 +2445,7 @@ insert_save (struct insn_chain *chain, int before_p, int regno,
rtx pat = NULL_RTX;
int code;
unsigned int numregs = 0;
- struct insn_chain *new;
+ struct insn_chain *new_chain;
rtx mem;
/* A common failure mode if register status is not correct in the
@@ -2500,19 +2499,19 @@ insert_save (struct insn_chain *chain, int before_p, int regno,
gen_rtx_REG (GET_MODE (mem),
regno));
code = reg_save_code (regno, GET_MODE (mem));
- new = insert_one_insn (chain, before_p, code, pat);
- new->saved_pseudo_regno = save_pseudo[regno];
+ new_chain = insert_one_insn (chain, before_p, code, pat);
+ new_chain->saved_pseudo_regno = save_pseudo[regno];
if (dump_file != NULL)
fprintf (dump_file, "inserting save insn %u for pseudo %d %s %u\n",
- INSN_UID (new->insn), save_pseudo[regno],
+ INSN_UID (new_chain->insn), save_pseudo[regno],
before_p ? "before" : "after", INSN_UID (chain->insn));
/* Set hard_regs_saved and dead_or_set for all the registers we saved. */
for (k = 0; k < numregs; k++)
{
SET_HARD_REG_BIT (hard_regs_saved, regno + k);
- SET_REGNO_REG_SET (&new->dead_or_set, regno + k);
+ SET_REGNO_REG_SET (&new_chain->dead_or_set, regno + k);
n_regs_saved++;
}
@@ -2525,7 +2524,7 @@ static struct insn_chain *
insert_one_insn (struct insn_chain *chain, int before_p, int code, rtx pat)
{
rtx insn = chain->insn;
- struct insn_chain *new;
+ struct insn_chain *new_chain;
#ifdef HAVE_cc0
/* If INSN references CC0, put our insns in front of the insn that sets
@@ -2540,23 +2539,23 @@ insert_one_insn (struct insn_chain *chain, int before_p, int code, rtx pat)
chain = chain->prev, insn = chain->insn;
#endif
- new = new_insn_chain ();
+ new_chain = new_insn_chain ();
if (before_p)
{
rtx link;
- new->prev = chain->prev;
- if (new->prev != 0)
- new->prev->next = new;
+ new_chain->prev = chain->prev;
+ if (new_chain->prev != 0)
+ new_chain->prev->next = new_chain;
else
- reload_insn_chain = new;
+ reload_insn_chain = new_chain;
- chain->prev = new;
- new->next = chain;
- new->insn = emit_insn_before (pat, insn);
+ chain->prev = new_chain;
+ new_chain->next = chain;
+ new_chain->insn = emit_insn_before (pat, insn);
/* ??? It would be nice if we could exclude the already / still saved
registers from the live sets. */
- COPY_REG_SET (&new->live_throughout, &chain->live_throughout);
+ COPY_REG_SET (&new_chain->live_throughout, &chain->live_throughout);
/* Registers that die in CHAIN->INSN still live in the new insn. */
for (link = REG_NOTES (chain->insn); link; link = XEXP (link, 1))
{
@@ -2573,7 +2572,7 @@ insert_one_insn (struct insn_chain *chain, int before_p, int code, rtx pat)
continue;
for (i = hard_regno_nregs[regno][GET_MODE (reg)] - 1;
i >= 0; i--)
- SET_REGNO_REG_SET (&new->live_throughout, regno + i);
+ SET_REGNO_REG_SET (&new_chain->live_throughout, regno + i);
}
}
@@ -2601,49 +2600,49 @@ insert_one_insn (struct insn_chain *chain, int before_p, int code, rtx pat)
for (i = hard_regno_nregs[regno][GET_MODE (reg)] - 1;
i >= 0; i--)
- SET_REGNO_REG_SET (&new->live_throughout, regno + i);
+ SET_REGNO_REG_SET (&new_chain->live_throughout, regno + i);
}
}
}
}
- CLEAR_REG_SET (&new->dead_or_set);
+ CLEAR_REG_SET (&new_chain->dead_or_set);
if (chain->insn == BB_HEAD (BASIC_BLOCK (chain->block)))
- BB_HEAD (BASIC_BLOCK (chain->block)) = new->insn;
+ BB_HEAD (BASIC_BLOCK (chain->block)) = new_chain->insn;
}
else
{
- new->next = chain->next;
- if (new->next != 0)
- new->next->prev = new;
- chain->next = new;
- new->prev = chain;
+ new_chain->next = chain->next;
+ if (new_chain->next != 0)
+ new_chain->next->prev = new_chain;
+ chain->next = new_chain;
+ new_chain->prev = chain;
if (GET_CODE (insn) != CODE_LABEL)
- new->insn = emit_insn_after (pat, insn);
+ new_chain->insn = emit_insn_after (pat, insn);
else
{
/* Put the insn after bb note in a empty basic block. */
gcc_assert (NEXT_INSN (insn) && NOTE_P (NEXT_INSN (insn)));
- new->insn = emit_insn_after (pat, NEXT_INSN (insn));
+ new_chain->insn = emit_insn_after (pat, NEXT_INSN (insn));
}
/* ??? It would be nice if we could exclude the already / still saved
registers from the live sets, and observe REG_UNUSED notes. */
- COPY_REG_SET (&new->live_throughout, &chain->live_throughout);
+ COPY_REG_SET (&new_chain->live_throughout, &chain->live_throughout);
/* Registers that are set in CHAIN->INSN live in the new insn.
(Unless there is a REG_UNUSED note for them, but we don't
look for them here.) */
if (INSN_P (chain->insn))
note_stores (PATTERN (chain->insn), add_stored_regs,
- &new->live_throughout);
- CLEAR_REG_SET (&new->dead_or_set);
+ &new_chain->live_throughout);
+ CLEAR_REG_SET (&new_chain->dead_or_set);
if (chain->insn == BB_END (BASIC_BLOCK (chain->block)))
- BB_END (BASIC_BLOCK (chain->block)) = new->insn;
+ BB_END (BASIC_BLOCK (chain->block)) = new_chain->insn;
}
- new->block = chain->block;
- new->is_caller_save_insn = 1;
+ new_chain->block = chain->block;
+ new_chain->is_caller_save_insn = 1;
- INSN_CODE (new->insn) = code;
- return new;
+ INSN_CODE (new_chain->insn) = code;
+ return new_chain;
}
#include "gt-caller-save.h"
diff --git a/gcc/calls.c b/gcc/calls.c
index a4470fa1477..71bdf8c003b 100644
--- a/gcc/calls.c
+++ b/gcc/calls.c
@@ -25,6 +25,7 @@ along with GCC; see the file COPYING3. If not see
#include "tm.h"
#include "rtl.h"
#include "tree.h"
+#include "gimple.h"
#include "flags.h"
#include "expr.h"
#include "optabs.h"
@@ -41,6 +42,7 @@ along with GCC; see the file COPYING3. If not see
#include "cgraph.h"
#include "except.h"
#include "dbgcnt.h"
+#include "tree-flow.h"
/* Like PREFERRED_STACK_BOUNDARY but in units of bytes, not bits. */
#define STACK_BYTES (PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT)
@@ -380,7 +382,7 @@ emit_call_1 (rtx funexp, tree fntree, tree fndecl ATTRIBUTE_UNUSED,
add_reg_note (call_insn, REG_EH_REGION, const0_rtx);
else
{
- int rn = lookup_stmt_eh_region (fntree);
+ int rn = lookup_expr_eh_region (fntree);
/* If rn < 0, then either (1) tree-ssa not used or (2) doesn't
throw, which we already took care of. */
@@ -542,7 +544,26 @@ setjmp_call_p (const_tree fndecl)
return special_function_p (fndecl, 0) & ECF_RETURNS_TWICE;
}
+
+/* Return true if STMT is an alloca call. */
+
+bool
+gimple_alloca_call_p (const_gimple stmt)
+{
+ tree fndecl;
+
+ if (!is_gimple_call (stmt))
+ return false;
+
+ fndecl = gimple_call_fndecl (stmt);
+ if (fndecl && (special_function_p (fndecl, 0) & ECF_MAY_BE_ALLOCA))
+ return true;
+
+ return false;
+}
+
/* Return true when exp contains alloca call. */
+
bool
alloca_call_p (const_tree exp)
{
@@ -2251,7 +2272,7 @@ expand_call (tree exp, rtx target, int ignore)
if (currently_expanding_call++ != 0
|| !flag_optimize_sibling_calls
|| args_size.var
- || lookup_stmt_eh_region (exp) >= 0
+ || lookup_expr_eh_region (exp) >= 0
|| dbg_cnt (tail_call) == false)
try_tail_call = 0;
@@ -3229,7 +3250,7 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value,
#ifdef REG_PARM_STACK_SPACE
/* Define the boundary of the register parm stack space that needs to be
save, if any. */
- int low_to_save, high_to_save;
+ int low_to_save = 0, high_to_save = 0;
rtx save_area = 0; /* Place that it is saved. */
#endif
diff --git a/gcc/cfg.c b/gcc/cfg.c
index e8bf789480b..1f681124105 100644
--- a/gcc/cfg.c
+++ b/gcc/cfg.c
@@ -597,7 +597,7 @@ dump_reg_info (FILE *file)
fprintf (file, "%d registers.\n", max);
for (i = FIRST_PSEUDO_REGISTER; i < max; i++)
{
- enum reg_class class, altclass;
+ enum reg_class rclass, altclass;
if (regstat_n_sets_and_refs)
fprintf (file, "\nRegister %d used %d times across %d insns",
@@ -628,17 +628,17 @@ dump_reg_info (FILE *file)
&& PSEUDO_REGNO_BYTES (i) != UNITS_PER_WORD)
fprintf (file, "; %d bytes", PSEUDO_REGNO_BYTES (i));
- class = reg_preferred_class (i);
+ rclass = reg_preferred_class (i);
altclass = reg_alternate_class (i);
- if (class != GENERAL_REGS || altclass != ALL_REGS)
+ if (rclass != GENERAL_REGS || altclass != ALL_REGS)
{
- if (altclass == ALL_REGS || class == ALL_REGS)
- fprintf (file, "; pref %s", reg_class_names[(int) class]);
+ if (altclass == ALL_REGS || rclass == ALL_REGS)
+ fprintf (file, "; pref %s", reg_class_names[(int) rclass]);
else if (altclass == NO_REGS)
- fprintf (file, "; %s or none", reg_class_names[(int) class]);
+ fprintf (file, "; %s or none", reg_class_names[(int) rclass]);
else
fprintf (file, "; pref %s, else %s",
- reg_class_names[(int) class],
+ reg_class_names[(int) rclass],
reg_class_names[(int) altclass]);
}
diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
index 6a48e1632d7..b4c33ab8193 100644
--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -42,6 +42,352 @@ along with GCC; see the file COPYING3. If not see
#include "value-prof.h"
#include "target.h"
+
+/* Return an expression tree corresponding to the RHS of GIMPLE
+ statement STMT. */
+
+tree
+gimple_assign_rhs_to_tree (gimple stmt)
+{
+ tree t;
+ enum gimple_rhs_class class;
+
+ class = get_gimple_rhs_class (gimple_expr_code (stmt));
+
+ if (class == GIMPLE_BINARY_RHS)
+ t = build2 (gimple_assign_rhs_code (stmt),
+ TREE_TYPE (gimple_assign_lhs (stmt)),
+ gimple_assign_rhs1 (stmt),
+ gimple_assign_rhs2 (stmt));
+ else if (class == GIMPLE_UNARY_RHS)
+ t = build1 (gimple_assign_rhs_code (stmt),
+ TREE_TYPE (gimple_assign_lhs (stmt)),
+ gimple_assign_rhs1 (stmt));
+ else if (class == GIMPLE_SINGLE_RHS)
+ t = gimple_assign_rhs1 (stmt);
+ else
+ gcc_unreachable ();
+
+ return t;
+}
+
+/* Return an expression tree corresponding to the PREDICATE of GIMPLE_COND
+ statement STMT. */
+
+static tree
+gimple_cond_pred_to_tree (gimple stmt)
+{
+ return build2 (gimple_cond_code (stmt), boolean_type_node,
+ gimple_cond_lhs (stmt), gimple_cond_rhs (stmt));
+}
+
+/* Helper for gimple_to_tree. Set EXPR_LOCATION for every expression
+ inside *TP. DATA is the location to set. */
+
+static tree
+set_expr_location_r (tree *tp, int *ws ATTRIBUTE_UNUSED, void *data)
+{
+ location_t *loc = (location_t *) data;
+ if (EXPR_P (*tp))
+ SET_EXPR_LOCATION (*tp, *loc);
+
+ return NULL_TREE;
+}
+
+
+/* RTL expansion has traditionally been done on trees, so the
+ transition to doing it on GIMPLE tuples is very invasive to the RTL
+ expander. To facilitate the transition, this function takes a
+ GIMPLE tuple STMT and returns the same statement in the form of a
+ tree. */
+
+static tree
+gimple_to_tree (gimple stmt)
+{
+ tree t;
+ int rn;
+ tree_ann_common_t ann;
+ location_t loc;
+
+ switch (gimple_code (stmt))
+ {
+ case GIMPLE_ASSIGN:
+ {
+ tree lhs = gimple_assign_lhs (stmt);
+
+ t = gimple_assign_rhs_to_tree (stmt);
+ t = build2 (MODIFY_EXPR, TREE_TYPE (lhs), lhs, t);
+ if (gimple_assign_nontemporal_move_p (stmt))
+ MOVE_NONTEMPORAL (t) = true;
+ }
+ break;
+
+ case GIMPLE_COND:
+ t = gimple_cond_pred_to_tree (stmt);
+ t = build3 (COND_EXPR, void_type_node, t, NULL_TREE, NULL_TREE);
+ break;
+
+ case GIMPLE_GOTO:
+ t = build1 (GOTO_EXPR, void_type_node, gimple_goto_dest (stmt));
+ break;
+
+ case GIMPLE_LABEL:
+ t = build1 (LABEL_EXPR, void_type_node, gimple_label_label (stmt));
+ break;
+
+ case GIMPLE_RETURN:
+ {
+ tree retval = gimple_return_retval (stmt);
+
+ if (retval && retval != error_mark_node)
+ {
+ tree result = DECL_RESULT (current_function_decl);
+
+ /* If we are not returning the current function's RESULT_DECL,
+ build an assignment to it. */
+ if (retval != result)
+ {
+ /* I believe that a function's RESULT_DECL is unique. */
+ gcc_assert (TREE_CODE (retval) != RESULT_DECL);
+
+ retval = build2 (MODIFY_EXPR, TREE_TYPE (result),
+ result, retval);
+ }
+ }
+ t = build1 (RETURN_EXPR, void_type_node, retval);
+ }
+ break;
+
+ case GIMPLE_ASM:
+ {
+ size_t i, n;
+ tree out, in, cl;
+ const char *s;
+
+ out = NULL_TREE;
+ n = gimple_asm_noutputs (stmt);
+ if (n > 0)
+ {
+ t = out = gimple_asm_output_op (stmt, 0);
+ for (i = 1; i < n; i++)
+ {
+ TREE_CHAIN (t) = gimple_asm_output_op (stmt, i);
+ t = gimple_asm_output_op (stmt, i);
+ }
+ }
+
+ in = NULL_TREE;
+ n = gimple_asm_ninputs (stmt);
+ if (n > 0)
+ {
+ t = in = gimple_asm_input_op (stmt, 0);
+ for (i = 1; i < n; i++)
+ {
+ TREE_CHAIN (t) = gimple_asm_input_op (stmt, i);
+ t = gimple_asm_input_op (stmt, i);
+ }
+ }
+
+ cl = NULL_TREE;
+ n = gimple_asm_nclobbers (stmt);
+ if (n > 0)
+ {
+ t = cl = gimple_asm_clobber_op (stmt, 0);
+ for (i = 1; i < n; i++)
+ {
+ TREE_CHAIN (t) = gimple_asm_clobber_op (stmt, i);
+ t = gimple_asm_clobber_op (stmt, i);
+ }
+ }
+
+ s = gimple_asm_string (stmt);
+ t = build4 (ASM_EXPR, void_type_node, build_string (strlen (s), s),
+ out, in, cl);
+ ASM_VOLATILE_P (t) = gimple_asm_volatile_p (stmt);
+ ASM_INPUT_P (t) = gimple_asm_input_p (stmt);
+ }
+ break;
+
+ case GIMPLE_CALL:
+ {
+ size_t i;
+ tree fn;
+ tree_ann_common_t ann;
+
+ t = build_vl_exp (CALL_EXPR, gimple_call_num_args (stmt) + 3);
+
+ fn = gimple_call_fn (stmt);
+ if (TREE_CODE (fn) == FUNCTION_DECL)
+ CALL_EXPR_FN (t) = build1 (ADDR_EXPR,
+ build_pointer_type (TREE_TYPE (fn)),
+ fn);
+ else
+ CALL_EXPR_FN (t) = fn;
+
+ TREE_TYPE (t) = gimple_call_return_type (stmt);
+
+ CALL_EXPR_STATIC_CHAIN (t) = gimple_call_chain (stmt);
+
+ for (i = 0; i < gimple_call_num_args (stmt); i++)
+ CALL_EXPR_ARG (t, i) = gimple_call_arg (stmt, i);
+
+ if (!(gimple_call_flags (stmt) & (ECF_CONST | ECF_PURE)))
+ TREE_SIDE_EFFECTS (t) = 1;
+
+ if (gimple_call_flags (stmt) & ECF_NOTHROW)
+ TREE_NOTHROW (t) = 1;
+
+ CALL_EXPR_TAILCALL (t) = gimple_call_tail_p (stmt);
+ CALL_EXPR_RETURN_SLOT_OPT (t) = gimple_call_return_slot_opt_p (stmt);
+ CALL_FROM_THUNK_P (t) = gimple_call_from_thunk_p (stmt);
+ CALL_CANNOT_INLINE_P (t) = gimple_call_cannot_inline_p (stmt);
+ CALL_EXPR_VA_ARG_PACK (t) = gimple_call_va_arg_pack_p (stmt);
+
+ /* If the call has a LHS then create a MODIFY_EXPR to hold it. */
+ {
+ tree lhs = gimple_call_lhs (stmt);
+
+ if (lhs)
+ t = build2 (MODIFY_EXPR, TREE_TYPE (lhs), lhs, t);
+ }
+
+ /* Record the original call statement, as it may be used
+ to retrieve profile information during expansion. */
+ if (TREE_CODE (fn) == FUNCTION_DECL && DECL_BUILT_IN (fn))
+ {
+ ann = get_tree_common_ann (t);
+ ann->stmt = stmt;
+ }
+ }
+ break;
+
+ case GIMPLE_SWITCH:
+ {
+ tree label_vec;
+ size_t i;
+ tree elt = gimple_switch_label (stmt, 0);
+
+ label_vec = make_tree_vec (gimple_switch_num_labels (stmt));
+
+ if (!CASE_LOW (elt) && !CASE_HIGH (elt))
+ {
+ for (i = 1; i < gimple_switch_num_labels (stmt); i++)
+ TREE_VEC_ELT (label_vec, i - 1) = gimple_switch_label (stmt, i);
+
+ /* The default case in a SWITCH_EXPR must be at the end of
+ the label vector. */
+ TREE_VEC_ELT (label_vec, i - 1) = gimple_switch_label (stmt, 0);
+ }
+ else
+ {
+ for (i = 0; i < gimple_switch_num_labels (stmt); i++)
+ TREE_VEC_ELT (label_vec, i) = gimple_switch_label (stmt, i);
+ }
+
+ t = build3 (SWITCH_EXPR, void_type_node, gimple_switch_index (stmt),
+ NULL, label_vec);
+ }
+ break;
+
+ case GIMPLE_NOP:
+ case GIMPLE_PREDICT:
+ t = build1 (NOP_EXPR, void_type_node, size_zero_node);
+ break;
+
+ case GIMPLE_RESX:
+ t = build_resx (gimple_resx_region (stmt));
+ break;
+
+ default:
+ if (errorcount == 0)
+ {
+ error ("Unrecognized GIMPLE statement during RTL expansion");
+ print_gimple_stmt (stderr, stmt, 4, 0);
+ gcc_unreachable ();
+ }
+ else
+ {
+ /* Ignore any bad gimple codes if we're going to die anyhow,
+ so we can at least set TREE_ASM_WRITTEN and have the rest
+ of compilation advance without sudden ICE death. */
+ t = build1 (NOP_EXPR, void_type_node, size_zero_node);
+ break;
+ }
+ }
+
+ /* If STMT is inside an exception region, record it in the generated
+ expression. */
+ rn = lookup_stmt_eh_region (stmt);
+ if (rn >= 0)
+ {
+ tree call = get_call_expr_in (t);
+
+ ann = get_tree_common_ann (t);
+ ann->rn = rn;
+
+ /* For a CALL_EXPR on the RHS of an assignment, calls.c looks up
+ the CALL_EXPR not the assignment statment for EH region number. */
+ if (call && call != t)
+ {
+ ann = get_tree_common_ann (call);
+ ann->rn = rn;
+ }
+ }
+
+ /* Set EXPR_LOCATION in all the embedded expressions. */
+ loc = gimple_location (stmt);
+ walk_tree (&t, set_expr_location_r, (void *) &loc, NULL);
+
+ TREE_BLOCK (t) = gimple_block (stmt);
+
+ return t;
+}
+
+
+/* Release back to GC memory allocated by gimple_to_tree. */
+
+static void
+release_stmt_tree (gimple stmt, tree stmt_tree)
+{
+ tree_ann_common_t ann;
+
+ switch (gimple_code (stmt))
+ {
+ case GIMPLE_ASSIGN:
+ if (get_gimple_rhs_class (gimple_expr_code (stmt)) != GIMPLE_SINGLE_RHS)
+ ggc_free (TREE_OPERAND (stmt_tree, 1));
+ break;
+ case GIMPLE_COND:
+ ggc_free (COND_EXPR_COND (stmt_tree));
+ break;
+ case GIMPLE_RETURN:
+ if (TREE_OPERAND (stmt_tree, 0)
+ && TREE_CODE (TREE_OPERAND (stmt_tree, 0)) == MODIFY_EXPR)
+ ggc_free (TREE_OPERAND (stmt_tree, 0));
+ break;
+ case GIMPLE_CALL:
+ if (gimple_call_lhs (stmt))
+ {
+ if (TREE_CODE (gimple_call_fn (stmt)) == FUNCTION_DECL)
+ ggc_free (CALL_EXPR_FN (TREE_OPERAND (stmt_tree, 1)));
+ ann = tree_common_ann (TREE_OPERAND (stmt_tree, 1));
+ if (ann)
+ ggc_free (ann);
+ ggc_free (TREE_OPERAND (stmt_tree, 1));
+ }
+ else if (TREE_CODE (gimple_call_fn (stmt)) == FUNCTION_DECL)
+ ggc_free (CALL_EXPR_FN (stmt_tree));
+ break;
+ default:
+ break;
+ }
+ ann = tree_common_ann (stmt_tree);
+ if (ann)
+ ggc_free (ann);
+ ggc_free (stmt_tree);
+}
+
+
/* Verify that there is exactly single jump instruction since last and attach
REG_BR_PROB note specifying probability.
??? We really ought to pass the probability down to RTL expanders and let it
@@ -617,28 +963,6 @@ expand_one_stack_var (tree var)
expand_one_stack_var_at (var, offset);
}
-/* A subroutine of expand_one_var. Called to assign rtl
- to a TREE_STATIC VAR_DECL. */
-
-static void
-expand_one_static_var (tree var)
-{
- /* In unit-at-a-time all the static variables are expanded at the end
- of compilation process. */
- if (flag_unit_at_a_time)
- return;
- /* If this is an inlined copy of a static local variable,
- look up the original. */
- var = DECL_ORIGIN (var);
-
- /* If we've already processed this variable because of that, do nothing. */
- if (TREE_ASM_WRITTEN (var))
- return;
-
- /* Otherwise, just emit the variable. */
- rest_of_decl_compilation (var, 0, 0);
-}
-
/* A subroutine of expand_one_var. Called to assign rtl to a VAR_DECL
that will reside in a hard register. */
@@ -742,10 +1066,7 @@ expand_one_var (tree var, bool toplevel, bool really_expand)
else if (DECL_HAS_VALUE_EXPR_P (var))
;
else if (TREE_STATIC (var))
- {
- if (really_expand)
- expand_one_static_var (var);
- }
+ ;
else if (DECL_RTL_SET_P (var))
;
else if (TREE_TYPE (var) == error_mark_node)
@@ -790,12 +1111,7 @@ expand_used_vars_for_block (tree block, bool toplevel)
/* Expand all variables at this level. */
for (t = BLOCK_VARS (block); t ; t = TREE_CHAIN (t))
- if (TREE_USED (t)
- /* Force local static variables to be output when marked by
- used attribute. For unit-at-a-time, cgraph code already takes
- care of this. */
- || (!flag_unit_at_a_time && TREE_STATIC (t)
- && DECL_PRESERVE_P (t)))
+ if (TREE_USED (t))
expand_one_var (t, toplevel, true);
this_sv_num = stack_vars_num;
@@ -1211,12 +1527,12 @@ expand_used_vars (void)
generated for STMT should have been appended. */
static void
-maybe_dump_rtl_for_tree_stmt (tree stmt, rtx since)
+maybe_dump_rtl_for_gimple_stmt (gimple stmt, rtx since)
{
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "\n;; ");
- print_generic_expr (dump_file, stmt, TDF_SLIM);
+ print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
fprintf (dump_file, "\n");
print_rtl (dump_file, since ? NEXT_INSN (since) : since);
@@ -1230,10 +1546,11 @@ static struct pointer_map_t *lab_rtx_for_bb;
/* Returns the label_rtx expression for a label starting basic block BB. */
static rtx
-label_rtx_for_bb (basic_block bb)
+label_rtx_for_bb (basic_block bb ATTRIBUTE_UNUSED)
{
- tree_stmt_iterator tsi;
- tree lab, lab_stmt;
+ gimple_stmt_iterator gsi;
+ tree lab;
+ gimple lab_stmt;
void **elt;
if (bb->flags & BB_RTL)
@@ -1245,13 +1562,13 @@ label_rtx_for_bb (basic_block bb)
/* Find the tree label if it is present. */
- for (tsi = tsi_start (bb_stmt_list (bb)); !tsi_end_p (tsi); tsi_next (&tsi))
+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
- lab_stmt = tsi_stmt (tsi);
- if (TREE_CODE (lab_stmt) != LABEL_EXPR)
+ lab_stmt = gsi_stmt (gsi);
+ if (gimple_code (lab_stmt) != GIMPLE_LABEL)
break;
- lab = LABEL_EXPR_LABEL (lab_stmt);
+ lab = gimple_label_label (lab_stmt);
if (DECL_NONLOCAL (lab))
break;
@@ -1263,29 +1580,28 @@ label_rtx_for_bb (basic_block bb)
return (rtx) *elt;
}
-/* A subroutine of expand_gimple_basic_block. Expand one COND_EXPR.
+
+/* A subroutine of expand_gimple_basic_block. Expand one GIMPLE_COND.
Returns a new basic block if we've terminated the current basic
block and created a new one. */
static basic_block
-expand_gimple_cond_expr (basic_block bb, tree stmt)
+expand_gimple_cond (basic_block bb, gimple stmt)
{
basic_block new_bb, dest;
edge new_edge;
edge true_edge;
edge false_edge;
- tree pred = COND_EXPR_COND (stmt);
+ tree pred = gimple_cond_pred_to_tree (stmt);
rtx last2, last;
- gcc_assert (COND_EXPR_THEN (stmt) == NULL_TREE);
- gcc_assert (COND_EXPR_ELSE (stmt) == NULL_TREE);
last2 = last = get_last_insn ();
extract_true_false_edges_from_block (bb, &true_edge, &false_edge);
- if (EXPR_LOCUS (stmt))
+ if (gimple_has_location (stmt))
{
- set_curr_insn_source_location (*(EXPR_LOCUS (stmt)));
- set_curr_insn_block (TREE_BLOCK (stmt));
+ set_curr_insn_source_location (gimple_location (stmt));
+ set_curr_insn_block (gimple_block (stmt));
}
/* These flags have no purpose in RTL land. */
@@ -1298,20 +1614,22 @@ expand_gimple_cond_expr (basic_block bb, tree stmt)
{
jumpif (pred, label_rtx_for_bb (true_edge->dest));
add_reg_br_prob_note (last, true_edge->probability);
- maybe_dump_rtl_for_tree_stmt (stmt, last);
+ maybe_dump_rtl_for_gimple_stmt (stmt, last);
if (true_edge->goto_locus)
set_curr_insn_source_location (true_edge->goto_locus);
false_edge->flags |= EDGE_FALLTHRU;
+ ggc_free (pred);
return NULL;
}
if (true_edge->dest == bb->next_bb)
{
jumpifnot (pred, label_rtx_for_bb (false_edge->dest));
add_reg_br_prob_note (last, false_edge->probability);
- maybe_dump_rtl_for_tree_stmt (stmt, last);
+ maybe_dump_rtl_for_gimple_stmt (stmt, last);
if (false_edge->goto_locus)
set_curr_insn_source_location (false_edge->goto_locus);
true_edge->flags |= EDGE_FALLTHRU;
+ ggc_free (pred);
return NULL;
}
@@ -1338,15 +1656,16 @@ expand_gimple_cond_expr (basic_block bb, tree stmt)
BB_END (new_bb) = PREV_INSN (BB_END (new_bb));
update_bb_for_insn (new_bb);
- maybe_dump_rtl_for_tree_stmt (stmt, last2);
+ maybe_dump_rtl_for_gimple_stmt (stmt, last2);
if (false_edge->goto_locus)
set_curr_insn_source_location (false_edge->goto_locus);
+ ggc_free (pred);
return new_bb;
}
-/* A subroutine of expand_gimple_basic_block. Expand one CALL_EXPR
+/* A subroutine of expand_gimple_basic_block. Expand one GIMPLE_CALL
that has CALL_EXPR_TAILCALL set. Returns non-null if we actually
generated a tail call (something that might be denied by the ABI
rules governing the call; see calls.c).
@@ -1357,23 +1676,26 @@ expand_gimple_cond_expr (basic_block bb, tree stmt)
tailcall) and the normal result happens via a sqrt instruction. */
static basic_block
-expand_gimple_tailcall (basic_block bb, tree stmt, bool *can_fallthru)
+expand_gimple_tailcall (basic_block bb, gimple stmt, bool *can_fallthru)
{
rtx last2, last;
edge e;
edge_iterator ei;
int probability;
gcov_type count;
+ tree stmt_tree = gimple_to_tree (stmt);
last2 = last = get_last_insn ();
- expand_expr_stmt (stmt);
+ expand_expr_stmt (stmt_tree);
+
+ release_stmt_tree (stmt, stmt_tree);
for (last = NEXT_INSN (last); last; last = NEXT_INSN (last))
if (CALL_P (last) && SIBLING_CALL_P (last))
goto found;
- maybe_dump_rtl_for_tree_stmt (stmt, last2);
+ maybe_dump_rtl_for_gimple_stmt (stmt, last2);
*can_fallthru = true;
return NULL;
@@ -1448,7 +1770,7 @@ expand_gimple_tailcall (basic_block bb, tree stmt, bool *can_fallthru)
BB_END (bb) = PREV_INSN (last);
}
- maybe_dump_rtl_for_tree_stmt (stmt, last2);
+ maybe_dump_rtl_for_gimple_stmt (stmt, last2);
return bb;
}
@@ -1458,50 +1780,52 @@ expand_gimple_tailcall (basic_block bb, tree stmt, bool *can_fallthru)
static basic_block
expand_gimple_basic_block (basic_block bb)
{
- tree_stmt_iterator tsi;
- tree stmts = bb_stmt_list (bb);
- tree stmt = NULL;
+ gimple_stmt_iterator gsi;
+ gimple_seq stmts;
+ gimple stmt = NULL;
rtx note, last;
edge e;
edge_iterator ei;
void **elt;
if (dump_file)
- {
- fprintf (dump_file,
- "\n;; Generating RTL for tree basic block %d\n",
- bb->index);
- }
-
- bb->il.tree = NULL;
+ fprintf (dump_file, "\n;; Generating RTL for gimple basic block %d\n",
+ bb->index);
+
+ /* Note that since we are now transitioning from GIMPLE to RTL, we
+ cannot use the gsi_*_bb() routines because they expect the basic
+ block to be in GIMPLE, instead of RTL. Therefore, we need to
+ access the BB sequence directly. */
+ stmts = bb_seq (bb);
+ bb->il.gimple = NULL;
init_rtl_bb_info (bb);
bb->flags |= BB_RTL;
/* Remove the RETURN_EXPR if we may fall though to the exit
instead. */
- tsi = tsi_last (stmts);
- if (!tsi_end_p (tsi)
- && TREE_CODE (tsi_stmt (tsi)) == RETURN_EXPR)
+ gsi = gsi_last (stmts);
+ if (!gsi_end_p (gsi)
+ && gimple_code (gsi_stmt (gsi)) == GIMPLE_RETURN)
{
- tree ret_stmt = tsi_stmt (tsi);
+ gimple ret_stmt = gsi_stmt (gsi);
gcc_assert (single_succ_p (bb));
gcc_assert (single_succ (bb) == EXIT_BLOCK_PTR);
if (bb->next_bb == EXIT_BLOCK_PTR
- && !TREE_OPERAND (ret_stmt, 0))
+ && !gimple_return_retval (ret_stmt))
{
- tsi_delink (&tsi);
+ gsi_remove (&gsi, false);
single_succ_edge (bb)->flags |= EDGE_FALLTHRU;
}
}
- tsi = tsi_start (stmts);
- if (!tsi_end_p (tsi))
+ gsi = gsi_start (stmts);
+ if (!gsi_end_p (gsi))
{
- stmt = tsi_stmt (tsi);
- if (TREE_CODE (stmt) != LABEL_EXPR)
- stmt = NULL_TREE;
+ stmt = gsi_stmt (gsi);
+ if (gimple_code (stmt) != GIMPLE_LABEL)
+ stmt = NULL;
}
elt = pointer_map_contains (lab_rtx_for_bb, bb);
@@ -1512,8 +1836,10 @@ expand_gimple_basic_block (basic_block bb)
if (stmt)
{
- expand_expr_stmt (stmt);
- tsi_next (&tsi);
+ tree stmt_tree = gimple_to_tree (stmt);
+ expand_expr_stmt (stmt_tree);
+ release_stmt_tree (stmt, stmt_tree);
+ gsi_next (&gsi);
}
if (elt)
@@ -1526,7 +1852,7 @@ expand_gimple_basic_block (basic_block bb)
BB_HEAD (bb) = NEXT_INSN (BB_HEAD (bb));
note = emit_note_after (NOTE_INSN_BASIC_BLOCK, BB_HEAD (bb));
- maybe_dump_rtl_for_tree_stmt (stmt, last);
+ maybe_dump_rtl_for_gimple_stmt (stmt, last);
}
else
note = BB_HEAD (bb) = emit_note (NOTE_INSN_BASIC_BLOCK);
@@ -1547,36 +1873,22 @@ expand_gimple_basic_block (basic_block bb)
ei_next (&ei);
}
- for (; !tsi_end_p (tsi); tsi_next (&tsi))
+ for (; !gsi_end_p (gsi); gsi_next (&gsi))
{
- tree stmt = tsi_stmt (tsi);
+ gimple stmt = gsi_stmt (gsi);
basic_block new_bb;
- if (!stmt)
- continue;
-
/* Expand this statement, then evaluate the resulting RTL and
fixup the CFG accordingly. */
- if (TREE_CODE (stmt) == COND_EXPR)
+ if (gimple_code (stmt) == GIMPLE_COND)
{
- new_bb = expand_gimple_cond_expr (bb, stmt);
+ new_bb = expand_gimple_cond (bb, stmt);
if (new_bb)
return new_bb;
}
else
{
- tree call = get_call_expr_in (stmt);
- int region;
- /* For the benefit of calls.c, converting all this to rtl,
- we need to record the call expression, not just the outer
- modify statement. */
- if (call && call != stmt)
- {
- if ((region = lookup_stmt_eh_region (stmt)) > 0)
- add_stmt_to_eh_region (call, region);
- gimple_duplicate_stmt_histograms (cfun, call, cfun, stmt);
- }
- if (call && CALL_EXPR_TAILCALL (call))
+ if (is_gimple_call (stmt) && gimple_call_tail_p (stmt))
{
bool can_fallthru;
new_bb = expand_gimple_tailcall (bb, stmt, &can_fallthru);
@@ -1590,9 +1902,11 @@ expand_gimple_basic_block (basic_block bb)
}
else
{
+ tree stmt_tree = gimple_to_tree (stmt);
last = get_last_insn ();
- expand_expr_stmt (stmt);
- maybe_dump_rtl_for_tree_stmt (stmt, last);
+ expand_expr_stmt (stmt_tree);
+ maybe_dump_rtl_for_gimple_stmt (stmt, last);
+ release_stmt_tree (stmt, stmt_tree);
}
}
}
@@ -1651,7 +1965,7 @@ construct_init_block (void)
otherwise we have to jump into proper target. */
if (e && e->dest != ENTRY_BLOCK_PTR->next_bb)
{
- tree label = tree_block_label (e->dest);
+ tree label = gimple_block_label (e->dest);
emit_jump (label_rtx (label));
flags = 0;
@@ -1809,14 +2123,14 @@ static void
discover_nonconstant_array_refs (void)
{
basic_block bb;
- block_stmt_iterator bsi;
+ gimple_stmt_iterator gsi;
FOR_EACH_BB (bb)
- {
- for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
- walk_tree (bsi_stmt_ptr (bsi), discover_nonconstant_array_refs_r,
- NULL , NULL);
- }
+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+ {
+ gimple stmt = gsi_stmt (gsi);
+ walk_gimple_op (stmt, discover_nonconstant_array_refs_r, NULL);
+ }
}
/* Translate the intermediate representation contained in the CFG
@@ -1829,7 +2143,7 @@ discover_nonconstant_array_refs (void)
the expansion. */
static unsigned int
-tree_expand_cfg (void)
+gimple_expand_cfg (void)
{
basic_block bb, init_block;
sbitmap blocks;
@@ -1979,7 +2293,7 @@ struct rtl_opt_pass pass_expand =
RTL_PASS,
"expand", /* name */
NULL, /* gate */
- tree_expand_cfg, /* execute */
+ gimple_expand_cfg, /* execute */
NULL, /* sub */
NULL, /* next */
0, /* static_pass_number */
diff --git a/gcc/cfghooks.c b/gcc/cfghooks.c
index 5815a7edd37..00d7151f6b8 100644
--- a/gcc/cfghooks.c
+++ b/gcc/cfghooks.c
@@ -51,9 +51,9 @@ cfg_layout_rtl_register_cfg_hooks (void)
/* Initialization of functions specific to the tree IR. */
void
-tree_register_cfg_hooks (void)
+gimple_register_cfg_hooks (void)
{
- cfg_hooks = &tree_cfg_hooks;
+ cfg_hooks = &gimple_cfg_hooks;
}
/* Returns current ir type. */
@@ -61,7 +61,7 @@ tree_register_cfg_hooks (void)
enum ir_type
current_ir_type (void)
{
- if (cfg_hooks == &tree_cfg_hooks)
+ if (cfg_hooks == &gimple_cfg_hooks)
return IR_GIMPLE;
else if (cfg_hooks == &rtl_cfg_hooks)
return IR_RTL_CFGRTL;
@@ -291,7 +291,7 @@ dump_bb (basic_block bb, FILE *outf, int indent)
putc ('\n', outf);
if (cfg_hooks->dump_bb)
- cfg_hooks->dump_bb (bb, outf, indent);
+ cfg_hooks->dump_bb (bb, outf, indent, 0);
}
/* Redirect edge E to the given basic block DEST and update underlying program
diff --git a/gcc/cfghooks.h b/gcc/cfghooks.h
index e581d9cd559..537c05f07ba 100644
--- a/gcc/cfghooks.h
+++ b/gcc/cfghooks.h
@@ -28,7 +28,7 @@ struct cfg_hooks
/* Debugging. */
int (*verify_flow_info) (void);
- void (*dump_bb) (basic_block, FILE *, int);
+ void (*dump_bb) (basic_block, FILE *, int, int);
/* Basic CFG manipulation. */
@@ -181,7 +181,7 @@ extern void lv_add_condition_to_bb (basic_block, basic_block, basic_block,
void *);
/* Hooks containers. */
-extern struct cfg_hooks tree_cfg_hooks;
+extern struct cfg_hooks gimple_cfg_hooks;
extern struct cfg_hooks rtl_cfg_hooks;
extern struct cfg_hooks cfg_layout_rtl_cfg_hooks;
@@ -189,6 +189,6 @@ extern struct cfg_hooks cfg_layout_rtl_cfg_hooks;
extern enum ir_type current_ir_type (void);
extern void rtl_register_cfg_hooks (void);
extern void cfg_layout_rtl_register_cfg_hooks (void);
-extern void tree_register_cfg_hooks (void);
+extern void gimple_register_cfg_hooks (void);
#endif /* GCC_CFGHOOKS_H */
diff --git a/gcc/cfgloop.c b/gcc/cfgloop.c
index f565708ae9e..4c9bbf0ab19 100644
--- a/gcc/cfgloop.c
+++ b/gcc/cfgloop.c
@@ -563,11 +563,13 @@ find_subloop_latch_edge_by_profile (VEC (edge, heap) *latches)
another edge. */
static edge
-find_subloop_latch_edge_by_ivs (struct loop *loop, VEC (edge, heap) *latches)
+find_subloop_latch_edge_by_ivs (struct loop *loop ATTRIBUTE_UNUSED, VEC (edge, heap) *latches)
{
edge e, latch = VEC_index (edge, latches, 0);
unsigned i;
- tree phi, lop;
+ gimple phi;
+ gimple_stmt_iterator psi;
+ tree lop;
basic_block bb;
/* Find the candidate for the latch edge. */
@@ -582,15 +584,16 @@ find_subloop_latch_edge_by_ivs (struct loop *loop, VEC (edge, heap) *latches)
/* Check for a phi node that would deny that this is a latch edge of
a subloop. */
- for (phi = phi_nodes (loop->header); phi; phi = PHI_CHAIN (phi))
+ for (psi = gsi_start_phis (loop->header); !gsi_end_p (psi); gsi_next (&psi))
{
+ phi = gsi_stmt (psi);
lop = PHI_ARG_DEF_FROM_EDGE (phi, latch);
/* Ignore the values that are not changed inside the subloop. */
if (TREE_CODE (lop) != SSA_NAME
|| SSA_NAME_DEF_STMT (lop) == phi)
continue;
- bb = bb_for_stmt (SSA_NAME_DEF_STMT (lop));
+ bb = gimple_bb (SSA_NAME_DEF_STMT (lop));
if (!bb || !flow_bb_inside_loop_p (loop, bb))
continue;
diff --git a/gcc/cfgloop.h b/gcc/cfgloop.h
index 056e8f0b1e5..d21d50bebdd 100644
--- a/gcc/cfgloop.h
+++ b/gcc/cfgloop.h
@@ -49,7 +49,7 @@ struct lpt_decision GTY (())
struct nb_iter_bound GTY ((chain_next ("%h.next")))
{
/* The statement STMT is executed at most ... */
- tree stmt;
+ gimple stmt;
/* ... BOUND + 1 times (BOUND must be an unsigned constant).
The + 1 is added for the following reasons:
diff --git a/gcc/cfgrtl.c b/gcc/cfgrtl.c
index 240455bca9d..f9e3e17e1a7 100644
--- a/gcc/cfgrtl.c
+++ b/gcc/cfgrtl.c
@@ -76,7 +76,7 @@ static void rtl_delete_block (basic_block);
static basic_block rtl_redirect_edge_and_branch_force (edge, basic_block);
static edge rtl_redirect_edge_and_branch (edge, basic_block);
static basic_block rtl_split_block (basic_block, void *);
-static void rtl_dump_bb (basic_block, FILE *, int);
+static void rtl_dump_bb (basic_block, FILE *, int, int);
static int rtl_verify_flow_info_1 (void);
static void rtl_make_forwarder_block (edge);
@@ -1510,7 +1510,7 @@ commit_edge_insertions (void)
at start and end). */
static void
-rtl_dump_bb (basic_block bb, FILE *outf, int indent)
+rtl_dump_bb (basic_block bb, FILE *outf, int indent, int flags ATTRIBUTE_UNUSED)
{
rtx insn;
rtx last;
diff --git a/gcc/cgraph.c b/gcc/cgraph.c
index 17ee8f0a63a..51181cbe6a2 100644
--- a/gcc/cgraph.c
+++ b/gcc/cgraph.c
@@ -81,7 +81,7 @@ The callgraph:
#include "varray.h"
#include "output.h"
#include "intl.h"
-#include "tree-gimple.h"
+#include "gimple.h"
#include "tree-dump.h"
#include "tree-flow.h"
@@ -91,6 +91,8 @@ static inline void cgraph_edge_remove_callee (struct cgraph_edge *e);
/* Hash table used to convert declarations into nodes. */
static GTY((param_is (struct cgraph_node))) htab_t cgraph_hash;
+/* Hash table used to convert assembler names into nodes. */
+static GTY((param_is (struct cgraph_node))) htab_t assembler_name_hash;
/* The linked list of cgraph nodes. */
struct cgraph_node *cgraph_nodes;
@@ -109,6 +111,9 @@ int cgraph_n_nodes;
/* Maximal uid used in cgraph nodes. */
int cgraph_max_uid;
+/* Maximal uid used in cgraph edges. */
+int cgraph_edge_max_uid;
+
/* Maximal pid used for profiling */
int cgraph_max_pid;
@@ -132,6 +137,206 @@ static GTY(()) struct cgraph_asm_node *cgraph_asm_last_node;
them, to support -fno-toplevel-reorder. */
int cgraph_order;
+/* List of hooks trigerred on cgraph_edge events. */
+struct cgraph_edge_hook_list {
+ cgraph_edge_hook hook;
+ void *data;
+ struct cgraph_edge_hook_list *next;
+};
+
+/* List of hooks trigerred on cgraph_node events. */
+struct cgraph_node_hook_list {
+ cgraph_node_hook hook;
+ void *data;
+ struct cgraph_node_hook_list *next;
+};
+
+/* List of hooks trigerred on events involving two cgraph_edges. */
+struct cgraph_2edge_hook_list {
+ cgraph_2edge_hook hook;
+ void *data;
+ struct cgraph_2edge_hook_list *next;
+};
+
+/* List of hooks trigerred on events involving two cgraph_nodes. */
+struct cgraph_2node_hook_list {
+ cgraph_2node_hook hook;
+ void *data;
+ struct cgraph_2node_hook_list *next;
+};
+
+/* List of hooks triggered when an edge is removed. */
+struct cgraph_edge_hook_list *first_cgraph_edge_removal_hook;
+/* List of hooks triggered when a node is removed. */
+struct cgraph_node_hook_list *first_cgraph_node_removal_hook;
+/* List of hooks triggered when an edge is duplicated. */
+struct cgraph_2edge_hook_list *first_cgraph_edge_duplicated_hook;
+/* List of hooks triggered when a node is duplicated. */
+struct cgraph_2node_hook_list *first_cgraph_node_duplicated_hook;
+
+
+/* Register HOOK to be called with DATA on each removed edge. */
+struct cgraph_edge_hook_list *
+cgraph_add_edge_removal_hook (cgraph_edge_hook hook, void *data)
+{
+ struct cgraph_edge_hook_list *entry;
+ struct cgraph_edge_hook_list **ptr = &first_cgraph_edge_removal_hook;
+
+ entry = (struct cgraph_edge_hook_list *) xmalloc (sizeof (*entry));
+ entry->hook = hook;
+ entry->data = data;
+ entry->next = NULL;
+ while (*ptr)
+ ptr = &(*ptr)->next;
+ *ptr = entry;
+ return entry;
+}
+
+/* Remove ENTRY from the list of hooks called on removing edges. */
+void
+cgraph_remove_edge_removal_hook (struct cgraph_edge_hook_list *entry)
+{
+ struct cgraph_edge_hook_list **ptr = &first_cgraph_edge_removal_hook;
+
+ while (*ptr != entry)
+ ptr = &(*ptr)->next;
+ *ptr = entry->next;
+}
+
+/* Call all edge removal hooks. */
+static void
+cgraph_call_edge_removal_hooks (struct cgraph_edge *e)
+{
+ struct cgraph_edge_hook_list *entry = first_cgraph_edge_removal_hook;
+ while (entry)
+ {
+ entry->hook (e, entry->data);
+ entry = entry->next;
+ }
+}
+
+/* Register HOOK to be called with DATA on each removed node. */
+struct cgraph_node_hook_list *
+cgraph_add_node_removal_hook (cgraph_node_hook hook, void *data)
+{
+ struct cgraph_node_hook_list *entry;
+ struct cgraph_node_hook_list **ptr = &first_cgraph_node_removal_hook;
+
+ entry = (struct cgraph_node_hook_list *) xmalloc (sizeof (*entry));
+ entry->hook = hook;
+ entry->data = data;
+ entry->next = NULL;
+ while (*ptr)
+ ptr = &(*ptr)->next;
+ *ptr = entry;
+ return entry;
+}
+
+/* Remove ENTRY from the list of hooks called on removing nodes. */
+void
+cgraph_remove_node_removal_hook (struct cgraph_node_hook_list *entry)
+{
+ struct cgraph_node_hook_list **ptr = &first_cgraph_node_removal_hook;
+
+ while (*ptr != entry)
+ ptr = &(*ptr)->next;
+ *ptr = entry->next;
+}
+
+/* Call all node removal hooks. */
+static void
+cgraph_call_node_removal_hooks (struct cgraph_node *node)
+{
+ struct cgraph_node_hook_list *entry = first_cgraph_node_removal_hook;
+ while (entry)
+ {
+ entry->hook (node, entry->data);
+ entry = entry->next;
+ }
+}
+
+/* Register HOOK to be called with DATA on each duplicated edge. */
+struct cgraph_2edge_hook_list *
+cgraph_add_edge_duplication_hook (cgraph_2edge_hook hook, void *data)
+{
+ struct cgraph_2edge_hook_list *entry;
+ struct cgraph_2edge_hook_list **ptr = &first_cgraph_edge_duplicated_hook;
+
+ entry = (struct cgraph_2edge_hook_list *) xmalloc (sizeof (*entry));
+ entry->hook = hook;
+ entry->data = data;
+ entry->next = NULL;
+ while (*ptr)
+ ptr = &(*ptr)->next;
+ *ptr = entry;
+ return entry;
+}
+
+/* Remove ENTRY from the list of hooks called on duplicating edges. */
+void
+cgraph_remove_edge_duplication_hook (struct cgraph_2edge_hook_list *entry)
+{
+ struct cgraph_2edge_hook_list **ptr = &first_cgraph_edge_duplicated_hook;
+
+ while (*ptr != entry)
+ ptr = &(*ptr)->next;
+ *ptr = entry->next;
+}
+
+/* Call all edge duplication hooks. */
+static void
+cgraph_call_edge_duplication_hooks (struct cgraph_edge *cs1,
+ struct cgraph_edge *cs2)
+{
+ struct cgraph_2edge_hook_list *entry = first_cgraph_edge_duplicated_hook;
+ while (entry)
+ {
+ entry->hook (cs1, cs2, entry->data);
+ entry = entry->next;
+ }
+}
+
+/* Register HOOK to be called with DATA on each duplicated node. */
+struct cgraph_2node_hook_list *
+cgraph_add_node_duplication_hook (cgraph_2node_hook hook, void *data)
+{
+ struct cgraph_2node_hook_list *entry;
+ struct cgraph_2node_hook_list **ptr = &first_cgraph_node_duplicated_hook;
+
+ entry = (struct cgraph_2node_hook_list *) xmalloc (sizeof (*entry));
+ entry->hook = hook;
+ entry->data = data;
+ entry->next = NULL;
+ while (*ptr)
+ ptr = &(*ptr)->next;
+ *ptr = entry;
+ return entry;
+}
+
+/* Remove ENTRY from the list of hooks called on duplicating nodes. */
+void
+cgraph_remove_node_duplication_hook (struct cgraph_2node_hook_list *entry)
+{
+ struct cgraph_2node_hook_list **ptr = &first_cgraph_node_duplicated_hook;
+
+ while (*ptr != entry)
+ ptr = &(*ptr)->next;
+ *ptr = entry->next;
+}
+
+/* Call all node duplication hooks. */
+static void
+cgraph_call_node_duplication_hooks (struct cgraph_node *node1,
+ struct cgraph_node *node2)
+{
+ struct cgraph_2node_hook_list *entry = first_cgraph_node_duplicated_hook;
+ while (entry)
+ {
+ entry->hook (node1, node2, entry->data);
+ entry = entry->next;
+ }
+}
+
/* Returns a hash code for P. */
static hashval_t
@@ -206,6 +411,7 @@ cgraph_node (tree decl)
node->origin->nested = node;
node->master_clone = node;
}
+
return node;
}
@@ -222,6 +428,24 @@ cgraph_insert_node_to_hashtable (struct cgraph_node *node)
*slot = node;
}
+/* Returns a hash code for P. */
+
+static hashval_t
+hash_node_by_assembler_name (const void *p)
+{
+ const struct cgraph_node *n = (const struct cgraph_node *) p;
+ return (hashval_t) decl_assembler_name_hash (DECL_ASSEMBLER_NAME (n->decl));
+}
+
+/* Returns nonzero if P1 and P2 are equal. */
+
+static int
+eq_assembler_name (const void *p1, const void *p2)
+{
+ const struct cgraph_node *n1 = (const struct cgraph_node *) p1;
+ const_tree name = (const_tree)p2;
+ return (decl_assembler_name_equal (n1->decl, name));
+}
/* Return the cgraph node that has ASMNAME for its DECL_ASSEMBLER_NAME.
Return NULL if there's no such node. */
@@ -230,11 +454,36 @@ struct cgraph_node *
cgraph_node_for_asm (tree asmname)
{
struct cgraph_node *node;
+ void **slot;
- for (node = cgraph_nodes; node ; node = node->next)
- if (decl_assembler_name_equal (node->decl, asmname))
- return node;
+ if (!assembler_name_hash)
+ {
+ assembler_name_hash =
+ htab_create_ggc (10, hash_node_by_assembler_name, eq_assembler_name,
+ NULL);
+ for (node = cgraph_nodes; node; node = node->next)
+ if (!node->global.inlined_to)
+ {
+ tree name = DECL_ASSEMBLER_NAME (node->decl);
+ slot = htab_find_slot_with_hash (assembler_name_hash, name,
+ decl_assembler_name_hash (name),
+ INSERT);
+ /* We can have multiple declarations with same assembler name. For C++
+ it is __builtin_strlen and strlen, for instance. Do we need to
+ record them all? Original implementation marked just first one
+ so lets hope for the best. */
+ if (*slot)
+ continue;
+ *slot = node;
+ }
+ }
+
+ slot = htab_find_slot_with_hash (assembler_name_hash, asmname,
+ decl_assembler_name_hash (asmname),
+ NO_INSERT);
+ if (slot)
+ return (struct cgraph_node *) *slot;
return NULL;
}
@@ -254,9 +503,12 @@ edge_eq (const void *x, const void *y)
return ((const struct cgraph_edge *) x)->call_stmt == y;
}
-/* Return callgraph edge representing CALL_EXPR statement. */
+
+/* Return the callgraph edge representing the GIMPLE_CALL statement
+ CALL_STMT. */
+
struct cgraph_edge *
-cgraph_edge (struct cgraph_node *node, tree call_stmt)
+cgraph_edge (struct cgraph_node *node, gimple call_stmt)
{
struct cgraph_edge *e, *e2;
int n = 0;
@@ -277,6 +529,7 @@ cgraph_edge (struct cgraph_node *node, tree call_stmt)
break;
n++;
}
+
if (n > 100)
{
node->call_site_hash = htab_create_ggc (120, edge_hash, edge_eq, NULL);
@@ -291,13 +544,15 @@ cgraph_edge (struct cgraph_node *node, tree call_stmt)
*slot = e2;
}
}
+
return e;
}
-/* Change call_stmt of edge E to NEW_STMT. */
+
+/* Change field call_smt of edge E to NEW_STMT. */
void
-cgraph_set_call_stmt (struct cgraph_edge *e, tree new_stmt)
+cgraph_set_call_stmt (struct cgraph_edge *e, gimple new_stmt)
{
if (e->caller->call_site_hash)
{
@@ -322,7 +577,7 @@ cgraph_set_call_stmt (struct cgraph_edge *e, tree new_stmt)
struct cgraph_edge *
cgraph_create_edge (struct cgraph_node *caller, struct cgraph_node *callee,
- tree call_stmt, gcov_type count, int freq, int nest)
+ gimple call_stmt, gcov_type count, int freq, int nest)
{
struct cgraph_edge *edge = GGC_NEW (struct cgraph_edge);
#ifdef ENABLE_CHECKING
@@ -332,9 +587,9 @@ cgraph_create_edge (struct cgraph_node *caller, struct cgraph_node *callee,
gcc_assert (e->call_stmt != call_stmt);
#endif
- gcc_assert (get_call_expr_in (call_stmt));
+ gcc_assert (is_gimple_call (call_stmt));
- if (!DECL_SAVED_TREE (callee->decl))
+ if (!gimple_body (callee->decl))
edge->inline_failed = N_("function body not available");
else if (callee->local.redefined_extern_inline)
edge->inline_failed = N_("redefined extern inline functions are not "
@@ -365,6 +620,8 @@ cgraph_create_edge (struct cgraph_node *caller, struct cgraph_node *callee,
gcc_assert (freq >= 0);
gcc_assert (freq <= CGRAPH_FREQ_MAX);
edge->loop_nest = nest;
+ edge->indirect_call = 0;
+ edge->uid = cgraph_edge_max_uid++;
if (caller->call_site_hash)
{
void **slot;
@@ -414,6 +671,7 @@ cgraph_edge_remove_caller (struct cgraph_edge *e)
void
cgraph_remove_edge (struct cgraph_edge *e)
{
+ cgraph_call_edge_removal_hooks (e);
/* Remove from callers list of the callee. */
cgraph_edge_remove_callee (e);
@@ -439,14 +697,15 @@ cgraph_redirect_edge_callee (struct cgraph_edge *e, struct cgraph_node *n)
e->callee = n;
}
-/* Update or remove corresponding cgraph edge if a call OLD_CALL
- in OLD_STMT changed into NEW_STMT. */
+
+/* Update or remove the corresponding cgraph edge if a GIMPLE_CALL
+ OLD_STMT changed into NEW_STMT. */
void
-cgraph_update_edges_for_call_stmt (tree old_stmt, tree old_call,
- tree new_stmt)
+cgraph_update_edges_for_call_stmt (gimple old_stmt, gimple new_stmt)
{
- tree new_call = get_call_expr_in (new_stmt);
+ tree new_call = (is_gimple_call (new_stmt)) ? gimple_call_fn (new_stmt) : 0;
+ tree old_call = (is_gimple_call (old_stmt)) ? gimple_call_fn (old_stmt) : 0;
struct cgraph_node *node = cgraph_node (cfun->decl);
if (old_call != new_call)
@@ -464,7 +723,7 @@ cgraph_update_edges_for_call_stmt (tree old_stmt, tree old_call,
cgraph_remove_edge (e);
if (new_call)
{
- new_decl = get_callee_fndecl (new_call);
+ new_decl = gimple_call_fndecl (new_stmt);
if (new_decl)
{
ne = cgraph_create_edge (node, cgraph_node (new_decl),
@@ -484,6 +743,7 @@ cgraph_update_edges_for_call_stmt (tree old_stmt, tree old_call,
}
}
+
/* Remove all callees from the node. */
void
@@ -495,7 +755,10 @@ cgraph_node_remove_callees (struct cgraph_node *node)
the callees. The callee list of the node can be zapped with one
assignment. */
for (e = node->callees; e; e = e->next_callee)
- cgraph_edge_remove_callee (e);
+ {
+ cgraph_call_edge_removal_hooks (e);
+ cgraph_edge_remove_callee (e);
+ }
node->callees = NULL;
if (node->call_site_hash)
{
@@ -515,7 +778,10 @@ cgraph_node_remove_callers (struct cgraph_node *node)
the callers. The caller list of the node can be zapped with one
assignment. */
for (e = node->callers; e; e = e->next_caller)
- cgraph_edge_remove_caller (e);
+ {
+ cgraph_call_edge_removal_hooks (e);
+ cgraph_edge_remove_caller (e);
+ }
node->callers = NULL;
}
@@ -533,6 +799,7 @@ cgraph_release_function_body (struct cgraph_node *node)
delete_tree_ssa ();
delete_tree_cfg_annotations ();
cfun->eh = NULL;
+ gimple_set_body (node->decl, NULL);
current_function_decl = old_decl;
pop_cfun();
}
@@ -549,8 +816,10 @@ cgraph_remove_node (struct cgraph_node *node)
void **slot;
bool kill_body = false;
+ cgraph_call_node_removal_hooks (node);
cgraph_node_remove_callers (node);
cgraph_node_remove_callees (node);
+
/* Incremental inlining access removed nodes stored in the postorder list.
*/
node->needed = node->reachable = false;
@@ -612,8 +881,18 @@ cgraph_remove_node (struct cgraph_node *node)
&& (TREE_ASM_WRITTEN (n->decl) || DECL_EXTERNAL (n->decl))))
kill_body = true;
}
+ if (assembler_name_hash)
+ {
+ tree name = DECL_ASSEMBLER_NAME (node->decl);
+ slot = htab_find_slot_with_hash (assembler_name_hash, name,
+ decl_assembler_name_hash (name),
+ NO_INSERT);
+ /* Inline clones are not hashed. */
+ if (slot && *slot == node)
+ htab_clear_slot (assembler_name_hash, slot);
+ }
- if (kill_body && flag_unit_at_a_time)
+ if (kill_body)
cgraph_release_function_body (node);
node->decl = NULL;
if (node->call_site_hash)
@@ -736,8 +1015,8 @@ dump_cgraph_node (FILE *f, struct cgraph_node *node)
fprintf (f, " needed");
else if (node->reachable)
fprintf (f, " reachable");
- if (DECL_SAVED_TREE (node->decl))
- fprintf (f, " tree");
+ if (gimple_body (node->decl))
+ fprintf (f, " body");
if (node->output)
fprintf (f, " output");
if (node->local.local)
@@ -768,6 +1047,8 @@ dump_cgraph_node (FILE *f, struct cgraph_node *node)
edge->frequency / (double)CGRAPH_FREQ_BASE);
if (!edge->inline_failed)
fprintf(f, "(inlined) ");
+ if (edge->indirect_call)
+ fprintf(f, "(indirect) ");
}
fprintf (f, "\n calls: ");
@@ -777,6 +1058,8 @@ dump_cgraph_node (FILE *f, struct cgraph_node *node)
edge->callee->uid);
if (!edge->inline_failed)
fprintf(f, "(inlined) ");
+ if (edge->indirect_call)
+ fprintf(f, "(indirect) ");
if (edge->count)
fprintf (f, "("HOST_WIDEST_INT_PRINT_DEC"x) ",
(HOST_WIDEST_INT)edge->count);
@@ -826,6 +1109,7 @@ debug_cgraph (void)
void
change_decl_assembler_name (tree decl, tree name)
{
+ gcc_assert (!assembler_name_hash);
if (!DECL_ASSEMBLER_NAME_SET_P (decl))
{
SET_DECL_ASSEMBLER_NAME (decl, name);
@@ -865,14 +1149,14 @@ bool
cgraph_function_possibly_inlined_p (tree decl)
{
if (!cgraph_global_info_ready)
- return (DECL_INLINE (decl) && !flag_really_no_inline);
+ return !DECL_UNINLINABLE (decl) && !flag_really_no_inline;
return DECL_POSSIBLY_INLINED (decl);
}
/* Create clone of E in the node N represented by CALL_EXPR the callgraph. */
struct cgraph_edge *
cgraph_clone_edge (struct cgraph_edge *e, struct cgraph_node *n,
- tree call_stmt, gcov_type count_scale, int freq_scale,
+ gimple call_stmt, gcov_type count_scale, int freq_scale,
int loop_nest, bool update_original)
{
struct cgraph_edge *new;
@@ -885,12 +1169,14 @@ cgraph_clone_edge (struct cgraph_edge *e, struct cgraph_node *n,
e->loop_nest + loop_nest);
new->inline_failed = e->inline_failed;
+ new->indirect_call = e->indirect_call;
if (update_original)
{
e->count -= new->count;
if (e->count < 0)
e->count = 0;
}
+ cgraph_call_edge_duplication_hooks (e, new);
return new;
}
@@ -901,8 +1187,8 @@ cgraph_clone_edge (struct cgraph_edge *e, struct cgraph_node *n,
function's profile to reflect the fact that part of execution is handled
by node. */
struct cgraph_node *
-cgraph_clone_node (struct cgraph_node *n, gcov_type count, int freq, int loop_nest,
- bool update_original)
+cgraph_clone_node (struct cgraph_node *n, gcov_type count, int freq,
+ int loop_nest, bool update_original)
{
struct cgraph_node *new = cgraph_create_node ();
struct cgraph_edge *e;
@@ -942,6 +1228,7 @@ cgraph_clone_node (struct cgraph_node *n, gcov_type count, int freq, int loop_ne
if (new->next_clone)
new->next_clone->prev_clone = new;
+ cgraph_call_node_duplication_hooks (n, new);
return new;
}
@@ -1057,8 +1344,8 @@ cgraph_add_new_function (tree fndecl, bool lowered)
{
push_cfun (DECL_STRUCT_FUNCTION (fndecl));
current_function_decl = fndecl;
- tree_register_cfg_hooks ();
- tree_lowering_passes (fndecl);
+ gimple_register_cfg_hooks ();
+ tree_lowering_passes (fndecl);
bitmap_obstack_initialize (NULL);
if (!gimple_in_ssa_p (DECL_STRUCT_FUNCTION (fndecl)))
execute_pass_list (pass_early_local_passes.pass.sub);
@@ -1079,11 +1366,11 @@ cgraph_add_new_function (tree fndecl, bool lowered)
to expansion. */
push_cfun (DECL_STRUCT_FUNCTION (fndecl));
current_function_decl = fndecl;
- tree_register_cfg_hooks ();
+ gimple_register_cfg_hooks ();
if (!lowered)
tree_lowering_passes (fndecl);
bitmap_obstack_initialize (NULL);
- if (!gimple_in_ssa_p (DECL_STRUCT_FUNCTION (fndecl)) && optimize)
+ if (!gimple_in_ssa_p (DECL_STRUCT_FUNCTION (fndecl)))
execute_pass_list (pass_early_local_passes.pass.sub);
bitmap_obstack_release (NULL);
tree_rest_of_compilation (fndecl);
diff --git a/gcc/cgraph.h b/gcc/cgraph.h
index dda2a1891f5..7a19dd6e059 100644
--- a/gcc/cgraph.h
+++ b/gcc/cgraph.h
@@ -91,7 +91,7 @@ struct cgraph_local_info GTY(())
};
/* Information about the function that needs to be computed globally
- once compilation is finished. Available only with -funit-at-time. */
+ once compilation is finished. Available only with -funit-at-a-time. */
struct cgraph_global_info GTY(())
{
@@ -100,7 +100,8 @@ struct cgraph_global_info GTY(())
/* Expected offset of the stack frame of inlined function. */
HOST_WIDE_INT stack_frame_offset;
- /* For inline clones this points to the function they will be inlined into. */
+ /* For inline clones this points to the function they will be
+ inlined into. */
struct cgraph_node *inlined_to;
/* Estimated size of the function after inlining. */
@@ -196,7 +197,7 @@ struct cgraph_edge GTY((chain_next ("%h.next_caller"), chain_prev ("%h.prev_call
struct cgraph_edge *next_caller;
struct cgraph_edge *prev_callee;
struct cgraph_edge *next_callee;
- tree call_stmt;
+ gimple call_stmt;
PTR GTY ((skip (""))) aux;
/* When NULL, inline this call. When non-NULL, points to the explanation
why function was not inlined. */
@@ -208,7 +209,11 @@ struct cgraph_edge GTY((chain_next ("%h.next_caller"), chain_prev ("%h.prev_call
per function call. The range is 0 to CGRAPH_FREQ_MAX. */
int frequency;
/* Depth of loop nest, 1 means no loop nest. */
- int loop_nest;
+ unsigned int loop_nest : 31;
+ /* Whether this edge describes a call that was originally indirect. */
+ unsigned int indirect_call : 1;
+ /* Unique id of the edge. */
+ int uid;
};
#define CGRAPH_FREQ_BASE 1000
@@ -222,7 +227,7 @@ DEF_VEC_ALLOC_P(cgraph_edge_p,heap);
/* The varpool data structure.
Each static variable decl has assigned varpool_node. */
-struct varpool_node GTY(())
+struct varpool_node GTY((chain_next ("%h.next")))
{
tree decl;
/* Pointer to the next function in varpool_nodes. */
@@ -266,6 +271,7 @@ struct cgraph_asm_node GTY(())
extern GTY(()) struct cgraph_node *cgraph_nodes;
extern GTY(()) int cgraph_n_nodes;
extern GTY(()) int cgraph_max_uid;
+extern GTY(()) int cgraph_edge_max_uid;
extern GTY(()) int cgraph_max_pid;
extern bool cgraph_global_info_ready;
enum cgraph_state
@@ -301,19 +307,19 @@ void cgraph_release_function_body (struct cgraph_node *);
void cgraph_node_remove_callees (struct cgraph_node *node);
struct cgraph_edge *cgraph_create_edge (struct cgraph_node *,
struct cgraph_node *,
- tree, gcov_type, int, int);
+ gimple, gcov_type, int, int);
struct cgraph_node *cgraph_node (tree);
struct cgraph_node *cgraph_node_for_asm (tree asmname);
-struct cgraph_edge *cgraph_edge (struct cgraph_node *, tree);
-void cgraph_set_call_stmt (struct cgraph_edge *, tree);
-void cgraph_update_edges_for_call_stmt (tree, tree, tree);
+struct cgraph_edge *cgraph_edge (struct cgraph_node *, gimple);
+void cgraph_set_call_stmt (struct cgraph_edge *, gimple);
+void cgraph_update_edges_for_call_stmt (gimple, gimple);
struct cgraph_local_info *cgraph_local_info (tree);
struct cgraph_global_info *cgraph_global_info (tree);
struct cgraph_rtl_info *cgraph_rtl_info (tree);
const char * cgraph_node_name (struct cgraph_node *);
struct cgraph_edge * cgraph_clone_edge (struct cgraph_edge *,
struct cgraph_node *,
- tree, gcov_type, int, int, bool);
+ gimple, gcov_type, int, int, bool);
struct cgraph_node * cgraph_clone_node (struct cgraph_node *, gcov_type, int,
int, bool);
@@ -351,8 +357,29 @@ struct cgraph_node *save_inline_function_body (struct cgraph_node *);
void record_references_in_initializer (tree);
bool cgraph_process_new_functions (void);
+typedef void (*cgraph_edge_hook)(struct cgraph_edge *, void *);
+typedef void (*cgraph_node_hook)(struct cgraph_node *, void *);
+typedef void (*cgraph_2edge_hook)(struct cgraph_edge *, struct cgraph_edge *,
+ void *);
+typedef void (*cgraph_2node_hook)(struct cgraph_node *, struct cgraph_node *,
+ void *);
+struct cgraph_edge_hook_list;
+struct cgraph_node_hook_list;
+struct cgraph_2edge_hook_list;
+struct cgraph_2node_hook_list;
+struct cgraph_edge_hook_list *cgraph_add_edge_removal_hook (cgraph_edge_hook, void *);
+void cgraph_remove_edge_removal_hook (struct cgraph_edge_hook_list *);
+struct cgraph_node_hook_list *cgraph_add_node_removal_hook (cgraph_node_hook,
+ void *);
+void cgraph_remove_node_removal_hook (struct cgraph_node_hook_list *);
+struct cgraph_2edge_hook_list *cgraph_add_edge_duplication_hook (cgraph_2edge_hook, void *);
+void cgraph_remove_edge_duplication_hook (struct cgraph_2edge_hook_list *);
+struct cgraph_2node_hook_list *cgraph_add_node_duplication_hook (cgraph_2node_hook, void *);
+void cgraph_remove_node_duplication_hook (struct cgraph_2node_hook_list *);
+
/* In cgraphbuild.c */
unsigned int rebuild_cgraph_edges (void);
+int compute_call_stmt_bb_frequency (basic_block bb);
/* In ipa.c */
bool cgraph_remove_unreachable_nodes (bool, FILE *);
@@ -378,6 +405,7 @@ bool varpool_assemble_decl (struct varpool_node *node);
bool varpool_analyze_pending_decls (void);
void varpool_output_debug_info (void);
void varpool_remove_unreferenced_decls (void);
+void varpool_empty_needed_queue (void);
/* Walk all reachable static variables. */
#define FOR_EACH_STATIC_VARIABLE(node) \
diff --git a/gcc/cgraphbuild.c b/gcc/cgraphbuild.c
index 19e198344b6..958fed7b0cc 100644
--- a/gcc/cgraphbuild.c
+++ b/gcc/cgraphbuild.c
@@ -1,5 +1,6 @@
/* Callgraph construction.
- Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
+ Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008
+ Free Software Foundation, Inc.
Contributed by Jan Hubicka
This file is part of GCC.
@@ -28,7 +29,7 @@ along with GCC; see the file COPYING3. If not see
#include "pointer-set.h"
#include "cgraph.h"
#include "intl.h"
-#include "tree-gimple.h"
+#include "gimple.h"
#include "tree-pass.h"
/* Walk tree and record all calls and references to functions/variables.
@@ -38,6 +39,7 @@ static tree
record_reference (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
{
tree t = *tp;
+ tree decl;
switch (TREE_CODE (t))
{
@@ -52,32 +54,11 @@ record_reference (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
case FDESC_EXPR:
case ADDR_EXPR:
- if (flag_unit_at_a_time)
- {
- /* Record dereferences to the functions. This makes the
- functions reachable unconditionally. */
- tree decl = TREE_OPERAND (*tp, 0);
- if (TREE_CODE (decl) == FUNCTION_DECL)
- cgraph_mark_needed_node (cgraph_node (decl));
- }
- break;
-
- case OMP_PARALLEL:
- if (flag_unit_at_a_time)
- {
- if (OMP_PARALLEL_FN (*tp))
- cgraph_mark_needed_node (cgraph_node (OMP_PARALLEL_FN (*tp)));
- }
- break;
-
- case OMP_TASK:
- if (flag_unit_at_a_time)
- {
- if (OMP_TASK_FN (*tp))
- cgraph_mark_needed_node (cgraph_node (OMP_TASK_FN (*tp)));
- if (OMP_TASK_COPYFN (*tp))
- cgraph_mark_needed_node (cgraph_node (OMP_TASK_COPYFN (*tp)));
- }
+ /* Record dereferences to the functions. This makes the
+ functions reachable unconditionally. */
+ decl = TREE_OPERAND (*tp, 0);
+ if (TREE_CODE (decl) == FUNCTION_DECL)
+ cgraph_mark_needed_node (cgraph_node (decl));
break;
default:
@@ -115,13 +96,32 @@ initialize_inline_failed (struct cgraph_node *node)
"considered for inlining");
else if (!node->local.inlinable)
e->inline_failed = N_("function not inlinable");
- else if (CALL_STMT_CANNOT_INLINE_P (e->call_stmt))
+ else if (gimple_call_cannot_inline_p (e->call_stmt))
e->inline_failed = N_("mismatched arguments");
else
e->inline_failed = N_("function not considered for inlining");
}
}
+/* Computes the frequency of the call statement so that it can be stored in
+ cgraph_edge. BB is the basic block of the call statement. */
+int
+compute_call_stmt_bb_frequency (basic_block bb)
+{
+ int entry_freq = ENTRY_BLOCK_PTR->frequency;
+ int freq;
+
+ if (!entry_freq)
+ entry_freq = 1;
+
+ freq = (!bb->frequency && !entry_freq ? CGRAPH_FREQ_BASE
+ : bb->frequency * CGRAPH_FREQ_BASE / entry_freq);
+ if (freq > CGRAPH_FREQ_MAX)
+ freq = CGRAPH_FREQ_MAX;
+
+ return freq;
+}
+
/* Create cgraph edges for function calls.
Also look for functions and variables having addresses taken. */
@@ -131,42 +131,54 @@ build_cgraph_edges (void)
basic_block bb;
struct cgraph_node *node = cgraph_node (current_function_decl);
struct pointer_set_t *visited_nodes = pointer_set_create ();
- block_stmt_iterator bsi;
+ gimple_stmt_iterator gsi;
tree step;
- int entry_freq = ENTRY_BLOCK_PTR->frequency;
-
- if (!entry_freq)
- entry_freq = 1;
/* Create the callgraph edges and record the nodes referenced by the function.
body. */
FOR_EACH_BB (bb)
- for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
- tree stmt = bsi_stmt (bsi);
- tree call = get_call_expr_in (stmt);
+ gimple stmt = gsi_stmt (gsi);
tree decl;
- if (call && (decl = get_callee_fndecl (call)))
+ if (is_gimple_call (stmt) && (decl = gimple_call_fndecl (stmt)))
{
- int i;
- int n = call_expr_nargs (call);
- int freq = (!bb->frequency && !entry_freq ? CGRAPH_FREQ_BASE
- : bb->frequency * CGRAPH_FREQ_BASE / entry_freq);
- if (freq > CGRAPH_FREQ_MAX)
- freq = CGRAPH_FREQ_MAX;
+ size_t i;
+ size_t n = gimple_call_num_args (stmt);
cgraph_create_edge (node, cgraph_node (decl), stmt,
- bb->count, freq,
+ bb->count, compute_call_stmt_bb_frequency (bb),
bb->loop_depth);
for (i = 0; i < n; i++)
- walk_tree (&CALL_EXPR_ARG (call, i),
- record_reference, node, visited_nodes);
- if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT)
- walk_tree (&GIMPLE_STMT_OPERAND (stmt, 0),
- record_reference, node, visited_nodes);
+ walk_tree (gimple_call_arg_ptr (stmt, i), record_reference,
+ node, visited_nodes);
+ if (gimple_call_lhs (stmt))
+ walk_tree (gimple_call_lhs_ptr (stmt), record_reference, node,
+ visited_nodes);
}
else
- walk_tree (bsi_stmt_ptr (bsi), record_reference, node, visited_nodes);
+ {
+ struct walk_stmt_info wi;
+ memset (&wi, 0, sizeof (wi));
+ wi.info = node;
+ wi.pset = visited_nodes;
+ walk_gimple_op (stmt, record_reference, &wi);
+ if (gimple_code (stmt) == GIMPLE_OMP_PARALLEL
+ && gimple_omp_parallel_child_fn (stmt))
+ {
+ tree fn = gimple_omp_parallel_child_fn (stmt);
+ cgraph_mark_needed_node (cgraph_node (fn));
+ }
+ if (gimple_code (stmt) == GIMPLE_OMP_TASK)
+ {
+ tree fn = gimple_omp_task_child_fn (stmt);
+ if (fn)
+ cgraph_mark_needed_node (cgraph_node (fn));
+ fn = gimple_omp_task_copy_fn (stmt);
+ if (fn)
+ cgraph_mark_needed_node (cgraph_node (fn));
+ }
+ }
}
/* Look for initializers of constant variables and private statics. */
@@ -176,8 +188,7 @@ build_cgraph_edges (void)
{
tree decl = TREE_VALUE (step);
if (TREE_CODE (decl) == VAR_DECL
- && (TREE_STATIC (decl) && !DECL_EXTERNAL (decl))
- && flag_unit_at_a_time)
+ && (TREE_STATIC (decl) && !DECL_EXTERNAL (decl)))
varpool_finalize_decl (decl);
else if (TREE_CODE (decl) == VAR_DECL && DECL_INITIAL (decl))
walk_tree (&DECL_INITIAL (decl), record_reference, node, visited_nodes);
@@ -226,32 +237,23 @@ rebuild_cgraph_edges (void)
{
basic_block bb;
struct cgraph_node *node = cgraph_node (current_function_decl);
- block_stmt_iterator bsi;
- int entry_freq = ENTRY_BLOCK_PTR->frequency;
-
- if (!entry_freq)
- entry_freq = 1;
+ gimple_stmt_iterator gsi;
cgraph_node_remove_callees (node);
node->count = ENTRY_BLOCK_PTR->count;
FOR_EACH_BB (bb)
- for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
- tree stmt = bsi_stmt (bsi);
- tree call = get_call_expr_in (stmt);
+ gimple stmt = gsi_stmt (gsi);
tree decl;
- if (call && (decl = get_callee_fndecl (call)))
- {
- int freq = (!bb->frequency && !entry_freq ? CGRAPH_FREQ_BASE
- : bb->frequency * CGRAPH_FREQ_BASE / entry_freq);
- if (freq > CGRAPH_FREQ_MAX)
- freq = CGRAPH_FREQ_MAX;
- cgraph_create_edge (node, cgraph_node (decl), stmt,
- bb->count, freq, bb->loop_depth);
- }
+ if (is_gimple_call (stmt) && (decl = gimple_call_fndecl (stmt)))
+ cgraph_create_edge (node, cgraph_node (decl), stmt,
+ bb->count, compute_call_stmt_bb_frequency (bb),
+ bb->loop_depth);
+
}
initialize_inline_failed (node);
gcc_assert (!node->global.inlined_to);
diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
index 2dcccc1bd93..48dd70bcac7 100644
--- a/gcc/cgraphunit.c
+++ b/gcc/cgraphunit.c
@@ -45,7 +45,7 @@ along with GCC; see the file COPYING3. If not see
This function is called once (source level) compilation unit is finalized
and it will no longer change.
- In the unit-at-a-time the call-graph construction and local function
+ In the the call-graph construction and local function
analysis takes place here. Bodies of unreachable functions are released
to conserve memory usage.
@@ -77,9 +77,7 @@ along with GCC; see the file COPYING3. If not see
??? On the tree-ssa genericizing should take place here and we will avoid
need for these hooks (replacing them by genericizing hook)
- We implement two compilation modes.
-
- - unit-at-a-time: In this mode analyzing of all functions is deferred
+ Analyzing of all functions is deferred
to cgraph_finalize_compilation_unit and expansion into cgraph_optimize.
In cgraph_finalize_compilation_unit the reachable functions are
@@ -105,23 +103,7 @@ along with GCC; see the file COPYING3. If not see
??? Reorganize code so variables are output very last and only if they
really has been referenced by produced code, so we catch more cases
- where reference has been optimized out.
-
- - non-unit-at-a-time
-
- All functions are variables are output as early as possible to conserve
- memory consumption. This may or may not result in less memory used but
- it is still needed for some legacy code that rely on particular ordering
- of things output from the compiler.
-
- Varpool data structures are not used and variables are output directly.
-
- Functions are output early using call of
- cgraph_assemble_pending_function from cgraph_finalize_function. The
- decision on whether function is needed is made more conservative so
- uninlinable static functions are needed too. During the call-graph
- construction the edge destinations are not marked as reachable and it
- is completely relied upon assemble_variable to mark them. */
+ where reference has been optimized out. */
#include "config.h"
@@ -148,7 +130,8 @@ along with GCC; see the file COPYING3. If not see
#include "intl.h"
#include "function.h"
#include "ipa-prop.h"
-#include "tree-gimple.h"
+#include "gimple.h"
+#include "tree-iterator.h"
#include "tree-pass.h"
#include "output.h"
@@ -190,7 +173,6 @@ record_cdtor_fn (tree fndecl)
VEC_safe_push (tree, gc, static_dtors, fndecl);
DECL_STATIC_DESTRUCTOR (fndecl) = 0;
}
- DECL_INLINE (fndecl) = 1;
node = cgraph_node (fndecl);
node->local.disregard_inline_limits = 1;
cgraph_mark_reachable_node (node);
@@ -326,13 +308,11 @@ cgraph_build_cdtor_fns (void)
/* Determine if function DECL is needed. That is, visible to something
either outside this translation unit, something magic in the system
- configury, or (if not doing unit-at-a-time) to something we haven't
- seen yet. */
+ configury. */
static bool
decide_is_function_needed (struct cgraph_node *node, tree decl)
{
- tree origin;
if (MAIN_NAME_P (DECL_NAME (decl))
&& TREE_PUBLIC (decl))
{
@@ -344,9 +324,6 @@ decide_is_function_needed (struct cgraph_node *node, tree decl)
if (node->local.externally_visible)
return true;
- if (!flag_unit_at_a_time && lookup_attribute ("used", DECL_ATTRIBUTES (decl)))
- return true;
-
/* ??? If the assembler name is set by hand, it is possible to assemble
the name later after finalizing the function and the fact is noticed
in assemble_name then. This is arguably a bug. */
@@ -389,32 +366,6 @@ decide_is_function_needed (struct cgraph_node *node, tree decl)
if (DECL_STATIC_CONSTRUCTOR (decl) || DECL_STATIC_DESTRUCTOR (decl))
return true;
- if (flag_unit_at_a_time)
- return false;
-
- /* If not doing unit at a time, then we'll only defer this function
- if its marked for inlining. Otherwise we want to emit it now. */
-
- /* "extern inline" functions are never output locally. */
- if (DECL_EXTERNAL (decl))
- return false;
- /* Nested functions of extern inline function shall not be emit unless
- we inlined the origin. */
- for (origin = decl_function_context (decl); origin;
- origin = decl_function_context (origin))
- if (DECL_EXTERNAL (origin))
- return false;
- /* We want to emit COMDAT functions only when absolutely necessary. */
- if (DECL_COMDAT (decl))
- return false;
- if (!DECL_INLINE (decl)
- || (!node->local.disregard_inline_limits
- /* When declared inline, defer even the uninlinable functions.
- This allows them to be eliminated when unused. */
- && !DECL_DECLARED_INLINE_P (decl)
- && (!node->local.inlinable || !cgraph_default_inline_p (node, NULL))))
- return true;
-
return false;
}
@@ -454,7 +405,7 @@ cgraph_process_new_functions (void)
transformations that has been already performed on the whole
cgraph but not on this function. */
- tree_register_cfg_hooks ();
+ gimple_register_cfg_hooks ();
if (!node->analyzed)
cgraph_analyze_function (node);
push_cfun (DECL_STRUCT_FUNCTION (fndecl));
@@ -487,39 +438,6 @@ cgraph_process_new_functions (void)
return output;
}
-/* When not doing unit-at-a-time, output all functions enqueued.
- Return true when such a functions were found. */
-
-static bool
-cgraph_assemble_pending_functions (void)
-{
- bool output = false;
-
- if (flag_unit_at_a_time || errorcount || sorrycount)
- return false;
-
- cgraph_output_pending_asms ();
-
- while (cgraph_nodes_queue)
- {
- struct cgraph_node *n = cgraph_nodes_queue;
-
- cgraph_nodes_queue = cgraph_nodes_queue->next_needed;
- n->next_needed = NULL;
- if (!n->global.inlined_to
- && !n->alias
- && !DECL_EXTERNAL (n->decl))
- {
- cgraph_expand_function (n);
- output = true;
- }
- output |= cgraph_process_new_functions ();
- }
-
- return output;
-}
-
-
/* As an GCC extension we allow redefinition of the function. The
semantics when both copies of bodies differ is not well defined.
We replace the old body with new body so in unit at a time mode
@@ -533,12 +451,11 @@ cgraph_assemble_pending_functions (void)
static void
cgraph_reset_node (struct cgraph_node *node)
{
- /* If node->output is set, then this is a unit-at-a-time compilation
- and we have already begun whole-unit analysis. This is *not*
- testing for whether we've already emitted the function. That
- case can be sort-of legitimately seen with real function
- redefinition errors. I would argue that the front end should
- never present us with such a case, but don't enforce that for now. */
+ /* If node->output is set, then we have already begun whole-unit analysis.
+ This is *not* testing for whether we've already emitted the function.
+ That case can be sort-of legitimately seen with real function redefinition
+ errors. I would argue that the front end should never present us with
+ such a case, but don't enforce that for now. */
gcc_assert (!node->output);
/* Reset our data structures so we can analyze the function again. */
@@ -549,18 +466,6 @@ cgraph_reset_node (struct cgraph_node *node)
node->local.redefined_extern_inline = true;
node->local.finalized = false;
- if (!flag_unit_at_a_time)
- {
- struct cgraph_node *n, *next;
-
- for (n = cgraph_nodes; n; n = next)
- {
- next = n->next;
- if (n->global.inlined_to == node)
- cgraph_remove_node (n);
- }
- }
-
cgraph_node_remove_callees (node);
/* We may need to re-queue the node for assembling in case
@@ -609,11 +514,6 @@ cgraph_finalize_function (tree decl, bool nested)
lower_nested_functions (decl);
gcc_assert (!node->nested);
- /* If not unit at a time, then we need to create the call graph
- now, so that called functions can be queued and emitted now. */
- if (!flag_unit_at_a_time)
- cgraph_analyze_function (node);
-
if (decide_is_function_needed (node, decl))
cgraph_mark_needed_node (node);
@@ -623,14 +523,6 @@ cgraph_finalize_function (tree decl, bool nested)
if ((TREE_PUBLIC (decl) && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl)))
cgraph_mark_reachable_node (node);
- /* If not unit at a time, go ahead and emit everything we've found
- to be reachable at this time. */
- if (!nested)
- {
- if (!cgraph_assemble_pending_functions ())
- ggc_collect ();
- }
-
/* If we've not yet emitted decl, tell the debug info about it. */
if (!TREE_ASM_WRITTEN (decl))
(*debug_hooks->deferred_inline_function) (decl);
@@ -638,6 +530,9 @@ cgraph_finalize_function (tree decl, bool nested)
/* Possibly warn about unused parameters. */
if (warn_unused_parameter)
do_warn_unused_parameter (decl);
+
+ if (!nested)
+ ggc_collect ();
}
/* C99 extern inline keywords allow changing of declaration after function
@@ -661,7 +556,7 @@ verify_cgraph_node (struct cgraph_node *node)
struct function *this_cfun = DECL_STRUCT_FUNCTION (node->decl);
struct function *saved_cfun = cfun;
basic_block this_block;
- block_stmt_iterator bsi;
+ gimple_stmt_iterator gsi;
bool error_found = false;
if (errorcount || sorrycount)
@@ -743,7 +638,8 @@ verify_cgraph_node (struct cgraph_node *node)
}
if (node->analyzed
- && DECL_SAVED_TREE (node->decl) && !TREE_ASM_WRITTEN (node->decl)
+ && gimple_body (node->decl)
+ && !TREE_ASM_WRITTEN (node->decl)
&& (!DECL_EXTERNAL (node->decl) || node->global.inlined_to))
{
if (this_cfun->cfg)
@@ -754,12 +650,13 @@ verify_cgraph_node (struct cgraph_node *node)
/* Reach the trees by walking over the CFG, and note the
enclosing basic-blocks in the call edges. */
FOR_EACH_BB_FN (this_block, this_cfun)
- for (bsi = bsi_start (this_block); !bsi_end_p (bsi); bsi_next (&bsi))
+ for (gsi = gsi_start_bb (this_block);
+ !gsi_end_p (gsi);
+ gsi_next (&gsi))
{
- tree stmt = bsi_stmt (bsi);
- tree call = get_call_expr_in (stmt);
+ gimple stmt = gsi_stmt (gsi);
tree decl;
- if (call && (decl = get_callee_fndecl (call)))
+ if (is_gimple_call (stmt) && (decl = gimple_call_fndecl (stmt)))
{
struct cgraph_edge *e = cgraph_edge (node, stmt);
if (e)
@@ -767,7 +664,7 @@ verify_cgraph_node (struct cgraph_node *node)
if (e->aux)
{
error ("shared call_stmt:");
- debug_generic_stmt (stmt);
+ debug_gimple_stmt (stmt);
error_found = true;
}
if (e->callee->decl != cgraph_node (decl)->decl
@@ -783,7 +680,7 @@ verify_cgraph_node (struct cgraph_node *node)
else
{
error ("missing callgraph edge for call stmt:");
- debug_generic_stmt (stmt);
+ debug_gimple_stmt (stmt);
error_found = true;
}
}
@@ -796,12 +693,12 @@ verify_cgraph_node (struct cgraph_node *node)
for (e = node->callees; e; e = e->next_callee)
{
- if (!e->aux)
+ if (!e->aux && !e->indirect_call)
{
error ("edge %s->%s has no corresponding call_stmt",
cgraph_node_name (e->caller),
cgraph_node_name (e->callee));
- debug_generic_stmt (e->call_stmt);
+ debug_gimple_stmt (e->call_stmt);
error_found = true;
}
e->aux = 0;
@@ -855,16 +752,6 @@ cgraph_analyze_function (struct cgraph_node *node)
cgraph_lower_function (node);
node->analyzed = true;
- if (!flag_unit_at_a_time && !sorrycount && !errorcount)
- {
- bitmap_obstack_initialize (NULL);
- tree_register_cfg_hooks ();
- execute_pass_list (pass_early_local_passes.pass.sub);
- free_dominance_info (CDI_POST_DOMINATORS);
- free_dominance_info (CDI_DOMINATORS);
- bitmap_obstack_release (NULL);
- }
-
pop_cfun ();
current_function_decl = NULL;
}
@@ -972,7 +859,7 @@ cgraph_analyze_functions (void)
{
fprintf (cgraph_dump_file, "Initial entry points:");
for (node = cgraph_nodes; node != first_analyzed; node = node->next)
- if (node->needed && DECL_SAVED_TREE (node->decl))
+ if (node->needed && gimple_body (node->decl))
fprintf (cgraph_dump_file, " %s", cgraph_node_name (node));
fprintf (cgraph_dump_file, "\n");
}
@@ -994,14 +881,14 @@ cgraph_analyze_functions (void)
/* ??? It is possible to create extern inline function and later using
weak alias attribute to kill its body. See
gcc.c-torture/compile/20011119-1.c */
- if (!DECL_SAVED_TREE (decl))
+ if (!DECL_STRUCT_FUNCTION (decl))
{
cgraph_reset_node (node);
continue;
}
gcc_assert (!node->analyzed && node->reachable);
- gcc_assert (DECL_SAVED_TREE (decl));
+ gcc_assert (gimple_body (decl));
cgraph_analyze_function (node);
@@ -1024,7 +911,7 @@ cgraph_analyze_functions (void)
{
fprintf (cgraph_dump_file, "Unit entry points:");
for (node = cgraph_nodes; node != first_analyzed; node = node->next)
- if (node->needed && DECL_SAVED_TREE (node->decl))
+ if (node->needed && gimple_body (node->decl))
fprintf (cgraph_dump_file, " %s", cgraph_node_name (node));
fprintf (cgraph_dump_file, "\n\nInitial ");
dump_cgraph (cgraph_dump_file);
@@ -1038,10 +925,10 @@ cgraph_analyze_functions (void)
tree decl = node->decl;
next = node->next;
- if (node->local.finalized && !DECL_SAVED_TREE (decl))
+ if (node->local.finalized && !gimple_body (decl))
cgraph_reset_node (node);
- if (!node->reachable && DECL_SAVED_TREE (decl))
+ if (!node->reachable && gimple_body (decl))
{
if (cgraph_dump_file)
fprintf (cgraph_dump_file, " %s", cgraph_node_name (node));
@@ -1050,7 +937,7 @@ cgraph_analyze_functions (void)
}
else
node->next_needed = NULL;
- gcc_assert (!node->local.finalized || DECL_SAVED_TREE (decl));
+ gcc_assert (!node->local.finalized || gimple_body (decl));
gcc_assert (node->analyzed == node->local.finalized);
}
if (cgraph_dump_file)
@@ -1072,14 +959,6 @@ cgraph_finalize_compilation_unit (void)
finish_aliases_1 ();
- if (!flag_unit_at_a_time)
- {
- cgraph_output_pending_asms ();
- cgraph_assemble_pending_functions ();
- varpool_output_debug_info ();
- return;
- }
-
if (!quiet_flag)
{
fprintf (stderr, "\nAnalyzing compilation unit\n");
@@ -1111,7 +990,7 @@ cgraph_mark_functions_to_output (void)
/* We need to output all local functions that are used and not
always inlined, as well as those that are reachable from
outside the current compilation unit. */
- if (DECL_SAVED_TREE (decl)
+ if (gimple_body (decl)
&& !node->global.inlined_to
&& (node->needed
|| (e && node->reachable))
@@ -1122,14 +1001,16 @@ cgraph_mark_functions_to_output (void)
{
/* We should've reclaimed all functions that are not needed. */
#ifdef ENABLE_CHECKING
- if (!node->global.inlined_to && DECL_SAVED_TREE (decl)
+ if (!node->global.inlined_to
+ && gimple_body (decl)
&& !DECL_EXTERNAL (decl))
{
dump_cgraph_node (stderr, node);
internal_error ("failed to reclaim unneeded function");
}
#endif
- gcc_assert (node->global.inlined_to || !DECL_SAVED_TREE (decl)
+ gcc_assert (node->global.inlined_to
+ || !gimple_body (decl)
|| DECL_EXTERNAL (decl));
}
@@ -1147,8 +1028,7 @@ cgraph_expand_function (struct cgraph_node *node)
/* We ought to not compile any inline clones. */
gcc_assert (!node->global.inlined_to);
- if (flag_unit_at_a_time)
- announce_function (decl);
+ announce_function (decl);
gcc_assert (node->lowered);
@@ -1160,7 +1040,6 @@ cgraph_expand_function (struct cgraph_node *node)
/* Make sure that BE didn't give up on compiling. */
/* ??? Can happen with nested function of extern inline. */
gcc_assert (TREE_ASM_WRITTEN (decl));
-
current_function_decl = NULL;
if (!cgraph_preserve_function_body_p (decl))
{
@@ -1291,6 +1170,16 @@ cgraph_output_in_order (void)
nodes[i].u.a = pa;
}
+ /* In toplevel reorder mode we output all statics; mark them as needed. */
+ for (i = 0; i < max; ++i)
+ {
+ if (nodes[i].kind == ORDER_VAR)
+ {
+ varpool_mark_needed_node (nodes[i].u.v);
+ }
+ }
+ varpool_empty_needed_queue ();
+
for (i = 0; i < max; ++i)
{
switch (nodes[i].kind)
@@ -1325,10 +1214,8 @@ bool
cgraph_preserve_function_body_p (tree decl)
{
struct cgraph_node *node;
- if (!cgraph_global_info_ready)
- return (flag_really_no_inline
- ? DECL_DISREGARD_INLINE_LIMITS (decl)
- : DECL_INLINE (decl));
+
+ gcc_assert (cgraph_global_info_ready);
/* Look if there is any clone around. */
for (node = cgraph_node (decl); node; node = node->next_clone)
if (node->global.inlined_to)
@@ -1341,7 +1228,7 @@ ipa_passes (void)
{
set_cfun (NULL);
current_function_decl = NULL;
- tree_register_cfg_hooks ();
+ gimple_register_cfg_hooks ();
bitmap_obstack_initialize (NULL);
execute_ipa_pass_list (all_ipa_passes);
bitmap_obstack_release (NULL);
@@ -1362,16 +1249,6 @@ cgraph_optimize (void)
/* Call functions declared with the "constructor" or "destructor"
attribute. */
cgraph_build_cdtor_fns ();
- if (!flag_unit_at_a_time)
- {
- cgraph_assemble_pending_functions ();
- cgraph_process_new_functions ();
- cgraph_state = CGRAPH_STATE_FINISHED;
- cgraph_output_pending_asms ();
- varpool_assemble_pending_decls ();
- varpool_output_debug_info ();
- return;
- }
/* Frontend may output common variables after the unit has been finalized.
It is safe to deal with them here as they are always zero initialized. */
@@ -1443,8 +1320,7 @@ cgraph_optimize (void)
verify_cgraph ();
/* Double check that all inline clones are gone and that all
function bodies have been released from memory. */
- if (flag_unit_at_a_time
- && !(sorrycount || errorcount))
+ if (!(sorrycount || errorcount))
{
struct cgraph_node *node;
bool error_found = false;
@@ -1452,7 +1328,7 @@ cgraph_optimize (void)
for (node = cgraph_nodes; node; node = node->next)
if (node->analyzed
&& (node->global.inlined_to
- || DECL_SAVED_TREE (node->decl)))
+ || gimple_body (node->decl)))
{
error_found = true;
dump_cgraph_node (stderr, node);
@@ -1541,10 +1417,10 @@ update_call_expr (struct cgraph_node *new_version)
struct cgraph_edge *e;
gcc_assert (new_version);
+
+ /* Update the call expr on the edges to call the new version. */
for (e = new_version->callers; e; e = e->next_caller)
- /* Update the call expr on the edges
- to call the new version. */
- TREE_OPERAND (CALL_EXPR_FN (get_call_expr_in (e->call_stmt)), 0) = new_version->decl;
+ gimple_call_set_fn (e->call_stmt, new_version->decl);
}
@@ -1673,29 +1549,10 @@ save_inline_function_body (struct cgraph_node *node)
cgraph_lower_function (node);
- /* In non-unit-at-a-time we construct full fledged clone we never output to
- assembly file. This clone is pointed out by inline_decl of original function
- and inlining infrastructure knows how to deal with this. */
- if (!flag_unit_at_a_time)
- {
- struct cgraph_edge *e;
-
- first_clone = cgraph_clone_node (node, node->count, 0, CGRAPH_FREQ_BASE,
- false);
- first_clone->needed = 0;
- first_clone->reachable = 1;
- /* Recursively clone all bodies. */
- for (e = first_clone->callees; e; e = e->next_callee)
- if (!e->inline_failed)
- cgraph_clone_inlined_nodes (e, true, false);
- }
- else
- first_clone = node->next_clone;
+ first_clone = node->next_clone;
first_clone->decl = copy_node (node->decl);
node->next_clone = NULL;
- if (!flag_unit_at_a_time)
- node->inline_decl = first_clone->decl;
first_clone->prev_clone = NULL;
cgraph_insert_node_to_hashtable (first_clone);
gcc_assert (first_clone == cgraph_node (first_clone->decl));
diff --git a/gcc/collect2.c b/gcc/collect2.c
index 314d30d7717..cdfe4e6be6d 100644
--- a/gcc/collect2.c
+++ b/gcc/collect2.c
@@ -236,8 +236,21 @@ static struct path_prefix *libpaths[3] = {&cmdline_lib_dirs,
&libpath_lib_dirs, NULL};
#endif
+/* Special kinds of symbols that a name may denote. */
+
+typedef enum {
+ SYM_REGULAR = 0, /* nothing special */
+
+ SYM_CTOR = 1, /* constructor */
+ SYM_DTOR = 2, /* destructor */
+ SYM_INIT = 3, /* shared object routine that calls all the ctors */
+ SYM_FINI = 4, /* shared object routine that calls all the dtors */
+ SYM_DWEH = 5 /* DWARF exception handling table */
+} symkind;
+
+static symkind is_ctor_dtor (const char *);
+
static void handler (int);
-static int is_ctor_dtor (const char *);
static char *find_a_file (struct path_prefix *, const char *);
static void add_prefix (struct path_prefix *, const char *);
static void prefix_from_env (const char *, struct path_prefix *);
@@ -519,12 +532,9 @@ dump_file (const char *name, FILE *to)
fclose (stream);
}
-/* Decide whether the given symbol is: a constructor (1), a destructor
- (2), a routine in a shared object that calls all the constructors
- (3) or destructors (4), a DWARF exception-handling table (5), or
- nothing special (0). */
+/* Return the kind of symbol denoted by name S. */
-static int
+static symkind
is_ctor_dtor (const char *s)
{
struct names { const char *const name; const int len; const int ret;
@@ -536,27 +546,27 @@ is_ctor_dtor (const char *s)
static const struct names special[] = {
#ifndef NO_DOLLAR_IN_LABEL
- { "GLOBAL__I$", sizeof ("GLOBAL__I$")-1, 1, 0 },
- { "GLOBAL__D$", sizeof ("GLOBAL__D$")-1, 2, 0 },
+ { "GLOBAL__I$", sizeof ("GLOBAL__I$")-1, SYM_CTOR, 0 },
+ { "GLOBAL__D$", sizeof ("GLOBAL__D$")-1, SYM_DTOR, 0 },
#else
#ifndef NO_DOT_IN_LABEL
- { "GLOBAL__I.", sizeof ("GLOBAL__I.")-1, 1, 0 },
- { "GLOBAL__D.", sizeof ("GLOBAL__D.")-1, 2, 0 },
+ { "GLOBAL__I.", sizeof ("GLOBAL__I.")-1, SYM_CTOR, 0 },
+ { "GLOBAL__D.", sizeof ("GLOBAL__D.")-1, SYM_DTOR, 0 },
#endif /* NO_DOT_IN_LABEL */
#endif /* NO_DOLLAR_IN_LABEL */
- { "GLOBAL__I_", sizeof ("GLOBAL__I_")-1, 1, 0 },
- { "GLOBAL__D_", sizeof ("GLOBAL__D_")-1, 2, 0 },
- { "GLOBAL__F_", sizeof ("GLOBAL__F_")-1, 5, 0 },
- { "GLOBAL__FI_", sizeof ("GLOBAL__FI_")-1, 3, 0 },
- { "GLOBAL__FD_", sizeof ("GLOBAL__FD_")-1, 4, 0 },
- { NULL, 0, 0, 0 }
+ { "GLOBAL__I_", sizeof ("GLOBAL__I_")-1, SYM_CTOR, 0 },
+ { "GLOBAL__D_", sizeof ("GLOBAL__D_")-1, SYM_DTOR, 0 },
+ { "GLOBAL__F_", sizeof ("GLOBAL__F_")-1, SYM_DWEH, 0 },
+ { "GLOBAL__FI_", sizeof ("GLOBAL__FI_")-1, SYM_INIT, 0 },
+ { "GLOBAL__FD_", sizeof ("GLOBAL__FD_")-1, SYM_FINI, 0 },
+ { NULL, 0, SYM_REGULAR, 0 }
};
while ((ch = *s) == '_')
++s;
if (s == orig_s)
- return 0;
+ return SYM_REGULAR;
for (p = &special[0]; p->len > 0; p++)
{
@@ -567,7 +577,7 @@ is_ctor_dtor (const char *s)
return p->ret;
}
}
- return 0;
+ return SYM_REGULAR;
}
/* We maintain two prefix lists: one from COMPILER_PATH environment variable
@@ -2171,17 +2181,17 @@ scan_prog_file (const char *prog_name, enum pass which_pass)
*end = '\0';
switch (is_ctor_dtor (name))
{
- case 1:
+ case SYM_CTOR:
if (which_pass != PASS_LIB)
add_to_list (&constructors, name);
break;
- case 2:
+ case SYM_DTOR:
if (which_pass != PASS_LIB)
add_to_list (&destructors, name);
break;
- case 3:
+ case SYM_INIT:
if (which_pass != PASS_LIB)
fatal ("init function found in object %s", prog_name);
#ifndef LD_INIT_SWITCH
@@ -2189,7 +2199,7 @@ scan_prog_file (const char *prog_name, enum pass which_pass)
#endif
break;
- case 4:
+ case SYM_FINI:
if (which_pass != PASS_LIB)
fatal ("fini function found in object %s", prog_name);
#ifndef LD_FINI_SWITCH
@@ -2197,7 +2207,7 @@ scan_prog_file (const char *prog_name, enum pass which_pass)
#endif
break;
- case 5:
+ case SYM_DWEH:
if (which_pass != PASS_LIB)
add_to_list (&frame_tables, name);
break;
@@ -2476,8 +2486,8 @@ scan_prog_file (const char *prog_name, enum pass which_pass)
/* Some platforms (e.g. OSF4) declare ldopen as taking a
non-const char * filename parameter, even though it will not
modify that string. So we must cast away const-ness here,
- which will cause -Wcast-qual to burp. */
- if ((ldptr = ldopen ((char *)prog_name, ldptr)) != NULL)
+ using CONST_CAST to prevent complaints from -Wcast-qual. */
+ if ((ldptr = ldopen (CONST_CAST (char *, prog_name), ldptr)) != NULL)
{
if (! MY_ISCOFF (HEADER (ldptr).f_magic))
fatal ("%s: not a COFF file", prog_name);
@@ -2516,7 +2526,7 @@ scan_prog_file (const char *prog_name, enum pass which_pass)
switch (is_ctor_dtor (name))
{
- case 1:
+ case SYM_CTOR:
if (! is_shared)
add_to_list (&constructors, name);
#if defined (COLLECT_EXPORT_LIST) && !defined (LD_INIT_SWITCH)
@@ -2525,7 +2535,7 @@ scan_prog_file (const char *prog_name, enum pass which_pass)
#endif
break;
- case 2:
+ case SYM_DTOR:
if (! is_shared)
add_to_list (&destructors, name);
#if defined (COLLECT_EXPORT_LIST) && !defined (LD_INIT_SWITCH)
@@ -2535,14 +2545,14 @@ scan_prog_file (const char *prog_name, enum pass which_pass)
break;
#ifdef COLLECT_EXPORT_LIST
- case 3:
+ case SYM_INIT:
#ifndef LD_INIT_SWITCH
if (is_shared)
add_to_list (&constructors, name);
#endif
break;
- case 4:
+ case SYM_FINI:
#ifndef LD_INIT_SWITCH
if (is_shared)
add_to_list (&destructors, name);
@@ -2550,7 +2560,7 @@ scan_prog_file (const char *prog_name, enum pass which_pass)
break;
#endif
- case 5:
+ case SYM_DWEH:
if (! is_shared)
add_to_list (&frame_tables, name);
#if defined (COLLECT_EXPORT_LIST) && !defined (LD_INIT_SWITCH)
diff --git a/gcc/combine-stack-adj.c b/gcc/combine-stack-adj.c
index bf7cccf2df7..c678a607c66 100644
--- a/gcc/combine-stack-adj.c
+++ b/gcc/combine-stack-adj.c
@@ -1,6 +1,6 @@
/* Combine stack adjustments.
Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997,
- 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
Free Software Foundation, Inc.
This file is part of GCC.
@@ -143,14 +143,14 @@ single_set_for_csa (rtx insn)
for (i = 1; i < XVECLEN (tmp, 0); ++i)
{
- rtx this = XVECEXP (tmp, 0, i);
+ rtx this_rtx = XVECEXP (tmp, 0, i);
/* The special case is allowing a no-op set. */
- if (GET_CODE (this) == SET
- && SET_SRC (this) == SET_DEST (this))
+ if (GET_CODE (this_rtx) == SET
+ && SET_SRC (this_rtx) == SET_DEST (this_rtx))
;
- else if (GET_CODE (this) != CLOBBER
- && GET_CODE (this) != USE)
+ else if (GET_CODE (this_rtx) != CLOBBER
+ && GET_CODE (this_rtx) != USE)
return NULL_RTX;
}
@@ -272,6 +272,72 @@ record_stack_memrefs (rtx *xp, void *data)
return 0;
}
+/* Adjust or create REG_FRAME_RELATED_EXPR note when merging a stack
+ adjustment into a frame related insn. */
+
+static void
+adjust_frame_related_expr (rtx last_sp_set, rtx insn,
+ HOST_WIDE_INT this_adjust)
+{
+ rtx note = find_reg_note (last_sp_set, REG_FRAME_RELATED_EXPR, NULL_RTX);
+ rtx new_expr = NULL_RTX;
+
+ if (note == NULL_RTX && RTX_FRAME_RELATED_P (insn))
+ return;
+
+ if (note
+ && GET_CODE (XEXP (note, 0)) == SEQUENCE
+ && XVECLEN (XEXP (note, 0), 0) >= 2)
+ {
+ rtx expr = XEXP (note, 0);
+ rtx last = XVECEXP (expr, 0, XVECLEN (expr, 0) - 1);
+ int i;
+
+ if (GET_CODE (last) == SET
+ && RTX_FRAME_RELATED_P (last) == RTX_FRAME_RELATED_P (insn)
+ && SET_DEST (last) == stack_pointer_rtx
+ && GET_CODE (SET_SRC (last)) == PLUS
+ && XEXP (SET_SRC (last), 0) == stack_pointer_rtx
+ && GET_CODE (XEXP (SET_SRC (last), 1)) == CONST_INT)
+ {
+ XEXP (SET_SRC (last), 1)
+ = GEN_INT (INTVAL (XEXP (SET_SRC (last), 1)) + this_adjust);
+ return;
+ }
+
+ new_expr = gen_rtx_SEQUENCE (VOIDmode,
+ rtvec_alloc (XVECLEN (expr, 0) + 1));
+ for (i = 0; i < XVECLEN (expr, 0); i++)
+ XVECEXP (new_expr, 0, i) = XVECEXP (expr, 0, i);
+ }
+ else
+ {
+ new_expr = gen_rtx_SEQUENCE (VOIDmode, rtvec_alloc (2));
+ if (note)
+ XVECEXP (new_expr, 0, 0) = XEXP (note, 0);
+ else
+ {
+ rtx expr = copy_rtx (single_set_for_csa (last_sp_set));
+
+ XEXP (SET_SRC (expr), 1)
+ = GEN_INT (INTVAL (XEXP (SET_SRC (expr), 1)) - this_adjust);
+ RTX_FRAME_RELATED_P (expr) = 1;
+ XVECEXP (new_expr, 0, 0) = expr;
+ }
+ }
+
+ XVECEXP (new_expr, 0, XVECLEN (new_expr, 0) - 1)
+ = copy_rtx (single_set_for_csa (insn));
+ RTX_FRAME_RELATED_P (XVECEXP (new_expr, 0, XVECLEN (new_expr, 0) - 1))
+ = RTX_FRAME_RELATED_P (insn);
+ if (note)
+ XEXP (note, 0) = new_expr;
+ else
+ REG_NOTES (last_sp_set)
+ = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR, new_expr,
+ REG_NOTES (last_sp_set));
+}
+
/* Subroutine of combine_stack_adjustments, called for each basic block. */
static void
@@ -343,6 +409,9 @@ combine_stack_adjustments_for_block (basic_block bb)
last_sp_adjust + this_adjust,
this_adjust))
{
+ if (RTX_FRAME_RELATED_P (last_sp_set))
+ adjust_frame_related_expr (last_sp_set, insn,
+ this_adjust);
/* It worked! */
delete_insn (insn);
last_sp_adjust += this_adjust;
@@ -373,7 +442,7 @@ combine_stack_adjustments_for_block (basic_block bb)
deallocation+allocation conspired to cancel, we can
delete the old deallocation insn. */
if (last_sp_set && last_sp_adjust == 0)
- delete_insn (insn);
+ delete_insn (last_sp_set);
free_csa_memlist (memlist);
memlist = NULL;
last_sp_set = insn;
diff --git a/gcc/combine.c b/gcc/combine.c
index a6cff36480f..16cd040afd5 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -1340,8 +1340,7 @@ setup_incoming_promotions (rtx first)
function lie within the current compilation unit. (This does
take into account the exporting of a function via taking its
address, and so forth.) */
- if (flag_unit_at_a_time)
- strictly_local = cgraph_local_info (current_function_decl)->local;
+ strictly_local = cgraph_local_info (current_function_decl)->local;
/* The mode and signedness of the argument before any promotions happen
(equal to the mode of the pseudo holding it at that stage). */
@@ -4278,7 +4277,7 @@ subst (rtx x, rtx from, rtx to, int in_dest, int unique_copy)
enum machine_mode op0_mode = VOIDmode;
const char *fmt;
int len, i;
- rtx new;
+ rtx new_rtx;
/* Two expressions are equal if they are identical copies of a shared
RTX or if they are both registers with the same register number
@@ -4333,14 +4332,14 @@ subst (rtx x, rtx from, rtx to, int in_dest, int unique_copy)
&& GET_CODE (XVECEXP (x, 0, 0)) == SET
&& GET_CODE (SET_SRC (XVECEXP (x, 0, 0))) == ASM_OPERANDS)
{
- new = subst (XVECEXP (x, 0, 0), from, to, 0, unique_copy);
+ new_rtx = subst (XVECEXP (x, 0, 0), from, to, 0, unique_copy);
/* If this substitution failed, this whole thing fails. */
- if (GET_CODE (new) == CLOBBER
- && XEXP (new, 0) == const0_rtx)
- return new;
+ if (GET_CODE (new_rtx) == CLOBBER
+ && XEXP (new_rtx, 0) == const0_rtx)
+ return new_rtx;
- SUBST (XVECEXP (x, 0, 0), new);
+ SUBST (XVECEXP (x, 0, 0), new_rtx);
for (i = XVECLEN (x, 0) - 1; i >= 1; i--)
{
@@ -4350,14 +4349,14 @@ subst (rtx x, rtx from, rtx to, int in_dest, int unique_copy)
&& GET_CODE (dest) != CC0
&& GET_CODE (dest) != PC)
{
- new = subst (dest, from, to, 0, unique_copy);
+ new_rtx = subst (dest, from, to, 0, unique_copy);
/* If this substitution failed, this whole thing fails. */
- if (GET_CODE (new) == CLOBBER
- && XEXP (new, 0) == const0_rtx)
- return new;
+ if (GET_CODE (new_rtx) == CLOBBER
+ && XEXP (new_rtx, 0) == const0_rtx)
+ return new_rtx;
- SUBST (SET_DEST (XVECEXP (x, 0, i)), new);
+ SUBST (SET_DEST (XVECEXP (x, 0, i)), new_rtx);
}
}
}
@@ -4390,33 +4389,33 @@ subst (rtx x, rtx from, rtx to, int in_dest, int unique_copy)
{
if (COMBINE_RTX_EQUAL_P (XVECEXP (x, i, j), from))
{
- new = (unique_copy && n_occurrences
+ new_rtx = (unique_copy && n_occurrences
? copy_rtx (to) : to);
n_occurrences++;
}
else
{
- new = subst (XVECEXP (x, i, j), from, to, 0,
+ new_rtx = subst (XVECEXP (x, i, j), from, to, 0,
unique_copy);
/* If this substitution failed, this whole thing
fails. */
- if (GET_CODE (new) == CLOBBER
- && XEXP (new, 0) == const0_rtx)
- return new;
+ if (GET_CODE (new_rtx) == CLOBBER
+ && XEXP (new_rtx, 0) == const0_rtx)
+ return new_rtx;
}
- SUBST (XVECEXP (x, i, j), new);
+ SUBST (XVECEXP (x, i, j), new_rtx);
}
}
else if (fmt[i] == 'e')
{
/* If this is a register being set, ignore it. */
- new = XEXP (x, i);
+ new_rtx = XEXP (x, i);
if (in_dest
&& i == 0
&& (((code == SUBREG || code == ZERO_EXTRACT)
- && REG_P (new))
+ && REG_P (new_rtx))
|| code == STRICT_LOW_PART))
;
@@ -4457,7 +4456,7 @@ subst (rtx x, rtx from, rtx to, int in_dest, int unique_copy)
return gen_rtx_CLOBBER (VOIDmode, const0_rtx);
#endif
- new = (unique_copy && n_occurrences ? copy_rtx (to) : to);
+ new_rtx = (unique_copy && n_occurrences ? copy_rtx (to) : to);
n_occurrences++;
}
else
@@ -4469,7 +4468,7 @@ subst (rtx x, rtx from, rtx to, int in_dest, int unique_copy)
STRICT_LOW_PART, and ZERO_EXTRACT, which are the only
things aside from REG and MEM that should appear in a
SET_DEST. */
- new = subst (XEXP (x, i), from, to,
+ new_rtx = subst (XEXP (x, i), from, to,
(((in_dest
&& (code == SUBREG || code == STRICT_LOW_PART
|| code == ZERO_EXTRACT))
@@ -4482,30 +4481,30 @@ subst (rtx x, rtx from, rtx to, int in_dest, int unique_copy)
well as prevent accidents where two CLOBBERs are considered
to be equal, thus producing an incorrect simplification. */
- if (GET_CODE (new) == CLOBBER && XEXP (new, 0) == const0_rtx)
- return new;
+ if (GET_CODE (new_rtx) == CLOBBER && XEXP (new_rtx, 0) == const0_rtx)
+ return new_rtx;
if (GET_CODE (x) == SUBREG
- && (GET_CODE (new) == CONST_INT
- || GET_CODE (new) == CONST_DOUBLE))
+ && (GET_CODE (new_rtx) == CONST_INT
+ || GET_CODE (new_rtx) == CONST_DOUBLE))
{
enum machine_mode mode = GET_MODE (x);
- x = simplify_subreg (GET_MODE (x), new,
+ x = simplify_subreg (GET_MODE (x), new_rtx,
GET_MODE (SUBREG_REG (x)),
SUBREG_BYTE (x));
if (! x)
x = gen_rtx_CLOBBER (mode, const0_rtx);
}
- else if (GET_CODE (new) == CONST_INT
+ else if (GET_CODE (new_rtx) == CONST_INT
&& GET_CODE (x) == ZERO_EXTEND)
{
x = simplify_unary_operation (ZERO_EXTEND, GET_MODE (x),
- new, GET_MODE (XEXP (x, 0)));
+ new_rtx, GET_MODE (XEXP (x, 0)));
gcc_assert (x);
}
else
- SUBST (XEXP (x, i), new);
+ SUBST (XEXP (x, i), new_rtx);
}
}
}
@@ -5638,9 +5637,9 @@ simplify_set (rtx x)
/* Attempt to simplify CC user. */
if (GET_CODE (pat) == SET)
{
- rtx new = simplify_rtx (SET_SRC (pat));
- if (new != NULL_RTX)
- SUBST (SET_SRC (pat), new);
+ rtx new_rtx = simplify_rtx (SET_SRC (pat));
+ if (new_rtx != NULL_RTX)
+ SUBST (SET_SRC (pat), new_rtx);
}
/* Convert X into a no-op move. */
@@ -6373,7 +6372,7 @@ make_extraction (enum machine_mode mode, rtx inner, HOST_WIDE_INT pos,
enum machine_mode pos_mode = word_mode;
enum machine_mode extraction_mode = word_mode;
enum machine_mode tmode = mode_for_size (len, MODE_INT, 1);
- rtx new = 0;
+ rtx new_rtx = 0;
rtx orig_pos_rtx = pos_rtx;
HOST_WIDE_INT orig_pos;
@@ -6397,11 +6396,11 @@ make_extraction (enum machine_mode mode, rtx inner, HOST_WIDE_INT pos,
(ashift X (const_int C)), where LEN > C. Extract the
least significant (LEN - C) bits of X, giving an rtx
whose mode is MODE, then shift it left C times. */
- new = make_extraction (mode, XEXP (inner, 0),
+ new_rtx = make_extraction (mode, XEXP (inner, 0),
0, 0, len - INTVAL (XEXP (inner, 1)),
unsignedp, in_dest, in_compare);
- if (new != 0)
- return gen_rtx_ASHIFT (mode, new, XEXP (inner, 1));
+ if (new_rtx != 0)
+ return gen_rtx_ASHIFT (mode, new_rtx, XEXP (inner, 1));
}
inner_mode = GET_MODE (inner);
@@ -6457,7 +6456,7 @@ make_extraction (enum machine_mode mode, rtx inner, HOST_WIDE_INT pos,
else
offset = pos / BITS_PER_UNIT;
- new = adjust_address_nv (inner, tmode, offset);
+ new_rtx = adjust_address_nv (inner, tmode, offset);
}
else if (REG_P (inner))
{
@@ -6487,16 +6486,16 @@ make_extraction (enum machine_mode mode, rtx inner, HOST_WIDE_INT pos,
if (!validate_subreg (tmode, inner_mode, inner, final_word))
return NULL_RTX;
- new = gen_rtx_SUBREG (tmode, inner, final_word);
+ new_rtx = gen_rtx_SUBREG (tmode, inner, final_word);
}
else
- new = gen_lowpart (tmode, inner);
+ new_rtx = gen_lowpart (tmode, inner);
}
else
- new = inner;
+ new_rtx = inner;
}
else
- new = force_to_mode (inner, tmode,
+ new_rtx = force_to_mode (inner, tmode,
len >= HOST_BITS_PER_WIDE_INT
? ~(unsigned HOST_WIDE_INT) 0
: ((unsigned HOST_WIDE_INT) 1 << len) - 1,
@@ -6506,30 +6505,30 @@ make_extraction (enum machine_mode mode, rtx inner, HOST_WIDE_INT pos,
make a STRICT_LOW_PART unless we made a MEM. */
if (in_dest)
- return (MEM_P (new) ? new
- : (GET_CODE (new) != SUBREG
+ return (MEM_P (new_rtx) ? new_rtx
+ : (GET_CODE (new_rtx) != SUBREG
? gen_rtx_CLOBBER (tmode, const0_rtx)
- : gen_rtx_STRICT_LOW_PART (VOIDmode, new)));
+ : gen_rtx_STRICT_LOW_PART (VOIDmode, new_rtx)));
if (mode == tmode)
- return new;
+ return new_rtx;
- if (GET_CODE (new) == CONST_INT)
- return gen_int_mode (INTVAL (new), mode);
+ if (GET_CODE (new_rtx) == CONST_INT)
+ return gen_int_mode (INTVAL (new_rtx), mode);
/* If we know that no extraneous bits are set, and that the high
bit is not set, convert the extraction to the cheaper of
sign and zero extension, that are equivalent in these cases. */
if (flag_expensive_optimizations
&& (GET_MODE_BITSIZE (tmode) <= HOST_BITS_PER_WIDE_INT
- && ((nonzero_bits (new, tmode)
+ && ((nonzero_bits (new_rtx, tmode)
& ~(((unsigned HOST_WIDE_INT)
GET_MODE_MASK (tmode))
>> 1))
== 0)))
{
- rtx temp = gen_rtx_ZERO_EXTEND (mode, new);
- rtx temp1 = gen_rtx_SIGN_EXTEND (mode, new);
+ rtx temp = gen_rtx_ZERO_EXTEND (mode, new_rtx);
+ rtx temp1 = gen_rtx_SIGN_EXTEND (mode, new_rtx);
/* Prefer ZERO_EXTENSION, since it gives more information to
backends. */
@@ -6542,7 +6541,7 @@ make_extraction (enum machine_mode mode, rtx inner, HOST_WIDE_INT pos,
proper mode. */
return (gen_rtx_fmt_e (unsignedp ? ZERO_EXTEND : SIGN_EXTEND,
- mode, new));
+ mode, new_rtx));
}
/* Unless this is a COMPARE or we have a funny memory reference,
@@ -6746,12 +6745,12 @@ make_extraction (enum machine_mode mode, rtx inner, HOST_WIDE_INT pos,
pos_rtx = GEN_INT (pos);
/* Make the required operation. See if we can use existing rtx. */
- new = gen_rtx_fmt_eee (unsignedp ? ZERO_EXTRACT : SIGN_EXTRACT,
+ new_rtx = gen_rtx_fmt_eee (unsignedp ? ZERO_EXTRACT : SIGN_EXTRACT,
extraction_mode, inner, GEN_INT (len), pos_rtx);
if (! in_dest)
- new = gen_lowpart (mode, new);
+ new_rtx = gen_lowpart (mode, new_rtx);
- return new;
+ return new_rtx;
}
/* See if X contains an ASHIFT of COUNT or more bits that can be commuted
@@ -6827,7 +6826,7 @@ make_compound_operation (rtx x, enum rtx_code in_code)
rtx rhs, lhs;
enum rtx_code next_code;
int i;
- rtx new = 0;
+ rtx new_rtx = 0;
rtx tem;
const char *fmt;
@@ -6852,8 +6851,8 @@ make_compound_operation (rtx x, enum rtx_code in_code)
&& INTVAL (XEXP (x, 1)) < HOST_BITS_PER_WIDE_INT
&& INTVAL (XEXP (x, 1)) >= 0)
{
- new = make_compound_operation (XEXP (x, 0), next_code);
- new = gen_rtx_MULT (mode, new,
+ new_rtx = make_compound_operation (XEXP (x, 0), next_code);
+ new_rtx = gen_rtx_MULT (mode, new_rtx,
GEN_INT ((HOST_WIDE_INT) 1
<< INTVAL (XEXP (x, 1))));
}
@@ -6870,8 +6869,8 @@ make_compound_operation (rtx x, enum rtx_code in_code)
if (GET_CODE (XEXP (x, 0)) == LSHIFTRT
&& (i = exact_log2 (INTVAL (XEXP (x, 1)) + 1)) >= 0)
{
- new = make_compound_operation (XEXP (XEXP (x, 0), 0), next_code);
- new = make_extraction (mode, new, 0, XEXP (XEXP (x, 0), 1), i, 1,
+ new_rtx = make_compound_operation (XEXP (XEXP (x, 0), 0), next_code);
+ new_rtx = make_extraction (mode, new_rtx, 0, XEXP (XEXP (x, 0), 1), i, 1,
0, in_code == COMPARE);
}
@@ -6881,9 +6880,9 @@ make_compound_operation (rtx x, enum rtx_code in_code)
&& GET_CODE (SUBREG_REG (XEXP (x, 0))) == LSHIFTRT
&& (i = exact_log2 (INTVAL (XEXP (x, 1)) + 1)) >= 0)
{
- new = make_compound_operation (XEXP (SUBREG_REG (XEXP (x, 0)), 0),
+ new_rtx = make_compound_operation (XEXP (SUBREG_REG (XEXP (x, 0)), 0),
next_code);
- new = make_extraction (GET_MODE (SUBREG_REG (XEXP (x, 0))), new, 0,
+ new_rtx = make_extraction (GET_MODE (SUBREG_REG (XEXP (x, 0))), new_rtx, 0,
XEXP (SUBREG_REG (XEXP (x, 0)), 1), i, 1,
0, in_code == COMPARE);
}
@@ -6895,12 +6894,12 @@ make_compound_operation (rtx x, enum rtx_code in_code)
&& (i = exact_log2 (INTVAL (XEXP (x, 1)) + 1)) >= 0)
{
/* Apply the distributive law, and then try to make extractions. */
- new = gen_rtx_fmt_ee (GET_CODE (XEXP (x, 0)), mode,
+ new_rtx = gen_rtx_fmt_ee (GET_CODE (XEXP (x, 0)), mode,
gen_rtx_AND (mode, XEXP (XEXP (x, 0), 0),
XEXP (x, 1)),
gen_rtx_AND (mode, XEXP (XEXP (x, 0), 1),
XEXP (x, 1)));
- new = make_compound_operation (new, in_code);
+ new_rtx = make_compound_operation (new_rtx, in_code);
}
/* If we are have (and (rotate X C) M) and C is larger than the number
@@ -6911,8 +6910,8 @@ make_compound_operation (rtx x, enum rtx_code in_code)
&& (i = exact_log2 (INTVAL (XEXP (x, 1)) + 1)) >= 0
&& i <= INTVAL (XEXP (XEXP (x, 0), 1)))
{
- new = make_compound_operation (XEXP (XEXP (x, 0), 0), next_code);
- new = make_extraction (mode, new,
+ new_rtx = make_compound_operation (XEXP (XEXP (x, 0), 0), next_code);
+ new_rtx = make_extraction (mode, new_rtx,
(GET_MODE_BITSIZE (mode)
- INTVAL (XEXP (XEXP (x, 0), 1))),
NULL_RTX, i, 1, 0, in_code == COMPARE);
@@ -6945,7 +6944,7 @@ make_compound_operation (rtx x, enum rtx_code in_code)
If it doesn't end up being a ZERO_EXTEND, we will ignore it unless
we are in a COMPARE. */
else if ((i = exact_log2 (INTVAL (XEXP (x, 1)) + 1)) >= 0)
- new = make_extraction (mode,
+ new_rtx = make_extraction (mode,
make_compound_operation (XEXP (x, 0),
next_code),
0, NULL_RTX, i, 1, 0, in_code == COMPARE);
@@ -6954,7 +6953,7 @@ make_compound_operation (rtx x, enum rtx_code in_code)
convert this into the appropriate bit extract. */
else if (in_code == COMPARE
&& (i = exact_log2 (INTVAL (XEXP (x, 1)))) >= 0)
- new = make_extraction (mode,
+ new_rtx = make_extraction (mode,
make_compound_operation (XEXP (x, 0),
next_code),
i, NULL_RTX, 1, 1, 0, 1);
@@ -6969,7 +6968,7 @@ make_compound_operation (rtx x, enum rtx_code in_code)
&& mode_width <= HOST_BITS_PER_WIDE_INT
&& (nonzero_bits (XEXP (x, 0), mode) & (1 << (mode_width - 1))) == 0)
{
- new = gen_rtx_ASHIFTRT (mode,
+ new_rtx = gen_rtx_ASHIFTRT (mode,
make_compound_operation (XEXP (x, 0),
next_code),
XEXP (x, 1));
@@ -6989,8 +6988,8 @@ make_compound_operation (rtx x, enum rtx_code in_code)
&& GET_CODE (XEXP (lhs, 1)) == CONST_INT
&& INTVAL (rhs) >= INTVAL (XEXP (lhs, 1)))
{
- new = make_compound_operation (XEXP (lhs, 0), next_code);
- new = make_extraction (mode, new,
+ new_rtx = make_compound_operation (XEXP (lhs, 0), next_code);
+ new_rtx = make_extraction (mode, new_rtx,
INTVAL (rhs) - INTVAL (XEXP (lhs, 1)),
NULL_RTX, mode_width - INTVAL (rhs),
code == LSHIFTRT, 0, in_code == COMPARE);
@@ -7007,8 +7006,8 @@ make_compound_operation (rtx x, enum rtx_code in_code)
&& (OBJECT_P (SUBREG_REG (lhs))))
&& GET_CODE (rhs) == CONST_INT
&& INTVAL (rhs) < HOST_BITS_PER_WIDE_INT
- && (new = extract_left_shift (lhs, INTVAL (rhs))) != 0)
- new = make_extraction (mode, make_compound_operation (new, next_code),
+ && (new_rtx = extract_left_shift (lhs, INTVAL (rhs))) != 0)
+ new_rtx = make_extraction (mode, make_compound_operation (new_rtx, next_code),
0, NULL_RTX, mode_width - INTVAL (rhs),
code == LSHIFTRT, 0, in_code == COMPARE);
@@ -7053,9 +7052,9 @@ make_compound_operation (rtx x, enum rtx_code in_code)
break;
}
- if (new)
+ if (new_rtx)
{
- x = gen_lowpart (mode, new);
+ x = gen_lowpart (mode, new_rtx);
code = GET_CODE (x);
}
@@ -7064,8 +7063,8 @@ make_compound_operation (rtx x, enum rtx_code in_code)
for (i = 0; i < GET_RTX_LENGTH (code); i++)
if (fmt[i] == 'e')
{
- new = make_compound_operation (XEXP (x, i), next_code);
- SUBST (XEXP (x, i), new);
+ new_rtx = make_compound_operation (XEXP (x, i), next_code);
+ SUBST (XEXP (x, i), new_rtx);
}
/* If this is a commutative operation, the changes to the operands
@@ -8074,16 +8073,16 @@ known_cond (rtx x, enum rtx_code cond, rtx reg, rtx val)
else if (code == SUBREG)
{
enum machine_mode inner_mode = GET_MODE (SUBREG_REG (x));
- rtx new, r = known_cond (SUBREG_REG (x), cond, reg, val);
+ rtx new_rtx, r = known_cond (SUBREG_REG (x), cond, reg, val);
if (SUBREG_REG (x) != r)
{
/* We must simplify subreg here, before we lose track of the
original inner_mode. */
- new = simplify_subreg (GET_MODE (x), r,
+ new_rtx = simplify_subreg (GET_MODE (x), r,
inner_mode, SUBREG_BYTE (x));
- if (new)
- return new;
+ if (new_rtx)
+ return new_rtx;
else
SUBST (SUBREG_REG (x), r);
}
@@ -8099,16 +8098,16 @@ known_cond (rtx x, enum rtx_code cond, rtx reg, rtx val)
else if (code == ZERO_EXTEND)
{
enum machine_mode inner_mode = GET_MODE (XEXP (x, 0));
- rtx new, r = known_cond (XEXP (x, 0), cond, reg, val);
+ rtx new_rtx, r = known_cond (XEXP (x, 0), cond, reg, val);
if (XEXP (x, 0) != r)
{
/* We must simplify the zero_extend here, before we lose
track of the original inner_mode. */
- new = simplify_unary_operation (ZERO_EXTEND, GET_MODE (x),
+ new_rtx = simplify_unary_operation (ZERO_EXTEND, GET_MODE (x),
r, inner_mode);
- if (new)
- return new;
+ if (new_rtx)
+ return new_rtx;
else
SUBST (XEXP (x, 0), r);
}
@@ -8961,7 +8960,7 @@ simplify_shift_const_1 (enum rtx_code code, enum machine_mode result_mode,
enum rtx_code outer_op = UNKNOWN;
HOST_WIDE_INT outer_const = 0;
int complement_p = 0;
- rtx new, x;
+ rtx new_rtx, x;
/* Make sure and truncate the "natural" shift on the way in. We don't
want to do this inside the loop as it makes it more difficult to
@@ -9083,10 +9082,10 @@ simplify_shift_const_1 (enum rtx_code code, enum machine_mode result_mode,
case ZERO_EXTEND:
case SIGN_EXTRACT:
case ZERO_EXTRACT:
- new = expand_compound_operation (varop);
- if (new != varop)
+ new_rtx = expand_compound_operation (varop);
+ if (new_rtx != varop)
{
- varop = new;
+ varop = new_rtx;
continue;
}
break;
@@ -9101,12 +9100,12 @@ simplify_shift_const_1 (enum rtx_code code, enum machine_mode result_mode,
&& (tmode = mode_for_size (GET_MODE_BITSIZE (mode) - count,
MODE_INT, 1)) != BLKmode)
{
- new = adjust_address_nv (varop, tmode,
+ new_rtx = adjust_address_nv (varop, tmode,
BYTES_BIG_ENDIAN ? 0
: count / BITS_PER_UNIT);
varop = gen_rtx_fmt_e (code == ASHIFTRT ? SIGN_EXTEND
- : ZERO_EXTEND, mode, new);
+ : ZERO_EXTEND, mode, new_rtx);
count = 0;
continue;
}
@@ -9327,10 +9326,10 @@ simplify_shift_const_1 (enum rtx_code code, enum machine_mode result_mode,
&& GET_CODE (XEXP (varop, 0)) == CONST_INT
&& GET_CODE (XEXP (varop, 1)) != CONST_INT)
{
- rtx new = simplify_const_binary_operation (code, mode,
+ rtx new_rtx = simplify_const_binary_operation (code, mode,
XEXP (varop, 0),
GEN_INT (count));
- varop = gen_rtx_fmt_ee (code, mode, new, XEXP (varop, 1));
+ varop = gen_rtx_fmt_ee (code, mode, new_rtx, XEXP (varop, 1));
count = 0;
continue;
}
@@ -9384,12 +9383,12 @@ simplify_shift_const_1 (enum rtx_code code, enum machine_mode result_mode,
&& !(code == ASHIFTRT && GET_CODE (varop) == XOR
&& 0 > trunc_int_for_mode (INTVAL (XEXP (varop, 1)),
shift_mode))
- && (new = simplify_const_binary_operation (code, result_mode,
+ && (new_rtx = simplify_const_binary_operation (code, result_mode,
XEXP (varop, 1),
GEN_INT (count))) != 0
- && GET_CODE (new) == CONST_INT
+ && GET_CODE (new_rtx) == CONST_INT
&& merge_outer_ops (&outer_op, &outer_const, GET_CODE (varop),
- INTVAL (new), result_mode, &complement_p))
+ INTVAL (new_rtx), result_mode, &complement_p))
{
varop = XEXP (varop, 0);
continue;
@@ -9512,12 +9511,12 @@ simplify_shift_const_1 (enum rtx_code code, enum machine_mode result_mode,
/* (ashift (plus foo C) N) is (plus (ashift foo N) C'). */
if (code == ASHIFT
&& GET_CODE (XEXP (varop, 1)) == CONST_INT
- && (new = simplify_const_binary_operation (ASHIFT, result_mode,
+ && (new_rtx = simplify_const_binary_operation (ASHIFT, result_mode,
XEXP (varop, 1),
GEN_INT (count))) != 0
- && GET_CODE (new) == CONST_INT
+ && GET_CODE (new_rtx) == CONST_INT
&& merge_outer_ops (&outer_op, &outer_const, PLUS,
- INTVAL (new), result_mode, &complement_p))
+ INTVAL (new_rtx), result_mode, &complement_p))
{
varop = XEXP (varop, 0);
continue;
@@ -9531,12 +9530,12 @@ simplify_shift_const_1 (enum rtx_code code, enum machine_mode result_mode,
if (code == LSHIFTRT
&& GET_CODE (XEXP (varop, 1)) == CONST_INT
&& mode_signbit_p (result_mode, XEXP (varop, 1))
- && (new = simplify_const_binary_operation (code, result_mode,
+ && (new_rtx = simplify_const_binary_operation (code, result_mode,
XEXP (varop, 1),
GEN_INT (count))) != 0
- && GET_CODE (new) == CONST_INT
+ && GET_CODE (new_rtx) == CONST_INT
&& merge_outer_ops (&outer_op, &outer_const, XOR,
- INTVAL (new), result_mode, &complement_p))
+ INTVAL (new_rtx), result_mode, &complement_p))
{
varop = XEXP (varop, 0);
continue;
diff --git a/gcc/common.opt b/gcc/common.opt
index 9490be23f59..f2e60ac1951 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -59,11 +59,11 @@ Common Joined Separate UInteger
-G<number> Put global and static data smaller than <number> bytes into a special section (on some targets)
O
-Common JoinedOrMissing
+Common JoinedOrMissing Optimization
-O<number> Set optimization level to <number>
Os
-Common
+Common Optimization
Optimize for space rather than speed
W
@@ -94,6 +94,10 @@ Wdisabled-optimization
Common Var(warn_disabled_optimization) Warning
Warn when an optimization pass is disabled
+Wdisallowed-function-list=
+Common RejectNegative Joined Warning
+Warn on calls to these functions
+
Werror
Common Var(warnings_are_errors)
Treat all warnings as errors
@@ -271,28 +275,28 @@ fabi-version=
Common Joined UInteger Var(flag_abi_version) Init(2)
falign-functions
-Common Report Var(align_functions,0)
+Common Report Var(align_functions,0) Optimization UInteger
Align the start of functions
falign-functions=
Common RejectNegative Joined UInteger
falign-jumps
-Common Report Var(align_jumps,0) Optimization
+Common Report Var(align_jumps,0) Optimization UInteger
Align labels which are only reached by jumping
falign-jumps=
Common RejectNegative Joined UInteger
falign-labels
-Common Report Var(align_labels,0) Optimization
+Common Report Var(align_labels,0) Optimization UInteger
Align all labels
falign-labels=
Common RejectNegative Joined UInteger
falign-loops
-Common Report Var(align_loops) Optimization
+Common Report Var(align_loops) Optimization UInteger
Align the start of loops
falign-loops=
@@ -571,6 +575,10 @@ finhibit-size-directive
Common Report Var(flag_inhibit_size_directive)
Do not generate .size directives
+findirect-inlining
+Common Report Var(flag_indirect_inlining)
+Perform indirect inlining
+
; Nonzero means that functions declared `inline' will be treated
; as `static'. Prevents generation of zillions of copies of unused
; static inline functions; instead, `inlines' are written out
@@ -694,7 +702,7 @@ Common
Does nothing. Preserved for backward compatibility.
fmath-errno
-Common Report Var(flag_errno_math) Init(1)
+Common Report Var(flag_errno_math) Init(1) Optimization
Set errno after built-in math functions
fmem-report
@@ -953,7 +961,7 @@ Reschedule instructions after register allocation
; sched_stalled_insns means that insns can be moved prematurely from the queue
; of stalled insns into the ready list.
fsched-stalled-insns
-Common Report Var(flag_sched_stalled_insns) Optimization
+Common Report Var(flag_sched_stalled_insns) Optimization UInteger
Allow premature scheduling of queued insns
fsched-stalled-insns=
@@ -965,7 +973,7 @@ Common RejectNegative Joined UInteger
; premature removal from the queue of stalled insns into the ready list (has
; an effect only if the flag 'sched_stalled_insns' is set).
fsched-stalled-insns-dep
-Common Report Var(flag_sched_stalled_insns_dep,1) Init(1) Optimization
+Common Report Var(flag_sched_stalled_insns_dep,1) Init(1) Optimization UInteger
Set dependence distance checking in premature scheduling of queued insns
fsched-stalled-insns-dep=
@@ -1074,7 +1082,7 @@ Common Joined RejectNegative
-ftls-model=[global-dynamic|local-dynamic|initial-exec|local-exec] Set the default thread-local storage code generation model
ftoplevel-reorder
-Common Report Var(flag_toplevel_reorder) Init(1) Optimization
+Common Report Var(flag_toplevel_reorder) Init(2) Optimization
Reorder top level functions, variables, and asms
ftracer
@@ -1185,7 +1193,7 @@ Common Report Var(flag_tree_sra) Optimization
Perform scalar replacement of aggregates
ftree-ter
-Common Report Var(flag_tree_ter) Optimization
+Common Report Var(flag_tree_ter) Init(1) Optimization
Replace temporary expressions in the SSA->normal pass
ftree-lrs
@@ -1197,7 +1205,7 @@ Common Report Var(flag_tree_vrp) Init(0) Optimization
Perform Value Range Propagation on trees
funit-at-a-time
-Common Report Var(flag_unit_at_a_time) Optimization
+Common Report Var(flag_unit_at_a_time) Init(1) Optimization
Compile whole compilation unit at a time
funroll-loops
diff --git a/gcc/config.gcc b/gcc/config.gcc
index b29a762895c..bc818e6f585 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -204,16 +204,32 @@ xm_file=
md_file=
# Obsolete configurations.
-#case ${target} in
-# )
-# if test "x$enable_obsolete" != xyes; then
-# echo "*** Configuration ${target} is obsolete." >&2
-# echo "*** Specify --enable-obsolete to build it anyway." >&2
-# echo "*** Support will be REMOVED in the next major release of GCC," >&2
-# echo "*** unless a maintainer comes forward." >&2
-# exit 1
-# fi;;
-#esac
+case ${target} in
+# Avoid generic cases below matching.
+ h8300-*-rtems* | h8300-*-elf* \
+ | sh-*-elf* | sh-*-symbianelf* | sh-*-linux* | sh-*-netbsdelf* \
+ | sh-*-rtems* | sh-wrs-vxworks) ;;
+ arm-*-coff* \
+ | armel-*-coff* \
+ | h8300-*-* \
+ | i[34567]86-*-aout* \
+ | i[34567]86-*-coff* \
+ | m68k-*-aout* \
+ | m68k-*-coff* \
+ | sh-*-* \
+ | mips-sgi-irix[56]* \
+ | pdp11-*-bsd \
+ | rs6000-ibm-aix4.[12]* \
+ | powerpc-ibm-aix4.[12]* \
+ )
+ if test "x$enable_obsolete" != xyes; then
+ echo "*** Configuration ${target} is obsolete." >&2
+ echo "*** Specify --enable-obsolete to build it anyway." >&2
+ echo "*** Support will be REMOVED in the next major release of GCC," >&2
+ echo "*** unless a maintainer comes forward." >&2
+ exit 1
+ fi;;
+esac
# Unsupported targets list. Do not put an entry in this list unless
# it would otherwise be caught by a more permissive pattern. The list
@@ -278,17 +294,21 @@ fido-*-*)
;;
i[34567]86-*-*)
cpu_type=i386
+ c_target_objs="i386-c.o"
+ cxx_target_objs="i386-c.o"
extra_headers="cpuid.h mmintrin.h mm3dnow.h xmmintrin.h emmintrin.h
pmmintrin.h tmmintrin.h ammintrin.h smmintrin.h
nmmintrin.h bmmintrin.h mmintrin-common.h
- wmmintrin.h"
+ wmmintrin.h cross-stdarg.h"
;;
x86_64-*-*)
cpu_type=i386
+ c_target_objs="i386-c.o"
+ cxx_target_objs="i386-c.o"
extra_headers="cpuid.h mmintrin.h mm3dnow.h xmmintrin.h emmintrin.h
pmmintrin.h tmmintrin.h ammintrin.h smmintrin.h
nmmintrin.h bmmintrin.h mmintrin-common.h
- wmmintrin.h"
+ wmmintrin.h cross-stdarg.h"
need_64bit_hwint=yes
;;
ia64-*-*)
@@ -394,8 +414,8 @@ case ${target} in
tmake_file="t-darwin ${cpu_type}/t-darwin t-slibgcc-darwin"
target_gtfiles="\$(srcdir)/config/darwin.c"
extra_options="${extra_options} darwin.opt"
- c_target_objs="darwin-c.o"
- cxx_target_objs="darwin-c.o"
+ c_target_objs="${c_target_objs} darwin-c.o"
+ cxx_target_objs="${cxx_target_objs} darwin-c.o"
fortran_target_objs="darwin-f.o"
extra_objs="darwin.o"
extra_gcc_objs="darwin-driver.o"
@@ -747,7 +767,9 @@ arm*-*-eabi* | arm*-*-symbianelf* )
tmake_file="arm/t-arm arm/t-arm-elf"
case ${target} in
arm*-*-eabi*)
+ tm_file="$tm_file arm/eabi.h"
tmake_file="${tmake_file} arm/t-bpabi"
+ extra_options="${extra_options} arm/eabi.opt"
;;
arm*-*-symbianelf*)
tm_file="${tm_file} arm/symbian.h"
@@ -1010,16 +1032,16 @@ i[34567]86-*-darwin*)
;;
x86_64-*-darwin*)
with_cpu=${with_cpu:-generic}
- tmake_file="t-darwin ${cpu_type}/t-darwin64 t-slibgcc-darwin i386/t-crtpc i386/t-crtfm"
+ tmake_file="${tmake_file} t-darwin ${cpu_type}/t-darwin64 t-slibgcc-darwin i386/t-crtpc i386/t-crtfm"
tm_file="${tm_file} ${cpu_type}/darwin64.h"
;;
i[34567]86-*-elf*)
tm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h i386/i386elf.h"
- tmake_file="i386/t-i386elf t-svr4"
+ tmake_file="${tmake_file} i386/t-i386elf t-svr4"
;;
x86_64-*-elf*)
tm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h i386/i386elf.h i386/x86-64.h"
- tmake_file="i386/t-i386elf t-svr4"
+ tmake_file="${tmake_file} i386/t-i386elf t-svr4"
;;
i[34567]86-*-aout*)
tm_file="${tm_file} i386/unix.h i386/bsd.h i386/gas.h i386/gstabs.h i386/i386-aout.h"
@@ -1036,7 +1058,7 @@ i[34567]86-*-netbsdelf*)
;;
i[34567]86-*-netbsd*)
tm_file="${tm_file} i386/unix.h i386/bsd.h i386/gas.h i386/gstabs.h netbsd.h netbsd-aout.h i386/netbsd.h"
- tmake_file=t-netbsd
+ tmake_file="${tmake_file} t-netbsd"
extra_parts=""
use_collect2=yes
;;
@@ -1047,7 +1069,7 @@ x86_64-*-netbsd*)
i[34567]86-*-openbsd2.*|i[34567]86-*openbsd3.[0123])
tm_file="i386/i386.h i386/unix.h i386/bsd.h i386/gas.h i386/gstabs.h openbsd-oldgas.h openbsd.h i386/openbsd.h"
# needed to unconfuse gdb
- tmake_file="t-libc-ok t-openbsd i386/t-openbsd"
+ tmake_file="${tmake_file} t-libc-ok t-openbsd i386/t-openbsd"
# we need collect2 until our bug is fixed...
use_collect2=yes
;;
@@ -1108,7 +1130,7 @@ i[34567]86-*-gnu*)
i[34567]86-pc-msdosdjgpp*)
xm_file=i386/xm-djgpp.h
tm_file="dbxcoff.h ${tm_file} i386/unix.h i386/bsd.h i386/gas.h i386/djgpp.h"
- tmake_file=i386/t-djgpp
+ tmake_file="${tmake_file} i386/t-djgpp"
extra_options="${extra_options} i386/djgpp.opt"
gnu_ld=yes
gas=yes
@@ -1116,7 +1138,7 @@ i[34567]86-pc-msdosdjgpp*)
i[34567]86-*-lynxos*)
xm_defines=POSIX
tm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h i386/lynx.h lynx.h"
- tmake_file="i386/t-crtstuff t-lynx"
+ tmake_file="${tmake_file} i386/t-crtstuff t-lynx"
extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
extra_options="${extra_options} lynx.opt"
thread_file=lynx
@@ -1125,7 +1147,7 @@ i[34567]86-*-lynxos*)
;;
i[3456x]86-*-netware*)
tm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h svr4.h tm-dwarf2.h i386/netware.h"
- tmake_file=i386/t-netware
+ tmake_file="${tmake_file} i386/t-netware"
extra_objs=netware.o
case /${with_ld} in
*/nwld)
@@ -1144,14 +1166,14 @@ i[3456x]86-*-netware*)
;;
i[34567]86-*-nto-qnx*)
tm_file="${tm_file} i386/att.h dbxelf.h tm-dwarf2.h elfos.h svr4.h i386/unix.h i386/nto.h"
- tmake_file=i386/t-nto
+ tmake_file="${tmake_file} i386/t-nto"
gnu_ld=yes
gas=yes
;;
i[34567]86-*-rtems*)
tm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h i386/i386elf.h i386/rtemself.h rtems.h"
extra_parts="crtbegin.o crtend.o crti.o crtn.o"
- tmake_file="i386/t-rtems-i386 i386/t-crtstuff t-rtems"
+ tmake_file="${tmake_file} i386/t-rtems-i386 i386/t-crtstuff t-rtems"
;;
i[34567]86-*-solaris2*)
tm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h svr4.h i386/sysv4.h sol2.h"
@@ -1161,9 +1183,9 @@ i[34567]86-*-solaris2*)
;;
esac
tm_file="${tm_file} i386/sol2.h"
- tmake_file="t-sol2 i386/t-sol2 t-svr4"
- c_target_objs="sol2-c.o"
- cxx_target_objs="sol2-c.o"
+ tmake_file="${tmake_file} t-sol2 i386/t-sol2 t-svr4"
+ c_target_objs="${c_target_objs} sol2-c.o"
+ cxx_target_objs="${cxx_target_objs} sol2-c.o"
extra_objs="sol2.o"
tm_p_file="${tm_p_file} sol2-protos.h"
if test x$gnu_ld = xyes; then
@@ -1229,12 +1251,12 @@ i[4567]86-wrs-vxworks|i[4567]86-wrs-vxworksae)
i[34567]86-*-pe | i[34567]86-*-cygwin*)
tm_file="${tm_file} i386/unix.h i386/bsd.h i386/gas.h dbxcoff.h i386/cygming.h i386/cygwin.h"
xm_file=i386/xm-cygwin.h
- tmake_file="i386/t-cygwin i386/t-cygming"
+ tmake_file="${tmake_file} i386/t-cygwin i386/t-cygming"
target_gtfiles="\$(srcdir)/config/i386/winnt.c"
extra_options="${extra_options} i386/cygming.opt"
extra_objs="winnt.o winnt-stubs.o"
- c_target_objs="cygwin2.o msformat-c.o"
- cxx_target_objs="cygwin2.o winnt-cxx.o msformat-c.o"
+ c_target_objs="${c_target_objs} cygwin2.o msformat-c.o"
+ cxx_target_objs="${cxx_target_objs} cygwin2.o winnt-cxx.o msformat-c.o"
extra_gcc_objs=cygwin1.o
if test x$enable_threads = xyes; then
thread_file='posix'
@@ -1243,12 +1265,12 @@ i[34567]86-*-pe | i[34567]86-*-cygwin*)
i[34567]86-*-mingw* | x86_64-*-mingw*)
tm_file="${tm_file} i386/unix.h i386/bsd.h i386/gas.h dbxcoff.h i386/cygming.h i386/mingw32.h"
xm_file=i386/xm-mingw32.h
- tmake_file="i386/t-cygming i386/t-mingw32"
+ tmake_file="${tmake_file} i386/t-cygming i386/t-mingw32"
target_gtfiles="\$(srcdir)/config/i386/winnt.c"
extra_options="${extra_options} i386/cygming.opt"
extra_objs="winnt.o winnt-stubs.o"
- c_target_objs="msformat-c.o"
- cxx_target_objs="winnt-cxx.o msformat-c.o"
+ c_target_objs="${c_target_objs} msformat-c.o"
+ cxx_target_objs="${cxx_target_objs} winnt-cxx.o msformat-c.o"
default_use_cxa_atexit=yes
case ${enable_threads} in
"" | yes | win32)
@@ -1273,7 +1295,7 @@ i[34567]86-*-mingw* | x86_64-*-mingw*)
;;
i[34567]86-*-interix3*)
tm_file="${tm_file} i386/unix.h i386/bsd.h i386/gas.h i386/i386-interix.h i386/i386-interix3.h interix.h interix3.h"
- tmake_file="i386/t-interix"
+ tmake_file="${tmake_file} i386/t-interix"
extra_objs=winnt.o
target_gtfiles="\$(srcdir)/config/i386/winnt.c"
if test x$enable_threads = xyes ; then
@@ -1459,9 +1481,11 @@ m68k-*-linux*) # Motorola m68k's running GNU/Linux
# aka the GNU/Linux C library 6.
default_m68k_cpu=68020
default_cf_cpu=5475
- tm_file="${tm_file} dbxelf.h elfos.h svr4.h linux.h m68k/linux.h"
+ with_arch=${with_arch:-m68k}
+ tm_file="${tm_file} dbxelf.h elfos.h svr4.h linux.h m68k/linux.h ./sysroot-suffix.h"
extra_options="${extra_options} m68k/ieee.opt"
tm_defines="${tm_defines} MOTOROLA=1"
+ tmake_file="${tmake_file} m68k/t-floatlib m68k/t-linux m68k/t-mlibs"
# if not configured with --enable-sjlj-exceptions, bump the
# libgcc version number
if test x$sjlj != x1; then
@@ -2349,10 +2373,10 @@ esac
case ${target} in
i[34567]86-*-linux* | x86_64-*-linux*)
- tmake_file="${tmake_file} i386/t-pmm_malloc"
+ tmake_file="${tmake_file} i386/t-pmm_malloc i386/t-i386"
;;
i[34567]86-*-* | x86_64-*-*)
- tmake_file="${tmake_file} i386/t-gmm_malloc"
+ tmake_file="${tmake_file} i386/t-gmm_malloc i386/t-i386"
;;
esac
diff --git a/gcc/config.in b/gcc/config.in
index ec2c468d402..ca66efe6c8b 100644
--- a/gcc/config.in
+++ b/gcc/config.in
@@ -126,6 +126,12 @@
#undef ENABLE_TREE_CHECKING
#endif
+/* Define if you want operations on GIMPLE (the basic data structure of
+ the high-level optimizers) to be checked for dynamic type safety at
+ runtime. This is moderately expensive. */
+#ifndef USED_FOR_TARGET
+#undef ENABLE_GIMPLE_CHECKING
+#endif
/* Define if you want all gimple types to be verified after gimplifiation.
This is cheap. */
@@ -180,12 +186,6 @@
#endif
-/* Define to 1 if you have the `alphasort' function. */
-#ifndef USED_FOR_TARGET
-#undef HAVE_ALPHASORT
-#endif
-
-
/* Define if your assembler supports cmpb. */
#ifndef USED_FOR_TARGET
#undef HAVE_AS_CMPB
@@ -1122,12 +1122,6 @@
#endif
-/* Define to 1 if you have the `scandir' function. */
-#ifndef USED_FOR_TARGET
-#undef HAVE_SCANDIR
-#endif
-
-
/* Define to 1 if you have the `setlocale' function. */
#ifndef USED_FOR_TARGET
#undef HAVE_SETLOCALE
@@ -1518,6 +1512,12 @@
#endif
+/* Define to `char *' if <sys/types.h> does not define. */
+#ifndef USED_FOR_TARGET
+#undef caddr_t
+#endif
+
+
/* Define to `int' if <sys/types.h> doesn't define. */
#ifndef USED_FOR_TARGET
#undef gid_t
diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c
index 350994234cd..e2835acd3b7 100644
--- a/gcc/config/alpha/alpha.c
+++ b/gcc/config/alpha/alpha.c
@@ -1,6 +1,6 @@
/* Subroutines used for code generation on the DEC Alpha.
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
- 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
+ 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
This file is part of GCC.
@@ -51,7 +51,7 @@ along with GCC; see the file COPYING3. If not see
#include "langhooks.h"
#include <splay-tree.h>
#include "cfglayout.h"
-#include "tree-gimple.h"
+#include "gimple.h"
#include "tree-flow.h"
#include "tree-stdarg.h"
#include "tm-constrs.h"
@@ -5817,11 +5817,11 @@ va_list_skip_additions (tree lhs)
if (TREE_CODE (stmt) == PHI_NODE)
return stmt;
- if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT
- || GIMPLE_STMT_OPERAND (stmt, 0) != lhs)
+ if (TREE_CODE (stmt) != MODIFY_EXPR
+ || TREE_OPERAND (stmt, 0) != lhs)
return lhs;
- rhs = GIMPLE_STMT_OPERAND (stmt, 1);
+ rhs = TREE_OPERAND (stmt, 1);
if (TREE_CODE (rhs) == WITH_SIZE_EXPR)
rhs = TREE_OPERAND (rhs, 0);
@@ -5856,11 +5856,17 @@ va_list_skip_additions (tree lhs)
current statement. */
static bool
-alpha_stdarg_optimize_hook (struct stdarg_info *si, const_tree lhs, const_tree rhs)
+alpha_stdarg_optimize_hook (struct stdarg_info *si, const_gimple stmt)
{
tree base, offset, arg1, arg2;
int offset_arg = 1;
+#if 1
+ /* FIXME tuples. */
+ (void) si;
+ (void) stmt;
+ return false;
+#else
while (handled_component_p (rhs))
rhs = TREE_OPERAND (rhs, 0);
if (TREE_CODE (rhs) != INDIRECT_REF
@@ -5953,6 +5959,7 @@ alpha_stdarg_optimize_hook (struct stdarg_info *si, const_tree lhs, const_tree r
escapes:
si->va_list_escapes = true;
return false;
+#endif
}
#endif
@@ -6087,7 +6094,7 @@ alpha_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED)
{
nextarg = plus_constant (nextarg, offset);
nextarg = plus_constant (nextarg, NUM_ARGS * UNITS_PER_WORD);
- t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (valist), valist,
+ t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist,
make_tree (ptr_type_node, nextarg));
TREE_SIDE_EFFECTS (t) = 1;
@@ -6106,20 +6113,20 @@ alpha_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED)
t = make_tree (ptr_type_node, virtual_incoming_args_rtx);
t = build2 (POINTER_PLUS_EXPR, ptr_type_node, t,
size_int (offset));
- t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (base_field), base_field, t);
+ t = build2 (MODIFY_EXPR, TREE_TYPE (base_field), base_field, t);
TREE_SIDE_EFFECTS (t) = 1;
expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
t = build_int_cst (NULL_TREE, NUM_ARGS * UNITS_PER_WORD);
- t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (offset_field),
- offset_field, t);
+ t = build2 (MODIFY_EXPR, TREE_TYPE (offset_field), offset_field, t);
TREE_SIDE_EFFECTS (t) = 1;
expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
}
}
static tree
-alpha_gimplify_va_arg_1 (tree type, tree base, tree offset, tree *pre_p)
+alpha_gimplify_va_arg_1 (tree type, tree base, gimple_seq offset,
+ gimple_seq *pre_p)
{
tree type_size, ptr_type, addend, t, addr, internal_post;
@@ -6128,9 +6135,9 @@ alpha_gimplify_va_arg_1 (tree type, tree base, tree offset, tree *pre_p)
if (targetm.calls.must_pass_in_stack (TYPE_MODE (type), type))
{
t = build_int_cst (TREE_TYPE (offset), 6*8);
- t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (offset), offset,
- build2 (MAX_EXPR, TREE_TYPE (offset), offset, t));
- gimplify_and_add (t, pre_p);
+ gimplify_assign (offset,
+ build2 (MAX_EXPR, TREE_TYPE (offset), offset, t),
+ pre_p);
}
addend = offset;
@@ -6182,15 +6189,15 @@ alpha_gimplify_va_arg_1 (tree type, tree base, tree offset, tree *pre_p)
t = size_binop (MULT_EXPR, t, size_int (8));
}
t = fold_convert (TREE_TYPE (offset), t);
- t = build2 (GIMPLE_MODIFY_STMT, void_type_node, offset,
- build2 (PLUS_EXPR, TREE_TYPE (offset), offset, t));
- gimplify_and_add (t, pre_p);
+ gimplify_assign (offset, build2 (PLUS_EXPR, TREE_TYPE (offset), offset, t),
+ pre_p);
return build_va_arg_indirect_ref (addr);
}
static tree
-alpha_gimplify_va_arg (tree valist, tree type, tree *pre_p, tree *post_p)
+alpha_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
+ gimple_seq *post_p)
{
tree offset_field, base_field, offset, base, t, r;
bool indirect;
@@ -6222,9 +6229,8 @@ alpha_gimplify_va_arg (tree valist, tree type, tree *pre_p, tree *post_p)
r = alpha_gimplify_va_arg_1 (type, base, offset, pre_p);
/* Stuff the offset temporary back into its field. */
- t = build2 (GIMPLE_MODIFY_STMT, void_type_node, offset_field,
- fold_convert (TREE_TYPE (offset_field), offset));
- gimplify_and_add (t, pre_p);
+ gimplify_assign (offset_field,
+ fold_convert (TREE_TYPE (offset_field), offset), pre_p);
if (indirect)
r = build_va_arg_indirect_ref (r);
diff --git a/gcc/config/arm/aout.h b/gcc/config/arm/aout.h
index cb46a8edc90..59c1bf70e5d 100644
--- a/gcc/config/arm/aout.h
+++ b/gcc/config/arm/aout.h
@@ -191,9 +191,6 @@
}
#endif
-/* Arm Assembler barfs on dollars. */
-#define DOLLARS_IN_IDENTIFIERS 0
-
#ifndef NO_DOLLAR_IN_LABEL
#define NO_DOLLAR_IN_LABEL 1
#endif
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index fa3d06dcd75..dfee7c3740e 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -3267,11 +3267,6 @@ arm_function_in_section_p (tree decl, section *section)
/* If DECL_SECTION_NAME is set, assume it is trustworthy. */
if (!DECL_SECTION_NAME (decl))
{
- /* Only cater for unit-at-a-time mode, where we know that the user
- cannot later specify a section for DECL. */
- if (!flag_unit_at_a_time)
- return false;
-
/* Make sure that we will not create a unique section for DECL. */
if (flag_function_sections || DECL_ONE_ONLY (decl))
return false;
@@ -15094,6 +15089,24 @@ arm_init_neon_builtins (void)
TYPE_PRECISION (neon_float_type_node) = FLOAT_TYPE_SIZE;
layout_type (neon_float_type_node);
+ /* Define typedefs which exactly correspond to the modes we are basing vector
+ types on. If you change these names you'll need to change
+ the table used by arm_mangle_type too. */
+ (*lang_hooks.types.register_builtin_type) (neon_intQI_type_node,
+ "__builtin_neon_qi");
+ (*lang_hooks.types.register_builtin_type) (neon_intHI_type_node,
+ "__builtin_neon_hi");
+ (*lang_hooks.types.register_builtin_type) (neon_intSI_type_node,
+ "__builtin_neon_si");
+ (*lang_hooks.types.register_builtin_type) (neon_float_type_node,
+ "__builtin_neon_sf");
+ (*lang_hooks.types.register_builtin_type) (neon_intDI_type_node,
+ "__builtin_neon_di");
+ (*lang_hooks.types.register_builtin_type) (neon_polyQI_type_node,
+ "__builtin_neon_poly8");
+ (*lang_hooks.types.register_builtin_type) (neon_polyHI_type_node,
+ "__builtin_neon_poly16");
+
intQI_pointer_node = build_pointer_type (neon_intQI_type_node);
intHI_pointer_node = build_pointer_type (neon_intHI_type_node);
intSI_pointer_node = build_pointer_type (neon_intSI_type_node);
@@ -15146,12 +15159,32 @@ arm_init_neon_builtins (void)
intUSI_type_node = make_unsigned_type (GET_MODE_PRECISION (SImode));
intUDI_type_node = make_unsigned_type (GET_MODE_PRECISION (DImode));
+ (*lang_hooks.types.register_builtin_type) (intUQI_type_node,
+ "__builtin_neon_uqi");
+ (*lang_hooks.types.register_builtin_type) (intUHI_type_node,
+ "__builtin_neon_uhi");
+ (*lang_hooks.types.register_builtin_type) (intUSI_type_node,
+ "__builtin_neon_usi");
+ (*lang_hooks.types.register_builtin_type) (intUDI_type_node,
+ "__builtin_neon_udi");
+
/* Opaque integer types for structures of vectors. */
intEI_type_node = make_signed_type (GET_MODE_PRECISION (EImode));
intOI_type_node = make_signed_type (GET_MODE_PRECISION (OImode));
intCI_type_node = make_signed_type (GET_MODE_PRECISION (CImode));
intXI_type_node = make_signed_type (GET_MODE_PRECISION (XImode));
+ (*lang_hooks.types.register_builtin_type) (intTI_type_node,
+ "__builtin_neon_ti");
+ (*lang_hooks.types.register_builtin_type) (intEI_type_node,
+ "__builtin_neon_ei");
+ (*lang_hooks.types.register_builtin_type) (intOI_type_node,
+ "__builtin_neon_oi");
+ (*lang_hooks.types.register_builtin_type) (intCI_type_node,
+ "__builtin_neon_ci");
+ (*lang_hooks.types.register_builtin_type) (intXI_type_node,
+ "__builtin_neon_xi");
+
/* Pointers to vector types. */
V8QI_pointer_node = build_pointer_type (V8QI_type_node);
V4HI_pointer_node = build_pointer_type (V4HI_type_node);
@@ -15195,44 +15228,6 @@ arm_init_neon_builtins (void)
build_function_type_list (void_type_node, V2DI_pointer_node, V2DI_type_node,
V2DI_type_node, NULL);
- /* Define typedefs which exactly correspond to the modes we are basing vector
- types on. If you change these names you'll need to change
- the table used by arm_mangle_type too. */
- (*lang_hooks.types.register_builtin_type) (neon_intQI_type_node,
- "__builtin_neon_qi");
- (*lang_hooks.types.register_builtin_type) (neon_intHI_type_node,
- "__builtin_neon_hi");
- (*lang_hooks.types.register_builtin_type) (neon_intSI_type_node,
- "__builtin_neon_si");
- (*lang_hooks.types.register_builtin_type) (neon_float_type_node,
- "__builtin_neon_sf");
- (*lang_hooks.types.register_builtin_type) (neon_intDI_type_node,
- "__builtin_neon_di");
-
- (*lang_hooks.types.register_builtin_type) (neon_polyQI_type_node,
- "__builtin_neon_poly8");
- (*lang_hooks.types.register_builtin_type) (neon_polyHI_type_node,
- "__builtin_neon_poly16");
- (*lang_hooks.types.register_builtin_type) (intUQI_type_node,
- "__builtin_neon_uqi");
- (*lang_hooks.types.register_builtin_type) (intUHI_type_node,
- "__builtin_neon_uhi");
- (*lang_hooks.types.register_builtin_type) (intUSI_type_node,
- "__builtin_neon_usi");
- (*lang_hooks.types.register_builtin_type) (intUDI_type_node,
- "__builtin_neon_udi");
-
- (*lang_hooks.types.register_builtin_type) (intTI_type_node,
- "__builtin_neon_ti");
- (*lang_hooks.types.register_builtin_type) (intEI_type_node,
- "__builtin_neon_ei");
- (*lang_hooks.types.register_builtin_type) (intOI_type_node,
- "__builtin_neon_oi");
- (*lang_hooks.types.register_builtin_type) (intCI_type_node,
- "__builtin_neon_ci");
- (*lang_hooks.types.register_builtin_type) (intXI_type_node,
- "__builtin_neon_xi");
-
dreg_types[0] = V8QI_type_node;
dreg_types[1] = V4HI_type_node;
dreg_types[2] = V2SI_type_node;
@@ -18318,7 +18313,8 @@ arm_cxx_key_method_may_be_inline (void)
static void
arm_cxx_determine_class_data_visibility (tree decl)
{
- if (!TARGET_AAPCS_BASED)
+ if (!TARGET_AAPCS_BASED
+ || !TARGET_DLLIMPORT_DECL_ATTRIBUTES)
return;
/* In general, \S 3.2.5.5 of the ARM EABI requires that class data
diff --git a/gcc/config/arm/bpabi.h b/gcc/config/arm/bpabi.h
index 876e23404ab..e28d9ead45e 100644
--- a/gcc/config/arm/bpabi.h
+++ b/gcc/config/arm/bpabi.h
@@ -60,11 +60,14 @@
#endif
/* The generic link spec in elf.h does not support shared libraries. */
-#undef LINK_SPEC
-#define LINK_SPEC "%{mbig-endian:-EB} %{mlittle-endian:-EL} " \
+#define BPABI_LINK_SPEC \
+ "%{mbig-endian:-EB} %{mlittle-endian:-EL} " \
"%{static:-Bstatic} %{shared:-shared} %{symbolic:-Bsymbolic} " \
"-X" SUBTARGET_EXTRA_LINK_SPEC
+#undef LINK_SPEC
+#define LINK_SPEC BPABI_LINK_SPEC
+
#if defined (__thumb__)
#define RENAME_LIBRARY_SET ".thumb_set"
#else
diff --git a/gcc/config/arm/eabi.h b/gcc/config/arm/eabi.h
new file mode 100644
index 00000000000..c7d1d3ed20c
--- /dev/null
+++ b/gcc/config/arm/eabi.h
@@ -0,0 +1,125 @@
+/* Configuration file for ARM EABI targets.
+ Copyright (C) 2008
+ Free Software Foundation, Inc.
+ Contributed by Doug Kwan (dougkwan@google.com)
+
+ This file is part of GCC.
+
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 3, or (at your
+ option) any later version.
+
+ GCC is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING3. If not see
+ <http://www.gnu.org/licenses/>. */
+
+/* This file contains macro overrides for EABI targets. */
+
+#undef TARGET_OS_CPP_BUILTINS
+#define TARGET_OS_CPP_BUILTINS() \
+ do \
+ { \
+ TARGET_BPABI_CPP_BUILTINS (); \
+ if (TARGET_ANDROID) \
+ builtin_define ("__ANDROID__"); \
+ } \
+ while (false)
+
+#undef SUBSUBTARGET_EXTRA_SPECS
+#define SUBSUBTARGET_EXTRA_SPECS \
+ { "link_android", ANDROID_LINK_SPEC }, \
+ { "link_default", BPABI_LINK_SPEC }, \
+ { "cc1_android", ANDROID_CC1_SPEC }, \
+ { "cc1_default", CC1_DEFAULT_SPEC }, \
+ { "cc1plus_android", ANDROID_CC1PLUS_SPEC }, \
+ { "cc1plus_default", CC1PLUS_DEFAULT_SPEC }, \
+ { "lib_android", ANDROID_LIB_SPEC }, \
+ { "lib_default", LIB_DEFAULT_SPEC }, \
+ { "startfile_android", ANDROID_STARTFILE_SPEC }, \
+ { "startfile_default", UNKNOWN_ELF_STARTFILE_SPEC }, \
+ { "endfile_android", ANDROID_ENDFILE_SPEC }, \
+ { "endfile_default", UNKNOWN_ELF_ENDFILE_SPEC }, \
+
+#undef ANDROID_LINK_SPEC
+#define ANDROID_LINK_SPEC \
+"%{mbig-endian:-EB} %{mlittle-endian:-EL} " \
+"%{static:-Bstatic} %{shared:-shared} %{symbolic:-Bsymbolic} " \
+"%{!static:" \
+ "%{shared: -Bsymbolic} " \
+ "%{!shared:" \
+ "%{rdynamic:-export-dynamic} " \
+ "%{!dynamic-linker:-dynamic-linker /system/bin/linker}}} " \
+"-X" SUBTARGET_EXTRA_LINK_SPEC
+
+/* Override LINK_SPEC in bpabi.h. */
+#undef LINK_SPEC
+#define LINK_SPEC \
+"%{mandroid: %(link_android) ;" \
+" : %(link_default)}"
+
+/* Android uses -fno-exceptions by default. */
+#undef ANDROID_CC1_SPEC
+#define ANDROID_CC1_SPEC "%{!fexceptions:-fno-exceptions}"
+
+/* Default CC1_SPEC as in arm.h. */
+#undef CC1_DEFAULT_SPEC
+#define CC1_DEFAULT_SPEC ""
+
+#undef CC1_SPEC
+#define CC1_SPEC \
+"%{mandroid: %(cc1_android) ;" \
+" : %(cc1_default)}"
+
+/* Android uses -fno-rtti by default. */
+#undef ANDROID_CC1PLUS_SPEC
+#define ANDROID_CC1PLUS_SPEC "%{!frtti:-fno-rtti}"
+
+/* Default CC1PLUS_SPEC as in gcc.c. */
+#undef CC1PLUS_DEFAULT_SPEC
+#define CC1PLUS_DEFAULT_SPEC ""
+
+#undef CC1PLUS_SPEC
+#define CC1PLUS_SPEC \
+"%{mandroid: %(cc1plus_android) ;" \
+" : %(cc1plus_default)}"
+
+#undef ANDROID_LIB_SPEC
+#define ANDROID_LIB_SPEC "-lc %{!static:-ldl}"
+
+/* Default LIB_SPEC as in gcc.c. */
+#undef LIB_DEFAULT_SPEC
+#define LIB_DEFAULT_SPEC \
+"%{!shared:%{g*:-lg} %{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p}}"
+
+#undef LIB_SPEC
+#define LIB_SPEC \
+"%{mandroid: %(lib_android) ;" \
+" : %(lib_default)}"
+
+#undef ANDROID_STARTFILE_SPEC
+#define ANDROID_STARTFILE_SPEC \
+"%{!shared:" \
+ "%{static: crtbegin_static%O%s ;" \
+ " : crtbegin_dynamic%O%s}}"
+
+/* Override STARTFILE_SPEC in unknown-elf.h. */
+#undef STARTFILE_SPEC
+#define STARTFILE_SPEC \
+"%{mandroid: %(startfile_android) ;" \
+" : %(startfile_default)}"
+
+#undef ANDROID_ENDFILE_SPEC
+#define ANDROID_ENDFILE_SPEC "%{!shared:crtend_android%O%s}"
+
+/* Override ENDFILE_SPEC in unknown-elf.h. */
+#undef ENDFILE_SPEC
+#define ENDFILE_SPEC \
+"%{mandroid: %(endfile_android) ;" \
+" : %(endfile_default)}"
+
diff --git a/gcc/config/arm/eabi.opt b/gcc/config/arm/eabi.opt
new file mode 100644
index 00000000000..2cda98d56d1
--- /dev/null
+++ b/gcc/config/arm/eabi.opt
@@ -0,0 +1,23 @@
+; EABI specific options for ARM port of the compiler.
+
+; Copyright (C) 2008 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/>.
+
+mandroid
+Target Report RejectNegative Mask(ANDROID)
+Generate code for the Android operating system.
diff --git a/gcc/config/arm/elf.h b/gcc/config/arm/elf.h
index 37c366d5ac8..7c3eddbe058 100644
--- a/gcc/config/arm/elf.h
+++ b/gcc/config/arm/elf.h
@@ -36,7 +36,8 @@
#ifndef SUBTARGET_EXTRA_SPECS
#define SUBTARGET_EXTRA_SPECS \
{ "subtarget_extra_asm_spec", SUBTARGET_EXTRA_ASM_SPEC }, \
- { "subtarget_asm_float_spec", SUBTARGET_ASM_FLOAT_SPEC },
+ { "subtarget_asm_float_spec", SUBTARGET_ASM_FLOAT_SPEC }, \
+ SUBSUBTARGET_EXTRA_SPECS
#endif
#ifndef SUBTARGET_EXTRA_ASM_SPEC
@@ -48,6 +49,9 @@
%{mapcs-float:-mfloat}"
#endif
+#undef SUBSUBTARGET_EXTRA_SPECS
+#define SUBSUBTARGET_EXTRA_SPECS
+
#ifndef ASM_SPEC
#define ASM_SPEC "\
%{mbig-endian:-EB} \
diff --git a/gcc/config/arm/iwmmxt.md b/gcc/config/arm/iwmmxt.md
index 633aaaa875f..b484b55e6cd 100644
--- a/gcc/config/arm/iwmmxt.md
+++ b/gcc/config/arm/iwmmxt.md
@@ -168,8 +168,8 @@
)
(define_insn "movv8qi_internal"
- [(set (match_operand:V8QI 0 "nonimmediate_operand" "=y,m,y,?r,?y,?r,?r")
- (match_operand:V8QI 1 "general_operand" "y,y,mi,y,r,r,mi"))]
+ [(set (match_operand:V8QI 0 "nonimmediate_operand" "=y,m,y,?r,?y,?r,?r,?m")
+ (match_operand:V8QI 1 "general_operand" "y,y,mi,y,r,r,mi,r"))]
"TARGET_REALLY_IWMMXT"
"*
switch (which_alternative)
@@ -183,14 +183,14 @@
default: return output_move_double (operands);
}"
[(set_attr "predicable" "yes")
- (set_attr "length" "4, 4, 4,4,4,8, 8")
- (set_attr "type" "*,store1,load1,*,*,*,load1")
- (set_attr "pool_range" "*, *, 256,*,*,*, 256")
- (set_attr "neg_pool_range" "*, *, 244,*,*,*, 244")])
+ (set_attr "length" "4, 4, 4,4,4,8, 8,8")
+ (set_attr "type" "*,store1,load1,*,*,*,load1,store1")
+ (set_attr "pool_range" "*, *, 256,*,*,*, 256,*")
+ (set_attr "neg_pool_range" "*, *, 244,*,*,*, 244,*")])
(define_insn "movv4hi_internal"
- [(set (match_operand:V4HI 0 "nonimmediate_operand" "=y,m,y,?r,?y,?r,?r")
- (match_operand:V4HI 1 "general_operand" "y,y,mi,y,r,r,mi"))]
+ [(set (match_operand:V4HI 0 "nonimmediate_operand" "=y,m,y,?r,?y,?r,?r,?m")
+ (match_operand:V4HI 1 "general_operand" "y,y,mi,y,r,r,mi,r"))]
"TARGET_REALLY_IWMMXT"
"*
switch (which_alternative)
@@ -204,14 +204,14 @@
default: return output_move_double (operands);
}"
[(set_attr "predicable" "yes")
- (set_attr "length" "4, 4, 4,4,4,8, 8")
- (set_attr "type" "*,store1,load1,*,*,*,load1")
- (set_attr "pool_range" "*, *, 256,*,*,*, 256")
- (set_attr "neg_pool_range" "*, *, 244,*,*,*, 244")])
+ (set_attr "length" "4, 4, 4,4,4,8, 8,8")
+ (set_attr "type" "*,store1,load1,*,*,*,load1,store1")
+ (set_attr "pool_range" "*, *, 256,*,*,*, 256,*")
+ (set_attr "neg_pool_range" "*, *, 244,*,*,*, 244,*")])
(define_insn "movv2si_internal"
- [(set (match_operand:V2SI 0 "nonimmediate_operand" "=y,m,y,?r,?y,?r,?r")
- (match_operand:V2SI 1 "general_operand" "y,y,mi,y,r,r,mi"))]
+ [(set (match_operand:V2SI 0 "nonimmediate_operand" "=y,m,y,?r,?y,?r,?r,?m")
+ (match_operand:V2SI 1 "general_operand" "y,y,mi,y,r,r,mi,r"))]
"TARGET_REALLY_IWMMXT"
"*
switch (which_alternative)
@@ -225,10 +225,10 @@
default: return output_move_double (operands);
}"
[(set_attr "predicable" "yes")
- (set_attr "length" "4, 4, 4,4,4,8, 24")
- (set_attr "type" "*,store1,load1,*,*,*,load1")
- (set_attr "pool_range" "*, *, 256,*,*,*, 256")
- (set_attr "neg_pool_range" "*, *, 244,*,*,*, 244")])
+ (set_attr "length" "4, 4, 4,4,4,8, 24,8")
+ (set_attr "type" "*,store1,load1,*,*,*,load1,store1")
+ (set_attr "pool_range" "*, *, 256,*,*,*, 256,*")
+ (set_attr "neg_pool_range" "*, *, 244,*,*,*, 244,*")])
;; This pattern should not be needed. It is to match a
;; wierd case generated by GCC when no optimizations are
diff --git a/gcc/config/arm/unknown-elf.h b/gcc/config/arm/unknown-elf.h
index 38b791d12b1..331e40a1ece 100644
--- a/gcc/config/arm/unknown-elf.h
+++ b/gcc/config/arm/unknown-elf.h
@@ -33,11 +33,15 @@
#endif
/* Now we define the strings used to build the spec file. */
+#define UNKNOWN_ELF_STARTFILE_SPEC " crti%O%s crtbegin%O%s crt0%O%s"
+
#undef STARTFILE_SPEC
-#define STARTFILE_SPEC " crti%O%s crtbegin%O%s crt0%O%s"
+#define STARTFILE_SPEC UNKNOWN_ELF_STARTFILE_SPEC
+
+#define UNKNOWN_ELF_ENDFILE_SPEC "crtend%O%s crtn%O%s"
#undef ENDFILE_SPEC
-#define ENDFILE_SPEC "crtend%O%s crtn%O%s"
+#define ENDFILE_SPEC UNKNOWN_ELF_ENDFILE_SPEC
/* The __USES_INITFINI__ define is tested in newlib/libc/sys/arm/crt0.S
to see if it needs to invoked _init() and _fini(). */
diff --git a/gcc/config/avr/avr-protos.h b/gcc/config/avr/avr-protos.h
index b8493101fb9..7665555fd84 100644
--- a/gcc/config/avr/avr-protos.h
+++ b/gcc/config/avr/avr-protos.h
@@ -122,7 +122,6 @@ extern RTX_CODE avr_normalize_condition (RTX_CODE condition);
extern int compare_eq_p (rtx insn);
extern void out_shift_with_cnt (const char *template, rtx insn,
rtx operands[], int *len, int t_len);
-extern int avr_peep2_scratch_safe (rtx reg_rtx);
#endif /* RTX_CODE */
#ifdef HAVE_MACHINE_MODES
diff --git a/gcc/config/avr/avr.c b/gcc/config/avr/avr.c
index 0176a2aac8f..84625d81f8a 100644
--- a/gcc/config/avr/avr.c
+++ b/gcc/config/avr/avr.c
@@ -85,6 +85,7 @@ static int avr_address_cost (rtx);
static bool avr_return_in_memory (const_tree, const_tree);
static struct machine_function * avr_init_machine_status (void);
static rtx avr_builtin_setjmp_frame_value (void);
+static bool avr_hard_regno_scratch_ok (unsigned int);
/* Allocate registers from r25 to r8 for parameters for function calls. */
#define FIRST_CUM_REG 26
@@ -335,6 +336,9 @@ int avr_case_values_threshold = 30000;
#undef TARGET_BUILTIN_SETJMP_FRAME_VALUE
#define TARGET_BUILTIN_SETJMP_FRAME_VALUE avr_builtin_setjmp_frame_value
+#undef TARGET_HARD_REGNO_SCRATCH_OK
+#define TARGET_HARD_REGNO_SCRATCH_OK avr_hard_regno_scratch_ok
+
struct gcc_target targetm = TARGET_INITIALIZER;
void
@@ -5902,27 +5906,20 @@ avr_output_addr_vec_elt (FILE *stream, int value)
fprintf (stream, "\trjmp .L%d\n", value);
}
-/* Returns 1 if SCRATCH are safe to be allocated as a scratch
+/* Returns true if SCRATCH are safe to be allocated as a scratch
registers (for a define_peephole2) in the current function. */
-int
-avr_peep2_scratch_safe (rtx scratch)
+bool
+avr_hard_regno_scratch_ok (unsigned int regno)
{
- if ((interrupt_function_p (current_function_decl)
- || signal_function_p (current_function_decl))
- && leaf_function_p ())
- {
- int first_reg = true_regnum (scratch);
- int last_reg = first_reg + GET_MODE_SIZE (GET_MODE (scratch)) - 1;
- int reg;
+ /* Interrupt functions can only use registers that have already been saved
+ by the prologue, even if they would normally be call-clobbered. */
- for (reg = first_reg; reg <= last_reg; reg++)
- {
- if (!df_regs_ever_live_p (reg))
- return 0;
- }
- }
- return 1;
+ if ((cfun->machine->is_interrupt || cfun->machine->is_signal)
+ && !df_regs_ever_live_p (regno))
+ return false;
+
+ return true;
}
/* Return nonzero if register OLD_REG can be renamed to register NEW_REG. */
diff --git a/gcc/config/avr/avr.md b/gcc/config/avr/avr.md
index bf75698b8b6..4723dd4ad95 100644
--- a/gcc/config/avr/avr.md
+++ b/gcc/config/avr/avr.md
@@ -262,8 +262,7 @@
&& operands[1] != constm1_rtx)"
[(parallel [(set (match_dup 0) (match_dup 1))
(clobber (match_dup 2))])]
- "if (!avr_peep2_scratch_safe (operands[2]))
- FAIL;")
+ "")
;;============================================================================
;; move word (16 bit)
@@ -321,8 +320,7 @@
&& operands[1] != constm1_rtx)"
[(parallel [(set (match_dup 0) (match_dup 1))
(clobber (match_dup 2))])]
- "if (!avr_peep2_scratch_safe (operands[2]))
- FAIL;")
+ "")
;; '*' because it is not used in rtl generation, only in above peephole
(define_insn "*reload_inhi"
@@ -398,8 +396,7 @@
&& operands[1] != constm1_rtx)"
[(parallel [(set (match_dup 0) (match_dup 1))
(clobber (match_dup 2))])]
- "if (!avr_peep2_scratch_safe (operands[2]))
- FAIL;")
+ "")
;; '*' because it is not used in rtl generation.
(define_insn "*reload_insi"
@@ -1433,8 +1430,7 @@
""
[(parallel [(set (match_dup 0) (ashift:HI (match_dup 1) (match_dup 2)))
(clobber (match_dup 3))])]
- "if (!avr_peep2_scratch_safe (operands[3]))
- FAIL;")
+ "")
(define_insn "*ashlhi3_const"
[(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r")
@@ -1454,8 +1450,7 @@
""
[(parallel [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))
(clobber (match_dup 3))])]
- "if (!avr_peep2_scratch_safe (operands[3]))
- FAIL;")
+ "")
(define_insn "*ashlsi3_const"
[(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
@@ -1507,8 +1502,7 @@
""
[(parallel [(set (match_dup 0) (ashiftrt:HI (match_dup 1) (match_dup 2)))
(clobber (match_dup 3))])]
- "if (!avr_peep2_scratch_safe (operands[3]))
- FAIL;")
+ "")
(define_insn "*ashrhi3_const"
[(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r")
@@ -1528,8 +1522,7 @@
""
[(parallel [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (match_dup 2)))
(clobber (match_dup 3))])]
- "if (!avr_peep2_scratch_safe (operands[3]))
- FAIL;")
+ "")
(define_insn "*ashrsi3_const"
[(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
@@ -1581,8 +1574,7 @@
""
[(parallel [(set (match_dup 0) (lshiftrt:HI (match_dup 1) (match_dup 2)))
(clobber (match_dup 3))])]
- "if (!avr_peep2_scratch_safe (operands[3]))
- FAIL;")
+ "")
(define_insn "*lshrhi3_const"
[(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r")
@@ -1602,8 +1594,7 @@
""
[(parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (match_dup 2)))
(clobber (match_dup 3))])]
- "if (!avr_peep2_scratch_safe (operands[3]))
- FAIL;")
+ "")
(define_insn "*lshrsi3_const"
[(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
diff --git a/gcc/config/bfin/bfin.c b/gcc/config/bfin/bfin.c
index 05a5e495cea..843726067b6 100644
--- a/gcc/config/bfin/bfin.c
+++ b/gcc/config/bfin/bfin.c
@@ -1129,8 +1129,7 @@ bfin_load_pic_reg (rtx dest)
struct cgraph_local_info *i = NULL;
rtx addr, insn;
- if (flag_unit_at_a_time)
- i = cgraph_local_info (current_function_decl);
+ i = cgraph_local_info (current_function_decl);
/* Functions local to the translation unit don't need to reload the
pic reg, since the caller always passes a usable one. */
@@ -1906,6 +1905,7 @@ static bool
bfin_function_ok_for_sibcall (tree decl ATTRIBUTE_UNUSED,
tree exp ATTRIBUTE_UNUSED)
{
+ struct cgraph_local_info *this_func, *called_func;
e_funkind fkind = funkind (TREE_TYPE (current_function_decl));
if (fkind != SUBROUTINE)
return false;
@@ -1917,17 +1917,10 @@ bfin_function_ok_for_sibcall (tree decl ATTRIBUTE_UNUSED,
not need to reload P5 in the prologue, but the sibcall wil pop P5 in the
sibcall epilogue, and we end up with the wrong value in P5. */
- if (!flag_unit_at_a_time || decl == NULL)
- /* Not enough information. */
- return false;
-
- {
- struct cgraph_local_info *this_func, *called_func;
- this_func = cgraph_local_info (current_function_decl);
- called_func = cgraph_local_info (decl);
- return !called_func->local || this_func->local;
- }
+ this_func = cgraph_local_info (current_function_decl);
+ called_func = cgraph_local_info (decl);
+ return !called_func->local || this_func->local;
}
/* Emit RTL insns to initialize the variable parts of a trampoline at
diff --git a/gcc/config/cris/cris.c b/gcc/config/cris/cris.c
index 3a0eb2de066..a77f200d7ca 100644
--- a/gcc/config/cris/cris.c
+++ b/gcc/config/cris/cris.c
@@ -684,7 +684,7 @@ cris_print_operand (FILE *file, rtx x, int code)
/* Print the unsigned supplied integer as if it were signed
and < 0, i.e print 255 or 65535 as -1, 254, 65534 as -2, etc. */
if (!CONST_INT_P (x)
- || ! CONST_OK_FOR_LETTER_P (INTVAL (x), 'O'))
+ || !CRIS_CONST_OK_FOR_LETTER_P (INTVAL (x), 'O'))
LOSE_AND_RETURN ("invalid operand for 'b' modifier", x);
fprintf (file, HOST_WIDE_INT_PRINT_DEC,
INTVAL (x)| (INTVAL (x) <= 255 ? ~255 : ~65535));
@@ -1503,8 +1503,8 @@ cris_normal_notice_update_cc (rtx exp, rtx insn)
> CRIS_LAST_GENERAL_REGISTER))
|| (TARGET_V32
&& GET_CODE (SET_SRC (exp)) == CONST_INT
- && CONST_OK_FOR_LETTER_P (INTVAL (SET_SRC (exp)),
- 'I')))
+ && CRIS_CONST_OK_FOR_LETTER_P (INTVAL (SET_SRC (exp)),
+ 'I')))
{
/* There's no CC0 change for this case. Just check
for overlap. */
@@ -1831,7 +1831,7 @@ cris_rtx_costs (rtx x, int code, int outer_code, int *total)
if (CONST_INT_P (XEXP (x, 1))
/* Two constants may actually happen before optimization. */
&& !CONST_INT_P (XEXP (x, 0))
- && !CONST_OK_FOR_LETTER_P (INTVAL (XEXP (x, 1)), 'I'))
+ && !CRIS_CONST_OK_FOR_LETTER_P (INTVAL (XEXP (x, 1)), 'I'))
{
*total = (rtx_cost (XEXP (x, 0), outer_code) + 2
+ 2 * GET_MODE_NUNITS (GET_MODE (XEXP (x, 0))));
@@ -1905,7 +1905,8 @@ cris_address_cost (rtx x)
/* A BDAP -32768 .. 32767 is like BDAP quick, but with 2 extra
bytes. */
- if (CONST_INT_P (tem2) && CONST_OK_FOR_LETTER_P (INTVAL (tem2), 'L'))
+ if (CONST_INT_P (tem2)
+ && CRIS_CONST_OK_FOR_LETTER_P (INTVAL (tem2), 'L'))
return (2 + 2) / 2;
/* A BDAP with some other constant is 2 bytes extra. */
diff --git a/gcc/config/cris/cris.h b/gcc/config/cris/cris.h
index 915c3143ceb..b8a66e96a4b 100644
--- a/gcc/config/cris/cris.h
+++ b/gcc/config/cris/cris.h
@@ -668,7 +668,7 @@ enum reg_class
/* We are now out of letters; we could use ten more. This forces us to
use C-code in the 'md' file. FIXME: Use some EXTRA_CONSTRAINTS. */
-#define CONST_OK_FOR_LETTER_P(VALUE, C) \
+#define CRIS_CONST_OK_FOR_LETTER_P(VALUE, C) \
( \
/* MOVEQ, CMPQ, ANDQ, ORQ. */ \
(C) == 'I' ? (VALUE) >= -32 && (VALUE) <= 31 : \
@@ -691,6 +691,16 @@ enum reg_class
(C) == 'P' ? (VALUE) >= -32768 && (VALUE) <= 65535 : \
0)
+#define CONST_OK_FOR_CONSTRAINT_P(VALUE, C, S) \
+ ( \
+ ((C) != 'K' || (S)[1] == 'c') \
+ ? CRIS_CONST_OK_FOR_LETTER_P (VALUE, C) : \
+ ((C) == 'K' && (S)[1] == 'p') \
+ ? exact_log2 (VALUE) >= 0 : \
+ 0)
+
+#define CONSTRAINT_LEN(C, S) ((C) == 'K' ? 2 : DEFAULT_CONSTRAINT_LEN (C, S))
+
/* It is really simple to make up a 0.0; it is the same as int-0 in
IEEE754. */
#define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) \
diff --git a/gcc/config/cris/cris.md b/gcc/config/cris/cris.md
index 9e3ec027d38..12e443115cd 100644
--- a/gcc/config/cris/cris.md
+++ b/gcc/config/cris/cris.md
@@ -347,7 +347,7 @@
(define_insn "*cmpdi_non_v32"
[(set (cc0)
(compare (match_operand:DI 0 "nonimmediate_operand" "r,r,r,r,r,r,o")
- (match_operand:DI 1 "general_operand" "K,I,P,n,r,o,r")))]
+ (match_operand:DI 1 "general_operand" "Kc,I,P,n,r,o,r")))]
"!TARGET_V32"
"@
cmpq %1,%M0\;ax\;cmpq 0,%H0
@@ -361,7 +361,7 @@
(define_insn "*cmpdi_v32"
[(set (cc0)
(compare (match_operand:DI 0 "register_operand" "r,r,r,r,r")
- (match_operand:DI 1 "nonmemory_operand" "K,I,P,n,r")))]
+ (match_operand:DI 1 "nonmemory_operand" "Kc,I,P,n,r")))]
"TARGET_V32"
"@
cmpq %1,%M0\;ax\;cmpq 0,%H0
@@ -458,9 +458,9 @@
(define_insn "*btst"
[(set (cc0)
(zero_extract
- (match_operand:SI 0 "nonmemory_operand" "r,r,r,r,r,r,n")
- (match_operand:SI 1 "const_int_operand" "K,n,K,n,K,n,n")
- (match_operand:SI 2 "nonmemory_operand" "M,M,K,n,r,r,r")))]
+ (match_operand:SI 0 "nonmemory_operand" "r, r,r, r,r, r,Kp")
+ (match_operand:SI 1 "const_int_operand" "Kc,n,Kc,n,Kc,n,n")
+ (match_operand:SI 2 "nonmemory_operand" "M, M,Kc,n,r, r,r")))]
;; Either it is a single bit, or consecutive ones starting at 0.
;; The btst ones depend on stuff in NOTICE_UPDATE_CC.
"CONST_INT_P (operands[1])
@@ -690,8 +690,8 @@
&& (!CONST_INT_P (operands[2])
|| INTVAL (operands[2]) > 127
|| INTVAL (operands[2]) < -128
- || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'N')
- || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J')))
+ || CRIS_CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'N')
+ || CRIS_CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J')))
return "#";
if (which_alternative == 4)
return "move<m> [%3=%2%S1],%0";
@@ -717,8 +717,8 @@
&& (!CONST_INT_P (operands[2])
|| INTVAL (operands[2]) > 127
|| INTVAL (operands[2]) < -128
- || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'N')
- || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J')))
+ || CRIS_CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'N')
+ || CRIS_CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J')))
return "#";
if (which_alternative < 3)
return "move.%s0 [%3=%1%S2],%0";
@@ -836,8 +836,8 @@
&& (!CONST_INT_P (operands[1])
|| INTVAL (operands[1]) > 127
|| INTVAL (operands[1]) < -128
- || CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'N')
- || CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'J')))
+ || CRIS_CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'N')
+ || CRIS_CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'J')))
return "#";
if (which_alternative == 1 || which_alternative == 5)
return "#";
@@ -870,8 +870,8 @@
&& (!CONST_INT_P (operands[1])
|| INTVAL (operands[1]) > 127
|| INTVAL (operands[1]) < -128
- || CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'N')
- || CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'J')))
+ || CRIS_CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'N')
+ || CRIS_CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'J')))
return "#";
if (which_alternative == 1
|| which_alternative == 7
@@ -943,8 +943,8 @@
&& (!CONST_INT_P (operands[1])
|| INTVAL (operands[1]) > 127
|| INTVAL (operands[1]) < -128
- || CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'N')
- || CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'J')))
+ || CRIS_CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'N')
+ || CRIS_CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'J')))
return "#";
if (which_alternative == 4)
return "clear<m> [%2=%1%S0]";
@@ -1286,8 +1286,8 @@
&& (!CONST_INT_P (operands[2])
|| INTVAL (operands[2]) > 127
|| INTVAL (operands[2]) < -128
- || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'N')
- || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J')))
+ || CRIS_CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'N')
+ || CRIS_CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J')))
return "#";
if (which_alternative == 4)
return "mov%e4.%m4 [%3=%2%S1],%0";
@@ -1310,8 +1310,8 @@
&& (!CONST_INT_P (operands[2])
|| INTVAL (operands[2]) > 127
|| INTVAL (operands[2]) < -128
- || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'N')
- || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J')))
+ || CRIS_CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'N')
+ || CRIS_CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J')))
return "#";
if (which_alternative == 4)
return "mov%e4<m> [%3=%2%S1],%0";
@@ -1647,8 +1647,8 @@
&& (!CONST_INT_P (operands[3])
|| INTVAL (operands[3]) > 127
|| INTVAL (operands[3]) < -128
- || CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'N')
- || CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'J')))
+ || CRIS_CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'N')
+ || CRIS_CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'J')))
return "#";
if (which_alternative == 4)
return "%x5.%s0 [%4=%3%S2],%0";
@@ -1705,8 +1705,8 @@
&& (!CONST_INT_P (operands[3])
|| INTVAL (operands[3]) > 127
|| INTVAL (operands[3]) < -128
- || CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'N')
- || CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'J')))
+ || CRIS_CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'N')
+ || CRIS_CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'J')))
return "#";
if (which_alternative == 4)
return "%x5<m> [%4=%3%S2],%0";
@@ -2137,8 +2137,8 @@
&& (!CONST_INT_P (operands[3])
|| INTVAL (operands[3]) > 127
|| INTVAL (operands[3]) < -128
- || CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'N')
- || CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'J')))
+ || CRIS_CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'N')
+ || CRIS_CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'J')))
return "#";
if (which_alternative == 4)
return "%x5%E6.%m6 [%4=%3%S2],%0";
@@ -2166,8 +2166,8 @@
&& (!CONST_INT_P (operands[3])
|| INTVAL (operands[3]) > 127
|| INTVAL (operands[3]) < -128
- || CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'N')
- || CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'J')))
+ || CRIS_CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'N')
+ || CRIS_CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'J')))
return "#";
if (which_alternative == 4)
return "%x5%E6<m> [%4=%3%S2],%0";
@@ -2246,8 +2246,8 @@
&& (!CONST_INT_P (operands[3])
|| INTVAL (operands[3]) > 127
|| INTVAL (operands[3]) < -128
- || CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'N')
- || CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'J')))
+ || CRIS_CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'N')
+ || CRIS_CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'J')))
return "#";
if (which_alternative == 4)
return "add%e5.b [%4=%3%S2],%0";
@@ -2274,8 +2274,8 @@
&& (!CONST_INT_P (operands[3])
|| INTVAL (operands[3]) > 127
|| INTVAL (operands[3]) < -128
- || CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'N')
- || CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'J')))
+ || CRIS_CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'N')
+ || CRIS_CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'J')))
return "#";
if (which_alternative == 4)
return \"%x6%E5.%m5 [%4=%3%S2],%0\";
@@ -3238,7 +3238,7 @@
(define_insn "<shlr>si3"
[(set (match_operand:SI 0 "register_operand" "=r")
(shift:SI (match_operand:SI 1 "register_operand" "0")
- (match_operand:SI 2 "nonmemory_operand" "Kr")))]
+ (match_operand:SI 2 "nonmemory_operand" "Kcr")))]
""
{
if (REG_S_P (operands[2]))
@@ -3318,7 +3318,7 @@
(define_insn "ashl<mode>3"
[(set (match_operand:BW 0 "register_operand" "=r,r")
(ashift:BW (match_operand:BW 1 "register_operand" "0,0")
- (match_operand:BW 2 "nonmemory_operand" "r,K")))]
+ (match_operand:BW 2 "nonmemory_operand" "r,Kc")))]
""
{
return
@@ -4668,8 +4668,8 @@
"GET_MODE_SIZE (GET_MODE (operands[4])) <= UNITS_PER_WORD
&& REGNO (operands[3]) != REGNO (operands[0])
&& (BASE_P (operands[1]) || BASE_P (operands[2]))
- && ! CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J')
- && ! CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'N')
+ && !CRIS_CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J')
+ && !CRIS_CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'N')
&& (INTVAL (operands[2]) >= -128 && INTVAL (operands[2]) < 128)
&& TARGET_SIDE_EFFECT_PREFIXES"
[(parallel
@@ -4704,8 +4704,8 @@
"GET_MODE_SIZE (GET_MODE (operands[4])) <= UNITS_PER_WORD
&& REGNO (operands[4]) != REGNO (operands[0])
&& (BASE_P (operands[1]) || BASE_P (operands[2]))
- && ! CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J')
- && ! CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'N')
+ && !CRIS_CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J')
+ && !CRIS_CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'N')
&& (INTVAL (operands[2]) >= -128 && INTVAL (operands[2]) < 128)
&& TARGET_SIDE_EFFECT_PREFIXES"
[(parallel
@@ -4742,8 +4742,8 @@
;; Change to GET_MODE_SIZE (GET_MODE (operands[3])) <= UNITS_PER_WORD?
"GET_MODE (operands[3]) != DImode
&& REGNO (operands[0]) != REGNO (operands[3])
- && ! CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J')
- && ! CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'N')
+ && !CRIS_CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J')
+ && !CRIS_CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'N')
&& INTVAL (operands[2]) >= -128
&& INTVAL (operands[2]) <= 127
&& TARGET_SIDE_EFFECT_PREFIXES"
@@ -4934,7 +4934,7 @@
;; don't do this for a mem-volatile access.
"REGNO (operands[2]) == REGNO (operands[0])
&& INTVAL (operands[3]) <= 65535 && INTVAL (operands[3]) >= 0
- && !CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'I')
+ && !CRIS_CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'I')
&& !side_effects_p (operands[1])"
;; FIXME: CC0 valid except for M (i.e. CC_NOT_NEGATIVE).
[(set (match_dup 0) (match_dup 4))
@@ -4942,7 +4942,7 @@
{
enum machine_mode zmode = INTVAL (operands[3]) <= 255 ? QImode : HImode;
enum machine_mode amode
- = CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'O') ? SImode : zmode;
+ = CRIS_CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'O') ? SImode : zmode;
rtx op1
= (REG_S_P (operands[1])
? gen_rtx_REG (zmode, REGNO (operands[1]))
diff --git a/gcc/config/frv/frv.c b/gcc/config/frv/frv.c
index 6ba924b1df7..07e8eaae928 100644
--- a/gcc/config/frv/frv.c
+++ b/gcc/config/frv/frv.c
@@ -2207,7 +2207,7 @@ frv_expand_builtin_va_start (tree valist, rtx nextarg)
debug_rtx (nextarg);
}
- t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (valist), valist,
+ t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist,
fold_convert (TREE_TYPE (valist),
make_tree (sizetype, nextarg)));
TREE_SIDE_EFFECTS (t) = 1;
diff --git a/gcc/config/h8300/h8300.c b/gcc/config/h8300/h8300.c
index f90bd414735..86790699f13 100644
--- a/gcc/config/h8300/h8300.c
+++ b/gcc/config/h8300/h8300.c
@@ -111,6 +111,7 @@ static unsigned int h8300_bitfield_length (rtx, rtx);
static unsigned int h8300_binary_length (rtx, const h8300_length_table *);
static bool h8300_short_move_mem_p (rtx, enum rtx_code);
static unsigned int h8300_move_length (rtx *, const h8300_length_table *);
+static bool h8300_hard_regno_scratch_ok (unsigned int);
/* CPU_TYPE, says what cpu we're compiling for. */
int cpu_type;
@@ -5612,6 +5613,20 @@ h8300_hard_regno_rename_ok (unsigned int old_reg ATTRIBUTE_UNUSED,
return 1;
}
+/* Returns true if register REGNO is safe to be allocated as a scratch
+ register in the current function. */
+
+static bool
+h8300_hard_regno_scratch_ok (unsigned int regno)
+{
+ if (h8300_current_function_interrupt_function_p ()
+ && ! WORD_REG_USED (regno))
+ return false;
+
+ return true;
+}
+
+
/* Return nonzero if X is a legitimate constant. */
int
@@ -5745,6 +5760,9 @@ h8300_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
#undef TARGET_MACHINE_DEPENDENT_REORG
#define TARGET_MACHINE_DEPENDENT_REORG h8300_reorg
+#undef TARGET_HARD_REGNO_SCRATCH_OK
+#define TARGET_HARD_REGNO_SCRATCH_OK h8300_hard_regno_scratch_ok
+
#undef TARGET_DEFAULT_TARGET_FLAGS
#define TARGET_DEFAULT_TARGET_FLAGS TARGET_DEFAULT
diff --git a/gcc/config/h8300/h8300.md b/gcc/config/h8300/h8300.md
index 9b6c0aa4e16..b48a9d6ef75 100644
--- a/gcc/config/h8300/h8300.md
+++ b/gcc/config/h8300/h8300.md
@@ -91,7 +91,7 @@
(const_int -126))
(le (plus (minus (match_dup 0) (pc))
(symbol_ref "DELAY_SLOT_LENGTH (insn)"))
- (const_int 126)))
+ (const_int 125)))
(const_int 2)
(if_then_else (and (eq_attr "cpu" "h8300h")
(and (ge (minus (pc) (match_dup 0))
diff --git a/gcc/config/host-linux.c b/gcc/config/host-linux.c
index f0666173b62..c94f822f701 100644
--- a/gcc/config/host-linux.c
+++ b/gcc/config/host-linux.c
@@ -84,6 +84,8 @@
# define TRY_EMPTY_VM_SPACE 0x8000000000
#elif defined(__sparc__)
# define TRY_EMPTY_VM_SPACE 0x60000000
+#elif defined(__mc68000__)
+# define TRY_EMPTY_VM_SPACE 0x40000000
#else
# define TRY_EMPTY_VM_SPACE 0
#endif
diff --git a/gcc/config/host-solaris.c b/gcc/config/host-solaris.c
index 9a471b49f4c..bde01db9813 100644
--- a/gcc/config/host-solaris.c
+++ b/gcc/config/host-solaris.c
@@ -42,7 +42,7 @@ sol_gt_pch_use_address (void *base, size_t size, int fd, size_t offset)
if (size == 0)
return -1;
- addr = mmap (base, size, PROT_READ | PROT_WRITE, MAP_PRIVATE,
+ addr = mmap ((caddr_t) base, size, PROT_READ | PROT_WRITE, MAP_PRIVATE,
fd, offset);
/* Solaris isn't good about honoring the mmap START parameter
@@ -55,18 +55,18 @@ sol_gt_pch_use_address (void *base, size_t size, int fd, size_t offset)
size_t i;
if (addr != (void *) MAP_FAILED)
- munmap (addr, size);
+ munmap ((caddr_t) addr, size);
errno = 0;
for (i = 0; i < size; i += page_size)
- if (mincore ((char *)base + i, page_size, (void *)&one_byte) == -1
+ if (mincore ((char *)base + i, page_size, (char *) &one_byte) == -1
&& errno == ENOMEM)
continue; /* The page is not mapped. */
else
break;
if (i >= size)
- addr = mmap (base, size,
+ addr = mmap ((caddr_t) base, size,
PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED,
fd, offset);
}
diff --git a/gcc/config/i386/cross-stdarg.h b/gcc/config/i386/cross-stdarg.h
new file mode 100644
index 00000000000..98ac1ecd5cc
--- /dev/null
+++ b/gcc/config/i386/cross-stdarg.h
@@ -0,0 +1,76 @@
+/* Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008
+ 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 2, 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 COPYING. If not, write to
+ the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA. */
+
+/* As a special exception, if you include this header file into source
+ files compiled by GCC, this header file does not by itself cause
+ the resulting executable to be covered by the GNU General Public
+ License. This exception does not however invalidate any other
+ reasons why the executable file might be covered by the GNU General
+ Public License. */
+
+#ifndef __CROSS_STDARG_H_INCLUDED
+#define __CROSS_STDARG_H_INCLUDED
+
+/* Make sure that for non x64 targets cross builtins are defined. */
+#ifndef __x86_64__
+/* Call abi ms_abi. */
+#define __builtin_ms_va_list __builtin_va_list
+#define __builtin_ms_va_copy __builtin_va_copy
+#define __builtin_ms_va_start __builtin_va_start
+#define __builtin_ms_va_end __builtin_va_end
+
+/* Call abi sysv_abi. */
+#define __builtin_sysv_va_list __builtin_va_list
+#define __builtin_sysv_va_copy __builtin_va_copy
+#define __builtin_sysv_va_start __builtin_va_start
+#define __builtin_sysv_va_end __builtin_va_end
+#endif
+
+#define __ms_va_copy(__d,__s) __builtin_ms_va_copy(__d,__s)
+#define __ms_va_start(__v,__l) __builtin_ms_va_start(__v,__l)
+#define __ms_va_arg(__v,__l) __builtin_va_arg(__v,__l)
+#define __ms_va_end(__v) __builtin_ms_va_end(__v)
+
+#define __sysv_va_copy(__d,__s) __builtin_sysv_va_copy(__d,__s)
+#define __sysv_va_start(__v,__l) __builtin_sysv_va_start(__v,__l)
+#define __sysv_va_arg(__v,__l) __builtin_va_arg(__v,__l)
+#define __sysv_va_end(__v) __builtin_sysv_va_end(__v)
+
+#ifndef __GNUC_SYSV_VA_LIST
+#define __GNUC_SYSV_VA_LIST
+ typedef __builtin_sysv_va_list __gnuc_sysv_va_list;
+#endif
+
+#ifndef _SYSV_VA_LIST_DEFINED
+#define _SYSV_VA_LIST_DEFINED
+ typedef __gnuc_sysv_va_list sysv_va_list;
+#endif
+
+#ifndef __GNUC_MS_VA_LIST
+#define __GNUC_MS_VA_LIST
+ typedef __builtin_ms_va_list __gnuc_ms_va_list;
+#endif
+
+#ifndef _MS_VA_LIST_DEFINED
+#define _MS_VA_LIST_DEFINED
+ typedef __gnuc_ms_va_list ms_va_list;
+#endif
+
+#endif /* __CROSS_STDARG_H_INCLUDED */
diff --git a/gcc/config/i386/darwin.h b/gcc/config/i386/darwin.h
index 6001f64b42a..c6ed10d8a72 100644
--- a/gcc/config/i386/darwin.h
+++ b/gcc/config/i386/darwin.h
@@ -263,8 +263,8 @@ extern void darwin_x86_file_end (void);
: (n) >= 11 && (n) <= 18 ? (n) + 1 \
: (n))
-#undef REGISTER_TARGET_PRAGMAS
-#define REGISTER_TARGET_PRAGMAS() DARWIN_REGISTER_TARGET_PRAGMAS()
+#undef REGISTER_SUBTARGET_PRAGMAS
+#define REGISTER_SUBTARGET_PRAGMAS() DARWIN_REGISTER_TARGET_PRAGMAS()
#undef TARGET_SET_DEFAULT_TYPE_ATTRIBUTES
#define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES darwin_set_default_type_attributes
diff --git a/gcc/config/i386/i386-c.c b/gcc/config/i386/i386-c.c
new file mode 100644
index 00000000000..f0a3a17f9f6
--- /dev/null
+++ b/gcc/config/i386/i386-c.c
@@ -0,0 +1,344 @@
+/* Subroutines used for macro/preprocessor support on the ia-32.
+ Copyright (C) 2008
+ 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/>. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "rtl.h"
+#include "tree.h"
+#include "tm_p.h"
+#include "flags.h"
+#include "c-common.h"
+#include "ggc.h"
+#include "target.h"
+#include "target-def.h"
+#include "cpplib.h"
+#include "c-pragma.h"
+
+static bool ix86_pragma_option_parse (tree);
+static void ix86_target_macros_internal
+ (int, enum processor_type, enum processor_type, enum fpmath_unit,
+ void (*def_or_undef) (cpp_reader *, const char *));
+
+
+/* Internal function to either define or undef the appropriate system
+ macros. */
+static void
+ix86_target_macros_internal (int isa_flag,
+ enum processor_type arch,
+ enum processor_type tune,
+ enum fpmath_unit fpmath,
+ void (*def_or_undef) (cpp_reader *,
+ const char *))
+{
+ /* For some of the k6/pentium varients there weren't seperate ISA bits to
+ identify which tune/arch flag was passed, so figure it out here. */
+ size_t arch_len = strlen (ix86_arch_string);
+ size_t tune_len = strlen (ix86_tune_string);
+ int last_arch_char = ix86_arch_string[arch_len - 1];
+ int last_tune_char = ix86_tune_string[tune_len - 1];
+
+ /* Built-ins based on -march=. */
+ switch (arch)
+ {
+ case PROCESSOR_I386:
+ break;
+ case PROCESSOR_I486:
+ def_or_undef (parse_in, "__i486");
+ def_or_undef (parse_in, "__i486__");
+ break;
+ case PROCESSOR_PENTIUM:
+ def_or_undef (parse_in, "__i586");
+ def_or_undef (parse_in, "__i586__");
+ def_or_undef (parse_in, "__pentium");
+ def_or_undef (parse_in, "__pentium__");
+ if (isa_flag & OPTION_MASK_ISA_MMX)
+ def_or_undef (parse_in, "__pentium_mmx__");
+ break;
+ case PROCESSOR_PENTIUMPRO:
+ def_or_undef (parse_in, "__i686");
+ def_or_undef (parse_in, "__i686__");
+ def_or_undef (parse_in, "__pentiumpro");
+ def_or_undef (parse_in, "__pentiumpro__");
+ break;
+ case PROCESSOR_GEODE:
+ def_or_undef (parse_in, "__geode");
+ def_or_undef (parse_in, "__geode__");
+ break;
+ case PROCESSOR_K6:
+ def_or_undef (parse_in, "__k6");
+ def_or_undef (parse_in, "__k6__");
+ if (last_arch_char == '2')
+ def_or_undef (parse_in, "__k6_2__");
+ else if (last_arch_char == '3')
+ def_or_undef (parse_in, "__k6_3__");
+ else if (isa_flag & OPTION_MASK_ISA_3DNOW)
+ def_or_undef (parse_in, "__k6_3__");
+ break;
+ case PROCESSOR_ATHLON:
+ def_or_undef (parse_in, "__athlon");
+ def_or_undef (parse_in, "__athlon__");
+ if (isa_flag & OPTION_MASK_ISA_SSE)
+ def_or_undef (parse_in, "__athlon_sse__");
+ break;
+ case PROCESSOR_K8:
+ def_or_undef (parse_in, "__k8");
+ def_or_undef (parse_in, "__k8__");
+ break;
+ case PROCESSOR_AMDFAM10:
+ def_or_undef (parse_in, "__amdfam10");
+ def_or_undef (parse_in, "__amdfam10__");
+ break;
+ case PROCESSOR_PENTIUM4:
+ def_or_undef (parse_in, "__pentium4");
+ def_or_undef (parse_in, "__pentium4__");
+ break;
+ case PROCESSOR_NOCONA:
+ def_or_undef (parse_in, "__nocona");
+ def_or_undef (parse_in, "__nocona__");
+ break;
+ case PROCESSOR_CORE2:
+ def_or_undef (parse_in, "__core2");
+ def_or_undef (parse_in, "__core2__");
+ break;
+ /* use PROCESSOR_max to not set/unset the arch macro. */
+ case PROCESSOR_max:
+ break;
+ case PROCESSOR_GENERIC32:
+ case PROCESSOR_GENERIC64:
+ gcc_unreachable ();
+ }
+
+ /* Built-ins based on -mtune=. */
+ switch (tune)
+ {
+ case PROCESSOR_I386:
+ def_or_undef (parse_in, "__tune_i386__");
+ break;
+ case PROCESSOR_I486:
+ def_or_undef (parse_in, "__tune_i486__");
+ break;
+ case PROCESSOR_PENTIUM:
+ def_or_undef (parse_in, "__tune_i586__");
+ def_or_undef (parse_in, "__tune_pentium__");
+ if (last_tune_char == 'x')
+ def_or_undef (parse_in, "__tune_pentium_mmx__");
+ break;
+ case PROCESSOR_PENTIUMPRO:
+ def_or_undef (parse_in, "__tune_i686__");
+ def_or_undef (parse_in, "__tune_pentiumpro__");
+ switch (last_tune_char)
+ {
+ case '3':
+ def_or_undef (parse_in, "__tune_pentium3__");
+ /* FALLTHRU */
+ case '2':
+ def_or_undef (parse_in, "__tune_pentium2__");
+ break;
+ }
+ break;
+ case PROCESSOR_GEODE:
+ def_or_undef (parse_in, "__tune_geode__");
+ break;
+ case PROCESSOR_K6:
+ def_or_undef (parse_in, "__tune_k6__");
+ if (last_tune_char == '2')
+ def_or_undef (parse_in, "__tune_k6_2__");
+ else if (last_tune_char == '3')
+ def_or_undef (parse_in, "__tune_k6_3__");
+ else if (isa_flag & OPTION_MASK_ISA_3DNOW)
+ def_or_undef (parse_in, "__tune_k6_3__");
+ break;
+ case PROCESSOR_ATHLON:
+ def_or_undef (parse_in, "__tune_athlon__");
+ if (isa_flag & OPTION_MASK_ISA_SSE)
+ def_or_undef (parse_in, "__tune_athlon_sse__");
+ break;
+ case PROCESSOR_K8:
+ def_or_undef (parse_in, "__tune_k8__");
+ break;
+ case PROCESSOR_AMDFAM10:
+ def_or_undef (parse_in, "__tune_amdfam10__");
+ break;
+ case PROCESSOR_PENTIUM4:
+ def_or_undef (parse_in, "__tune_pentium4__");
+ break;
+ case PROCESSOR_NOCONA:
+ def_or_undef (parse_in, "__tune_nocona__");
+ break;
+ case PROCESSOR_CORE2:
+ def_or_undef (parse_in, "__tune_core2__");
+ break;
+ case PROCESSOR_GENERIC32:
+ case PROCESSOR_GENERIC64:
+ break;
+ /* use PROCESSOR_max to not set/unset the tune macro. */
+ case PROCESSOR_max:
+ break;
+ }
+
+ if (isa_flag & OPTION_MASK_ISA_MMX)
+ def_or_undef (parse_in, "__MMX__");
+ if (isa_flag & OPTION_MASK_ISA_3DNOW)
+ def_or_undef (parse_in, "__3dNOW__");
+ if (isa_flag & OPTION_MASK_ISA_3DNOW_A)
+ def_or_undef (parse_in, "__3dNOW_A__");
+ if (isa_flag & OPTION_MASK_ISA_SSE)
+ def_or_undef (parse_in, "__SSE__");
+ if (isa_flag & OPTION_MASK_ISA_SSE2)
+ def_or_undef (parse_in, "__SSE2__");
+ if (isa_flag & OPTION_MASK_ISA_SSE3)
+ def_or_undef (parse_in, "__SSE3__");
+ if (isa_flag & OPTION_MASK_ISA_SSSE3)
+ def_or_undef (parse_in, "__SSSE3__");
+ if (isa_flag & OPTION_MASK_ISA_SSE4_1)
+ def_or_undef (parse_in, "__SSE4_1__");
+ if (isa_flag & OPTION_MASK_ISA_SSE4_2)
+ def_or_undef (parse_in, "__SSE4_2__");
+ if (isa_flag & OPTION_MASK_ISA_AES)
+ def_or_undef (parse_in, "__AES__");
+ if (isa_flag & OPTION_MASK_ISA_PCLMUL)
+ def_or_undef (parse_in, "__PCLMUL__");
+ if (isa_flag & OPTION_MASK_ISA_SSE4A)
+ def_or_undef (parse_in, "__SSE4A__");
+ if (isa_flag & OPTION_MASK_ISA_SSE5)
+ def_or_undef (parse_in, "__SSE5__");
+ if ((fpmath & FPMATH_SSE) && (isa_flag & OPTION_MASK_ISA_SSE))
+ def_or_undef (parse_in, "__SSE_MATH__");
+ if ((fpmath & FPMATH_SSE) && (isa_flag & OPTION_MASK_ISA_SSE2))
+ def_or_undef (parse_in, "__SSE2_MATH__");
+}
+
+
+/* Hook to validate the current #pragma option and set the state, and update
+ the macros based on what was changed. */
+
+static bool
+ix86_pragma_option_parse (tree args)
+{
+ tree prev_tree = build_target_option_node ();
+ tree cur_tree;
+ struct cl_target_option *prev_opt;
+ struct cl_target_option *cur_opt;
+ int prev_isa;
+ int cur_isa;
+ int diff_isa;
+ enum processor_type prev_arch;
+ enum processor_type prev_tune;
+ enum processor_type cur_arch;
+ enum processor_type cur_tune;
+
+ if (! args)
+ {
+ cur_tree = target_option_default_node;
+ cl_target_option_restore (TREE_TARGET_OPTION (cur_tree));
+ }
+ else
+ {
+ cur_tree = ix86_valid_option_attribute_tree (args);
+ if (!cur_tree)
+ return false;
+ }
+
+ target_option_current_node = cur_tree;
+
+ /* Figure out the previous/current isa, arch, tune and the differences. */
+ prev_opt = TREE_TARGET_OPTION (prev_tree);
+ cur_opt = TREE_TARGET_OPTION (cur_tree);
+ prev_isa = prev_opt->ix86_isa_flags;
+ cur_isa = cur_opt->ix86_isa_flags;
+ diff_isa = (prev_isa ^ cur_isa);
+ prev_arch = prev_opt->arch;
+ prev_tune = prev_opt->tune;
+ cur_arch = cur_opt->arch;
+ cur_tune = cur_opt->tune;
+
+ /* If the same processor is used for both previous and current options, don't
+ change the macros. */
+ if (cur_arch == prev_arch)
+ cur_arch = prev_arch = PROCESSOR_max;
+
+ if (cur_tune == prev_tune)
+ cur_tune = prev_tune = PROCESSOR_max;
+
+ /* Undef all of the macros for that are no longer current. */
+ ix86_target_macros_internal (prev_isa & diff_isa,
+ prev_arch,
+ prev_tune,
+ prev_opt->fpmath,
+ cpp_undef);
+
+ /* Define all of the macros for new options that were just turned on. */
+ ix86_target_macros_internal (cur_isa & diff_isa,
+ cur_arch,
+ cur_tune,
+ cur_opt->fpmath,
+ cpp_define);
+
+ return true;
+}
+
+/* Function to tell the preprocessor about the defines for the current target. */
+
+void
+ix86_target_macros (void)
+{
+ /* 32/64-bit won't change with target specific options, so do the assert and
+ builtin_define_std calls here. */
+ if (TARGET_64BIT)
+ {
+ cpp_assert (parse_in, "cpu=x86_64");
+ cpp_assert (parse_in, "machine=x86_64");
+ cpp_define (parse_in, "__amd64");
+ cpp_define (parse_in, "__amd64__");
+ cpp_define (parse_in, "__x86_64");
+ cpp_define (parse_in, "__x86_64__");
+ }
+ else
+ {
+ cpp_assert (parse_in, "cpu=i386");
+ cpp_assert (parse_in, "machine=i386");
+ builtin_define_std ("i386");
+ }
+
+ ix86_target_macros_internal (ix86_isa_flags,
+ ix86_arch,
+ ix86_tune,
+ ix86_fpmath,
+ cpp_define);
+}
+
+
+/* Register target pragmas. We need to add the hook for parsing #pragma GCC
+ option here rather than in i386.c since it will pull in various preprocessor
+ functions, and those are not present in languages like fortran without a
+ preprocessor. */
+
+void
+ix86_register_pragmas (void)
+{
+ /* Update pragma hook to allow parsing #pragma GCC option. */
+ targetm.target_option.pragma_parse = ix86_pragma_option_parse;
+
+#ifdef REGISTER_SUBTARGET_PRAGMAS
+ REGISTER_SUBTARGET_PRAGMAS ();
+#endif
+}
diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h
index 8d0772dbe8b..3ebfd3cd9a9 100644
--- a/gcc/config/i386/i386-protos.h
+++ b/gcc/config/i386/i386-protos.h
@@ -20,7 +20,7 @@ along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
/* Functions in i386.c */
-extern void override_options (void);
+extern void override_options (bool);
extern void optimization_options (int, int);
extern int ix86_can_use_return_insn_p (void);
@@ -141,6 +141,9 @@ extern int ix86_cfun_abi (void);
extern int ix86_function_abi (const_tree);
extern int ix86_function_type_abi (const_tree);
extern void ix86_call_abi_override (const_tree);
+extern tree ix86_fn_abi_va_list (tree);
+extern tree ix86_canonical_va_list_type (tree);
+extern int ix86_enum_va_list (int, const char **, tree *);
extern int ix86_reg_parm_stack_space (const_tree);
extern void ix86_split_fp_branch (enum rtx_code code, rtx, rtx,
@@ -199,6 +202,7 @@ extern int ix86_constant_alignment (tree, int);
extern tree ix86_handle_shared_attribute (tree *, tree, tree, int, bool *);
extern tree ix86_handle_selectany_attribute (tree *, tree, tree, int, bool *);
extern int x86_field_alignment (tree, int);
+extern tree ix86_valid_option_attribute_tree (tree);
#endif
extern rtx ix86_tls_get_addr (void);
@@ -209,9 +213,13 @@ extern void ix86_expand_vector_set (bool, rtx, rtx, int);
extern void ix86_expand_vector_extract (bool, rtx, rtx, int);
extern void ix86_expand_reduc_v4sf (rtx (*)(rtx, rtx, rtx), rtx, rtx);
-extern bool ix86_sse5_valid_op_p (rtx [], rtx, int, bool, int);
+extern bool ix86_sse5_valid_op_p (rtx [], rtx, int, bool, int, bool);
extern void ix86_expand_sse5_multiple_memory (rtx [], int, enum machine_mode);
+/* In i386-c.c */
+extern void ix86_target_macros (void);
+extern void ix86_register_pragmas (void);
+
/* In winnt.c */
extern void i386_pe_unique_section (tree, int);
extern void i386_pe_declare_function_type (FILE *, const char *, int);
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index a0edacaaaba..62d1b8d9bce 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -48,7 +48,7 @@ along with GCC; see the file COPYING3. If not see
#include "target-def.h"
#include "langhooks.h"
#include "cgraph.h"
-#include "tree-gimple.h"
+#include "gimple.h"
#include "dwarf2.h"
#include "df.h"
#include "tm-constrs.h"
@@ -1210,7 +1210,11 @@ const struct processor_costs *ix86_cost = &pentium_cost;
#define m_GENERIC (m_GENERIC32 | m_GENERIC64)
/* Feature tests against the various tunings. */
-unsigned int ix86_tune_features[X86_TUNE_LAST] = {
+unsigned char ix86_tune_features[X86_TUNE_LAST];
+
+/* Feature tests against the various tunings used to create ix86_tune_features
+ based on the processor mask. */
+static unsigned int initial_ix86_tune_features[X86_TUNE_LAST] = {
/* X86_TUNE_USE_LEAVE: Leave does not affect Nocona SPEC2000 results
negatively, so enabling for Generic64 seems like good code size
tradeoff. We can't enable it for 32bit generic because it does not
@@ -1443,7 +1447,11 @@ unsigned int ix86_tune_features[X86_TUNE_LAST] = {
};
/* Feature tests against the various architecture variations. */
-unsigned int ix86_arch_features[X86_ARCH_LAST] = {
+unsigned char ix86_arch_features[X86_ARCH_LAST];
+
+/* Feature tests against the various architecture variations, used to create
+ ix86_arch_features based on the processor mask. */
+static unsigned int initial_ix86_arch_features[X86_ARCH_LAST] = {
/* X86_ARCH_CMOVE: Conditional move was added for pentiumpro. */
~(m_386 | m_486 | m_PENT | m_K6),
@@ -1716,6 +1724,10 @@ unsigned int ix86_preferred_stack_boundary;
/* Values 1-5: see jump.c */
int ix86_branch_cost;
+/* Calling abi specific va_list type nodes. */
+static GTY(()) tree sysv_va_list_type_node;
+static GTY(()) tree ms_va_list_type_node;
+
/* Variables which are this size or smaller are put in the data/bss
or ldata/lbss sections. */
@@ -1769,6 +1781,26 @@ static void ix86_compute_frame_layout (struct ix86_frame *);
static bool ix86_expand_vector_init_one_nonzero (bool, enum machine_mode,
rtx, rtx, int);
+enum ix86_function_specific_strings
+{
+ IX86_FUNCTION_SPECIFIC_ARCH,
+ IX86_FUNCTION_SPECIFIC_TUNE,
+ IX86_FUNCTION_SPECIFIC_FPMATH,
+ IX86_FUNCTION_SPECIFIC_MAX
+};
+
+static char *ix86_target_string (int, int, const char *, const char *,
+ const char *, bool);
+static void ix86_debug_options (void) ATTRIBUTE_UNUSED;
+static void ix86_function_specific_save (struct cl_target_option *);
+static void ix86_function_specific_restore (struct cl_target_option *);
+static void ix86_function_specific_print (FILE *, int,
+ struct cl_target_option *);
+static bool ix86_valid_option_attribute_p (tree, tree, tree, int);
+static bool ix86_valid_option_attribute_inner_p (tree, char *[]);
+static bool ix86_can_inline_p (tree, tree);
+static void ix86_set_current_function (tree);
+
/* The svr4 ABI for the i386 says that records and unions are returned
in memory. */
@@ -1776,6 +1808,10 @@ static bool ix86_expand_vector_init_one_nonzero (bool, enum machine_mode,
#define DEFAULT_PCC_STRUCT_RETURN 1
#endif
+/* Whether -mtune= or -march= were specified */
+static int ix86_tune_defaulted;
+static int ix86_arch_specified;
+
/* Bit flags that specify the ISA we are compiling for. */
int ix86_isa_flags = TARGET_64BIT_DEFAULT | TARGET_SUBTARGET_ISA_DEFAULT;
@@ -1811,6 +1847,18 @@ static int ix86_isa_flags_explicit;
#define OPTION_MASK_ISA_SSE5_SET \
(OPTION_MASK_ISA_SSE5 | OPTION_MASK_ISA_SSE4A_SET)
+/* AES and PCLMUL need SSE2 because they use xmm registers */
+#define OPTION_MASK_ISA_AES_SET \
+ (OPTION_MASK_ISA_AES | OPTION_MASK_ISA_SSE2_SET)
+#define OPTION_MASK_ISA_PCLMUL_SET \
+ (OPTION_MASK_ISA_PCLMUL | OPTION_MASK_ISA_SSE2_SET)
+
+#define OPTION_MASK_ISA_ABM_SET \
+ (OPTION_MASK_ISA_ABM | OPTION_MASK_ISA_POPCNT)
+#define OPTION_MASK_ISA_POPCNT_SET OPTION_MASK_ISA_POPCNT
+#define OPTION_MASK_ISA_CX16_SET OPTION_MASK_ISA_CX16
+#define OPTION_MASK_ISA_SAHF_SET OPTION_MASK_ISA_SAHF
+
/* Define a set of ISAs which aren't available when a given ISA is
disabled. MMX and SSE ISAs are handled separately. */
@@ -1840,14 +1888,73 @@ static int ix86_isa_flags_explicit;
#define OPTION_MASK_ISA_SSE4A_UNSET \
(OPTION_MASK_ISA_SSE4A | OPTION_MASK_ISA_SSE5_UNSET)
-
#define OPTION_MASK_ISA_SSE5_UNSET OPTION_MASK_ISA_SSE5
+#define OPTION_MASK_ISA_AES_UNSET OPTION_MASK_ISA_AES
+#define OPTION_MASK_ISA_PCLMUL_UNSET OPTION_MASK_ISA_PCLMUL
+#define OPTION_MASK_ISA_ABM_UNSET OPTION_MASK_ISA_ABM
+#define OPTION_MASK_ISA_POPCNT_UNSET OPTION_MASK_ISA_POPCNT
+#define OPTION_MASK_ISA_CX16_UNSET OPTION_MASK_ISA_CX16
+#define OPTION_MASK_ISA_SAHF_UNSET OPTION_MASK_ISA_SAHF
/* Vectorization library interface and handlers. */
tree (*ix86_veclib_handler)(enum built_in_function, tree, tree) = NULL;
static tree ix86_veclibabi_svml (enum built_in_function, tree, tree);
static tree ix86_veclibabi_acml (enum built_in_function, tree, tree);
+/* Processor target table, indexed by processor number */
+struct ptt
+{
+ const struct processor_costs *cost; /* Processor costs */
+ const int align_loop; /* Default alignments. */
+ const int align_loop_max_skip;
+ const int align_jump;
+ const int align_jump_max_skip;
+ const int align_func;
+};
+
+static const struct ptt processor_target_table[PROCESSOR_max] =
+{
+ {&i386_cost, 4, 3, 4, 3, 4},
+ {&i486_cost, 16, 15, 16, 15, 16},
+ {&pentium_cost, 16, 7, 16, 7, 16},
+ {&pentiumpro_cost, 16, 15, 16, 10, 16},
+ {&geode_cost, 0, 0, 0, 0, 0},
+ {&k6_cost, 32, 7, 32, 7, 32},
+ {&athlon_cost, 16, 7, 16, 7, 16},
+ {&pentium4_cost, 0, 0, 0, 0, 0},
+ {&k8_cost, 16, 7, 16, 7, 16},
+ {&nocona_cost, 0, 0, 0, 0, 0},
+ {&core2_cost, 16, 10, 16, 10, 16},
+ {&generic32_cost, 16, 7, 16, 7, 16},
+ {&generic64_cost, 16, 10, 16, 10, 16},
+ {&amdfam10_cost, 32, 24, 32, 7, 32}
+};
+
+static const char *const cpu_names[TARGET_CPU_DEFAULT_max] =
+{
+ "generic",
+ "i386",
+ "i486",
+ "pentium",
+ "pentium-mmx",
+ "pentiumpro",
+ "pentium2",
+ "pentium3",
+ "pentium4",
+ "pentium-m",
+ "prescott",
+ "nocona",
+ "core2",
+ "geode",
+ "k6",
+ "k6-2",
+ "k6-3",
+ "athlon",
+ "athlon-4",
+ "k8",
+ "amdfam10"
+};
+
/* Implement TARGET_HANDLE_OPTION. */
static bool
@@ -1998,11 +2105,295 @@ ix86_handle_option (size_t code, const char *arg ATTRIBUTE_UNUSED, int value)
}
return true;
+ case OPT_mabm:
+ if (value)
+ {
+ ix86_isa_flags |= OPTION_MASK_ISA_ABM_SET;
+ ix86_isa_flags_explicit |= OPTION_MASK_ISA_ABM_SET;
+ }
+ else
+ {
+ ix86_isa_flags &= ~OPTION_MASK_ISA_ABM_UNSET;
+ ix86_isa_flags_explicit |= OPTION_MASK_ISA_ABM_UNSET;
+ }
+ return true;
+
+ case OPT_mpopcnt:
+ if (value)
+ {
+ ix86_isa_flags |= OPTION_MASK_ISA_POPCNT_SET;
+ ix86_isa_flags_explicit |= OPTION_MASK_ISA_POPCNT_SET;
+ }
+ else
+ {
+ ix86_isa_flags &= ~OPTION_MASK_ISA_POPCNT_UNSET;
+ ix86_isa_flags_explicit |= OPTION_MASK_ISA_POPCNT_UNSET;
+ }
+ return true;
+
+ case OPT_msahf:
+ if (value)
+ {
+ ix86_isa_flags |= OPTION_MASK_ISA_SAHF_SET;
+ ix86_isa_flags_explicit |= OPTION_MASK_ISA_SAHF_SET;
+ }
+ else
+ {
+ ix86_isa_flags &= ~OPTION_MASK_ISA_SAHF_UNSET;
+ ix86_isa_flags_explicit |= OPTION_MASK_ISA_SAHF_UNSET;
+ }
+ return true;
+
+ case OPT_mcx16:
+ if (value)
+ {
+ ix86_isa_flags |= OPTION_MASK_ISA_CX16_SET;
+ ix86_isa_flags_explicit |= OPTION_MASK_ISA_CX16_SET;
+ }
+ else
+ {
+ ix86_isa_flags &= ~OPTION_MASK_ISA_CX16_UNSET;
+ ix86_isa_flags_explicit |= OPTION_MASK_ISA_CX16_UNSET;
+ }
+ return true;
+
+ case OPT_maes:
+ if (value)
+ {
+ ix86_isa_flags |= OPTION_MASK_ISA_AES_SET;
+ ix86_isa_flags_explicit |= OPTION_MASK_ISA_AES_SET;
+ }
+ else
+ {
+ ix86_isa_flags &= ~OPTION_MASK_ISA_AES_UNSET;
+ ix86_isa_flags_explicit |= OPTION_MASK_ISA_AES_UNSET;
+ }
+ return true;
+
+ case OPT_mpclmul:
+ if (value)
+ {
+ ix86_isa_flags |= OPTION_MASK_ISA_PCLMUL_SET;
+ ix86_isa_flags_explicit |= OPTION_MASK_ISA_PCLMUL_SET;
+ }
+ else
+ {
+ ix86_isa_flags &= ~OPTION_MASK_ISA_PCLMUL_UNSET;
+ ix86_isa_flags_explicit |= OPTION_MASK_ISA_PCLMUL_UNSET;
+ }
+ return true;
+
default:
return true;
}
}
+
+/* Return a string the documents the current -m options. The caller is
+ responsible for freeing the string. */
+
+static char *
+ix86_target_string (int isa, int flags, const char *arch, const char *tune,
+ const char *fpmath, bool add_nl_p)
+{
+ struct ix86_target_opts
+ {
+ const char *option; /* option string */
+ int mask; /* isa mask options */
+ };
+
+ /* This table is ordered so that options like -msse5 or -msse4.2 that imply
+ preceding options while match those first. */
+ static struct ix86_target_opts isa_opts[] =
+ {
+ { "-m64", OPTION_MASK_ISA_64BIT },
+ { "-msse5", OPTION_MASK_ISA_SSE5 },
+ { "-msse4a", OPTION_MASK_ISA_SSE4A },
+ { "-msse4.2", OPTION_MASK_ISA_SSE4_2 },
+ { "-msse4.1", OPTION_MASK_ISA_SSE4_1 },
+ { "-mssse3", OPTION_MASK_ISA_SSSE3 },
+ { "-msse3", OPTION_MASK_ISA_SSE3 },
+ { "-msse2", OPTION_MASK_ISA_SSE2 },
+ { "-msse", OPTION_MASK_ISA_SSE },
+ { "-m3dnow", OPTION_MASK_ISA_3DNOW },
+ { "-m3dnowa", OPTION_MASK_ISA_3DNOW_A },
+ { "-mmmx", OPTION_MASK_ISA_MMX },
+ { "-mabm", OPTION_MASK_ISA_ABM },
+ { "-mpopcnt", OPTION_MASK_ISA_POPCNT },
+ { "-maes", OPTION_MASK_ISA_AES },
+ { "-mpclmul", OPTION_MASK_ISA_PCLMUL },
+ };
+
+ /* Flag options. */
+ static struct ix86_target_opts flag_opts[] =
+ {
+ { "-m128bit-long-double", MASK_128BIT_LONG_DOUBLE },
+ { "-m80387", MASK_80387 },
+ { "-maccumulate-outgoing-args", MASK_ACCUMULATE_OUTGOING_ARGS },
+ { "-malign-double", MASK_ALIGN_DOUBLE },
+ { "-mcld", MASK_CLD },
+ { "-mfp-ret-in-387", MASK_FLOAT_RETURNS },
+ { "-mieee-fp", MASK_IEEE_FP },
+ { "-minline-all-stringops", MASK_INLINE_ALL_STRINGOPS },
+ { "-minline-stringops-dynamically", MASK_INLINE_STRINGOPS_DYNAMICALLY },
+ { "-mms-bitfields", MASK_MS_BITFIELD_LAYOUT },
+ { "-mno-align-stringops", MASK_NO_ALIGN_STRINGOPS },
+ { "-mno-fancy-math-387", MASK_NO_FANCY_MATH_387 },
+ { "-mno-fused-madd", MASK_NO_FUSED_MADD },
+ { "-mno-push-args", MASK_NO_PUSH_ARGS },
+ { "-mno-red-zone", MASK_NO_RED_ZONE },
+ { "-momit-leaf-frame-pointer", MASK_OMIT_LEAF_FRAME_POINTER },
+ { "-mrecip", MASK_RECIP },
+ { "-mrtd", MASK_RTD },
+ { "-msseregparm", MASK_SSEREGPARM },
+ { "-mstack-arg-probe", MASK_STACK_PROBE },
+ { "-mtls-direct-seg-refs", MASK_TLS_DIRECT_SEG_REFS },
+ };
+
+ const char *opts[ (sizeof (isa_opts) / sizeof (isa_opts[0])
+ + sizeof (flag_opts) / sizeof (flag_opts[0])
+ + 6)][2];
+
+ char isa_other[40];
+ char target_other[40];
+ unsigned num = 0;
+ unsigned i, j;
+ char *ret;
+ char *ptr;
+ size_t len;
+ size_t line_len;
+ size_t sep_len;
+
+ memset (opts, '\0', sizeof (opts));
+
+ /* Add -march= option. */
+ if (arch)
+ {
+ opts[num][0] = "-march=";
+ opts[num++][1] = arch;
+ }
+
+ /* Add -mtune= option. */
+ if (tune)
+ {
+ opts[num][0] = "-mtune=";
+ opts[num++][1] = tune;
+ }
+
+ /* Pick out the options in isa options. */
+ for (i = 0; i < sizeof (isa_opts) / sizeof (isa_opts[0]); i++)
+ {
+ if ((isa & isa_opts[i].mask) != 0)
+ {
+ opts[num++][0] = isa_opts[i].option;
+ isa &= ~ isa_opts[i].mask;
+ }
+ }
+
+ if (isa && add_nl_p)
+ {
+ opts[num++][0] = isa_other;
+ sprintf (isa_other, "(other isa: 0x%x)", isa);
+ }
+
+ /* Add flag options. */
+ for (i = 0; i < sizeof (flag_opts) / sizeof (flag_opts[0]); i++)
+ {
+ if ((flags & flag_opts[i].mask) != 0)
+ {
+ opts[num++][0] = flag_opts[i].option;
+ flags &= ~ flag_opts[i].mask;
+ }
+ }
+
+ if (flags && add_nl_p)
+ {
+ opts[num++][0] = target_other;
+ sprintf (target_other, "(other flags: 0x%x)", isa);
+ }
+
+ /* Add -fpmath= option. */
+ if (fpmath)
+ {
+ opts[num][0] = "-mfpmath=";
+ opts[num++][1] = fpmath;
+ }
+
+ /* Any options? */
+ if (num == 0)
+ return NULL;
+
+ gcc_assert (num < sizeof (opts) / sizeof (opts[0]));
+
+ /* Size the string. */
+ len = 0;
+ sep_len = (add_nl_p) ? 3 : 1;
+ for (i = 0; i < num; i++)
+ {
+ len += sep_len;
+ for (j = 0; j < 2; j++)
+ if (opts[i][j])
+ len += strlen (opts[i][j]);
+ }
+
+ /* Build the string. */
+ ret = ptr = (char *) xmalloc (len);
+ line_len = 0;
+
+ for (i = 0; i < num; i++)
+ {
+ size_t len2[2];
+
+ for (j = 0; j < 2; j++)
+ len2[j] = (opts[i][j]) ? strlen (opts[i][j]) : 0;
+
+ if (i != 0)
+ {
+ *ptr++ = ' ';
+ line_len++;
+
+ if (add_nl_p && line_len + len2[0] + len2[1] > 70)
+ {
+ *ptr++ = '\\';
+ *ptr++ = '\n';
+ line_len = 0;
+ }
+ }
+
+ for (j = 0; j < 2; j++)
+ if (opts[i][j])
+ {
+ memcpy (ptr, opts[i][j], len2[j]);
+ ptr += len2[j];
+ line_len += len2[j];
+ }
+ }
+
+ *ptr = '\0';
+ gcc_assert (ret + len >= ptr);
+
+ return ret;
+}
+
+/* Function that is callable from the debugger to print the current
+ options. */
+void
+ix86_debug_options (void)
+{
+ char *opts = ix86_target_string (ix86_isa_flags, target_flags,
+ ix86_arch_string, ix86_tune_string,
+ ix86_fpmath_string, true);
+ if (opts)
+ {
+ fprintf (stderr, "%s\n\n", opts);
+ free (opts);
+ }
+ else
+ fprintf (stderr, "<no options>\n\n");
+
+ return;
+}
+
/* Sometimes certain combinations of command options do not make
sense on a particular target machine. You can define a macro
`OVERRIDE_OPTIONS' to take account of this. This macro, if
@@ -2013,68 +2404,17 @@ ix86_handle_option (size_t code, const char *arg ATTRIBUTE_UNUSED, int value)
`-O'. That is what `OPTIMIZATION_OPTIONS' is for. */
void
-override_options (void)
+override_options (bool main_args_p)
{
int i;
- int ix86_tune_defaulted = 0;
- int ix86_arch_specified = 0;
unsigned int ix86_arch_mask, ix86_tune_mask;
+ const char *prefix;
+ const char *suffix;
+ const char *sw;
/* Comes from final.c -- no real reason to change it. */
#define MAX_CODE_ALIGN 16
- static struct ptt
- {
- const struct processor_costs *cost; /* Processor costs */
- const int align_loop; /* Default alignments. */
- const int align_loop_max_skip;
- const int align_jump;
- const int align_jump_max_skip;
- const int align_func;
- }
- const processor_target_table[PROCESSOR_max] =
- {
- {&i386_cost, 4, 3, 4, 3, 4},
- {&i486_cost, 16, 15, 16, 15, 16},
- {&pentium_cost, 16, 7, 16, 7, 16},
- {&pentiumpro_cost, 16, 15, 16, 10, 16},
- {&geode_cost, 0, 0, 0, 0, 0},
- {&k6_cost, 32, 7, 32, 7, 32},
- {&athlon_cost, 16, 7, 16, 7, 16},
- {&pentium4_cost, 0, 0, 0, 0, 0},
- {&k8_cost, 16, 7, 16, 7, 16},
- {&nocona_cost, 0, 0, 0, 0, 0},
- {&core2_cost, 16, 10, 16, 10, 16},
- {&generic32_cost, 16, 7, 16, 7, 16},
- {&generic64_cost, 16, 10, 16, 10, 16},
- {&amdfam10_cost, 32, 24, 32, 7, 32}
- };
-
- static const char *const cpu_names[TARGET_CPU_DEFAULT_max] =
- {
- "generic",
- "i386",
- "i486",
- "pentium",
- "pentium-mmx",
- "pentiumpro",
- "pentium2",
- "pentium3",
- "pentium4",
- "pentium-m",
- "prescott",
- "nocona",
- "core2",
- "geode",
- "k6",
- "k6-2",
- "k6-3",
- "athlon",
- "athlon-4",
- "k8",
- "amdfam10"
- };
-
enum pta_flags
{
PTA_SSE = 1 << 0,
@@ -2193,6 +2533,21 @@ override_options (void)
int const pta_size = ARRAY_SIZE (processor_alias_table);
+ /* Set up prefix/suffix so the error messages refer to either the command
+ line argument, or the attribute(option). */
+ if (main_args_p)
+ {
+ prefix = "-m";
+ suffix = "";
+ sw = "switch";
+ }
+ else
+ {
+ prefix = "option(\"";
+ suffix = "\")";
+ sw = "attribute";
+ }
+
#ifdef SUBTARGET_OVERRIDE_OPTIONS
SUBTARGET_OVERRIDE_OPTIONS;
#endif
@@ -2242,8 +2597,15 @@ override_options (void)
else
ix86_tune_string = "generic32";
}
+ /* If this call is for setting the option attribute, allow the
+ generic32/generic64 that was previously set. */
+ else if (!main_args_p
+ && (!strcmp (ix86_tune_string, "generic32")
+ || !strcmp (ix86_tune_string, "generic64")))
+ ;
else if (!strncmp (ix86_tune_string, "generic", 7))
- error ("bad value (%s) for -mtune= switch", ix86_tune_string);
+ error ("bad value (%s) for %stune=%s %s",
+ ix86_tune_string, prefix, suffix, sw);
}
else
{
@@ -2284,11 +2646,13 @@ override_options (void)
else if (!strcmp (ix86_stringop_string, "unrolled_loop"))
stringop_alg = unrolled_loop;
else
- error ("bad value (%s) for -mstringop-strategy= switch", ix86_stringop_string);
+ error ("bad value (%s) for %sstringop-strategy=%s %s",
+ ix86_stringop_string, prefix, suffix, sw);
}
if (!strcmp (ix86_tune_string, "x86-64"))
- warning (OPT_Wdeprecated, "-mtune=x86-64 is deprecated. Use -mtune=k8 or "
- "-mtune=generic instead as appropriate.");
+ warning (OPT_Wdeprecated, "%stune=x86-64%s is deprecated. Use "
+ "%stune=k8%s or %stune=generic%s instead as appropriate.",
+ prefix, suffix, prefix, suffix, prefix, suffix);
if (!ix86_arch_string)
ix86_arch_string = TARGET_64BIT ? "x86-64" : "i386";
@@ -2296,9 +2660,11 @@ override_options (void)
ix86_arch_specified = 1;
if (!strcmp (ix86_arch_string, "generic"))
- error ("generic CPU can be used only for -mtune= switch");
+ error ("generic CPU can be used only for %stune=%s %s",
+ prefix, suffix, sw);
if (!strncmp (ix86_arch_string, "generic", 7))
- error ("bad value (%s) for -march= switch", ix86_arch_string);
+ error ("bad value (%s) for %sarch=%s %s",
+ ix86_arch_string, prefix, suffix, sw);
if (ix86_cmodel_string != 0)
{
@@ -2315,7 +2681,8 @@ override_options (void)
else if (!strcmp (ix86_cmodel_string, "kernel") && !flag_pic)
ix86_cmodel = CM_KERNEL;
else
- error ("bad value (%s) for -mcmodel= switch", ix86_cmodel_string);
+ error ("bad value (%s) for %scmodel=%s %s",
+ ix86_cmodel_string, prefix, suffix, sw);
}
else
{
@@ -2338,7 +2705,8 @@ override_options (void)
else if (!strcmp (ix86_asm_string, "att"))
ix86_asm_dialect = ASM_ATT;
else
- error ("bad value (%s) for -masm= switch", ix86_asm_string);
+ error ("bad value (%s) for %sasm=%s %s",
+ ix86_asm_string, prefix, suffix, sw);
}
if ((TARGET_64BIT == 0) != (ix86_cmodel == CM_32))
error ("code model %qs not supported in the %s bit mode",
@@ -2391,31 +2759,37 @@ override_options (void)
if (processor_alias_table[i].flags & PTA_SSE5
&& !(ix86_isa_flags_explicit & OPTION_MASK_ISA_SSE5))
ix86_isa_flags |= OPTION_MASK_ISA_SSE5;
-
- if (processor_alias_table[i].flags & PTA_ABM)
- x86_abm = true;
- if (processor_alias_table[i].flags & PTA_CX16)
- x86_cmpxchg16b = true;
- if (processor_alias_table[i].flags & (PTA_POPCNT | PTA_ABM))
- x86_popcnt = true;
+ if (processor_alias_table[i].flags & PTA_ABM
+ && !(ix86_isa_flags_explicit & OPTION_MASK_ISA_ABM))
+ ix86_isa_flags |= OPTION_MASK_ISA_ABM;
+ if (processor_alias_table[i].flags & PTA_CX16
+ && !(ix86_isa_flags_explicit & OPTION_MASK_ISA_CX16))
+ ix86_isa_flags |= OPTION_MASK_ISA_CX16;
+ if (processor_alias_table[i].flags & (PTA_POPCNT | PTA_ABM)
+ && !(ix86_isa_flags_explicit & OPTION_MASK_ISA_POPCNT))
+ ix86_isa_flags |= OPTION_MASK_ISA_POPCNT;
+ if (!(TARGET_64BIT && (processor_alias_table[i].flags & PTA_NO_SAHF))
+ && !(ix86_isa_flags_explicit & OPTION_MASK_ISA_SAHF))
+ ix86_isa_flags |= OPTION_MASK_ISA_SAHF;
+ if (processor_alias_table[i].flags & PTA_AES
+ && !(ix86_isa_flags_explicit & OPTION_MASK_ISA_AES))
+ ix86_isa_flags |= OPTION_MASK_ISA_AES;
+ if (processor_alias_table[i].flags & PTA_PCLMUL
+ && !(ix86_isa_flags_explicit & OPTION_MASK_ISA_PCLMUL))
+ ix86_isa_flags |= OPTION_MASK_ISA_PCLMUL;
if (processor_alias_table[i].flags & (PTA_PREFETCH_SSE | PTA_SSE))
x86_prefetch_sse = true;
- if (!(TARGET_64BIT && (processor_alias_table[i].flags & PTA_NO_SAHF)))
- x86_sahf = true;
- if (processor_alias_table[i].flags & PTA_AES)
- x86_aes = true;
- if (processor_alias_table[i].flags & PTA_PCLMUL)
- x86_pclmul = true;
break;
}
if (i == pta_size)
- error ("bad value (%s) for -march= switch", ix86_arch_string);
+ error ("bad value (%s) for %sarch=%s %s",
+ ix86_arch_string, prefix, suffix, sw);
ix86_arch_mask = 1u << ix86_arch;
for (i = 0; i < X86_ARCH_LAST; ++i)
- ix86_arch_features[i] &= ix86_arch_mask;
+ ix86_arch_features[i] = !!(initial_ix86_arch_features[i] & ix86_arch_mask);
for (i = 0; i < pta_size; i++)
if (! strcmp (ix86_tune_string, processor_alias_table[i].name))
@@ -2447,19 +2821,12 @@ override_options (void)
break;
}
if (i == pta_size)
- error ("bad value (%s) for -mtune= switch", ix86_tune_string);
-
- /* Enable SSE2 if AES or PCLMUL is enabled. */
- if ((x86_aes || x86_pclmul)
- && !(ix86_isa_flags_explicit & OPTION_MASK_ISA_SSE2))
- {
- ix86_isa_flags |= OPTION_MASK_ISA_SSE2_SET;
- ix86_isa_flags_explicit |= OPTION_MASK_ISA_SSE2_SET;
- }
+ error ("bad value (%s) for %stune=%s %s",
+ ix86_tune_string, prefix, suffix, sw);
ix86_tune_mask = 1u << ix86_tune;
for (i = 0; i < X86_TUNE_LAST; ++i)
- ix86_tune_features[i] &= ix86_tune_mask;
+ ix86_tune_features[i] = !!(initial_ix86_tune_features[i] & ix86_tune_mask);
if (optimize_size)
ix86_cost = &size_cost;
@@ -2473,10 +2840,11 @@ override_options (void)
if (ix86_regparm_string)
{
if (TARGET_64BIT)
- warning (0, "-mregparm is ignored in 64-bit mode");
+ warning (0, "%sregparm%s is ignored in 64-bit mode", prefix, suffix);
i = atoi (ix86_regparm_string);
if (i < 0 || i > REGPARM_MAX)
- error ("-mregparm=%d is not between 0 and %d", i, REGPARM_MAX);
+ error ("%sregparm=%d%s is not between 0 and %d",
+ prefix, i, suffix, REGPARM_MAX);
else
ix86_regparm = i;
}
@@ -2488,12 +2856,14 @@ override_options (void)
Remove this code in GCC 3.2 or later. */
if (ix86_align_loops_string)
{
- warning (0, "-malign-loops is obsolete, use -falign-loops");
+ warning (0, "%salign-loops%s is obsolete, use %salign-loops%s",
+ prefix, suffix, prefix, suffix);
if (align_loops == 0)
{
i = atoi (ix86_align_loops_string);
if (i < 0 || i > MAX_CODE_ALIGN)
- error ("-malign-loops=%d is not between 0 and %d", i, MAX_CODE_ALIGN);
+ error ("%salign-loops=%d%s is not between 0 and %d",
+ prefix, i, suffix, MAX_CODE_ALIGN);
else
align_loops = 1 << i;
}
@@ -2501,12 +2871,14 @@ override_options (void)
if (ix86_align_jumps_string)
{
- warning (0, "-malign-jumps is obsolete, use -falign-jumps");
+ warning (0, "%salign-jumps%s is obsolete, use %salign-jumps%s",
+ prefix, suffix, prefix, suffix);
if (align_jumps == 0)
{
i = atoi (ix86_align_jumps_string);
if (i < 0 || i > MAX_CODE_ALIGN)
- error ("-malign-loops=%d is not between 0 and %d", i, MAX_CODE_ALIGN);
+ error ("%salign-loops=%d%s is not between 0 and %d",
+ prefix, i, suffix, MAX_CODE_ALIGN);
else
align_jumps = 1 << i;
}
@@ -2514,12 +2886,14 @@ override_options (void)
if (ix86_align_funcs_string)
{
- warning (0, "-malign-functions is obsolete, use -falign-functions");
+ warning (0, "%salign-functions%s is obsolete, use %salign-functions%s",
+ prefix, suffix, prefix, suffix);
if (align_functions == 0)
{
i = atoi (ix86_align_funcs_string);
if (i < 0 || i > MAX_CODE_ALIGN)
- error ("-malign-loops=%d is not between 0 and %d", i, MAX_CODE_ALIGN);
+ error ("%salign-loops=%d%s is not between 0 and %d",
+ prefix, i, suffix, MAX_CODE_ALIGN);
else
align_functions = 1 << i;
}
@@ -2547,7 +2921,7 @@ override_options (void)
{
i = atoi (ix86_branch_cost_string);
if (i < 0 || i > 5)
- error ("-mbranch-cost=%d is not between 0 and 5", i);
+ error ("%sbranch-cost=%d%s is not between 0 and 5", prefix, i, suffix);
else
ix86_branch_cost = i;
}
@@ -2555,7 +2929,7 @@ override_options (void)
{
i = atoi (ix86_section_threshold_string);
if (i < 0)
- error ("-mlarge-data-threshold=%d is negative", i);
+ error ("%slarge-data-threshold=%d%s is negative", prefix, i, suffix);
else
ix86_section_threshold = i;
}
@@ -2569,8 +2943,8 @@ override_options (void)
else if (strcmp (ix86_tls_dialect_string, "sun") == 0)
ix86_tls_dialect = TLS_DIALECT_SUN;
else
- error ("bad value (%s) for -mtls-dialect= switch",
- ix86_tls_dialect_string);
+ error ("bad value (%s) for %stls-dialect=%s %s",
+ ix86_tls_dialect_string, prefix, suffix, sw);
}
if (ix87_precision_string)
@@ -2593,7 +2967,7 @@ override_options (void)
| TARGET_SUBTARGET64_ISA_DEFAULT) & ~ix86_isa_flags_explicit);
if (TARGET_RTD)
- warning (0, "-mrtd is ignored in 64bit mode");
+ warning (0, "%srtd%s is ignored in 64bit mode", prefix, suffix);
}
else
{
@@ -2639,7 +3013,7 @@ override_options (void)
/* Turn on popcnt instruction for -msse4.2 or -mabm. */
if (TARGET_SSE4_2 || TARGET_ABM)
- x86_popcnt = true;
+ ix86_isa_flags |= OPTION_MASK_ISA_POPCNT & ~ix86_isa_flags_explicit;
/* Validate -mpreferred-stack-boundary= value, or provide default.
The default of 128 bits is for Pentium III's SSE __m128. We can't
@@ -2650,8 +3024,8 @@ override_options (void)
{
i = atoi (ix86_preferred_stack_boundary_string);
if (i < (TARGET_64BIT ? 4 : 2) || i > 12)
- error ("-mpreferred-stack-boundary=%d is not between %d and 12", i,
- TARGET_64BIT ? 4 : 2);
+ error ("%spreferred-stack-boundary=%d%s is not between %d and 12",
+ prefix, i, suffix, TARGET_64BIT ? 4 : 2);
else
ix86_preferred_stack_boundary = (1 << i) * BITS_PER_UNIT;
}
@@ -2659,7 +3033,7 @@ override_options (void)
/* Accept -msseregparm only if at least SSE support is enabled. */
if (TARGET_SSEREGPARM
&& ! TARGET_SSE)
- error ("-msseregparm used without SSE enabled");
+ error ("%ssseregparm%s used without SSE enabled", prefix, suffix);
ix86_fpmath = TARGET_FPMATH_DEFAULT;
if (ix86_fpmath_string != 0)
@@ -2677,7 +3051,10 @@ override_options (void)
ix86_fpmath = FPMATH_SSE;
}
else if (! strcmp (ix86_fpmath_string, "387,sse")
- || ! strcmp (ix86_fpmath_string, "sse,387"))
+ || ! strcmp (ix86_fpmath_string, "387+sse")
+ || ! strcmp (ix86_fpmath_string, "sse,387")
+ || ! strcmp (ix86_fpmath_string, "sse+387")
+ || ! strcmp (ix86_fpmath_string, "both"))
{
if (!TARGET_SSE)
{
@@ -2693,7 +3070,8 @@ override_options (void)
ix86_fpmath = (enum fpmath_unit) (FPMATH_SSE | FPMATH_387);
}
else
- error ("bad value (%s) for -mfpmath= switch", ix86_fpmath_string);
+ error ("bad value (%s) for %sfpmath=%s %s",
+ ix86_fpmath_string, prefix, suffix, sw);
}
/* If the i387 is disabled, then do not return values in it. */
@@ -2709,7 +3087,8 @@ override_options (void)
ix86_veclib_handler = ix86_veclibabi_acml;
else
error ("unknown vectorization library ABI type (%s) for "
- "-mveclibabi= switch", ix86_veclibabi_string);
+ "%sveclibabi=%s %s", ix86_veclibabi_string,
+ prefix, suffix, sw);
}
if ((x86_accumulate_outgoing_args & ix86_tune_mask)
@@ -2728,7 +3107,8 @@ override_options (void)
{
if (target_flags_explicit & MASK_ACCUMULATE_OUTGOING_ARGS)
warning (0, "unwind tables currently require either a frame pointer "
- "or -maccumulate-outgoing-args for correctness");
+ "or %saccumulate-outgoing-args%s for correctness",
+ prefix, suffix);
target_flags |= MASK_ACCUMULATE_OUTGOING_ARGS;
}
@@ -2739,8 +3119,8 @@ override_options (void)
&& !(target_flags & MASK_ACCUMULATE_OUTGOING_ARGS))
{
if (target_flags_explicit & MASK_ACCUMULATE_OUTGOING_ARGS)
- warning (0, "stack probing requires -maccumulate-outgoing-args "
- "for correctness");
+ warning (0, "stack probing requires %saccumulate-outgoing-args%s "
+ "for correctness", prefix, suffix);
target_flags |= MASK_ACCUMULATE_OUTGOING_ARGS;
}
@@ -2758,11 +3138,6 @@ override_options (void)
*p = '\0';
}
- /* When scheduling description is not available, disable scheduler pass
- so it won't slow down the compilation and make x87 code slower. */
- if (!TARGET_SCHEDULE)
- flag_schedule_insns_after_reload = flag_schedule_insns = 0;
-
if (!PARAM_SET_P (PARAM_SIMULTANEOUS_PREFETCHES))
set_param_value ("simultaneous-prefetches",
ix86_cost->simultaneous_prefetches);
@@ -2774,9 +3149,8 @@ override_options (void)
set_param_value ("l2-cache-size", ix86_cost->l2_cache_size);
/* If using typedef char *va_list, signal that __builtin_va_start (&ap, 0)
- can be optimized to ap = __builtin_next_arg (0).
- For abi switching it should be corrected. */
- if (!TARGET_64BIT || DEFAULT_ABI == MS_ABI)
+ can be optimized to ap = __builtin_next_arg (0). */
+ if (!TARGET_64BIT)
targetm.expand_builtin_va_start = NULL;
if (TARGET_64BIT)
@@ -2805,8 +3179,500 @@ override_options (void)
if (!TARGET_64BIT)
target_flags |= MASK_CLD & ~target_flags_explicit;
#endif
+
+ /* Save the initial options in case the user does function specific options */
+ if (main_args_p)
+ target_option_default_node = target_option_current_node
+ = build_target_option_node ();
}
+/* Save the current options */
+
+static void
+ix86_function_specific_save (struct cl_target_option *ptr)
+{
+ gcc_assert (IN_RANGE (ix86_arch, 0, 255));
+ gcc_assert (IN_RANGE (ix86_tune, 0, 255));
+ gcc_assert (IN_RANGE (ix86_fpmath, 0, 255));
+ gcc_assert (IN_RANGE (ix86_branch_cost, 0, 255));
+
+ ptr->arch = ix86_arch;
+ ptr->tune = ix86_tune;
+ ptr->fpmath = ix86_fpmath;
+ ptr->branch_cost = ix86_branch_cost;
+ ptr->tune_defaulted = ix86_tune_defaulted;
+ ptr->arch_specified = ix86_arch_specified;
+ ptr->ix86_isa_flags_explicit = ix86_isa_flags_explicit;
+ ptr->target_flags_explicit = target_flags_explicit;
+}
+
+/* Restore the current options */
+
+static void
+ix86_function_specific_restore (struct cl_target_option *ptr)
+{
+ enum processor_type old_tune = ix86_tune;
+ enum processor_type old_arch = ix86_arch;
+ unsigned int ix86_arch_mask, ix86_tune_mask;
+ int i;
+
+ ix86_arch = ptr->arch;
+ ix86_tune = ptr->tune;
+ ix86_fpmath = ptr->fpmath;
+ ix86_branch_cost = ptr->branch_cost;
+ ix86_tune_defaulted = ptr->tune_defaulted;
+ ix86_arch_specified = ptr->arch_specified;
+ ix86_isa_flags_explicit = ptr->ix86_isa_flags_explicit;
+ target_flags_explicit = ptr->target_flags_explicit;
+
+ /* Recreate the arch feature tests if the arch changed */
+ if (old_arch != ix86_arch)
+ {
+ ix86_arch_mask = 1u << ix86_arch;
+ for (i = 0; i < X86_ARCH_LAST; ++i)
+ ix86_arch_features[i]
+ = !!(initial_ix86_arch_features[i] & ix86_arch_mask);
+ }
+
+ /* Recreate the tune optimization tests */
+ if (old_tune != ix86_tune)
+ {
+ ix86_tune_mask = 1u << ix86_tune;
+ for (i = 0; i < X86_TUNE_LAST; ++i)
+ ix86_tune_features[i]
+ = !!(initial_ix86_tune_features[i] & ix86_tune_mask);
+ }
+}
+
+/* Print the current options */
+
+static void
+ix86_function_specific_print (FILE *file, int indent,
+ struct cl_target_option *ptr)
+{
+ char *target_string
+ = ix86_target_string (ptr->ix86_isa_flags, ptr->target_flags,
+ NULL, NULL, NULL, false);
+
+ fprintf (file, "%*sarch = %d (%s)\n",
+ indent, "",
+ ptr->arch,
+ ((ptr->arch < TARGET_CPU_DEFAULT_max)
+ ? cpu_names[ptr->arch]
+ : "<unknown>"));
+
+ fprintf (file, "%*stune = %d (%s)\n",
+ indent, "",
+ ptr->tune,
+ ((ptr->tune < TARGET_CPU_DEFAULT_max)
+ ? cpu_names[ptr->tune]
+ : "<unknown>"));
+
+ fprintf (file, "%*sfpmath = %d%s%s\n", indent, "", ptr->fpmath,
+ (ptr->fpmath & FPMATH_387) ? ", 387" : "",
+ (ptr->fpmath & FPMATH_SSE) ? ", sse" : "");
+ fprintf (file, "%*sbranch_cost = %d\n", indent, "", ptr->branch_cost);
+
+ if (target_string)
+ {
+ fprintf (file, "%*s%s\n", indent, "", target_string);
+ free (target_string);
+ }
+}
+
+
+/* Inner function to process the attribute((option(...))), take an argument and
+ set the current options from the argument. If we have a list, recursively go
+ over the list. */
+
+static bool
+ix86_valid_option_attribute_inner_p (tree args, char *p_strings[])
+{
+ char *next_optstr;
+ bool ret = true;
+
+#define IX86_ATTR_ISA(S,O) { S, sizeof (S)-1, ix86_opt_isa, O, 0 }
+#define IX86_ATTR_STR(S,O) { S, sizeof (S)-1, ix86_opt_str, O, 0 }
+#define IX86_ATTR_YES(S,O,M) { S, sizeof (S)-1, ix86_opt_yes, O, M }
+#define IX86_ATTR_NO(S,O,M) { S, sizeof (S)-1, ix86_opt_no, O, M }
+
+ enum ix86_opt_type
+ {
+ ix86_opt_unknown,
+ ix86_opt_yes,
+ ix86_opt_no,
+ ix86_opt_str,
+ ix86_opt_isa
+ };
+
+ static const struct
+ {
+ const char *string;
+ size_t len;
+ enum ix86_opt_type type;
+ int opt;
+ int mask;
+ } attrs[] = {
+ /* isa options */
+ IX86_ATTR_ISA ("3dnow", OPT_m3dnow),
+ IX86_ATTR_ISA ("abm", OPT_mabm),
+ IX86_ATTR_ISA ("aes", OPT_maes),
+ IX86_ATTR_ISA ("mmx", OPT_mmmx),
+ IX86_ATTR_ISA ("pclmul", OPT_mpclmul),
+ IX86_ATTR_ISA ("popcnt", OPT_mpopcnt),
+ IX86_ATTR_ISA ("sse", OPT_msse),
+ IX86_ATTR_ISA ("sse2", OPT_msse2),
+ IX86_ATTR_ISA ("sse3", OPT_msse3),
+ IX86_ATTR_ISA ("sse4", OPT_msse4),
+ IX86_ATTR_ISA ("sse4.1", OPT_msse4_1),
+ IX86_ATTR_ISA ("sse4.2", OPT_msse4_2),
+ IX86_ATTR_ISA ("sse4a", OPT_msse4a),
+ IX86_ATTR_ISA ("sse5", OPT_msse5),
+ IX86_ATTR_ISA ("ssse3", OPT_mssse3),
+
+ /* string options */
+ IX86_ATTR_STR ("arch=", IX86_FUNCTION_SPECIFIC_ARCH),
+ IX86_ATTR_STR ("fpmath=", IX86_FUNCTION_SPECIFIC_FPMATH),
+ IX86_ATTR_STR ("tune=", IX86_FUNCTION_SPECIFIC_TUNE),
+
+ /* flag options */
+ IX86_ATTR_YES ("cld",
+ OPT_mcld,
+ MASK_CLD),
+
+ IX86_ATTR_NO ("fancy-math-387",
+ OPT_mfancy_math_387,
+ MASK_NO_FANCY_MATH_387),
+
+ IX86_ATTR_NO ("fused-madd",
+ OPT_mfused_madd,
+ MASK_NO_FUSED_MADD),
+
+ IX86_ATTR_YES ("ieee-fp",
+ OPT_mieee_fp,
+ MASK_IEEE_FP),
+
+ IX86_ATTR_YES ("inline-all-stringops",
+ OPT_minline_all_stringops,
+ MASK_INLINE_ALL_STRINGOPS),
+
+ IX86_ATTR_YES ("inline-stringops-dynamically",
+ OPT_minline_stringops_dynamically,
+ MASK_INLINE_STRINGOPS_DYNAMICALLY),
+
+ IX86_ATTR_NO ("align-stringops",
+ OPT_mno_align_stringops,
+ MASK_NO_ALIGN_STRINGOPS),
+
+ IX86_ATTR_YES ("recip",
+ OPT_mrecip,
+ MASK_RECIP),
+
+ };
+
+ /* If this is a list, recurse to get the options. */
+ if (TREE_CODE (args) == TREE_LIST)
+ {
+ bool ret = true;
+
+ for (; args; args = TREE_CHAIN (args))
+ if (TREE_VALUE (args)
+ && !ix86_valid_option_attribute_inner_p (TREE_VALUE (args), p_strings))
+ ret = false;
+
+ return ret;
+ }
+
+ else if (TREE_CODE (args) != STRING_CST)
+ gcc_unreachable ();
+
+ /* Handle multiple arguments separated by commas. */
+ next_optstr = ASTRDUP (TREE_STRING_POINTER (args));
+
+ while (next_optstr && *next_optstr != '\0')
+ {
+ char *p = next_optstr;
+ char *orig_p = p;
+ char *comma = strchr (next_optstr, ',');
+ const char *opt_string;
+ size_t len, opt_len;
+ int opt;
+ bool opt_set_p;
+ char ch;
+ unsigned i;
+ enum ix86_opt_type type = ix86_opt_unknown;
+ int mask = 0;
+
+ if (comma)
+ {
+ *comma = '\0';
+ len = comma - next_optstr;
+ next_optstr = comma + 1;
+ }
+ else
+ {
+ len = strlen (p);
+ next_optstr = NULL;
+ }
+
+ /* Recognize no-xxx. */
+ if (len > 3 && p[0] == 'n' && p[1] == 'o' && p[2] == '-')
+ {
+ opt_set_p = false;
+ p += 3;
+ len -= 3;
+ }
+ else
+ opt_set_p = true;
+
+ /* Find the option. */
+ ch = *p;
+ opt = N_OPTS;
+ for (i = 0; i < sizeof (attrs) / sizeof (attrs[0]); i++)
+ {
+ type = attrs[i].type;
+ opt_len = attrs[i].len;
+ if (ch == attrs[i].string[0]
+ && ((type != ix86_opt_str) ? len == opt_len : len > opt_len)
+ && memcmp (p, attrs[i].string, opt_len) == 0)
+ {
+ opt = attrs[i].opt;
+ mask = attrs[i].mask;
+ opt_string = attrs[i].string;
+ break;
+ }
+ }
+
+ /* Process the option. */
+ if (opt == N_OPTS)
+ {
+ error ("attribute(option(\"%s\")) is unknown", orig_p);
+ ret = false;
+ }
+
+ else if (type == ix86_opt_isa)
+ ix86_handle_option (opt, p, opt_set_p);
+
+ else if (type == ix86_opt_yes || type == ix86_opt_no)
+ {
+ if (type == ix86_opt_no)
+ opt_set_p = !opt_set_p;
+
+ if (opt_set_p)
+ target_flags |= mask;
+ else
+ target_flags &= ~mask;
+ }
+
+ else if (type == ix86_opt_str)
+ {
+ if (p_strings[opt])
+ {
+ error ("option(\"%s\") was already specified", opt_string);
+ ret = false;
+ }
+ else
+ p_strings[opt] = xstrdup (p + opt_len);
+ }
+
+ else
+ gcc_unreachable ();
+ }
+
+ return ret;
+}
+
+/* Return a TARGET_OPTION_NODE tree of the target options listed or NULL. */
+
+tree
+ix86_valid_option_attribute_tree (tree args)
+{
+ const char *orig_arch_string = ix86_arch_string;
+ const char *orig_tune_string = ix86_tune_string;
+ const char *orig_fpmath_string = ix86_fpmath_string;
+ int orig_tune_defaulted = ix86_tune_defaulted;
+ int orig_arch_specified = ix86_arch_specified;
+ char *option_strings[IX86_FUNCTION_SPECIFIC_MAX] = { NULL, NULL, NULL };
+ tree t = NULL_TREE;
+ int i;
+ struct cl_target_option *def
+ = TREE_TARGET_OPTION (target_option_default_node);
+
+ /* Process each of the options on the chain. */
+ if (! ix86_valid_option_attribute_inner_p (args, option_strings))
+ return NULL_TREE;
+
+ /* If the changed options are different from the default, rerun override_options,
+ and then save the options away. The string options are are attribute options,
+ and will be undone when we copy the save structure. */
+ if (ix86_isa_flags != def->ix86_isa_flags
+ || target_flags != def->target_flags
+ || option_strings[IX86_FUNCTION_SPECIFIC_ARCH]
+ || option_strings[IX86_FUNCTION_SPECIFIC_TUNE]
+ || option_strings[IX86_FUNCTION_SPECIFIC_FPMATH])
+ {
+ /* If we are using the default tune= or arch=, undo the string assigned,
+ and use the default. */
+ if (option_strings[IX86_FUNCTION_SPECIFIC_ARCH])
+ ix86_arch_string = option_strings[IX86_FUNCTION_SPECIFIC_ARCH];
+ else if (!orig_arch_specified)
+ ix86_arch_string = NULL;
+
+ if (option_strings[IX86_FUNCTION_SPECIFIC_TUNE])
+ ix86_tune_string = option_strings[IX86_FUNCTION_SPECIFIC_TUNE];
+ else if (orig_tune_defaulted)
+ ix86_tune_string = NULL;
+
+ /* If fpmath= is not set, and we now have sse2 on 32-bit, use it. */
+ if (option_strings[IX86_FUNCTION_SPECIFIC_FPMATH])
+ ix86_fpmath_string = option_strings[IX86_FUNCTION_SPECIFIC_FPMATH];
+ else if (!TARGET_64BIT && TARGET_SSE)
+ ix86_fpmath_string = "sse,387";
+
+ /* Do any overrides, such as arch=xxx, or tune=xxx support. */
+ override_options (false);
+
+ /* Save the current options unless we are validating options for
+ #pragma. */
+ t = build_target_option_node ();
+
+ ix86_arch_string = orig_arch_string;
+ ix86_tune_string = orig_tune_string;
+ ix86_fpmath_string = orig_fpmath_string;
+
+ /* Free up memory allocated to hold the strings */
+ for (i = 0; i < IX86_FUNCTION_SPECIFIC_MAX; i++)
+ if (option_strings[i])
+ free (option_strings[i]);
+ }
+
+ return t;
+}
+
+/* Hook to validate attribute((option("string"))). */
+
+static bool
+ix86_valid_option_attribute_p (tree fndecl,
+ tree ARG_UNUSED (name),
+ tree args,
+ int ARG_UNUSED (flags))
+{
+ struct cl_target_option cur_opts;
+ bool ret = true;
+ tree new_opts;
+
+ cl_target_option_save (&cur_opts);
+ new_opts = ix86_valid_option_attribute_tree (args);
+ if (!new_opts)
+ ret = false;
+
+ else if (fndecl)
+ DECL_FUNCTION_SPECIFIC_TARGET (fndecl) = new_opts;
+
+ cl_target_option_restore (&cur_opts);
+ return ret;
+}
+
+
+/* Hook to determine if one function can safely inline another. */
+
+static bool
+ix86_can_inline_p (tree caller, tree callee)
+{
+ bool ret = false;
+ tree caller_tree = DECL_FUNCTION_SPECIFIC_TARGET (caller);
+ tree callee_tree = DECL_FUNCTION_SPECIFIC_TARGET (callee);
+
+ /* If callee has no option attributes, then it is ok to inline. */
+ if (!callee_tree)
+ ret = true;
+
+ /* If caller has no option attributes, but callee does then it is not ok to
+ inline. */
+ else if (!caller_tree)
+ ret = false;
+
+ else
+ {
+ struct cl_target_option *caller_opts = TREE_TARGET_OPTION (caller_tree);
+ struct cl_target_option *callee_opts = TREE_TARGET_OPTION (callee_tree);
+
+ /* Callee's isa options should a subset of the caller's, i.e. a SSE5 function
+ can inline a SSE2 function but a SSE2 function can't inline a SSE5
+ function. */
+ if ((caller_opts->ix86_isa_flags & callee_opts->ix86_isa_flags)
+ != callee_opts->ix86_isa_flags)
+ ret = false;
+
+ /* See if we have the same non-isa options. */
+ else if (caller_opts->target_flags != callee_opts->target_flags)
+ ret = false;
+
+ /* See if arch, tune, etc. are the same. */
+ else if (caller_opts->arch != callee_opts->arch)
+ ret = false;
+
+ else if (caller_opts->tune != callee_opts->tune)
+ ret = false;
+
+ else if (caller_opts->fpmath != callee_opts->fpmath)
+ ret = false;
+
+ else if (caller_opts->branch_cost != callee_opts->branch_cost)
+ ret = false;
+
+ else
+ ret = true;
+ }
+
+ return ret;
+}
+
+
+/* Remember the last target of ix86_set_current_function. */
+static GTY(()) tree ix86_previous_fndecl;
+
+/* Establish appropriate back-end context for processing the function
+ FNDECL. The argument might be NULL to indicate processing at top
+ level, outside of any function scope. */
+static void
+ix86_set_current_function (tree fndecl)
+{
+ /* Only change the context if the function changes. This hook is called
+ several times in the course of compiling a function, and we don't want to
+ slow things down too much or call target_reinit when it isn't safe. */
+ if (fndecl && fndecl != ix86_previous_fndecl)
+ {
+ tree old_tree = (ix86_previous_fndecl
+ ? DECL_FUNCTION_SPECIFIC_TARGET (ix86_previous_fndecl)
+ : NULL_TREE);
+
+ tree new_tree = (fndecl
+ ? DECL_FUNCTION_SPECIFIC_TARGET (fndecl)
+ : NULL_TREE);
+
+ ix86_previous_fndecl = fndecl;
+ if (old_tree == new_tree)
+ ;
+
+ else if (new_tree)
+ {
+ cl_target_option_restore (TREE_TARGET_OPTION (new_tree));
+ target_reinit ();
+ }
+
+ else if (old_tree)
+ {
+ struct cl_target_option *def
+ = TREE_TARGET_OPTION (target_option_current_node);
+
+ cl_target_option_restore (def);
+ target_reinit ();
+ }
+ }
+}
+
+
/* Return true if this goes in large data/bss. */
static bool
@@ -3039,6 +3905,11 @@ optimization_options (int level, int size ATTRIBUTE_UNUSED)
flag_schedule_insns = 0;
#endif
+ /* When scheduling description is not available, disable scheduler pass
+ so it won't slow down the compilation and make x87 code slower. */
+ if (!TARGET_SCHEDULE)
+ flag_schedule_insns_after_reload = flag_schedule_insns = 0;
+
if (TARGET_MACHO)
/* The Darwin libraries never set errno, so we might as well
avoid calling them when that's the only reason we would. */
@@ -3201,7 +4072,7 @@ ix86_handle_cconv_attribute (tree *node, tree name,
if (TARGET_64BIT)
{
/* Do not warn when emulating the MS ABI. */
- if (TREE_CODE (*node) != FUNCTION_TYPE || !ix86_function_type_abi (*node))
+ if (TREE_CODE (*node) != FUNCTION_TYPE || ix86_function_type_abi (*node)!=MS_ABI)
warning (OPT_Wattributes, "%qs attribute ignored",
IDENTIFIER_POINTER (name));
*no_add_attrs = true;
@@ -3338,7 +4209,7 @@ ix86_function_regparm (const_tree type, const_tree decl)
/* Use register calling convention for local functions when possible. */
if (decl && TREE_CODE (decl) == FUNCTION_DECL
- && flag_unit_at_a_time && !profile_flag)
+ && !profile_flag)
{
/* FIXME: remove this CONST_CAST when cgraph.[ch] is constified. */
struct cgraph_local_info *i = cgraph_local_info (CONST_CAST_TREE(decl));
@@ -3425,7 +4296,7 @@ ix86_function_sseregparm (const_tree type, const_tree decl, bool warn)
/* For local functions, pass up to SSE_REGPARM_MAX SFmode
(and DFmode for SSE2) arguments in SSE registers. */
- if (decl && TARGET_SSE_MATH && flag_unit_at_a_time && !profile_flag)
+ if (decl && TARGET_SSE_MATH && !profile_flag)
{
/* FIXME: remove this CONST_CAST when cgraph.[ch] is constified. */
struct cgraph_local_info *i = cgraph_local_info (CONST_CAST_TREE(decl));
@@ -3604,9 +4475,6 @@ ix86_function_type_abi (const_tree fntype)
else
abi = lookup_attribute ("sysv_abi", TYPE_ATTRIBUTES (fntype)) ? SYSV_ABI : MS_ABI;
- if (DEFAULT_ABI == MS_ABI && abi == SYSV_ABI)
- sorry ("using sysv calling convention on target w64 is not supported");
-
return abi;
}
return DEFAULT_ABI;
@@ -5174,13 +6042,16 @@ ix86_struct_value_rtx (tree type, int incoming ATTRIBUTE_UNUSED)
/* Create the va_list data type. */
+/* Returns the calling convention specific va_list date type.
+ The argument ABI can be DEFAULT_ABI, MS_ABI, or SYSV_ABI. */
+
static tree
-ix86_build_builtin_va_list (void)
+ix86_build_builtin_va_list_abi (enum calling_abi abi)
{
tree f_gpr, f_fpr, f_ovf, f_sav, record, type_decl;
/* For i386 we use plain pointer to argument area. */
- if (!TARGET_64BIT || ix86_cfun_abi () == MS_ABI)
+ if (!TARGET_64BIT || abi == MS_ABI)
return build_pointer_type (char_type_node);
record = (*lang_hooks.types.make_type) (RECORD_TYPE);
@@ -5216,6 +6087,51 @@ ix86_build_builtin_va_list (void)
return build_array_type (record, build_index_type (size_zero_node));
}
+/* Setup the builtin va_list data type and for 64-bit the additional
+ calling convention specific va_list data types. */
+
+static tree
+ix86_build_builtin_va_list (void)
+{
+ tree ret = ix86_build_builtin_va_list_abi (DEFAULT_ABI);
+
+ /* Initialize abi specific va_list builtin types. */
+ if (TARGET_64BIT)
+ {
+ tree t;
+ if (DEFAULT_ABI == MS_ABI)
+ {
+ t = ix86_build_builtin_va_list_abi (SYSV_ABI);
+ if (TREE_CODE (t) != RECORD_TYPE)
+ t = build_variant_type_copy (t);
+ sysv_va_list_type_node = t;
+ }
+ else
+ {
+ t = ret;
+ if (TREE_CODE (t) != RECORD_TYPE)
+ t = build_variant_type_copy (t);
+ sysv_va_list_type_node = t;
+ }
+ if (DEFAULT_ABI != MS_ABI)
+ {
+ t = ix86_build_builtin_va_list_abi (MS_ABI);
+ if (TREE_CODE (t) != RECORD_TYPE)
+ t = build_variant_type_copy (t);
+ ms_va_list_type_node = t;
+ }
+ else
+ {
+ t = ret;
+ if (TREE_CODE (t) != RECORD_TYPE)
+ t = build_variant_type_copy (t);
+ ms_va_list_type_node = t;
+ }
+ }
+
+ return ret;
+}
+
/* Worker function for TARGET_SETUP_INCOMING_VARARGS. */
static void
@@ -5360,6 +6276,21 @@ ix86_setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
setup_incoming_varargs_64 (&next_cum);
}
+/* Checks if TYPE is of kind va_list char *. */
+
+static bool
+is_va_list_char_pointer (tree type)
+{
+ tree canonic;
+
+ /* For 32-bit it is always true. */
+ if (!TARGET_64BIT)
+ return true;
+ canonic = ix86_canonical_va_list_type (type);
+ return (canonic == ms_va_list_type_node
+ || (DEFAULT_ABI == MS_ABI && canonic == va_list_type_node));
+}
+
/* Implement va_start. */
static void
@@ -5371,13 +6302,13 @@ ix86_va_start (tree valist, rtx nextarg)
tree type;
/* Only 64bit target needs something special. */
- if (!TARGET_64BIT || cfun->machine->call_abi == MS_ABI)
+ if (!TARGET_64BIT || is_va_list_char_pointer (TREE_TYPE (valist)))
{
std_expand_builtin_va_start (valist, nextarg);
return;
}
- f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
+ f_gpr = TYPE_FIELDS (TREE_TYPE (sysv_va_list_type_node));
f_fpr = TREE_CHAIN (f_gpr);
f_ovf = TREE_CHAIN (f_fpr);
f_sav = TREE_CHAIN (f_ovf);
@@ -5396,8 +6327,8 @@ ix86_va_start (tree valist, rtx nextarg)
if (cfun->va_list_gpr_size)
{
type = TREE_TYPE (gpr);
- t = build2 (GIMPLE_MODIFY_STMT, type, gpr,
- build_int_cst (type, n_gpr * 8));
+ t = build2 (MODIFY_EXPR, type,
+ gpr, build_int_cst (type, n_gpr * 8));
TREE_SIDE_EFFECTS (t) = 1;
expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
}
@@ -5405,7 +6336,7 @@ ix86_va_start (tree valist, rtx nextarg)
if (cfun->va_list_fpr_size)
{
type = TREE_TYPE (fpr);
- t = build2 (GIMPLE_MODIFY_STMT, type, fpr,
+ t = build2 (MODIFY_EXPR, type, fpr,
build_int_cst (type, n_fpr * 16 + 8*X86_64_REGPARM_MAX));
TREE_SIDE_EFFECTS (t) = 1;
expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
@@ -5417,7 +6348,7 @@ ix86_va_start (tree valist, rtx nextarg)
if (words != 0)
t = build2 (POINTER_PLUS_EXPR, type, t,
size_int (words * UNITS_PER_WORD));
- t = build2 (GIMPLE_MODIFY_STMT, type, ovf, t);
+ t = build2 (MODIFY_EXPR, type, ovf, t);
TREE_SIDE_EFFECTS (t) = 1;
expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
@@ -5427,7 +6358,7 @@ ix86_va_start (tree valist, rtx nextarg)
Prologue of the function save it right above stack frame. */
type = TREE_TYPE (sav);
t = make_tree (type, frame_pointer_rtx);
- t = build2 (GIMPLE_MODIFY_STMT, type, sav, t);
+ t = build2 (MODIFY_EXPR, type, sav, t);
TREE_SIDE_EFFECTS (t) = 1;
expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
}
@@ -5436,7 +6367,8 @@ ix86_va_start (tree valist, rtx nextarg)
/* Implement va_arg. */
static tree
-ix86_gimplify_va_arg (tree valist, tree type, tree *pre_p, tree *post_p)
+ix86_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
+ gimple_seq *post_p)
{
static const int intreg[6] = { 0, 1, 2, 3, 4, 5 };
tree f_gpr, f_fpr, f_ovf, f_sav;
@@ -5448,12 +6380,13 @@ ix86_gimplify_va_arg (tree valist, tree type, tree *pre_p, tree *post_p)
int indirect_p = 0;
tree ptrtype;
enum machine_mode nat_mode;
+ int arg_boundary;
/* Only 64bit target needs something special. */
- if (!TARGET_64BIT || cfun->machine->call_abi == MS_ABI)
+ if (!TARGET_64BIT || is_va_list_char_pointer (TREE_TYPE (valist)))
return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
- f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
+ f_gpr = TYPE_FIELDS (TREE_TYPE (sysv_va_list_type_node));
f_fpr = TREE_CHAIN (f_gpr);
f_ovf = TREE_CHAIN (f_fpr);
f_sav = TREE_CHAIN (f_ovf);
@@ -5565,16 +6498,14 @@ ix86_gimplify_va_arg (tree valist, tree type, tree *pre_p, tree *post_p)
/* int_addr = gpr + sav; */
t = fold_convert (sizetype, gpr);
t = build2 (POINTER_PLUS_EXPR, ptr_type_node, sav, t);
- t = build2 (GIMPLE_MODIFY_STMT, void_type_node, int_addr, t);
- gimplify_and_add (t, pre_p);
+ gimplify_assign (int_addr, t, pre_p);
}
if (needed_sseregs)
{
/* sse_addr = fpr + sav; */
t = fold_convert (sizetype, fpr);
t = build2 (POINTER_PLUS_EXPR, ptr_type_node, sav, t);
- t = build2 (GIMPLE_MODIFY_STMT, void_type_node, sse_addr, t);
- gimplify_and_add (t, pre_p);
+ gimplify_assign (sse_addr, t, pre_p);
}
if (need_temp)
{
@@ -5583,8 +6514,7 @@ ix86_gimplify_va_arg (tree valist, tree type, tree *pre_p, tree *post_p)
/* addr = &temp; */
t = build1 (ADDR_EXPR, build_pointer_type (type), temp);
- t = build2 (GIMPLE_MODIFY_STMT, void_type_node, addr, t);
- gimplify_and_add (t, pre_p);
+ gimplify_assign (addr, t, pre_p);
for (i = 0; i < XVECLEN (container, 0); i++)
{
@@ -5617,8 +6547,7 @@ ix86_gimplify_va_arg (tree valist, tree type, tree *pre_p, tree *post_p)
size_int (INTVAL (XEXP (slot, 1))));
dest = build_va_arg_indirect_ref (dest_addr);
- t = build2 (GIMPLE_MODIFY_STMT, void_type_node, dest, src);
- gimplify_and_add (t, pre_p);
+ gimplify_assign (dest, src, pre_p);
}
}
@@ -5626,33 +6555,38 @@ ix86_gimplify_va_arg (tree valist, tree type, tree *pre_p, tree *post_p)
{
t = build2 (PLUS_EXPR, TREE_TYPE (gpr), gpr,
build_int_cst (TREE_TYPE (gpr), needed_intregs * 8));
- t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (gpr), gpr, t);
- gimplify_and_add (t, pre_p);
+ gimplify_assign (gpr, t, pre_p);
}
+
if (needed_sseregs)
{
t = build2 (PLUS_EXPR, TREE_TYPE (fpr), fpr,
build_int_cst (TREE_TYPE (fpr), needed_sseregs * 16));
- t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (fpr), fpr, t);
- gimplify_and_add (t, pre_p);
+ gimplify_assign (fpr, t, pre_p);
}
- t = build1 (GOTO_EXPR, void_type_node, lab_over);
- gimplify_and_add (t, pre_p);
+ gimple_seq_add_stmt (pre_p, gimple_build_goto (lab_over));
- t = build1 (LABEL_EXPR, void_type_node, lab_false);
- append_to_statement_list (t, pre_p);
+ gimple_seq_add_stmt (pre_p, gimple_build_label (lab_false));
}
/* ... otherwise out of the overflow area. */
+ /* When we align parameter on stack for caller, if the parameter
+ alignment is beyond PREFERRED_STACK_BOUNDARY, it will be
+ aligned at PREFERRED_STACK_BOUNDARY. We will match callee
+ here with caller. */
+ arg_boundary = FUNCTION_ARG_BOUNDARY (VOIDmode, type);
+ if ((unsigned int) arg_boundary > PREFERRED_STACK_BOUNDARY)
+ arg_boundary = PREFERRED_STACK_BOUNDARY;
+
/* Care for on-stack alignment if needed. */
- if (FUNCTION_ARG_BOUNDARY (VOIDmode, type) <= 64
+ if (arg_boundary <= 64
|| integer_zerop (TYPE_SIZE (type)))
t = ovf;
else
{
- HOST_WIDE_INT align = FUNCTION_ARG_BOUNDARY (VOIDmode, type) / 8;
+ HOST_WIDE_INT align = arg_boundary / 8;
t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (ovf), ovf,
size_int (align - 1));
t = fold_convert (sizetype, t);
@@ -5661,20 +6595,14 @@ ix86_gimplify_va_arg (tree valist, tree type, tree *pre_p, tree *post_p)
t = fold_convert (TREE_TYPE (ovf), t);
}
gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue);
-
- t2 = build2 (GIMPLE_MODIFY_STMT, void_type_node, addr, t);
- gimplify_and_add (t2, pre_p);
+ gimplify_assign (addr, t, pre_p);
t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t,
size_int (rsize * UNITS_PER_WORD));
- t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (ovf), ovf, t);
- gimplify_and_add (t, pre_p);
+ gimplify_assign (unshare_expr (ovf), t, pre_p);
if (container)
- {
- t = build1 (LABEL_EXPR, void_type_node, lab_over);
- append_to_statement_list (t, pre_p);
- }
+ gimple_seq_add_stmt (pre_p, gimple_build_label (lab_over));
ptrtype = build_pointer_type (type);
addr = fold_convert (ptrtype, addr);
@@ -8182,7 +9110,8 @@ get_dllimport_decl (tree decl)
name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
name = targetm.strip_name_encoding (name);
- prefix = name[0] == FASTCALL_PREFIX ? "*__imp_": "*__imp__";
+ prefix = name[0] == FASTCALL_PREFIX || user_label_prefix[0] == 0
+ ? "*__imp_" : "*__imp__";
namelen = strlen (name);
prefixlen = strlen (prefix);
imp_name = (char *) alloca (namelen + prefixlen + 1);
@@ -14651,10 +15580,13 @@ ix86_split_ashl (rtx *operands, rtx scratch, enum machine_mode mode)
ix86_expand_clear (scratch);
emit_insn ((mode == DImode
? gen_x86_shift_adj_1
- : gen_x86_64_shift_adj) (high[0], low[0], operands[2], scratch));
+ : gen_x86_64_shift_adj_1) (high[0], low[0], operands[2],
+ scratch));
}
else
- emit_insn (gen_x86_shift_adj_2 (high[0], low[0], operands[2]));
+ emit_insn ((mode == DImode
+ ? gen_x86_shift_adj_2
+ : gen_x86_64_shift_adj_2) (high[0], low[0], operands[2]));
}
void
@@ -14728,11 +15660,13 @@ ix86_split_ashr (rtx *operands, rtx scratch, enum machine_mode mode)
GEN_INT (single_width - 1)));
emit_insn ((mode == DImode
? gen_x86_shift_adj_1
- : gen_x86_64_shift_adj) (low[0], high[0], operands[2],
- scratch));
+ : gen_x86_64_shift_adj_1) (low[0], high[0], operands[2],
+ scratch));
}
else
- emit_insn (gen_x86_shift_adj_3 (low[0], high[0], operands[2]));
+ emit_insn ((mode == DImode
+ ? gen_x86_shift_adj_3
+ : gen_x86_64_shift_adj_3) (low[0], high[0], operands[2]));
}
}
@@ -14791,11 +15725,13 @@ ix86_split_lshr (rtx *operands, rtx scratch, enum machine_mode mode)
ix86_expand_clear (scratch);
emit_insn ((mode == DImode
? gen_x86_shift_adj_1
- : gen_x86_64_shift_adj) (low[0], high[0], operands[2],
- scratch));
+ : gen_x86_64_shift_adj_1) (low[0], high[0], operands[2],
+ scratch));
}
else
- emit_insn (gen_x86_shift_adj_2 (low[0], high[0], operands[2]));
+ emit_insn ((mode == DImode
+ ? gen_x86_shift_adj_2
+ : gen_x86_64_shift_adj_2) (low[0], high[0], operands[2]));
}
}
@@ -18050,22 +18986,29 @@ enum ix86_builtins
/* Table for the ix86 builtin decls. */
static GTY(()) tree ix86_builtins[(int) IX86_BUILTIN_MAX];
-/* Add an ix86 target builtin function with CODE, NAME and TYPE. Do so,
- * if the target_flags include one of MASK. Stores the function decl
- * in the ix86_builtins array.
- * Returns the function decl or NULL_TREE, if the builtin was not added. */
+/* Table to record which ISA options the builtin needs. */
+static int ix86_builtins_isa[(int) IX86_BUILTIN_MAX];
+
+/* Add an ix86 target builtin function with CODE, NAME and TYPE. Save the MASK
+ * of which isa_flags to use in the ix86_builtins_isa array. Stores the
+ * function decl in the ix86_builtins array. Returns the function decl or
+ * NULL_TREE, if the builtin was not added.
+ *
+ * Record all builtins, even if it isn't an instruction set in the current ISA
+ * in case the user uses function specific options for a different ISA. When
+ * the builtin is expanded, check at that time whether it is valid. */
static inline tree
def_builtin (int mask, const char *name, tree type, enum ix86_builtins code)
{
tree decl = NULL_TREE;
- if (mask & ix86_isa_flags
- && (!(mask & OPTION_MASK_ISA_64BIT) || TARGET_64BIT))
+ if (!(mask & OPTION_MASK_ISA_64BIT) || TARGET_64BIT)
{
decl = add_builtin_function (name, type, code, BUILT_IN_MD,
NULL, NULL_TREE);
ix86_builtins[(int) code] = decl;
+ ix86_builtins_isa[(int) code] = mask;
}
return decl;
@@ -19108,9 +20051,10 @@ static const struct builtin_description bdesc_multi_arg[] =
{ OPTION_MASK_ISA_SSE5, CODE_FOR_sse5_pcom_tfv2di3, "__builtin_ia32_pcomtrueuq", IX86_BUILTIN_PCOMTRUEUQ, PCOM_TRUE, (int)MULTI_ARG_2_DI_TF },
};
-/* Set up all the MMX/SSE builtins. This is not called if TARGET_MMX
- is zero. Otherwise, if TARGET_SSE is not set, only expand the MMX
- builtins. */
+/* Set up all the MMX/SSE builtins, even builtins for instructions that are not
+ in the current target ISA to allow the user to compile particular modules
+ with different target specific options that differ from the command line
+ options. */
static void
ix86_init_mmx_sse_builtins (void)
{
@@ -20049,23 +20993,15 @@ ix86_init_mmx_sse_builtins (void)
def_builtin (OPTION_MASK_ISA_SSE3, "__builtin_ia32_mwait", void_ftype_unsigned_unsigned, IX86_BUILTIN_MWAIT);
/* AES */
- if (TARGET_AES)
- {
- /* Define AES built-in functions only if AES is enabled. */
- def_builtin_const (OPTION_MASK_ISA_SSE2, "__builtin_ia32_aesenc128", v2di_ftype_v2di_v2di, IX86_BUILTIN_AESENC128);
- def_builtin_const (OPTION_MASK_ISA_SSE2, "__builtin_ia32_aesenclast128", v2di_ftype_v2di_v2di, IX86_BUILTIN_AESENCLAST128);
- def_builtin_const (OPTION_MASK_ISA_SSE2, "__builtin_ia32_aesdec128", v2di_ftype_v2di_v2di, IX86_BUILTIN_AESDEC128);
- def_builtin_const (OPTION_MASK_ISA_SSE2, "__builtin_ia32_aesdeclast128", v2di_ftype_v2di_v2di, IX86_BUILTIN_AESDECLAST128);
- def_builtin_const (OPTION_MASK_ISA_SSE2, "__builtin_ia32_aesimc128", v2di_ftype_v2di, IX86_BUILTIN_AESIMC128);
- def_builtin_const (OPTION_MASK_ISA_SSE2, "__builtin_ia32_aeskeygenassist128", v2di_ftype_v2di_int, IX86_BUILTIN_AESKEYGENASSIST128);
- }
+ def_builtin_const (OPTION_MASK_ISA_AES, "__builtin_ia32_aesenc128", v2di_ftype_v2di_v2di, IX86_BUILTIN_AESENC128);
+ def_builtin_const (OPTION_MASK_ISA_AES, "__builtin_ia32_aesenclast128", v2di_ftype_v2di_v2di, IX86_BUILTIN_AESENCLAST128);
+ def_builtin_const (OPTION_MASK_ISA_AES, "__builtin_ia32_aesdec128", v2di_ftype_v2di_v2di, IX86_BUILTIN_AESDEC128);
+ def_builtin_const (OPTION_MASK_ISA_AES, "__builtin_ia32_aesdeclast128", v2di_ftype_v2di_v2di, IX86_BUILTIN_AESDECLAST128);
+ def_builtin_const (OPTION_MASK_ISA_AES, "__builtin_ia32_aesimc128", v2di_ftype_v2di, IX86_BUILTIN_AESIMC128);
+ def_builtin_const (OPTION_MASK_ISA_AES, "__builtin_ia32_aeskeygenassist128", v2di_ftype_v2di_int, IX86_BUILTIN_AESKEYGENASSIST128);
/* PCLMUL */
- if (TARGET_PCLMUL)
- {
- /* Define PCLMUL built-in function only if PCLMUL is enabled. */
- def_builtin_const (OPTION_MASK_ISA_SSE2, "__builtin_ia32_pclmulqdq128", v2di_ftype_v2di_v2di_int, IX86_BUILTIN_PCLMULQDQ128);
- }
+ def_builtin_const (OPTION_MASK_ISA_PCLMUL, "__builtin_ia32_pclmulqdq128", v2di_ftype_v2di_v2di_int, IX86_BUILTIN_PCLMULQDQ128);
/* Access to the vec_init patterns. */
ftype = build_function_type_list (V2SI_type_node, integer_type_node,
@@ -20216,6 +21152,55 @@ ix86_init_mmx_sse_builtins (void)
}
}
+/* Internal method for ix86_init_builtins. */
+
+static void
+ix86_init_builtins_va_builtins_abi (void)
+{
+ tree ms_va_ref, sysv_va_ref;
+ tree fnvoid_va_end_ms, fnvoid_va_end_sysv;
+ tree fnvoid_va_start_ms, fnvoid_va_start_sysv;
+ tree fnvoid_va_copy_ms, fnvoid_va_copy_sysv;
+ tree fnattr_ms = NULL_TREE, fnattr_sysv = NULL_TREE;
+
+ if (!TARGET_64BIT)
+ return;
+ fnattr_ms = build_tree_list (get_identifier ("ms_abi"), NULL_TREE);
+ fnattr_sysv = build_tree_list (get_identifier ("sysv_abi"), NULL_TREE);
+ ms_va_ref = build_reference_type (ms_va_list_type_node);
+ sysv_va_ref =
+ build_pointer_type (TREE_TYPE (sysv_va_list_type_node));
+
+ fnvoid_va_end_ms =
+ build_function_type_list (void_type_node, ms_va_ref, NULL_TREE);
+ fnvoid_va_start_ms =
+ build_varargs_function_type_list (void_type_node, ms_va_ref, NULL_TREE);
+ fnvoid_va_end_sysv =
+ build_function_type_list (void_type_node, sysv_va_ref, NULL_TREE);
+ fnvoid_va_start_sysv =
+ build_varargs_function_type_list (void_type_node, sysv_va_ref,
+ NULL_TREE);
+ fnvoid_va_copy_ms =
+ build_function_type_list (void_type_node, ms_va_ref, ms_va_list_type_node,
+ NULL_TREE);
+ fnvoid_va_copy_sysv =
+ build_function_type_list (void_type_node, sysv_va_ref,
+ sysv_va_ref, NULL_TREE);
+
+ add_builtin_function ("__builtin_ms_va_start", fnvoid_va_start_ms,
+ BUILT_IN_VA_START, BUILT_IN_NORMAL, NULL, fnattr_ms);
+ add_builtin_function ("__builtin_ms_va_end", fnvoid_va_end_ms,
+ BUILT_IN_VA_END, BUILT_IN_NORMAL, NULL, fnattr_ms);
+ add_builtin_function ("__builtin_ms_va_copy", fnvoid_va_copy_ms,
+ BUILT_IN_VA_COPY, BUILT_IN_NORMAL, NULL, fnattr_ms);
+ add_builtin_function ("__builtin_sysv_va_start", fnvoid_va_start_sysv,
+ BUILT_IN_VA_START, BUILT_IN_NORMAL, NULL, fnattr_sysv);
+ add_builtin_function ("__builtin_sysv_va_end", fnvoid_va_end_sysv,
+ BUILT_IN_VA_END, BUILT_IN_NORMAL, NULL, fnattr_sysv);
+ add_builtin_function ("__builtin_sysv_va_copy", fnvoid_va_copy_sysv,
+ BUILT_IN_VA_COPY, BUILT_IN_NORMAL, NULL, fnattr_sysv);
+}
+
static void
ix86_init_builtins (void)
{
@@ -20271,8 +21256,9 @@ ix86_init_builtins (void)
ix86_builtins[(int) IX86_BUILTIN_COPYSIGNQ] = decl;
TREE_READONLY (decl) = 1;
- if (TARGET_MMX)
- ix86_init_mmx_sse_builtins ();
+ ix86_init_mmx_sse_builtins ();
+ if (TARGET_64BIT)
+ ix86_init_builtins_va_builtins_abi ();
}
/* Errors in the source file can cause expand_expr to return const0_rtx
@@ -21486,6 +22472,28 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
enum machine_mode mode0, mode1, mode2;
unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
+ /* Determine whether the builtin function is available under the current ISA.
+ Originally the builtin was not created if it wasn't applicable to the
+ current ISA based on the command line switches. With function specific
+ options, we need to check in the context of the function making the call
+ whether it is supported. */
+ if (ix86_builtins_isa[fcode]
+ && !(ix86_builtins_isa[fcode] & ix86_isa_flags))
+ {
+ char *opts = ix86_target_string (ix86_builtins_isa[fcode], 0, NULL,
+ NULL, NULL, false);
+
+ if (!opts)
+ error ("%qE needs unknown isa option", fndecl);
+ else
+ {
+ gcc_assert (opts != NULL);
+ error ("%qE needs isa option %s", fndecl, opts);
+ free (opts);
+ }
+ return const0_rtx;
+ }
+
switch (fcode)
{
case IX86_BUILTIN_MASKMOVQ:
@@ -23097,6 +24105,54 @@ x86_order_regs_for_local_alloc (void)
reg_alloc_order [pos++] = 0;
}
+/* Handle a "ms_abi" or "sysv" attribute; arguments as in
+ struct attribute_spec.handler. */
+static tree
+ix86_handle_abi_attribute (tree *node, tree name,
+ tree args ATTRIBUTE_UNUSED,
+ int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
+{
+ if (TREE_CODE (*node) != FUNCTION_TYPE
+ && TREE_CODE (*node) != METHOD_TYPE
+ && TREE_CODE (*node) != FIELD_DECL
+ && TREE_CODE (*node) != TYPE_DECL)
+ {
+ warning (OPT_Wattributes, "%qs attribute only applies to functions",
+ IDENTIFIER_POINTER (name));
+ *no_add_attrs = true;
+ return NULL_TREE;
+ }
+ if (!TARGET_64BIT)
+ {
+ warning (OPT_Wattributes, "%qs attribute only available for 64-bit",
+ IDENTIFIER_POINTER (name));
+ *no_add_attrs = true;
+ return NULL_TREE;
+ }
+
+ /* Can combine regparm with all attributes but fastcall. */
+ if (is_attribute_p ("ms_abi", name))
+ {
+ if (lookup_attribute ("sysv_abi", TYPE_ATTRIBUTES (*node)))
+ {
+ error ("ms_abi and sysv_abi attributes are not compatible");
+ }
+
+ return NULL_TREE;
+ }
+ else if (is_attribute_p ("sysv_abi", name))
+ {
+ if (lookup_attribute ("ms_abi", TYPE_ATTRIBUTES (*node)))
+ {
+ error ("ms_abi and sysv_abi attributes are not compatible");
+ }
+
+ return NULL_TREE;
+ }
+
+ return NULL_TREE;
+}
+
/* Handle a "ms_struct" or "gcc_struct" attribute; arguments as in
struct attribute_spec.handler. */
static tree
@@ -25691,11 +26747,12 @@ ix86_expand_round (rtx operand0, rtx operand1)
OPERANDS is the array of operands.
NUM is the number of operands.
USES_OC0 is true if the instruction uses OC0 and provides 4 variants.
- NUM_MEMORY is the maximum number of memory operands to accept. */
+ NUM_MEMORY is the maximum number of memory operands to accept.
+ when COMMUTATIVE is set, operand 1 and 2 can be swapped. */
bool
ix86_sse5_valid_op_p (rtx operands[], rtx insn ATTRIBUTE_UNUSED, int num,
- bool uses_oc0, int num_memory)
+ bool uses_oc0, int num_memory, bool commutative)
{
int mem_mask;
int mem_count;
@@ -25779,6 +26836,8 @@ ix86_sse5_valid_op_p (rtx operands[], rtx insn ATTRIBUTE_UNUSED, int num,
/* format, example pmacsdd:
xmm1, xmm2, xmm3/mem, xmm1 */
+ if (commutative)
+ return (mem_mask == (1 << 2) || mem_mask == (1 << 1));
else
return (mem_mask == (1 << 2));
}
@@ -25813,6 +26872,8 @@ ix86_sse5_valid_op_p (rtx operands[], rtx insn ATTRIBUTE_UNUSED, int num,
For the integer multiply/add instructions be more restrictive and
require operands[2] and operands[3] to be the memory operands. */
+ if (commutative)
+ return (mem_mask == ((1 << 1) | (1 << 3)) || ((1 << 2) | (1 << 3)));
else
return (mem_mask == ((1 << 2) | (1 << 3)));
}
@@ -25906,6 +26967,10 @@ static const struct attribute_spec ix86_attribute_table[] =
#ifdef SUBTARGET_ATTRIBUTE_TABLE
SUBTARGET_ATTRIBUTE_TABLE,
#endif
+ /* ms_abi and sysv_abi calling convention function attributes. */
+ { "ms_abi", 0, 0, false, true, true, ix86_handle_abi_attribute },
+ { "sysv_abi", 0, 0, false, true, true, ix86_handle_abi_attribute },
+ /* End element. */
{ NULL, 0, 0, false, false, false, NULL }
};
@@ -25933,6 +26998,128 @@ x86_builtin_vectorization_cost (bool runtime_test)
return 0;
}
+/* This function returns the calling abi specific va_list type node.
+ It returns the FNDECL specific va_list type. */
+
+tree
+ix86_fn_abi_va_list (tree fndecl)
+{
+ int abi;
+
+ if (!TARGET_64BIT)
+ return va_list_type_node;
+ gcc_assert (fndecl != NULL_TREE);
+ abi = ix86_function_abi ((const_tree) fndecl);
+
+ if (abi == MS_ABI)
+ return ms_va_list_type_node;
+ else
+ return sysv_va_list_type_node;
+}
+
+/* Returns the canonical va_list type specified by TYPE. If there
+ is no valid TYPE provided, it return NULL_TREE. */
+
+tree
+ix86_canonical_va_list_type (tree type)
+{
+ tree wtype, htype;
+
+ /* Resolve references and pointers to va_list type. */
+ if (INDIRECT_REF_P (type))
+ type = TREE_TYPE (type);
+ else if (POINTER_TYPE_P (type) && POINTER_TYPE_P (TREE_TYPE(type)))
+ type = TREE_TYPE (type);
+
+ if (TARGET_64BIT)
+ {
+ wtype = va_list_type_node;
+ gcc_assert (wtype != NULL_TREE);
+ htype = type;
+ if (TREE_CODE (wtype) == ARRAY_TYPE)
+ {
+ /* If va_list is an array type, the argument may have decayed
+ to a pointer type, e.g. by being passed to another function.
+ In that case, unwrap both types so that we can compare the
+ underlying records. */
+ if (TREE_CODE (htype) == ARRAY_TYPE
+ || POINTER_TYPE_P (htype))
+ {
+ wtype = TREE_TYPE (wtype);
+ htype = TREE_TYPE (htype);
+ }
+ }
+ if (TYPE_MAIN_VARIANT (wtype) == TYPE_MAIN_VARIANT (htype))
+ return va_list_type_node;
+ wtype = sysv_va_list_type_node;
+ gcc_assert (wtype != NULL_TREE);
+ htype = type;
+ if (TREE_CODE (wtype) == ARRAY_TYPE)
+ {
+ /* If va_list is an array type, the argument may have decayed
+ to a pointer type, e.g. by being passed to another function.
+ In that case, unwrap both types so that we can compare the
+ underlying records. */
+ if (TREE_CODE (htype) == ARRAY_TYPE
+ || POINTER_TYPE_P (htype))
+ {
+ wtype = TREE_TYPE (wtype);
+ htype = TREE_TYPE (htype);
+ }
+ }
+ if (TYPE_MAIN_VARIANT (wtype) == TYPE_MAIN_VARIANT (htype))
+ return sysv_va_list_type_node;
+ wtype = ms_va_list_type_node;
+ gcc_assert (wtype != NULL_TREE);
+ htype = type;
+ if (TREE_CODE (wtype) == ARRAY_TYPE)
+ {
+ /* If va_list is an array type, the argument may have decayed
+ to a pointer type, e.g. by being passed to another function.
+ In that case, unwrap both types so that we can compare the
+ underlying records. */
+ if (TREE_CODE (htype) == ARRAY_TYPE
+ || POINTER_TYPE_P (htype))
+ {
+ wtype = TREE_TYPE (wtype);
+ htype = TREE_TYPE (htype);
+ }
+ }
+ if (TYPE_MAIN_VARIANT (wtype) == TYPE_MAIN_VARIANT (htype))
+ return ms_va_list_type_node;
+ return NULL_TREE;
+ }
+ return std_canonical_va_list_type (type);
+}
+
+/* Iterate through the target-specific builtin types for va_list.
+ IDX denotes the iterator, *PTREE is set to the result type of
+ the va_list builtin, and *PNAME to its internal type.
+ Returns zero if there is no element for this index, otherwise
+ IDX should be increased upon the next call.
+ Note, do not iterate a base builtin's name like __builtin_va_list.
+ Used from c_common_nodes_and_builtins. */
+
+int
+ix86_enum_va_list (int idx, const char **pname, tree *ptree)
+{
+ if (!TARGET_64BIT)
+ return 0;
+ switch (idx) {
+ case 0:
+ *ptree = ms_va_list_type_node;
+ *pname = "__builtin_ms_va_list";
+ break;
+ case 1:
+ *ptree = sysv_va_list_type_node;
+ *pname = "__builtin_sysv_va_list";
+ break;
+ default:
+ return 0;
+ }
+ return 1;
+}
+
/* Initialize the GCC target structure. */
#undef TARGET_RETURN_IN_MEMORY
#define TARGET_RETURN_IN_MEMORY ix86_return_in_memory
@@ -26061,6 +27248,12 @@ x86_builtin_vectorization_cost (bool runtime_test)
#undef TARGET_BUILD_BUILTIN_VA_LIST
#define TARGET_BUILD_BUILTIN_VA_LIST ix86_build_builtin_va_list
+#undef TARGET_FN_ABI_VA_LIST
+#define TARGET_FN_ABI_VA_LIST ix86_fn_abi_va_list
+
+#undef TARGET_CANONICAL_VA_LIST_TYPE
+#define TARGET_CANONICAL_VA_LIST_TYPE ix86_canonical_va_list_type
+
#undef TARGET_EXPAND_BUILTIN_VA_START
#define TARGET_EXPAND_BUILTIN_VA_START ix86_va_start
@@ -26121,6 +27314,30 @@ x86_builtin_vectorization_cost (bool runtime_test)
#undef TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST
#define TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST x86_builtin_vectorization_cost
+#undef TARGET_SET_CURRENT_FUNCTION
+#define TARGET_SET_CURRENT_FUNCTION ix86_set_current_function
+
+#undef TARGET_OPTION_VALID_ATTRIBUTE_P
+#define TARGET_OPTION_VALID_ATTRIBUTE_P ix86_valid_option_attribute_p
+
+#undef TARGET_OPTION_SAVE
+#define TARGET_OPTION_SAVE ix86_function_specific_save
+
+#undef TARGET_OPTION_RESTORE
+#define TARGET_OPTION_RESTORE ix86_function_specific_restore
+
+#undef TARGET_OPTION_PRINT
+#define TARGET_OPTION_PRINT ix86_function_specific_print
+
+#undef TARGET_OPTION_CAN_INLINE_P
+#define TARGET_OPTION_CAN_INLINE_P ix86_can_inline_p
+
+#undef TARGET_OPTION_COLD_ATTRIBUTE_SETS_OPTIMIZATION
+#define TARGET_OPTION_COLD_ATTRIBUTE_SETS_OPTIMIZATION true
+
+#undef TARGET_OPTION_HOT_ATTRIBUTE_SETS_OPTIMIZATION
+#define TARGET_OPTION_HOT_ATTRIBUTE_SETS_OPTIMIZATION true
+
struct gcc_target targetm = TARGET_INITIALIZER;
#include "gt-i386.h"
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index 3c135203369..528a2336dcb 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -49,6 +49,13 @@ along with GCC; see the file COPYING3. If not see
#define TARGET_SSE4A OPTION_ISA_SSE4A
#define TARGET_SSE5 OPTION_ISA_SSE5
#define TARGET_ROUND OPTION_ISA_ROUND
+#define TARGET_ABM OPTION_ISA_ABM
+#define TARGET_POPCNT OPTION_ISA_POPCNT
+#define TARGET_SAHF OPTION_ISA_SAHF
+#define TARGET_AES OPTION_ISA_AES
+#define TARGET_PCLMUL OPTION_ISA_PCLMUL
+#define TARGET_CMPXCHG16B OPTION_ISA_CX16
+
/* SSE5 and SSE4.1 define the same round instructions */
#define OPTION_MASK_ISA_ROUND (OPTION_MASK_ISA_SSE4_1 | OPTION_MASK_ISA_SSE5)
@@ -286,7 +293,7 @@ enum ix86_tune_indices {
X86_TUNE_LAST
};
-extern unsigned int ix86_tune_features[X86_TUNE_LAST];
+extern unsigned char ix86_tune_features[X86_TUNE_LAST];
#define TARGET_USE_LEAVE ix86_tune_features[X86_TUNE_USE_LEAVE]
#define TARGET_PUSH_MEMORY ix86_tune_features[X86_TUNE_PUSH_MEMORY]
@@ -380,7 +387,7 @@ enum ix86_arch_indices {
X86_ARCH_LAST
};
-extern unsigned int ix86_arch_features[X86_ARCH_LAST];
+extern unsigned char ix86_arch_features[X86_ARCH_LAST];
#define TARGET_CMOVE ix86_arch_features[X86_ARCH_CMOVE]
#define TARGET_CMPXCHG ix86_arch_features[X86_ARCH_CMPXCHG]
@@ -392,15 +399,7 @@ extern unsigned int ix86_arch_features[X86_ARCH_LAST];
extern int x86_prefetch_sse;
-#define TARGET_ABM x86_abm
-#define TARGET_CMPXCHG16B x86_cmpxchg16b
-#define TARGET_POPCNT x86_popcnt
#define TARGET_PREFETCH_SSE x86_prefetch_sse
-#define TARGET_SAHF x86_sahf
-#define TARGET_RECIP x86_recip
-#define TARGET_FUSED_MADD x86_fused_muladd
-#define TARGET_AES (TARGET_SSE2 && x86_aes)
-#define TARGET_PCLMUL (TARGET_SSE2 && x86_pclmul)
#define ASSEMBLER_DIALECT (ix86_asm_dialect)
@@ -453,7 +452,7 @@ extern tree x86_mfence;
#define TARGET_64BIT_MS_ABI (TARGET_64BIT && ix86_cfun_abi () == MS_ABI)
/* Available call abi. */
-enum
+enum calling_abi
{
SYSV_ABI = 0,
MS_ABI = 1
@@ -475,7 +474,7 @@ enum
Don't use this macro to turn on various extra optimizations for
`-O'. That is what `OPTIMIZATION_OPTIONS' is for. */
-#define OVERRIDE_OPTIONS override_options ()
+#define OVERRIDE_OPTIONS override_options (true)
/* Define this to change the optimizations performed by default. */
#define OPTIMIZATION_OPTIONS(LEVEL, SIZE) \
@@ -537,196 +536,10 @@ extern const char *host_detect_local_cpu (int argc, const char **argv);
#endif
/* Target CPU builtins. */
-#define TARGET_CPU_CPP_BUILTINS() \
- do \
- { \
- size_t arch_len = strlen (ix86_arch_string); \
- size_t tune_len = strlen (ix86_tune_string); \
- int last_arch_char = ix86_arch_string[arch_len - 1]; \
- int last_tune_char = ix86_tune_string[tune_len - 1]; \
- \
- if (TARGET_64BIT) \
- { \
- builtin_assert ("cpu=x86_64"); \
- builtin_assert ("machine=x86_64"); \
- builtin_define ("__amd64"); \
- builtin_define ("__amd64__"); \
- builtin_define ("__x86_64"); \
- builtin_define ("__x86_64__"); \
- } \
- else \
- { \
- builtin_assert ("cpu=i386"); \
- builtin_assert ("machine=i386"); \
- builtin_define_std ("i386"); \
- } \
- \
- /* Built-ins based on -march=. */ \
- switch (ix86_arch) \
- { \
- case PROCESSOR_I386: \
- break; \
- case PROCESSOR_I486: \
- builtin_define ("__i486"); \
- builtin_define ("__i486__"); \
- break; \
- case PROCESSOR_PENTIUM: \
- builtin_define ("__i586"); \
- builtin_define ("__i586__"); \
- builtin_define ("__pentium"); \
- builtin_define ("__pentium__"); \
- if (last_arch_char == 'x') \
- builtin_define ("__pentium_mmx__"); \
- break; \
- case PROCESSOR_PENTIUMPRO: \
- builtin_define ("__i686"); \
- builtin_define ("__i686__"); \
- builtin_define ("__pentiumpro"); \
- builtin_define ("__pentiumpro__"); \
- break; \
- case PROCESSOR_GEODE: \
- builtin_define ("__geode"); \
- builtin_define ("__geode__"); \
- break; \
- case PROCESSOR_K6: \
- builtin_define ("__k6"); \
- builtin_define ("__k6__"); \
- if (last_arch_char == '2') \
- builtin_define ("__k6_2__"); \
- else if (last_arch_char == '3') \
- builtin_define ("__k6_3__"); \
- break; \
- case PROCESSOR_ATHLON: \
- builtin_define ("__athlon"); \
- builtin_define ("__athlon__"); \
- /* Only plain "athlon" lacks SSE. */ \
- if (last_arch_char != 'n') \
- builtin_define ("__athlon_sse__"); \
- break; \
- case PROCESSOR_K8: \
- builtin_define ("__k8"); \
- builtin_define ("__k8__"); \
- break; \
- case PROCESSOR_AMDFAM10: \
- builtin_define ("__amdfam10"); \
- builtin_define ("__amdfam10__"); \
- break; \
- case PROCESSOR_PENTIUM4: \
- builtin_define ("__pentium4"); \
- builtin_define ("__pentium4__"); \
- break; \
- case PROCESSOR_NOCONA: \
- builtin_define ("__nocona"); \
- builtin_define ("__nocona__"); \
- break; \
- case PROCESSOR_CORE2: \
- builtin_define ("__core2"); \
- builtin_define ("__core2__"); \
- break; \
- case PROCESSOR_GENERIC32: \
- case PROCESSOR_GENERIC64: \
- case PROCESSOR_max: \
- gcc_unreachable (); \
- } \
- \
- /* Built-ins based on -mtune=. */ \
- switch (ix86_tune) \
- { \
- case PROCESSOR_I386: \
- builtin_define ("__tune_i386__"); \
- break; \
- case PROCESSOR_I486: \
- builtin_define ("__tune_i486__"); \
- break; \
- case PROCESSOR_PENTIUM: \
- builtin_define ("__tune_i586__"); \
- builtin_define ("__tune_pentium__"); \
- if (last_tune_char == 'x') \
- builtin_define ("__tune_pentium_mmx__"); \
- break; \
- case PROCESSOR_PENTIUMPRO: \
- builtin_define ("__tune_i686__"); \
- builtin_define ("__tune_pentiumpro__"); \
- switch (last_tune_char) \
- { \
- case '3': \
- builtin_define ("__tune_pentium3__"); \
- /* FALLTHRU */ \
- case '2': \
- builtin_define ("__tune_pentium2__"); \
- break; \
- } \
- break; \
- case PROCESSOR_GEODE: \
- builtin_define ("__tune_geode__"); \
- break; \
- case PROCESSOR_K6: \
- builtin_define ("__tune_k6__"); \
- if (last_tune_char == '2') \
- builtin_define ("__tune_k6_2__"); \
- else if (last_tune_char == '3') \
- builtin_define ("__tune_k6_3__"); \
- break; \
- case PROCESSOR_ATHLON: \
- builtin_define ("__tune_athlon__"); \
- /* Only plain "athlon" lacks SSE. */ \
- if (last_tune_char != 'n') \
- builtin_define ("__tune_athlon_sse__"); \
- break; \
- case PROCESSOR_K8: \
- builtin_define ("__tune_k8__"); \
- break; \
- case PROCESSOR_AMDFAM10: \
- builtin_define ("__tune_amdfam10__"); \
- break; \
- case PROCESSOR_PENTIUM4: \
- builtin_define ("__tune_pentium4__"); \
- break; \
- case PROCESSOR_NOCONA: \
- builtin_define ("__tune_nocona__"); \
- break; \
- case PROCESSOR_CORE2: \
- builtin_define ("__tune_core2__"); \
- break; \
- case PROCESSOR_GENERIC32: \
- case PROCESSOR_GENERIC64: \
- break; \
- case PROCESSOR_max: \
- gcc_unreachable (); \
- } \
- \
- if (TARGET_MMX) \
- builtin_define ("__MMX__"); \
- if (TARGET_3DNOW) \
- builtin_define ("__3dNOW__"); \
- if (TARGET_3DNOW_A) \
- builtin_define ("__3dNOW_A__"); \
- if (TARGET_SSE) \
- builtin_define ("__SSE__"); \
- if (TARGET_SSE2) \
- builtin_define ("__SSE2__"); \
- if (TARGET_SSE3) \
- builtin_define ("__SSE3__"); \
- if (TARGET_SSSE3) \
- builtin_define ("__SSSE3__"); \
- if (TARGET_SSE4_1) \
- builtin_define ("__SSE4_1__"); \
- if (TARGET_SSE4_2) \
- builtin_define ("__SSE4_2__"); \
- if (TARGET_AES) \
- builtin_define ("__AES__"); \
- if (TARGET_PCLMUL) \
- builtin_define ("__PCLMUL__"); \
- if (TARGET_SSE4A) \
- builtin_define ("__SSE4A__"); \
- if (TARGET_SSE5) \
- builtin_define ("__SSE5__"); \
- if (TARGET_SSE_MATH && TARGET_SSE) \
- builtin_define ("__SSE_MATH__"); \
- if (TARGET_SSE_MATH && TARGET_SSE2) \
- builtin_define ("__SSE2_MATH__"); \
- } \
- while (0)
+#define TARGET_CPU_CPP_BUILTINS() ix86_target_macros ()
+
+/* Target Pragmas. */
+#define REGISTER_TARGET_PRAGMAS() ix86_register_pragmas ()
enum target_cpu_default
{
@@ -2569,6 +2382,11 @@ struct machine_function GTY(())
#undef TARG_COND_BRANCH_COST
#define TARG_COND_BRANCH_COST ix86_cost->branch_cost
+/* Enum through the target specific extra va_list types. Please, do not
+ iterate the base va_list type name. */
+#define TARGET_ENUM_VA_LIST(IDX, PNAME, PTYPE) \
+ (!TARGET_64BIT ? 0 : ix86_enum_va_list (IDX, PNAME, PTYPE))
+
/* Cost of any scalar operation, excluding load and store. */
#undef TARG_SCALAR_STMT_COST
#define TARG_SCALAR_STMT_COST ix86_cost->scalar_stmt_cost
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 6c06184f879..e7a9827c5b9 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -10917,7 +10917,7 @@
(set_attr "athlon_decode" "vector")
(set_attr "amdfam10_decode" "vector")])
-(define_expand "x86_64_shift_adj"
+(define_expand "x86_64_shift_adj_1"
[(set (reg:CCZ FLAGS_REG)
(compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
(const_int 64))
@@ -10933,6 +10933,34 @@
"TARGET_64BIT"
"")
+(define_expand "x86_64_shift_adj_2"
+ [(use (match_operand:DI 0 "register_operand" ""))
+ (use (match_operand:DI 1 "register_operand" ""))
+ (use (match_operand:QI 2 "register_operand" ""))]
+ "TARGET_64BIT"
+{
+ rtx label = gen_label_rtx ();
+ rtx tmp;
+
+ emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
+
+ tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
+ tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
+ tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
+ gen_rtx_LABEL_REF (VOIDmode, label),
+ pc_rtx);
+ tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
+ JUMP_LABEL (tmp) = label;
+
+ emit_move_insn (operands[0], operands[1]);
+ ix86_expand_clear (operands[1]);
+
+ emit_label (label);
+ LABEL_NUSES (label) = 1;
+
+ DONE;
+})
+
(define_expand "ashldi3"
[(set (match_operand:DI 0 "shiftdi_operand" "")
(ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
@@ -11880,7 +11908,35 @@
""
"ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
-(define_insn "*ashrdi3_63_rex64"
+(define_expand "x86_64_shift_adj_3"
+ [(use (match_operand:DI 0 "register_operand" ""))
+ (use (match_operand:DI 1 "register_operand" ""))
+ (use (match_operand:QI 2 "register_operand" ""))]
+ ""
+{
+ rtx label = gen_label_rtx ();
+ rtx tmp;
+
+ emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
+
+ tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
+ tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
+ tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
+ gen_rtx_LABEL_REF (VOIDmode, label),
+ pc_rtx);
+ tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
+ JUMP_LABEL (tmp) = label;
+
+ emit_move_insn (operands[0], operands[1]);
+ emit_insn (gen_ashrdi3_63_rex64 (operands[1], operands[1], GEN_INT (63)));
+
+ emit_label (label);
+ LABEL_NUSES (label) = 1;
+
+ DONE;
+})
+
+(define_insn "ashrdi3_63_rex64"
[(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
(ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
(match_operand:DI 2 "const_int_operand" "i,i")))
@@ -19508,7 +19564,7 @@
(match_operand:MODEF 1 "register_operand" "x,0")
(match_operand:MODEF 2 "register_operand" "0,x")
(match_operand:MODEF 3 "register_operand" "x,x")))]
- "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1)"
+ "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, false)"
"pcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
[(set_attr "type" "sse4arg")])
diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt
index 75c94ba771e..d5c0978dde5 100644
--- a/gcc/config/i386/i386.opt
+++ b/gcc/config/i386/i386.opt
@@ -18,24 +18,58 @@
; along with GCC; see the file COPYING3. If not see
; <http://www.gnu.org/licenses/>.
+;; Definitions to add to the cl_target_option structure
+;; -march= processor
+TargetSave
+unsigned char arch
+
+;; -mtune= processor
+TargetSave
+unsigned char tune
+
+;; -mfpath=
+TargetSave
+unsigned char fpmath
+
+;; branch cost
+TargetSave
+unsigned char branch_cost
+
+;; which flags were passed by the user
+TargetSave
+int ix86_isa_flags_explicit
+
+;; which flags were passed by the user
+TargetSave
+int target_flags_explicit
+
+;; whether -mtune was not specified
+TargetSave
+unsigned char tune_defaulted
+
+;; whether -march was specified
+TargetSave
+unsigned char arch_specified
+
+;; x86 options
m128bit-long-double
-Target RejectNegative Report Mask(128BIT_LONG_DOUBLE)
+Target RejectNegative Report Mask(128BIT_LONG_DOUBLE) Save
sizeof(long double) is 16
m80387
-Target Report Mask(80387)
+Target Report Mask(80387) Save
Use hardware fp
m96bit-long-double
-Target RejectNegative Report InverseMask(128BIT_LONG_DOUBLE)
+Target RejectNegative Report InverseMask(128BIT_LONG_DOUBLE) Save
sizeof(long double) is 12
maccumulate-outgoing-args
-Target Report Mask(ACCUMULATE_OUTGOING_ARGS)
+Target Report Mask(ACCUMULATE_OUTGOING_ARGS) Save
Reserve space for outgoing arguments in the function prologue
malign-double
-Target Report Mask(ALIGN_DOUBLE)
+Target Report Mask(ALIGN_DOUBLE) Save
Align some doubles on dword boundary
malign-functions=
@@ -51,7 +85,7 @@ Target RejectNegative Joined Var(ix86_align_loops_string)
Loop code aligned to this power of 2
malign-stringops
-Target RejectNegative Report InverseMask(NO_ALIGN_STRINGOPS, ALIGN_STRINGOPS)
+Target RejectNegative Report InverseMask(NO_ALIGN_STRINGOPS, ALIGN_STRINGOPS) Save
Align destination of the string operations
march=
@@ -75,11 +109,11 @@ Target RejectNegative Joined Var(ix86_cmodel_string)
Use given x86-64 code model
mfancy-math-387
-Target RejectNegative Report InverseMask(NO_FANCY_MATH_387, USE_FANCY_MATH_387)
+Target RejectNegative Report InverseMask(NO_FANCY_MATH_387, USE_FANCY_MATH_387) Save
Generate sin, cos, sqrt for FPU
mfp-ret-in-387
-Target Report Mask(FLOAT_RETURNS)
+Target Report Mask(FLOAT_RETURNS) Save
Return values of functions in FPU registers
mfpmath=
@@ -87,19 +121,19 @@ Target RejectNegative Joined Var(ix86_fpmath_string)
Generate floating point mathematics using given instruction set
mhard-float
-Target RejectNegative Mask(80387) MaskExists
+Target RejectNegative Mask(80387) MaskExists Save
Use hardware fp
mieee-fp
-Target Report Mask(IEEE_FP)
+Target Report Mask(IEEE_FP) Save
Use IEEE math for fp comparisons
minline-all-stringops
-Target Report Mask(INLINE_ALL_STRINGOPS)
+Target Report Mask(INLINE_ALL_STRINGOPS) Save
Inline all known string operations
minline-stringops-dynamically
-Target Report Mask(INLINE_STRINGOPS_DYNAMICALLY)
+Target Report Mask(INLINE_STRINGOPS_DYNAMICALLY) Save
Inline memset/memcpy string operations, but perform inline version only for small blocks
mintel-syntax
@@ -107,23 +141,23 @@ Target Undocumented
;; Deprecated
mms-bitfields
-Target Report Mask(MS_BITFIELD_LAYOUT)
+Target Report Mask(MS_BITFIELD_LAYOUT) Save
Use native (MS) bitfield layout
mno-align-stringops
-Target RejectNegative Report Mask(NO_ALIGN_STRINGOPS) Undocumented
+Target RejectNegative Report Mask(NO_ALIGN_STRINGOPS) Undocumented Save
mno-fancy-math-387
-Target RejectNegative Report Mask(NO_FANCY_MATH_387) Undocumented
+Target RejectNegative Report Mask(NO_FANCY_MATH_387) Undocumented Save
mno-push-args
-Target RejectNegative Report Mask(NO_PUSH_ARGS) Undocumented
+Target RejectNegative Report Mask(NO_PUSH_ARGS) Undocumented Save
mno-red-zone
-Target RejectNegative Report Mask(NO_RED_ZONE) Undocumented
+Target RejectNegative Report Mask(NO_RED_ZONE) Undocumented Save
momit-leaf-frame-pointer
-Target Report Mask(OMIT_LEAF_FRAME_POINTER)
+Target Report Mask(OMIT_LEAF_FRAME_POINTER) Save
Omit the frame pointer in leaf functions
mpc
@@ -135,11 +169,11 @@ Target RejectNegative Joined Var(ix86_preferred_stack_boundary_string)
Attempt to keep stack aligned to this power of 2
mpush-args
-Target Report InverseMask(NO_PUSH_ARGS, PUSH_ARGS)
+Target Report InverseMask(NO_PUSH_ARGS, PUSH_ARGS) Save
Use push instructions to save outgoing arguments
mred-zone
-Target RejectNegative Report InverseMask(NO_RED_ZONE, RED_ZONE)
+Target RejectNegative Report InverseMask(NO_RED_ZONE, RED_ZONE) Save
Use red-zone in the x86-64 code
mregparm=
@@ -147,15 +181,15 @@ Target RejectNegative Joined Var(ix86_regparm_string)
Number of registers used to pass integer arguments
mrtd
-Target Report Mask(RTD)
+Target Report Mask(RTD) Save
Alternate calling convention
msoft-float
-Target InverseMask(80387)
+Target InverseMask(80387) Save
Do not use hardware fp
msseregparm
-Target RejectNegative Mask(SSEREGPARM)
+Target RejectNegative Mask(SSEREGPARM) Save
Use SSE register passing conventions for SF and DF mode
mstackrealign
@@ -163,7 +197,7 @@ Target Report Var(ix86_force_align_arg_pointer)
Realign stack in prologue
mstack-arg-probe
-Target Report Mask(STACK_PROBE)
+Target Report Mask(STACK_PROBE) Save
Enable stack probing
mstringop-strategy=
@@ -186,104 +220,105 @@ mveclibabi=
Target RejectNegative Joined Var(ix86_veclibabi_string)
Vector library ABI to use
+mrecip
+Target Report Mask(RECIP) Save
+Generate reciprocals instead of divss and sqrtss.
+
+mcld
+Target Report Mask(CLD) Save
+Generate cld instruction in the function prologue.
+
+mno-fused-madd
+Target RejectNegative Report Mask(NO_FUSED_MADD) Undocumented Save
+
+mfused-madd
+Target Report InverseMask(NO_FUSED_MADD, FUSED_MADD) Save
+Enable automatic generation of fused floating point multiply-add instructions
+if the ISA supports such instructions. The -mfused-madd option is on by
+default.
+
;; ISA support
m32
-Target RejectNegative Negative(m64) Report InverseMask(ISA_64BIT) Var(ix86_isa_flags) VarExists
+Target RejectNegative Negative(m64) Report InverseMask(ISA_64BIT) Var(ix86_isa_flags) VarExists Save
Generate 32bit i386 code
m64
-Target RejectNegative Negative(m32) Report Mask(ISA_64BIT) Var(ix86_isa_flags) VarExists
+Target RejectNegative Negative(m32) Report Mask(ISA_64BIT) Var(ix86_isa_flags) VarExists Save
Generate 64bit x86-64 code
mmmx
-Target Report Mask(ISA_MMX) Var(ix86_isa_flags) VarExists
+Target Report Mask(ISA_MMX) Var(ix86_isa_flags) VarExists Save
Support MMX built-in functions
m3dnow
-Target Report Mask(ISA_3DNOW) Var(ix86_isa_flags) VarExists
+Target Report Mask(ISA_3DNOW) Var(ix86_isa_flags) VarExists Save
Support 3DNow! built-in functions
m3dnowa
-Target Undocumented Mask(ISA_3DNOW_A) Var(ix86_isa_flags) VarExists
+Target Undocumented Mask(ISA_3DNOW_A) Var(ix86_isa_flags) VarExists Save
Support Athlon 3Dnow! built-in functions
msse
-Target Report Mask(ISA_SSE) Var(ix86_isa_flags) VarExists
+Target Report Mask(ISA_SSE) Var(ix86_isa_flags) VarExists Save
Support MMX and SSE built-in functions and code generation
msse2
-Target Report Mask(ISA_SSE2) Var(ix86_isa_flags) VarExists
+Target Report Mask(ISA_SSE2) Var(ix86_isa_flags) VarExists Save
Support MMX, SSE and SSE2 built-in functions and code generation
msse3
-Target Report Mask(ISA_SSE3) Var(ix86_isa_flags) VarExists
+Target Report Mask(ISA_SSE3) Var(ix86_isa_flags) VarExists Save
Support MMX, SSE, SSE2 and SSE3 built-in functions and code generation
mssse3
-Target Report Mask(ISA_SSSE3) Var(ix86_isa_flags) VarExists
+Target Report Mask(ISA_SSSE3) Var(ix86_isa_flags) VarExists Save
Support MMX, SSE, SSE2, SSE3 and SSSE3 built-in functions and code generation
msse4.1
-Target Report Mask(ISA_SSE4_1) Var(ix86_isa_flags) VarExists
+Target Report Mask(ISA_SSE4_1) Var(ix86_isa_flags) VarExists Save
Support MMX, SSE, SSE2, SSE3, SSSE3 and SSE4.1 built-in functions and code generation
msse4.2
-Target Report Mask(ISA_SSE4_2) Var(ix86_isa_flags) VarExists
+Target Report Mask(ISA_SSE4_2) Var(ix86_isa_flags) VarExists Save
Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1 and SSE4.2 built-in functions and code generation
msse4
-Target RejectNegative Report Mask(ISA_SSE4_2) MaskExists Var(ix86_isa_flags) VarExists
+Target RejectNegative Report Mask(ISA_SSE4_2) MaskExists Var(ix86_isa_flags) VarExists Save
Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1 and SSE4.2 built-in functions and code generation
mno-sse4
-Target RejectNegative Report InverseMask(ISA_SSE4_1) MaskExists Var(ix86_isa_flags) VarExists
+Target RejectNegative Report InverseMask(ISA_SSE4_1) MaskExists Var(ix86_isa_flags) VarExists Save
Do not support SSE4.1 and SSE4.2 built-in functions and code generation
msse4a
-Target Report Mask(ISA_SSE4A) Var(ix86_isa_flags) VarExists
+Target Report Mask(ISA_SSE4A) Var(ix86_isa_flags) VarExists Save
Support MMX, SSE, SSE2, SSE3 and SSE4A built-in functions and code generation
msse5
-Target Report Mask(ISA_SSE5) Var(ix86_isa_flags) VarExists
+Target Report Mask(ISA_SSE5) Var(ix86_isa_flags) VarExists Save
Support SSE5 built-in functions and code generation
-;; Instruction support
-
-mcld
-Target Report Mask(CLD)
-Generate cld instruction in the function prologue.
-
mabm
-Target Report RejectNegative Var(x86_abm)
+Target Report Mask(ISA_ABM) Var(ix86_isa_flags) VarExists Save
Support code generation of Advanced Bit Manipulation (ABM) instructions.
-mcx16
-Target Report RejectNegative Var(x86_cmpxchg16b)
-Support code generation of cmpxchg16b instruction.
-
mpopcnt
-Target Report RejectNegative Var(x86_popcnt)
+Target Report Mask(ISA_POPCNT) Var(ix86_isa_flags) VarExists Save
Support code generation of popcnt instruction.
+mcx16
+Target Report Mask(ISA_CX16) Var(ix86_isa_flags) VarExists Save
+Support code generation of cmpxchg16b instruction.
+
msahf
-Target Report RejectNegative Var(x86_sahf)
+Target Report Mask(ISA_SAHF) Var(ix86_isa_flags) VarExists Save
Support code generation of sahf instruction in 64bit x86-64 code.
-mrecip
-Target Report RejectNegative Var(x86_recip)
-Generate reciprocals instead of divss and sqrtss.
-
-mfused-madd
-Target Report Var(x86_fused_muladd) Init(1)
-Enable automatic generation of fused floating point multiply-add instructions
-if the ISA supports such instructions. The -mfused-madd option is on by
-default.
-
maes
-Target Report RejectNegative Var(x86_aes)
+Target Report Mask(ISA_AES) Var(ix86_isa_flags) VarExists Save
Support AES built-in functions and code generation
mpclmul
-Target Report RejectNegative Var(x86_pclmul)
+Target Report Mask(ISA_PCLMUL) Var(ix86_isa_flags) VarExists Save
Support PCLMUL built-in functions and code generation
diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md
index 84fb001cd63..c1d306054ad 100644
--- a/gcc/config/i386/sse.md
+++ b/gcc/config/i386/sse.md
@@ -868,7 +868,7 @@
(match_operand:SSEMODEF4 2 "nonimmediate_operand" "x,xm,xm,x"))
(match_operand:SSEMODEF4 3 "nonimmediate_operand" "xm,x,0,0")))]
"TARGET_SSE5 && TARGET_FUSED_MADD
- && ix86_sse5_valid_op_p (operands, insn, 4, true, 2)"
+ && ix86_sse5_valid_op_p (operands, insn, 4, true, 2, true)"
"fmadd<ssemodesuffixf4>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
[(set_attr "type" "ssemuladd")
(set_attr "mode" "<MODE>")])
@@ -882,8 +882,8 @@
(match_operand:SSEMODEF4 2 "nonimmediate_operand" ""))
(match_operand:SSEMODEF4 3 "nonimmediate_operand" "")))]
"TARGET_SSE5
- && !ix86_sse5_valid_op_p (operands, insn, 4, true, 1)
- && ix86_sse5_valid_op_p (operands, insn, 4, true, 2)
+ && !ix86_sse5_valid_op_p (operands, insn, 4, true, 1, true)
+ && ix86_sse5_valid_op_p (operands, insn, 4, true, 2, true)
&& !reg_mentioned_p (operands[0], operands[1])
&& !reg_mentioned_p (operands[0], operands[2])
&& !reg_mentioned_p (operands[0], operands[3])"
@@ -909,7 +909,7 @@
(match_dup 1)
(const_int 1)))]
"TARGET_SSE5 && TARGET_FUSED_MADD
- && ix86_sse5_valid_op_p (operands, insn, 4, true, 1)"
+ && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, true)"
"fmadd<ssemodesuffixf2s>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
[(set_attr "type" "ssemuladd")
(set_attr "mode" "<MODE>")])
@@ -924,7 +924,7 @@
(match_operand:SSEMODEF4 2 "nonimmediate_operand" "x,xm,xm,x"))
(match_operand:SSEMODEF4 3 "nonimmediate_operand" "xm,x,0,0")))]
"TARGET_SSE5 && TARGET_FUSED_MADD
- && ix86_sse5_valid_op_p (operands, insn, 4, true, 2)"
+ && ix86_sse5_valid_op_p (operands, insn, 4, true, 2, true)"
"fmsub<ssemodesuffixf4>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
[(set_attr "type" "ssemuladd")
(set_attr "mode" "<MODE>")])
@@ -938,8 +938,8 @@
(match_operand:SSEMODEF4 2 "nonimmediate_operand" ""))
(match_operand:SSEMODEF4 3 "nonimmediate_operand" "")))]
"TARGET_SSE5
- && !ix86_sse5_valid_op_p (operands, insn, 4, true, 1)
- && ix86_sse5_valid_op_p (operands, insn, 4, true, 2)
+ && !ix86_sse5_valid_op_p (operands, insn, 4, true, 1, true)
+ && ix86_sse5_valid_op_p (operands, insn, 4, true, 2, true)
&& !reg_mentioned_p (operands[0], operands[1])
&& !reg_mentioned_p (operands[0], operands[2])
&& !reg_mentioned_p (operands[0], operands[3])"
@@ -965,7 +965,7 @@
(match_dup 1)
(const_int 1)))]
"TARGET_SSE5 && TARGET_FUSED_MADD
- && ix86_sse5_valid_op_p (operands, insn, 4, true, 1)"
+ && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, false)"
"fmsub<ssemodesuffixf2s>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
[(set_attr "type" "ssemuladd")
(set_attr "mode" "<MODE>")])
@@ -982,7 +982,7 @@
(match_operand:SSEMODEF4 1 "nonimmediate_operand" "%0,0,x,xm")
(match_operand:SSEMODEF4 2 "nonimmediate_operand" "x,xm,xm,x"))))]
"TARGET_SSE5 && TARGET_FUSED_MADD
- && ix86_sse5_valid_op_p (operands, insn, 4, true, 2)"
+ && ix86_sse5_valid_op_p (operands, insn, 4, true, 2, true)"
"fnmadd<ssemodesuffixf4>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
[(set_attr "type" "ssemuladd")
(set_attr "mode" "<MODE>")])
@@ -996,8 +996,8 @@
(match_operand:SSEMODEF4 1 "nonimmediate_operand" "")
(match_operand:SSEMODEF4 2 "nonimmediate_operand" ""))))]
"TARGET_SSE5
- && !ix86_sse5_valid_op_p (operands, insn, 4, true, 1)
- && ix86_sse5_valid_op_p (operands, insn, 4, true, 2)
+ && !ix86_sse5_valid_op_p (operands, insn, 4, true, 1, true)
+ && ix86_sse5_valid_op_p (operands, insn, 4, true, 2, true)
&& !reg_mentioned_p (operands[0], operands[1])
&& !reg_mentioned_p (operands[0], operands[2])
&& !reg_mentioned_p (operands[0], operands[3])"
@@ -1023,7 +1023,7 @@
(match_dup 1)
(const_int 1)))]
"TARGET_SSE5 && TARGET_FUSED_MADD
- && ix86_sse5_valid_op_p (operands, insn, 4, true, 1)"
+ && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, true)"
"fnmadd<ssemodesuffixf2s>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
[(set_attr "type" "ssemuladd")
(set_attr "mode" "<MODE>")])
@@ -1040,7 +1040,7 @@
(match_operand:SSEMODEF4 2 "nonimmediate_operand" "x,xm"))
(match_operand:SSEMODEF4 3 "nonimmediate_operand" "xm,x")))]
"TARGET_SSE5 && TARGET_FUSED_MADD
- && ix86_sse5_valid_op_p (operands, insn, 4, true, 2)"
+ && ix86_sse5_valid_op_p (operands, insn, 4, true, 2, false)"
"fnmsub<ssemodesuffixf4>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
[(set_attr "type" "ssemuladd")
(set_attr "mode" "<MODE>")])
@@ -1055,8 +1055,8 @@
(match_operand:SSEMODEF4 2 "nonimmediate_operand" ""))
(match_operand:SSEMODEF4 3 "nonimmediate_operand" "")))]
"TARGET_SSE5
- && !ix86_sse5_valid_op_p (operands, insn, 4, true, 1)
- && ix86_sse5_valid_op_p (operands, insn, 4, true, 2)
+ && !ix86_sse5_valid_op_p (operands, insn, 4, true, 1, false)
+ && ix86_sse5_valid_op_p (operands, insn, 4, true, 2, false)
&& !reg_mentioned_p (operands[0], operands[1])
&& !reg_mentioned_p (operands[0], operands[2])
&& !reg_mentioned_p (operands[0], operands[3])"
@@ -1083,7 +1083,7 @@
(match_dup 1)
(const_int 1)))]
"TARGET_SSE5 && TARGET_FUSED_MADD
- && ix86_sse5_valid_op_p (operands, insn, 4, true, 2)"
+ && ix86_sse5_valid_op_p (operands, insn, 4, true, 2, false)"
"fnmsub<ssemodesuffixf2s>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
[(set_attr "type" "ssemuladd")
(set_attr "mode" "<MODE>")])
@@ -1121,7 +1121,7 @@
(match_operand:SSEMODEF2P 2 "nonimmediate_operand" "x,xm,xm,x"))
(match_operand:SSEMODEF2P 3 "nonimmediate_operand" "xm,x,0,0"))]
UNSPEC_SSE5_INTRINSIC))]
- "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1)"
+ "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, true)"
"fmadd<ssemodesuffixf4>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
[(set_attr "type" "ssemuladd")
(set_attr "mode" "<MODE>")])
@@ -1151,11 +1151,11 @@
(unspec:SSEMODEF2P
[(minus:SSEMODEF2P
(mult:SSEMODEF2P
- (match_operand:SSEMODEF2P 1 "register_operand" "%0,0,x,xm")
+ (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "%0,0,x,xm")
(match_operand:SSEMODEF2P 2 "nonimmediate_operand" "x,xm,xm,x"))
(match_operand:SSEMODEF2P 3 "nonimmediate_operand" "xm,x,0,0"))]
UNSPEC_SSE5_INTRINSIC))]
- "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1)"
+ "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, true)"
"fmsub<ssemodesuffixf4>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
[(set_attr "type" "ssemuladd")
(set_attr "mode" "<MODE>")])
@@ -1191,7 +1191,7 @@
(match_operand:SSEMODEF2P 1 "nonimmediate_operand" "%0,0,x,xm")
(match_operand:SSEMODEF2P 2 "nonimmediate_operand" "x,xm,xm,x")))]
UNSPEC_SSE5_INTRINSIC))]
- "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1)"
+ "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, true)"
"fnmadd<ssemodesuffixf4>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
[(set_attr "type" "ssemuladd")
(set_attr "mode" "<MODE>")])
@@ -1224,11 +1224,11 @@
[(minus:SSEMODEF2P
(mult:SSEMODEF2P
(neg:SSEMODEF2P
- (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "%0,0,x,xm"))
+ (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "0,0,x,xm"))
(match_operand:SSEMODEF2P 2 "nonimmediate_operand" "x,xm,xm,x"))
(match_operand:SSEMODEF2P 3 "nonimmediate_operand" "xm,x,0,0"))]
UNSPEC_SSE5_INTRINSIC))]
- "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1)"
+ "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, false)"
"fnmsub<ssemodesuffixf4>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
[(set_attr "type" "ssemuladd")
(set_attr "mode" "<MODE>")])
@@ -1271,7 +1271,7 @@
(match_dup 0)
(const_int 0))]
UNSPEC_SSE5_INTRINSIC))]
- "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1)"
+ "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, false)"
"fmadd<ssemodesuffixf2s>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
[(set_attr "type" "ssemuladd")
(set_attr "mode" "<ssescalarmode>")])
@@ -1305,13 +1305,13 @@
[(vec_merge:SSEMODEF2P
(minus:SSEMODEF2P
(mult:SSEMODEF2P
- (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "0,0")
+ (match_operand:SSEMODEF2P 1 "register_operand" "0,0")
(match_operand:SSEMODEF2P 2 "nonimmediate_operand" "x,xm"))
(match_operand:SSEMODEF2P 3 "nonimmediate_operand" "xm,x"))
(match_dup 1)
(const_int 1))]
UNSPEC_SSE5_INTRINSIC))]
- "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1)"
+ "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, false)"
"fmsub<ssemodesuffixf2s>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
[(set_attr "type" "ssemuladd")
(set_attr "mode" "<ssescalarmode>")])
@@ -1347,12 +1347,12 @@
(minus:SSEMODEF2P
(match_operand:SSEMODEF2P 3 "nonimmediate_operand" "xm,x")
(mult:SSEMODEF2P
- (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "0,0")
+ (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "%0,0")
(match_operand:SSEMODEF2P 2 "nonimmediate_operand" "x,xm")))
(match_dup 1)
(const_int 1))]
UNSPEC_SSE5_INTRINSIC))]
- "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1)"
+ "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, true)"
"fnmadd<ssemodesuffixf2s>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
[(set_attr "type" "ssemuladd")
(set_attr "mode" "<ssescalarmode>")])
@@ -1388,13 +1388,13 @@
(minus:SSEMODEF2P
(mult:SSEMODEF2P
(neg:SSEMODEF2P
- (match_operand:SSEMODEF2P 1 "nonimmediate_operand" "0,0"))
+ (match_operand:SSEMODEF2P 1 "register_operand" "0,0"))
(match_operand:SSEMODEF2P 2 "nonimmediate_operand" "x,xm"))
(match_operand:SSEMODEF2P 3 "nonimmediate_operand" "xm,x"))
(match_dup 1)
(const_int 1))]
UNSPEC_SSE5_INTRINSIC))]
- "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1)"
+ "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, false)"
"fnmsub<ssemodesuffixf2s>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
[(set_attr "type" "ssemuladd")
(set_attr "mode" "<ssescalarmode>")])
@@ -6842,10 +6842,10 @@
[(set (match_operand:V8HI 0 "register_operand" "=x,x,x")
(plus:V8HI
(mult:V8HI
- (match_operand:V8HI 1 "nonimmediate_operand" "%x,x,m")
- (match_operand:V8HI 2 "nonimmediate_operand" "x,m,x"))
- (match_operand:V8HI 3 "nonimmediate_operand" "0,0,0")))]
- "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, false, 2)"
+ (match_operand:V8HI 1 "nonimmediate_operand" "%x,x,xm")
+ (match_operand:V8HI 2 "nonimmediate_operand" "x,xm,x"))
+ (match_operand:V8HI 3 "register_operand" "0,0,0")))]
+ "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, false, 2, true)"
"@
pmacsww\t{%3, %2, %1, %0|%0, %1, %2, %3}
pmacsww\t{%3, %2, %1, %0|%0, %1, %2, %3}
@@ -6861,8 +6861,8 @@
(match_operand:V8HI 2 "nonimmediate_operand" ""))
(match_operand:V8HI 3 "nonimmediate_operand" "")))]
"TARGET_SSE5
- && !ix86_sse5_valid_op_p (operands, insn, 4, false, 1)
- && ix86_sse5_valid_op_p (operands, insn, 4, false, 2)
+ && !ix86_sse5_valid_op_p (operands, insn, 4, false, 1, true)
+ && ix86_sse5_valid_op_p (operands, insn, 4, false, 2, true)
&& !reg_mentioned_p (operands[0], operands[1])
&& !reg_mentioned_p (operands[0], operands[2])
&& !reg_mentioned_p (operands[0], operands[3])"
@@ -6879,8 +6879,8 @@
(ss_plus:V8HI
(mult:V8HI (match_operand:V8HI 1 "nonimmediate_operand" "%x,x,m")
(match_operand:V8HI 2 "nonimmediate_operand" "x,m,x"))
- (match_operand:V8HI 3 "nonimmediate_operand" "0,0,0")))]
- "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, false, 1)"
+ (match_operand:V8HI 3 "register_operand" "0,0,0")))]
+ "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, false, 1, true)"
"@
pmacssww\t{%3, %2, %1, %0|%0, %1, %2, %3}
pmacssww\t{%3, %2, %1, %0|%0, %1, %2, %3}
@@ -6898,8 +6898,8 @@
(mult:V4SI
(match_operand:V4SI 1 "nonimmediate_operand" "%x,x,m")
(match_operand:V4SI 2 "nonimmediate_operand" "x,m,x"))
- (match_operand:V4SI 3 "nonimmediate_operand" "0,0,0")))]
- "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, false, 2)"
+ (match_operand:V4SI 3 "register_operand" "0,0,0")))]
+ "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, false, 2, true)"
"@
pmacsdd\t{%3, %2, %1, %0|%0, %1, %2, %3}
pmacsdd\t{%3, %2, %1, %0|%0, %1, %2, %3}
@@ -6915,8 +6915,8 @@
(match_operand:V4SI 2 "nonimmediate_operand" ""))
(match_operand:V4SI 3 "nonimmediate_operand" "")))]
"TARGET_SSE5
- && !ix86_sse5_valid_op_p (operands, insn, 4, false, 1)
- && ix86_sse5_valid_op_p (operands, insn, 4, false, 2)
+ && !ix86_sse5_valid_op_p (operands, insn, 4, false, 1, true)
+ && ix86_sse5_valid_op_p (operands, insn, 4, false, 2, true)
&& !reg_mentioned_p (operands[0], operands[1])
&& !reg_mentioned_p (operands[0], operands[2])
&& !reg_mentioned_p (operands[0], operands[3])"
@@ -6933,8 +6933,8 @@
(ss_plus:V4SI
(mult:V4SI (match_operand:V4SI 1 "nonimmediate_operand" "%x,x,m")
(match_operand:V4SI 2 "nonimmediate_operand" "x,m,x"))
- (match_operand:V4SI 3 "nonimmediate_operand" "0,0,0")))]
- "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, false, 1)"
+ (match_operand:V4SI 3 "register_operand" "0,0,0")))]
+ "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, false, 1, true)"
"@
pmacssdd\t{%3, %2, %1, %0|%0, %1, %2, %3}
pmacssdd\t{%3, %2, %1, %0|%0, %1, %2, %3}
@@ -6948,7 +6948,7 @@
(mult:V2DI
(sign_extend:V2DI
(vec_select:V2SI
- (match_operand:V4SI 1 "nonimmediate_operand" "x,x,m")
+ (match_operand:V4SI 1 "nonimmediate_operand" "%x,x,m")
(parallel [(const_int 1)
(const_int 3)])))
(vec_select:V2SI
@@ -6956,7 +6956,7 @@
(parallel [(const_int 1)
(const_int 3)])))
(match_operand:V2DI 3 "register_operand" "0,0,0")))]
- "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, false, 1)"
+ "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, false, 1, true)"
"@
pmacssdql\t{%3, %2, %1, %0|%0, %1, %2, %3}
pmacssdql\t{%3, %2, %1, %0|%0, %1, %2, %3}
@@ -6970,7 +6970,7 @@
(mult:V2DI
(sign_extend:V2DI
(vec_select:V2SI
- (match_operand:V4SI 1 "nonimmediate_operand" "x,x,m")
+ (match_operand:V4SI 1 "nonimmediate_operand" "%x,x,m")
(parallel [(const_int 0)
(const_int 2)])))
(sign_extend:V2DI
@@ -6979,7 +6979,7 @@
(parallel [(const_int 0)
(const_int 2)]))))
(match_operand:V2DI 3 "register_operand" "0,0,0")))]
- "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, false, 1)"
+ "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, false, 1, true)"
"@
pmacssdqh\t{%3, %2, %1, %0|%0, %1, %2, %3}
pmacssdqh\t{%3, %2, %1, %0|%0, %1, %2, %3}
@@ -6993,7 +6993,7 @@
(mult:V2DI
(sign_extend:V2DI
(vec_select:V2SI
- (match_operand:V4SI 1 "nonimmediate_operand" "x,x,m")
+ (match_operand:V4SI 1 "nonimmediate_operand" "%x,x,m")
(parallel [(const_int 1)
(const_int 3)])))
(sign_extend:V2DI
@@ -7002,7 +7002,7 @@
(parallel [(const_int 1)
(const_int 3)]))))
(match_operand:V2DI 3 "register_operand" "0,0,0")))]
- "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, false, 1)"
+ "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, false, 1, true)"
"@
pmacsdql\t{%3, %2, %1, %0|%0, %1, %2, %3}
pmacsdql\t{%3, %2, %1, %0|%0, %1, %2, %3}
@@ -7016,7 +7016,7 @@
(mult:V2DI
(sign_extend:V2DI
(vec_select:V2SI
- (match_operand:V4SI 1 "nonimmediate_operand" "x,x,m")
+ (match_operand:V4SI 1 "nonimmediate_operand" "%x,x,m")
(parallel [(const_int 1)
(const_int 3)])))
(sign_extend:V2DI
@@ -7025,7 +7025,7 @@
(parallel [(const_int 1)
(const_int 3)]))))
(match_operand:V2DI 3 "memory_operand" "m,m,m")))]
- "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, false, -1)"
+ "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, false, -1, true)"
"#"
"&& (reload_completed
|| (!reg_mentioned_p (operands[0], operands[1])
@@ -7097,7 +7097,7 @@
(mult:V2DI
(sign_extend:V2DI
(vec_select:V2SI
- (match_operand:V4SI 1 "nonimmediate_operand" "x,x,m")
+ (match_operand:V4SI 1 "nonimmediate_operand" "%x,x,m")
(parallel [(const_int 0)
(const_int 2)])))
(sign_extend:V2DI
@@ -7106,7 +7106,7 @@
(parallel [(const_int 0)
(const_int 2)]))))
(match_operand:V2DI 3 "register_operand" "0,0,0")))]
- "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, false, 1)"
+ "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, false, 1, true)"
"@
pmacsdqh\t{%3, %2, %1, %0|%0, %1, %2, %3}
pmacsdqh\t{%3, %2, %1, %0|%0, %1, %2, %3}
@@ -7120,7 +7120,7 @@
(mult:V2DI
(sign_extend:V2DI
(vec_select:V2SI
- (match_operand:V4SI 1 "nonimmediate_operand" "x,x,m")
+ (match_operand:V4SI 1 "nonimmediate_operand" "%x,x,m")
(parallel [(const_int 0)
(const_int 2)])))
(sign_extend:V2DI
@@ -7129,7 +7129,7 @@
(parallel [(const_int 0)
(const_int 2)]))))
(match_operand:V2DI 3 "memory_operand" "m,m,m")))]
- "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, false, -1)"
+ "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, false, -1, true)"
"#"
"&& (reload_completed
|| (!reg_mentioned_p (operands[0], operands[1])
@@ -7202,7 +7202,7 @@
(mult:V4SI
(sign_extend:V4SI
(vec_select:V4HI
- (match_operand:V8HI 1 "nonimmediate_operand" "x,x,m")
+ (match_operand:V8HI 1 "nonimmediate_operand" "%x,x,m")
(parallel [(const_int 1)
(const_int 3)
(const_int 5)
@@ -7215,7 +7215,7 @@
(const_int 5)
(const_int 7)]))))
(match_operand:V4SI 3 "register_operand" "0,0,0")))]
- "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, false, 1)"
+ "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, false, 1, true)"
"@
pmacsswd\t{%3, %2, %1, %0|%0, %1, %2, %3}
pmacsswd\t{%3, %2, %1, %0|%0, %1, %2, %3}
@@ -7229,7 +7229,7 @@
(mult:V4SI
(sign_extend:V4SI
(vec_select:V4HI
- (match_operand:V8HI 1 "nonimmediate_operand" "x,x,m")
+ (match_operand:V8HI 1 "nonimmediate_operand" "%x,x,m")
(parallel [(const_int 1)
(const_int 3)
(const_int 5)
@@ -7242,7 +7242,7 @@
(const_int 5)
(const_int 7)]))))
(match_operand:V4SI 3 "register_operand" "0,0,0")))]
- "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, false, 1)"
+ "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, false, 1, true)"
"@
pmacswd\t{%3, %2, %1, %0|%0, %1, %2, %3}
pmacswd\t{%3, %2, %1, %0|%0, %1, %2, %3}
@@ -7257,7 +7257,7 @@
(mult:V4SI
(sign_extend:V4SI
(vec_select:V4HI
- (match_operand:V8HI 1 "nonimmediate_operand" "x,x,m")
+ (match_operand:V8HI 1 "nonimmediate_operand" "%x,x,m")
(parallel [(const_int 0)
(const_int 2)
(const_int 4)
@@ -7285,7 +7285,7 @@
(const_int 5)
(const_int 7)])))))
(match_operand:V4SI 3 "register_operand" "0,0,0")))]
- "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, false, 1)"
+ "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, false, 1, true)"
"@
pmadcsswd\t{%3, %2, %1, %0|%0, %1, %2, %3}
pmadcsswd\t{%3, %2, %1, %0|%0, %1, %2, %3}
@@ -7300,7 +7300,7 @@
(mult:V4SI
(sign_extend:V4SI
(vec_select:V4HI
- (match_operand:V8HI 1 "nonimmediate_operand" "x,x,m")
+ (match_operand:V8HI 1 "nonimmediate_operand" "%x,x,m")
(parallel [(const_int 0)
(const_int 2)
(const_int 4)
@@ -7328,7 +7328,7 @@
(const_int 5)
(const_int 7)])))))
(match_operand:V4SI 3 "register_operand" "0,0,0")))]
- "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, false, 1)"
+ "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, false, 1, true)"
"@
pmadcswd\t{%3, %2, %1, %0|%0, %1, %2, %3}
pmadcswd\t{%3, %2, %1, %0|%0, %1, %2, %3}
@@ -7343,7 +7343,7 @@
(match_operand:SSEMODE 3 "nonimmediate_operand" "0,0,xm,x")
(match_operand:SSEMODE 1 "vector_move_operand" "x,xm,0,0")
(match_operand:SSEMODE 2 "vector_move_operand" "xm,x,x,xm")))]
- "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1)"
+ "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, false)"
"@
pcmov\t{%3, %2, %1, %0|%0, %1, %2, %3}
pcmov\t{%3, %2, %1, %0|%0, %1, %2, %3}
@@ -7799,7 +7799,7 @@
(match_operand:V16QI 2 "nonimmediate_operand" "x,xm,xm,x")
(match_operand:V16QI 3 "nonimmediate_operand" "xm,x,0,0")]
UNSPEC_SSE5_PERMUTE))]
- "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1)"
+ "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, false)"
"pperm\t{%3, %2, %1, %0|%0, %1, %2, %3}"
[(set_attr "type" "sse4arg")
(set_attr "mode" "TI")])
@@ -7902,7 +7902,7 @@
(truncate:V2SI
(match_operand:V2DI 2 "nonimmediate_operand" "x,xm,xm,x"))))
(use (match_operand:V16QI 3 "nonimmediate_operand" "xm,x,0,0"))]
- "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1)"
+ "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, false)"
"pperm\t{%3, %2, %1, %0|%0, %1, %2, %3}"
[(set_attr "type" "sse4arg")
(set_attr "mode" "TI")])
@@ -7915,7 +7915,7 @@
(truncate:V4HI
(match_operand:V4SI 2 "nonimmediate_operand" "x,xm,xm,x"))))
(use (match_operand:V16QI 3 "nonimmediate_operand" "xm,x,0,0"))]
- "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1)"
+ "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, false)"
"pperm\t{%3, %2, %1, %0|%0, %1, %2, %3}"
[(set_attr "type" "sse4arg")
(set_attr "mode" "TI")])
@@ -7928,7 +7928,7 @@
(truncate:V8QI
(match_operand:V8HI 2 "nonimmediate_operand" "x,xm,xm,x"))))
(use (match_operand:V16QI 3 "nonimmediate_operand" "xm,x,0,0"))]
- "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1)"
+ "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, false)"
"pperm\t{%3, %2, %1, %0|%0, %1, %2, %3}"
[(set_attr "type" "sse4arg")
(set_attr "mode" "TI")])
@@ -7941,7 +7941,7 @@
(match_operand:SSEMODEF2P 2 "nonimmediate_operand" "x,xm,xm,x")
(match_operand:V16QI 3 "nonimmediate_operand" "xm,x,0,0")]
UNSPEC_SSE5_PERMUTE))]
- "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1)"
+ "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, false)"
"perm<ssemodesuffixf4>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
[(set_attr "type" "sse4arg")
(set_attr "mode" "<MODE>")])
@@ -8068,7 +8068,7 @@
(rotatert:SSEMODE1248
(match_dup 1)
(neg:SSEMODE1248 (match_dup 2)))))]
- "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 3, true, 1)"
+ "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 3, true, 1, false)"
"prot<ssevecsize>\t{%2, %1, %0|%0, %1, %2}"
[(set_attr "type" "sseishft")
(set_attr "mode" "TI")])
@@ -8121,7 +8121,7 @@
(ashiftrt:SSEMODE1248
(match_dup 1)
(neg:SSEMODE1248 (match_dup 2)))))]
- "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 3, true, 1)"
+ "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 3, true, 1, false)"
"psha<ssevecsize>\t{%2, %1, %0|%0, %1, %2}"
[(set_attr "type" "sseishft")
(set_attr "mode" "TI")])
@@ -8138,7 +8138,7 @@
(lshiftrt:SSEMODE1248
(match_dup 1)
(neg:SSEMODE1248 (match_dup 2)))))]
- "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 3, true, 1)"
+ "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 3, true, 1, false)"
"pshl<ssevecsize>\t{%2, %1, %0|%0, %1, %2}"
[(set_attr "type" "sseishft")
(set_attr "mode" "TI")])
diff --git a/gcc/config/i386/t-i386 b/gcc/config/i386/t-i386
new file mode 100644
index 00000000000..4c0c046dae6
--- /dev/null
+++ b/gcc/config/i386/t-i386
@@ -0,0 +1,13 @@
+i386.o: $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
+ $(RTL_H) $(TREE_H) $(TM_P_H) $(REGS_H) hard-reg-set.h \
+ $(REAL_H) insn-config.h conditions.h output.h insn-codes.h \
+ $(INSN_ATTR_H) $(FLAGS_H) $(C_COMMON_H) except.h $(FUNCTION_H) \
+ $(RECOG_H) $(EXPR_H) $(OPTABS_H) toplev.h $(BASIC_BLOCK_H) \
+ $(GGC_H) $(TARGET_H) $(TARGET_DEF_H) langhooks.h $(CGRAPH_H) \
+ $(TREE_GIMPLE_H) dwarf2.h $(DF_H) tm-constrs.h $(PARAMS_H)
+
+i386-c.o: $(srcdir)/config/i386/i386-c.c \
+ $(srcdir)/config/i386/i386-protos.h $(CONFIG_H) $(SYSTEM_H) coretypes.h \
+ $(TM_H) $(RTL_H) $(TREE_H) $(TM_P_H) $(FLAGS_H) $(C_COMMON_H) $(GGC_H) \
+ $(TARGET_H) $(TARGET_DEF_H) $(CPPLIB_H) $(C_PRAGMA_H)
+ $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(srcdir)/config/i386/i386-c.c
diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c
index de39ab12946..c07b21d9d53 100644
--- a/gcc/config/ia64/ia64.c
+++ b/gcc/config/ia64/ia64.c
@@ -50,7 +50,7 @@ along with GCC; see the file COPYING3. If not see
#include "hashtab.h"
#include "langhooks.h"
#include "cfglayout.h"
-#include "tree-gimple.h"
+#include "gimple.h"
#include "intl.h"
#include "df.h"
#include "debug.h"
@@ -275,7 +275,7 @@ static tree ia64_handle_model_attribute (tree *, tree, tree, int, bool *);
static tree ia64_handle_version_id_attribute (tree *, tree, tree, int, bool *);
static void ia64_encode_section_info (tree, rtx, int);
static rtx ia64_struct_value_rtx (tree, int);
-static tree ia64_gimplify_va_arg (tree, tree, tree *, tree *);
+static tree ia64_gimplify_va_arg (tree, tree, gimple_seq *, gimple_seq *);
static bool ia64_scalar_mode_supported_p (enum machine_mode mode);
static bool ia64_vector_mode_supported_p (enum machine_mode mode);
static bool ia64_cannot_force_const_mem (rtx);
@@ -493,6 +493,12 @@ static const struct attribute_spec ia64_attribute_table[] =
#undef TARGET_C_MODE_FOR_SUFFIX
#define TARGET_C_MODE_FOR_SUFFIX ia64_c_mode_for_suffix
+#undef TARGET_OPTION_COLD_ATTRIBUTE_SETS_OPTIMIZATION
+#define TARGET_OPTION_COLD_ATTRIBUTE_SETS_OPTIMIZATION true
+
+#undef TARGET_OPTION_HOT_ATTRIBUTE_SETS_OPTIMIZATION
+#define TARGET_OPTION_HOT_ATTRIBUTE_SETS_OPTIMIZATION true
+
struct gcc_target targetm = TARGET_INITIALIZER;
typedef enum
@@ -1119,8 +1125,8 @@ ia64_split_tmode (rtx out[2], rtx in, bool reversed, bool dead)
}
else
{
- p[0] = (((unsigned HOST_WIDE_INT) l[3]) << 32) + l[2];
- p[1] = (((unsigned HOST_WIDE_INT) l[1]) << 32) + l[0];
+ p[0] = (((unsigned HOST_WIDE_INT) l[1]) << 32) + l[0];
+ p[1] = (((unsigned HOST_WIDE_INT) l[3]) << 32) + l[2];
}
out[0] = GEN_INT (p[0]);
out[1] = GEN_INT (p[1]);
@@ -4336,7 +4342,8 @@ ia64_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
/* Implement va_arg. */
static tree
-ia64_gimplify_va_arg (tree valist, tree type, tree *pre_p, tree *post_p)
+ia64_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
+ gimple_seq *post_p)
{
/* Variable sized types are passed by reference. */
if (pass_by_reference (NULL, TYPE_MODE (type), type, false))
@@ -4359,8 +4366,7 @@ ia64_gimplify_va_arg (tree valist, tree type, tree *pre_p, tree *post_p)
t = build2 (BIT_AND_EXPR, TREE_TYPE (t), t,
size_int (-2 * UNITS_PER_WORD));
t = fold_convert (TREE_TYPE (valist), t);
- t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (valist), valist, t);
- gimplify_and_add (t, pre_p);
+ gimplify_assign (unshare_expr (valist), t, pre_p);
}
return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
@@ -5232,9 +5238,6 @@ ia64_override_options (void)
TARGET_INLINE_SQRT = INL_MAX_THR;
}
- ia64_flag_schedule_insns2 = flag_schedule_insns_after_reload;
- flag_schedule_insns_after_reload = 0;
-
ia64_section_threshold = g_switch_set ? g_switch_value : IA64_DEFAULT_GVALUE;
init_machine_status = ia64_init_machine_status;
@@ -9927,6 +9930,13 @@ void
ia64_optimization_options (int level ATTRIBUTE_UNUSED,
int size ATTRIBUTE_UNUSED)
{
+ /* Disable the second machine independent scheduling pass and use one for the
+ IA-64. This needs to be here instead of in OVERRIDE_OPTIONS because this
+ is done whenever the optimization is changed via #pragma GCC optimize or
+ attribute((optimize(...))). */
+ ia64_flag_schedule_insns2 = flag_schedule_insns_after_reload;
+ flag_schedule_insns_after_reload = 0;
+
/* Let the scheduler form additional regions. */
set_param_value ("max-sched-extend-regions-iters", 2);
diff --git a/gcc/config/m32c/m32c-protos.h b/gcc/config/m32c/m32c-protos.h
index a63191c21ab..ec98d81f93c 100644
--- a/gcc/config/m32c/m32c-protos.h
+++ b/gcc/config/m32c/m32c-protos.h
@@ -1,5 +1,5 @@
/* Target Prototypes for R8C/M16C/M32C
- Copyright (C) 2005, 2007
+ Copyright (C) 2005, 2007, 2008
Free Software Foundation, Inc.
Contributed by Red Hat.
@@ -108,7 +108,7 @@ int m32c_split_psi_p (rtx *);
#ifdef TREE_CODE
void m32c_function_arg_advance (CUMULATIVE_ARGS *, MM, tree, int);
-tree m32c_gimplify_va_arg_expr (tree, tree, tree *, tree *);
+tree m32c_gimplify_va_arg_expr (tree, tree, gimple_seq *, gimple_seq *);
void m32c_init_cumulative_args (CUMULATIVE_ARGS *, tree, rtx, tree, int);
bool m32c_promote_function_return (const_tree);
int m32c_special_page_vector_p (tree);
diff --git a/gcc/config/m32c/m32c.c b/gcc/config/m32c/m32c.c
index b0733dd8364..0e03c9e6bf2 100644
--- a/gcc/config/m32c/m32c.c
+++ b/gcc/config/m32c/m32c.c
@@ -47,7 +47,7 @@
#include "target-def.h"
#include "tm_p.h"
#include "langhooks.h"
-#include "tree-gimple.h"
+#include "gimple.h"
#include "df.h"
/* Prototypes */
diff --git a/gcc/config/m68k/lb1sf68.asm b/gcc/config/m68k/lb1sf68.asm
index d09213fc033..e03b7b30d87 100644
--- a/gcc/config/m68k/lb1sf68.asm
+++ b/gcc/config/m68k/lb1sf68.asm
@@ -129,10 +129,11 @@ Boston, MA 02110-1301, USA. */
#else /* __PIC__ */
- /* Common for -mid-shared-libary and -msep-data */
+ /* Common for Linux and uClinux, the latter with either
+ -mid-shared-library or -msep-data. */
.macro PICCALL addr
-#if defined (__mcoldfire__) && !defined (__mcfisab__)
+#if defined (__mcoldfire__) && !defined (__mcfisab__) && !defined (__mcfisac__)
lea \addr-.-8,a0
jsr pc@(a0)
#else
@@ -141,6 +142,9 @@ Boston, MA 02110-1301, USA. */
.endm
.macro PICJUMP addr
+ /* ISA C has no bra.l instruction, and since this assembly file
+ gets assembled into multiple object files, we avoid the
+ bra instruction entirely. */
#if defined (__mcoldfire__) && !defined (__mcfisab__)
lea \addr-.-8,a0
jmp pc@(a0)
@@ -149,7 +153,11 @@ Boston, MA 02110-1301, USA. */
#endif
.endm
-# if defined(__ID_SHARED_LIBRARY__)
+# if defined (__uClinux__)
+
+ /* Versions for uClinux */
+
+# if defined(__ID_SHARED_LIBRARY__)
/* -mid-shared-library versions */
@@ -163,7 +171,7 @@ Boston, MA 02110-1301, USA. */
movel \sym@GOT(\areg), sp@-
.endm
-# else /* !__ID_SHARED_LIBRARY__ */
+# else /* !__ID_SHARED_LIBRARY__ */
/* Versions for -msep-data */
@@ -175,7 +183,25 @@ Boston, MA 02110-1301, USA. */
movel \sym@GOT(a5), sp@-
.endm
-# endif /* !__ID_SHARED_LIBRARY__ */
+# endif
+
+# else /* !__uClinux__ */
+
+ /* Versions for Linux */
+
+ .macro PICLEA sym, reg
+ movel #_GLOBAL_OFFSET_TABLE_@GOTPC, \reg
+ lea (-6, pc, \reg), \reg
+ movel \sym@GOT(\reg), \reg
+ .endm
+
+ .macro PICPEA sym, areg
+ movel #_GLOBAL_OFFSET_TABLE_@GOTPC, \areg
+ lea (-6, pc, \areg), \areg
+ movel \sym@GOT(\areg), sp@-
+ .endm
+
+# endif
#endif /* __PIC__ */
diff --git a/gcc/config/m68k/m68k-devices.def b/gcc/config/m68k/m68k-devices.def
index 7b06e35b737..fb5cde3b451 100644
--- a/gcc/config/m68k/m68k-devices.def
+++ b/gcc/config/m68k/m68k-devices.def
@@ -63,7 +63,11 @@
There is a bit of duplication between devices in the same family,
but this approach makes scripting easier. We keep each entry on
- a single line for the same reason. */
+ a single line for the same reason.
+
+ As the compiler does not (currently) generate MAC or EMAC commands,
+ we do not need separate multilibs for cores that only differ in
+ their MAC functionality. */
/* 680x0 series processors. */
M68K_DEVICE ("68000", m68000, "68000", "68000", 68000, isa_00, 0)
@@ -86,31 +90,31 @@ M68K_DEVICE ("5206", mcf5206, "5206", "5206", cfv2, isa_a, 0)
M68K_DEVICE ("5206e", mcf5206e, "5206e", "5206e", cfv2, isa_a, FL_CF_HWDIV | FL_CF_MAC)
M68K_DEVICE ("5207", mcf5207, "5208", "5208", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_EMAC)
M68K_DEVICE ("5208", mcf5208, "5208", "5208", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_EMAC)
-M68K_DEVICE ("5210a", mcf5210a, "5211a", "5213", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_MAC)
-M68K_DEVICE ("5211a", mcf5211a, "5211a", "5213", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_MAC)
-M68K_DEVICE ("5211", mcf5211, "5213", "5213", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_MAC)
-M68K_DEVICE ("5212", mcf5212, "5213", "5213", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_MAC)
-M68K_DEVICE ("5213", mcf5213, "5213", "5213", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_MAC)
+M68K_DEVICE ("5210a", mcf5210a, "5211a", "5208", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_MAC)
+M68K_DEVICE ("5211a", mcf5211a, "5211a", "5208", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_MAC)
+M68K_DEVICE ("5211", mcf5211, "5213", "5208", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_MAC)
+M68K_DEVICE ("5212", mcf5212, "5213", "5208", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_MAC)
+M68K_DEVICE ("5213", mcf5213, "5213", "5208", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_MAC)
M68K_DEVICE ("5214", mcf5214, "5216", "5208", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_EMAC)
M68K_DEVICE ("5216", mcf5216, "5216", "5208", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_EMAC)
-M68K_DEVICE ("52221", mcf52221, "52223", "5213", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_MAC)
-M68K_DEVICE ("52223", mcf52223, "52223", "5213", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_MAC)
+M68K_DEVICE ("52221", mcf52221, "52223", "5208", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_MAC)
+M68K_DEVICE ("52223", mcf52223, "52223", "5208", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_MAC)
M68K_DEVICE ("52230", mcf52230, "52235", "5208", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_EMAC)
M68K_DEVICE ("52231", mcf52231, "52235", "5208", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_EMAC)
M68K_DEVICE ("52232", mcf52232, "52235", "5208", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_EMAC)
M68K_DEVICE ("52233", mcf52233, "52235", "5208", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_EMAC)
M68K_DEVICE ("52234", mcf52234, "52235", "5208", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_EMAC)
M68K_DEVICE ("52235", mcf52235, "52235", "5208", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_EMAC)
-M68K_DEVICE ("5224", mcf5224, "5225", "5213", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_MAC)
-M68K_DEVICE ("5225", mcf5225, "5225", "5213", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_MAC)
+M68K_DEVICE ("5224", mcf5224, "5225", "5208", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_MAC)
+M68K_DEVICE ("5225", mcf5225, "5225", "5208", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_MAC)
M68K_DEVICE ("5232", mcf5232, "5235", "5208", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_EMAC)
M68K_DEVICE ("5233", mcf5233, "5235", "5208", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_EMAC)
M68K_DEVICE ("5234", mcf5234, "5235", "5208", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_EMAC)
M68K_DEVICE ("5235", mcf5235, "5235", "5208", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_EMAC)
M68K_DEVICE ("523x", mcf523x, "5235", "5208", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_EMAC)
-M68K_DEVICE ("5249", mcf5249, "5249", "5249", cfv2, isa_a, FL_CF_HWDIV | FL_CF_EMAC)
-M68K_DEVICE ("5250", mcf5250, "5250", "5249", cfv2, isa_a, FL_CF_HWDIV | FL_CF_EMAC)
-M68K_DEVICE ("5253", mcf5253, "5253", "5249", cfv2, isa_a, FL_CF_HWDIV | FL_CF_EMAC)
+M68K_DEVICE ("5249", mcf5249, "5249", "5206e", cfv2, isa_a, FL_CF_HWDIV | FL_CF_EMAC)
+M68K_DEVICE ("5250", mcf5250, "5250", "5206e", cfv2, isa_a, FL_CF_HWDIV | FL_CF_EMAC)
+M68K_DEVICE ("5253", mcf5253, "5253", "5206e", cfv2, isa_a, FL_CF_HWDIV | FL_CF_EMAC)
M68K_DEVICE ("5270", mcf5270, "5271", "5208", cfv2, isa_aplus, FL_CF_HWDIV | FL_CF_EMAC)
M68K_DEVICE ("5271", mcf5271, "5271", "5208", cfv2, isa_aplus, FL_CF_HWDIV)
M68K_DEVICE ("5272", mcf5272, "5272", "5206e", cfv2, isa_a, FL_CF_HWDIV | FL_CF_MAC)
diff --git a/gcc/config/m68k/m68k.c b/gcc/config/m68k/m68k.c
index 046132088bc..1853073af81 100644
--- a/gcc/config/m68k/m68k.c
+++ b/gcc/config/m68k/m68k.c
@@ -148,7 +148,7 @@ static bool m68k_save_reg (unsigned int regno, bool interrupt_handler);
static bool m68k_ok_for_sibcall_p (tree, tree);
static bool m68k_rtx_costs (rtx, int, int, int *);
#if M68K_HONOR_TARGET_STRICT_ALIGNMENT
-static bool m68k_return_in_memory (tree, tree);
+static bool m68k_return_in_memory (const_tree, const_tree);
#endif
@@ -4627,7 +4627,7 @@ m68k_function_value (const_tree valtype, const_tree func ATTRIBUTE_UNUSED)
/* Worker function for TARGET_RETURN_IN_MEMORY. */
#if M68K_HONOR_TARGET_STRICT_ALIGNMENT
static bool
-m68k_return_in_memory (tree type, tree fntype ATTRIBUTE_UNUSED)
+m68k_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
{
enum machine_mode mode = TYPE_MODE (type);
diff --git a/gcc/config/m68k/t-cf b/gcc/config/m68k/t-cf
index 697946654af..7bf8e11ee82 100644
--- a/gcc/config/m68k/t-cf
+++ b/gcc/config/m68k/t-cf
@@ -2,3 +2,6 @@
M68K_MLIB_CPU += && (CPU ~ "^mcf")
M68K_ARCH := cf
+# Do not stamp the multilibs with a MAC type, as we never use those
+# instructions in compiler-generated code.
+MULTILIB_EXTRA_OPTS += Wa,-mno-mac
diff --git a/gcc/config/m68k/t-linux b/gcc/config/m68k/t-linux
new file mode 100644
index 00000000000..f46d3a873d5
--- /dev/null
+++ b/gcc/config/m68k/t-linux
@@ -0,0 +1,11 @@
+EXTRA_MULTILIB_PARTS=crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o
+
+# Only include multilibs for CPUs with an MMU.
+M68K_MLIB_CPU += && match(FLAGS, "FL_MMU")
+
+# This rule uses MULTILIB_MATCHES to generate a definition of
+# SYSROOT_SUFFIX_SPEC.
+sysroot-suffix.h: $(srcdir)/config/m68k/print-sysroot-suffix.sh
+ $(SHELL) $(srcdir)/config/m68k/print-sysroot-suffix.sh \
+ "$(SYSTEM_HEADER_DIR)/../.." "$(MULTILIB_MATCHES)" \
+ "$(MULTILIB_OPTIONS)" > $@
diff --git a/gcc/config/mips/constraints.md b/gcc/config/mips/constraints.md
index a387489f204..88fcbf65ef6 100644
--- a/gcc/config/mips/constraints.md
+++ b/gcc/config/mips/constraints.md
@@ -55,8 +55,11 @@
(define_register_constraint "j" "PIC_FN_ADDR_REG"
"@internal")
+;; Don't use this constraint in gcc code! It runs the risk of
+;; introducing a spill failure; see tls_get_tp_<mode>.
(define_register_constraint "v" "V1_REG"
- "@internal")
+ "Register @code{$3}. Do not use this constraint in new code;
+ it is retained only for compatibility with glibc.")
(define_register_constraint "y" "GR_REGS"
"Equivalent to @code{r}; retained for backwards compatibility.")
diff --git a/gcc/config/mips/driver-native.c b/gcc/config/mips/driver-native.c
index 22b08939e24..24831c654c8 100644
--- a/gcc/config/mips/driver-native.c
+++ b/gcc/config/mips/driver-native.c
@@ -19,6 +19,8 @@ along with GCC; see the file COPYING3. If not see
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
/* This will be called by the spec parser in gcc.c when it sees
a %:local_cpu_detect(args) construct. Currently it will be called
@@ -61,6 +63,10 @@ host_detect_local_cpu (int argc, const char **argv)
else if (strstr (buf, "Godson2 V0.3") != NULL
|| strstr (buf, "Loongson-2 V0.3") != NULL)
cpu = "loongson2f";
+ else if (strstr (buf, "SiByte SB1") != NULL)
+ cpu = "sb1";
+ else if (strstr (buf, "R5000") != NULL)
+ cpu = "r5000";
break;
}
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index 48ba54b1cef..913acc71cf1 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -56,7 +56,7 @@ along with GCC; see the file COPYING3. If not see
#include "langhooks.h"
#include "cfglayout.h"
#include "sched-int.h"
-#include "tree-gimple.h"
+#include "gimple.h"
#include "bitmap.h"
#include "diagnostic.h"
@@ -442,7 +442,7 @@ const struct mips_rtx_cost_data *mips_cost;
static int mips_base_target_flags;
/* True if MIPS16 is the default mode. */
-static bool mips_base_mips16;
+bool mips_base_mips16;
/* The ambient values of other global variables. */
static int mips_base_delayed_branch; /* flag_delayed_branch */
@@ -2465,6 +2465,21 @@ mips_call_tls_get_addr (rtx sym, enum mips_symbol_type type, rtx v0)
return insn;
}
+/* Return a pseudo register that contains the current thread pointer. */
+
+static rtx
+mips_get_tp (void)
+{
+ rtx tp;
+
+ tp = gen_reg_rtx (Pmode);
+ if (Pmode == DImode)
+ emit_insn (gen_tls_get_tp_di (tp));
+ else
+ emit_insn (gen_tls_get_tp_si (tp));
+ return tp;
+}
+
/* Generate the code to access LOC, a thread-local SYMBOL_REF, and return
its address. The return value will be both a valid address and a valid
SET_SRC (either a REG or a LO_SUM). */
@@ -2472,7 +2487,7 @@ mips_call_tls_get_addr (rtx sym, enum mips_symbol_type type, rtx v0)
static rtx
mips_legitimize_tls_address (rtx loc)
{
- rtx dest, insn, v0, v1, tmp1, tmp2, eqv;
+ rtx dest, insn, v0, tp, tmp1, tmp2, eqv;
enum tls_model model;
if (TARGET_MIPS16)
@@ -2514,31 +2529,20 @@ mips_legitimize_tls_address (rtx loc)
break;
case TLS_MODEL_INITIAL_EXEC:
- v1 = gen_rtx_REG (Pmode, GP_RETURN + 1);
+ tp = mips_get_tp ();
tmp1 = gen_reg_rtx (Pmode);
tmp2 = mips_unspec_address (loc, SYMBOL_GOTTPREL);
if (Pmode == DImode)
- {
- emit_insn (gen_tls_get_tp_di (v1));
- emit_insn (gen_load_gotdi (tmp1, pic_offset_table_rtx, tmp2));
- }
+ emit_insn (gen_load_gotdi (tmp1, pic_offset_table_rtx, tmp2));
else
- {
- emit_insn (gen_tls_get_tp_si (v1));
- emit_insn (gen_load_gotsi (tmp1, pic_offset_table_rtx, tmp2));
- }
+ emit_insn (gen_load_gotsi (tmp1, pic_offset_table_rtx, tmp2));
dest = gen_reg_rtx (Pmode);
- emit_insn (gen_add3_insn (dest, tmp1, v1));
+ emit_insn (gen_add3_insn (dest, tmp1, tp));
break;
case TLS_MODEL_LOCAL_EXEC:
- v1 = gen_rtx_REG (Pmode, GP_RETURN + 1);
- if (Pmode == DImode)
- emit_insn (gen_tls_get_tp_di (v1));
- else
- emit_insn (gen_tls_get_tp_si (v1));
-
- tmp1 = mips_unspec_offset_high (NULL, v1, loc, SYMBOL_TPREL);
+ tp = mips_get_tp ();
+ tmp1 = mips_unspec_offset_high (NULL, tp, loc, SYMBOL_TPREL);
dest = gen_rtx_LO_SUM (Pmode, tmp1,
mips_unspec_address (loc, SYMBOL_TPREL));
break;
@@ -4955,12 +4959,12 @@ mips_va_start (tree valist, rtx nextarg)
if (cum->stack_words > 0)
t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (ovfl), t,
size_int (cum->stack_words * UNITS_PER_WORD));
- t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (ovfl), ovfl, t);
+ t = build2 (MODIFY_EXPR, TREE_TYPE (ovfl), ovfl, t);
expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
/* Emit code to initialize GTOP, the top of the GPR save area. */
t = make_tree (TREE_TYPE (gtop), virtual_incoming_args_rtx);
- t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (gtop), gtop, t);
+ t = build2 (MODIFY_EXPR, TREE_TYPE (gtop), gtop, t);
expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
/* Emit code to initialize FTOP, the top of the FPR save area.
@@ -4972,18 +4976,18 @@ mips_va_start (tree valist, rtx nextarg)
if (fpr_offset)
t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (ftop), t,
size_int (-fpr_offset));
- t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (ftop), ftop, t);
+ t = build2 (MODIFY_EXPR, TREE_TYPE (ftop), ftop, t);
expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
/* Emit code to initialize GOFF, the offset from GTOP of the
next GPR argument. */
- t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (goff), goff,
+ t = build2 (MODIFY_EXPR, TREE_TYPE (goff), goff,
build_int_cst (TREE_TYPE (goff), gpr_save_area_size));
expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
/* Likewise emit code to initialize FOFF, the offset from FTOP
of the next FPR argument. */
- t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (foff), foff,
+ t = build2 (MODIFY_EXPR, TREE_TYPE (foff), foff,
build_int_cst (TREE_TYPE (foff), fpr_save_area_size));
expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
}
@@ -4997,7 +5001,8 @@ mips_va_start (tree valist, rtx nextarg)
/* Implement TARGET_GIMPLIFY_VA_ARG_EXPR. */
static tree
-mips_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, tree *post_p)
+mips_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p,
+ gimple_seq *post_p)
{
tree addr;
bool indirect_p;
@@ -5096,8 +5101,7 @@ mips_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, tree *post_p)
/* [1] Emit code for: off &= -rsize. */
t = build2 (BIT_AND_EXPR, TREE_TYPE (off), off,
build_int_cst (NULL_TREE, -rsize));
- t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (off), off, t);
- gimplify_and_add (t, pre_p);
+ gimplify_assign (off, t, pre_p);
}
osize = rsize;
}
@@ -5133,7 +5137,7 @@ mips_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, tree *post_p)
u = size_int (-osize);
t = build2 (BIT_AND_EXPR, sizetype, t, u);
t = fold_convert (TREE_TYPE (ovfl), t);
- align = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (ovfl), ovfl, t);
+ align = build2 (MODIFY_EXPR, TREE_TYPE (ovfl), ovfl, t);
}
else
align = NULL;
@@ -12333,8 +12337,14 @@ mips_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
}
/* The last argument passed to mips_set_mips16_mode, or negative if the
- function hasn't been called yet. */
-static GTY(()) int was_mips16_p = -1;
+ function hasn't been called yet.
+
+ There are two copies of this information. One is saved and restored
+ by the PCH process while the other is specific to this compiler
+ invocation. The information calculated by mips_set_mips16_mode
+ is invalid unless the two variables are the same. */
+static int was_mips16_p = -1;
+static GTY(()) int was_mips16_pch_p = -1;
/* Set up the target-dependent global state so that it matches the
current function's ISA mode. */
@@ -12342,7 +12352,8 @@ static GTY(()) int was_mips16_p = -1;
static void
mips_set_mips16_mode (int mips16_p)
{
- if (mips16_p == was_mips16_p)
+ if (mips16_p == was_mips16_p
+ && mips16_p == was_mips16_pch_p)
return;
/* Restore base settings of various flags. */
@@ -12417,11 +12428,12 @@ mips_set_mips16_mode (int mips16_p)
/* (Re)initialize MIPS target internals for new ISA. */
mips_init_relocs ();
- if (was_mips16_p >= 0)
+ if (was_mips16_p >= 0 || was_mips16_pch_p >= 0)
/* Reinitialize target-dependent state. */
target_reinit ();
was_mips16_p = mips16_p;
+ was_mips16_pch_p = mips16_p;
}
/* Implement TARGET_SET_CURRENT_FUNCTION. Decide whether the current
@@ -12627,6 +12639,10 @@ mips_override_options (void)
{
int i, start, regno, mode;
+ /* Process flags as though we were generating non-MIPS16 code. */
+ mips_base_mips16 = TARGET_MIPS16;
+ target_flags &= ~MASK_MIPS16;
+
#ifdef SUBTARGET_OVERRIDE_OPTIONS
SUBTARGET_OVERRIDE_OPTIONS;
#endif
@@ -12772,14 +12788,6 @@ mips_override_options (void)
target_flags &= ~MASK_ABICALLS;
}
- /* MIPS16 cannot generate PIC yet. */
- if (TARGET_MIPS16 && (flag_pic || TARGET_ABICALLS))
- {
- sorry ("MIPS16 PIC");
- target_flags &= ~MASK_ABICALLS;
- flag_pic = flag_pie = flag_shlib = 0;
- }
-
if (TARGET_ABICALLS)
/* We need to set flag_pic for executables as well as DSOs
because we may reference symbols that are not defined in
@@ -12807,7 +12815,7 @@ mips_override_options (void)
{
if (!TARGET_GPOPT)
{
- if (!TARGET_MIPS16 && !TARGET_EXPLICIT_RELOCS)
+ if (!TARGET_EXPLICIT_RELOCS)
error ("%<-mno-gpopt%> needs %<-mexplicit-relocs%>");
TARGET_LOCAL_SDATA = false;
@@ -12911,7 +12919,6 @@ mips_override_options (void)
target_flags |= MASK_FIX_R4400;
/* Save base state of options. */
- mips_base_mips16 = TARGET_MIPS16;
mips_base_target_flags = target_flags;
mips_base_delayed_branch = flag_delayed_branch;
mips_base_schedule_insns = flag_schedule_insns;
@@ -12921,8 +12928,11 @@ mips_override_options (void)
mips_base_align_jumps = align_jumps;
mips_base_align_functions = align_functions;
- /* Now select the ISA mode. */
- mips_set_mips16_mode (mips_base_mips16);
+ /* Now select the ISA mode.
+
+ Do all CPP-sensitive stuff in non-MIPS16 mode; we'll switch to
+ MIPS16 mode afterwards if need be. */
+ mips_set_mips16_mode (false);
/* We call dbr_schedule from within mips_reorg. */
flag_delayed_branch = 0;
diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h
index 781528d01ba..8518a86233b 100644
--- a/gcc/config/mips/mips.h
+++ b/gcc/config/mips/mips.h
@@ -390,7 +390,7 @@ enum mips_code_readable_setting {
else \
builtin_define ("__mips_fpr=32"); \
\
- if (TARGET_MIPS16) \
+ if (mips_base_mips16) \
builtin_define ("__mips16"); \
\
if (TARGET_MIPS3D) \
@@ -3232,6 +3232,7 @@ extern int mips_abi; /* which ABI to use */
extern const struct mips_cpu_info *mips_arch_info;
extern const struct mips_cpu_info *mips_tune_info;
extern const struct mips_rtx_cost_data *mips_cost;
+extern bool mips_base_mips16;
extern enum mips_code_readable_setting mips_code_readable;
#endif
diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md
index 6b2f5fac64d..43c47e5883c 100644
--- a/gcc/config/mips/mips.md
+++ b/gcc/config/mips/mips.md
@@ -69,6 +69,7 @@
(UNSPEC_ADDRESS_FIRST 100)
+ (TLS_GET_TP_REGNUM 3)
(GOT_VERSION_REGNUM 79)
;; For MIPS Paired-Singled Floating Point Instructions.
@@ -6499,26 +6500,47 @@
[(set_attr "type" "arith")
(set_attr "extended_mips16" "yes")])
-; Thread-Local Storage
-
-; The TLS base pointer is accessed via "rdhwr $v1, $29". No current
-; MIPS architecture defines this register, and no current
-; implementation provides it; instead, any OS which supports TLS is
-; expected to trap and emulate this instruction. rdhwr is part of the
-; MIPS 32r2 specification, but we use it on any architecture because
-; we expect it to be emulated. Use .set to force the assembler to
-; accept it.
-
-(define_insn "tls_get_tp_<mode>"
- [(set (match_operand:P 0 "register_operand" "=v")
- (unspec:P [(const_int 0)]
- UNSPEC_TLS_GET_TP))]
+;; Thread-Local Storage
+
+;; The TLS base pointer is accessed via "rdhwr $3, $29". No current
+;; MIPS architecture defines this register, and no current
+;; implementation provides it; instead, any OS which supports TLS is
+;; expected to trap and emulate this instruction. rdhwr is part of the
+;; MIPS 32r2 specification, but we use it on any architecture because
+;; we expect it to be emulated. Use .set to force the assembler to
+;; accept it.
+;;
+;; We do not use a constraint to force the destination to be $3
+;; because $3 can appear explicitly as a function return value.
+;; If we leave the use of $3 implicit in the constraints until
+;; reload, we may end up making a $3 return value live across
+;; the instruction, leading to a spill failure when reloading it.
+(define_insn_and_split "tls_get_tp_<mode>"
+ [(set (match_operand:P 0 "register_operand" "=d")
+ (unspec:P [(const_int 0)] UNSPEC_TLS_GET_TP))
+ (clobber (reg:P TLS_GET_TP_REGNUM))]
"HAVE_AS_TLS && !TARGET_MIPS16"
- ".set\tpush\;.set\tmips32r2\t\;rdhwr\t%0,$29\;.set\tpop"
+ "#"
+ "&& reload_completed"
+ [(set (reg:P TLS_GET_TP_REGNUM)
+ (unspec:P [(const_int 0)] UNSPEC_TLS_GET_TP))
+ (set (match_dup 0) (reg:P TLS_GET_TP_REGNUM))]
+ ""
[(set_attr "type" "unknown")
; Since rdhwr always generates a trap for now, putting it in a delay
; slot would make the kernel's emulation of it much slower.
(set_attr "can_delay" "no")
+ (set_attr "mode" "<MODE>")
+ (set_attr "length" "8")])
+
+(define_insn "*tls_get_tp_<mode>_split"
+ [(set (reg:P TLS_GET_TP_REGNUM)
+ (unspec:P [(const_int 0)] UNSPEC_TLS_GET_TP))]
+ "HAVE_AS_TLS && !TARGET_MIPS16"
+ ".set\tpush\;.set\tmips32r2\t\;rdhwr\t$3,$29\;.set\tpop"
+ [(set_attr "type" "unknown")
+ ; See tls_get_tp_<mode>
+ (set_attr "can_delay" "no")
(set_attr "mode" "<MODE>")])
; The MIPS Paired-Single Floating Point and MIPS-3D Instructions.
diff --git a/gcc/config/mn10300/mn10300.h b/gcc/config/mn10300/mn10300.h
index 1d2339b6b15..07035fbb06b 100644
--- a/gcc/config/mn10300/mn10300.h
+++ b/gcc/config/mn10300/mn10300.h
@@ -295,6 +295,19 @@ enum reg_class {
{ 0xffffffff, 0x3ffff } /* ALL_REGS */ \
}
+/* The following macro defines cover classes for Integrated Register
+ Allocator. Cover classes is a set of non-intersected register
+ classes covering all hard registers used for register allocation
+ purpose. Any move between two registers of a cover class should be
+ cheaper than load or store of the registers. The macro value is
+ array of register classes with LIM_REG_CLASSES used as the end
+ marker. */
+
+#define IRA_COVER_CLASSES \
+{ \
+ GENERAL_REGS, FP_REGS, LIM_REG_CLASSES \
+}
+
/* The same information, inverted:
Return the class number of the smallest class containing
reg number REGNO. This could be a conditional expression
diff --git a/gcc/config/mn10300/mn10300.md b/gcc/config/mn10300/mn10300.md
index 73043e99b1a..8fbbdc87df5 100644
--- a/gcc/config/mn10300/mn10300.md
+++ b/gcc/config/mn10300/mn10300.md
@@ -115,8 +115,8 @@
[(set_attr "cc" "none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
(define_insn ""
- [(set (match_operand:QI 0 "nonimmediate_operand" "=d*a,d,d*a,d,m")
- (match_operand:QI 1 "general_operand" "0,I,dai,m,d"))]
+ [(set (match_operand:QI 0 "nonimmediate_operand" "=d*a,d,d,!*a,d*a,d,m")
+ (match_operand:QI 1 "general_operand" "0,I,i,i,da,m,d"))]
"register_operand (operands[0], QImode)
|| register_operand (operands[1], QImode)"
"*
@@ -128,6 +128,8 @@
case 1:
return \"clr %0\";
case 2:
+ case 3:
+ case 4:
if (GET_CODE (operands[1]) == CONST_DOUBLE)
{
rtx xoperands[2];
@@ -138,14 +140,14 @@
}
return \"mov %1,%0\";
- case 3:
- case 4:
+ case 5:
+ case 6:
return \"movbu %1,%0\";
default:
gcc_unreachable ();
}
}"
- [(set_attr "cc" "none,clobber,none_0hit,none_0hit,none_0hit")])
+ [(set_attr "cc" "none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
;; movhi
@@ -208,8 +210,8 @@
[(set_attr "cc" "none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
(define_insn ""
- [(set (match_operand:HI 0 "nonimmediate_operand" "=d*a,d,d*a,d,m")
- (match_operand:HI 1 "general_operand" "0,I,dai,m,d"))]
+ [(set (match_operand:HI 0 "nonimmediate_operand" "=d*a,d,d,!*a,d*a,d,m")
+ (match_operand:HI 1 "general_operand" "0,I,i,i,da,m,d"))]
"register_operand (operands[0], HImode)
|| register_operand (operands[1], HImode)"
"*
@@ -221,6 +223,8 @@
case 1:
return \"clr %0\";
case 2:
+ case 3:
+ case 4:
if (GET_CODE (operands[1]) == CONST_DOUBLE)
{
rtx xoperands[2];
@@ -230,14 +234,14 @@
return \"\";
}
return \"mov %1,%0\";
- case 3:
- case 4:
+ case 5:
+ case 6:
return \"movhu %1,%0\";
default:
gcc_unreachable ();
}
}"
- [(set_attr "cc" "none,clobber,none_0hit,none_0hit,none_0hit")])
+ [(set_attr "cc" "none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
;; movsi and helpers
diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c
index 238d35276e4..76d84bad092 100644
--- a/gcc/config/pa/pa.c
+++ b/gcc/config/pa/pa.c
@@ -1,6 +1,6 @@
/* Subroutines for insn-output.c for HPPA.
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
- 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
+ 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
Contributed by Tim Moore (moore@cs.utah.edu), based on sparc.c
This file is part of GCC.
@@ -125,7 +125,7 @@ static void pa_asm_out_destructor (rtx, int);
static void pa_init_builtins (void);
static rtx hppa_builtin_saveregs (void);
static void hppa_va_start (tree, rtx);
-static tree hppa_gimplify_va_arg_expr (tree, tree, tree *, tree *);
+static tree hppa_gimplify_va_arg_expr (tree, tree, gimple_seq *, gimple_seq *);
static bool pa_scalar_mode_supported_p (enum machine_mode);
static bool pa_commutative_p (const_rtx x, int outer_code);
static void copy_fp_args (rtx) ATTRIBUTE_UNUSED;
@@ -5998,7 +5998,8 @@ hppa_va_start (tree valist, rtx nextarg)
}
static tree
-hppa_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, tree *post_p)
+hppa_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p,
+ gimple_seq *post_p)
{
if (TARGET_64BIT)
{
diff --git a/gcc/config/rs6000/host-darwin.c b/gcc/config/rs6000/host-darwin.c
index bb50f0edfd3..333f4884e1b 100644
--- a/gcc/config/rs6000/host-darwin.c
+++ b/gcc/config/rs6000/host-darwin.c
@@ -1,5 +1,6 @@
/* Darwin/powerpc host-specific hook definitions.
- Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
+ Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008
+ Free Software Foundation, Inc.
This file is part of GCC.
@@ -138,7 +139,7 @@ darwin_rs6000_extra_signals (void)
struct sigaction sact;
stack_t sigstk;
- sigstk.ss_sp = xmalloc (SIGSTKSZ);
+ sigstk.ss_sp = (char*)xmalloc (SIGSTKSZ);
sigstk.ss_size = SIGSTKSZ;
sigstk.ss_flags = 0;
if (sigaltstack (&sigstk, NULL) < 0)
diff --git a/gcc/config/rs6000/rs6000-c.c b/gcc/config/rs6000/rs6000-c.c
index d0830bba7e0..76c92352b57 100644
--- a/gcc/config/rs6000/rs6000-c.c
+++ b/gcc/config/rs6000/rs6000-c.c
@@ -84,6 +84,149 @@ rs6000_pragma_longcall (cpp_reader *pfile ATTRIBUTE_UNUSED)
#define builtin_define(TXT) cpp_define (pfile, TXT)
#define builtin_assert(TXT) cpp_assert (pfile, TXT)
+/* Keep the AltiVec keywords handy for fast comparisons. */
+static GTY(()) tree __vector_keyword;
+static GTY(()) tree vector_keyword;
+static GTY(()) tree __pixel_keyword;
+static GTY(()) tree pixel_keyword;
+static GTY(()) tree __bool_keyword;
+static GTY(()) tree bool_keyword;
+
+/* Preserved across calls. */
+static tree expand_bool_pixel;
+
+static cpp_hashnode *
+altivec_categorize_keyword (const cpp_token *tok)
+{
+ if (tok->type == CPP_NAME)
+ {
+ cpp_hashnode *ident = tok->val.node;
+
+ if (ident == C_CPP_HASHNODE (vector_keyword)
+ || ident == C_CPP_HASHNODE (__vector_keyword))
+ return C_CPP_HASHNODE (__vector_keyword);
+
+ if (ident == C_CPP_HASHNODE (pixel_keyword)
+ || ident == C_CPP_HASHNODE (__pixel_keyword))
+ return C_CPP_HASHNODE (__pixel_keyword);
+
+ if (ident == C_CPP_HASHNODE (bool_keyword)
+ || ident == C_CPP_HASHNODE (__bool_keyword))
+ return C_CPP_HASHNODE (__bool_keyword);
+
+ return ident;
+ }
+
+ return 0;
+}
+
+static void
+init_vector_keywords (void)
+{
+ /* Keywords without two leading underscores are context-sensitive,
+ and hence implemented as conditional macros, controlled by the
+ rs6000_macro_to_expand() function below. */
+
+ __vector_keyword = get_identifier ("__vector");
+ C_CPP_HASHNODE (__vector_keyword)->flags |= NODE_CONDITIONAL;
+
+ __pixel_keyword = get_identifier ("__pixel");
+ C_CPP_HASHNODE (__pixel_keyword)->flags |= NODE_CONDITIONAL;
+
+ __bool_keyword = get_identifier ("__bool");
+ C_CPP_HASHNODE (__bool_keyword)->flags |= NODE_CONDITIONAL;
+
+ vector_keyword = get_identifier ("vector");
+ C_CPP_HASHNODE (vector_keyword)->flags |= NODE_CONDITIONAL;
+
+ pixel_keyword = get_identifier ("pixel");
+ C_CPP_HASHNODE (pixel_keyword)->flags |= NODE_CONDITIONAL;
+
+ bool_keyword = get_identifier ("bool");
+ C_CPP_HASHNODE (bool_keyword)->flags |= NODE_CONDITIONAL;
+}
+
+/* Called to decide whether a conditional macro should be expanded.
+ Since we have exactly one such macro (i.e, 'vector'), we do not
+ need to examine the 'tok' parameter. */
+
+static cpp_hashnode *
+rs6000_macro_to_expand (cpp_reader *pfile, const cpp_token *tok)
+{
+ cpp_hashnode *expand_this = tok->val.node;
+ cpp_hashnode *ident;
+
+ ident = altivec_categorize_keyword (tok);
+
+ if (ident == C_CPP_HASHNODE (__vector_keyword))
+ {
+ tok = cpp_peek_token (pfile, 0);
+ ident = altivec_categorize_keyword (tok);
+
+ if (ident == C_CPP_HASHNODE (__pixel_keyword))
+ {
+ expand_this = C_CPP_HASHNODE (__vector_keyword);
+ expand_bool_pixel = __pixel_keyword;
+ }
+ else if (ident == C_CPP_HASHNODE (__bool_keyword))
+ {
+ expand_this = C_CPP_HASHNODE (__vector_keyword);
+ expand_bool_pixel = __bool_keyword;
+ }
+ else if (ident)
+ {
+ enum rid rid_code = (enum rid)(ident->rid_code);
+ if (ident->type == NT_MACRO)
+ {
+ (void)cpp_get_token (pfile);
+ tok = cpp_peek_token (pfile, 0);
+ ident = altivec_categorize_keyword (tok);
+ if (ident)
+ rid_code = (enum rid)(ident->rid_code);
+ }
+
+ if (rid_code == RID_UNSIGNED || rid_code == RID_LONG
+ || rid_code == RID_SHORT || rid_code == RID_SIGNED
+ || rid_code == RID_INT || rid_code == RID_CHAR
+ || rid_code == RID_FLOAT)
+ {
+ expand_this = C_CPP_HASHNODE (__vector_keyword);
+ /* If the next keyword is bool or pixel, it
+ will need to be expanded as well. */
+ tok = cpp_peek_token (pfile, 1);
+ ident = altivec_categorize_keyword (tok);
+
+ if (ident == C_CPP_HASHNODE (__pixel_keyword))
+ expand_bool_pixel = __pixel_keyword;
+ else if (ident == C_CPP_HASHNODE (__bool_keyword))
+ expand_bool_pixel = __bool_keyword;
+ else
+ {
+ /* Try two tokens down, too. */
+ tok = cpp_peek_token (pfile, 2);
+ ident = altivec_categorize_keyword (tok);
+ if (ident == C_CPP_HASHNODE (__pixel_keyword))
+ expand_bool_pixel = __pixel_keyword;
+ else if (ident == C_CPP_HASHNODE (__bool_keyword))
+ expand_bool_pixel = __bool_keyword;
+ }
+ }
+ }
+ }
+ else if (expand_bool_pixel && ident == C_CPP_HASHNODE (__pixel_keyword))
+ {
+ expand_this = C_CPP_HASHNODE (__pixel_keyword);
+ expand_bool_pixel = 0;
+ }
+ else if (expand_bool_pixel && ident == C_CPP_HASHNODE (__bool_keyword))
+ {
+ expand_this = C_CPP_HASHNODE (__bool_keyword);
+ expand_bool_pixel = 0;
+ }
+
+ return expand_this;
+}
+
void
rs6000_cpu_cpp_builtins (cpp_reader *pfile)
{
@@ -120,6 +263,20 @@ rs6000_cpu_cpp_builtins (cpp_reader *pfile)
builtin_define ("__vector=__attribute__((altivec(vector__)))");
builtin_define ("__pixel=__attribute__((altivec(pixel__))) unsigned short");
builtin_define ("__bool=__attribute__((altivec(bool__))) unsigned");
+
+ if (!flag_iso)
+ {
+ /* Define this when supporting context-sensitive keywords. */
+ builtin_define ("__APPLE_ALTIVEC__");
+
+ builtin_define ("vector=vector");
+ builtin_define ("pixel=pixel");
+ builtin_define ("bool=bool");
+ init_vector_keywords ();
+
+ /* Enable context-sensitive macros. */
+ cpp_get_callbacks (pfile)->macro_to_expand = rs6000_macro_to_expand;
+ }
}
if (TARGET_SPE)
builtin_define ("__SPE__");
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 214b6922b5c..0e03be0fe2a 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -52,7 +52,7 @@
#include "reload.h"
#include "cfglayout.h"
#include "sched-int.h"
-#include "tree-gimple.h"
+#include "gimple.h"
#include "tree-flow.h"
#include "intl.h"
#include "params.h"
@@ -958,7 +958,7 @@ static void rs6000_darwin_file_start (void);
static tree rs6000_build_builtin_va_list (void);
static void rs6000_va_start (tree, rtx);
-static tree rs6000_gimplify_va_arg (tree, tree, tree *, tree *);
+static tree rs6000_gimplify_va_arg (tree, tree, gimple_seq *, gimple_seq *);
static bool rs6000_must_pass_in_stack (enum machine_mode, const_tree);
static bool rs6000_scalar_mode_supported_p (enum machine_mode);
static bool rs6000_vector_mode_supported_p (enum machine_mode);
@@ -1493,19 +1493,20 @@ rs6000_override_options (const char *default_cpu)
{"power3", PROCESSOR_PPC630,
POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
{"power4", PROCESSOR_POWER4,
- POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_MFCRF | MASK_POWERPC64},
+ POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
+ | MASK_MFCRF},
{"power5", PROCESSOR_POWER5,
- POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GFXOPT
+ POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
| MASK_MFCRF | MASK_POPCNTB},
{"power5+", PROCESSOR_POWER5,
- POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GFXOPT
+ POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
| MASK_MFCRF | MASK_POPCNTB | MASK_FPRND},
{"power6", PROCESSOR_POWER6,
- POWERPC_7400_MASK | MASK_POWERPC64 | MASK_MFCRF | MASK_POPCNTB
- | MASK_FPRND | MASK_CMPB | MASK_DFP },
+ POWERPC_7400_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_MFCRF
+ | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP},
{"power6x", PROCESSOR_POWER6,
- POWERPC_7400_MASK | MASK_POWERPC64 | MASK_MFCRF | MASK_POPCNTB
- | MASK_FPRND | MASK_CMPB | MASK_MFPGPR | MASK_DFP },
+ POWERPC_7400_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_MFCRF
+ | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP | MASK_MFPGPR},
{"powerpc", PROCESSOR_POWERPC, POWERPC_BASE_MASK},
{"powerpc64", PROCESSOR_POWERPC64,
POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
@@ -2110,7 +2111,7 @@ optimization_options (int level ATTRIBUTE_UNUSED, int size ATTRIBUTE_UNUSED)
Skip section anchors for Objective C and Objective C++
until front-ends fixed. */
if (!TARGET_MACHO && lang_hooks.name[4] != 'O')
- flag_section_anchors = 1;
+ flag_section_anchors = 2;
}
/* Implement TARGET_HANDLE_OPTION. */
@@ -6712,9 +6713,12 @@ rs6000_va_start (tree valist, rtx nextarg)
valist = build_va_arg_indirect_ref (valist);
gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
- fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr, NULL_TREE);
- ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf, NULL_TREE);
- sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav, 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;
@@ -6730,7 +6734,7 @@ rs6000_va_start (tree valist, rtx nextarg)
if (cfun->va_list_gpr_size)
{
- t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (gpr), gpr,
+ 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);
@@ -6738,7 +6742,7 @@ rs6000_va_start (tree valist, rtx nextarg)
if (cfun->va_list_fpr_size)
{
- t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (fpr), fpr,
+ 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);
@@ -6749,7 +6753,7 @@ rs6000_va_start (tree valist, rtx nextarg)
if (words != 0)
t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (ovf), t,
size_int (words * UNITS_PER_WORD));
- t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (ovf), ovf, t);
+ t = build2 (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
TREE_SIDE_EFFECTS (t) = 1;
expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
@@ -6766,7 +6770,7 @@ rs6000_va_start (tree valist, rtx nextarg)
if (cfun->machine->varargs_save_offset)
t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (sav), t,
size_int (cfun->machine->varargs_save_offset));
- t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (sav), sav, t);
+ t = build2 (MODIFY_EXPR, TREE_TYPE (sav), sav, t);
TREE_SIDE_EFFECTS (t) = 1;
expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
}
@@ -6774,7 +6778,8 @@ rs6000_va_start (tree valist, rtx nextarg)
/* Implement va_arg. */
tree
-rs6000_gimplify_va_arg (tree valist, tree type, tree *pre_p, tree *post_p)
+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;
@@ -6783,6 +6788,7 @@ rs6000_gimplify_va_arg (tree valist, tree type, tree *pre_p, tree *post_p)
int align;
tree ptrtype = build_pointer_type (type);
int regalign = 0;
+ gimple stmt;
if (pass_by_reference (NULL, TYPE_MODE (type), type, false))
{
@@ -6801,14 +6807,14 @@ rs6000_gimplify_va_arg (tree valist, tree type, tree *pre_p, tree *post_p)
if (elem_size < UNITS_PER_WORD)
{
tree real_part, imag_part;
- tree post = NULL_TREE;
+ 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);
- append_to_statement_list (post, pre_p);
+ gimple_seq_add_seq (pre_p, post);
imag_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
post_p);
@@ -6828,9 +6834,12 @@ rs6000_gimplify_va_arg (tree valist, tree type, tree *pre_p, tree *post_p)
valist = build_va_arg_indirect_ref (valist);
gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
- fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr, NULL_TREE);
- ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf, NULL_TREE);
- sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav, 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;
@@ -6884,18 +6893,19 @@ rs6000_gimplify_va_arg (tree valist, tree type, tree *pre_p, tree *post_p)
if (n_reg == 2 && reg == gpr)
{
regalign = 1;
- u = build2 (BIT_AND_EXPR, TREE_TYPE (reg), reg,
+ 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), reg, u);
+ 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 && TYPE_MODE (type) == TDmode)
{
regalign = 1;
- t = build2 (BIT_IOR_EXPR, TREE_TYPE (reg), reg,
+ 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, reg, t);
+ u = build2 (MODIFY_EXPR, void_type_node, unshare_expr (reg), t);
}
t = fold_convert (TREE_TYPE (reg), size_int (8 - n_reg + 1));
@@ -6908,7 +6918,7 @@ rs6000_gimplify_va_arg (tree valist, tree type, tree *pre_p, tree *post_p)
if (sav_ofs)
t = build2 (POINTER_PLUS_EXPR, ptr_type_node, sav, size_int (sav_ofs));
- u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg), reg,
+ 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));
@@ -6921,22 +6931,18 @@ rs6000_gimplify_va_arg (tree valist, tree type, tree *pre_p, tree *post_p)
&& TYPE_MODE (type) == SDmode)
t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
- t = build2 (GIMPLE_MODIFY_STMT, void_type_node, addr, t);
- gimplify_and_add (t, pre_p);
+ gimplify_assign (addr, t, pre_p);
- t = build1 (GOTO_EXPR, void_type_node, lab_over);
- gimplify_and_add (t, pre_p);
+ gimple_seq_add_stmt (pre_p, gimple_build_goto (lab_over));
- t = build1 (LABEL_EXPR, void_type_node, lab_false);
- append_to_statement_list (t, pre_p);
+ 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. */
- t = build_gimple_modify_stmt (reg,
- build_int_cst (TREE_TYPE (reg), 8));
- gimplify_and_add (t, pre_p);
+ gimplify_assign (reg, build_int_cst (TREE_TYPE (reg), 8), pre_p);
}
}
@@ -6954,17 +6960,15 @@ rs6000_gimplify_va_arg (tree valist, tree type, tree *pre_p, tree *post_p)
}
gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue);
- u = build2 (GIMPLE_MODIFY_STMT, void_type_node, addr, t);
- gimplify_and_add (u, pre_p);
+ gimplify_assign (unshare_expr (addr), t, pre_p);
t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
- t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (ovf), ovf, t);
- gimplify_and_add (t, pre_p);
+ gimplify_assign (unshare_expr (ovf), t, pre_p);
if (lab_over)
{
- t = build1 (LABEL_EXPR, void_type_node, lab_over);
- append_to_statement_list (t, pre_p);
+ stmt = gimple_build_label (lab_over);
+ gimple_seq_add_stmt (pre_p, stmt);
}
if (STRICT_ALIGNMENT
@@ -11320,15 +11324,14 @@ rs6000_alloc_sdmode_stack_slot (void)
{
tree t;
basic_block bb;
- block_stmt_iterator bsi;
+ gimple_stmt_iterator gsi;
gcc_assert (cfun->machine->sdmode_stack_slot == NULL_RTX);
FOR_EACH_BB (bb)
- for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
- tree ret = walk_tree_without_duplicates (bsi_stmt_ptr (bsi),
- rs6000_check_sdmode, NULL);
+ tree ret = walk_gimple_op (gsi_stmt (gsi), rs6000_check_sdmode, NULL);
if (ret)
{
rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
@@ -12288,9 +12291,13 @@ print_operand (FILE *file, rtx x, int code)
fprintf (file, "0,%s", reg_names[REGNO (tmp)]);
else
{
- gcc_assert (GET_CODE (tmp) == PLUS
- && REG_P (XEXP (tmp, 0))
- && REG_P (XEXP (tmp, 1)));
+ if (!GET_CODE (tmp) == PLUS
+ || !REG_P (XEXP (tmp, 0))
+ || !REG_P (XEXP (tmp, 1)))
+ {
+ output_operand_lossage ("invalid %%y value, try using the 'Z' constraint");
+ break;
+ }
if (REGNO (XEXP (tmp, 0)) == 0)
fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ],
diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c
index b9f231729a6..3c7d92b3c8d 100644
--- a/gcc/config/s390/s390.c
+++ b/gcc/config/s390/s390.c
@@ -50,7 +50,7 @@ along with GCC; see the file COPYING3. If not see
#include "debug.h"
#include "langhooks.h"
#include "optabs.h"
-#include "tree-gimple.h"
+#include "gimple.h"
#include "df.h"
@@ -3026,6 +3026,14 @@ s390_secondary_reload (bool in_p, rtx x, enum reg_class class,
}
}
+ /* A scratch address register is needed when a symbolic constant is
+ copied to r0 compiling with -fPIC. In other cases the target
+ register might be used as temporary (see legitimize_pic_address). */
+ if (in_p && SYMBOLIC_CONST (x) && flag_pic == 2 && class != ADDR_REGS)
+ sri->icode = (TARGET_64BIT ?
+ CODE_FOR_reloaddi_PIC_addr :
+ CODE_FOR_reloadsi_PIC_addr);
+
/* Either scratch or no register needed. */
return NO_REGS;
}
@@ -3272,7 +3280,10 @@ legitimize_pic_address (rtx orig, rtx reg)
/* If the GOT offset might be >= 4k, we determine the position
of the GOT entry via a PC-relative LARL (@GOTENT). */
- rtx temp = gen_reg_rtx (Pmode);
+ rtx temp = reg ? reg : gen_reg_rtx (Pmode);
+
+ gcc_assert (REGNO (temp) >= FIRST_PSEUDO_REGISTER
+ || REGNO_REG_CLASS (REGNO (temp)) == ADDR_REGS);
new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTENT);
new = gen_rtx_CONST (Pmode, new);
@@ -3287,7 +3298,10 @@ legitimize_pic_address (rtx orig, rtx reg)
/* If the GOT offset might be >= 4k, we have to load it
from the literal pool (@GOT). */
- rtx temp = gen_reg_rtx (Pmode);
+ rtx temp = reg ? reg : gen_reg_rtx (Pmode);
+
+ gcc_assert (REGNO (temp) >= FIRST_PSEUDO_REGISTER
+ || REGNO_REG_CLASS (REGNO (temp)) == ADDR_REGS);
if (reload_in_progress || reload_completed)
df_set_regs_ever_live (PIC_OFFSET_TABLE_REGNUM, true);
@@ -3707,7 +3721,10 @@ legitimize_tls_address (rtx addr, rtx reg)
return new;
}
-/* Emit insns to move operands[1] into operands[0]. */
+/* Emit insns making the address in operands[1] valid for a standard
+ move to operands[0]. operands[1] is replaced by an address which
+ should be used instead of the former RTX to emit the move
+ pattern. */
void
emit_symbolic_move (rtx *operands)
@@ -8407,15 +8424,15 @@ s390_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED)
if (cfun->va_list_gpr_size)
{
- t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (gpr), gpr,
- build_int_cst (NULL_TREE, n_gpr));
+ 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 (GIMPLE_MODIFY_STMT, TREE_TYPE (fpr), fpr,
+ 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);
@@ -8435,7 +8452,7 @@ s390_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED)
t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (ovf), t, size_int (off));
- t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (ovf), ovf, t);
+ t = build2 (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
TREE_SIDE_EFFECTS (t) = 1;
expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
}
@@ -8448,7 +8465,7 @@ s390_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED)
t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (sav), t,
size_int (-RETURN_REGNUM * UNITS_PER_WORD));
- t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (sav), sav, t);
+ t = build2 (MODIFY_EXPR, TREE_TYPE (sav), sav, t);
TREE_SIDE_EFFECTS (t) = 1;
expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
}
@@ -8479,8 +8496,8 @@ s390_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED)
} */
static tree
-s390_gimplify_va_arg (tree valist, tree type, tree *pre_p,
- tree *post_p ATTRIBUTE_UNUSED)
+s390_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
+ gimple_seq *post_p ATTRIBUTE_UNUSED)
{
tree f_gpr, f_fpr, f_ovf, f_sav;
tree gpr, fpr, ovf, sav, reg, t, u;
@@ -8495,9 +8512,13 @@ s390_gimplify_va_arg (tree valist, tree type, tree *pre_p,
valist = build_va_arg_indirect_ref (valist);
gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr, NULL_TREE);
- ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf, NULL_TREE);
sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav, NULL_TREE);
+ /* The tree for args* cannot be shared between gpr/fpr and ovf since
+ both appear on a lhs. */
+ valist = unshare_expr (valist);
+ ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf, NULL_TREE);
+
size = int_size_in_bytes (type);
if (pass_by_reference (NULL, TYPE_MODE (type), type, false))
@@ -8581,14 +8602,11 @@ s390_gimplify_va_arg (tree valist, tree type, tree *pre_p,
fold_convert (TREE_TYPE (reg), size_int (sav_scale)));
t = build2 (POINTER_PLUS_EXPR, ptr_type_node, t, fold_convert (sizetype, u));
- t = build2 (GIMPLE_MODIFY_STMT, void_type_node, addr, t);
- gimplify_and_add (t, pre_p);
+ gimplify_assign (addr, t, pre_p);
- t = build1 (GOTO_EXPR, void_type_node, lab_over);
- gimplify_and_add (t, pre_p);
+ gimple_seq_add_stmt (pre_p, gimple_build_goto (lab_over));
- t = build1 (LABEL_EXPR, void_type_node, lab_false);
- append_to_statement_list (t, pre_p);
+ gimple_seq_add_stmt (pre_p, gimple_build_label (lab_false));
/* ... Otherwise out of the overflow area. */
@@ -8600,16 +8618,13 @@ s390_gimplify_va_arg (tree valist, tree type, tree *pre_p,
gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue);
- u = build2 (GIMPLE_MODIFY_STMT, void_type_node, addr, t);
- gimplify_and_add (u, pre_p);
+ gimplify_assign (addr, t, pre_p);
t = build2 (POINTER_PLUS_EXPR, ptr_type_node, t,
size_int (size));
- t = build2 (GIMPLE_MODIFY_STMT, ptr_type_node, ovf, t);
- gimplify_and_add (t, pre_p);
+ gimplify_assign (ovf, t, pre_p);
- t = build1 (LABEL_EXPR, void_type_node, lab_over);
- append_to_statement_list (t, pre_p);
+ gimple_seq_add_stmt (pre_p, gimple_build_label (lab_over));
/* Increment register save count. */
diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md
index d33cc5c3267..ec5b7532977 100644
--- a/gcc/config/s390/s390.md
+++ b/gcc/config/s390/s390.md
@@ -1175,6 +1175,16 @@
DONE;
})
+(define_expand "reload<mode>_PIC_addr"
+ [(parallel [(match_operand 0 "register_operand" "=d")
+ (match_operand 1 "larl_operand" "")
+ (match_operand:P 2 "register_operand" "=a")])]
+ ""
+{
+ rtx new = legitimize_pic_address (operands[1], operands[2]);
+ emit_move_insn (operands[0], new);
+})
+
;
; movdi instruction pattern(s).
;
diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c
index 380705104ee..c7b8f582062 100644
--- a/gcc/config/sh/sh.c
+++ b/gcc/config/sh/sh.c
@@ -51,7 +51,7 @@ along with GCC; see the file COPYING3. If not see
#include "intl.h"
#include "sched-int.h"
#include "ggc.h"
-#include "tree-gimple.h"
+#include "gimple.h"
#include "cfgloop.h"
#include "alloc-pool.h"
#include "tm-constrs.h"
@@ -260,8 +260,9 @@ static void sh_setup_incoming_varargs (CUMULATIVE_ARGS *, enum machine_mode, tre
static bool sh_strict_argument_naming (CUMULATIVE_ARGS *);
static bool sh_pretend_outgoing_varargs_named (CUMULATIVE_ARGS *);
static tree sh_build_builtin_va_list (void);
+static tree sh_canonical_va_list_type (tree);
static void sh_va_start (tree, rtx);
-static tree sh_gimplify_va_arg_expr (tree, tree, tree *, tree *);
+static tree sh_gimplify_va_arg_expr (tree, tree, gimple_seq *, gimple_seq *);
static bool sh_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
const_tree, bool);
static bool sh_callee_copies (CUMULATIVE_ARGS *, enum machine_mode,
@@ -441,6 +442,8 @@ static int sh2a_function_vector_p (tree);
#undef TARGET_BUILD_BUILTIN_VA_LIST
#define TARGET_BUILD_BUILTIN_VA_LIST sh_build_builtin_va_list
+#undef TARGET_CANONICAL_VA_LIST_TYPE
+#define TARGET_CANONICAL_VA_LIST_TYPE sh_canonical_va_list_type
#undef TARGET_EXPAND_BUILTIN_VA_START
#define TARGET_EXPAND_BUILTIN_VA_START sh_va_start
#undef TARGET_GIMPLIFY_VA_ARG_EXPR
@@ -7145,6 +7148,14 @@ sh_build_builtin_va_list (void)
return record;
}
+/* Return always va_list_type_node. */
+
+static tree
+sh_canonical_va_list_type (tree type ATTRIBUTE_UNUSED)
+{
+ return va_list_type_node;
+}
+
/* Implement `va_start' for varargs and stdarg. */
static void
@@ -7189,7 +7200,7 @@ sh_va_start (tree valist, rtx nextarg)
/* Call __builtin_saveregs. */
u = make_tree (sizetype, expand_builtin_saveregs ());
u = fold_convert (ptr_type_node, u);
- t = build2 (GIMPLE_MODIFY_STMT, ptr_type_node, next_fp, u);
+ t = build2 (MODIFY_EXPR, ptr_type_node, next_fp, u);
TREE_SIDE_EFFECTS (t) = 1;
expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
@@ -7200,11 +7211,11 @@ sh_va_start (tree valist, rtx nextarg)
nfp = 0;
u = fold_build2 (POINTER_PLUS_EXPR, ptr_type_node, u,
size_int (UNITS_PER_WORD * nfp));
- t = build2 (GIMPLE_MODIFY_STMT, ptr_type_node, next_fp_limit, u);
+ t = build2 (MODIFY_EXPR, ptr_type_node, next_fp_limit, u);
TREE_SIDE_EFFECTS (t) = 1;
expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
- t = build2 (GIMPLE_MODIFY_STMT, ptr_type_node, next_o, u);
+ t = build2 (MODIFY_EXPR, ptr_type_node, next_o, u);
TREE_SIDE_EFFECTS (t) = 1;
expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
@@ -7215,12 +7226,12 @@ sh_va_start (tree valist, rtx nextarg)
nint = 0;
u = fold_build2 (POINTER_PLUS_EXPR, ptr_type_node, u,
size_int (UNITS_PER_WORD * nint));
- t = build2 (GIMPLE_MODIFY_STMT, ptr_type_node, next_o_limit, u);
+ t = build2 (MODIFY_EXPR, ptr_type_node, next_o_limit, u);
TREE_SIDE_EFFECTS (t) = 1;
expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
u = make_tree (ptr_type_node, nextarg);
- t = build2 (GIMPLE_MODIFY_STMT, ptr_type_node, next_stack, u);
+ t = build2 (MODIFY_EXPR, ptr_type_node, next_stack, u);
TREE_SIDE_EFFECTS (t) = 1;
expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
}
@@ -7249,8 +7260,8 @@ find_sole_member (tree type)
/* Implement `va_arg'. */
static tree
-sh_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p,
- tree *post_p ATTRIBUTE_UNUSED)
+sh_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p,
+ gimple_seq *post_p ATTRIBUTE_UNUSED)
{
HOST_WIDE_INT size, rsize;
tree tmp, pptr_type_node;
@@ -7340,11 +7351,9 @@ sh_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p,
bool is_double = size == 8 && TREE_CODE (eff_type) == REAL_TYPE;
tmp = build1 (ADDR_EXPR, pptr_type_node, next_fp);
- tmp = build2 (GIMPLE_MODIFY_STMT, void_type_node, addr, tmp);
- gimplify_and_add (tmp, pre_p);
+ gimplify_assign (addr, tmp, pre_p);
- tmp = build2 (GIMPLE_MODIFY_STMT, ptr_type_node, next_fp_tmp, valist);
- gimplify_and_add (tmp, pre_p);
+ gimplify_assign (next_fp_tmp, valist, pre_p);
tmp = next_fp_limit;
if (size > 4 && !is_double)
tmp = build2 (POINTER_PLUS_EXPR, TREE_TYPE (tmp), tmp,
@@ -7364,9 +7373,7 @@ sh_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p,
size_int (UNITS_PER_WORD));
tmp = build2 (POINTER_PLUS_EXPR, ptr_type_node,
next_fp_tmp, tmp);
- tmp = build2 (GIMPLE_MODIFY_STMT, ptr_type_node,
- next_fp_tmp, tmp);
- gimplify_and_add (tmp, pre_p);
+ gimplify_assign (next_fp_tmp, tmp, pre_p);
}
if (is_double)
gimplify_and_add (cmp, pre_p);
@@ -7398,13 +7405,10 @@ sh_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p,
gimplify_and_add (tmp, pre_p);
tmp = build1 (ADDR_EXPR, pptr_type_node, next_stack);
- tmp = build2 (GIMPLE_MODIFY_STMT, void_type_node, addr, tmp);
- gimplify_and_add (tmp, pre_p);
- tmp = build2 (GIMPLE_MODIFY_STMT, ptr_type_node, next_fp_tmp, valist);
- gimplify_and_add (tmp, pre_p);
+ gimplify_assign (addr, tmp, pre_p);
+ gimplify_assign (next_fp_tmp, valist, pre_p);
- tmp = build2 (GIMPLE_MODIFY_STMT, ptr_type_node, valist, next_fp_tmp);
- gimplify_and_add (tmp, post_p);
+ gimplify_assign (valist, next_fp_tmp, post_p);
valist = next_fp_tmp;
}
else
@@ -7418,8 +7422,7 @@ sh_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p,
gimplify_and_add (tmp, pre_p);
tmp = build1 (ADDR_EXPR, pptr_type_node, next_o);
- tmp = build2 (GIMPLE_MODIFY_STMT, void_type_node, addr, tmp);
- gimplify_and_add (tmp, pre_p);
+ gimplify_assign (addr, tmp, pre_p);
tmp = build1 (GOTO_EXPR, void_type_node, lab_over);
gimplify_and_add (tmp, pre_p);
@@ -7428,15 +7431,10 @@ sh_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p,
gimplify_and_add (tmp, pre_p);
if (size > 4 && ! (TARGET_SH4 || TARGET_SH2A))
- {
- tmp = build2 (GIMPLE_MODIFY_STMT, ptr_type_node,
- next_o, next_o_limit);
- gimplify_and_add (tmp, pre_p);
- }
+ gimplify_assign (next_o, next_o_limit, pre_p);
tmp = build1 (ADDR_EXPR, pptr_type_node, next_stack);
- tmp = build2 (GIMPLE_MODIFY_STMT, void_type_node, addr, tmp);
- gimplify_and_add (tmp, pre_p);
+ gimplify_assign (addr, tmp, pre_p);
}
if (!result)
@@ -7452,8 +7450,7 @@ sh_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p,
tmp = std_gimplify_va_arg_expr (valist, type, pre_p, NULL);
if (result)
{
- tmp = build2 (GIMPLE_MODIFY_STMT, void_type_node, result, tmp);
- gimplify_and_add (tmp, pre_p);
+ gimplify_assign (result, tmp, pre_p);
tmp = build1 (LABEL_EXPR, void_type_node, lab_over);
gimplify_and_add (tmp, pre_p);
diff --git a/gcc/config/sh/sh.h b/gcc/config/sh/sh.h
index 2059c460b11..8af2f436169 100644
--- a/gcc/config/sh/sh.h
+++ b/gcc/config/sh/sh.h
@@ -1,6 +1,6 @@
/* Definitions of target machine for GNU compiler for Renesas / SuperH SH.
Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
- 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
+ 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
Contributed by Steve Chamberlain (sac@cygnus.com).
Improved by Jim Wilson (wilson@cygnus.com).
@@ -463,7 +463,7 @@ do { \
do { \
if (LEVEL) \
{ \
- flag_omit_frame_pointer = -1; \
+ flag_omit_frame_pointer = 2; \
if (! SIZE) \
sh_div_str = "inv:minlat"; \
} \
@@ -690,7 +690,7 @@ do { \
if (! VALID_REGISTER_P (ADDREGNAMES_REGNO (regno))) \
sh_additional_register_names[regno][0] = '\0'; \
\
- if (flag_omit_frame_pointer < 0) \
+ if (flag_omit_frame_pointer == 2) \
{ \
/* The debugging information is sufficient, \
but gdb doesn't implement this yet */ \
@@ -712,8 +712,8 @@ do { \
to the pressure on R0. */ \
/* Enable sched1 for SH4; ready queue will be reordered by \
the target hooks when pressure is high. We can not do this for \
- SH3 and lower as they give spill failures for R0. */ \
- if (!TARGET_HARD_SH4) \
+ PIC, SH3 and lower as they give spill failures for R0. */ \
+ if (!TARGET_HARD_SH4 || flag_pic) \
flag_schedule_insns = 0; \
/* ??? Current exception handling places basic block boundaries \
after call_insns. It causes the high pressure on R0 and gives \
diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md
index 95f436f642a..b6e56aa5a5e 100644
--- a/gcc/config/sh/sh.md
+++ b/gcc/config/sh/sh.md
@@ -8883,9 +8883,6 @@ label:
/* ??? Should we have a special alias set for the GOT? */
insn = emit_move_insn (operands[0], mem);
- set_unique_reg_note (insn, REG_EQUAL,
- XVECEXP (XEXP (operands[1], 0), 0, 0));
-
DONE;
}")
diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index 5e6f5748672..adf28c027b1 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -48,7 +48,7 @@ along with GCC; see the file COPYING3. If not see
#include "target.h"
#include "target-def.h"
#include "cfglayout.h"
-#include "tree-gimple.h"
+#include "gimple.h"
#include "langhooks.h"
#include "params.h"
#include "df.h"
@@ -410,7 +410,7 @@ static rtx sparc_struct_value_rtx (tree, int);
static bool sparc_return_in_memory (const_tree, const_tree);
static bool sparc_strict_argument_naming (CUMULATIVE_ARGS *);
static void sparc_va_start (tree, rtx);
-static tree sparc_gimplify_va_arg (tree, tree, tree *, tree *);
+static tree sparc_gimplify_va_arg (tree, tree, gimple_seq *, gimple_seq *);
static bool sparc_vector_mode_supported_p (enum machine_mode);
static bool sparc_pass_by_reference (CUMULATIVE_ARGS *,
enum machine_mode, const_tree, bool);
@@ -5709,7 +5709,8 @@ sparc_va_start (tree valist, rtx nextarg)
/* Implement `va_arg' for stdarg. */
static tree
-sparc_gimplify_va_arg (tree valist, tree type, tree *pre_p, tree *post_p)
+sparc_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
+ gimple_seq *post_p)
{
HOST_WIDE_INT size, rsize, align;
tree addr, incr;
@@ -5792,8 +5793,7 @@ sparc_gimplify_va_arg (tree valist, tree type, tree *pre_p, tree *post_p)
addr = fold_convert (ptrtype, addr);
incr = fold_build2 (POINTER_PLUS_EXPR, ptr_type_node, incr, size_int (rsize));
- incr = build2 (GIMPLE_MODIFY_STMT, ptr_type_node, valist, incr);
- gimplify_and_add (incr, post_p);
+ gimplify_assign (valist, incr, post_p);
return build_va_arg_indirect_ref (addr);
}
diff --git a/gcc/config/sparc/sparc.h b/gcc/config/sparc/sparc.h
index b88e3c78f67..42894705361 100644
--- a/gcc/config/sparc/sparc.h
+++ b/gcc/config/sparc/sparc.h
@@ -981,9 +981,12 @@ extern int sparc_mode_class[];
/* Pick a default value we can notice from override_options:
!v9: Default is on.
- v9: Default is off. */
+ v9: Default is off.
+ Originally it was -1, but later on the container of options changed to
+ unsigned byte, so we decided to pick 127 as default value, which does
+ reflect an undefined default value in case of 0/1. */
-#define DEFAULT_PCC_STRUCT_RETURN -1
+#define DEFAULT_PCC_STRUCT_RETURN 127
/* Functions which return large structures get the address
to place the wanted value at offset 64 from the frame.
diff --git a/gcc/config/spu/spu-c.c b/gcc/config/spu/spu-c.c
index 0b0d2e8743a..96fe43e6e94 100644
--- a/gcc/config/spu/spu-c.c
+++ b/gcc/config/spu/spu-c.c
@@ -35,6 +35,64 @@
#include "spu-builtins.h"
+/* Keep the vector keywords handy for fast comparisons. */
+static GTY(()) tree __vector_keyword;
+static GTY(()) tree vector_keyword;
+
+static cpp_hashnode *
+spu_categorize_keyword (const cpp_token *tok)
+{
+ if (tok->type == CPP_NAME)
+ {
+ cpp_hashnode *ident = tok->val.node;
+
+ if (ident == C_CPP_HASHNODE (vector_keyword)
+ || ident == C_CPP_HASHNODE (__vector_keyword))
+ return C_CPP_HASHNODE (__vector_keyword);
+ else
+ return ident;
+ }
+ return 0;
+}
+
+/* Called to decide whether a conditional macro should be expanded.
+ Since we have exactly one such macro (i.e, 'vector'), we do not
+ need to examine the 'tok' parameter. */
+
+static cpp_hashnode *
+spu_macro_to_expand (cpp_reader *pfile, const cpp_token *tok)
+{
+ cpp_hashnode *expand_this = tok->val.node;
+ cpp_hashnode *ident;
+
+ ident = spu_categorize_keyword (tok);
+ if (ident == C_CPP_HASHNODE (__vector_keyword))
+ {
+ tok = cpp_peek_token (pfile, 0);
+ ident = spu_categorize_keyword (tok);
+
+ if (ident)
+ {
+ enum rid rid_code = (enum rid)(ident->rid_code);
+ if (ident->type == NT_MACRO)
+ {
+ (void) cpp_get_token (pfile);
+ tok = cpp_peek_token (pfile, 0);
+ ident = spu_categorize_keyword (tok);
+ if (ident)
+ rid_code = (enum rid)(ident->rid_code);
+ }
+
+ if (rid_code == RID_UNSIGNED || rid_code == RID_LONG
+ || rid_code == RID_SHORT || rid_code == RID_SIGNED
+ || rid_code == RID_INT || rid_code == RID_CHAR
+ || rid_code == RID_FLOAT || rid_code == RID_DOUBLE)
+ expand_this = C_CPP_HASHNODE (__vector_keyword);
+ }
+ }
+ return expand_this;
+}
+
/* target hook for resolve_overloaded_builtin(). Returns a function call
RTX if we can resolve the overloaded builtin */
tree
@@ -140,6 +198,22 @@ spu_cpu_cpp_builtins (struct cpp_reader *pfile)
if (spu_arch == PROCESSOR_CELLEDP)
builtin_define_std ("__SPU_EDP__");
builtin_define_std ("__vector=__attribute__((__spu_vector__))");
+
+ if (!flag_iso)
+ {
+ /* Define this when supporting context-sensitive keywords. */
+ cpp_define (pfile, "__VECTOR_KEYWORD_SUPPORTED__");
+ cpp_define (pfile, "vector=vector");
+
+ /* Initialize vector keywords. */
+ __vector_keyword = get_identifier ("__vector");
+ C_CPP_HASHNODE (__vector_keyword)->flags |= NODE_CONDITIONAL;
+ vector_keyword = get_identifier ("vector");
+ C_CPP_HASHNODE (vector_keyword)->flags |= NODE_CONDITIONAL;
+
+ /* Enable context-sensitive macros. */
+ cpp_get_callbacks (pfile)->macro_to_expand = spu_macro_to_expand;
+ }
}
void
diff --git a/gcc/config/spu/spu.c b/gcc/config/spu/spu.c
index e645adb2281..83bd9f51315 100644
--- a/gcc/config/spu/spu.c
+++ b/gcc/config/spu/spu.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006, 2007 Free Software Foundation, Inc.
+/* Copyright (C) 2006, 2007, 2008 Free Software Foundation, Inc.
This file 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
@@ -50,7 +50,7 @@
#include "assert.h"
#include "c-common.h"
#include "machmode.h"
-#include "tree-gimple.h"
+#include "gimple.h"
#include "tm-constrs.h"
#include "spu-builtins.h"
#include "ddg.h"
@@ -118,8 +118,8 @@ static unsigned char spu_pass_by_reference (CUMULATIVE_ARGS *cum, enum machine_m
const_tree type, unsigned char named);
static tree spu_build_builtin_va_list (void);
static void spu_va_start (tree, rtx);
-static tree spu_gimplify_va_arg_expr (tree valist, tree type, tree * pre_p,
- tree * post_p);
+static tree spu_gimplify_va_arg_expr (tree valist, tree type,
+ gimple_seq * pre_p, gimple_seq * post_p);
static int regno_aligned_for_load (int regno);
static int store_with_one_insn_p (rtx mem);
static int mem_is_padded_component_ref (rtx x);
@@ -3238,7 +3238,7 @@ spu_va_start (tree valist, rtx nextarg)
if (crtl->args.pretend_args_size > 0)
t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (args), t,
size_int (-STACK_POINTER_OFFSET));
- t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (args), args, t);
+ t = build2 (MODIFY_EXPR, TREE_TYPE (args), args, t);
TREE_SIDE_EFFECTS (t) = 1;
expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
@@ -3247,7 +3247,7 @@ spu_va_start (tree valist, rtx nextarg)
t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (skip), t,
size_int (crtl->args.pretend_args_size
- STACK_POINTER_OFFSET));
- t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (skip), skip, t);
+ t = build2 (MODIFY_EXPR, TREE_TYPE (skip), skip, t);
TREE_SIDE_EFFECTS (t) = 1;
expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
}
@@ -3270,8 +3270,8 @@ spu_va_start (tree valist, rtx nextarg)
ret = *(TYPE *)addr;
*/
static tree
-spu_gimplify_va_arg_expr (tree valist, tree type, tree * pre_p,
- tree * post_p ATTRIBUTE_UNUSED)
+spu_gimplify_va_arg_expr (tree valist, tree type, gimple_seq * pre_p,
+ gimple_seq * post_p ATTRIBUTE_UNUSED)
{
tree f_args, f_skip;
tree args, skip;
@@ -3303,22 +3303,21 @@ spu_gimplify_va_arg_expr (tree valist, tree type, tree * pre_p,
/* build conditional expression to calculate addr. The expression
will be gimplified later. */
paddedsize = size_int (rsize);
- tmp = build2 (POINTER_PLUS_EXPR, ptr_type_node, args, paddedsize);
+ tmp = build2 (POINTER_PLUS_EXPR, ptr_type_node, unshare_expr (args), paddedsize);
tmp = build2 (TRUTH_AND_EXPR, boolean_type_node,
- build2 (GT_EXPR, boolean_type_node, tmp, skip),
- build2 (LE_EXPR, boolean_type_node, args, skip));
+ build2 (GT_EXPR, boolean_type_node, tmp, unshare_expr (skip)),
+ build2 (LE_EXPR, boolean_type_node, unshare_expr (args),
+ unshare_expr (skip)));
tmp = build3 (COND_EXPR, ptr_type_node, tmp,
- build2 (POINTER_PLUS_EXPR, ptr_type_node, skip,
- size_int (32)), args);
+ build2 (POINTER_PLUS_EXPR, ptr_type_node, unshare_expr (skip),
+ size_int (32)), unshare_expr (args));
- tmp = build2 (GIMPLE_MODIFY_STMT, ptr_type_node, addr, tmp);
- gimplify_and_add (tmp, pre_p);
+ gimplify_assign (addr, tmp, pre_p);
/* update VALIST.__args */
tmp = build2 (POINTER_PLUS_EXPR, ptr_type_node, addr, paddedsize);
- tmp = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (args), args, tmp);
- gimplify_and_add (tmp, pre_p);
+ gimplify_assign (unshare_expr (args), tmp, pre_p);
addr = fold_convert (build_pointer_type (type), addr);
diff --git a/gcc/config/spu/spu.md b/gcc/config/spu/spu.md
index 6985a683697..c267efd29d1 100644
--- a/gcc/config/spu/spu.md
+++ b/gcc/config/spu/spu.md
@@ -1721,20 +1721,33 @@
[(set_attr "type" "multi0")
(set_attr "length" "80")])
-(define_insn_and_split "div<mode>3"
+(define_expand "div<mode>3"
+ [(parallel
+ [(set (match_operand:VSF 0 "spu_reg_operand" "")
+ (div:VSF (match_operand:VSF 1 "spu_reg_operand" "")
+ (match_operand:VSF 2 "spu_reg_operand" "")))
+ (clobber (match_scratch:VSF 3 ""))
+ (clobber (match_scratch:VSF 4 ""))
+ (clobber (match_scratch:VSF 5 ""))])]
+ ""
+ "")
+
+(define_insn_and_split "*div<mode>3_fast"
[(set (match_operand:VSF 0 "spu_reg_operand" "=r")
(div:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
(match_operand:VSF 2 "spu_reg_operand" "r")))
(clobber (match_scratch:VSF 3 "=&r"))
- (clobber (match_scratch:VSF 4 "=&r"))]
- ""
+ (clobber (match_scratch:VSF 4 "=&r"))
+ (clobber (scratch:VSF))]
+ "flag_unsafe_math_optimizations"
"#"
"reload_completed"
[(set (match_dup:VSF 0)
(div:VSF (match_dup:VSF 1)
(match_dup:VSF 2)))
(clobber (match_dup:VSF 3))
- (clobber (match_dup:VSF 4))]
+ (clobber (match_dup:VSF 4))
+ (clobber (scratch:VSF))]
{
emit_insn (gen_frest_<mode>(operands[3], operands[2]));
emit_insn (gen_fi_<mode>(operands[3], operands[2], operands[3]));
@@ -1744,6 +1757,50 @@
DONE;
})
+(define_insn_and_split "*div<mode>3_adjusted"
+ [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
+ (div:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
+ (match_operand:VSF 2 "spu_reg_operand" "r")))
+ (clobber (match_scratch:VSF 3 "=&r"))
+ (clobber (match_scratch:VSF 4 "=&r"))
+ (clobber (match_scratch:VSF 5 "=&r"))]
+ "!flag_unsafe_math_optimizations"
+ "#"
+ "reload_completed"
+ [(set (match_dup:VSF 0)
+ (div:VSF (match_dup:VSF 1)
+ (match_dup:VSF 2)))
+ (clobber (match_dup:VSF 3))
+ (clobber (match_dup:VSF 4))
+ (clobber (match_dup:VSF 5))]
+ {
+ emit_insn (gen_frest_<mode> (operands[3], operands[2]));
+ emit_insn (gen_fi_<mode> (operands[3], operands[2], operands[3]));
+ emit_insn (gen_mul<mode>3 (operands[4], operands[1], operands[3]));
+ emit_insn (gen_fnms_<mode> (operands[5], operands[4], operands[2], operands[1]));
+ emit_insn (gen_fma_<mode> (operands[3], operands[5], operands[3], operands[4]));
+
+ /* Due to truncation error, the quotient result may be low by 1 ulp.
+ Conditionally add one if the estimate is too small in magnitude. */
+
+ emit_move_insn (gen_lowpart (<F2I>mode, operands[4]),
+ spu_const (<F2I>mode, 0x80000000ULL));
+ emit_move_insn (gen_lowpart (<F2I>mode, operands[5]),
+ spu_const (<F2I>mode, 0x3f800000ULL));
+ emit_insn (gen_selb (operands[5], operands[5], operands[1], operands[4]));
+
+ emit_insn (gen_add<f2i>3 (gen_lowpart (<F2I>mode, operands[4]),
+ gen_lowpart (<F2I>mode, operands[3]),
+ spu_const (<F2I>mode, 1)));
+ emit_insn (gen_fnms_<mode> (operands[0], operands[2], operands[4], operands[1]));
+ emit_insn (gen_mul<mode>3 (operands[0], operands[0], operands[5]));
+ emit_insn (gen_cgt_<f2i> (gen_lowpart (<F2I>mode, operands[0]),
+ gen_lowpart (<F2I>mode, operands[0]),
+ spu_const (<F2I>mode, -1)));
+ emit_insn (gen_selb (operands[0], operands[3], operands[4], operands[0]));
+ DONE;
+ })
+
;; Taken from STI's gcc
;; Does not correctly handle INF or NAN.
(define_expand "divdf3"
diff --git a/gcc/config/stormy16/stormy16.c b/gcc/config/stormy16/stormy16.c
index 6cbe52d5048..64ecec8f5e5 100644
--- a/gcc/config/stormy16/stormy16.c
+++ b/gcc/config/stormy16/stormy16.c
@@ -45,7 +45,7 @@ along with GCC; see the file COPYING3. If not see
#include "target-def.h"
#include "tm_p.h"
#include "langhooks.h"
-#include "tree-gimple.h"
+#include "gimple.h"
#include "df.h"
#include "ggc.h"
@@ -1350,11 +1350,11 @@ xstormy16_expand_builtin_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED)
u = build_int_cst (NULL_TREE, INCOMING_FRAME_SP_OFFSET);
u = fold_convert (TREE_TYPE (count), u);
t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (base), t, u);
- t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (base), base, t);
+ t = build2 (MODIFY_EXPR, TREE_TYPE (base), base, t);
TREE_SIDE_EFFECTS (t) = 1;
expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
- t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (count), count,
+ t = build2 (MODIFY_EXPR, TREE_TYPE (count), count,
build_int_cst (NULL_TREE,
crtl->args.info * UNITS_PER_WORD));
TREE_SIDE_EFFECTS (t) = 1;
@@ -1366,8 +1366,8 @@ xstormy16_expand_builtin_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED)
Note: This algorithm is documented in stormy-abi. */
static tree
-xstormy16_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p,
- tree *post_p ATTRIBUTE_UNUSED)
+xstormy16_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p,
+ gimple_seq *post_p ATTRIBUTE_UNUSED)
{
tree f_base, f_count;
tree base, count;
@@ -1408,8 +1408,7 @@ xstormy16_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p,
gimplify_and_add (t, pre_p);
t = build2 (POINTER_PLUS_EXPR, ptr_type_node, base, count_tmp);
- t = build2 (GIMPLE_MODIFY_STMT, void_type_node, addr, t);
- gimplify_and_add (t, pre_p);
+ gimplify_assign (addr, t, pre_p);
t = build1 (GOTO_EXPR, void_type_node, lab_gotaddr);
gimplify_and_add (t, pre_p);
@@ -1427,7 +1426,7 @@ xstormy16_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p,
tree r, u;
r = size_int (NUM_ARGUMENT_REGISTERS * UNITS_PER_WORD);
- u = build2 (GIMPLE_MODIFY_STMT, void_type_node, count_tmp, r);
+ u = build2 (MODIFY_EXPR, TREE_TYPE (count_tmp), count_tmp, r);
t = fold_convert (TREE_TYPE (count), r);
t = build2 (GE_EXPR, boolean_type_node, count_tmp, t);
@@ -1444,16 +1443,14 @@ xstormy16_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p,
t = fold_convert (TREE_TYPE (t), fold (t));
t = fold_build1 (NEGATE_EXPR, TREE_TYPE (t), t);
t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (base), base, t);
- t = build2 (GIMPLE_MODIFY_STMT, void_type_node, addr, t);
- gimplify_and_add (t, pre_p);
+ gimplify_assign (addr, t, pre_p);
t = build1 (LABEL_EXPR, void_type_node, lab_gotaddr);
gimplify_and_add (t, pre_p);
t = fold_convert (TREE_TYPE (count), size_tree);
t = build2 (PLUS_EXPR, TREE_TYPE (count), count_tmp, t);
- t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (count), count, t);
- gimplify_and_add (t, pre_p);
+ gimplify_assign (count, t, pre_p);
addr = fold_convert (build_pointer_type (type), addr);
return build_va_arg_indirect_ref (addr);
diff --git a/gcc/config/xtensa/libgcc-xtensa.ver b/gcc/config/xtensa/libgcc-xtensa.ver
new file mode 100644
index 00000000000..43e7d4fc7c7
--- /dev/null
+++ b/gcc/config/xtensa/libgcc-xtensa.ver
@@ -0,0 +1,3 @@
+GCC_4.3.0 {
+ __umulsidi3
+}
diff --git a/gcc/config/xtensa/t-linux b/gcc/config/xtensa/t-linux
index 7d39351fa66..7d535e155b4 100644
--- a/gcc/config/xtensa/t-linux
+++ b/gcc/config/xtensa/t-linux
@@ -1 +1,3 @@
EXTRA_MULTILIB_PARTS = crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o
+
+SHLIB_MAPFILES += $(srcdir)/config/xtensa/libgcc-xtensa.ver
diff --git a/gcc/config/xtensa/xtensa.c b/gcc/config/xtensa/xtensa.c
index 6e26d76daad..000df14854c 100644
--- a/gcc/config/xtensa/xtensa.c
+++ b/gcc/config/xtensa/xtensa.c
@@ -48,7 +48,7 @@ along with GCC; see the file COPYING3. If not see
#include "target.h"
#include "target-def.h"
#include "langhooks.h"
-#include "tree-gimple.h"
+#include "gimple.h"
#include "df.h"
@@ -142,7 +142,9 @@ static section *xtensa_select_rtx_section (enum machine_mode, rtx,
static bool xtensa_rtx_costs (rtx, int, int, int *);
static tree xtensa_build_builtin_va_list (void);
static bool xtensa_return_in_memory (const_tree, const_tree);
-static tree xtensa_gimplify_va_arg_expr (tree, tree, tree *, tree *);
+static tree xtensa_gimplify_va_arg_expr (tree, tree, gimple_seq *,
+ gimple_seq *);
+static rtx xtensa_function_value (const_tree, const_tree, bool);
static void xtensa_init_builtins (void);
static tree xtensa_fold_builtin (tree, tree, bool);
static rtx xtensa_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
@@ -192,6 +194,8 @@ static const int reg_nonleaf_alloc_order[FIRST_PSEUDO_REGISTER] =
#undef TARGET_RETURN_IN_MEMORY
#define TARGET_RETURN_IN_MEMORY xtensa_return_in_memory
+#undef TARGET_FUNCTION_VALUE
+#define TARGET_FUNCTION_VALUE xtensa_function_value
#undef TARGET_SPLIT_COMPLEX_ARG
#define TARGET_SPLIT_COMPLEX_ARG hook_bool_const_tree_true
#undef TARGET_MUST_PASS_IN_STACK
@@ -2535,14 +2539,14 @@ xtensa_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED)
/* Call __builtin_saveregs; save the result in __va_reg */
u = make_tree (sizetype, expand_builtin_saveregs ());
u = fold_convert (ptr_type_node, u);
- t = build2 (GIMPLE_MODIFY_STMT, ptr_type_node, reg, u);
+ t = build2 (MODIFY_EXPR, ptr_type_node, reg, u);
TREE_SIDE_EFFECTS (t) = 1;
expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
/* Set the __va_stk member to ($arg_ptr - 32). */
u = make_tree (ptr_type_node, virtual_incoming_args_rtx);
u = fold_build2 (POINTER_PLUS_EXPR, ptr_type_node, u, size_int (-32));
- t = build2 (GIMPLE_MODIFY_STMT, ptr_type_node, stk, u);
+ t = build2 (MODIFY_EXPR, ptr_type_node, stk, u);
TREE_SIDE_EFFECTS (t) = 1;
expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
@@ -2551,7 +2555,7 @@ xtensa_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED)
alignment offset for __va_stk. */
if (arg_words >= MAX_ARGS_IN_REGISTERS)
arg_words += 2;
- t = build2 (GIMPLE_MODIFY_STMT, integer_type_node, ndx,
+ t = build2 (MODIFY_EXPR, integer_type_node, ndx,
build_int_cst (integer_type_node, arg_words * UNITS_PER_WORD));
TREE_SIDE_EFFECTS (t) = 1;
expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
@@ -2561,8 +2565,8 @@ xtensa_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED)
/* Implement `va_arg'. */
static tree
-xtensa_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p,
- tree *post_p ATTRIBUTE_UNUSED)
+xtensa_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p,
+ gimple_seq *post_p ATTRIBUTE_UNUSED)
{
tree f_stk, stk;
tree f_reg, reg;
@@ -2621,8 +2625,7 @@ xtensa_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p,
build_int_cst (integer_type_node, align - 1));
t = build2 (BIT_AND_EXPR, integer_type_node, t,
build_int_cst (integer_type_node, -align));
- t = build2 (GIMPLE_MODIFY_STMT, integer_type_node, orig_ndx, t);
- gimplify_and_add (t, pre_p);
+ gimplify_assign (orig_ndx, t, pre_p);
}
@@ -2632,8 +2635,7 @@ xtensa_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p,
t = fold_convert (integer_type_node, va_size);
t = build2 (PLUS_EXPR, integer_type_node, orig_ndx, t);
- t = build2 (GIMPLE_MODIFY_STMT, integer_type_node, ndx, t);
- gimplify_and_add (t, pre_p);
+ gimplify_assign (ndx, t, pre_p);
/* Check if the argument is in registers:
@@ -2658,8 +2660,7 @@ xtensa_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p,
NULL_TREE);
gimplify_and_add (t, pre_p);
- t = build2 (GIMPLE_MODIFY_STMT, void_type_node, array, reg);
- gimplify_and_add (t, pre_p);
+ gimplify_assign (array, reg, pre_p);
t = build1 (GOTO_EXPR, void_type_node, lab_over);
gimplify_and_add (t, pre_p);
@@ -2691,14 +2692,12 @@ xtensa_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p,
t = size_binop (PLUS_EXPR, va_size, size_int (32));
t = fold_convert (integer_type_node, t);
- t = build2 (GIMPLE_MODIFY_STMT, integer_type_node, ndx, t);
- gimplify_and_add (t, pre_p);
+ gimplify_assign (ndx, t, pre_p);
t = build1 (LABEL_EXPR, void_type_node, lab_false2);
gimplify_and_add (t, pre_p);
- t = build2 (GIMPLE_MODIFY_STMT, void_type_node, array, stk);
- gimplify_and_add (t, pre_p);
+ gimplify_assign (array, stk, pre_p);
if (lab_over)
{
@@ -3163,6 +3162,17 @@ xtensa_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
> 4 * UNITS_PER_WORD);
}
+/* Worker function for TARGET_FUNCTION_VALUE. */
+
+rtx
+xtensa_function_value (const_tree valtype, const_tree func ATTRIBUTE_UNUSED,
+ bool outgoing)
+{
+ return gen_rtx_REG ((INTEGRAL_TYPE_P (valtype)
+ && TYPE_PRECISION (valtype) < BITS_PER_WORD)
+ ? SImode : TYPE_MODE (valtype),
+ outgoing ? GP_OUTGOING_RETURN : GP_RETURN);
+}
/* TRAMPOLINE_TEMPLATE: For Xtensa, the trampoline must perform an ENTRY
instruction with a minimal stack frame in order to get some free
diff --git a/gcc/config/xtensa/xtensa.h b/gcc/config/xtensa/xtensa.h
index eaef97e2094..920f9d2ef18 100644
--- a/gcc/config/xtensa/xtensa.h
+++ b/gcc/config/xtensa/xtensa.h
@@ -608,22 +608,6 @@ extern const enum reg_class xtensa_regno_to_class[FIRST_PSEUDO_REGISTER];
#define LIBCALL_OUTGOING_VALUE(MODE) \
XTENSA_LIBCALL_VALUE ((MODE), 1)
-/* Define how to find the value returned by a function.
- VALTYPE is the data type of the value (as a tree).
- If the precise function being called is known, FUNC is its FUNCTION_DECL;
- otherwise, FUNC is 0. */
-#define XTENSA_FUNCTION_VALUE(VALTYPE, FUNC, OUTGOINGP) \
- gen_rtx_REG ((INTEGRAL_TYPE_P (VALTYPE) \
- && TYPE_PRECISION (VALTYPE) < BITS_PER_WORD) \
- ? SImode: TYPE_MODE (VALTYPE), \
- OUTGOINGP ? GP_OUTGOING_RETURN : GP_RETURN)
-
-#define FUNCTION_VALUE(VALTYPE, FUNC) \
- XTENSA_FUNCTION_VALUE (VALTYPE, FUNC, 0)
-
-#define FUNCTION_OUTGOING_VALUE(VALTYPE, FUNC) \
- XTENSA_FUNCTION_VALUE (VALTYPE, FUNC, 1)
-
/* A C expression that is nonzero if REGNO is the number of a hard
register in which the values of called function may come back. A
register whose use for returning values is limited to serving as
diff --git a/gcc/configure b/gcc/configure
index f2b15d192e7..3293be1713e 100755
--- a/gcc/configure
+++ b/gcc/configure
@@ -1017,7 +1017,7 @@ Optional Features:
enable expensive run-time checks. With LIST,
enable only specific categories of checks.
Categories are: yes,no,all,none,release.
- Flags are: assert,df,fold,gc,gcac,misc,
+ Flags are: assert,df,fold,gc,gcac,gimple,misc,
rtlflag,rtl,runtime,tree,valgrind,types.
--enable-coverage=LEVEL
enable compiler's code coverage collection.
@@ -7015,7 +7015,7 @@ fi
loose_warn=
save_CFLAGS="$CFLAGS"
for option in -W -Wall -Wwrite-strings -Wstrict-prototypes \
- -Wmissing-prototypes -Wcast-qual -Wc++-compat; do
+ -Wmissing-prototypes -Wcast-qual; do
as_acx_Woption=`echo "acx_cv_prog_cc_warning_$option" | $as_tr_sh`
echo "$as_me:$LINENO: checking whether $CC supports $option" >&5
@@ -7082,7 +7082,7 @@ CFLAGS="$save_CFLAGS"
strict_warn=
save_CFLAGS="$CFLAGS"
-for option in -Wold-style-definition \
+for option in -Wold-style-definition -Wc++-compat \
-Wmissing-format-attribute; do
as_acx_Woption=`echo "acx_cv_prog_cc_warning_$option" | $as_tr_sh`
@@ -7266,25 +7266,25 @@ do
# these set all the flags to specific states
yes) ac_assert_checking=1 ; ac_checking=1 ; ac_df_checking= ;
ac_fold_checking= ; ac_gc_checking=1 ;
- ac_gc_always_collect= ; ac_rtl_checking= ;
+ ac_gc_always_collect= ; ac_gimple_checking=1 ; ac_rtl_checking= ;
ac_rtlflag_checking=1 ; ac_runtime_checking=1 ;
ac_tree_checking=1 ; ac_valgrind_checking= ;
ac_types_checking=1 ;;
no|none) ac_assert_checking= ; ac_checking= ; ac_df_checking= ;
ac_fold_checking= ; ac_gc_checking= ;
- ac_gc_always_collect= ; ac_rtl_checking= ;
+ ac_gc_always_collect= ; ac_gimple_checking= ; ac_rtl_checking= ;
ac_rtlflag_checking= ; ac_runtime_checking= ;
ac_tree_checking= ; ac_valgrind_checking= ;
ac_types_checking= ;;
all) ac_assert_checking=1 ; ac_checking=1 ; ac_df_checking=1 ;
ac_fold_checking=1 ; ac_gc_checking=1 ;
- ac_gc_always_collect=1 ; ac_rtl_checking=1 ;
+ ac_gc_always_collect=1 ; ac_gimple_checking=1 ; ac_rtl_checking=1 ;
ac_rtlflag_checking=1 ; ac_runtime_checking=1 ;
ac_tree_checking=1 ; ac_valgrind_checking= ;
ac_types_checking=1 ;;
release) ac_assert_checking=1 ; ac_checking= ; ac_df_checking= ;
ac_fold_checking= ; ac_gc_checking= ;
- ac_gc_always_collect= ; ac_rtl_checking= ;
+ ac_gc_always_collect= ; ac_gimple_checking= ; ac_rtl_checking= ;
ac_rtlflag_checking= ; ac_runtime_checking=1 ;
ac_tree_checking= ; ac_valgrind_checking= ;
ac_types_checking= ;;
@@ -7294,6 +7294,7 @@ do
fold) ac_fold_checking=1 ;;
gc) ac_gc_checking=1 ;;
gcac) ac_gc_always_collect=1 ;;
+ gimple) ac_gimple_checking=1 ;;
misc) ac_checking=1 ;;
rtl) ac_rtl_checking=1 ;;
rtlflag) ac_rtlflag_checking=1 ;;
@@ -7332,6 +7333,13 @@ cat >>confdefs.h <<\_ACEOF
_ACEOF
fi
+if test x$ac_gimple_checking != x ; then
+
+cat >>confdefs.h <<\_ACEOF
+#define ENABLE_GIMPLE_CHECKING 1
+_ACEOF
+
+fi
if test x$ac_runtime_checking != x ; then
@@ -8541,7 +8549,7 @@ else
case $ac_prog_version in
'') gcc_cv_prog_makeinfo_modern=no;;
- 4.[4-9]*|4.[1-9][0-9]*|[5-9]*|[1-9][0-9]*) gcc_cv_prog_makeinfo_modern=yes;;
+ 4.[7-9]*|4.[1-9][0-9]*|[5-9]*|[1-9][0-9]*) gcc_cv_prog_makeinfo_modern=yes;;
*) gcc_cv_prog_makeinfo_modern=no;;
esac
@@ -10097,10 +10105,8 @@ fi
-
-
for ac_func in times clock kill getrlimit setrlimit atoll atoq \
- sysconf strsignal getrusage nl_langinfo scandir alphasort \
+ sysconf strsignal getrusage nl_langinfo \
gettimeofday mbstowcs wcswidth mmap mincore setlocale \
clearerr_unlocked feof_unlocked ferror_unlocked fflush_unlocked fgetc_unlocked fgets_unlocked fileno_unlocked fprintf_unlocked fputc_unlocked fputs_unlocked fread_unlocked fwrite_unlocked getchar_unlocked getc_unlocked putchar_unlocked putc_unlocked
do
@@ -10326,6 +10332,72 @@ _ACEOF
fi
+echo "$as_me:$LINENO: checking for caddr_t" >&5
+echo $ECHO_N "checking for caddr_t... $ECHO_C" >&6
+if test "${ac_cv_type_caddr_t+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+if ((caddr_t *) 0)
+ return 0;
+if (sizeof (caddr_t))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_type_caddr_t=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_caddr_t=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_caddr_t" >&5
+echo "${ECHO_T}$ac_cv_type_caddr_t" >&6
+if test $ac_cv_type_caddr_t = yes; then
+ :
+else
+
+cat >>confdefs.h <<_ACEOF
+#define caddr_t char *
+_ACEOF
+
+fi
+
# Try to determine the array type of the second argument of getgroups
# for the target system (int or gid_t).
@@ -14659,13 +14731,13 @@ if test "${lt_cv_nm_interface+set}" = set; then
else
lt_cv_nm_interface="BSD nm"
echo "int some_variable = 0;" > conftest.$ac_ext
- (eval echo "\"\$as_me:14662: $ac_compile\"" >&5)
+ (eval echo "\"\$as_me:14734: $ac_compile\"" >&5)
(eval "$ac_compile" 2>conftest.err)
cat conftest.err >&5
- (eval echo "\"\$as_me:14665: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
+ (eval echo "\"\$as_me:14737: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
(eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
cat conftest.err >&5
- (eval echo "\"\$as_me:14668: output\"" >&5)
+ (eval echo "\"\$as_me:14740: output\"" >&5)
cat conftest.out >&5
if $GREP 'External.*some_variable' conftest.out > /dev/null; then
lt_cv_nm_interface="MS dumpbin"
@@ -15720,7 +15792,7 @@ ia64-*-hpux*)
;;
*-*-irix6*)
# Find out which ABI we are using.
- echo '#line 15723 "configure"' > conftest.$ac_ext
+ echo '#line 15795 "configure"' > conftest.$ac_ext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>&5
ac_status=$?
@@ -16340,11 +16412,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:16343: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:16415: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:16347: \$? = $ac_status" >&5
+ echo "$as_me:16419: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
@@ -16662,11 +16734,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:16665: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:16737: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:16669: \$? = $ac_status" >&5
+ echo "$as_me:16741: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
@@ -16767,11 +16839,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:16770: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:16842: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
- echo "$as_me:16774: \$? = $ac_status" >&5
+ echo "$as_me:16846: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
@@ -16822,11 +16894,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:16825: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:16897: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
- echo "$as_me:16829: \$? = $ac_status" >&5
+ echo "$as_me:16901: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
@@ -19619,7 +19691,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 19622 "configure"
+#line 19694 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -19719,7 +19791,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 19722 "configure"
+#line 19794 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
diff --git a/gcc/configure.ac b/gcc/configure.ac
index 31b448720a2..6d266f285d9 100644
--- a/gcc/configure.ac
+++ b/gcc/configure.ac
@@ -323,8 +323,8 @@ AC_CHECK_TYPES([__int64], [AC_CHECK_SIZEOF(__int64)])
# So, we only use -pedantic if we can disable those warnings.
ACX_PROG_CC_WARNING_OPTS([-W -Wall -Wwrite-strings -Wstrict-prototypes \
- -Wmissing-prototypes -Wcast-qual -Wc++-compat], [loose_warn])
-ACX_PROG_CC_WARNING_OPTS([-Wold-style-definition \
+ -Wmissing-prototypes -Wcast-qual], [loose_warn])
+ACX_PROG_CC_WARNING_OPTS([-Wold-style-definition -Wc++-compat \
-Wmissing-format-attribute], [strict_warn])
ACX_PROG_CC_WARNING_ALMOST_PEDANTIC([-Wno-long-long -Wno-variadic-macros \
-Wno-overlength-strings], [strict_warn])
@@ -350,7 +350,7 @@ AC_ARG_ENABLE(checking,
enable expensive run-time checks. With LIST,
enable only specific categories of checks.
Categories are: yes,no,all,none,release.
- Flags are: assert,df,fold,gc,gcac,misc,
+ Flags are: assert,df,fold,gc,gcac,gimple,misc,
rtlflag,rtl,runtime,tree,valgrind,types.],
[ac_checking_flags="${enableval}"],[
# Determine the default checks.
@@ -366,25 +366,25 @@ do
# these set all the flags to specific states
yes) ac_assert_checking=1 ; ac_checking=1 ; ac_df_checking= ;
ac_fold_checking= ; ac_gc_checking=1 ;
- ac_gc_always_collect= ; ac_rtl_checking= ;
+ ac_gc_always_collect= ; ac_gimple_checking=1 ; ac_rtl_checking= ;
ac_rtlflag_checking=1 ; ac_runtime_checking=1 ;
ac_tree_checking=1 ; ac_valgrind_checking= ;
ac_types_checking=1 ;;
no|none) ac_assert_checking= ; ac_checking= ; ac_df_checking= ;
ac_fold_checking= ; ac_gc_checking= ;
- ac_gc_always_collect= ; ac_rtl_checking= ;
+ ac_gc_always_collect= ; ac_gimple_checking= ; ac_rtl_checking= ;
ac_rtlflag_checking= ; ac_runtime_checking= ;
ac_tree_checking= ; ac_valgrind_checking= ;
ac_types_checking= ;;
all) ac_assert_checking=1 ; ac_checking=1 ; ac_df_checking=1 ;
ac_fold_checking=1 ; ac_gc_checking=1 ;
- ac_gc_always_collect=1 ; ac_rtl_checking=1 ;
+ ac_gc_always_collect=1 ; ac_gimple_checking=1 ; ac_rtl_checking=1 ;
ac_rtlflag_checking=1 ; ac_runtime_checking=1 ;
ac_tree_checking=1 ; ac_valgrind_checking= ;
ac_types_checking=1 ;;
release) ac_assert_checking=1 ; ac_checking= ; ac_df_checking= ;
ac_fold_checking= ; ac_gc_checking= ;
- ac_gc_always_collect= ; ac_rtl_checking= ;
+ ac_gc_always_collect= ; ac_gimple_checking= ; ac_rtl_checking= ;
ac_rtlflag_checking= ; ac_runtime_checking=1 ;
ac_tree_checking= ; ac_valgrind_checking= ;
ac_types_checking= ;;
@@ -394,6 +394,7 @@ do
fold) ac_fold_checking=1 ;;
gc) ac_gc_checking=1 ;;
gcac) ac_gc_always_collect=1 ;;
+ gimple) ac_gimple_checking=1 ;;
misc) ac_checking=1 ;;
rtl) ac_rtl_checking=1 ;;
rtlflag) ac_rtlflag_checking=1 ;;
@@ -422,6 +423,12 @@ if test x$ac_assert_checking != x ; then
AC_DEFINE(ENABLE_ASSERT_CHECKING, 1,
[Define if you want assertions enabled. This is a cheap check.])
fi
+if test x$ac_gimple_checking != x ; then
+ AC_DEFINE(ENABLE_GIMPLE_CHECKING, 1,
+[Define if you want operations on GIMPLE (the basic data structure of
+the high-level optimizers) to be checked for dynamic type safety at
+runtime. This is moderately expensive.])
+fi
GCC_TARGET_TEMPLATE(ENABLE_RUNTIME_CHECKING)
if test x$ac_runtime_checking != x ; then
AC_DEFINE(ENABLE_RUNTIME_CHECKING, 1,
@@ -842,7 +849,7 @@ AC_CHECK_PROG(have_mktemp_command, mktemp, yes, no)
# that we can use it.
ACX_CHECK_PROG_VER(MAKEINFO, makeinfo, --version,
[GNU texinfo.* \([0-9][0-9.]*\)],
- [4.[4-9]*|4.[1-9][0-9]*|[5-9]*|[1-9][0-9]*])
+ [4.[7-9]*|4.[1-9][0-9]*|[5-9]*|[1-9][0-9]*])
if test $gcc_cv_prog_makeinfo_modern = no; then
AC_MSG_WARN([
*** Makeinfo is missing or too old.
@@ -987,7 +994,7 @@ define(gcc_UNLOCKED_FUNCS, clearerr_unlocked feof_unlocked dnl
fread_unlocked fwrite_unlocked getchar_unlocked getc_unlocked dnl
putchar_unlocked putc_unlocked)
AC_CHECK_FUNCS(times clock kill getrlimit setrlimit atoll atoq \
- sysconf strsignal getrusage nl_langinfo scandir alphasort \
+ sysconf strsignal getrusage nl_langinfo \
gettimeofday mbstowcs wcswidth mmap mincore setlocale \
gcc_UNLOCKED_FUNCS)
@@ -1010,6 +1017,7 @@ int main()
fi
AC_CHECK_TYPE(ssize_t, int)
+AC_CHECK_TYPE(caddr_t, char *)
# Try to determine the array type of the second argument of getgroups
# for the target system (int or gid_t).
diff --git a/gcc/coretypes.h b/gcc/coretypes.h
index 4fe480f781f..e1d66a52608 100644
--- a/gcc/coretypes.h
+++ b/gcc/coretypes.h
@@ -47,9 +47,20 @@ typedef struct rtvec_def *rtvec;
typedef const struct rtvec_def *const_rtvec;
union tree_node;
typedef union tree_node *tree;
+union gimple_statement_d;
+typedef union gimple_statement_d *gimple;
typedef const union tree_node *const_tree;
+typedef const union gimple_statement_d *const_gimple;
union section;
typedef union section section;
+struct cl_target_option;
+struct cl_optimization;
+struct gimple_seq_d;
+typedef struct gimple_seq_d *gimple_seq;
+typedef const struct gimple_seq_d *const_gimple_seq;
+struct gimple_seq_node_d;
+typedef struct gimple_seq_node_d *gimple_seq_node;
+typedef const struct gimple_seq_node_d *const_gimple_seq_node;
/* The major intermediate representations of GCC. */
enum ir_type {
@@ -60,9 +71,11 @@ enum ir_type {
/* Provide forward struct declaration so that we don't have to include
all of cpplib.h whenever a random prototype includes a pointer.
- Note that the cpp_reader typedef remains part of cpplib.h. */
+ Note that the cpp_reader and cpp_token typedefs remain part of
+ cpplib.h. */
struct cpp_reader;
+struct cpp_token;
/* The thread-local storage model associated with a given VAR_DECL
or SYMBOL_REF. This isn't used much, but both trees and RTL refer
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 5ef7e2e1005..ad2964cf403 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,423 @@
+2008-07-28 Richard Guenther <rguenther@suse.de>
+
+ Merge from gimple-tuples-branch.
+
+ 2008-07-22 Aldy Hernandez <aldyh@redhat.com>
+
+ * cp-gimplify.c (gimplify_if_stmt): Set location on newly created
+ COND_EXPR.
+
+ 2008-07-18 Jakub Jelinek <jakub@redhat.com>
+
+ * decl.c (finish_function): Call gimple_body after cp_genericize.
+
+ 2008-07-18 Aldy Hernandez <aldyh@redhat.com>
+
+ * optimize.c: Include gimple.h instead of tree-gimple.h.
+ * Make-lang.in (cp-gimplify.o): Depend on tree-iterator.h.
+ * cp-gimplify.c: Rename tree-gimple.h to gimple.h. Include
+ tree-iterator.h.
+
+ 2008-07-16 Jakub Jelinek <jakub@redhat.com>
+
+ * optimize.c (maybe_clone_body): Clear DECL_SAVED_TREE for the clone.
+
+ 2008-07-14 Jakub Jelinek <jakub@redhat.com>
+
+ * cp-gimplify.c (cp_gimplify_expr): Update comment.
+
+ 2008-07-14 Aldy Hernandez <aldyh@redhat.com>
+
+ * cp-tree.h (union lang_tree_node): Rename GENERIC_NEXT to
+ TREE_CHAIN.
+ * cp-gimplify.c (cxx_omp_clause_apply_fn): Rename
+ GIMPLE_MODIFY_STMT to MODIFY_EXPR.
+ (cxx_omp_clause_copy_ctor): Same.
+ (cxx_omp_clause_assign_op): Same.
+
+ 2008-05-28 Jakub Jelinek <jakub@redhat.com>
+
+ * cp-gimplify.c (cp_gimplify_omp_for): Add pre_p argument. Tuplify.
+ (cp_gimplify_expr): Adjust caller.
+
+ 2008-05-11 Doug Kwan <dougkwan@google.com>
+
+ * init.c (build_vec_delete): Add type conversion for argument
+ 0 of POINTER_PLUS_EXPR.
+
+ 2008-04-29 Doug Kwan <dougkwan@google.com>
+
+ * decl2 (File): Include "gimple.h"
+ (cp_write_global_declarations): Use gimple_body instead of
+ DECL_SAVED_TREE.
+ * Make-lang.in (cp/decl2.o): Add $(GIMPLE_H)
+
+ 2008-04-10 Diego Novillo <dnovillo@google.com>
+
+ http://gcc.gnu.org/ml/gcc-patches/2008-04/msg00913.html
+
+ * optimize.c (maybe_clone_body): Re-enable call to
+ clone_body.
+ * cp-gimplify.c (cp_gimplify_omp_for): Mark disabled
+ code with call to gimple_unreachable.
+ (cp_genericize): Fix handling of clone bodies.
+
+ 2008-04-04 Diego Novillo <dnovillo@google.com>
+
+ http://gcc.gnu.org/ml/gcc-patches/2008-04/msg00413.html
+
+ * optimize.c (maybe_clone_body): Re-enable.
+
+ 2008-02-19 Diego Novillo <dnovillo@google.com>
+ Oleg Ryjkov <olegr@google.com>
+
+ http://gcc.gnu.org/ml/gcc-patches/2008-02/msg00804.html
+
+ * cp-gimplify.c (gimplify_for_stmt): Change gimple_seq
+ argument to gimple_seq *. Update all users.
+ (gimplify_must_not_throw_expr): Likewise.
+
+ 2008-02-04 Oleg Ryjkov <olegr@google.com>
+
+ * except.c: Include gimple.h
+ (cp_protect_cleanup_actions): Convert to tuples.
+ * Make-lang.in (cp/except.o): Add dependency on gimple.h
+
+ 2007-11-10 Aldy Hernandez <aldyh@redhat.com>
+
+ * cp-gimplify.c (gimplify_cp_loop): Call tree_annotate_all_with_locus
+ instead of annotating each block manually.
+
+ 2007-10-30 Aldy Hernandez <aldyh@redhat.com>
+
+ * cp-gimplify.c (gimplify_cp_loop): Tuplify.
+ (gimplify_for_stmt): Same.
+ (gimplify_switch_stmt): Same.
+ (cp_gimplify_expr): [FOR_STMT]: Do not call gimplify_for_stmt. Return
+ GS_OK.
+ [WHILE_STMT]: Return GS_OK.
+ [SWITCH_STMT]: Same.
+ [CONTINUE_STMT]: Same.
+ [BREAK_STMT]: Same.
+ (cp_genericize): Set gimple_body() of cloned functions when needed.
+
+ 2007-10-29 Aldy Hernandez <aldy@quesejoda.com>
+
+ * cp-gimplify.c: Move build_gimple_eh_filter_tree here.
+ (cp_gimplify_init_expr): Convert to tuples.
+ (gimplify_must_not_throw_expr): Make function return a
+ gimplify_status and convert to tuples.
+
+ 2007-10-18 Aldy Hernandez <aldy@quesejoda.com>
+
+ * cp-gimplify.c (genericize_try_block): Enable and do not call
+ gimplify_stmt.
+ (genericize_catch_block): Same.
+ (genericize_eh_spec_block): Same.
+ Rename gimple_build_eh_filter_tree to build_gimple_eh_filter_tree.
+ (cp_gimplify_expr): Enable TRY_BLOCK, HANDLER, and EH_SPEC_BLOCK.
+
+ 2007-10-16 Aldy Hernandez <aldy@quesejoda.com>
+
+ * optimize.c (maybe_clone_body): Comment out call to clone_body.
+ * decl.c (finish_function): Use gimple_body instead of
+ DECL_SAVED_TREE.
+ * cp-tree.h (cp_gimplify_expr): Last 2 arguments are sequences.
+ * cp-gimplify.c (genericize_try_block): Comment out.
+ (genericize_catch_block): Same.
+ (genericize_eh_spec_block): Same.
+ (gimplify_cp_loop): Comment out calls to gimplify_stmt.
+ (gimplify_for_stmt): Comment out.
+ (gimplify_switch_stmt): Comment out call to gimplify_stmt.
+ (cp_gimplify_omp_for): Same.
+ (gimplify_must_not_throw_expr): Argument pre_p is a sequence.
+ Comment out call to gimplify_stmt and append_to_statement_list.
+ Rename gimple_build_eh_filter_tree to build_gimple_eh_filter_tree.
+ (cp_gimplify_init_expr): Arguments pre_p and post_p are sequences.
+ (cp_gimplify_expr): Same.
+ Comment out calls to genericize_*_block. Comment out call to
+ gimplify_for_stmt.
+
+2008-07-27 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR c++/36944
+ * class.c (type_has_user_provided_default_constructor): Handle
+ default parameters.
+
+2008-07-27 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * decl.c (push_library_fn): Add a parameter for the exceptions that
+ the function may throw.
+ (push_void_library_fn, push_throw_library_fn, expand_static_init):
+ Adjust.
+ (build_library_fn): Change to static.
+ * cp-tree.h: Adjust declarations.
+ * except.c (declare_nothrow_library_fn): New.
+ (do_get_exception_ptr, do_begin_catch, do_free_exception,
+ do_allocate_exception): Use the latter, adjust the declarations
+ (ie, add empty exception-specification), consistently with the
+ actual implementation in libsupc++.
+
+2008-07-25 Jan Hubicka <jh@suse.cz>
+
+ * typeck.c (inline_conversion): Remove.
+ (cp_build_function_call): Do not use inline_conversion.
+ * decl.c (duplicate_decls): Do not insist on inline being declared
+ early.
+ (start_cleanup_fn): Do not assume that INLINE flags prevent function
+ from being output. We now remove static functions always.
+ (finish_function): Do return warning on all static functions.
+ * call.c (build_over_call): Do not use inline_conversion.
+ * cp-tree.h (possibly_inlined_p): Declare.
+ (inline_conversion): Remove.
+ * pt.c (instantiate_decl): Use possibly_inlined_p predicate.
+ * decl2.c (cp_write_global_declarations): Likewise.
+ (mark_used): Likewise.
+ (possibly_inlined_p): New functions.
+
+2008-07-25 Jason Merrill <jason@redhat.com>
+
+ * class.c (type_has_user_provided_default_constructor): Handle
+ templates.
+
+2008-07-23 Jan Hubicka <jh@suse.cz>
+
+ * decl.c (duplicate_decls): Update comment and unit-at-a-time.
+ (grogfndecl): Drop flag_inline_trees code.
+ * pt.c (instantiate_decl): Drop flag_iline_trees code.
+ * lex.c (cxx_init): Do not set unit-at-a-time.
+
+2008-07-23 Jason Merrill <jason@redhat.com>
+
+ * mangle.c (write_unqualified_name): Avoid infinite recursion when
+ trying to mangle a decl with no name.
+
+ Implement defaulted/deleted functions as per N2346
+ * cp-tree.h (struct lang_decl_flags): Add defaulted_p bitfield.
+ (DECL_DELETED_FN): New macro.
+ (DECL_DEFAULTED_FN): New macro.
+ * class.c (user_provided_p): New fn.
+ (defaultable_fn_p): New fn.
+ (type_has_user_provided_constructor): New fn.
+ (type_has_user_provided_default_constructor): New fn.
+ (check_methods): A defaulted fn is still trivial.
+ (check_bases_and_members): Likewise.
+ * decl.c (grok_special_member_properties): Likewise.
+ (duplicate_decls): Complain about redeclaring a function as deleted.
+ (start_decl): initialized==2 means deleted.
+ (cp_finish_decl): Handle deleted/defaulted semantics.
+ * decl2.c (grokfield): Likewise.
+ (mark_used): Check DECL_DEFAULTED_FN instead of DECL_ARTIFICIAL.
+ Complain about using a deleted fn.
+ * init.c (build_value_init_1): Use type_has_user_provided_constructor.
+ (perform_member_init): Check for a user-provided default constructor
+ even if TYPE_NEEDS_CONSTRUCTING.
+ (build_new_1): Likewise.
+ * call.c (build_over_call): Don't call mark_used twice.
+ * method.c (implicitly_declare_fn): Set DECL_DEFAULTED_FN.
+ * search.c (check_final_overrider): Check for deleted mismatch.
+ * parser.c (cp_parser_init_declarator): Tell start_decl about =delete.
+ (cp_parser_pure_specifier): Handle =default and =delete.
+
+ * error.c (maybe_warn_cpp0x): Suggest -std=gnu++0x as well.
+
+2008-07-23 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
+
+ PR 35058
+ * typeck.c: All calls to pedwarn changed.
+ * decl.c: All calls to pedwarn changed.
+ * call.c: All calls to pedwarn changed.
+ * error.c: All calls to pedwarn changed.
+ * typeck2.c: All calls to pedwarn changed.
+ * pt.c: All calls to pedwarn changed.
+ * name-lookup.c: All calls to pedwarn changed.
+ * parser.c: All calls to pedwarn changed.
+
+2008-07-21 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
+
+ * call.c: Fix comment typos.
+ * class.c: Likewise.
+ * cp-tree.h: Likewise.
+ * cxx-pretty-print.c: Likewise.
+ * decl.c: Likewise.
+ * init.c: Likewise.
+ * name-lookup.c: Likewise.
+ * operators.def: Likewise.
+ * parser.c: Likewise.
+ * pt.c: Likewise.
+ * tree.c: Likewise.
+ * typeck.c: Likewise.
+
+2008-07-21 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/36871
+ PR c++/36872
+ * semantics.c (classtype_has_nothrow_assign_or_copy_p): Only check
+ copy constructors and copy assignment operators proper.
+
+2008-07-21 Rafael Avila de Espindola <espindola@google.com>
+
+ * parser.c (cp_token): Remove in_system_header.
+ (eof_token): Remove in_system_header.
+ (cp_lexer_get_preprocessor_token): Don't set in_system_header.
+ (cp_lexer_set_source_position_from_token): Don't set in_system_header.
+ (cp_parser_member_declaration): Use in_system_header_at.
+ * pt.c (lookup_template_class): Don't set DECL_IN_SYSTEM_HEADER.
+ (pop_tinst_level): Don't set in_system_header.
+ (instantiate_class_template): Don't set in_system_header.
+ (instantiate_decl): Don't set in_system_header.
+ (instantiate_pending_templates): Don't set in_system_header.
+
+2008-07-21 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/36870
+ * semantics.c (classtype_has_nothrow_assign_or_copy_p): Use
+ TYPE_NOTHROW_P, not TREE_NOTHROW.
+ (trait_expr_value): Likewise.
+
+2008-07-18 Dodji Seketeli <dseketel@redhat.com>
+
+ PR c++/36407
+ * call.c (convert_like_real): Don't take the error code path
+ when a rvalue or base conversion has the bad_p field set.
+
+2008-07-18 Kris Van Hees <kris.van.hees@oracle.com>
+
+ * rtti.c (emit_support_tinfos): Add char16_type_node and
+ char32_type_node.
+ * typeck2.c (digest_init): Support char16_t and char32_t.
+
+2008-07-18 Kavih R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * cvt.c (convert_to_void): Avoid C++ keywords.
+ * decl.c (walk_namespaces_r, wrapup_globals_for_namespace):
+ Likewise.
+ * friend.c (is_friend): Likewise.
+ * init.c (perform_member_init): Likewise.
+ * mangle.c (write_template_prefix, write_template_template_param):
+ Likewise.
+ * name-lookup.c (do_namespace_alias, do_using_directive,
+ parse_using_directive, ambiguous_decl, arg_assoc): Likewise.
+ * parser.c (cp_parser_template_id, cp_parser_namespace_definition,
+ cp_parser_objc_typename, cp_parser_objc_method_keyword_params):
+ Likewise.
+ * pt.c (is_specialization_of_friend, lookup_template_class,
+ push_tinst_level, instantiate_class_template,
+ tsubst_copy_and_build): Likewise.
+ * tree.c (add_stmt_to_compound): Likewise.
+ * typeck.c (finish_class_member_access_expr): Likewise.
+
+2008-07-17 Julian Brown <julian@codesourcery.com>
+ Mark Mitchell <mark@codesourcery.com>
+
+ * decl2.c (determine_visibility): Allow target to override
+ visibility of class data.
+
+2008-07-17 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/36855
+ * semantics.c (trait_expr_value): Update __has_trivial_destructor
+ semantics to the current WP (N2691).
+
+2008-07-16 Dodji Seketeli <dseketel@redhat.com>
+
+ PR c++/13699
+ * name-lookup.c (lookup_extern_c_fun_binding_in_all_ns): New function.
+ (pushdecl_maybe_friend): Check if a redeclaration of extern C function
+ complies with exception specification constraints.
+
+2008-07-14 Jason Merrill <jason@redhat.com>
+
+ * lex.c (init_reswords): Always set D_OBJC.
+
+2008-07-11 Tom Tromey <tromey@redhat.com>
+ Ian Lance Taylor <iant@google.com>
+
+ * lex.c (struct resword, reswords): Don't define.
+ (D_EXT, D_ASM, D_OBJC, D_CXX0X): Don't define.
+ (init_reswords): Clarify mask code. Use c_common_reswords rather
+ than reswords.
+
+2008-07-11 Dodji Seketeli <dseketel@redhat.com>
+
+ PR c++/13101
+ * decl.c (grokdeclarator): Warn about initializing variables
+ of storage class 'extern' only after the type of the declarator
+ has been properly computed.
+
+2008-07-11 Dodji Seketeli <dseketel@redhat.com>
+
+ PR c++/31754
+ * cp-tree.h (struct cp_decl_specifier_seq): Add a location field. It
+ carries the location of the primary type.
+ * parser.c (cp_parser_check_type_definition): Update documentation.
+ (cp_parser_check_for_definition_in_return_type,
+ cp_parser_check_for_invalid_template_id,
+ cp_parser_set_decl_spec_type,
+ cp_parser_check_for_definition_in_return_type,
+ cp_parser_diagnose_invalid_type_name,
+ cp_parser_new_expression, cp_parser_explicit_instantiation,
+ cp_parser_type_specifier, cp_parser_simple_type_specifier,
+ cp_parser_omp_for_loop, cp_parser_pragma): Use location in error
+ messages.
+
+2008-07-11 Dodji Seketeli <dseketel@redhat.com>
+
+ PR c++/31754
+ * pt.c, semantic.c:
+ * semantic.c (qualified_name_lookup_error, finish_id_expression):
+ Add a location_t parameter so that
+ error message can have a more accurate location.
+ * cp-tree.h: Updated prototype
+ * pt.c (tsubst_qualified_id): Use location in error messages.
+ * parser.c (cp_parser_postfix_expression,
+ cp_parser_objc_statement, cp_parser_trait_expr,
+ cp_parser_token_is_class_key,
+ cp_parser_uncommitted_to_tentative_parse_p,
+ cp_parser_check_for_invalid_template_id, cp_parser_is_string_literal,
+ cp_parser_error, cp_parser_name_lookup_error,
+ cp_parser_simulate_error, cp_parser_check_decl_spec,
+ cp_parser_check_decl_spec, cp_parser_non_integral_constant_expression,
+ cp_parser_diagnose_invalid_type_name,
+ cp_parser_parse_and_diagnose_invalid_type_name,
+ cp_parser_require_pragma_eol, cp_parser_make_typename_type,
+ cp_parser_string_literal, cp_parser_primary_expression,
+ cp_parser_primary_expression, cp_parser_unqualified_id,
+ cp_parser_nested_name_specifier_opt, cp_parser_postfix_expression,
+ cp_parser_postfix_dot_deref_expression, cp_parser_new_expression,
+ cp_parser_direct_new_declarator, cp_parser_builtin_offsetof,
+ cp_parser_label_for_labeled_statement, cp_parser_statement_seq_opt,
+ cp_parser_jump_statement, cp_parser_block_declaration,
+ cp_parser_simple_declaration, cp_parser_decl_specifier_seq,
+ cp_parser_function_specifier_opt, cp_parser_decltype,
+ cp_parser_mem_initializer_list, cp_parser_mem_initializer,
+ cp_parser_mem_initializer_id, cp_parser_template_parameter,
+ cp_parser_type_parameter, cp_parser_template_id,
+ cp_parser_template_name, cp_parser_template_argument): Likewise.
+
+2008-07-09 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/36760
+ * pt.c (tsubst_function_type): Remove warning for type qualifiers
+ on function return type.
+
+2008-07-09 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/36760
+ * pt.c (tsubst_function_type): Don't warn for type qualifiers
+ on function return type in case of system header.
+
+2008-07-09 Raksit Ashok <raksit@google.com>
+
+ * parser.c (cp_parser_postfix_expression): New warning based on flag
+ warn_disallowed_functions.
+
+2008-07-08 Simon Martin <simartin@users.sourceforge.net>
+
+ PR c++/34963
+ * decl.c (grokdeclarator): Reset storage_class and staticp for friend
+ functions declared with a storage class qualifier.
+
2008-07-03 Richard Guenther <rguenther@suse.de>
PR c++/36128
@@ -76,7 +496,7 @@
* pt.c: (tsubst_copy_and_build): Adjust.
(unify): Handle { }.
* name-lookup.c (arg_assoc_type): Handle init_list_type_node.
-
+
2008-07-01 Daniel Jacobowitz <dan@codesourcery.com>
* typeck.c (comp_ptr_ttypes_real): Use vector_targets_convertible_p.
diff --git a/gcc/cp/Make-lang.in b/gcc/cp/Make-lang.in
index c7877205f25..03963446251 100644
--- a/gcc/cp/Make-lang.in
+++ b/gcc/cp/Make-lang.in
@@ -239,7 +239,7 @@ cp/decl.o: cp/decl.c $(CXX_TREE_H) $(TM_H) $(FLAGS_H) cp/decl.h \
debug.h gt-cp-decl.h $(TIMEVAR_H) $(TREE_FLOW_H) $(TARGET_H)
cp/decl2.o: cp/decl2.c $(CXX_TREE_H) $(TM_H) $(FLAGS_H) cp/decl.h $(EXPR_H) \
output.h except.h toplev.h $(RTL_H) $(C_COMMON_H) gt-cp-decl2.h $(CGRAPH_H) \
- $(C_PRAGMA_H) $(TREE_DUMP_H) intl.h $(TARGET_H)
+ $(C_PRAGMA_H) $(TREE_DUMP_H) intl.h $(TARGET_H) $(GIMPLE_H)
cp/cp-objcp-common.o : cp/cp-objcp-common.c $(CONFIG_H) $(SYSTEM_H) \
coretypes.h $(TM_H) $(TREE_H) $(CXX_TREE_H) $(C_COMMON_H) toplev.h \
langhooks.h $(LANGHOOKS_DEF_H) $(DIAGNOSTIC_H) debug.h \
@@ -280,17 +280,17 @@ cp/repo.o: cp/repo.c $(CXX_TREE_H) $(TM_H) toplev.h $(DIAGNOSTIC_H) \
gt-cp-repo.h
cp/semantics.o: cp/semantics.c $(CXX_TREE_H) $(TM_H) except.h toplev.h \
$(FLAGS_H) debug.h output.h $(RTL_H) $(TIMEVAR_H) $(EXPR_H) \
- $(TREE_INLINE_H) $(CGRAPH_H) $(TARGET_H) $(C_COMMON_H)
+ $(TREE_INLINE_H) $(CGRAPH_H) $(TARGET_H) $(C_COMMON_H) $(GIMPLE_H)
cp/dump.o: cp/dump.c $(CXX_TREE_H) $(TM_H) $(TREE_DUMP_H)
cp/optimize.o: cp/optimize.c $(CXX_TREE_H) $(TM_H) rtl.h $(INTEGRATE_H) \
- insn-config.h input.h $(PARAMS_H) debug.h $(TREE_INLINE_H) $(TREE_GIMPLE_H) \
+ insn-config.h input.h $(PARAMS_H) debug.h $(TREE_INLINE_H) $(GIMPLE_H) \
$(TARGET_H)
cp/mangle.o: cp/mangle.c $(CXX_TREE_H) $(TM_H) toplev.h $(REAL_H) \
gt-cp-mangle.h $(TARGET_H) $(TM_P_H)
cp/parser.o: cp/parser.c $(CXX_TREE_H) $(TM_H) $(DIAGNOSTIC_H) gt-cp-parser.h \
output.h $(TARGET_H)
cp/cp-gimplify.o: cp/cp-gimplify.c $(CXX_TREE_H) toplev.h $(C_COMMON_H) \
- $(TM_H) coretypes.h pointer-set.h
+ $(TM_H) coretypes.h pointer-set.h tree-iterator.h
cp/name-lookup.o: cp/name-lookup.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TM_H) $(CXX_TREE_H) $(TIMEVAR_H) gt-cp-name-lookup.h toplev.h \
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 368d95a677f..cb07c82f1ab 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -3404,8 +3404,9 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3,
calculated only once. */
if (!arg2)
{
- if (pedantic && (complain & tf_error))
- pedwarn ("ISO C++ forbids omitting the middle term of a ?: expression");
+ if (complain & tf_error)
+ pedwarn (OPT_pedantic,
+ "ISO C++ forbids omitting the middle term of a ?: expression");
/* Make sure that lvalues remain lvalues. See g++.oliva/ext1.C. */
if (real_lvalue_p (arg1))
@@ -3416,7 +3417,7 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3,
/* [expr.cond]
- The first expr ession is implicitly converted to bool (clause
+ The first expression is implicitly converted to bool (clause
_conv_). */
arg1 = perform_implicit_conversion (boolean_type_node, arg1, complain);
@@ -4510,7 +4511,9 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
if (convs->bad_p
&& convs->kind != ck_user
&& convs->kind != ck_ambig
- && convs->kind != ck_ref_bind)
+ && convs->kind != ck_ref_bind
+ && convs->kind != ck_rvalue
+ && convs->kind != ck_base)
{
conversion *t = convs;
for (; t; t = convs->u.next)
@@ -5087,6 +5090,7 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
int is_method = 0;
int nargs;
tree *argarray;
+ bool already_used = false;
/* In a template, there is no need to perform all of the work that
is normally done. We are only interested in the type of the call
@@ -5307,7 +5311,10 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
/* [class.copy]: the copy constructor is implicitly defined even if
the implementation elided its use. */
if (TYPE_HAS_COMPLEX_INIT_REF (DECL_CONTEXT (fn)))
- mark_used (fn);
+ {
+ mark_used (fn);
+ already_used = true;
+ }
/* If we're creating a temp and we already have one, don't create a
new one. If we're not creating a temp but we get one, use
@@ -5367,7 +5374,8 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
return val;
}
- mark_used (fn);
+ if (!already_used)
+ mark_used (fn);
if (DECL_VINDEX (fn) && (flags & LOOKUP_NONVIRTUAL) == 0)
{
@@ -5392,8 +5400,6 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
fn = build_vfn_ref (argarray[0], DECL_VINDEX (fn));
TREE_TYPE (fn) = t;
}
- else if (DECL_INLINE (fn))
- fn = inline_conversion (fn);
else
fn = build_addr_func (fn);
@@ -6758,7 +6764,7 @@ tweak:
{
if (warn)
{
- warning (0,
+ pedwarn (0,
"ISO C++ says that these are ambiguous, even "
"though the worst conversion for the first is better than "
"the worst conversion for the second:");
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 12b17f3751c..f7e46a717aa 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -3045,7 +3045,7 @@ check_field_decls (tree t, tree *access_decls,
/* Core issue 80: A nonstatic data member is required to have a
different name from the class iff the class has a
- user-defined constructor. */
+ user-declared constructor. */
if (constructor_name_p (DECL_NAME (x), t)
&& TYPE_HAS_USER_CONSTRUCTOR (t))
permerror ("field %q+#D with same name as class", x);
@@ -3767,8 +3767,8 @@ check_methods (tree t)
if (DECL_PURE_VIRTUAL_P (x))
VEC_safe_push (tree, gc, CLASSTYPE_PURE_VIRTUALS (t), x);
}
- /* All user-declared destructors are non-trivial. */
- if (DECL_DESTRUCTOR_P (x))
+ /* All user-provided destructors are non-trivial. */
+ if (DECL_DESTRUCTOR_P (x) && !DECL_DEFAULTED_FN (x))
TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t) = 1;
}
}
@@ -4067,6 +4067,91 @@ type_has_user_nondefault_constructor (tree t)
return false;
}
+/* Returns true iff FN is a user-provided function, i.e. user-declared
+ and not defaulted at its first declaration. */
+
+static bool
+user_provided_p (tree fn)
+{
+ if (TREE_CODE (fn) == TEMPLATE_DECL)
+ return true;
+ else
+ return (!DECL_ARTIFICIAL (fn)
+ && !(DECL_DEFAULTED_FN (fn)
+ && DECL_INITIALIZED_IN_CLASS_P (fn)));
+}
+
+/* Returns true iff class T has a user-provided constructor. */
+
+bool
+type_has_user_provided_constructor (tree t)
+{
+ tree fns;
+
+ if (!TYPE_HAS_USER_CONSTRUCTOR (t))
+ return false;
+
+ /* This can happen in error cases; avoid crashing. */
+ if (!CLASSTYPE_METHOD_VEC (t))
+ return false;
+
+ for (fns = CLASSTYPE_CONSTRUCTORS (t); fns; fns = OVL_NEXT (fns))
+ if (user_provided_p (OVL_CURRENT (fns)))
+ return true;
+
+ return false;
+}
+
+/* Returns true iff class T has a user-provided default constructor. */
+
+bool
+type_has_user_provided_default_constructor (tree t)
+{
+ tree fns, args;
+
+ if (!TYPE_HAS_USER_CONSTRUCTOR (t))
+ return false;
+
+ for (fns = CLASSTYPE_CONSTRUCTORS (t); fns; fns = OVL_NEXT (fns))
+ {
+ tree fn = OVL_CURRENT (fns);
+ if (TREE_CODE (fn) == FUNCTION_DECL
+ && user_provided_p (fn))
+ {
+ args = FUNCTION_FIRST_USER_PARMTYPE (fn);
+ while (args && TREE_PURPOSE (args))
+ args = TREE_CHAIN (args);
+ if (!args || args == void_list_node)
+ return true;
+ }
+ }
+
+ return false;
+}
+
+/* Returns true if FN can be explicitly defaulted. */
+
+bool
+defaultable_fn_p (tree fn)
+{
+ if (DECL_CONSTRUCTOR_P (fn))
+ {
+ if (skip_artificial_parms_for (fn, DECL_ARGUMENTS (fn))
+ == NULL_TREE)
+ return true;
+ else if (copy_fn_p (fn) > 0)
+ return true;
+ else
+ return false;
+ }
+ else if (DECL_DESTRUCTOR_P (fn))
+ return true;
+ else if (DECL_ASSIGNMENT_OPERATOR_P (fn))
+ return copy_fn_p (fn);
+ else
+ return false;
+}
+
/* Remove all zero-width bit-fields from T. */
static void
@@ -4158,6 +4243,8 @@ check_bases_and_members (tree t)
should take a non-const reference argument. */
int no_const_asn_ref;
tree access_decls;
+ bool saved_complex_asn_ref;
+ bool saved_nontrivial_dtor;
/* By default, we use const reference arguments and generate default
constructors. */
@@ -4171,6 +4258,12 @@ check_bases_and_members (tree t)
/* Check all the method declarations. */
check_methods (t);
+ /* Save the initial values of these flags which only indicate whether
+ or not the class has user-provided functions. As we analyze the
+ bases and members we can set these flags for other reasons. */
+ saved_complex_asn_ref = TYPE_HAS_COMPLEX_ASSIGN_REF (t);
+ saved_nontrivial_dtor = TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t);
+
/* Check all the data member declarations. We cannot call
check_field_decls until we have called check_bases check_methods,
as check_field_decls depends on TYPE_HAS_NONTRIVIAL_DESTRUCTOR
@@ -4186,30 +4279,27 @@ check_bases_and_members (tree t)
/* Do some bookkeeping that will guide the generation of implicitly
declared member functions. */
- TYPE_HAS_COMPLEX_INIT_REF (t)
- |= (TYPE_HAS_INIT_REF (t) || TYPE_CONTAINS_VPTR_P (t));
+ TYPE_HAS_COMPLEX_INIT_REF (t) |= TYPE_CONTAINS_VPTR_P (t);
/* We need to call a constructor for this class if it has a
- user-declared constructor, or if the default constructor is going
+ user-provided constructor, or if the default constructor is going
to initialize the vptr. (This is not an if-and-only-if;
TYPE_NEEDS_CONSTRUCTING is set elsewhere if bases or members
themselves need constructing.) */
TYPE_NEEDS_CONSTRUCTING (t)
- |= (TYPE_HAS_USER_CONSTRUCTOR (t) || TYPE_CONTAINS_VPTR_P (t));
+ |= (type_has_user_provided_constructor (t) || TYPE_CONTAINS_VPTR_P (t));
/* [dcl.init.aggr]
- An aggregate is an arry or a class with no user-declared
+ An aggregate is an array or a class with no user-provided
constructors ... and no virtual functions.
Again, other conditions for being an aggregate are checked
elsewhere. */
CLASSTYPE_NON_AGGREGATE (t)
- |= (TYPE_HAS_USER_CONSTRUCTOR (t) || TYPE_POLYMORPHIC_P (t));
+ |= (type_has_user_provided_constructor (t) || TYPE_POLYMORPHIC_P (t));
CLASSTYPE_NON_POD_P (t)
|= (CLASSTYPE_NON_AGGREGATE (t)
- || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t)
- || TYPE_HAS_ASSIGN_REF (t));
- TYPE_HAS_COMPLEX_ASSIGN_REF (t)
- |= TYPE_HAS_ASSIGN_REF (t) || TYPE_CONTAINS_VPTR_P (t);
+ || saved_nontrivial_dtor || saved_complex_asn_ref);
+ TYPE_HAS_COMPLEX_ASSIGN_REF (t) |= TYPE_CONTAINS_VPTR_P (t);
TYPE_HAS_COMPLEX_DFLT (t)
|= (TYPE_HAS_DEFAULT_CONSTRUCTOR (t) || TYPE_CONTAINS_VPTR_P (t));
@@ -7386,7 +7476,7 @@ build_vtbl_initializer (tree binfo,
We first check this in update_vtable_entry_for_fn, so we handle
restored primary bases properly; we also need to do it here so we
- zero out unused slots in ctor vtables, rather than filling themff
+ zero out unused slots in ctor vtables, rather than filling them
with erroneous values (though harmless, apart from relocation
costs). */
for (b = binfo; ; b = get_primary_binfo (b))
diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c
index c6d64dfbb75..8dda74d3cbe 100644
--- a/gcc/cp/cp-gimplify.c
+++ b/gcc/cp/cp-gimplify.c
@@ -28,7 +28,8 @@ along with GCC; see the file COPYING3. If not see
#include "cp-tree.h"
#include "c-common.h"
#include "toplev.h"
-#include "tree-gimple.h"
+#include "tree-iterator.h"
+#include "gimple.h"
#include "hashtab.h"
#include "pointer-set.h"
#include "flags.h"
@@ -62,20 +63,14 @@ begin_bc_block (enum bc_t bc)
If we saw a break (or continue) in the scope, append a LABEL_EXPR to
body. Otherwise, just forget the label. */
-static tree
-finish_bc_block (enum bc_t bc, tree label, tree body)
+static gimple_seq
+finish_bc_block (enum bc_t bc, tree label, gimple_seq body)
{
gcc_assert (label == bc_label[bc]);
if (TREE_USED (label))
{
- tree t, sl = NULL;
-
- t = build1 (LABEL_EXPR, void_type_node, label);
-
- append_to_statement_list (body, &sl);
- append_to_statement_list (t, &sl);
- body = sl;
+ gimple_seq_add_stmt (&body, gimple_build_label (label));
}
bc_label[bc] = TREE_CHAIN (label);
@@ -83,11 +78,11 @@ finish_bc_block (enum bc_t bc, tree label, tree body)
return body;
}
-/* Build a GOTO_EXPR to represent a break or continue statement. BC
- indicates which. */
+/* Get the LABEL_EXPR to represent a break or continue statement
+ in the current block scope. BC indicates which. */
static tree
-build_bc_goto (enum bc_t bc)
+get_bc_label (enum bc_t bc)
{
tree label = bc_label[bc];
@@ -103,7 +98,7 @@ build_bc_goto (enum bc_t bc)
/* Mark the label used for finish_bc_block. */
TREE_USED (label) = 1;
- return build1 (GOTO_EXPR, void_type_node, label);
+ return label;
}
/* Genericize a TRY_BLOCK. */
@@ -114,13 +109,6 @@ genericize_try_block (tree *stmt_p)
tree body = TRY_STMTS (*stmt_p);
tree cleanup = TRY_HANDLERS (*stmt_p);
- gimplify_stmt (&body);
-
- if (CLEANUP_P (*stmt_p))
- /* A cleanup is an expression, so it doesn't need to be genericized. */;
- else
- gimplify_stmt (&cleanup);
-
*stmt_p = build2 (TRY_CATCH_EXPR, void_type_node, body, cleanup);
}
@@ -132,12 +120,28 @@ genericize_catch_block (tree *stmt_p)
tree type = HANDLER_TYPE (*stmt_p);
tree body = HANDLER_BODY (*stmt_p);
- gimplify_stmt (&body);
-
/* FIXME should the caught type go in TREE_TYPE? */
*stmt_p = build2 (CATCH_EXPR, void_type_node, type, body);
}
+/* A terser interface for building a representation of an exception
+ specification. */
+
+static tree
+build_gimple_eh_filter_tree (tree body, tree allowed, tree failure)
+{
+ tree t;
+
+ /* FIXME should the allowed types go in TREE_TYPE? */
+ t = build2 (EH_FILTER_EXPR, void_type_node, allowed, NULL_TREE);
+ append_to_statement_list (failure, &EH_FILTER_FAILURE (t));
+
+ t = build2 (TRY_CATCH_EXPR, void_type_node, NULL_TREE, t);
+ append_to_statement_list (body, &TREE_OPERAND (t, 0));
+
+ return t;
+}
+
/* Genericize an EH_SPEC_BLOCK by converting it to a
TRY_CATCH_EXPR/EH_FILTER_EXPR pair. */
@@ -147,9 +151,8 @@ genericize_eh_spec_block (tree *stmt_p)
tree body = EH_SPEC_STMTS (*stmt_p);
tree allowed = EH_SPEC_RAISES (*stmt_p);
tree failure = build_call_n (call_unexpected_node, 1, build_exc_ptr ());
- gimplify_stmt (&body);
- *stmt_p = gimple_build_eh_filter (body, allowed, failure);
+ *stmt_p = build_gimple_eh_filter_tree (body, allowed, failure);
}
/* Genericize an IF_STMT by turning it into a COND_EXPR. */
@@ -158,6 +161,7 @@ static void
gimplify_if_stmt (tree *stmt_p)
{
tree stmt, cond, then_, else_;
+ location_t locus = EXPR_LOCATION (*stmt_p);
stmt = *stmt_p;
cond = IF_COND (stmt);
@@ -175,6 +179,8 @@ gimplify_if_stmt (tree *stmt_p)
stmt = else_;
else
stmt = build3 (COND_EXPR, void_type_node, cond, then_, else_);
+ if (CAN_HAVE_LOCATION_P (stmt) && !EXPR_HAS_LOCATION (stmt))
+ SET_EXPR_LOCATION (stmt, locus);
*stmt_p = stmt;
}
@@ -185,15 +191,20 @@ gimplify_if_stmt (tree *stmt_p)
evaluated before the loop body as in while and for loops, or after the
loop body as in do-while loops. */
-static tree
+static gimple_seq
gimplify_cp_loop (tree cond, tree body, tree incr, bool cond_is_first)
{
- tree top, entry, exit, cont_block, break_block, stmt_list, t;
+ gimple top, entry, stmt;
+ gimple_seq stmt_list, body_seq, incr_seq, exit_seq;
+ tree cont_block, break_block;
location_t stmt_locus;
stmt_locus = input_location;
- stmt_list = NULL_TREE;
- entry = NULL_TREE;
+ stmt_list = NULL;
+ body_seq = NULL;
+ incr_seq = NULL;
+ exit_seq = NULL;
+ entry = NULL;
break_block = begin_bc_block (bc_break);
cont_block = begin_bc_block (bc_continue);
@@ -201,12 +212,12 @@ gimplify_cp_loop (tree cond, tree body, tree incr, bool cond_is_first)
/* If condition is zero don't generate a loop construct. */
if (cond && integer_zerop (cond))
{
- top = NULL_TREE;
- exit = NULL_TREE;
+ top = NULL;
if (cond_is_first)
{
- t = build_bc_goto (bc_break);
- append_to_statement_list (t, &stmt_list);
+ stmt = gimple_build_goto (get_bc_label (bc_break));
+ gimple_set_location (stmt, stmt_locus);
+ gimple_seq_add_stmt (&stmt_list, stmt);
}
}
else
@@ -215,44 +226,55 @@ gimplify_cp_loop (tree cond, tree body, tree incr, bool cond_is_first)
back through the main gimplifier to lower it. Given that we
have to gimplify the loop body NOW so that we can resolve
break/continue stmts, seems easier to just expand to gotos. */
- top = build1 (LABEL_EXPR, void_type_node, NULL_TREE);
+ top = gimple_build_label (create_artificial_label ());
/* If we have an exit condition, then we build an IF with gotos either
out of the loop, or to the top of it. If there's no exit condition,
then we just build a jump back to the top. */
- exit = build_and_jump (&LABEL_EXPR_LABEL (top));
if (cond && !integer_nonzerop (cond))
{
- t = build_bc_goto (bc_break);
- exit = fold_build3 (COND_EXPR, void_type_node, cond, exit, t);
- gimplify_stmt (&exit);
+ if (cond != error_mark_node)
+ {
+ gimplify_expr (&cond, &exit_seq, NULL, is_gimple_val, fb_rvalue);
+ stmt = gimple_build_cond (NE_EXPR, cond,
+ build_int_cst (TREE_TYPE (cond), 0),
+ gimple_label_label (top),
+ get_bc_label (bc_break));
+ gimple_seq_add_stmt (&exit_seq, stmt);
+ }
if (cond_is_first)
{
if (incr)
{
- entry = build1 (LABEL_EXPR, void_type_node, NULL_TREE);
- t = build_and_jump (&LABEL_EXPR_LABEL (entry));
+ entry = gimple_build_label (create_artificial_label ());
+ stmt = gimple_build_goto (gimple_label_label (entry));
}
else
- t = build_bc_goto (bc_continue);
- append_to_statement_list (t, &stmt_list);
+ stmt = gimple_build_goto (get_bc_label (bc_continue));
+ gimple_set_location (stmt, stmt_locus);
+ gimple_seq_add_stmt (&stmt_list, stmt);
}
}
+ else
+ {
+ stmt = gimple_build_goto (gimple_label_label (top));
+ gimple_seq_add_stmt (&exit_seq, stmt);
+ }
}
- gimplify_stmt (&body);
- gimplify_stmt (&incr);
+ gimplify_stmt (&body, &body_seq);
+ gimplify_stmt (&incr, &incr_seq);
- body = finish_bc_block (bc_continue, cont_block, body);
+ body_seq = finish_bc_block (bc_continue, cont_block, body_seq);
- append_to_statement_list (top, &stmt_list);
- append_to_statement_list (body, &stmt_list);
- append_to_statement_list (incr, &stmt_list);
- append_to_statement_list (entry, &stmt_list);
- append_to_statement_list (exit, &stmt_list);
+ gimple_seq_add_stmt (&stmt_list, top);
+ gimple_seq_add_seq (&stmt_list, body_seq);
+ gimple_seq_add_seq (&stmt_list, incr_seq);
+ gimple_seq_add_stmt (&stmt_list, entry);
+ gimple_seq_add_seq (&stmt_list, exit_seq);
- annotate_all_with_locus (&stmt_list, stmt_locus);
+ annotate_all_with_location (stmt_list, stmt_locus);
return finish_bc_block (bc_break, break_block, stmt_list);
}
@@ -261,45 +283,52 @@ gimplify_cp_loop (tree cond, tree body, tree incr, bool cond_is_first)
prequeue and hand off to gimplify_cp_loop. */
static void
-gimplify_for_stmt (tree *stmt_p, tree *pre_p)
+gimplify_for_stmt (tree *stmt_p, gimple_seq *pre_p)
{
tree stmt = *stmt_p;
if (FOR_INIT_STMT (stmt))
gimplify_and_add (FOR_INIT_STMT (stmt), pre_p);
- *stmt_p = gimplify_cp_loop (FOR_COND (stmt), FOR_BODY (stmt),
- FOR_EXPR (stmt), 1);
+ gimple_seq_add_seq (pre_p,
+ gimplify_cp_loop (FOR_COND (stmt), FOR_BODY (stmt),
+ FOR_EXPR (stmt), 1));
+ *stmt_p = NULL_TREE;
}
/* Gimplify a WHILE_STMT node. */
static void
-gimplify_while_stmt (tree *stmt_p)
+gimplify_while_stmt (tree *stmt_p, gimple_seq *pre_p)
{
tree stmt = *stmt_p;
- *stmt_p = gimplify_cp_loop (WHILE_COND (stmt), WHILE_BODY (stmt),
- NULL_TREE, 1);
+ gimple_seq_add_seq (pre_p,
+ gimplify_cp_loop (WHILE_COND (stmt), WHILE_BODY (stmt),
+ NULL_TREE, 1));
+ *stmt_p = NULL_TREE;
}
/* Gimplify a DO_STMT node. */
static void
-gimplify_do_stmt (tree *stmt_p)
+gimplify_do_stmt (tree *stmt_p, gimple_seq *pre_p)
{
tree stmt = *stmt_p;
- *stmt_p = gimplify_cp_loop (DO_COND (stmt), DO_BODY (stmt),
- NULL_TREE, 0);
+ gimple_seq_add_seq (pre_p,
+ gimplify_cp_loop (DO_COND (stmt), DO_BODY (stmt),
+ NULL_TREE, 0));
+ *stmt_p = NULL_TREE;
}
/* Genericize a SWITCH_STMT by turning it into a SWITCH_EXPR. */
static void
-gimplify_switch_stmt (tree *stmt_p)
+gimplify_switch_stmt (tree *stmt_p, gimple_seq *pre_p)
{
tree stmt = *stmt_p;
- tree break_block, body;
+ tree break_block, body, t;
location_t stmt_locus = input_location;
+ gimple_seq seq = NULL;
break_block = begin_bc_block (bc_break);
@@ -307,12 +336,14 @@ gimplify_switch_stmt (tree *stmt_p)
if (!body)
body = build_empty_stmt ();
- *stmt_p = build3 (SWITCH_EXPR, SWITCH_STMT_TYPE (stmt),
- SWITCH_STMT_COND (stmt), body, NULL_TREE);
- SET_EXPR_LOCATION (*stmt_p, stmt_locus);
- gimplify_stmt (stmt_p);
+ t = build3 (SWITCH_EXPR, SWITCH_STMT_TYPE (stmt),
+ SWITCH_STMT_COND (stmt), body, NULL_TREE);
+ SET_EXPR_LOCATION (t, stmt_locus);
+ gimplify_and_add (t, &seq);
- *stmt_p = finish_bc_block (bc_break, break_block, *stmt_p);
+ seq = finish_bc_block (bc_break, break_block, seq);
+ gimple_seq_add_seq (pre_p, seq);
+ *stmt_p = NULL_TREE;
}
/* Hook into the middle of gimplifying an OMP_FOR node. This is required
@@ -321,10 +352,12 @@ gimplify_switch_stmt (tree *stmt_p)
regular gimplifier. */
static enum gimplify_status
-cp_gimplify_omp_for (tree *expr_p)
+cp_gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
{
tree for_stmt = *expr_p;
tree cont_block;
+ gimple stmt;
+ gimple_seq seq = NULL;
/* Protect ourselves from recursion. */
if (OMP_FOR_GIMPLIFYING_P (for_stmt))
@@ -336,10 +369,15 @@ cp_gimplify_omp_for (tree *expr_p)
statement expressions within the INIT, COND, or INCR expressions. */
cont_block = begin_bc_block (bc_continue);
- gimplify_stmt (expr_p);
+ gimplify_and_add (for_stmt, &seq);
+ stmt = gimple_seq_last_stmt (seq);
+ if (gimple_code (stmt) == GIMPLE_OMP_FOR)
+ gimple_omp_set_body (stmt, finish_bc_block (bc_continue, cont_block,
+ gimple_omp_body (stmt)));
+ else
+ seq = finish_bc_block (bc_continue, cont_block, seq);
+ gimple_seq_add_seq (pre_p, seq);
- OMP_FOR_BODY (for_stmt)
- = finish_bc_block (bc_continue, cont_block, OMP_FOR_BODY (for_stmt));
OMP_FOR_GIMPLIFYING_P (for_stmt) = 0;
return GS_ALL_DONE;
@@ -383,7 +421,7 @@ gimplify_expr_stmt (tree *stmt_p)
/* Gimplify initialization from an AGGR_INIT_EXPR. */
static void
-cp_gimplify_init_expr (tree *expr_p, tree *pre_p, tree *post_p)
+cp_gimplify_init_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
{
tree from = TREE_OPERAND (*expr_p, 1);
tree to = TREE_OPERAND (*expr_p, 0);
@@ -441,31 +479,31 @@ cp_gimplify_init_expr (tree *expr_p, tree *pre_p, tree *post_p)
/* Gimplify a MUST_NOT_THROW_EXPR. */
-static void
-gimplify_must_not_throw_expr (tree *expr_p, tree *pre_p)
+static enum gimplify_status
+gimplify_must_not_throw_expr (tree *expr_p, gimple_seq *pre_p)
{
tree stmt = *expr_p;
tree temp = voidify_wrapper_expr (stmt, NULL);
tree body = TREE_OPERAND (stmt, 0);
- gimplify_stmt (&body);
-
- stmt = gimple_build_eh_filter (body, NULL_TREE,
- build_call_n (terminate_node, 0));
+ stmt = build_gimple_eh_filter_tree (body, NULL_TREE,
+ build_call_n (terminate_node, 0));
+ gimplify_and_add (stmt, pre_p);
if (temp)
{
- append_to_statement_list (stmt, pre_p);
*expr_p = temp;
+ return GS_OK;
}
- else
- *expr_p = stmt;
+
+ *expr_p = NULL;
+ return GS_ALL_DONE;
}
/* Do C++-specific gimplification. Args are as for gimplify_expr. */
int
-cp_gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p)
+cp_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
{
int saved_stmts_are_full_exprs_p = 0;
enum tree_code code = TREE_CODE (*expr_p);
@@ -498,11 +536,10 @@ cp_gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p)
break;
case MUST_NOT_THROW_EXPR:
- gimplify_must_not_throw_expr (expr_p, pre_p);
- ret = GS_OK;
+ ret = gimplify_must_not_throw_expr (expr_p, pre_p);
break;
- /* We used to do this for GIMPLE_MODIFY_STMT as well, but that's unsafe; the
+ /* We used to do this for MODIFY_EXPR as well, but that's unsafe; the
LHS of an assignment might also be involved in the RHS, as in bug
25979. */
case INIT_EXPR:
@@ -539,7 +576,7 @@ cp_gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p)
case USING_STMT:
/* Just ignore for now. Eventually we will want to pass this on to
the debugger. */
- *expr_p = build_empty_stmt ();
+ *expr_p = NULL;
ret = GS_ALL_DONE;
break;
@@ -550,35 +587,37 @@ cp_gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p)
case FOR_STMT:
gimplify_for_stmt (expr_p, pre_p);
- ret = GS_ALL_DONE;
+ ret = GS_OK;
break;
case WHILE_STMT:
- gimplify_while_stmt (expr_p);
- ret = GS_ALL_DONE;
+ gimplify_while_stmt (expr_p, pre_p);
+ ret = GS_OK;
break;
case DO_STMT:
- gimplify_do_stmt (expr_p);
- ret = GS_ALL_DONE;
+ gimplify_do_stmt (expr_p, pre_p);
+ ret = GS_OK;
break;
case SWITCH_STMT:
- gimplify_switch_stmt (expr_p);
- ret = GS_ALL_DONE;
+ gimplify_switch_stmt (expr_p, pre_p);
+ ret = GS_OK;
break;
case OMP_FOR:
- ret = cp_gimplify_omp_for (expr_p);
+ ret = cp_gimplify_omp_for (expr_p, pre_p);
break;
case CONTINUE_STMT:
- *expr_p = build_bc_goto (bc_continue);
+ gimple_seq_add_stmt (pre_p, gimple_build_goto (get_bc_label (bc_continue)));
+ *expr_p = NULL_TREE;
ret = GS_ALL_DONE;
break;
case BREAK_STMT:
- *expr_p = build_bc_goto (bc_break);
+ gimple_seq_add_stmt (pre_p, gimple_build_goto (get_bc_label (bc_break)));
+ *expr_p = NULL_TREE;
ret = GS_ALL_DONE;
break;
@@ -835,13 +874,13 @@ cxx_omp_clause_apply_fn (tree fn, tree arg1, tree arg2)
end1 = build2 (POINTER_PLUS_EXPR, TREE_TYPE (start1), start1, end1);
p1 = create_tmp_var (TREE_TYPE (start1), NULL);
- t = build2 (GIMPLE_MODIFY_STMT, void_type_node, p1, start1);
+ t = build2 (MODIFY_EXPR, TREE_TYPE (p1), p1, start1);
append_to_statement_list (t, &ret);
if (arg2)
{
p2 = create_tmp_var (TREE_TYPE (start2), NULL);
- t = build2 (GIMPLE_MODIFY_STMT, void_type_node, p2, start2);
+ t = build2 (MODIFY_EXPR, TREE_TYPE (p2), p2, start2);
append_to_statement_list (t, &ret);
}
@@ -864,14 +903,14 @@ cxx_omp_clause_apply_fn (tree fn, tree arg1, tree arg2)
t = TYPE_SIZE_UNIT (inner_type);
t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (p1), p1, t);
- t = build2 (GIMPLE_MODIFY_STMT, void_type_node, p1, t);
+ t = build2 (MODIFY_EXPR, TREE_TYPE (p1), p1, t);
append_to_statement_list (t, &ret);
if (arg2)
{
t = TYPE_SIZE_UNIT (inner_type);
t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (p2), p2, t);
- t = build2 (GIMPLE_MODIFY_STMT, void_type_node, p2, t);
+ t = build2 (MODIFY_EXPR, TREE_TYPE (p2), p2, t);
append_to_statement_list (t, &ret);
}
@@ -925,7 +964,7 @@ cxx_omp_clause_copy_ctor (tree clause, tree dst, tree src)
if (info)
ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 0), dst, src);
if (ret == NULL)
- ret = build2 (GIMPLE_MODIFY_STMT, void_type_node, dst, src);
+ ret = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
return ret;
}
@@ -941,7 +980,7 @@ cxx_omp_clause_assign_op (tree clause, tree dst, tree src)
if (info)
ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 2), dst, src);
if (ret == NULL)
- ret = build2 (GIMPLE_MODIFY_STMT, void_type_node, dst, src);
+ ret = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
return ret;
}
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index ed6ae0e810a..f9a2af8bb01 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -534,7 +534,7 @@ enum cp_tree_node_structure_enum {
/* The resulting tree type. */
union lang_tree_node GTY((desc ("cp_tree_node_structure (&%h)"),
- chain_next ("(union lang_tree_node *)GENERIC_NEXT (&%h.generic)")))
+ chain_next ("(union lang_tree_node *)TREE_CHAIN (&%h.generic)")))
{
union tree_node GTY ((tag ("TS_CP_GENERIC"),
desc ("tree_node_structure (&%h)"))) generic;
@@ -853,7 +853,7 @@ struct language_function GTY(())
#define cp_function_chain (cfun->language)
/* In a constructor destructor, the point at which all derived class
- destroying/construction has been has been done. Ie. just before a
+ destroying/construction has been done. I.e., just before a
constructor returns, or before any base class destroying will be done
in a destructor. */
@@ -1609,7 +1609,7 @@ struct lang_decl_flags GTY(())
unsigned repo_available_p : 1;
unsigned hidden_friend_p : 1;
unsigned threadprivate_p : 1;
- /* One unused bit. */
+ unsigned defaulted_p : 1;
union lang_decl_u {
/* In a FUNCTION_DECL for which DECL_THUNK_P holds, this is
@@ -1917,7 +1917,7 @@ struct lang_decl GTY(())
/* Nonzero if the DECL was initialized in the class definition itself,
rather than outside the class. This is used for both static member
- VAR_DECLS, and FUNTION_DECLS that are defined in the class. */
+ VAR_DECLS, and FUNCTION_DECLS that are defined in the class. */
#define DECL_INITIALIZED_IN_CLASS_P(DECL) \
(DECL_LANG_SPECIFIC (DECL)->decl_flags.initialized_in_class)
@@ -2626,6 +2626,14 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter)
#define CP_DECL_THREADPRIVATE_P(DECL) \
(DECL_LANG_SPECIFIC (VAR_DECL_CHECK (DECL))->decl_flags.threadprivate_p)
+/* Nonzero if DECL was declared with '= delete'. */
+#define DECL_DELETED_FN(DECL) \
+ (DECL_LANG_SPECIFIC (FUNCTION_DECL_CHECK (DECL))->decl_flags.threadprivate_p)
+
+/* Nonzero if DECL was declared with '= default'. */
+#define DECL_DEFAULTED_FN(DECL) \
+ (DECL_LANG_SPECIFIC (FUNCTION_DECL_CHECK (DECL))->decl_flags.defaulted_p)
+
/* Record whether a typedef for type `int' was actually `signed int'. */
#define C_TYPEDEF_EXPLICITLY_SIGNED(EXP) DECL_LANG_FLAG_1 (EXP)
@@ -3199,7 +3207,7 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter)
template <class T> struct S { friend void f(T) {}; };
the declaration of `void f(int)' generated when S<int> is
instantiated will not be a DECL_TEMPLATE_INSTANTIATION, but will be
- a DECL_FRIEND_PSUEDO_TEMPLATE_INSTANTIATION. */
+ a DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION. */
#define DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION(DECL) \
(DECL_TEMPLATE_INFO (DECL) && !DECL_USE_TEMPLATE (DECL))
@@ -3927,6 +3935,9 @@ typedef struct cp_decl_specifier_seq {
reflected here. This field will be a TYPE, unless a typedef-name
was used, in which case it will be a TYPE_DECL. */
tree type;
+ /* The location of the primary type. Mainly used for error
+ reporting. */
+ location_t type_location;
/* The attributes, if any, provided with the specifier sequence. */
tree attributes;
/* If non-NULL, a built-in type that the user attempted to redefine
@@ -4168,6 +4179,9 @@ extern void check_for_override (tree, tree);
extern void push_class_stack (void);
extern void pop_class_stack (void);
extern bool type_has_user_nondefault_constructor (tree);
+extern bool type_has_user_provided_constructor (tree);
+extern bool type_has_user_provided_default_constructor (tree);
+extern bool defaultable_fn_p (tree);
/* in cvt.c */
extern tree convert_to_reference (tree, tree, int, int, tree);
@@ -4211,10 +4225,9 @@ extern bool check_omp_return (void);
extern tree make_typename_type (tree, tree, enum tag_types, tsubst_flags_t);
extern tree make_unbound_class_template (tree, tree, tree, tsubst_flags_t);
extern tree check_for_out_of_scope_variable (tree);
-extern tree build_library_fn (tree, tree);
extern tree build_library_fn_ptr (const char *, tree);
extern tree build_cp_library_fn_ptr (const char *, tree);
-extern tree push_library_fn (tree, tree);
+extern tree push_library_fn (tree, tree, tree);
extern tree push_void_library_fn (tree, tree);
extern tree push_throw_library_fn (tree, tree);
extern tree check_tag_decl (cp_decl_specifier_seq *);
@@ -4320,6 +4333,7 @@ extern void mark_needed (tree);
extern bool decl_needed_p (tree);
extern void note_vague_linkage_fn (tree);
extern tree build_artificial_parm (tree, tree);
+extern bool possibly_inlined_p (tree);
/* in error.c */
extern void init_error (void);
@@ -4653,13 +4667,15 @@ extern void finish_template_decl (tree);
extern tree finish_template_type (tree, tree, int);
extern tree finish_base_specifier (tree, tree, bool);
extern void finish_member_declaration (tree);
-extern void qualified_name_lookup_error (tree, tree, tree);
+extern void qualified_name_lookup_error (tree, tree, tree,
+ location_t);
extern void check_template_keyword (tree);
extern tree finish_id_expression (tree, tree, tree,
cp_id_kind *,
bool, bool, bool *,
bool, bool, bool, bool,
- const char **);
+ const char **,
+ location_t);
extern tree finish_typeof (tree);
extern tree finish_offsetof (tree);
extern void finish_decl_cleanup (tree, tree);
@@ -4796,7 +4812,6 @@ extern int comp_cv_qual_signature (tree, tree);
extern tree cxx_sizeof_or_alignof_expr (tree, enum tree_code, bool);
extern tree cxx_sizeof_or_alignof_type (tree, enum tree_code, bool);
extern tree cxx_sizeof_nowarn (tree);
-extern tree inline_conversion (tree);
extern tree is_bitfield_expr_with_lowered_type (const_tree);
extern tree unlowered_expr_type (const_tree);
extern tree decay_conversion (tree);
@@ -4923,7 +4938,8 @@ extern void init_shadowed_var_for_decl (void);
extern tree cxx_staticp (tree);
/* in cp-gimplify.c */
-extern int cp_gimplify_expr (tree *, tree *, tree *);
+extern int cp_gimplify_expr (tree *, gimple_seq *,
+ gimple_seq *);
extern void cp_genericize (tree);
/* -- end of C++ */
diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c
index 70ef00a4fce..3ee3ba7956b 100644
--- a/gcc/cp/cvt.c
+++ b/gcc/cp/cvt.c
@@ -938,7 +938,7 @@ convert_to_void (tree expr, const char *implicit, tsubst_flags_t complain)
{
tree e;
enum tree_code code;
- enum tree_code_class class;
+ enum tree_code_class tclass;
e = expr;
/* We might like to warn about (say) "(int) f()", as the
@@ -955,10 +955,10 @@ convert_to_void (tree expr, const char *implicit, tsubst_flags_t complain)
e = TREE_OPERAND (e, 0);
code = TREE_CODE (e);
- class = TREE_CODE_CLASS (code);
- if ((class == tcc_comparison
- || class == tcc_unary
- || (class == tcc_binary
+ tclass = TREE_CODE_CLASS (code);
+ if ((tclass == tcc_comparison
+ || tclass == tcc_unary
+ || (tclass == tcc_binary
&& !(code == MODIFY_EXPR
|| code == INIT_EXPR
|| code == PREDECREMENT_EXPR
diff --git a/gcc/cp/cxx-pretty-print.c b/gcc/cp/cxx-pretty-print.c
index 62ff1fc3fc3..cf9ed482e84 100644
--- a/gcc/cp/cxx-pretty-print.c
+++ b/gcc/cp/cxx-pretty-print.c
@@ -452,7 +452,7 @@ pp_cxx_primary_expression (cxx_pretty_printer *pp, tree t)
reinterpret_cast < type-id > ( expression )
const_cast < type-id > ( expression )
typeid ( expression )
- typeif ( type-id ) */
+ typeid ( type-id ) */
static void
pp_cxx_postfix_expression (cxx_pretty_printer *pp, tree t)
@@ -810,7 +810,7 @@ pp_cxx_pm_expression (cxx_pretty_printer *pp, tree t)
{
switch (TREE_CODE (t))
{
- /* Handle unfortunate OFFESET_REF overloading here. */
+ /* Handle unfortunate OFFSET_REF overloading here. */
case OFFSET_REF:
if (TYPE_P (TREE_OPERAND (t, 0)))
{
@@ -2016,7 +2016,7 @@ pp_cxx_template_parameter (cxx_pretty_printer *pp, tree t)
pp_cxx_identifier (pp, "...");
if (DECL_NAME (parameter))
pp_cxx_tree_identifier (pp, DECL_NAME (parameter));
- /* FIXME: Chech if we should print also default argument. */
+ /* FIXME: Check if we should print also default argument. */
break;
case PARM_DECL:
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index a5a5574d7b4..630faacb354 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -315,7 +315,7 @@ current_tmpl_spec_kind (int n_class_scopes)
template <class T> void S<T>::f(int);
- The `class T' maches the `S<T>', leaving no template headers
+ The `class T' matches the `S<T>', leaving no template headers
corresponding to the `f'. */
return tsk_none;
else if (n_template_parm_scopes > n_class_scopes + 1)
@@ -800,12 +800,12 @@ insert_block (tree block)
itself, calling F for each. The DATA is passed to F as well. */
static int
-walk_namespaces_r (tree namespace, walk_namespaces_fn f, void* data)
+walk_namespaces_r (tree name_space, walk_namespaces_fn f, void* data)
{
int result = 0;
- tree current = NAMESPACE_LEVEL (namespace)->namespaces;
+ tree current = NAMESPACE_LEVEL (name_space)->namespaces;
- result |= (*f) (namespace, data);
+ result |= (*f) (name_space, data);
for (; current; current = TREE_CHAIN (current))
result |= walk_namespaces_r (current, f, data);
@@ -827,9 +827,9 @@ walk_namespaces (walk_namespaces_fn f, void* data)
wrapup_global_declarations for this NAMESPACE. */
int
-wrapup_globals_for_namespace (tree namespace, void* data)
+wrapup_globals_for_namespace (tree name_space, void* data)
{
- struct cp_binding_level *level = NAMESPACE_LEVEL (namespace);
+ struct cp_binding_level *level = NAMESPACE_LEVEL (name_space);
VEC(tree,gc) *statics = level->static_decls;
tree *vec = VEC_address (tree, statics);
int len = VEC_length (tree, statics);
@@ -1551,14 +1551,6 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
olddecl);
}
}
-
- if (DECL_DECLARED_INLINE_P (newdecl)
- && ! DECL_DECLARED_INLINE_P (olddecl)
- && TREE_ADDRESSABLE (olddecl) && warn_inline)
- {
- warning (0, "%q#D was used before it was declared inline", newdecl);
- warning (0, "%Jprevious non-inline declaration here", olddecl);
- }
}
}
@@ -1613,6 +1605,12 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
warning (OPT_Wredundant_decls, "redundant redeclaration of %qD in same scope", newdecl);
warning (OPT_Wredundant_decls, "previous declaration of %q+D", olddecl);
}
+
+ if (DECL_DELETED_FN (newdecl))
+ {
+ error ("deleted definition of %qD", newdecl);
+ error ("after previous declaration %q+D", olddecl);
+ }
}
/* Deal with C++: must preserve virtual function table size. */
@@ -1948,8 +1946,9 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
}
else if (new_defines_function && DECL_INITIAL (olddecl))
{
- /* C++ is always in in unit-at-a-time mode, so we never
- inline re-defined extern inline functions. */
+ /* Never inline re-defined extern inline functions.
+ FIXME: this could be better handled by keeping both
+ function as separate declarations. */
DECL_INLINE (newdecl) = 0;
DECL_UNINLINABLE (newdecl) = 1;
}
@@ -3591,7 +3590,7 @@ build_library_fn_1 (tree name, enum tree_code operator_code, tree type)
We assume that such functions never throw; if this is incorrect,
callers should unset TREE_NOTHROW. */
-tree
+static tree
build_library_fn (tree name, tree type)
{
tree fn = build_library_fn_1 (name, ERROR_MARK, type);
@@ -3630,12 +3629,18 @@ build_cp_library_fn_ptr (const char* name, tree type)
}
/* Like build_library_fn, but also pushes the function so that we will
- be able to find it via IDENTIFIER_GLOBAL_VALUE. */
+ be able to find it via IDENTIFIER_GLOBAL_VALUE. Also, the function
+ may throw exceptions listed in RAISES. */
tree
-push_library_fn (tree name, tree type)
+push_library_fn (tree name, tree type, tree raises)
{
- tree fn = build_library_fn (name, type);
+ tree fn;
+
+ if (raises)
+ type = build_exception_variant (type, raises);
+
+ fn = build_library_fn (name, type);
pushdecl_top_level (fn);
return fn;
}
@@ -3660,7 +3665,7 @@ tree
push_void_library_fn (tree name, tree parmtypes)
{
tree type = build_function_type (void_type_node, parmtypes);
- return push_library_fn (name, type);
+ return push_library_fn (name, type, NULL_TREE);
}
/* Like push_library_fn, but also note that this function throws
@@ -3669,7 +3674,7 @@ push_void_library_fn (tree name, tree parmtypes)
tree
push_throw_library_fn (tree name, tree type)
{
- tree fn = push_library_fn (name, type);
+ tree fn = push_library_fn (name, type, NULL_TREE);
TREE_THIS_VOLATILE (fn) = 1;
TREE_NOTHROW (fn) = 0;
return fn;
@@ -3813,9 +3818,8 @@ check_tag_decl (cp_decl_specifier_seq *declspecs)
/* Anonymous unions are objects, so they can have specifiers. */;
SET_ANON_AGGR_TYPE_P (declared_type);
- if (TREE_CODE (declared_type) != UNION_TYPE && pedantic
- && !in_system_header)
- pedwarn ("ISO C++ prohibits anonymous structs");
+ if (TREE_CODE (declared_type) != UNION_TYPE && !in_system_header)
+ pedwarn (OPT_pedantic, "ISO C++ prohibits anonymous structs");
}
else
@@ -3932,13 +3936,14 @@ groktypename (cp_decl_specifier_seq *type_specifiers,
grokfield.) The DECL corresponding to the DECLARATOR is returned.
If an error occurs, the error_mark_node is returned instead.
- DECLSPECS are the decl-specifiers for the declaration. INITIALIZED
- is true if an explicit initializer is present, but false if this is
- a variable implicitly initialized via a default constructor.
- ATTRIBUTES and PREFIX_ATTRIBUTES are GNU attributes associated with
- this declaration. *PUSHED_SCOPE_P is set to the scope entered in
- this function, if any; if set, the caller is responsible for
- calling pop_scope. */
+ DECLSPECS are the decl-specifiers for the declaration. INITIALIZED is 1
+ if an explicit initializer is present, or 2 for an explicitly defaulted
+ function, or 3 for an explicitly deleted function, but 0 if this is a
+ variable implicitly initialized via a default constructor. ATTRIBUTES
+ and PREFIX_ATTRIBUTES are GNU attributes associated with this
+ declaration. *PUSHED_SCOPE_P is set to the scope entered in this
+ function, if any; if set, the caller is responsible for calling
+ pop_scope. */
tree
start_decl (const cp_declarator *declarator,
@@ -3992,12 +3997,15 @@ start_decl (const cp_declarator *declarator,
switch (TREE_CODE (decl))
{
case TYPE_DECL:
- error ("typedef %qD is initialized (use __typeof__ instead)", decl);
+ error ("typedef %qD is initialized (use decltype instead)", decl);
return error_mark_node;
case FUNCTION_DECL:
- error ("function %q#D is initialized like a variable", decl);
- return error_mark_node;
+ if (initialized == 3)
+ /* We'll handle the rest of the semantics later, but we need to
+ set this now so it's visible to duplicate_decls. */
+ DECL_DELETED_FN (decl) = 1;
+ break;
default:
break;
@@ -4345,7 +4353,7 @@ check_array_designated_initializer (const constructor_elt *ce)
if (ce->index)
{
/* The parser only allows identifiers as designated
- intializers. */
+ initializers. */
gcc_assert (TREE_CODE (ce->index) == IDENTIFIER_NODE);
error ("name %qD used in a GNU-style designated "
"initializer for an array", ce->index);
@@ -5687,10 +5695,38 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
else
abstract_virtuals_error (decl, type);
- if (TREE_CODE (decl) == FUNCTION_DECL
- || TREE_TYPE (decl) == error_mark_node)
+ if (TREE_TYPE (decl) == error_mark_node)
/* No initialization required. */
;
+ else if (TREE_CODE (decl) == FUNCTION_DECL)
+ {
+ if (init)
+ {
+ if (init == ridpointers[(int)RID_DELETE])
+ {
+ /* fixme check this is 1st decl */
+ DECL_DELETED_FN (decl) = 1;
+ DECL_DECLARED_INLINE_P (decl) = 1;
+ DECL_INITIAL (decl) = error_mark_node;
+ }
+ else if (init == ridpointers[(int)RID_DEFAULT])
+ {
+ if (!defaultable_fn_p (decl))
+ error ("%qD cannot be defaulted", decl);
+ else
+ {
+ /* An out-of-class default definition is defined at
+ the point where it is explicitly defaulted. */
+ DECL_DEFAULTED_FN (decl) = 1;
+ if (DECL_INITIAL (decl) == error_mark_node)
+ synthesize_method (decl);
+ }
+ }
+ else
+ error ("function %q#D is initialized like a variable", decl);
+ }
+ /* else no initialization required. */
+ }
else if (DECL_EXTERNAL (decl)
&& ! (DECL_LANG_SPECIFIC (decl)
&& DECL_NOT_REALLY_EXTERN (decl)))
@@ -5916,8 +5952,6 @@ start_cleanup_fn (void)
actually needed. It is unlikely that it will be inlined, since
it is only called via a function pointer, but we avoid unnecessary
emissions this way. */
- DECL_INLINE (fndecl) = 1;
- DECL_DECLARED_INLINE_P (fndecl) = 1;
DECL_INTERFACE_KNOWN (fndecl) = 1;
/* Build the parameter. */
if (use_cxa_atexit)
@@ -6141,9 +6175,10 @@ expand_static_init (tree decl, tree init)
void_list_node);
tree vfntype = build_function_type (void_type_node, argtypes);
acquire_fn = push_library_fn
- (acquire_fn, build_function_type (integer_type_node, argtypes));
- release_fn = push_library_fn (release_fn, vfntype);
- abort_fn = push_library_fn (abort_fn, vfntype);
+ (acquire_fn, build_function_type (integer_type_node, argtypes),
+ NULL_TREE);
+ release_fn = push_library_fn (release_fn, vfntype, NULL_TREE);
+ abort_fn = push_library_fn (abort_fn, vfntype, NULL_TREE);
}
else
{
@@ -6606,7 +6641,7 @@ grokfndecl (tree ctype,
/* We inline functions that are explicitly declared inline, or, when
the user explicitly asks us to, all functions. */
if (DECL_DECLARED_INLINE_P (decl)
- || (flag_inline_trees == 2 && !DECL_INLINE (decl) && funcdef_flag))
+ || (!DECL_INLINE (decl) && funcdef_flag))
DECL_INLINE (decl) = 1;
DECL_EXTERNAL (decl) = 1;
@@ -7004,8 +7039,8 @@ check_static_variable_definition (tree decl, tree type)
error ("ISO C++ forbids in-class initialization of non-const "
"static member %qD",
decl);
- else if (pedantic && !INTEGRAL_TYPE_P (type))
- pedwarn ("ISO C++ forbids initialization of member constant "
+ else if (!INTEGRAL_TYPE_P (type))
+ pedwarn (OPT_pedantic, "ISO C++ forbids initialization of member constant "
"%qD of non-integral type %qT", decl, type);
return 0;
@@ -7050,7 +7085,7 @@ compute_array_index_type (tree name, tree size)
if (!abi_version_at_least (2) && processing_template_decl)
/* For abi-1, we handled all instances in templates the same way,
- even when they were non-dependent. This effects the manglings
+ even when they were non-dependent. This affects the manglings
produced. So, we do the normal checking for non-dependent
sizes, but at the end we'll return the same type that abi-1
would have, but with TYPE_CANONICAL set to the "right"
@@ -7082,12 +7117,12 @@ compute_array_index_type (tree name, tree size)
}
/* As an extension we allow zero-sized arrays. We always allow
them in system headers because glibc uses them. */
- else if (integer_zerop (size) && pedantic && !in_system_header)
+ else if (integer_zerop (size) && !in_system_header)
{
if (name)
- pedwarn ("ISO C++ forbids zero-size array %qD", name);
+ pedwarn (OPT_pedantic, "ISO C++ forbids zero-size array %qD", name);
else
- pedwarn ("ISO C++ forbids zero-size array");
+ pedwarn (OPT_pedantic, "ISO C++ forbids zero-size array");
}
}
else if (TREE_CONSTANT (size))
@@ -7103,9 +7138,9 @@ compute_array_index_type (tree name, tree size)
else if (pedantic && warn_vla != 0)
{
if (name)
- pedwarn ("ISO C++ forbids variable length array %qD", name);
+ pedwarn (OPT_Wvla, "ISO C++ forbids variable length array %qD", name);
else
- pedwarn ("ISO C++ forbids variable length array");
+ pedwarn (OPT_Wvla, "ISO C++ forbids variable length array");
}
else if (warn_vla > 0)
{
@@ -7362,7 +7397,7 @@ check_var_type (tree identifier, tree type)
Don't make a DECL node; just return the ..._TYPE node.
FIELD for a struct or union field; make a FIELD_DECL.
BITFIELD for a field with specified width.
- INITIALIZED is 1 if the decl has an initializer.
+ INITIALIZED is as for start_decl.
ATTRLIST is a pointer to the list of attributes, which may be NULL
if there are none; *ATTRLIST may be modified if attributes from inside
@@ -7460,6 +7495,9 @@ grokdeclarator (const cp_declarator *declarator,
else if (decl_context == BITFIELD)
bitfield = 1, decl_context = FIELD;
+ if (initialized > 1)
+ funcdef_flag = true;
+
/* Look inside a declarator for the name being declared
and get it as a string, for an error message. */
for (id_declarator = declarator;
@@ -7736,7 +7774,8 @@ grokdeclarator (const cp_declarator *declarator,
else if (! is_main)
permerror ("ISO C++ forbids declaration of %qs with no type", name);
else if (pedantic)
- pedwarn ("ISO C++ forbids declaration of %qs with no type", name);
+ pedwarn (OPT_pedantic,
+ "ISO C++ forbids declaration of %qs with no type", name);
else
warning (OPT_Wreturn_type,
"ISO C++ forbids declaration of %qs with no type", name);
@@ -7791,7 +7830,8 @@ grokdeclarator (const cp_declarator *declarator,
ok = 1;
if (!explicit_int && !defaulted_int && !explicit_char && pedantic)
{
- pedwarn ("long, short, signed or unsigned used invalidly for %qs",
+ pedwarn (OPT_pedantic,
+ "long, short, signed or unsigned used invalidly for %qs",
name);
if (flag_pedantic_errors)
ok = 0;
@@ -7896,7 +7936,8 @@ grokdeclarator (const cp_declarator *declarator,
if (pedantic)
{
tree bad_type = build_qualified_type (type, type_quals);
- pedwarn ("ignoring %qV qualifiers added to function type %qT",
+ pedwarn (OPT_pedantic,
+ "ignoring %qV qualifiers added to function type %qT",
bad_type, type);
}
type_quals = TYPE_UNQUALIFIED;
@@ -8005,19 +8046,6 @@ grokdeclarator (const cp_declarator *declarator,
storage_class = sc_none;
}
}
- else if (storage_class == sc_extern && initialized
- && !funcdef_flag)
- {
- if (toplevel_bindings_p ())
- {
- /* It's common practice (and completely valid) to have a const
- be initialized and declared extern. */
- if (!(type_quals & TYPE_QUAL_CONST))
- warning (0, "%qs initialized and declared %<extern%>", name);
- }
- else
- error ("%qs has both %<extern%> and initializer", name);
- }
else if (storage_class == sc_extern && funcdef_flag
&& ! toplevel_bindings_p ())
error ("nested function %qs declared %<extern%>", name);
@@ -8036,7 +8064,11 @@ grokdeclarator (const cp_declarator *declarator,
}
if (storage_class && friendp)
- error ("storage class specifiers invalid in friend function declarations");
+ {
+ error ("storage class specifiers invalid in friend function declarations");
+ storage_class = sc_none;
+ staticp = 0;
+ }
if (!id_declarator)
unqualified_id = NULL_TREE;
@@ -9133,10 +9165,12 @@ grokdeclarator (const cp_declarator *declarator,
&& pedantic)
{
if (storage_class == sc_static)
- pedwarn ("%<static%> specified invalid for function %qs "
+ pedwarn (OPT_pedantic,
+ "%<static%> specified invalid for function %qs "
"declared out of global scope", name);
else
- pedwarn ("%<inline%> specifier invalid for function %qs "
+ pedwarn (OPT_pedantic,
+ "%<inline%> specifier invalid for function %qs "
"declared out of global scope", name);
}
@@ -9224,14 +9258,27 @@ grokdeclarator (const cp_declarator *declarator,
}
if (storage_class == sc_extern && pedantic)
{
- pedwarn ("cannot explicitly declare member %q#D to have "
- "extern linkage",
- decl);
+ pedwarn (OPT_pedantic,
+ "cannot explicitly declare member %q#D to have "
+ "extern linkage", decl);
storage_class = sc_none;
}
}
}
+ if (storage_class == sc_extern && initialized && !funcdef_flag)
+ {
+ if (toplevel_bindings_p ())
+ {
+ /* It's common practice (and completely valid) to have a const
+ be initialized and declared extern. */
+ if (!(type_quals & TYPE_QUAL_CONST))
+ warning (0, "%qs initialized and declared %<extern%>", name);
+ }
+ else
+ error ("%qs has both %<extern%> and initializer", name);
+ }
+
/* Record `register' declaration for warnings on &
and in case doing stupid register allocation. */
@@ -9662,6 +9709,8 @@ grok_special_member_properties (tree decl)
are no other parameters or else all other parameters have
default arguments. */
TYPE_HAS_INIT_REF (class_type) = 1;
+ if (!DECL_DEFAULTED_FN (decl))
+ TYPE_HAS_COMPLEX_INIT_REF (class_type) = 1;
if (ctor > 1)
TYPE_HAS_CONST_INIT_REF (class_type) = 1;
}
@@ -9683,6 +9732,8 @@ grok_special_member_properties (tree decl)
if (assop)
{
TYPE_HAS_ASSIGN_REF (class_type) = 1;
+ if (!DECL_DEFAULTED_FN (decl))
+ TYPE_HAS_COMPLEX_ASSIGN_REF (class_type) = 1;
if (assop != 1)
TYPE_HAS_CONST_ASSIGN_REF (class_type) = 1;
}
@@ -10100,8 +10151,8 @@ grok_op_properties (tree decl, bool complain)
if (operator_code == POSTINCREMENT_EXPR
|| operator_code == POSTDECREMENT_EXPR)
{
- if (pedantic)
- pedwarn ("%qD cannot have default arguments", decl);
+ pedwarn (OPT_pedantic, "%qD cannot have default arguments",
+ decl);
}
else
{
@@ -10835,7 +10886,7 @@ finish_enum (tree enumtype)
underlying_type = integer_types[itk_unsigned_long_long];
}
- /* Compute the minium and maximum values for the type.
+ /* Compute the minimum and maximum values for the type.
[dcl.enum]
@@ -11957,13 +12008,15 @@ finish_function (int flags)
/* Don't complain if we abort or throw. */
&& !current_function_returns_abnormally
&& !DECL_NAME (DECL_RESULT (fndecl))
- /* Normally, with -Wreturn-type, flow will complain. Unless we're an
- inline function, as we might never be compiled separately. */
- && (DECL_INLINE (fndecl) || processing_template_decl)
+ && !TREE_NO_WARNING (fndecl)
/* Structor return values (if any) are set by the compiler. */
&& !DECL_CONSTRUCTOR_P (fndecl)
&& !DECL_DESTRUCTOR_P (fndecl))
- warning (OPT_Wreturn_type, "no return statement in function returning non-void");
+ {
+ warning (OPT_Wreturn_type,
+ "no return statement in function returning non-void");
+ TREE_NO_WARNING (fndecl) = 1;
+ }
/* Store the end of the function, so that we get good line number
info for the epilogue. */
@@ -11985,7 +12038,7 @@ finish_function (int flags)
f->extern_decl_map = NULL;
/* Handle attribute((warn_unused_result)). Relies on gimple input. */
- c_warn_unused_result (&DECL_SAVED_TREE (fndecl));
+ c_warn_unused_result (gimple_body (fndecl));
}
/* Clear out the bits we don't need. */
local_names = NULL;
@@ -12191,7 +12244,7 @@ maybe_register_incomplete_var (tree var)
}
/* Called when a class type (given by TYPE) is defined. If there are
- any existing VAR_DECLs whose type hsa been completed by this
+ any existing VAR_DECLs whose type has been completed by this
declaration, update them now. */
void
@@ -12256,7 +12309,7 @@ cxx_maybe_build_cleanup (tree decl)
initial checks on the attribute. Note that those checks
include ensuring that the function found is not an overloaded
function, or an object with an overloaded call operator,
- etc.; we can rely on the fact that the functionfound is an
+ etc.; we can rely on the fact that the function found is an
ordinary FUNCTION_DECL. */
fn = lookup_name (id);
arg = build_address (decl);
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index a5ece9a6709..20b0826faf2 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -51,6 +51,7 @@ along with GCC; see the file COPYING3. If not see
#include "c-pragma.h"
#include "tree-dump.h"
#include "intl.h"
+#include "gimple.h"
extern cpp_reader *parse_in;
@@ -821,7 +822,25 @@ grokfield (const cp_declarator *declarator,
{
/* Initializers for functions are rejected early in the parser.
If we get here, it must be a pure specifier for a method. */
- if (TREE_CODE (TREE_TYPE (value)) == METHOD_TYPE)
+ if (init == ridpointers[(int)RID_DELETE])
+ {
+ DECL_DELETED_FN (value) = 1;
+ DECL_DECLARED_INLINE_P (value) = 1;
+ DECL_INITIAL (value) = error_mark_node;
+ }
+ else if (init == ridpointers[(int)RID_DEFAULT])
+ {
+ if (!defaultable_fn_p (value))
+ error ("%qD cannot be defaulted", value);
+ else
+ {
+ DECL_DEFAULTED_FN (value) = 1;
+ DECL_INITIALIZED_IN_CLASS_P (value) = 1;
+ DECL_DECLARED_INLINE_P (value) = 1;
+ DECL_INLINE (value) = 1;
+ }
+ }
+ else if (TREE_CODE (TREE_TYPE (value)) == METHOD_TYPE)
{
gcc_assert (error_operand_p (init) || integer_zerop (init));
DECL_PURE_VIRTUAL_P (value) = 1;
@@ -1963,6 +1982,14 @@ determine_visibility (tree decl)
/* tinfo visibility is based on the type it's for. */
constrain_visibility
(decl, type_visibility (TREE_TYPE (DECL_NAME (decl))));
+
+ /* Give the target a chance to override the visibility associated
+ with DECL. */
+ if (TREE_PUBLIC (decl)
+ && !DECL_REALLY_EXTERN (decl)
+ && CLASS_TYPE_P (TREE_TYPE (DECL_NAME (decl)))
+ && !CLASSTYPE_VISIBILITY_SPECIFIED (TREE_TYPE (DECL_NAME (decl))))
+ targetm.cxx.determine_class_data_visibility (decl);
}
else if (use_template)
/* Template instantiations and specializations get visibility based
@@ -3396,7 +3423,7 @@ cp_write_global_declarations (void)
{
/* Does it need synthesizing? */
if (DECL_ARTIFICIAL (decl) && ! DECL_INITIAL (decl)
- && (! DECL_REALLY_EXTERN (decl) || DECL_INLINE (decl)))
+ && (! DECL_REALLY_EXTERN (decl) || possibly_inlined_p (decl)))
{
/* Even though we're already at the top-level, we push
there again. That way, when we pop back a few lines
@@ -3413,7 +3440,7 @@ cp_write_global_declarations (void)
reconsider = true;
}
- if (!DECL_SAVED_TREE (decl))
+ if (!gimple_body (decl))
continue;
/* We lie to the back end, pretending that some functions
@@ -3657,6 +3684,22 @@ check_default_args (tree x)
}
}
+/* Return true if function DECL can be inlined. This is used to force
+ instantiation of methods that might be interesting for inlining. */
+bool
+possibly_inlined_p (tree decl)
+{
+ gcc_assert (TREE_CODE (decl) == FUNCTION_DECL);
+ if (DECL_UNINLINABLE (decl))
+ return false;
+ if (!optimize)
+ return DECL_DECLARED_INLINE_P (decl);
+ /* When optimizing, we might inline everything when flatten
+ attribute or heuristics inlining for size or autoinlining
+ is used. */
+ return true;
+}
+
/* Mark DECL (either a _DECL or a BASELINK) as "used" in the program.
If DECL is a specialization or implicitly declared class member,
generate the actual definition. */
@@ -3731,7 +3774,7 @@ mark_used (tree decl)
/* Is it a synthesized method that needs to be synthesized? */
if (TREE_CODE (decl) == FUNCTION_DECL
&& DECL_NONSTATIC_MEMBER_FUNCTION_P (decl)
- && DECL_ARTIFICIAL (decl)
+ && DECL_DEFAULTED_FN (decl)
&& !DECL_THUNK_P (decl)
&& ! DECL_INITIAL (decl)
/* Kludge: don't synthesize for default args. Unfortunately this
@@ -3744,12 +3787,19 @@ mark_used (tree decl)
/* If we've already synthesized the method we don't need to
do the instantiation test below. */
}
+ else if (TREE_CODE (decl) == FUNCTION_DECL
+ && DECL_DELETED_FN (decl))
+ {
+ error ("deleted function %q+D", decl);
+ error ("used here");
+ }
else if ((DECL_NON_THUNK_FUNCTION_P (decl) || TREE_CODE (decl) == VAR_DECL)
&& DECL_LANG_SPECIFIC (decl) && DECL_TEMPLATE_INFO (decl)
&& (!DECL_EXPLICIT_INSTANTIATION (decl)
|| (TREE_CODE (decl) == FUNCTION_DECL
- && DECL_INLINE (DECL_TEMPLATE_RESULT
- (template_for_substitution (decl))))
+ && possibly_inlined_p
+ (DECL_TEMPLATE_RESULT (
+ template_for_substitution (decl))))
/* We need to instantiate static data members so that there
initializers are available in integral constant
expressions. */
diff --git a/gcc/cp/error.c b/gcc/cp/error.c
index 80aa6e962d2..ef26ad9114a 100644
--- a/gcc/cp/error.c
+++ b/gcc/cp/error.c
@@ -2685,7 +2685,7 @@ maybe_warn_cpp0x (const char* str)
/* We really want to suppress this warning in system headers,
because libstdc++ uses variadic templates even when we aren't
in C++0x mode. */
- pedwarn ("%s only available with -std=c++0x", str);
+ pedwarn (0, "%s only available with -std=c++0x or -std=gnu++0x", str);
}
/* Warn about the use of variadic templates when appropriate. */
diff --git a/gcc/cp/except.c b/gcc/cp/except.c
index 3070cda4d54..56a551212fe 100644
--- a/gcc/cp/except.c
+++ b/gcc/cp/except.c
@@ -1,6 +1,7 @@
/* Handle exceptional things in C++.
Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- 2000, 2001, 2002, 2003, 2004, 2005, 2007 Free Software Foundation, Inc.
+ 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008
+ Free Software Foundation, Inc.
Contributed by Michael Tiemann <tiemann@cygnus.com>
Rewritten by Mike Stump <mrs@cygnus.com>, based upon an
initial re-implementation courtesy Tad Hunt.
@@ -38,6 +39,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-inline.h"
#include "tree-iterator.h"
#include "target.h"
+#include "gimple.h"
static void push_eh_cleanup (tree);
static tree prepare_eh_type (tree);
@@ -52,7 +54,7 @@ static tree wrap_cleanups_r (tree *, int *, void *);
static int complete_ptr_ref_or_void_ptr_p (tree, tree);
static bool is_admissible_throw_operand (tree);
static int can_convert_eh (tree, tree);
-static tree cp_protect_cleanup_actions (void);
+static gimple cp_protect_cleanup_actions (void);
/* Sets up all the global eh stuff that needs to be initialized at the
start of compilation. */
@@ -91,14 +93,14 @@ init_exception_processing (void)
/* Returns an expression to be executed if an unhandled exception is
propagated out of a cleanup region. */
-static tree
+static gimple
cp_protect_cleanup_actions (void)
{
/* [except.terminate]
When the destruction of an object during stack unwinding exits
using an exception ... void terminate(); is called. */
- return build_call_n (terminate_node, 0);
+ return gimple_build_call (terminate_node, 0);
}
static tree
@@ -160,6 +162,21 @@ build_exc_ptr (void)
return build0 (EXC_PTR_EXPR, ptr_type_node);
}
+/* Declare a function NAME, returning RETURN_TYPE, taking a single
+ parameter PARM_TYPE, with an empty exception specification.
+
+ Note that the C++ ABI document does not have a throw-specifier on
+ the routines declared below via this function. The declarations
+ are consistent with the actual implementations in libsupc++. */
+
+static tree
+declare_nothrow_library_fn (tree name, tree return_type, tree parm_type)
+{
+ tree tmp = tree_cons (NULL_TREE, parm_type, void_list_node);
+ return push_library_fn (name, build_function_type (return_type, tmp),
+ empty_except_spec);
+}
+
/* Build up a call to __cxa_get_exception_ptr so that we can build a
copy constructor for the thrown object. */
@@ -171,9 +188,8 @@ do_get_exception_ptr (void)
fn = get_identifier ("__cxa_get_exception_ptr");
if (!get_global_value_if_present (fn, &fn))
{
- /* Declare void* __cxa_get_exception_ptr (void *). */
- tree tmp = tree_cons (NULL_TREE, ptr_type_node, void_list_node);
- fn = push_library_fn (fn, build_function_type (ptr_type_node, tmp));
+ /* Declare void* __cxa_get_exception_ptr (void *) throw(). */
+ fn = declare_nothrow_library_fn (fn, ptr_type_node, ptr_type_node);
}
return cp_build_function_call (fn, tree_cons (NULL_TREE, build_exc_ptr (),
@@ -192,9 +208,8 @@ do_begin_catch (void)
fn = get_identifier ("__cxa_begin_catch");
if (!get_global_value_if_present (fn, &fn))
{
- /* Declare void* __cxa_begin_catch (void *). */
- tree tmp = tree_cons (NULL_TREE, ptr_type_node, void_list_node);
- fn = push_library_fn (fn, build_function_type (ptr_type_node, tmp));
+ /* Declare void* __cxa_begin_catch (void *) throw(). */
+ fn = declare_nothrow_library_fn (fn, ptr_type_node, ptr_type_node);
}
return cp_build_function_call (fn, tree_cons (NULL_TREE, build_exc_ptr (),
@@ -543,9 +558,8 @@ do_allocate_exception (tree type)
fn = get_identifier ("__cxa_allocate_exception");
if (!get_global_value_if_present (fn, &fn))
{
- /* Declare void *__cxa_allocate_exception(size_t). */
- tree tmp = tree_cons (NULL_TREE, size_type_node, void_list_node);
- fn = push_library_fn (fn, build_function_type (ptr_type_node, tmp));
+ /* Declare void *__cxa_allocate_exception(size_t) throw(). */
+ fn = declare_nothrow_library_fn (fn, ptr_type_node, size_type_node);
}
return cp_build_function_call (fn,
@@ -565,9 +579,8 @@ do_free_exception (tree ptr)
fn = get_identifier ("__cxa_free_exception");
if (!get_global_value_if_present (fn, &fn))
{
- /* Declare void __cxa_free_exception (void *). */
- fn = push_void_library_fn (fn, tree_cons (NULL_TREE, ptr_type_node,
- void_list_node));
+ /* Declare void __cxa_free_exception (void *) throw(). */
+ fn = declare_nothrow_library_fn (fn, void_type_node, ptr_type_node);
}
return cp_build_function_call (fn, tree_cons (NULL_TREE, ptr, NULL_TREE),
diff --git a/gcc/cp/friend.c b/gcc/cp/friend.c
index 96c6dc653ba..090f84db288 100644
--- a/gcc/cp/friend.c
+++ b/gcc/cp/friend.c
@@ -59,15 +59,15 @@ is_friend (tree type, tree supplicant)
tree friends = FRIEND_DECLS (list);
for (; friends ; friends = TREE_CHAIN (friends))
{
- tree friend = TREE_VALUE (friends);
+ tree this_friend = TREE_VALUE (friends);
- if (friend == NULL_TREE)
+ if (this_friend == NULL_TREE)
continue;
- if (supplicant == friend)
+ if (supplicant == this_friend)
return 1;
- if (is_specialization_of_friend (supplicant, friend))
+ if (is_specialization_of_friend (supplicant, this_friend))
return 1;
}
break;
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index 3e9e612f2b4..3deb85d432b 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -346,7 +346,7 @@ build_value_init_1 (tree type, bool have_ctor)
if (CLASS_TYPE_P (type))
{
- if (TYPE_HAS_USER_CONSTRUCTOR (type) && !have_ctor)
+ if (type_has_user_provided_constructor (type) && !have_ctor)
return build_cplus_new
(type,
build_special_member_call (NULL_TREE, complete_ctor_identifier,
@@ -469,13 +469,13 @@ perform_member_init (tree member, tree init)
{
tree decl;
tree type = TREE_TYPE (member);
- bool explicit;
+ bool is_explicit;
- explicit = (init != NULL_TREE);
+ is_explicit = (init != NULL_TREE);
/* Effective C++ rule 12 requires that all data members be
initialized. */
- if (warn_ecpp && !explicit && TREE_CODE (type) != ARRAY_TYPE)
+ if (warn_ecpp && !is_explicit && TREE_CODE (type) != ARRAY_TYPE)
warning (OPT_Weffc__, "%J%qD should be initialized in the member initialization "
"list", current_function_decl, member);
@@ -503,7 +503,7 @@ perform_member_init (tree member, tree init)
}
else if (TYPE_NEEDS_CONSTRUCTING (type))
{
- if (explicit
+ if (is_explicit
&& TREE_CODE (type) == ARRAY_TYPE
&& init != NULL_TREE
&& TREE_CHAIN (init) == NULL_TREE
@@ -516,14 +516,23 @@ perform_member_init (tree member, tree init)
tf_warning_or_error));
}
else
- finish_expr_stmt (build_aggr_init (decl, init, 0,
- tf_warning_or_error));
+ {
+ if (CP_TYPE_CONST_P (type)
+ && init == NULL_TREE
+ && !type_has_user_provided_default_constructor (type))
+ /* TYPE_NEEDS_CONSTRUCTING can be set just because we have a
+ vtable; still give this diagnostic. */
+ permerror ("%Juninitialized member %qD with %<const%> type %qT",
+ current_function_decl, member, type);
+ finish_expr_stmt (build_aggr_init (decl, init, 0,
+ tf_warning_or_error));
+ }
}
else
{
if (init == NULL_TREE)
{
- if (explicit)
+ if (is_explicit)
{
init = build_default_init (type, /*nelts=*/NULL_TREE);
if (TREE_CODE (type) == REFERENCE_TYPE)
@@ -1578,7 +1587,7 @@ build_offset_ref (tree type, tree member, bool address_p)
a class derived from that class (_class.base.init_). */
if (DECL_NONSTATIC_MEMBER_FUNCTION_P (member))
{
- /* Build a representation of a the qualified name suitable
+ /* Build a representation of the qualified name suitable
for use as the operand to "&" -- even though the "&" is
not actually present. */
member = build2 (OFFSET_REF, TREE_TYPE (member), decl, member);
@@ -1883,7 +1892,9 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
return error_mark_node;
is_initialized = (TYPE_NEEDS_CONSTRUCTING (elt_type) || init);
- if (CP_TYPE_CONST_P (elt_type) && !is_initialized)
+
+ if (CP_TYPE_CONST_P (elt_type) && !init
+ && !type_has_user_provided_default_constructor (elt_type))
{
if (complain & tf_error)
error ("uninitialized const in %<new%> of %q#T", elt_type);
@@ -3264,6 +3275,7 @@ build_vec_delete (tree base, tree maxindex,
{
/* Step back one from start of vector, and read dimension. */
tree cookie_addr;
+ tree size_ptr_type = build_pointer_type (sizetype);
if (TREE_SIDE_EFFECTS (base))
{
@@ -3273,8 +3285,8 @@ build_vec_delete (tree base, tree maxindex,
type = strip_array_types (TREE_TYPE (type));
cookie_addr = fold_build1 (NEGATE_EXPR, sizetype, TYPE_SIZE_UNIT (sizetype));
cookie_addr = build2 (POINTER_PLUS_EXPR,
- build_pointer_type (sizetype),
- base,
+ size_ptr_type,
+ fold_convert (size_ptr_type, base),
cookie_addr);
maxindex = cp_build_indirect_ref (cookie_addr, NULL, tf_warning_or_error);
}
diff --git a/gcc/cp/lex.c b/gcc/cp/lex.c
index 233011b85d9..2c169d1bd76 100644
--- a/gcc/cp/lex.c
+++ b/gcc/cp/lex.c
@@ -163,190 +163,33 @@ init_operators (void)
= "(round %=)";
}
-/* The reserved keyword table. */
-struct resword
-{
- const char *const word;
- ENUM_BITFIELD(rid) const rid : 16;
- const unsigned int disable : 16;
-};
-
-/* Disable mask. Keywords are disabled if (reswords[i].disable & mask) is
- _true_. */
-#define D_EXT 0x01 /* GCC extension */
-#define D_ASM 0x02 /* in C99, but has a switch to turn it off */
-#define D_OBJC 0x04 /* Objective C++ only */
-#define D_CXX0X 0x08 /* C++0x only */
-
-CONSTRAINT(ridbits_fit, RID_LAST_MODIFIER < sizeof(unsigned long) * CHAR_BIT);
-
-static const struct resword reswords[] =
-{
- { "_Complex", RID_COMPLEX, 0 },
- { "__FUNCTION__", RID_FUNCTION_NAME, 0 },
- { "__PRETTY_FUNCTION__", RID_PRETTY_FUNCTION_NAME, 0 },
- { "__alignof", RID_ALIGNOF, 0 },
- { "__alignof__", RID_ALIGNOF, 0 },
- { "__asm", RID_ASM, 0 },
- { "__asm__", RID_ASM, 0 },
- { "__attribute", RID_ATTRIBUTE, 0 },
- { "__attribute__", RID_ATTRIBUTE, 0 },
- { "__builtin_offsetof", RID_OFFSETOF, 0 },
- { "__builtin_va_arg", RID_VA_ARG, 0 },
- { "__complex", RID_COMPLEX, 0 },
- { "__complex__", RID_COMPLEX, 0 },
- { "__const", RID_CONST, 0 },
- { "__const__", RID_CONST, 0 },
- { "__decltype", RID_DECLTYPE, 0 },
- { "__extension__", RID_EXTENSION, 0 },
- { "__func__", RID_C99_FUNCTION_NAME, 0 },
- { "__has_nothrow_assign", RID_HAS_NOTHROW_ASSIGN, 0 },
- { "__has_nothrow_constructor", RID_HAS_NOTHROW_CONSTRUCTOR, 0 },
- { "__has_nothrow_copy", RID_HAS_NOTHROW_COPY, 0 },
- { "__has_trivial_assign", RID_HAS_TRIVIAL_ASSIGN, 0 },
- { "__has_trivial_constructor", RID_HAS_TRIVIAL_CONSTRUCTOR, 0 },
- { "__has_trivial_copy", RID_HAS_TRIVIAL_COPY, 0 },
- { "__has_trivial_destructor", RID_HAS_TRIVIAL_DESTRUCTOR, 0 },
- { "__has_virtual_destructor", RID_HAS_VIRTUAL_DESTRUCTOR, 0 },
- { "__is_abstract", RID_IS_ABSTRACT, 0 },
- { "__is_base_of", RID_IS_BASE_OF, 0 },
- { "__is_class", RID_IS_CLASS, 0 },
- { "__is_convertible_to", RID_IS_CONVERTIBLE_TO, 0 },
- { "__is_empty", RID_IS_EMPTY, 0 },
- { "__is_enum", RID_IS_ENUM, 0 },
- { "__is_pod", RID_IS_POD, 0 },
- { "__is_polymorphic", RID_IS_POLYMORPHIC, 0 },
- { "__is_union", RID_IS_UNION, 0 },
- { "__imag", RID_IMAGPART, 0 },
- { "__imag__", RID_IMAGPART, 0 },
- { "__inline", RID_INLINE, 0 },
- { "__inline__", RID_INLINE, 0 },
- { "__label__", RID_LABEL, 0 },
- { "__null", RID_NULL, 0 },
- { "__real", RID_REALPART, 0 },
- { "__real__", RID_REALPART, 0 },
- { "__restrict", RID_RESTRICT, 0 },
- { "__restrict__", RID_RESTRICT, 0 },
- { "__signed", RID_SIGNED, 0 },
- { "__signed__", RID_SIGNED, 0 },
- { "__thread", RID_THREAD, 0 },
- { "__typeof", RID_TYPEOF, 0 },
- { "__typeof__", RID_TYPEOF, 0 },
- { "__volatile", RID_VOLATILE, 0 },
- { "__volatile__", RID_VOLATILE, 0 },
- { "asm", RID_ASM, D_ASM },
- { "auto", RID_AUTO, 0 },
- { "bool", RID_BOOL, 0 },
- { "break", RID_BREAK, 0 },
- { "case", RID_CASE, 0 },
- { "catch", RID_CATCH, 0 },
- { "char", RID_CHAR, 0 },
- { "char16_t", RID_CHAR16, D_CXX0X },
- { "char32_t", RID_CHAR32, D_CXX0X },
- { "class", RID_CLASS, 0 },
- { "const", RID_CONST, 0 },
- { "const_cast", RID_CONSTCAST, 0 },
- { "continue", RID_CONTINUE, 0 },
- { "decltype", RID_DECLTYPE, D_CXX0X },
- { "default", RID_DEFAULT, 0 },
- { "delete", RID_DELETE, 0 },
- { "do", RID_DO, 0 },
- { "double", RID_DOUBLE, 0 },
- { "dynamic_cast", RID_DYNCAST, 0 },
- { "else", RID_ELSE, 0 },
- { "enum", RID_ENUM, 0 },
- { "explicit", RID_EXPLICIT, 0 },
- { "export", RID_EXPORT, 0 },
- { "extern", RID_EXTERN, 0 },
- { "false", RID_FALSE, 0 },
- { "float", RID_FLOAT, 0 },
- { "for", RID_FOR, 0 },
- { "friend", RID_FRIEND, 0 },
- { "goto", RID_GOTO, 0 },
- { "if", RID_IF, 0 },
- { "inline", RID_INLINE, 0 },
- { "int", RID_INT, 0 },
- { "long", RID_LONG, 0 },
- { "mutable", RID_MUTABLE, 0 },
- { "namespace", RID_NAMESPACE, 0 },
- { "new", RID_NEW, 0 },
- { "operator", RID_OPERATOR, 0 },
- { "private", RID_PRIVATE, 0 },
- { "protected", RID_PROTECTED, 0 },
- { "public", RID_PUBLIC, 0 },
- { "register", RID_REGISTER, 0 },
- { "reinterpret_cast", RID_REINTCAST, 0 },
- { "return", RID_RETURN, 0 },
- { "short", RID_SHORT, 0 },
- { "signed", RID_SIGNED, 0 },
- { "sizeof", RID_SIZEOF, 0 },
- { "static", RID_STATIC, 0 },
- { "static_assert", RID_STATIC_ASSERT, D_CXX0X },
- { "static_cast", RID_STATCAST, 0 },
- { "struct", RID_STRUCT, 0 },
- { "switch", RID_SWITCH, 0 },
- { "template", RID_TEMPLATE, 0 },
- { "this", RID_THIS, 0 },
- { "throw", RID_THROW, 0 },
- { "true", RID_TRUE, 0 },
- { "try", RID_TRY, 0 },
- { "typedef", RID_TYPEDEF, 0 },
- { "typename", RID_TYPENAME, 0 },
- { "typeid", RID_TYPEID, 0 },
- { "typeof", RID_TYPEOF, D_ASM|D_EXT },
- { "union", RID_UNION, 0 },
- { "unsigned", RID_UNSIGNED, 0 },
- { "using", RID_USING, 0 },
- { "virtual", RID_VIRTUAL, 0 },
- { "void", RID_VOID, 0 },
- { "volatile", RID_VOLATILE, 0 },
- { "wchar_t", RID_WCHAR, 0 },
- { "while", RID_WHILE, 0 },
-
- /* The remaining keywords are specific to Objective-C++. NB:
- All of them will remain _disabled_, since they are context-
- sensitive. */
-
- /* These ObjC keywords are recognized only immediately after
- an '@'. NB: The following C++ keywords double as
- ObjC keywords in this context: RID_CLASS, RID_PRIVATE,
- RID_PROTECTED, RID_PUBLIC, RID_THROW, RID_TRY and RID_CATCH. */
- { "compatibility_alias", RID_AT_ALIAS, D_OBJC },
- { "defs", RID_AT_DEFS, D_OBJC },
- { "encode", RID_AT_ENCODE, D_OBJC },
- { "end", RID_AT_END, D_OBJC },
- { "implementation", RID_AT_IMPLEMENTATION, D_OBJC },
- { "interface", RID_AT_INTERFACE, D_OBJC },
- { "protocol", RID_AT_PROTOCOL, D_OBJC },
- { "selector", RID_AT_SELECTOR, D_OBJC },
- { "finally", RID_AT_FINALLY, D_OBJC },
- { "synchronized", RID_AT_SYNCHRONIZED, D_OBJC },
- /* These are recognized only in protocol-qualifier context. */
- { "bycopy", RID_BYCOPY, D_OBJC },
- { "byref", RID_BYREF, D_OBJC },
- { "in", RID_IN, D_OBJC },
- { "inout", RID_INOUT, D_OBJC },
- { "oneway", RID_ONEWAY, D_OBJC },
- { "out", RID_OUT, D_OBJC },
-};
+/* Initialize the reserved words. */
void
init_reswords (void)
{
unsigned int i;
tree id;
- int mask = ((flag_no_asm ? D_ASM : 0)
- | D_OBJC
- | (flag_no_gnu_keywords ? D_EXT : 0)
- | ((cxx_dialect == cxx0x) ? 0 : D_CXX0X));
+ int mask = 0;
+
+ mask |= D_CONLY;
+ if (cxx_dialect != cxx0x)
+ mask |= D_CXX0X;
+ if (flag_no_asm)
+ mask |= D_ASM | D_EXT;
+ if (flag_no_gnu_keywords)
+ mask |= D_EXT;
+
+ /* The Objective-C keywords are all context-dependent. */
+ mask |= D_OBJC;
ridpointers = GGC_CNEWVEC (tree, (int) RID_MAX);
- for (i = 0; i < ARRAY_SIZE (reswords); i++)
+ for (i = 0; i < num_c_common_reswords; i++)
{
- id = get_identifier (reswords[i].word);
- C_SET_RID_CODE (id, reswords[i].rid);
- ridpointers [(int) reswords[i].rid] = id;
- if (! (reswords[i].disable & mask))
+ id = get_identifier (c_common_reswords[i].word);
+ C_SET_RID_CODE (id, c_common_reswords[i].rid);
+ ridpointers [(int) c_common_reswords[i].rid] = id;
+ if (! (c_common_reswords[i].disable & mask))
C_IS_RESERVED_WORD (id) = 1;
}
}
@@ -404,17 +247,6 @@ cxx_init (void)
cxx_init_decl_processing ();
- /* The fact that G++ uses COMDAT for many entities (inline
- functions, template instantiations, virtual tables, etc.) mean
- that it is fundamentally unreliable to try to make decisions
- about whether or not to output a particular entity until the end
- of the compilation. However, the inliner requires that functions
- be provided to the back end if they are to be inlined.
- Therefore, we always use unit-at-a-time mode; in that mode, we
- can provide entities to the back end and it will decide what to
- emit based on what is actually needed. */
- flag_unit_at_a_time = 1;
-
if (c_common_init () == false)
{
input_location = saved_loc;
diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c
index b27b2db9b3a..0703d0a96f7 100644
--- a/gcc/cp/mangle.c
+++ b/gcc/cp/mangle.c
@@ -974,19 +974,19 @@ write_template_prefix (const tree node)
tree type = DECL_P (node) ? TREE_TYPE (node) : node;
tree context = CP_DECL_CONTEXT (decl);
tree template_info;
- tree template;
+ tree templ;
tree substitution;
MANGLE_TRACE_TREE ("template-prefix", node);
/* Find the template decl. */
if (decl_is_template_id (decl, &template_info))
- template = TI_TEMPLATE (template_info);
+ templ = TI_TEMPLATE (template_info);
else
{
gcc_assert (CLASSTYPE_TEMPLATE_ID_P (type));
- template = TYPE_TI_TEMPLATE (type);
+ templ = TYPE_TI_TEMPLATE (type);
}
/* For a member template, though, the template name for the
@@ -1012,21 +1012,21 @@ write_template_prefix (const tree node)
substitution candidate by a TREE_LIST whose purpose is `Outer<int>'
and whose value is `Outer<T>::Inner<U>'. */
if (TYPE_P (context))
- substitution = build_tree_list (context, template);
+ substitution = build_tree_list (context, templ);
else
- substitution = template;
+ substitution = templ;
if (find_substitution (substitution))
return;
/* In G++ 3.2, the name of the template template parameter was used. */
- if (TREE_CODE (TREE_TYPE (template)) == TEMPLATE_TEMPLATE_PARM
+ if (TREE_CODE (TREE_TYPE (templ)) == TEMPLATE_TEMPLATE_PARM
&& !abi_version_at_least (2))
G.need_abi_warning = true;
- if (TREE_CODE (TREE_TYPE (template)) == TEMPLATE_TEMPLATE_PARM
+ if (TREE_CODE (TREE_TYPE (templ)) == TEMPLATE_TEMPLATE_PARM
&& abi_version_at_least (2))
- write_template_param (TREE_TYPE (template));
+ write_template_param (TREE_TYPE (templ));
else
{
write_prefix (context);
@@ -1056,7 +1056,10 @@ write_unqualified_name (const tree decl)
else if (DECL_LANG_SPECIFIC (decl) != NULL && DECL_DESTRUCTOR_P (decl))
write_special_name_destructor (decl);
else if (DECL_NAME (decl) == NULL_TREE)
- write_source_name (DECL_ASSEMBLER_NAME (decl));
+ {
+ gcc_assert (DECL_ASSEMBLER_NAME_SET_P (decl));
+ write_source_name (DECL_ASSEMBLER_NAME (decl));
+ }
else if (DECL_CONV_FN_P (decl))
{
/* Conversion operator. Handle it right here.
@@ -2480,24 +2483,24 @@ write_template_param (const tree parm)
static void
write_template_template_param (const tree parm)
{
- tree template = NULL_TREE;
+ tree templ = NULL_TREE;
/* PARM, a TEMPLATE_TEMPLATE_PARM, is an instantiation of the
template template parameter. The substitution candidate here is
only the template. */
if (TREE_CODE (parm) == BOUND_TEMPLATE_TEMPLATE_PARM)
{
- template
+ templ
= TI_TEMPLATE (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (parm));
- if (find_substitution (template))
+ if (find_substitution (templ))
return;
}
/* <template-param> encodes only the template parameter position,
not its template arguments, which is fine here. */
write_template_param (parm);
- if (template)
- add_substitution (template);
+ if (templ)
+ add_substitution (templ);
}
/* Non-terminal <substitution>.
diff --git a/gcc/cp/method.c b/gcc/cp/method.c
index bd63d0cba52..f3d23eba23d 100644
--- a/gcc/cp/method.c
+++ b/gcc/cp/method.c
@@ -1108,6 +1108,7 @@ implicitly_declare_fn (special_function_kind kind, tree type, bool const_p)
rest_of_decl_compilation (fn, toplevel_bindings_p (), at_eof);
DECL_IN_AGGR_P (fn) = 1;
DECL_ARTIFICIAL (fn) = 1;
+ DECL_DEFAULTED_FN (fn) = 1;
DECL_NOT_REALLY_EXTERN (fn) = 1;
DECL_DECLARED_INLINE_P (fn) = 1;
DECL_INLINE (fn) = 1;
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index e42f60afba7..9b456d54c57 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -50,6 +50,7 @@ static bool qualified_lookup_using_namespace (tree, tree,
struct scope_binding *, int);
static tree lookup_type_current_level (tree);
static tree push_using_directive (tree);
+static cxx_binding* lookup_extern_c_fun_binding_in_all_ns (tree);
/* The :: namespace. */
@@ -130,7 +131,7 @@ struct binding_table_s GTY(())
binding_entry * GTY((length ("%h.chain_count"))) chain;
/* The number of chains in this table. This is the length of the
- the member "chain" considered as an array. */
+ member "chain" considered as an array. */
size_t chain_count;
/* Number of "binding_entry"s in this table. */
@@ -723,10 +724,10 @@ pushdecl_maybe_friend (tree x, bool is_friend)
/* Don't do anything just yet. */;
else if (t == wchar_decl_node)
{
- if (pedantic && ! DECL_IN_SYSTEM_HEADER (x))
- pedwarn ("redeclaration of %<wchar_t%> as %qT",
+ if (! DECL_IN_SYSTEM_HEADER (x))
+ pedwarn (OPT_pedantic, "redeclaration of %<wchar_t%> as %qT",
TREE_TYPE (x));
-
+
/* Throw away the redeclaration. */
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
}
@@ -763,6 +764,49 @@ pushdecl_maybe_friend (tree x, bool is_friend)
}
}
+ /* If x has C linkage-specification, (extern "C"),
+ lookup its binding, in case it's already bound to an object.
+ The lookup is done in all namespaces.
+ If we find an existing binding, make sure it has the same
+ exception specification as x, otherwise, bail in error [7.5, 7.6]. */
+ if ((TREE_CODE (x) == FUNCTION_DECL)
+ && DECL_EXTERN_C_P (x)
+ /* We should ignore declarations happening in system headers. */
+ && !DECL_IN_SYSTEM_HEADER (x))
+ {
+ cxx_binding *function_binding =
+ lookup_extern_c_fun_binding_in_all_ns (x);
+ if (function_binding
+ && !DECL_IN_SYSTEM_HEADER (function_binding->value))
+ {
+ tree previous = function_binding->value;
+
+ /* In case either x or previous is declared to throw an exception,
+ make sure both exception specifications are equal. */
+ if (decls_match (x, previous))
+ {
+ tree x_exception_spec = NULL_TREE;
+ tree previous_exception_spec = NULL_TREE;
+
+ x_exception_spec =
+ TYPE_RAISES_EXCEPTIONS (TREE_TYPE (x));
+ previous_exception_spec =
+ TYPE_RAISES_EXCEPTIONS (TREE_TYPE (previous));
+ if (!comp_except_specs (previous_exception_spec,
+ x_exception_spec,
+ true))
+ {
+ pedwarn (0, "declaration of %q#D with C language linkage",
+ x);
+ pedwarn (0, "conflicts with previous declaration %q+#D",
+ previous);
+ pedwarn (0, "due to different exception specifications");
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
+ }
+ }
+ }
+ }
+
if (TREE_CODE (x) == FUNCTION_DECL || DECL_FUNCTION_TEMPLATE_P (x))
check_default_args (x);
@@ -1831,6 +1875,39 @@ binding_for_name (cxx_scope *scope, tree name)
return result;
}
+/* Walk through the bindings associated to the name of FUNCTION,
+ and return the first binding that declares a function with a
+ "C" linkage specification, a.k.a 'extern "C"'.
+ This function looks for the binding, regardless of which scope it
+ has been defined in. It basically looks in all the known scopes.
+ Note that this function does not lookup for bindings of builtin functions
+ or for functions declared in system headers. */
+static cxx_binding*
+lookup_extern_c_fun_binding_in_all_ns (tree function)
+{
+ tree name;
+ cxx_binding *iter;
+
+ gcc_assert (function && TREE_CODE (function) == FUNCTION_DECL);
+
+ name = DECL_NAME (function);
+ gcc_assert (name && TREE_CODE (name) == IDENTIFIER_NODE);
+
+ for (iter = IDENTIFIER_NAMESPACE_BINDINGS (name);
+ iter;
+ iter = iter->previous)
+ {
+ if (iter->value
+ && TREE_CODE (iter->value) == FUNCTION_DECL
+ && DECL_EXTERN_C_P (iter->value)
+ && !DECL_ARTIFICIAL (iter->value))
+ {
+ return iter;
+ }
+ }
+ return NULL;
+}
+
/* Insert another USING_DECL into the current binding level, returning
this declaration. If this is a redeclaration, do nothing, and
return NULL_TREE if this not in namespace scope (in namespace
@@ -3234,18 +3311,18 @@ namespace_ancestor (tree ns1, tree ns2)
/* Process a namespace-alias declaration. */
void
-do_namespace_alias (tree alias, tree namespace)
+do_namespace_alias (tree alias, tree name_space)
{
- if (namespace == error_mark_node)
+ if (name_space == error_mark_node)
return;
- gcc_assert (TREE_CODE (namespace) == NAMESPACE_DECL);
+ gcc_assert (TREE_CODE (name_space) == NAMESPACE_DECL);
- namespace = ORIGINAL_NAMESPACE (namespace);
+ name_space = ORIGINAL_NAMESPACE (name_space);
/* Build the alias. */
alias = build_lang_decl (NAMESPACE_DECL, alias, void_type_node);
- DECL_NAMESPACE_ALIAS (alias) = namespace;
+ DECL_NAMESPACE_ALIAS (alias) = name_space;
DECL_EXTERNAL (alias) = 1;
DECL_CONTEXT (alias) = FROB_CONTEXT (current_scope ());
pushdecl (alias);
@@ -3383,46 +3460,46 @@ do_toplevel_using_decl (tree decl, tree scope, tree name)
/* Process a using-directive. */
void
-do_using_directive (tree namespace)
+do_using_directive (tree name_space)
{
tree context = NULL_TREE;
- if (namespace == error_mark_node)
+ if (name_space == error_mark_node)
return;
- gcc_assert (TREE_CODE (namespace) == NAMESPACE_DECL);
+ gcc_assert (TREE_CODE (name_space) == NAMESPACE_DECL);
if (building_stmt_tree ())
- add_stmt (build_stmt (USING_STMT, namespace));
- namespace = ORIGINAL_NAMESPACE (namespace);
+ add_stmt (build_stmt (USING_STMT, name_space));
+ name_space = ORIGINAL_NAMESPACE (name_space);
if (!toplevel_bindings_p ())
{
- push_using_directive (namespace);
+ push_using_directive (name_space);
context = current_scope ();
}
else
{
/* direct usage */
- add_using_namespace (current_namespace, namespace, 0);
+ add_using_namespace (current_namespace, name_space, 0);
if (current_namespace != global_namespace)
context = current_namespace;
}
/* Emit debugging info. */
if (!processing_template_decl)
- (*debug_hooks->imported_module_or_decl) (namespace, context);
+ (*debug_hooks->imported_module_or_decl) (name_space, context);
}
/* Deal with a using-directive seen by the parser. Currently we only
handle attributes here, since they cannot appear inside a template. */
void
-parse_using_directive (tree namespace, tree attribs)
+parse_using_directive (tree name_space, tree attribs)
{
tree a;
- do_using_directive (namespace);
+ do_using_directive (name_space);
for (a = attribs; a; a = TREE_CHAIN (a))
{
@@ -3431,14 +3508,14 @@ parse_using_directive (tree namespace, tree attribs)
{
if (!toplevel_bindings_p ())
error ("strong using only meaningful at namespace scope");
- else if (namespace != error_mark_node)
+ else if (name_space != error_mark_node)
{
- if (!is_ancestor (current_namespace, namespace))
+ if (!is_ancestor (current_namespace, name_space))
error ("current namespace %qD does not enclose strongly used namespace %qD",
- current_namespace, namespace);
- DECL_NAMESPACE_ASSOCIATIONS (namespace)
+ current_namespace, name_space);
+ DECL_NAMESPACE_ASSOCIATIONS (name_space)
= tree_cons (current_namespace, 0,
- DECL_NAMESPACE_ASSOCIATIONS (namespace));
+ DECL_NAMESPACE_ASSOCIATIONS (name_space));
}
}
else
@@ -3527,25 +3604,25 @@ merge_functions (tree s1, tree s2)
/* This should return an error not all definitions define functions.
It is not an error if we find two functions with exactly the
same signature, only if these are selected in overload resolution.
- old is the current set of bindings, new the freshly-found binding.
+ old is the current set of bindings, new_binding the freshly-found binding.
XXX Do we want to give *all* candidates in case of ambiguity?
XXX In what way should I treat extern declarations?
XXX I don't want to repeat the entire duplicate_decls here */
static void
-ambiguous_decl (struct scope_binding *old, cxx_binding *new, int flags)
+ambiguous_decl (struct scope_binding *old, cxx_binding *new_binding, int flags)
{
tree val, type;
gcc_assert (old != NULL);
/* Copy the type. */
- type = new->type;
+ type = new_binding->type;
if (LOOKUP_NAMESPACES_ONLY (flags)
|| (type && hidden_name_p (type) && !(flags & LOOKUP_HIDDEN)))
type = NULL_TREE;
/* Copy the value. */
- val = new->value;
+ val = new_binding->value;
if (val)
{
if (hidden_name_p (val) && !(flags & LOOKUP_HIDDEN))
@@ -4696,21 +4773,21 @@ arg_assoc (struct arg_lookup *k, tree n)
If T is a template-id, its associated namespaces and classes
are the namespace in which the template is defined; for
member templates, the member template's class... */
- tree template = TREE_OPERAND (n, 0);
+ tree templ = TREE_OPERAND (n, 0);
tree args = TREE_OPERAND (n, 1);
tree ctx;
int ix;
- if (TREE_CODE (template) == COMPONENT_REF)
- template = TREE_OPERAND (template, 1);
+ if (TREE_CODE (templ) == COMPONENT_REF)
+ templ = TREE_OPERAND (templ, 1);
/* First, the template. There may actually be more than one if
this is an overloaded function template. But, in that case,
we only need the first; all the functions will be in the same
namespace. */
- template = OVL_CURRENT (template);
+ templ = OVL_CURRENT (templ);
- ctx = CP_DECL_CONTEXT (template);
+ ctx = CP_DECL_CONTEXT (templ);
if (TREE_CODE (ctx) == NAMESPACE_DECL)
{
diff --git a/gcc/cp/operators.def b/gcc/cp/operators.def
index 6c24ba19251..9c2dd8b2ca1 100644
--- a/gcc/cp/operators.def
+++ b/gcc/cp/operators.def
@@ -5,7 +5,7 @@
non-overloadable operators (like the `?:' ternary operator).
Written by Mark Mitchell <mark@codesourcery.com>
- Copyright (C) 2000, 2001, 2002, 2003, 2005, 2007
+ Copyright (C) 2000, 2001, 2002, 2003, 2005, 2007, 2008
Free Software Foundation, Inc.
This file is part of GCC.
@@ -56,7 +56,7 @@ along with GCC; see the file COPYING3. If not see
A boolean value. If nonzero, this is an assignment operator.
- Before including this file, you should define DEFOPERATOR
+ Before including this file, you should define DEF_OPERATOR
to take these arguments.
There is code (such as in grok_op_properties) that depends on the
diff --git a/gcc/cp/optimize.c b/gcc/cp/optimize.c
index a91f8d5f564..ed43b435831 100644
--- a/gcc/cp/optimize.c
+++ b/gcc/cp/optimize.c
@@ -1,5 +1,5 @@
/* Perform optimizations on tree structure.
- Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2007
+ Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2007, 2008
Free Software Foundation, Inc.
Written by Mark Michell (mark@codesourcery.com).
@@ -40,7 +40,7 @@ along with GCC; see the file COPYING3. If not see
#include "langhooks.h"
#include "diagnostic.h"
#include "tree-dump.h"
-#include "tree-gimple.h"
+#include "gimple.h"
/* Prototypes. */
@@ -72,35 +72,40 @@ update_cloned_parm (tree parm, tree cloned_parm, bool first)
DECL_GIMPLE_REG_P (cloned_parm) = DECL_GIMPLE_REG_P (parm);
}
-/* FN is a function that has a complete body, and CLONE is a function whose
- body is to be set to a copy of FN, mapping argument declarations according
- to the ARG_MAP splay_tree. */
+
+/* FN is a function in High GIMPLE form that has a complete body and no
+ CFG. CLONE is a function whose body is to be set to a copy of FN,
+ mapping argument declarations according to the ARG_MAP splay_tree. */
static void
clone_body (tree clone, tree fn, void *arg_map)
{
copy_body_data id;
+ gimple_seq new_body;
+
+ /* FN must already be in GIMPLE form. */
+ gcc_assert (gimple_body (fn));
- /* Clone the body, as if we were making an inline call. But, remap the
- parameters in the callee to the parameters of caller. */
+ /* Clone the body, as if we were making an inline call. But, remap
+ the parameters in the callee to the parameters of caller. */
memset (&id, 0, sizeof (id));
id.src_fn = fn;
id.dst_fn = clone;
id.src_cfun = DECL_STRUCT_FUNCTION (fn);
- id.decl_map = (struct pointer_map_t *)arg_map;
+ id.decl_map = (struct pointer_map_t *) arg_map;
id.copy_decl = copy_decl_no_change;
id.transform_call_graph_edges = CB_CGE_DUPLICATE;
id.transform_new_cfg = true;
id.transform_return_to_modify = false;
- id.transform_lang_insert_block = insert_block;
+ id.transform_lang_insert_block = NULL;
/* We're not inside any EH region. */
id.eh_region = -1;
/* Actually copy the body. */
- append_to_statement_list_force (copy_generic_body (&id),
- &DECL_SAVED_TREE (clone));
+ new_body = remap_gimple_seq (gimple_body (fn), &id);
+ gimple_set_body (clone, new_body);
}
/* FN is a function that has a complete body. Clone the body as
@@ -228,6 +233,7 @@ maybe_clone_body (tree fn)
/* Now, expand this function into RTL, if appropriate. */
finish_function (0);
BLOCK_ABSTRACT_ORIGIN (DECL_INITIAL (clone)) = DECL_INITIAL (fn);
+ DECL_SAVED_TREE (clone) = NULL;
expand_or_defer_fn (clone);
first = false;
}
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 2323c672166..15b66b03b95 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -71,8 +71,6 @@ typedef struct cp_token GTY (())
unsigned char flags;
/* Identifier for the pragma. */
ENUM_BITFIELD (pragma_kind) pragma_kind : 6;
- /* True if this token is from a system header. */
- BOOL_BITFIELD in_system_header : 1;
/* True if this token is from a context where it is implicitly extern "C" */
BOOL_BITFIELD implicit_extern_c : 1;
/* True for a CPP_NAME token that is not a keyword (i.e., for which
@@ -97,7 +95,7 @@ DEF_VEC_ALLOC_P (cp_token_position,heap);
static cp_token eof_token =
{
- CPP_EOF, RID_MAX, 0, PRAGMA_NONE, 0, false, 0, { NULL },
+ CPP_EOF, RID_MAX, 0, PRAGMA_NONE, false, 0, { NULL },
0
};
@@ -408,7 +406,6 @@ cp_lexer_get_preprocessor_token (cp_lexer *lexer, cp_token *token)
lexer == NULL ? 0 : C_LEX_RAW_STRINGS);
token->keyword = RID_MAX;
token->pragma_kind = PRAGMA_NONE;
- token->in_system_header = in_system_header;
/* On some systems, some header files are surrounded by an
implicit extern "C" block. Set a flag in the token if it
@@ -478,15 +475,13 @@ cp_lexer_get_preprocessor_token (cp_lexer *lexer, cp_token *token)
}
}
-/* Update the globals input_location and in_system_header and the
- input file stack from TOKEN. */
+/* Update the globals input_location and the input file stack from TOKEN. */
static inline void
cp_lexer_set_source_position_from_token (cp_token *token)
{
if (token->type != CPP_EOF)
{
input_location = token->location;
- in_system_header = token->in_system_header;
}
}
@@ -1377,7 +1372,7 @@ cp_parser_context_new (cp_parser_context* next)
/* No errors have occurred yet in this context. */
context->status = CP_PARSER_STATUS_KIND_NO_ERROR;
- /* If this is not the bottomost context, copy information that we
+ /* If this is not the bottommost context, copy information that we
need from the previous context. */
if (next)
{
@@ -1593,7 +1588,7 @@ static tree cp_parser_postfix_expression
static tree cp_parser_postfix_open_square_expression
(cp_parser *, tree, bool);
static tree cp_parser_postfix_dot_deref_expression
- (cp_parser *, enum cpp_ttype, tree, bool, cp_id_kind *);
+ (cp_parser *, enum cpp_ttype, tree, bool, cp_id_kind *, location_t);
static tree cp_parser_parenthesized_expression_list
(cp_parser *, bool, bool, bool, bool *);
static void cp_parser_pseudo_destructor_name
@@ -1904,15 +1899,15 @@ static tree cp_parser_objc_statement
/* Utility Routines */
static tree cp_parser_lookup_name
- (cp_parser *, tree, enum tag_types, bool, bool, bool, tree *);
+ (cp_parser *, tree, enum tag_types, bool, bool, bool, tree *, location_t);
static tree cp_parser_lookup_name_simple
- (cp_parser *, tree);
+ (cp_parser *, tree, location_t);
static tree cp_parser_maybe_treat_template_as_class
(tree, bool);
static bool cp_parser_check_declarator_template_parameters
- (cp_parser *, cp_declarator *);
+ (cp_parser *, cp_declarator *, location_t);
static bool cp_parser_check_template_parameters
- (cp_parser *, unsigned);
+ (cp_parser *, unsigned, location_t);
static tree cp_parser_simple_cast_expression
(cp_parser *);
static tree cp_parser_global_scope_opt
@@ -1948,9 +1943,9 @@ static tree cp_parser_trait_expr
static bool cp_parser_declares_only_class_p
(cp_parser *);
static void cp_parser_set_storage_class
- (cp_parser *, cp_decl_specifier_seq *, enum rid);
+ (cp_parser *, cp_decl_specifier_seq *, enum rid, location_t);
static void cp_parser_set_decl_spec_type
- (cp_decl_specifier_seq *, tree, bool);
+ (cp_decl_specifier_seq *, tree, location_t, bool);
static bool cp_parser_friend_p
(const cp_decl_specifier_seq *);
static cp_token *cp_parser_require
@@ -1970,7 +1965,7 @@ static enum tag_types cp_parser_token_is_class_key
static void cp_parser_check_class_key
(enum tag_types, tree type);
static void cp_parser_check_access_in_redeclaration
- (tree type);
+ (tree type, location_t location);
static bool cp_parser_optional_template_keyword
(cp_parser *);
static void cp_parser_pre_parsed_nested_name_specifier
@@ -1992,19 +1987,19 @@ static bool cp_parser_uncommitted_to_tentative_parse_p
static void cp_parser_error
(cp_parser *, const char *);
static void cp_parser_name_lookup_error
- (cp_parser *, tree, tree, const char *);
+ (cp_parser *, tree, tree, const char *, location_t);
static bool cp_parser_simulate_error
(cp_parser *);
static bool cp_parser_check_type_definition
(cp_parser *);
static void cp_parser_check_for_definition_in_return_type
- (cp_declarator *, tree);
+ (cp_declarator *, tree, location_t type_location);
static void cp_parser_check_for_invalid_template_id
- (cp_parser *, tree);
+ (cp_parser *, tree, location_t location);
static bool cp_parser_non_integral_constant_expression
(cp_parser *, const char *);
static void cp_parser_diagnose_invalid_type_name
- (cp_parser *, tree, tree);
+ (cp_parser *, tree, tree, location_t);
static bool cp_parser_parse_and_diagnose_invalid_type_name
(cp_parser *);
static int cp_parser_skip_to_closing_parenthesis
@@ -2030,7 +2025,7 @@ static bool cp_parser_is_string_literal
static bool cp_parser_is_keyword
(cp_token *, enum rid);
static tree cp_parser_make_typename_type
- (cp_parser *, tree, tree);
+ (cp_parser *, tree, tree, location_t location);
static cp_declarator * cp_parser_make_indirect_declarator
(enum tree_code, tree, cp_cv_quals, cp_declarator *);
@@ -2079,7 +2074,7 @@ cp_parser_error (cp_parser* parser, const char* message)
if (token->type == CPP_PRAGMA)
{
- error ("%<#pragma%> is not allowed here");
+ error ("%H%<#pragma%> is not allowed here", &token->location);
cp_parser_skip_to_pragma_eol (parser, token);
return;
}
@@ -2102,33 +2097,34 @@ static void
cp_parser_name_lookup_error (cp_parser* parser,
tree name,
tree decl,
- const char* desired)
+ const char* desired,
+ location_t location)
{
/* If name lookup completely failed, tell the user that NAME was not
declared. */
if (decl == error_mark_node)
{
if (parser->scope && parser->scope != global_namespace)
- error ("%<%E::%E%> has not been declared",
- parser->scope, name);
+ error ("%H%<%E::%E%> has not been declared",
+ &location, parser->scope, name);
else if (parser->scope == global_namespace)
- error ("%<::%E%> has not been declared", name);
+ error ("%H%<::%E%> has not been declared", &location, name);
else if (parser->object_scope
&& !CLASS_TYPE_P (parser->object_scope))
- error ("request for member %qE in non-class type %qT",
- name, parser->object_scope);
+ error ("%Hrequest for member %qE in non-class type %qT",
+ &location, name, parser->object_scope);
else if (parser->object_scope)
- error ("%<%T::%E%> has not been declared",
- parser->object_scope, name);
+ error ("%H%<%T::%E%> has not been declared",
+ &location, parser->object_scope, name);
else
- error ("%qE has not been declared", name);
+ error ("%H%qE has not been declared", &location, name);
}
else if (parser->scope && parser->scope != global_namespace)
- error ("%<%E::%E%> %s", parser->scope, name, desired);
+ error ("%H%<%E::%E%> %s", &location, parser->scope, name, desired);
else if (parser->scope == global_namespace)
- error ("%<::%E%> %s", name, desired);
+ error ("%H%<::%E%> %s", &location, name, desired);
else
- error ("%qE %s", name, desired);
+ error ("%H%qE %s", &location, name, desired);
}
/* If we are parsing tentatively, remember that an error has occurred
@@ -2149,7 +2145,8 @@ cp_parser_simulate_error (cp_parser* parser)
/* Check for repeated decl-specifiers. */
static void
-cp_parser_check_decl_spec (cp_decl_specifier_seq *decl_specs)
+cp_parser_check_decl_spec (cp_decl_specifier_seq *decl_specs,
+ location_t location)
{
cp_decl_spec ds;
@@ -2162,10 +2159,12 @@ cp_parser_check_decl_spec (cp_decl_specifier_seq *decl_specs)
if (ds == ds_long)
{
if (count > 2)
- error ("%<long long long%> is too long for GCC");
+ error ("%H%<long long long%> is too long for GCC", &location);
else if (pedantic && !in_system_header && warn_long_long
&& cxx_dialect == cxx98)
- pedwarn ("ISO C++ 1998 does not support %<long long%>");
+ pedwarn (OPT_Wlong_long,
+ "%HISO C++ 1998 does not support %<long long%>",
+ &location);
}
else if (count > 1)
{
@@ -2185,7 +2184,7 @@ cp_parser_check_decl_spec (cp_decl_specifier_seq *decl_specs)
"__complex",
"__thread"
};
- error ("duplicate %qs", decl_spec_names[(int)ds]);
+ error ("%Hduplicate %qs", &location, decl_spec_names[(int)ds]);
}
}
}
@@ -2211,11 +2210,12 @@ cp_parser_check_type_definition (cp_parser* parser)
/* This function is called when the DECLARATOR is processed. The TYPE
was a type defined in the decl-specifiers. If it is invalid to
define a type in the decl-specifiers for DECLARATOR, an error is
- issued. */
+ issued. TYPE_LOCATION is the location of TYPE and is used
+ for error reporting. */
static void
cp_parser_check_for_definition_in_return_type (cp_declarator *declarator,
- tree type)
+ tree type, location_t type_location)
{
/* [dcl.fct] forbids type definitions in return types.
Unfortunately, it's not easy to know whether or not we are
@@ -2228,31 +2228,32 @@ cp_parser_check_for_definition_in_return_type (cp_declarator *declarator,
if (declarator
&& declarator->kind == cdk_function)
{
- error ("new types may not be defined in a return type");
- inform ("(perhaps a semicolon is missing after the definition of %qT)",
- type);
+ error ("%Hnew types may not be defined in a return type", &type_location);
+ inform ("%H(perhaps a semicolon is missing after the definition of %qT)",
+ &type_location, type);
}
}
/* A type-specifier (TYPE) has been parsed which cannot be followed by
"<" in any valid C++ program. If the next token is indeed "<",
issue a message warning the user about what appears to be an
- invalid attempt to form a template-id. */
+ invalid attempt to form a template-id. LOCATION is the location
+ of the type-specifier (TYPE) */
static void
cp_parser_check_for_invalid_template_id (cp_parser* parser,
- tree type)
+ tree type, location_t location)
{
cp_token_position start = 0;
if (cp_lexer_next_token_is (parser->lexer, CPP_LESS))
{
if (TYPE_P (type))
- error ("%qT is not a template", type);
+ error ("%H%qT is not a template", &location, type);
else if (TREE_CODE (type) == IDENTIFIER_NODE)
- error ("%qE is not a template", type);
+ error ("%H%qE is not a template", &location, type);
else
- error ("invalid template-id");
+ error ("%Hinvalid template-id", &location);
/* Remember the location of the invalid "<". */
if (cp_parser_uncommitted_to_tentative_parse_p (parser))
start = cp_lexer_token_position (parser->lexer, true);
@@ -2298,30 +2299,34 @@ cp_parser_non_integral_constant_expression (cp_parser *parser,
qualifying scope (or NULL, if none) for ID. This function commits
to the current active tentative parse, if any. (Otherwise, the
problematic construct might be encountered again later, resulting
- in duplicate error messages.) */
+ in duplicate error messages.) LOCATION is the location of ID. */
static void
-cp_parser_diagnose_invalid_type_name (cp_parser *parser, tree scope, tree id)
+cp_parser_diagnose_invalid_type_name (cp_parser *parser,
+ tree scope, tree id,
+ location_t location)
{
tree decl, old_scope;
/* Try to lookup the identifier. */
old_scope = parser->scope;
parser->scope = scope;
- decl = cp_parser_lookup_name_simple (parser, id);
+ decl = cp_parser_lookup_name_simple (parser, id, location);
parser->scope = old_scope;
/* If the lookup found a template-name, it means that the user forgot
to specify an argument list. Emit a useful error message. */
if (TREE_CODE (decl) == TEMPLATE_DECL)
- error ("invalid use of template-name %qE without an argument list", decl);
+ error ("%Hinvalid use of template-name %qE without an argument list",
+ &location, decl);
else if (TREE_CODE (id) == BIT_NOT_EXPR)
- error ("invalid use of destructor %qD as a type", id);
+ error ("%Hinvalid use of destructor %qD as a type", &location, id);
else if (TREE_CODE (decl) == TYPE_DECL)
/* Something like 'unsigned A a;' */
- error ("invalid combination of multiple type-specifiers");
+ error ("%Hinvalid combination of multiple type-specifiers",
+ &location);
else if (!parser->scope)
{
/* Issue an error message. */
- error ("%qE does not name a type", id);
+ error ("%H%qE does not name a type", &location, id);
/* If we're in a template class, it's possible that the user was
referring to a type from a base class. For example:
@@ -2353,8 +2358,8 @@ cp_parser_diagnose_invalid_type_name (cp_parser *parser, tree scope, tree id)
if (TREE_CODE (field) == TYPE_DECL
&& DECL_NAME (field) == id)
{
- inform ("(perhaps %<typename %T::%E%> was intended)",
- BINFO_TYPE (b), id);
+ inform ("%H(perhaps %<typename %T::%E%> was intended)",
+ &location, BINFO_TYPE (b), id);
break;
}
if (field)
@@ -2368,10 +2373,11 @@ cp_parser_diagnose_invalid_type_name (cp_parser *parser, tree scope, tree id)
else if (parser->scope != error_mark_node)
{
if (TREE_CODE (parser->scope) == NAMESPACE_DECL)
- error ("%qE in namespace %qE does not name a type",
- id, parser->scope);
+ error ("%H%qE in namespace %qE does not name a type",
+ &location, id, parser->scope);
else if (TYPE_P (parser->scope))
- error ("%qE in class %qT does not name a type", id, parser->scope);
+ error ("%H%qE in class %qT does not name a type",
+ &location, id, parser->scope);
else
gcc_unreachable ();
}
@@ -2392,6 +2398,7 @@ static bool
cp_parser_parse_and_diagnose_invalid_type_name (cp_parser *parser)
{
tree id;
+ cp_token *token = cp_lexer_peek_token (parser->lexer);
cp_parser_parse_tentatively (parser);
id = cp_parser_id_expression (parser,
@@ -2415,7 +2422,8 @@ cp_parser_parse_and_diagnose_invalid_type_name (cp_parser *parser)
return false;
/* Emit a diagnostic for the invalid type. */
- cp_parser_diagnose_invalid_type_name (parser, parser->scope, id);
+ cp_parser_diagnose_invalid_type_name (parser, parser->scope,
+ id, token->location);
/* Skip to the end of the declaration; there's no point in
trying to process it. */
cp_parser_skip_to_end_of_block_or_statement (parser);
@@ -2703,7 +2711,8 @@ cp_parser_require_pragma_eol (cp_parser *parser, cp_token *pragma_tok)
using cp_parser_diagnose_invalid_type_name. */
static tree
-cp_parser_make_typename_type (cp_parser *parser, tree scope, tree id)
+cp_parser_make_typename_type (cp_parser *parser, tree scope,
+ tree id, location_t id_location)
{
tree result;
if (TREE_CODE (id) == IDENTIFIER_NODE)
@@ -2711,7 +2720,7 @@ cp_parser_make_typename_type (cp_parser *parser, tree scope, tree id)
result = make_typename_type (scope, id, typename_type,
/*complain=*/tf_none);
if (result == error_mark_node)
- cp_parser_diagnose_invalid_type_name (parser, scope, id);
+ cp_parser_diagnose_invalid_type_name (parser, scope, id, id_location);
return result;
}
return make_typename_type (scope, id, typename_type, tf_error);
@@ -2929,7 +2938,8 @@ cp_parser_string_literal (cp_parser *parser, bool translate, bool wide_ok)
if (type == CPP_STRING)
type = tok->type;
else if (tok->type != CPP_STRING)
- error ("unsupported non-standard concatenation of string literals");
+ error ("%Hunsupported non-standard concatenation "
+ "of string literals", &tok->location);
}
obstack_grow (&str_ob, &str, sizeof (cpp_string));
@@ -3108,7 +3118,7 @@ cp_parser_primary_expression (cp_parser *parser,
bool template_arg_p,
cp_id_kind *idk)
{
- cp_token *token;
+ cp_token *token = NULL;
/* Assume the primary expression is not an id-expression. */
*idk = CP_ID_KIND_NONE;
@@ -3205,8 +3215,9 @@ cp_parser_primary_expression (cp_parser *parser,
&& cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
{
/* Statement-expressions are not allowed by the standard. */
- if (pedantic)
- pedwarn ("ISO C++ forbids braced-groups within expressions");
+ pedwarn (OPT_pedantic,
+ "%HISO C++ forbids braced-groups within expressions",
+ &token->location);
/* And they're not allowed outside of a function-body; you
cannot, for example, write:
@@ -3217,8 +3228,9 @@ cp_parser_primary_expression (cp_parser *parser,
if (!parser->in_function_body
|| parser->in_template_argument_list_p)
{
- error ("statement-expressions are not allowed outside "
- "functions nor in template-argument lists");
+ error ("%Hstatement-expressions are not allowed outside "
+ "functions nor in template-argument lists",
+ &token->location);
cp_parser_skip_to_end_of_block_or_statement (parser);
expr = error_mark_node;
}
@@ -3275,7 +3287,8 @@ cp_parser_primary_expression (cp_parser *parser,
cp_lexer_consume_token (parser->lexer);
if (parser->local_variables_forbidden_p)
{
- error ("%<this%> may not be used in this context");
+ error ("%H%<this%> may not be used in this context",
+ &token->location);
return error_mark_node;
}
/* Pointers cannot appear in constant-expressions. */
@@ -3375,6 +3388,7 @@ cp_parser_primary_expression (cp_parser *parser,
const char *error_msg;
bool template_p;
bool done;
+ cp_token *id_expr_token;
id_expression:
/* Parse the id-expression. */
@@ -3387,6 +3401,7 @@ cp_parser_primary_expression (cp_parser *parser,
/*optional_p=*/false);
if (id_expression == error_mark_node)
return error_mark_node;
+ id_expr_token = token;
token = cp_lexer_peek_token (parser->lexer);
done = (token->type != CPP_OPEN_SQUARE
&& token->type != CPP_OPEN_PAREN
@@ -3410,7 +3425,8 @@ cp_parser_primary_expression (cp_parser *parser,
template_p,
/*is_namespace=*/false,
/*check_dependency=*/true,
- &ambiguous_decls);
+ &ambiguous_decls,
+ id_expr_token->location);
/* If the lookup was ambiguous, an error will already have
been issued. */
if (ambiguous_decls)
@@ -3457,8 +3473,8 @@ cp_parser_primary_expression (cp_parser *parser,
decl = check_for_out_of_scope_variable (decl);
if (local_variable_p (decl))
{
- error ("local variable %qD may not appear in this context",
- decl);
+ error ("%Hlocal variable %qD may not appear in this context",
+ &id_expr_token->location, decl);
return error_mark_node;
}
}
@@ -3472,7 +3488,8 @@ cp_parser_primary_expression (cp_parser *parser,
&parser->non_integral_constant_expression_p,
template_p, done, address_p,
template_arg_p,
- &error_msg));
+ &error_msg,
+ id_expr_token->location));
if (error_msg)
cp_parser_error (parser, error_msg);
return decl;
@@ -3756,7 +3773,8 @@ cp_parser_unqualified_id (cp_parser* parser,
if (scope && TREE_CODE (scope) == NAMESPACE_DECL)
{
if (!cp_parser_uncommitted_to_tentative_parse_p (parser))
- error ("scope %qT before %<~%> is not a class-name", scope);
+ error ("%Hscope %qT before %<~%> is not a class-name",
+ &token->location, scope);
cp_parser_simulate_error (parser);
if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
cp_lexer_consume_token (parser->lexer);
@@ -3857,8 +3875,8 @@ cp_parser_unqualified_id (cp_parser* parser,
if (declarator_p && scope && !check_dtor_name (scope, type_decl))
{
if (!cp_parser_uncommitted_to_tentative_parse_p (parser))
- error ("declaration of %<~%T%> as member of %qT",
- type_decl, scope);
+ error ("%Hdeclaration of %<~%T%> as member of %qT",
+ &token->location, type_decl, scope);
cp_parser_simulate_error (parser);
return error_mark_node;
}
@@ -3871,8 +3889,8 @@ cp_parser_unqualified_id (cp_parser* parser,
&& !DECL_IMPLICIT_TYPEDEF_P (type_decl)
&& !DECL_SELF_REFERENCE_P (type_decl)
&& !cp_parser_uncommitted_to_tentative_parse_p (parser))
- error ("typedef-name %qD used as destructor declarator",
- type_decl);
+ error ("%Htypedef-name %qD used as destructor declarator",
+ &token->location, type_decl);
return build_nt (BIT_NOT_EXPR, TREE_TYPE (type_decl));
}
@@ -4076,20 +4094,23 @@ cp_parser_nested_name_specifier_opt (cp_parser *parser,
/*is_template=*/false,
/*is_namespace=*/false,
/*check_dependency=*/true,
- &ambiguous_decls);
+ &ambiguous_decls,
+ token->location);
if (TREE_CODE (decl) == TEMPLATE_DECL)
- error ("%qD used without template parameters", decl);
+ error ("%H%qD used without template parameters",
+ &token->location, decl);
else if (ambiguous_decls)
{
- error ("reference to %qD is ambiguous",
- token->u.value);
+ error ("%Hreference to %qD is ambiguous",
+ &token->location, token->u.value);
print_candidates (ambiguous_decls);
decl = error_mark_node;
}
else
cp_parser_name_lookup_error
(parser, token->u.value, decl,
- "is not a class or namespace");
+ "is not a class or namespace",
+ token->location);
}
parser->scope = error_mark_node;
error_p = true;
@@ -4525,8 +4546,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
{
/* Warn the user that a compound literal is not
allowed in standard C++. */
- if (pedantic)
- pedwarn ("ISO C++ forbids compound-literals");
+ pedwarn (OPT_pedantic, "ISO C++ forbids compound-literals");
/* For simplicity, we disallow compound literals in
constant-expressions. We could
allow compound literals of integer type, whose
@@ -4725,6 +4745,9 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
koenig_p,
tf_warning_or_error);
+ if (warn_disallowed_functions)
+ warn_if_disallowed_function_p (postfix_expression);
+
/* The POSTFIX_EXPRESSION is certainly no longer an id. */
idk = CP_ID_KIND_NONE;
}
@@ -4743,7 +4766,8 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
postfix_expression
= cp_parser_postfix_dot_deref_expression (parser, token->type,
postfix_expression,
- false, &idk);
+ false, &idk,
+ token->location);
is_member_access = true;
break;
@@ -4857,7 +4881,8 @@ static tree
cp_parser_postfix_dot_deref_expression (cp_parser *parser,
enum cpp_ttype token_type,
tree postfix_expression,
- bool for_offsetof, cp_id_kind *idk)
+ bool for_offsetof, cp_id_kind *idk,
+ location_t location)
{
tree name;
bool dependent_p;
@@ -4889,7 +4914,7 @@ cp_parser_postfix_dot_deref_expression (cp_parser *parser,
/* The type of the POSTFIX_EXPRESSION must be complete. */
if (scope == unknown_type_node)
{
- error ("%qE does not have class type", postfix_expression);
+ error ("%H%qE does not have class type", &location, postfix_expression);
scope = NULL_TREE;
}
else
@@ -4945,6 +4970,7 @@ cp_parser_postfix_dot_deref_expression (cp_parser *parser,
ordinary class member access expression, rather than a
pseudo-destructor-name. */
bool template_p;
+ cp_token *token = cp_lexer_peek_token (parser->lexer);
/* Parse the id-expression. */
name = (cp_parser_id_expression
(parser,
@@ -4972,7 +4998,7 @@ cp_parser_postfix_dot_deref_expression (cp_parser *parser,
TYPE_DECL here. That is invalid code. */
if (TREE_CODE (name) == TYPE_DECL)
{
- error ("invalid use of %qD", name);
+ error ("%Hinvalid use of %qD", &token->location, name);
postfix_expression = error_mark_node;
}
else
@@ -5535,19 +5561,23 @@ cp_parser_new_expression (cp_parser* parser)
type-id. */
if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
{
+ cp_token *token;
/* Consume the `('. */
cp_lexer_consume_token (parser->lexer);
/* Parse the type-id. */
type = cp_parser_type_id (parser);
/* Look for the closing `)'. */
cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>");
+ token = cp_lexer_peek_token (parser->lexer);
/* There should not be a direct-new-declarator in this production,
but GCC used to allowed this, so we check and emit a sensible error
message for this case. */
if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_SQUARE))
{
- error ("array bound forbidden after parenthesized type-id");
- inform ("try removing the parentheses around the type-id");
+ error ("%Harray bound forbidden after parenthesized type-id",
+ &token->location);
+ inform ("%Htry removing the parentheses around the type-id",
+ &token->location);
cp_parser_direct_new_declarator (parser);
}
nelts = NULL_TREE;
@@ -5724,6 +5754,7 @@ cp_parser_direct_new_declarator (cp_parser* parser)
/* The first expression is not required to be constant. */
if (!declarator)
{
+ cp_token *token = cp_lexer_peek_token (parser->lexer);
expression = cp_parser_expression (parser, /*cast_p=*/false);
/* The standard requires that the expression have integral
type. DR 74 adds enumeration types. We believe that the
@@ -5739,8 +5770,8 @@ cp_parser_direct_new_declarator (cp_parser* parser)
/*complain=*/true);
if (!expression)
{
- error ("expression in new-declarator must have integral "
- "or enumeration type");
+ error ("%Hexpression in new-declarator must have integral "
+ "or enumeration type", &token->location);
expression = error_mark_node;
}
}
@@ -6288,7 +6319,7 @@ cp_parser_assignment_operator_opt (cp_parser* parser)
enum tree_code op;
cp_token *token;
- /* Peek at the next toen. */
+ /* Peek at the next token. */
token = cp_lexer_peek_token (parser->lexer);
switch (token->type)
@@ -6481,6 +6512,7 @@ cp_parser_builtin_offsetof (cp_parser *parser)
int save_ice_p, save_non_ice_p;
tree type, expr;
cp_id_kind dummy;
+ cp_token *token;
/* We're about to accept non-integral-constant things, but will
definitely yield an integral constant expression. Save and
@@ -6496,6 +6528,7 @@ cp_parser_builtin_offsetof (cp_parser *parser)
type = cp_parser_type_id (parser);
/* Look for the `,'. */
cp_parser_require (parser, CPP_COMMA, "%<,%>");
+ token = cp_lexer_peek_token (parser->lexer);
/* Build the (type *)null that begins the traditional offsetof macro. */
expr = build_static_cast (build_pointer_type (type), null_pointer_node,
@@ -6503,10 +6536,10 @@ cp_parser_builtin_offsetof (cp_parser *parser)
/* Parse the offsetof-member-designator. We begin as if we saw "expr->". */
expr = cp_parser_postfix_dot_deref_expression (parser, CPP_DEREF, expr,
- true, &dummy);
+ true, &dummy, token->location);
while (true)
{
- cp_token *token = cp_lexer_peek_token (parser->lexer);
+ token = cp_lexer_peek_token (parser->lexer);
switch (token->type)
{
case CPP_OPEN_SQUARE:
@@ -6518,7 +6551,8 @@ cp_parser_builtin_offsetof (cp_parser *parser)
/* offsetof-member-designator "." identifier */
cp_lexer_consume_token (parser->lexer);
expr = cp_parser_postfix_dot_deref_expression (parser, CPP_DOT, expr,
- true, &dummy);
+ true, &dummy,
+ token->location);
break;
case CPP_CLOSE_PAREN:
@@ -6880,7 +6914,8 @@ cp_parser_label_for_labeled_statement (cp_parser* parser)
if (parser->in_switch_statement_p)
finish_case_label (expr, expr_hi);
else
- error ("case label %qE not within a switch statement", expr);
+ error ("%Hcase label %qE not within a switch statement",
+ &token->location, expr);
}
break;
@@ -6891,7 +6926,7 @@ cp_parser_label_for_labeled_statement (cp_parser* parser)
if (parser->in_switch_statement_p)
finish_case_label (NULL_TREE, NULL_TREE);
else
- error ("case label not within a switch statement");
+ error ("%Hcase label not within a switch statement", &token->location);
break;
default:
@@ -7009,7 +7044,7 @@ cp_parser_statement_seq_opt (cp_parser* parser, tree in_statement_expr)
else
{
token = cp_lexer_consume_token (parser->lexer);
- error ("%<else%> without a previous %<if%>");
+ error ("%H%<else%> without a previous %<if%>", &token->location);
}
}
@@ -7511,7 +7546,7 @@ cp_parser_jump_statement (cp_parser* parser)
switch (in_statement)
{
case 0:
- error ("break statement not within loop or switch");
+ error ("%Hbreak statement not within loop or switch", &token->location);
break;
default:
gcc_assert ((in_statement & IN_SWITCH_STMT)
@@ -7519,10 +7554,10 @@ cp_parser_jump_statement (cp_parser* parser)
statement = finish_break_stmt ();
break;
case IN_OMP_BLOCK:
- error ("invalid exit from OpenMP structured block");
+ error ("%Hinvalid exit from OpenMP structured block", &token->location);
break;
case IN_OMP_FOR:
- error ("break statement used with OpenMP for loop");
+ error ("%Hbreak statement used with OpenMP for loop", &token->location);
break;
}
cp_parser_require (parser, CPP_SEMICOLON, "%<;%>");
@@ -7532,14 +7567,14 @@ cp_parser_jump_statement (cp_parser* parser)
switch (parser->in_statement & ~(IN_SWITCH_STMT | IN_IF_STMT))
{
case 0:
- error ("continue statement not within a loop");
+ error ("%Hcontinue statement not within a loop", &token->location);
break;
case IN_ITERATION_STMT:
case IN_OMP_FOR:
statement = finish_continue_stmt ();
break;
case IN_OMP_BLOCK:
- error ("invalid exit from OpenMP structured block");
+ error ("%Hinvalid exit from OpenMP structured block", &token->location);
break;
default:
gcc_unreachable ();
@@ -7575,8 +7610,7 @@ cp_parser_jump_statement (cp_parser* parser)
if (cp_lexer_next_token_is (parser->lexer, CPP_MULT))
{
/* Issue a warning about this use of a GNU extension. */
- if (pedantic)
- pedwarn ("ISO C++ forbids computed gotos");
+ pedwarn (OPT_pedantic, "%HISO C++ forbids computed gotos", &token->location);
/* Consume the '*' token. */
cp_lexer_consume_token (parser->lexer);
/* Parse the dependent expression. */
@@ -7715,8 +7749,8 @@ cp_parser_declaration_seq_opt (cp_parser* parser)
/* A declaration consisting of a single semicolon is
invalid. Allow it unless we're being pedantic. */
cp_lexer_consume_token (parser->lexer);
- if (pedantic && !in_system_header)
- pedwarn ("extra %<;%>");
+ if (!in_system_header)
+ pedwarn (OPT_pedantic, "extra %<;%>");
continue;
}
@@ -7937,7 +7971,7 @@ cp_parser_block_declaration (cp_parser *parser,
else if (token1->keyword == RID_LABEL)
{
cp_lexer_consume_token (parser->lexer);
- error ("%<__label__%> not at the beginning of a block");
+ error ("%H%<__label__%> not at the beginning of a block", &token1->location);
cp_parser_skip_to_end_of_statement (parser);
/* If the next token is now a `;', consume it. */
if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
@@ -8071,7 +8105,11 @@ cp_parser_simple_declaration (cp_parser* parser,
which is erroneous. */
if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
- error ("mixing declarations and function-definitions is forbidden");
+ {
+ cp_token *token = cp_lexer_peek_token (parser->lexer);
+ error ("%Hmixing declarations and function-definitions is forbidden",
+ &token->location);
+ }
/* Otherwise, we're done with the list of declarators. */
else
{
@@ -8167,6 +8205,7 @@ cp_parser_decl_specifier_seq (cp_parser* parser,
int* declares_class_or_enum)
{
bool constructor_possible_p = !parser->in_declarator_p;
+ cp_token *start_token = NULL;
/* Clear DECL_SPECS. */
clear_decl_specs (decl_specs);
@@ -8183,6 +8222,11 @@ cp_parser_decl_specifier_seq (cp_parser* parser,
/* Peek at the next token. */
token = cp_lexer_peek_token (parser->lexer);
+
+ /* Save the first token of the decl spec list for error
+ reporting. */
+ if (!start_token)
+ start_token = token;
/* Handle attributes. */
if (token->keyword == RID_ATTRIBUTE)
{
@@ -8259,15 +8303,17 @@ cp_parser_decl_specifier_seq (cp_parser* parser,
we're complaining about C++0x compatibility. */
warning
(OPT_Wc__0x_compat,
- "%<auto%> will change meaning in C++0x; please remove it");
+ "%H%<auto%> will change meaning in C++0x; please remove it",
+ &token->location);
/* Set the storage class anyway. */
- cp_parser_set_storage_class (parser, decl_specs, RID_AUTO);
+ cp_parser_set_storage_class (parser, decl_specs, RID_AUTO,
+ token->location);
}
else
/* We do not yet support the use of `auto' as a
type-specifier. */
- error ("C++0x %<auto%> specifier not supported");
+ error ("%HC++0x %<auto%> specifier not supported", &token->location);
break;
case RID_REGISTER:
@@ -8276,7 +8322,8 @@ cp_parser_decl_specifier_seq (cp_parser* parser,
case RID_MUTABLE:
/* Consume the token. */
cp_lexer_consume_token (parser->lexer);
- cp_parser_set_storage_class (parser, decl_specs, token->keyword);
+ cp_parser_set_storage_class (parser, decl_specs, token->keyword,
+ token->location);
break;
case RID_THREAD:
/* Consume the token. */
@@ -8312,7 +8359,6 @@ cp_parser_decl_specifier_seq (cp_parser* parser,
/*is_declaration=*/true,
&decl_spec_declares_class_or_enum,
&is_cv_qualifier);
-
*declares_class_or_enum |= decl_spec_declares_class_or_enum;
/* If this type-specifier referenced a user-defined type
@@ -8372,12 +8418,13 @@ cp_parser_decl_specifier_seq (cp_parser* parser,
flags |= CP_PARSER_FLAGS_OPTIONAL;
}
- cp_parser_check_decl_spec (decl_specs);
+ cp_parser_check_decl_spec (decl_specs, start_token->location);
/* Don't allow a friend specifier with a class definition. */
if (decl_specs->specs[(int) ds_friend] != 0
&& (*declares_class_or_enum & 2))
- error ("class definition may not be declared a friend");
+ error ("%Hclass definition may not be declared a friend",
+ &start_token->location);
}
/* Parse an (optional) storage-class-specifier.
@@ -8433,7 +8480,8 @@ static tree
cp_parser_function_specifier_opt (cp_parser* parser,
cp_decl_specifier_seq *decl_specs)
{
- switch (cp_lexer_peek_token (parser->lexer)->keyword)
+ cp_token *token = cp_lexer_peek_token (parser->lexer);
+ switch (token->keyword)
{
case RID_INLINE:
if (decl_specs)
@@ -8445,7 +8493,7 @@ cp_parser_function_specifier_opt (cp_parser* parser,
A member function template shall not be virtual. */
if (PROCESSING_REAL_TEMPLATE_DECL_P ())
- error ("templates may not be %<virtual%>");
+ error ("%Htemplates may not be %<virtual%>", &token->location);
else if (decl_specs)
++decl_specs->specs[(int) ds_virtual];
break;
@@ -8599,6 +8647,7 @@ cp_parser_decltype (cp_parser *parser)
const char *saved_message;
bool saved_integral_constant_expression_p;
bool saved_non_integral_constant_expression_p;
+ cp_token *id_expr_start_token;
/* Look for the `decltype' token. */
if (!cp_parser_require_keyword (parser, RID_DECLTYPE, "%<decltype%>"))
@@ -8628,6 +8677,7 @@ cp_parser_decltype (cp_parser *parser)
return error_mark_node;
/* First, try parsing an id-expression. */
+ id_expr_start_token = cp_lexer_peek_token (parser->lexer);
cp_parser_parse_tentatively (parser);
expr = cp_parser_id_expression (parser,
/*template_keyword_p=*/false,
@@ -8650,7 +8700,8 @@ cp_parser_decltype (cp_parser *parser)
/*is_template=*/false,
/*is_namespace=*/false,
/*check_dependency=*/true,
- /*ambiguous_decls=*/NULL);
+ /*ambiguous_decls=*/NULL,
+ id_expr_start_token->location);
if (expr
&& expr != error_mark_node
@@ -8670,7 +8721,8 @@ cp_parser_decltype (cp_parser *parser)
/*done=*/true,
/*address_p=*/false,
/*template_arg_p=*/false,
- &error_msg));
+ &error_msg,
+ id_expr_start_token->location));
if (expr == error_mark_node)
/* We found an id-expression, but it was something that we
@@ -8913,17 +8965,20 @@ static void
cp_parser_mem_initializer_list (cp_parser* parser)
{
tree mem_initializer_list = NULL_TREE;
+ cp_token *token = cp_lexer_peek_token (parser->lexer);
/* Let the semantic analysis code know that we are starting the
mem-initializer-list. */
if (!DECL_CONSTRUCTOR_P (current_function_decl))
- error ("only constructors take base initializers");
+ error ("%Honly constructors take base initializers",
+ &token->location);
/* Loop through the list. */
while (true)
{
tree mem_initializer;
+ token = cp_lexer_peek_token (parser->lexer);
/* Parse the mem-initializer. */
mem_initializer = cp_parser_mem_initializer (parser);
/* If the next token is a `...', we're expanding member initializers. */
@@ -8937,8 +8992,8 @@ cp_parser_mem_initializer_list (cp_parser* parser)
if (mem_initializer != error_mark_node
&& !TYPE_P (TREE_PURPOSE (mem_initializer)))
{
- error ("cannot expand initializer for member %<%D%>",
- TREE_PURPOSE (mem_initializer));
+ error ("%Hcannot expand initializer for member %<%D%>",
+ &token->location, TREE_PURPOSE (mem_initializer));
mem_initializer = error_mark_node;
}
@@ -8986,11 +9041,13 @@ cp_parser_mem_initializer (cp_parser* parser)
tree mem_initializer_id;
tree expression_list;
tree member;
+ cp_token *token = cp_lexer_peek_token (parser->lexer);
/* Find out what is being initialized. */
if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
{
- permerror ("anachronistic old-style base class initializer");
+ permerror ("%Hanachronistic old-style base class initializer",
+ &token->location);
mem_initializer_id = NULL_TREE;
}
else
@@ -9041,11 +9098,14 @@ cp_parser_mem_initializer_id (cp_parser* parser)
bool template_p = false;
tree id;
+ cp_token *token = cp_lexer_peek_token (parser->lexer);
+
/* `typename' is not allowed in this context ([temp.res]). */
if (cp_lexer_next_token_is_keyword (parser->lexer, RID_TYPENAME))
{
- error ("keyword %<typename%> not allowed in this context (a qualified "
- "member initializer is implicitly a type)");
+ error ("%Hkeyword %<typename%> not allowed in this context (a qualified "
+ "member initializer is implicitly a type)",
+ &token->location);
cp_lexer_consume_token (parser->lexer);
}
/* Look for the optional `::' operator. */
@@ -9562,6 +9622,7 @@ cp_parser_template_parameter (cp_parser* parser, bool *is_non_type,
appropriate diagnostic here. */
/* Consume the `='. */
+ cp_token *start_token = cp_lexer_peek_token (parser->lexer);
cp_lexer_consume_token (parser->lexer);
/* Find the name of the parameter pack. */
@@ -9570,10 +9631,11 @@ cp_parser_template_parameter (cp_parser* parser, bool *is_non_type,
id_declarator = id_declarator->declarator;
if (id_declarator && id_declarator->kind == cdk_id)
- error ("template parameter pack %qD cannot have a default argument",
- id_declarator->u.id.unqualified_name);
+ error ("%Htemplate parameter pack %qD cannot have a default argument",
+ &start_token->location, id_declarator->u.id.unqualified_name);
else
- error ("template parameter pack cannot have a default argument");
+ error ("%Htemplate parameter pack cannot have a default argument",
+ &start_token->location);
/* Parse the default argument, but throw away the result. */
cp_parser_default_argument (parser, /*template_parm_p=*/true);
@@ -9667,10 +9729,11 @@ cp_parser_type_parameter (cp_parser* parser, bool *is_parameter_pack)
if (*is_parameter_pack)
{
if (identifier)
- error ("template parameter pack %qD cannot have a default argument",
- identifier);
+ error ("%Htemplate parameter pack %qD cannot have a "
+ "default argument", &token->location, identifier);
else
- error ("template parameter packs cannot have default arguments");
+ error ("%Htemplate parameter packs cannot have "
+ "default arguments", &token->location);
default_argument = NULL_TREE;
}
pop_deferring_access_checks ();
@@ -9738,6 +9801,9 @@ cp_parser_type_parameter (cp_parser* parser, bool *is_parameter_pack)
cp_lexer_consume_token (parser->lexer);
/* Parse the id-expression. */
push_deferring_access_checks (dk_no_deferred);
+ /* save token before parsing the id-expression, for error
+ reporting */
+ token = cp_lexer_peek_token (parser->lexer);
default_argument
= cp_parser_id_expression (parser,
/*template_keyword_p=*/false,
@@ -9758,7 +9824,8 @@ cp_parser_type_parameter (cp_parser* parser, bool *is_parameter_pack)
/*is_template=*/is_template,
/*is_namespace=*/false,
/*check_dependency=*/true,
- /*ambiguous_decls=*/NULL);
+ /*ambiguous_decls=*/NULL,
+ token->location);
/* See if the default argument is valid. */
default_argument
= check_template_template_default_arg (default_argument);
@@ -9768,10 +9835,13 @@ cp_parser_type_parameter (cp_parser* parser, bool *is_parameter_pack)
if (*is_parameter_pack)
{
if (identifier)
- error ("template parameter pack %qD cannot have a default argument",
- identifier);
+ error ("%Htemplate parameter pack %qD cannot "
+ "have a default argument",
+ &token->location, identifier);
else
- error ("template parameter packs cannot have default arguments");
+ error ("%Htemplate parameter packs cannot "
+ "have default arguments",
+ &token->location);
default_argument = NULL_TREE;
}
pop_deferring_access_checks ();
@@ -9814,13 +9884,13 @@ cp_parser_template_id (cp_parser *parser,
bool is_declaration)
{
int i;
- tree template;
+ tree templ;
tree arguments;
tree template_id;
cp_token_position start_of_id = 0;
deferred_access_check *chk;
VEC (deferred_access_check,gc) *access_check;
- cp_token *next_token, *next_token_2;
+ cp_token *next_token = NULL, *next_token_2 = NULL, *token = NULL;
bool is_identifier;
/* If the next token corresponds to a template-id, there is no need
@@ -9868,14 +9938,15 @@ cp_parser_template_id (cp_parser *parser,
/* Parse the template-name. */
is_identifier = false;
- template = cp_parser_template_name (parser, template_keyword_p,
- check_dependency_p,
- is_declaration,
- &is_identifier);
- if (template == error_mark_node || is_identifier)
+ token = cp_lexer_peek_token (parser->lexer);
+ templ = cp_parser_template_name (parser, template_keyword_p,
+ check_dependency_p,
+ is_declaration,
+ &is_identifier);
+ if (templ == error_mark_node || is_identifier)
{
pop_deferring_access_checks ();
- return template;
+ return templ;
}
/* If we find the sequence `[:' after a template-name, it's probably
@@ -9894,6 +9965,7 @@ cp_parser_template_id (cp_parser *parser,
/* Consume the first token (CPP_OPEN_SQUARE - which we pretend it is
CPP_LESS. */
cp_lexer_consume_token (parser->lexer);
+
/* Parse the arguments. */
arguments = cp_parser_enclosed_template_argument_list (parser);
if (!cp_parser_parse_definitely (parser))
@@ -9908,15 +9980,18 @@ cp_parser_template_id (cp_parser *parser,
}
/* Otherwise, emit an error about the invalid digraph, but continue
parsing because we got our argument list. */
- permerror ("%<<::%> cannot begin a template-argument list");
- inform ("%<<:%> is an alternate spelling for %<[%>. Insert whitespace "
- "between %<<%> and %<::%>");
+ permerror ("%H%<<::%> cannot begin a template-argument list",
+ &next_token->location);
+ inform ("%H%<<:%> is an alternate spelling for %<[%>. Insert whitespace "
+ "between %<<%> and %<::%>",
+ &next_token->location);
if (!flag_permissive)
{
static bool hint;
if (!hint)
{
- inform ("(if you use %<-fpermissive%> G++ will accept your code)");
+ inform ("%H(if you use %<-fpermissive%> G++ will accept your code)",
+ &next_token->location);
hint = true;
}
}
@@ -9934,10 +10009,10 @@ cp_parser_template_id (cp_parser *parser,
}
/* Build a representation of the specialization. */
- if (TREE_CODE (template) == IDENTIFIER_NODE)
- template_id = build_min_nt (TEMPLATE_ID_EXPR, template, arguments);
- else if (DECL_CLASS_TEMPLATE_P (template)
- || DECL_TEMPLATE_TEMPLATE_PARM_P (template))
+ if (TREE_CODE (templ) == IDENTIFIER_NODE)
+ template_id = build_min_nt (TEMPLATE_ID_EXPR, templ, arguments);
+ else if (DECL_CLASS_TEMPLATE_P (templ)
+ || DECL_TEMPLATE_TEMPLATE_PARM_P (templ))
{
bool entering_scope;
/* In "template <typename T> ... A<T>::", A<T> is the abstract A
@@ -9949,17 +10024,17 @@ cp_parser_template_id (cp_parser *parser,
&& cp_lexer_next_token_is (parser->lexer,
CPP_SCOPE));
template_id
- = finish_template_type (template, arguments, entering_scope);
+ = finish_template_type (templ, arguments, entering_scope);
}
else
{
/* If it's not a class-template or a template-template, it should be
a function-template. */
- gcc_assert ((DECL_FUNCTION_TEMPLATE_P (template)
- || TREE_CODE (template) == OVERLOAD
- || BASELINK_P (template)));
+ gcc_assert ((DECL_FUNCTION_TEMPLATE_P (templ)
+ || TREE_CODE (templ) == OVERLOAD
+ || BASELINK_P (templ)));
- template_id = lookup_template_function (template, arguments);
+ template_id = lookup_template_function (templ, arguments);
}
/* If parsing tentatively, replace the sequence of tokens that makes
@@ -9989,7 +10064,8 @@ cp_parser_template_id (cp_parser *parser,
user, as opposed to simply marking the tentative parse as
failed? */
if (cp_parser_error_occurred (parser) && template_id != error_mark_node)
- error ("parse error in template argument list");
+ error ("%Hparse error in template argument list",
+ &token->location);
}
pop_deferring_access_checks ();
@@ -10043,6 +10119,7 @@ cp_parser_template_name (cp_parser* parser,
tree identifier;
tree decl;
tree fns;
+ cp_token *token = cp_lexer_peek_token (parser->lexer);
/* If the next token is `operator', then we have either an
operator-function-id or a conversion-function-id. */
@@ -10102,7 +10179,8 @@ cp_parser_template_name (cp_parser* parser,
cp_token_position start = 0;
/* Explain what went wrong. */
- error ("non-template %qD used as template", identifier);
+ error ("%Hnon-template %qD used as template",
+ &token->location, identifier);
inform ("use %<%T::template %D%> to indicate that it is a template",
parser->scope, identifier);
/* If parsing tentatively, find the location of the "<" token. */
@@ -10146,7 +10224,8 @@ cp_parser_template_name (cp_parser* parser,
/*is_template=*/false,
/*is_namespace=*/false,
check_dependency_p,
- /*ambiguous_decls=*/NULL);
+ /*ambiguous_decls=*/NULL,
+ token->location);
decl = maybe_get_template_decl_from_type_decl (decl);
/* If DECL is a template, then the name was a template-name. */
@@ -10292,7 +10371,7 @@ cp_parser_template_argument (cp_parser* parser)
bool template_p;
bool address_p;
bool maybe_type_id = false;
- cp_token *token;
+ cp_token *token = NULL, *argument_start_token = NULL;
cp_id_kind idk;
/* There's really no way to know what we're looking at, so we just
@@ -10339,6 +10418,7 @@ cp_parser_template_argument (cp_parser* parser)
/* We're still not sure what the argument will be. */
cp_parser_parse_tentatively (parser);
/* Try a template. */
+ argument_start_token = cp_lexer_peek_token (parser->lexer);
argument = cp_parser_id_expression (parser,
/*template_keyword_p=*/false,
/*check_dependency_p=*/true,
@@ -10361,7 +10441,8 @@ cp_parser_template_argument (cp_parser* parser)
/*is_template=*/template_p,
/*is_namespace=*/false,
/*check_dependency=*/true,
- /*ambiguous_decls=*/NULL);
+ /*ambiguous_decls=*/NULL,
+ argument_start_token->location);
if (TREE_CODE (argument) != TEMPLATE_DECL
&& TREE_CODE (argument) != UNBOUND_CLASS_TEMPLATE)
cp_parser_error (parser, "expected template-name");
@@ -10386,7 +10467,7 @@ cp_parser_template_argument (cp_parser* parser)
{
cp_parser_parse_tentatively (parser);
argument = cp_parser_primary_expression (parser,
- /*adress_p=*/false,
+ /*address_p=*/false,
/*cast_p=*/false,
/*template_arg_p=*/true,
&idk);
@@ -10518,6 +10599,7 @@ cp_parser_explicit_instantiation (cp_parser* parser)
int declares_class_or_enum;
cp_decl_specifier_seq decl_specifiers;
tree extension_specifier = NULL_TREE;
+ cp_token *token;
/* Look for an (optional) storage-class-specifier or
function-specifier. */
@@ -10540,6 +10622,7 @@ cp_parser_explicit_instantiation (cp_parser* parser)
control while processing explicit instantiation directives. */
push_deferring_access_checks (dk_no_check);
/* Parse a decl-specifier-seq. */
+ token = cp_lexer_peek_token (parser->lexer);
cp_parser_decl_specifier_seq (parser,
CP_PARSER_FLAGS_OPTIONAL,
&decl_specifiers,
@@ -10572,7 +10655,8 @@ cp_parser_explicit_instantiation (cp_parser* parser)
/*member_p=*/false);
if (declares_class_or_enum & 2)
cp_parser_check_for_definition_in_return_type (declarator,
- decl_specifiers.type);
+ decl_specifiers.type,
+ decl_specifiers.type_location);
if (declarator != cp_error_declarator)
{
decl = grokdeclarator (declarator, &decl_specifiers,
@@ -10613,6 +10697,8 @@ static void
cp_parser_explicit_specialization (cp_parser* parser)
{
bool need_lang_pop;
+ cp_token *token = cp_lexer_peek_token (parser->lexer);
+
/* Look for the `template' keyword. */
cp_parser_require_keyword (parser, RID_TEMPLATE, "%<template%>");
/* Look for the `<'. */
@@ -10627,7 +10713,7 @@ cp_parser_explicit_specialization (cp_parser* parser)
linkage. */
if (current_lang_name == lang_name_c)
{
- error ("template specialization with C linkage");
+ error ("%Htemplate specialization with C linkage", &token->location);
/* Give it C++ linkage to avoid confusing other parts of the
front end. */
push_lang_context (lang_name_cplusplus);
@@ -10742,6 +10828,7 @@ cp_parser_type_specifier (cp_parser* parser,
if (decl_specs)
cp_parser_set_decl_spec_type (decl_specs,
type_spec,
+ token->location,
/*user_defined_p=*/true);
return type_spec;
}
@@ -10766,6 +10853,7 @@ cp_parser_type_specifier (cp_parser* parser,
if (decl_specs)
cp_parser_set_decl_spec_type (decl_specs,
type_spec,
+ token->location,
/*user_defined_p=*/true);
return type_spec;
}
@@ -10787,6 +10875,7 @@ cp_parser_type_specifier (cp_parser* parser,
if (decl_specs)
cp_parser_set_decl_spec_type (decl_specs,
type_spec,
+ token->location,
/*user_defined_p=*/true);
return type_spec;
@@ -10952,7 +11041,7 @@ cp_parser_simple_type_specifier (cp_parser* parser,
cp_lexer_consume_token (parser->lexer);
/* We do not yet support the use of `auto' as a
type-specifier. */
- error ("C++0x %<auto%> specifier not supported");
+ error ("%HC++0x %<auto%> specifier not supported", &token->location);
}
break;
@@ -10962,6 +11051,7 @@ cp_parser_simple_type_specifier (cp_parser* parser,
if (decl_specs)
cp_parser_set_decl_spec_type (decl_specs, type,
+ token->location,
/*user_defined_p=*/true);
return type;
@@ -10977,6 +11067,7 @@ cp_parser_simple_type_specifier (cp_parser* parser,
if (decl_specs)
cp_parser_set_decl_spec_type (decl_specs, type,
+ token->location,
/*user_defined_p=*/true);
return type;
@@ -10998,6 +11089,7 @@ cp_parser_simple_type_specifier (cp_parser* parser,
&& token->keyword != RID_LONG))
cp_parser_set_decl_spec_type (decl_specs,
type,
+ token->location,
/*user_defined=*/false);
if (decl_specs)
decl_specs->any_specifiers_p = true;
@@ -11008,7 +11100,7 @@ cp_parser_simple_type_specifier (cp_parser* parser,
/* There is no valid C++ program where a non-template type is
followed by a "<". That usually indicates that the user thought
that the type was a template. */
- cp_parser_check_for_invalid_template_id (parser, type);
+ cp_parser_check_for_invalid_template_id (parser, type, token->location);
return TYPE_NAME (type);
}
@@ -11037,6 +11129,7 @@ cp_parser_simple_type_specifier (cp_parser* parser,
/*type_p=*/false,
/*is_declaration=*/false)
!= NULL_TREE);
+ token = cp_lexer_peek_token (parser->lexer);
/* If we have seen a nested-name-specifier, and the next token
is `template', then we are using the template-id production. */
if (parser->scope
@@ -11071,6 +11164,7 @@ cp_parser_simple_type_specifier (cp_parser* parser,
type = NULL_TREE;
if (type && decl_specs)
cp_parser_set_decl_spec_type (decl_specs, type,
+ token->location,
/*user_defined=*/true);
}
@@ -11103,7 +11197,8 @@ cp_parser_simple_type_specifier (cp_parser* parser,
return qual_type;
}
- cp_parser_check_for_invalid_template_id (parser, TREE_TYPE (type));
+ cp_parser_check_for_invalid_template_id (parser, TREE_TYPE (type),
+ token->location);
}
return type;
@@ -11165,12 +11260,13 @@ cp_parser_nonclass_name (cp_parser* parser)
tree type_decl;
tree identifier;
+ cp_token *token = cp_lexer_peek_token (parser->lexer);
identifier = cp_parser_identifier (parser);
if (identifier == error_mark_node)
return error_mark_node;
/* Look up the type-name. */
- type_decl = cp_parser_lookup_name_simple (parser, identifier);
+ type_decl = cp_parser_lookup_name_simple (parser, identifier, token->location);
if (TREE_CODE (type_decl) != TYPE_DECL
&& (objc_is_id (identifier) || objc_is_class_name (identifier)))
@@ -11187,7 +11283,7 @@ cp_parser_nonclass_name (cp_parser* parser)
{
if (!cp_parser_simulate_error (parser))
cp_parser_name_lookup_error (parser, identifier, type_decl,
- "is not a type");
+ "is not a type", token->location);
return error_mark_node;
}
/* Remember that the name was used in the definition of the
@@ -11236,6 +11332,7 @@ cp_parser_elaborated_type_specifier (cp_parser* parser,
tree identifier;
tree type = NULL_TREE;
tree attributes = NULL_TREE;
+ cp_token *token = NULL;
/* See if we're looking at the `enum' keyword. */
if (cp_lexer_next_token_is_keyword (parser->lexer, RID_ENUM))
@@ -11305,6 +11402,7 @@ cp_parser_elaborated_type_specifier (cp_parser* parser,
if (!template_p)
cp_parser_parse_tentatively (parser);
/* Parse the template-id. */
+ token = cp_lexer_peek_token (parser->lexer);
decl = cp_parser_template_id (parser, template_p,
/*check_dependency_p=*/true,
is_declaration);
@@ -11326,6 +11424,7 @@ cp_parser_elaborated_type_specifier (cp_parser* parser,
if (!type)
{
+ token = cp_lexer_peek_token (parser->lexer);
identifier = cp_parser_identifier (parser);
if (identifier == error_mark_node)
@@ -11338,7 +11437,8 @@ cp_parser_elaborated_type_specifier (cp_parser* parser,
if (tag_type == typename_type
&& TREE_CODE (parser->scope) != NAMESPACE_DECL)
return cp_parser_make_typename_type (parser, parser->scope,
- identifier);
+ identifier,
+ token->location);
/* Look up a qualified name in the usual way. */
if (parser->scope)
{
@@ -11350,7 +11450,8 @@ cp_parser_elaborated_type_specifier (cp_parser* parser,
/*is_template=*/false,
/*is_namespace=*/false,
/*check_dependency=*/true,
- &ambiguous_decls);
+ &ambiguous_decls,
+ token->location);
/* If the lookup was ambiguous, an error will already have been
issued. */
@@ -11386,7 +11487,8 @@ cp_parser_elaborated_type_specifier (cp_parser* parser,
{
cp_parser_diagnose_invalid_type_name (parser,
parser->scope,
- identifier);
+ identifier,
+ token->location);
return error_mark_node;
}
@@ -11486,7 +11588,8 @@ cp_parser_elaborated_type_specifier (cp_parser* parser,
/* An unqualified name was used to reference this type, so
there were no qualifying templates. */
if (!cp_parser_check_template_parameters (parser,
- /*num_templates=*/0))
+ /*num_templates=*/0,
+ token->location))
return error_mark_node;
type = xref_tag (tag_type, identifier, ts, template_p);
}
@@ -11517,7 +11620,7 @@ cp_parser_elaborated_type_specifier (cp_parser* parser,
/* A "<" cannot follow an elaborated type specifier. If that
happens, the user was probably trying to form a template-id. */
- cp_parser_check_for_invalid_template_id (parser, type);
+ cp_parser_check_for_invalid_template_id (parser, type, token->location);
return type;
}
@@ -11630,8 +11733,8 @@ cp_parser_enumerator_list (cp_parser* parser, tree type)
/* If the next token is a `}', there is a trailing comma. */
if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_BRACE))
{
- if (pedantic && !in_system_header)
- pedwarn ("comma at end of enumerator list");
+ if (!in_system_header)
+ pedwarn (OPT_pedantic, "comma at end of enumerator list");
break;
}
}
@@ -11689,6 +11792,8 @@ cp_parser_namespace_name (cp_parser* parser)
tree identifier;
tree namespace_decl;
+ cp_token *token = cp_lexer_peek_token (parser->lexer);
+
/* Get the name of the namespace. */
identifier = cp_parser_identifier (parser);
if (identifier == error_mark_node)
@@ -11717,13 +11822,14 @@ cp_parser_namespace_name (cp_parser* parser)
/*is_template=*/false,
/*is_namespace=*/true,
/*check_dependency=*/true,
- /*ambiguous_decls=*/NULL);
+ /*ambiguous_decls=*/NULL,
+ token->location);
/* If it's not a namespace, issue an error. */
if (namespace_decl == error_mark_node
|| TREE_CODE (namespace_decl) != NAMESPACE_DECL)
{
if (!cp_parser_uncommitted_to_tentative_parse_p (parser))
- error ("%qD is not a namespace-name", identifier);
+ error ("%H%qD is not a namespace-name", &token->location, identifier);
cp_parser_error (parser, "expected namespace-name");
namespace_decl = error_mark_node;
}
@@ -11789,14 +11895,14 @@ cp_parser_namespace_definition (cp_parser* parser)
followed by a strong using directive. */
if (is_inline)
{
- tree namespace = current_namespace;
+ tree name_space = current_namespace;
/* Set up namespace association. */
- DECL_NAMESPACE_ASSOCIATIONS (namespace)
- = tree_cons (CP_DECL_CONTEXT (namespace), NULL_TREE,
- DECL_NAMESPACE_ASSOCIATIONS (namespace));
+ DECL_NAMESPACE_ASSOCIATIONS (name_space)
+ = tree_cons (CP_DECL_CONTEXT (name_space), NULL_TREE,
+ DECL_NAMESPACE_ASSOCIATIONS (name_space));
/* Import the contents of the inline namespace. */
pop_namespace ();
- do_using_directive (namespace);
+ do_using_directive (name_space);
push_namespace (identifier);
}
@@ -11838,6 +11944,8 @@ cp_parser_namespace_alias_definition (cp_parser* parser)
tree identifier;
tree namespace_specifier;
+ cp_token *token = cp_lexer_peek_token (parser->lexer);
+
/* Look for the `namespace' keyword. */
cp_parser_require_keyword (parser, RID_NAMESPACE, "%<namespace%>");
/* Look for the identifier. */
@@ -11848,7 +11956,7 @@ cp_parser_namespace_alias_definition (cp_parser* parser)
if (!cp_parser_uncommitted_to_tentative_parse_p (parser)
&& cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
{
- error ("%<namespace%> definition is not allowed here");
+ error ("%H%<namespace%> definition is not allowed here", &token->location);
/* Skip the definition. */
cp_lexer_consume_token (parser->lexer);
if (cp_parser_skip_to_closing_brace (parser))
@@ -11963,6 +12071,7 @@ cp_parser_using_declaration (cp_parser* parser,
cp_parser_parse_definitely will be false, as required. */
return cp_parser_parse_definitely (parser);
+ token = cp_lexer_peek_token (parser->lexer);
/* Parse the unqualified-id. */
identifier = cp_parser_unqualified_id (parser,
/*template_keyword_p=*/false,
@@ -11987,7 +12096,8 @@ cp_parser_using_declaration (cp_parser* parser,
/* [namespace.udecl]
A using declaration shall not name a template-id. */
- error ("a template-id may not appear in a using-declaration");
+ error ("%Ha template-id may not appear in a using-declaration",
+ &token->location);
else
{
if (at_class_scope_p ())
@@ -12003,9 +12113,13 @@ cp_parser_using_declaration (cp_parser* parser,
}
else
{
- decl = cp_parser_lookup_name_simple (parser, identifier);
+ decl = cp_parser_lookup_name_simple (parser,
+ identifier,
+ token->location);
if (decl == error_mark_node)
- cp_parser_name_lookup_error (parser, identifier, decl, NULL);
+ cp_parser_name_lookup_error (parser, identifier,
+ decl, NULL,
+ token->location);
else if (check_for_bare_parameter_packs (decl))
return false;
else if (!at_namespace_scope_p ())
@@ -12255,7 +12369,8 @@ cp_parser_init_declarator (cp_parser* parser,
int declares_class_or_enum,
bool* function_definition_p)
{
- cp_token *token;
+ cp_token *token = NULL, *asm_spec_start_token = NULL,
+ *attributes_start_token = NULL;
cp_declarator *declarator;
tree prefix_attributes;
tree attributes;
@@ -12263,7 +12378,7 @@ cp_parser_init_declarator (cp_parser* parser,
tree initializer;
tree decl = NULL_TREE;
tree scope;
- bool is_initialized;
+ int is_initialized;
/* Only valid if IS_INITIALIZED is true. In that case, CPP_EQ if
initialized with "= ..", CPP_OPEN_PAREN if initialized with
"(...)". */
@@ -12289,6 +12404,7 @@ cp_parser_init_declarator (cp_parser* parser,
resume_deferring_access_checks ();
/* Parse the declarator. */
+ token = cp_lexer_peek_token (parser->lexer);
declarator
= cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED,
&ctor_dtor_or_conv_p,
@@ -12303,12 +12419,14 @@ cp_parser_init_declarator (cp_parser* parser,
return error_mark_node;
/* Check that the number of template-parameter-lists is OK. */
- if (!cp_parser_check_declarator_template_parameters (parser, declarator))
+ if (!cp_parser_check_declarator_template_parameters (parser, declarator,
+ token->location))
return error_mark_node;
if (declares_class_or_enum & 2)
cp_parser_check_for_definition_in_return_type (declarator,
- decl_specifiers->type);
+ decl_specifiers->type,
+ decl_specifiers->type_location);
/* Figure out what scope the entity declared by the DECLARATOR is
located in. `grokdeclarator' sometimes changes the scope, so
@@ -12320,8 +12438,10 @@ cp_parser_init_declarator (cp_parser* parser,
if (cp_parser_allow_gnu_extensions_p (parser))
{
/* Look for an asm-specification. */
+ asm_spec_start_token = cp_lexer_peek_token (parser->lexer);
asm_specification = cp_parser_asm_specification_opt (parser);
/* And attributes. */
+ attributes_start_token = cp_lexer_peek_token (parser->lexer);
attributes = cp_parser_attributes_opt (parser);
}
else
@@ -12350,9 +12470,12 @@ cp_parser_init_declarator (cp_parser* parser,
/* Neither attributes nor an asm-specification are allowed
on a function-definition. */
if (asm_specification)
- error ("an asm-specification is not allowed on a function-definition");
+ error ("%Han asm-specification is not allowed "
+ "on a function-definition",
+ &asm_spec_start_token->location);
if (attributes)
- error ("attributes are not allowed on a function-definition");
+ error ("%Hattributes are not allowed on a function-definition",
+ &attributes_start_token->location);
/* This is a function-definition. */
*function_definition_p = true;
@@ -12391,8 +12514,18 @@ cp_parser_init_declarator (cp_parser* parser,
|| token->type == CPP_OPEN_PAREN
|| token->type == CPP_OPEN_BRACE)
{
- is_initialized = true;
+ is_initialized = 1;
initialization_kind = token->type;
+
+ if (token->type == CPP_EQ
+ && function_declarator_p (declarator))
+ {
+ cp_token *t2 = cp_lexer_peek_nth_token (parser->lexer, 2);
+ if (t2->keyword == RID_DEFAULT)
+ is_initialized = 2;
+ else if (t2->keyword == RID_DELETE)
+ is_initialized = 3;
+ }
}
else
{
@@ -12404,7 +12537,7 @@ cp_parser_init_declarator (cp_parser* parser,
cp_parser_error (parser, "expected initializer");
return error_mark_node;
}
- is_initialized = false;
+ is_initialized = 0;
initialization_kind = CPP_EOF;
}
@@ -12462,7 +12595,7 @@ cp_parser_init_declarator (cp_parser* parser,
cp_parser_perform_template_parameter_access_checks (checks);
/* Perform the access control checks for the declarator and the
- the decl-specifiers. */
+ decl-specifiers. */
perform_deferred_access_checks ();
/* Restore the saved value. */
@@ -12478,6 +12611,7 @@ cp_parser_init_declarator (cp_parser* parser,
{
if (function_declarator_p (declarator))
{
+ cp_token *initializer_start_token = cp_lexer_peek_token (parser->lexer);
if (initialization_kind == CPP_EQ)
initializer = cp_parser_pure_specifier (parser);
else
@@ -12486,7 +12620,8 @@ cp_parser_init_declarator (cp_parser* parser,
know what the user intended, so just silently
consume the initializer. */
if (decl != error_mark_node)
- error ("initializer provided for function");
+ error ("%Hinitializer provided for function",
+ &initializer_start_token->location);
cp_parser_skip_to_closing_parenthesis (parser,
/*recovering=*/true,
/*or_comma=*/false,
@@ -12737,7 +12872,7 @@ cp_parser_direct_declarator (cp_parser* parser,
int i (3);
The first is the declaration of a function while the
- second is a the definition of a variable, including its
+ second is the definition of a variable, including its
initializer.
Having seen only the parenthesis, we cannot know which of
@@ -12888,7 +13023,8 @@ cp_parser_direct_declarator (cp_parser* parser,
in function scopes. */
else if (!parser->in_function_body)
{
- error ("array bound is not an integer constant");
+ error ("%Harray bound is not an integer constant",
+ &token->location);
bounds = error_mark_node;
}
}
@@ -12910,6 +13046,7 @@ cp_parser_direct_declarator (cp_parser* parser,
special_function_kind sfk;
bool abstract_ok;
bool pack_expansion_p = false;
+ cp_token *declarator_id_start_token;
/* Parse a declarator-id */
abstract_ok = (dcl_kind == CP_PARSER_DECLARATOR_EITHER);
@@ -12928,6 +13065,7 @@ cp_parser_direct_declarator (cp_parser* parser,
}
}
+ declarator_id_start_token = cp_lexer_peek_token (parser->lexer);
unqualified_name
= cp_parser_declarator_id (parser, /*optional_p=*/abstract_ok);
qualifying_scope = parser->scope;
@@ -12997,7 +13135,8 @@ cp_parser_direct_declarator (cp_parser* parser,
/*only_current_p=*/false);
/* If that failed, the declarator is invalid. */
if (TREE_CODE (type) == TYPENAME_TYPE)
- error ("%<%T::%E%> is not a type",
+ error ("%H%<%T::%E%> is not a type",
+ &declarator_id_start_token->location,
TYPE_CONTEXT (qualifying_scope),
TYPE_IDENTIFIER (qualifying_scope));
qualifying_scope = type;
@@ -13023,7 +13162,8 @@ cp_parser_direct_declarator (cp_parser* parser,
if (qualifying_scope
&& CLASSTYPE_USE_TEMPLATE (name_type))
{
- error ("invalid use of constructor as a template");
+ error ("%Hinvalid use of constructor as a template",
+ &declarator_id_start_token->location);
inform ("use %<%T::%D%> instead of %<%T::%D%> to "
"name the constructor in a qualified name",
class_type,
@@ -13182,6 +13322,7 @@ cp_parser_ptr_operator (cp_parser* parser,
cp_parser_global_scope_opt (parser,
/*current_scope_valid_p=*/false);
/* Look for the nested-name specifier. */
+ token = cp_lexer_peek_token (parser->lexer);
cp_parser_nested_name_specifier (parser,
/*typename_keyword_p=*/false,
/*check_dependency_p=*/true,
@@ -13196,7 +13337,7 @@ cp_parser_ptr_operator (cp_parser* parser,
code = INDIRECT_REF;
if (TREE_CODE (parser->scope) == NAMESPACE_DECL)
- error ("%qD is a namespace", parser->scope);
+ error ("%H%qD is a namespace", &token->location, parser->scope);
else
{
/* The type of which the member is a member is given by the
@@ -13271,7 +13412,7 @@ cp_parser_cv_qualifier_seq_opt (cp_parser* parser)
if (cv_quals & cv_qualifier)
{
- error ("duplicate cv-qualifier");
+ error ("%Hduplicate cv-qualifier", &token->location);
cp_lexer_purge_token (parser->lexer);
}
else
@@ -13381,6 +13522,7 @@ cp_parser_type_specifier_seq (cp_parser* parser,
{
bool seen_type_specifier = false;
cp_parser_flags flags = CP_PARSER_FLAGS_OPTIONAL;
+ cp_token *start_token = NULL;
/* Clear the TYPE_SPECIFIER_SEQ. */
clear_decl_specs (type_specifier_seq);
@@ -13400,6 +13542,11 @@ cp_parser_type_specifier_seq (cp_parser* parser,
continue;
}
+ /* record the token of the beginning of the type specifier seq,
+ for error reporting purposes*/
+ if (!start_token)
+ start_token = cp_lexer_peek_token (parser->lexer);
+
/* Look for the type-specifier. */
type_specifier = cp_parser_type_specifier (parser,
flags,
@@ -13443,7 +13590,7 @@ cp_parser_type_specifier_seq (cp_parser* parser,
flags |= CP_PARSER_FLAGS_NO_USER_DEFINED_TYPES;
}
- cp_parser_check_decl_spec (type_specifier_seq);
+ cp_parser_check_decl_spec (type_specifier_seq, start_token->location);
}
/* Parse a parameter-declaration-clause.
@@ -13670,7 +13817,7 @@ cp_parser_parameter_declaration (cp_parser *parser,
cp_decl_specifier_seq decl_specifiers;
cp_declarator *declarator;
tree default_argument;
- cp_token *token;
+ cp_token *token = NULL, *declarator_token_start = NULL;
const char *saved_message;
/* In a template parameter, `>' is not an operator.
@@ -13739,6 +13886,7 @@ cp_parser_parameter_declaration (cp_parser *parser,
&& cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_PAREN))
cp_parser_commit_to_tentative_parse (parser);
/* Parse the declarator. */
+ declarator_token_start = token;
declarator = cp_parser_declarator (parser,
CP_PARSER_DECLARATOR_EITHER,
/*ctor_dtor_or_conv_p=*/NULL,
@@ -13897,7 +14045,7 @@ cp_parser_parameter_declaration (cp_parser *parser,
/* If we run out of tokens, issue an error message. */
case CPP_EOF:
case CPP_PRAGMA_EOL:
- error ("file ends in default argument");
+ error ("%Hfile ends in default argument", &token->location);
done = true;
break;
@@ -13934,8 +14082,11 @@ cp_parser_parameter_declaration (cp_parser *parser,
/* Outside of a class definition, we can just parse the
assignment-expression. */
else
- default_argument
- = cp_parser_default_argument (parser, template_parm_p);
+ {
+ token = cp_lexer_peek_token (parser->lexer);
+ default_argument
+ = cp_parser_default_argument (parser, template_parm_p);
+ }
if (!parser->default_arg_ok_p)
{
@@ -13943,7 +14094,9 @@ cp_parser_parameter_declaration (cp_parser *parser,
warning (0, "deprecated use of default argument for parameter of non-function");
else
{
- error ("default arguments are only permitted for function parameters");
+ error ("%Hdefault arguments are only "
+ "permitted for function parameters",
+ &token->location);
default_argument = NULL_TREE;
}
}
@@ -13959,11 +14112,12 @@ cp_parser_parameter_declaration (cp_parser *parser,
id_declarator = id_declarator->declarator;
if (id_declarator && id_declarator->kind == cdk_id)
- error ("%sparameter pack %qD cannot have a default argument",
+ error ("%H%sparameter pack %qD cannot have a default argument",
+ &declarator_token_start->location,
kind, id_declarator->u.id.unqualified_name);
else
- error ("%sparameter pack cannot have a default argument",
- kind);
+ error ("%H%sparameter pack cannot have a default argument",
+ &declarator_token_start->location, kind);
default_argument = NULL_TREE;
}
@@ -14224,8 +14378,8 @@ cp_parser_initializer_list (cp_parser* parser, bool* non_constant_p)
&& cp_lexer_peek_nth_token (parser->lexer, 2)->type == CPP_COLON)
{
/* Warn the user that they are using an extension. */
- if (pedantic)
- pedwarn ("ISO C++ does not allow designated initializers");
+ pedwarn (OPT_pedantic,
+ "ISO C++ does not allow designated initializers");
/* Consume the identifier. */
identifier = cp_lexer_consume_token (parser->lexer)->u.value;
/* Consume the `:'. */
@@ -14374,10 +14528,12 @@ cp_parser_class_name (cp_parser *parser,
/*is_template=*/false,
/*is_namespace=*/false,
check_dependency_p,
- &ambiguous_decls);
+ &ambiguous_decls,
+ identifier_token->location);
if (ambiguous_decls)
{
- error ("reference to %qD is ambiguous", identifier);
+ error ("%Hreference to %qD is ambiguous",
+ &identifier_token->location, identifier);
print_candidates (ambiguous_decls);
if (cp_parser_parsing_tentatively (parser))
{
@@ -14668,7 +14824,7 @@ cp_parser_class_head (cp_parser* parser,
bool invalid_explicit_specialization_p = false;
tree pushed_scope = NULL_TREE;
unsigned num_templates;
-
+ cp_token *type_start_token = NULL, *nested_name_specifier_token_start = NULL;
/* Assume no nested-name-specifier will be present. */
*nested_name_specifier_p = false;
/* Assume no template parameter lists will be used in defining the
@@ -14701,6 +14857,7 @@ cp_parser_class_head (cp_parser* parser,
/* Determine the name of the class. Begin by looking for an
optional nested-name-specifier. */
+ nested_name_specifier_token_start = cp_lexer_peek_token (parser->lexer);
nested_name_specifier
= cp_parser_nested_name_specifier_opt (parser,
/*typename_keyword_p=*/false,
@@ -14711,6 +14868,7 @@ cp_parser_class_head (cp_parser* parser,
identifier. */
if (nested_name_specifier)
{
+ type_start_token = cp_lexer_peek_token (parser->lexer);
/* Although the grammar says `identifier', it really means
`class-name' or `template-name'. You are only allowed to
define a class that has already been declared with this
@@ -14740,6 +14898,7 @@ cp_parser_class_head (cp_parser* parser,
if (!cp_parser_parse_definitely (parser))
{
invalid_nested_name_p = true;
+ type_start_token = cp_lexer_peek_token (parser->lexer);
id = cp_parser_identifier (parser);
if (id == error_mark_node)
id = NULL_TREE;
@@ -14774,6 +14933,7 @@ cp_parser_class_head (cp_parser* parser,
an identifier, or nothing at all. */
cp_parser_parse_tentatively (parser);
/* Check for a template-id. */
+ type_start_token = cp_lexer_peek_token (parser->lexer);
id = cp_parser_template_id (parser,
/*template_keyword_p=*/false,
/*check_dependency_p=*/true,
@@ -14782,7 +14942,10 @@ cp_parser_class_head (cp_parser* parser,
if (!cp_parser_parse_definitely (parser))
{
if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
- id = cp_parser_identifier (parser);
+ {
+ type_start_token = cp_lexer_peek_token (parser->lexer);
+ id = cp_parser_identifier (parser);
+ }
else
id = NULL_TREE;
}
@@ -14796,7 +14959,8 @@ cp_parser_class_head (cp_parser* parser,
pop_deferring_access_checks ();
if (id)
- cp_parser_check_for_invalid_template_id (parser, id);
+ cp_parser_check_for_invalid_template_id (parser, id,
+ type_start_token->location);
/* If it's not a `:' or a `{' then we can't really be looking at a
class-head, since a class-head only appears as part of a
@@ -14825,7 +14989,8 @@ cp_parser_class_head (cp_parser* parser,
/* Reject typedef-names in class heads. */
if (!DECL_IMPLICIT_TYPEDEF_P (type))
{
- error ("invalid class name in declaration of %qD", type);
+ error ("%Hinvalid class name in declaration of %qD",
+ &type_start_token->location, type);
type = NULL_TREE;
goto done;
}
@@ -14837,23 +15002,27 @@ cp_parser_class_head (cp_parser* parser,
if (scope && !is_ancestor (scope, nested_name_specifier))
{
if (at_namespace_scope_p ())
- error ("declaration of %qD in namespace %qD which does not "
- "enclose %qD", type, scope, nested_name_specifier);
+ error ("%Hdeclaration of %qD in namespace %qD which does not "
+ "enclose %qD",
+ &type_start_token->location,
+ type, scope, nested_name_specifier);
else
- error ("declaration of %qD in %qD which does not enclose %qD",
+ error ("%Hdeclaration of %qD in %qD which does not enclose %qD",
+ &type_start_token->location,
type, scope, nested_name_specifier);
type = NULL_TREE;
goto done;
}
/* [dcl.meaning]
- A declarator-id shall not be qualified exception of the
+ A declarator-id shall not be qualified except for the
definition of a ... nested class outside of its class
- ... [or] a the definition or explicit instantiation of a
+ ... [or] the definition or explicit instantiation of a
class member of a namespace outside of its namespace. */
if (scope == nested_name_specifier)
{
- permerror ("extra qualification not allowed");
+ permerror ("%Hextra qualification not allowed",
+ &nested_name_specifier_token_start->location);
nested_name_specifier = NULL_TREE;
num_templates = 0;
}
@@ -14864,7 +15033,8 @@ cp_parser_class_head (cp_parser* parser,
&& parser->num_template_parameter_lists == 0
&& template_id_p)
{
- error ("an explicit specialization must be preceded by %<template <>%>");
+ error ("%Han explicit specialization must be preceded by %<template <>%>",
+ &type_start_token->location);
invalid_explicit_specialization_p = true;
/* Take the same action that would have been taken by
cp_parser_explicit_specialization. */
@@ -14876,7 +15046,8 @@ cp_parser_class_head (cp_parser* parser,
use "goto done;" to return. */
/* Make sure that the right number of template parameters were
present. */
- if (!cp_parser_check_template_parameters (parser, num_templates))
+ if (!cp_parser_check_template_parameters (parser, num_templates,
+ type_start_token->location))
{
/* If something went wrong, there is no point in even trying to
process the class-definition. */
@@ -14891,7 +15062,8 @@ cp_parser_class_head (cp_parser* parser,
&& (DECL_FUNCTION_TEMPLATE_P (TREE_OPERAND (id, 0))
|| TREE_CODE (TREE_OPERAND (id, 0)) == OVERLOAD))
{
- error ("function template %qD redeclared as a class template", id);
+ error ("%Hfunction template %qD redeclared as a class template",
+ &type_start_token->location, id);
type = error_mark_node;
}
else
@@ -14972,8 +15144,10 @@ cp_parser_class_head (cp_parser* parser,
that's an error. */
if (type != error_mark_node && COMPLETE_TYPE_P (type))
{
- error ("redefinition of %q#T", type);
- error ("previous definition of %q+#T", type);
+ error ("%Hredefinition of %q#T",
+ &type_start_token->location, type);
+ error ("%Hprevious definition of %q+#T",
+ &type_start_token->location, type);
type = NULL_TREE;
goto done;
}
@@ -15128,7 +15302,9 @@ cp_parser_member_declaration (cp_parser* parser)
tree decl;
int declares_class_or_enum;
bool friend_p;
- cp_token *token;
+ cp_token *token = NULL;
+ cp_token *decl_spec_token_start = NULL;
+ cp_token *initializer_token_start = NULL;
int saved_pedantic;
/* Check for the `__extension__' keyword. */
@@ -15192,6 +15368,7 @@ cp_parser_member_declaration (cp_parser* parser)
return;
/* Parse the decl-specifier-seq. */
+ decl_spec_token_start = cp_lexer_peek_token (parser->lexer);
cp_parser_decl_specifier_seq (parser,
CP_PARSER_FLAGS_OPTIONAL,
&decl_specifiers,
@@ -15218,8 +15395,8 @@ cp_parser_member_declaration (cp_parser* parser)
if (!decl_specifiers.any_specifiers_p)
{
cp_token *token = cp_lexer_peek_token (parser->lexer);
- if (pedantic && !token->in_system_header)
- pedwarn ("%Hextra %<;%>", &token->location);
+ if (!in_system_header_at (token->location))
+ pedwarn (OPT_pedantic, "%Hextra %<;%>", &token->location);
}
else
{
@@ -15237,7 +15414,8 @@ cp_parser_member_declaration (cp_parser* parser)
/* If the `friend' keyword was present, the friend must
be introduced with a class-key. */
if (!declares_class_or_enum)
- error ("a class-key must be used when declaring a friend");
+ error ("%Ha class-key must be used when declaring a friend",
+ &decl_spec_token_start->location);
/* In this case:
template <typename T> struct A {
@@ -15251,8 +15429,8 @@ cp_parser_member_declaration (cp_parser* parser)
&& TYPE_P (decl_specifiers.type))
type = decl_specifiers.type;
if (!type || !TYPE_P (type))
- error ("friend declaration does not name a class or "
- "function");
+ error ("%Hfriend declaration does not name a class or "
+ "function", &decl_spec_token_start->location);
else
make_friend_class (current_class_type, type,
/*complain=*/true);
@@ -15275,7 +15453,9 @@ cp_parser_member_declaration (cp_parser* parser)
finish_member_declaration (decl);
}
else
- cp_parser_check_access_in_redeclaration (TYPE_NAME (type));
+ cp_parser_check_access_in_redeclaration
+ (TYPE_NAME (type),
+ decl_spec_token_start->location);
}
}
else
@@ -15369,7 +15549,8 @@ cp_parser_member_declaration (cp_parser* parser)
if (declares_class_or_enum & 2)
cp_parser_check_for_definition_in_return_type
- (declarator, decl_specifiers.type);
+ (declarator, decl_specifiers.type,
+ decl_specifiers.type_location);
/* Look for an asm-specification. */
asm_specification = cp_parser_asm_specification_opt (parser);
@@ -15403,6 +15584,7 @@ cp_parser_member_declaration (cp_parser* parser)
for a pure-specifier; otherwise, we look for a
constant-initializer. When we call `grokfield', it will
perform more stringent semantics checks. */
+ initializer_token_start = cp_lexer_peek_token (parser->lexer);
if (function_declarator_p (declarator))
initializer = cp_parser_pure_specifier (parser);
else
@@ -15427,7 +15609,8 @@ cp_parser_member_declaration (cp_parser* parser)
standard, since a pure function may be defined
outside of the class-specifier. */
if (initializer)
- error ("pure-specifier on function-definition");
+ error ("%Hpure-specifier on function-definition",
+ &initializer_token_start->location);
decl = cp_parser_save_member_function_body (parser,
&decl_specifiers,
declarator,
@@ -15508,6 +15691,15 @@ cp_parser_pure_specifier (cp_parser* parser)
return error_mark_node;
/* Look for the `0' token. */
token = cp_lexer_consume_token (parser->lexer);
+
+ /* Accept = default or = delete in c++0x mode. */
+ if (token->keyword == RID_DEFAULT
+ || token->keyword == RID_DELETE)
+ {
+ maybe_warn_cpp0x ("defaulted and deleted functions");
+ return token->u.value;
+ }
+
/* c_lex_with_flags marks a single digit '0' with PURE_ZERO. */
if (token->type != CPP_NUMBER || !(token->flags & PURE_ZERO))
{
@@ -15518,7 +15710,7 @@ cp_parser_pure_specifier (cp_parser* parser)
}
if (PROCESSING_REAL_TEMPLATE_DECL_P ())
{
- error ("templates may not be %<virtual%>");
+ error ("%Htemplates may not be %<virtual%>", &token->location);
return error_mark_node;
}
@@ -15720,11 +15912,14 @@ cp_parser_base_specifier (cp_parser* parser)
as base classes. */
if (cp_lexer_next_token_is_keyword (parser->lexer, RID_TYPENAME))
{
+ token = cp_lexer_peek_token (parser->lexer);
if (!processing_template_decl)
- error ("keyword %<typename%> not allowed outside of templates");
+ error ("%Hkeyword %<typename%> not allowed outside of templates",
+ &token->location);
else
- error ("keyword %<typename%> not allowed in this context "
- "(the base class is implicitly a type)");
+ error ("%Hkeyword %<typename%> not allowed in this context "
+ "(the base class is implicitly a type)",
+ &token->location);
cp_lexer_consume_token (parser->lexer);
}
@@ -16425,7 +16620,8 @@ cp_parser_lookup_name (cp_parser *parser, tree name,
bool is_template,
bool is_namespace,
bool check_dependency,
- tree *ambiguous_decls)
+ tree *ambiguous_decls,
+ location_t name_location)
{
int flags = 0;
tree decl;
@@ -16606,7 +16802,8 @@ cp_parser_lookup_name (cp_parser *parser, tree name,
cp_parser_error, so we incorporate its actions directly. */
if (!cp_parser_simulate_error (parser))
{
- error ("reference to %qD is ambiguous", name);
+ error ("%Hreference to %qD is ambiguous",
+ &name_location, name);
print_candidates (decl);
}
return error_mark_node;
@@ -16636,14 +16833,15 @@ cp_parser_lookup_name (cp_parser *parser, tree name,
IS_NAMESPACE is FALSE, and CHECK_DEPENDENCY is TRUE. */
static tree
-cp_parser_lookup_name_simple (cp_parser* parser, tree name)
+cp_parser_lookup_name_simple (cp_parser* parser, tree name, location_t location)
{
return cp_parser_lookup_name (parser, name,
none_type,
/*is_template=*/false,
/*is_namespace=*/false,
/*check_dependency=*/true,
- /*ambiguous_decls=*/NULL);
+ /*ambiguous_decls=*/NULL,
+ location);
}
/* If DECL is a TEMPLATE_DECL that can be treated like a TYPE_DECL in
@@ -16696,7 +16894,8 @@ cp_parser_maybe_treat_template_as_class (tree decl, bool tag_name_p)
static bool
cp_parser_check_declarator_template_parameters (cp_parser* parser,
- cp_declarator *declarator)
+ cp_declarator *declarator,
+ location_t declarator_location)
{
unsigned num_templates;
@@ -16746,7 +16945,8 @@ cp_parser_check_declarator_template_parameters (cp_parser* parser,
++num_templates;
return cp_parser_check_template_parameters (parser,
- num_templates);
+ num_templates,
+ declarator_location);
case cdk_function:
case cdk_array:
@@ -16754,7 +16954,7 @@ cp_parser_check_declarator_template_parameters (cp_parser* parser,
case cdk_reference:
case cdk_ptrmem:
return (cp_parser_check_declarator_template_parameters
- (parser, declarator->declarator));
+ (parser, declarator->declarator, declarator_location));
case cdk_error:
return true;
@@ -16771,7 +16971,8 @@ cp_parser_check_declarator_template_parameters (cp_parser* parser,
static bool
cp_parser_check_template_parameters (cp_parser* parser,
- unsigned num_templates)
+ unsigned num_templates,
+ location_t location)
{
/* If there are more template classes than parameter lists, we have
something like:
@@ -16779,7 +16980,7 @@ cp_parser_check_template_parameters (cp_parser* parser,
template <class T> void S<T>::R<T>::f (); */
if (parser->num_template_parameter_lists < num_templates)
{
- error ("too few template-parameter-lists");
+ error ("%Htoo few template-parameter-lists", &location);
return false;
}
/* If there are the same number of template classes and parameter
@@ -16794,7 +16995,7 @@ cp_parser_check_template_parameters (cp_parser* parser,
something like:
template <class T> template <class U> void S::f(); */
- error ("too many template-parameter-lists");
+ error ("%Htoo many template-parameter-lists", &location);
return false;
}
@@ -17052,12 +17253,14 @@ cp_parser_function_definition_after_declarator (cp_parser* parser,
bool saved_in_unbraced_linkage_specification_p;
bool saved_in_function_body;
unsigned saved_num_template_parameter_lists;
+ cp_token *token;
saved_in_function_body = parser->in_function_body;
parser->in_function_body = true;
/* If the next token is `return', then the code may be trying to
make use of the "named return value" extension that G++ used to
support. */
+ token = cp_lexer_peek_token (parser->lexer);
if (cp_lexer_next_token_is_keyword (parser->lexer, RID_RETURN))
{
/* Consume the `return' keyword. */
@@ -17066,7 +17269,8 @@ cp_parser_function_definition_after_declarator (cp_parser* parser,
returned. */
cp_parser_identifier (parser);
/* Issue an error message. */
- error ("named return values are no longer supported");
+ error ("%Hnamed return values are no longer supported",
+ &token->location);
/* Skip tokens until we reach the start of the function body. */
while (true)
{
@@ -17125,8 +17329,10 @@ cp_parser_template_declaration_after_export (cp_parser* parser, bool member_p)
tree parameter_list;
bool friend_p = false;
bool need_lang_pop;
+ cp_token *token;
/* Look for the `template' keyword. */
+ token = cp_lexer_peek_token (parser->lexer);
if (!cp_parser_require_keyword (parser, RID_TEMPLATE, "%<template%>"))
return;
@@ -17138,7 +17344,8 @@ cp_parser_template_declaration_after_export (cp_parser* parser, bool member_p)
/* 14.5.2.2 [temp.mem]
A local class shall not have member templates. */
- error ("invalid declaration of member template in local class");
+ error ("%Hinvalid declaration of member template in local class",
+ &token->location);
cp_parser_skip_to_end_of_block_or_statement (parser);
return;
}
@@ -17147,7 +17354,7 @@ cp_parser_template_declaration_after_export (cp_parser* parser, bool member_p)
A template ... shall not have C linkage. */
if (current_lang_name == lang_name_c)
{
- error ("template with C linkage");
+ error ("%Htemplate with C linkage", &token->location);
/* Give it C++ linkage to avoid confusing other parts of the
front end. */
push_lang_context (lang_name_cplusplus);
@@ -17194,6 +17401,7 @@ cp_parser_template_declaration_after_export (cp_parser* parser, bool member_p)
/* There are no access checks when parsing a template, as we do not
know if a specialization will be a friend. */
push_deferring_access_checks (dk_no_check);
+ token = cp_lexer_peek_token (parser->lexer);
decl = cp_parser_single_declaration (parser,
checks,
member_p,
@@ -17206,7 +17414,7 @@ cp_parser_template_declaration_after_export (cp_parser* parser, bool member_p)
if (member_p && !friend_p && decl)
{
if (TREE_CODE (decl) == TYPE_DECL)
- cp_parser_check_access_in_redeclaration (decl);
+ cp_parser_check_access_in_redeclaration (decl, token->location);
decl = finish_member_template_decl (decl);
}
@@ -17270,6 +17478,7 @@ cp_parser_single_declaration (cp_parser* parser,
tree decl = NULL_TREE;
cp_decl_specifier_seq decl_specifiers;
bool function_definition_p = false;
+ cp_token *decl_spec_token_start;
/* This function is only used when processing a template
declaration. */
@@ -17281,6 +17490,7 @@ cp_parser_single_declaration (cp_parser* parser,
/* Try the `decl-specifier-seq [opt] init-declarator [opt]'
alternative. */
+ decl_spec_token_start = cp_lexer_peek_token (parser->lexer);
cp_parser_decl_specifier_seq (parser,
CP_PARSER_FLAGS_OPTIONAL,
&decl_specifiers,
@@ -17291,7 +17501,8 @@ cp_parser_single_declaration (cp_parser* parser,
/* There are no template typedefs. */
if (decl_specifiers.specs[(int) ds_typedef])
{
- error ("template declaration of %qs", "typedef");
+ error ("%Htemplate declaration of %qs",
+ &decl_spec_token_start->location, "typedef");
decl = error_mark_node;
}
@@ -17354,7 +17565,8 @@ cp_parser_single_declaration (cp_parser* parser,
&& explicit_specialization_p
&& decl_specifiers.storage_class != sc_none)
{
- error ("explicit template specialization cannot have a storage class");
+ error ("%Hexplicit template specialization cannot have a storage class",
+ &decl_spec_token_start->location);
decl = error_mark_node;
}
}
@@ -17583,9 +17795,9 @@ cp_parser_enclosed_template_argument_list (cp_parser* parser)
is a typo for '>'. Emit an error message and continue.
Same deal about the token location, but here we can get it
right by consuming the '>>' before issuing the diagnostic. */
- cp_lexer_consume_token (parser->lexer);
- error ("spurious %<>>%>, use %<>%> to terminate "
- "a template argument list");
+ cp_token *token = cp_lexer_consume_token (parser->lexer);
+ error ("%Hspurious %<>>%>, use %<>%> to terminate "
+ "a template argument list", &token->location);
}
}
else
@@ -17906,14 +18118,15 @@ cp_parser_declares_only_class_p (cp_parser *parser)
static void
cp_parser_set_storage_class (cp_parser *parser,
cp_decl_specifier_seq *decl_specs,
- enum rid keyword)
+ enum rid keyword,
+ location_t location)
{
cp_storage_class storage_class;
if (parser->in_unbraced_linkage_specification_p)
{
- error ("invalid use of %qD in linkage specification",
- ridpointers[keyword]);
+ error ("%Hinvalid use of %qD in linkage specification",
+ &location, ridpointers[keyword]);
return;
}
else if (decl_specs->storage_class != sc_none)
@@ -17925,7 +18138,7 @@ cp_parser_set_storage_class (cp_parser *parser,
if ((keyword == RID_EXTERN || keyword == RID_STATIC)
&& decl_specs->specs[(int) ds_thread])
{
- error ("%<__thread%> before %qD", ridpointers[keyword]);
+ error ("%H%<__thread%> before %qD", &location, ridpointers[keyword]);
decl_specs->specs[(int) ds_thread] = 0;
}
@@ -17966,6 +18179,7 @@ cp_parser_set_storage_class (cp_parser *parser,
static void
cp_parser_set_decl_spec_type (cp_decl_specifier_seq *decl_specs,
tree type_spec,
+ location_t location,
bool user_defined_p)
{
decl_specs->any_specifiers_p = true;
@@ -17992,6 +18206,7 @@ cp_parser_set_decl_spec_type (cp_decl_specifier_seq *decl_specs,
{
decl_specs->type = type_spec;
decl_specs->user_defined_type_p = false;
+ decl_specs->type_location = location;
}
}
else if (decl_specs->type)
@@ -18001,6 +18216,7 @@ cp_parser_set_decl_spec_type (cp_decl_specifier_seq *decl_specs,
decl_specs->type = type_spec;
decl_specs->user_defined_type_p = user_defined_p;
decl_specs->redefined_builtin_type = NULL_TREE;
+ decl_specs->type_location = location;
}
}
@@ -18255,7 +18471,7 @@ cp_parser_check_class_key (enum tag_types class_key, tree type)
[class.mem/1]. */
static void
-cp_parser_check_access_in_redeclaration (tree decl)
+cp_parser_check_access_in_redeclaration (tree decl, location_t location)
{
if (!decl || !CLASS_TYPE_P (TREE_TYPE (decl)))
return;
@@ -18264,7 +18480,7 @@ cp_parser_check_access_in_redeclaration (tree decl)
!= (current_access_specifier == access_private_node))
|| (TREE_PROTECTED (decl)
!= (current_access_specifier == access_protected_node)))
- error ("%qD redeclared with different access", decl);
+ error ("%H%qD redeclared with different access", &location, decl);
}
/* Look for the `template' keyword, as a syntactic disambiguator.
@@ -18281,8 +18497,9 @@ cp_parser_optional_template_keyword (cp_parser *parser)
template and what is not. */
if (!processing_template_decl)
{
- error ("%<template%> (as a disambiguator) is only allowed "
- "within templates");
+ cp_token *token = cp_lexer_peek_token (parser->lexer);
+ error ("%H%<template%> (as a disambiguator) is only allowed "
+ "within templates", &token->location);
/* If this part of the token stream is rescanned, the same
error message would be generated. So, we purge the token
from the stream. */
@@ -18547,7 +18764,8 @@ cp_parser_objc_expression (cp_parser* parser)
break;
}
default:
- error ("misplaced %<@%D%> Objective-C++ construct", kwd->u.value);
+ error ("%Hmisplaced %<@%D%> Objective-C++ construct",
+ &kwd->location, kwd->u.value);
cp_parser_skip_to_end_of_block_or_statement (parser);
}
@@ -18680,15 +18898,18 @@ static tree
cp_parser_objc_encode_expression (cp_parser* parser)
{
tree type;
+ cp_token *token;
cp_lexer_consume_token (parser->lexer); /* Eat '@encode'. */
cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>");
+ token = cp_lexer_peek_token (parser->lexer);
type = complete_type (cp_parser_type_id (parser));
cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>");
if (!type)
{
- error ("%<@encode%> must specify a type as an argument");
+ error ("%H%<@encode%> must specify a type as an argument",
+ &token->location);
return error_mark_node;
}
@@ -18961,7 +19182,7 @@ cp_parser_objc_protocol_qualifiers (cp_parser* parser)
static tree
cp_parser_objc_typename (cp_parser* parser)
{
- tree typename = NULL_TREE;
+ tree type_name = NULL_TREE;
if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
{
@@ -18976,10 +19197,10 @@ cp_parser_objc_typename (cp_parser* parser)
cp_type = cp_parser_type_id (parser);
cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>");
- typename = build_tree_list (proto_quals, cp_type);
+ type_name = build_tree_list (proto_quals, cp_type);
}
- return typename;
+ return type_name;
}
/* Check to see if TYPE refers to an Objective-C selector name. */
@@ -19003,7 +19224,7 @@ cp_parser_objc_selector (cp_parser* parser)
if (!cp_parser_objc_selector_p (token->type))
{
- error ("invalid Objective-C++ selector name");
+ error ("%Hinvalid Objective-C++ selector name", &token->location);
return error_mark_node;
}
@@ -19036,7 +19257,7 @@ cp_parser_objc_method_keyword_params (cp_parser* parser)
while (cp_parser_objc_selector_p (token->type) || token->type == CPP_COLON)
{
- tree selector = NULL_TREE, typename, identifier;
+ tree selector = NULL_TREE, type_name, identifier;
if (token->type != CPP_COLON)
selector = cp_parser_objc_selector (parser);
@@ -19048,13 +19269,13 @@ cp_parser_objc_method_keyword_params (cp_parser* parser)
maybe_unary_selector_p = false;
cp_parser_require (parser, CPP_COLON, "%<:%>");
- typename = cp_parser_objc_typename (parser);
+ type_name = cp_parser_objc_typename (parser);
identifier = cp_parser_identifier (parser);
params
= chainon (params,
objc_build_keyword_decl (selector,
- typename,
+ type_name,
identifier));
token = cp_lexer_peek_token (parser->lexer);
@@ -19333,7 +19554,8 @@ cp_parser_objc_protocol_declaration (cp_parser* parser)
cp_lexer_consume_token (parser->lexer); /* Eat '@protocol'. */
if (cp_lexer_next_token_is_not (parser->lexer, CPP_NAME))
{
- error ("identifier expected after %<@protocol%>");
+ tok = cp_lexer_peek_token (parser->lexer);
+ error ("%Hidentifier expected after %<@protocol%>", &tok->location);
goto finish;
}
@@ -19469,7 +19691,8 @@ cp_parser_objc_declaration (cp_parser* parser)
cp_parser_objc_end_implementation (parser);
break;
default:
- error ("misplaced %<@%D%> Objective-C++ construct", kwd->u.value);
+ error ("%Hmisplaced %<@%D%> Objective-C++ construct",
+ &kwd->location, kwd->u.value);
cp_parser_skip_to_end_of_block_or_statement (parser);
}
}
@@ -19600,7 +19823,8 @@ cp_parser_objc_statement (cp_parser * parser) {
case RID_AT_THROW:
return cp_parser_objc_throw_statement (parser);
default:
- error ("misplaced %<@%D%> Objective-C++ construct", kwd->u.value);
+ error ("%Hmisplaced %<@%D%> Objective-C++ construct",
+ &kwd->location, kwd->u.value);
cp_parser_skip_to_end_of_block_or_statement (parser);
}
@@ -19684,14 +19908,15 @@ cp_parser_omp_clause_name (cp_parser *parser)
/* Validate that a clause of the given type does not already exist. */
static void
-check_no_duplicate_clause (tree clauses, enum tree_code code, const char *name)
+check_no_duplicate_clause (tree clauses, enum tree_code code,
+ const char *name, location_t location)
{
tree c;
for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
if (OMP_CLAUSE_CODE (c) == code)
{
- error ("too many %qs clauses", name);
+ error ("%Htoo many %qs clauses", &location, name);
break;
}
}
@@ -19714,10 +19939,12 @@ static tree
cp_parser_omp_var_list_no_open (cp_parser *parser, enum omp_clause_code kind,
tree list)
{
+ cp_token *token;
while (1)
{
tree name, decl;
+ token = cp_lexer_peek_token (parser->lexer);
name = cp_parser_id_expression (parser, /*template_p=*/false,
/*check_dependency_p=*/true,
/*template_p=*/NULL,
@@ -19726,9 +19953,9 @@ cp_parser_omp_var_list_no_open (cp_parser *parser, enum omp_clause_code kind,
if (name == error_mark_node)
goto skip_comma;
- decl = cp_parser_lookup_name_simple (parser, name);
+ decl = cp_parser_lookup_name_simple (parser, name, token->location);
if (decl == error_mark_node)
- cp_parser_name_lookup_error (parser, name, decl, NULL);
+ cp_parser_name_lookup_error (parser, name, decl, NULL, token->location);
else if (kind != 0)
{
tree u = build_omp_clause (kind);
@@ -19778,7 +20005,7 @@ cp_parser_omp_var_list (cp_parser *parser, enum omp_clause_code kind, tree list)
collapse ( constant-expression ) */
static tree
-cp_parser_omp_clause_collapse (cp_parser *parser, tree list)
+cp_parser_omp_clause_collapse (cp_parser *parser, tree list, location_t location)
{
tree c, num;
location_t loc;
@@ -19803,11 +20030,12 @@ cp_parser_omp_clause_collapse (cp_parser *parser, tree list)
|| (n = tree_low_cst (num, 0)) <= 0
|| (int) n != n)
{
- error ("%Hcollapse argument needs positive constant integer expression", &loc);
+ error ("%Hcollapse argument needs positive constant integer expression",
+ &loc);
return list;
}
- check_no_duplicate_clause (list, OMP_CLAUSE_COLLAPSE, "collapse");
+ check_no_duplicate_clause (list, OMP_CLAUSE_COLLAPSE, "collapse", location);
c = build_omp_clause (OMP_CLAUSE_COLLAPSE);
OMP_CLAUSE_CHAIN (c) = list;
OMP_CLAUSE_COLLAPSE_EXPR (c) = num;
@@ -19819,7 +20047,7 @@ cp_parser_omp_clause_collapse (cp_parser *parser, tree list)
default ( shared | none ) */
static tree
-cp_parser_omp_clause_default (cp_parser *parser, tree list)
+cp_parser_omp_clause_default (cp_parser *parser, tree list, location_t location)
{
enum omp_clause_default_kind kind = OMP_CLAUSE_DEFAULT_UNSPECIFIED;
tree c;
@@ -19865,7 +20093,7 @@ cp_parser_omp_clause_default (cp_parser *parser, tree list)
if (kind == OMP_CLAUSE_DEFAULT_UNSPECIFIED)
return list;
- check_no_duplicate_clause (list, OMP_CLAUSE_DEFAULT, "default");
+ check_no_duplicate_clause (list, OMP_CLAUSE_DEFAULT, "default", location);
c = build_omp_clause (OMP_CLAUSE_DEFAULT);
OMP_CLAUSE_CHAIN (c) = list;
OMP_CLAUSE_DEFAULT_KIND (c) = kind;
@@ -19877,7 +20105,7 @@ cp_parser_omp_clause_default (cp_parser *parser, tree list)
if ( expression ) */
static tree
-cp_parser_omp_clause_if (cp_parser *parser, tree list)
+cp_parser_omp_clause_if (cp_parser *parser, tree list, location_t location)
{
tree t, c;
@@ -19892,7 +20120,7 @@ cp_parser_omp_clause_if (cp_parser *parser, tree list)
/*or_comma=*/false,
/*consume_paren=*/true);
- check_no_duplicate_clause (list, OMP_CLAUSE_IF, "if");
+ check_no_duplicate_clause (list, OMP_CLAUSE_IF, "if", location);
c = build_omp_clause (OMP_CLAUSE_IF);
OMP_CLAUSE_IF_EXPR (c) = t;
@@ -19905,11 +20133,12 @@ cp_parser_omp_clause_if (cp_parser *parser, tree list)
nowait */
static tree
-cp_parser_omp_clause_nowait (cp_parser *parser ATTRIBUTE_UNUSED, tree list)
+cp_parser_omp_clause_nowait (cp_parser *parser ATTRIBUTE_UNUSED,
+ tree list, location_t location)
{
tree c;
- check_no_duplicate_clause (list, OMP_CLAUSE_NOWAIT, "nowait");
+ check_no_duplicate_clause (list, OMP_CLAUSE_NOWAIT, "nowait", location);
c = build_omp_clause (OMP_CLAUSE_NOWAIT);
OMP_CLAUSE_CHAIN (c) = list;
@@ -19920,7 +20149,8 @@ cp_parser_omp_clause_nowait (cp_parser *parser ATTRIBUTE_UNUSED, tree list)
num_threads ( expression ) */
static tree
-cp_parser_omp_clause_num_threads (cp_parser *parser, tree list)
+cp_parser_omp_clause_num_threads (cp_parser *parser, tree list,
+ location_t location)
{
tree t, c;
@@ -19935,7 +20165,8 @@ cp_parser_omp_clause_num_threads (cp_parser *parser, tree list)
/*or_comma=*/false,
/*consume_paren=*/true);
- check_no_duplicate_clause (list, OMP_CLAUSE_NUM_THREADS, "num_threads");
+ check_no_duplicate_clause (list, OMP_CLAUSE_NUM_THREADS,
+ "num_threads", location);
c = build_omp_clause (OMP_CLAUSE_NUM_THREADS);
OMP_CLAUSE_NUM_THREADS_EXPR (c) = t;
@@ -19948,11 +20179,13 @@ cp_parser_omp_clause_num_threads (cp_parser *parser, tree list)
ordered */
static tree
-cp_parser_omp_clause_ordered (cp_parser *parser ATTRIBUTE_UNUSED, tree list)
+cp_parser_omp_clause_ordered (cp_parser *parser ATTRIBUTE_UNUSED,
+ tree list, location_t location)
{
tree c;
- check_no_duplicate_clause (list, OMP_CLAUSE_ORDERED, "ordered");
+ check_no_duplicate_clause (list, OMP_CLAUSE_ORDERED,
+ "ordered", location);
c = build_omp_clause (OMP_CLAUSE_ORDERED);
OMP_CLAUSE_CHAIN (c) = list;
@@ -20029,7 +20262,7 @@ cp_parser_omp_clause_reduction (cp_parser *parser, tree list)
static | dynamic | guided | runtime | auto */
static tree
-cp_parser_omp_clause_schedule (cp_parser *parser, tree list)
+cp_parser_omp_clause_schedule (cp_parser *parser, tree list, location_t location)
{
tree c, t;
@@ -20077,18 +20310,20 @@ cp_parser_omp_clause_schedule (cp_parser *parser, tree list)
if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
{
+ cp_token *token;
cp_lexer_consume_token (parser->lexer);
+ token = cp_lexer_peek_token (parser->lexer);
t = cp_parser_assignment_expression (parser, false);
if (t == error_mark_node)
goto resync_fail;
else if (OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_RUNTIME)
- error ("schedule %<runtime%> does not take "
- "a %<chunk_size%> parameter");
+ error ("%Hschedule %<runtime%> does not take "
+ "a %<chunk_size%> parameter", &token->location);
else if (OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_AUTO)
- error ("schedule %<auto%> does not take "
- "a %<chunk_size%> parameter");
+ error ("%Hschedule %<auto%> does not take "
+ "a %<chunk_size%> parameter", &token->location);
else
OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c) = t;
@@ -20098,7 +20333,7 @@ cp_parser_omp_clause_schedule (cp_parser *parser, tree list)
else if (!cp_parser_require (parser, CPP_CLOSE_PAREN, "%<,%> or %<)%>"))
goto resync_fail;
- check_no_duplicate_clause (list, OMP_CLAUSE_SCHEDULE, "schedule");
+ check_no_duplicate_clause (list, OMP_CLAUSE_SCHEDULE, "schedule", location);
OMP_CLAUSE_CHAIN (c) = list;
return c;
@@ -20115,11 +20350,12 @@ cp_parser_omp_clause_schedule (cp_parser *parser, tree list)
untied */
static tree
-cp_parser_omp_clause_untied (cp_parser *parser ATTRIBUTE_UNUSED, tree list)
+cp_parser_omp_clause_untied (cp_parser *parser ATTRIBUTE_UNUSED,
+ tree list, location_t location)
{
tree c;
- check_no_duplicate_clause (list, OMP_CLAUSE_UNTIED, "untied");
+ check_no_duplicate_clause (list, OMP_CLAUSE_UNTIED, "untied", location);
c = build_omp_clause (OMP_CLAUSE_UNTIED);
OMP_CLAUSE_CHAIN (c) = list;
@@ -20136,6 +20372,7 @@ cp_parser_omp_all_clauses (cp_parser *parser, unsigned int mask,
{
tree clauses = NULL;
bool first = true;
+ cp_token *token = NULL;
while (cp_lexer_next_token_is_not (parser->lexer, CPP_PRAGMA_EOL))
{
@@ -20146,13 +20383,15 @@ cp_parser_omp_all_clauses (cp_parser *parser, unsigned int mask,
if (!first && cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
cp_lexer_consume_token (parser->lexer);
+ token = cp_lexer_peek_token (parser->lexer);
c_kind = cp_parser_omp_clause_name (parser);
first = false;
switch (c_kind)
{
case PRAGMA_OMP_CLAUSE_COLLAPSE:
- clauses = cp_parser_omp_clause_collapse (parser, clauses);
+ clauses = cp_parser_omp_clause_collapse (parser, clauses,
+ token->location);
c_name = "collapse";
break;
case PRAGMA_OMP_CLAUSE_COPYIN:
@@ -20165,7 +20404,8 @@ cp_parser_omp_all_clauses (cp_parser *parser, unsigned int mask,
c_name = "copyprivate";
break;
case PRAGMA_OMP_CLAUSE_DEFAULT:
- clauses = cp_parser_omp_clause_default (parser, clauses);
+ clauses = cp_parser_omp_clause_default (parser, clauses,
+ token->location);
c_name = "default";
break;
case PRAGMA_OMP_CLAUSE_FIRSTPRIVATE:
@@ -20174,7 +20414,7 @@ cp_parser_omp_all_clauses (cp_parser *parser, unsigned int mask,
c_name = "firstprivate";
break;
case PRAGMA_OMP_CLAUSE_IF:
- clauses = cp_parser_omp_clause_if (parser, clauses);
+ clauses = cp_parser_omp_clause_if (parser, clauses, token->location);
c_name = "if";
break;
case PRAGMA_OMP_CLAUSE_LASTPRIVATE:
@@ -20183,15 +20423,17 @@ cp_parser_omp_all_clauses (cp_parser *parser, unsigned int mask,
c_name = "lastprivate";
break;
case PRAGMA_OMP_CLAUSE_NOWAIT:
- clauses = cp_parser_omp_clause_nowait (parser, clauses);
+ clauses = cp_parser_omp_clause_nowait (parser, clauses, token->location);
c_name = "nowait";
break;
case PRAGMA_OMP_CLAUSE_NUM_THREADS:
- clauses = cp_parser_omp_clause_num_threads (parser, clauses);
+ clauses = cp_parser_omp_clause_num_threads (parser, clauses,
+ token->location);
c_name = "num_threads";
break;
case PRAGMA_OMP_CLAUSE_ORDERED:
- clauses = cp_parser_omp_clause_ordered (parser, clauses);
+ clauses = cp_parser_omp_clause_ordered (parser, clauses,
+ token->location);
c_name = "ordered";
break;
case PRAGMA_OMP_CLAUSE_PRIVATE:
@@ -20204,7 +20446,8 @@ cp_parser_omp_all_clauses (cp_parser *parser, unsigned int mask,
c_name = "reduction";
break;
case PRAGMA_OMP_CLAUSE_SCHEDULE:
- clauses = cp_parser_omp_clause_schedule (parser, clauses);
+ clauses = cp_parser_omp_clause_schedule (parser, clauses,
+ token->location);
c_name = "schedule";
break;
case PRAGMA_OMP_CLAUSE_SHARED:
@@ -20213,7 +20456,8 @@ cp_parser_omp_all_clauses (cp_parser *parser, unsigned int mask,
c_name = "shared";
break;
case PRAGMA_OMP_CLAUSE_UNTIED:
- clauses = cp_parser_omp_clause_untied (parser, clauses);
+ clauses = cp_parser_omp_clause_untied (parser, clauses,
+ token->location);
c_name = "nowait";
break;
default:
@@ -20226,7 +20470,7 @@ cp_parser_omp_all_clauses (cp_parser *parser, unsigned int mask,
/* Remove the invalid clause(s) from the list to avoid
confusing the rest of the compiler. */
clauses = prev;
- error ("%qs is not valid for %qs", c_name, where);
+ error ("%H%qs is not valid for %qs", &token->location, c_name, where);
}
}
saw_error:
@@ -20902,7 +21146,10 @@ cp_parser_omp_for_loop (cp_parser *parser, tree clauses, tree *par_clauses)
else
{
if (!collapse_err)
- error ("collapsed loops not perfectly nested");
+ {
+ location_t loc = cp_lexer_peek_token (parser->lexer)->location;
+ error ("%Hcollapsed loops not perfectly nested", &loc);
+ }
collapse_err = true;
cp_parser_statement_seq_opt (parser, NULL);
cp_parser_require (parser, CPP_CLOSE_BRACE, "%<}%>");
@@ -21312,10 +21559,11 @@ cp_parser_initial_pragma (cp_token *first_token)
cp_lexer_get_preprocessor_token (NULL, first_token);
if (first_token->type != CPP_PRAGMA_EOL)
- error ("junk at end of %<#pragma GCC pch_preprocess%>");
+ error ("%Hjunk at end of %<#pragma GCC pch_preprocess%>",
+ &first_token->location);
}
else
- error ("expected string literal");
+ error ("%Hexpected string literal", &first_token->location);
/* Skip to the end of the pragma. */
while (first_token->type != CPP_PRAGMA_EOL && first_token->type != CPP_EOF)
@@ -21348,7 +21596,8 @@ cp_parser_pragma (cp_parser *parser, enum pragma_context context)
switch (id)
{
case PRAGMA_GCC_PCH_PREPROCESS:
- error ("%<#pragma GCC pch_preprocess%> must be first");
+ error ("%H%<#pragma GCC pch_preprocess%> must be first",
+ &pragma_tok->location);
break;
case PRAGMA_OMP_BARRIER:
@@ -21358,8 +21607,8 @@ cp_parser_pragma (cp_parser *parser, enum pragma_context context)
cp_parser_omp_barrier (parser, pragma_tok);
return false;
case pragma_stmt:
- error ("%<#pragma omp barrier%> may only be "
- "used in compound statements");
+ error ("%H%<#pragma omp barrier%> may only be "
+ "used in compound statements", &pragma_tok->location);
break;
default:
goto bad_stmt;
@@ -21373,8 +21622,8 @@ cp_parser_pragma (cp_parser *parser, enum pragma_context context)
cp_parser_omp_flush (parser, pragma_tok);
return false;
case pragma_stmt:
- error ("%<#pragma omp flush%> may only be "
- "used in compound statements");
+ error ("%H%<#pragma omp flush%> may only be "
+ "used in compound statements", &pragma_tok->location);
break;
default:
goto bad_stmt;
@@ -21388,8 +21637,9 @@ cp_parser_pragma (cp_parser *parser, enum pragma_context context)
cp_parser_omp_taskwait (parser, pragma_tok);
return false;
case pragma_stmt:
- error ("%<#pragma omp taskwait%> may only be "
- "used in compound statements");
+ error ("%H%<#pragma omp taskwait%> may only be "
+ "used in compound statements",
+ &pragma_tok->location);
break;
default:
goto bad_stmt;
@@ -21415,8 +21665,8 @@ cp_parser_pragma (cp_parser *parser, enum pragma_context context)
return true;
case PRAGMA_OMP_SECTION:
- error ("%<#pragma omp section%> may only be used in "
- "%<#pragma omp sections%> construct");
+ error ("%H%<#pragma omp section%> may only be used in "
+ "%<#pragma omp sections%> construct", &pragma_tok->location);
break;
default:
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index cce706f0705..b47ee5e6b3f 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -1022,10 +1022,10 @@ is_specialization_of (tree decl, tree tmpl)
}
/* Returns nonzero iff DECL is a specialization of friend declaration
- FRIEND according to [temp.friend]. */
+ FRIEND_DECL according to [temp.friend]. */
bool
-is_specialization_of_friend (tree decl, tree friend)
+is_specialization_of_friend (tree decl, tree friend_decl)
{
bool need_template = true;
int template_depth;
@@ -1033,26 +1033,26 @@ is_specialization_of_friend (tree decl, tree friend)
gcc_assert (TREE_CODE (decl) == FUNCTION_DECL
|| TREE_CODE (decl) == TYPE_DECL);
- /* For [temp.friend/6] when FRIEND is an ordinary member function
+ /* For [temp.friend/6] when FRIEND_DECL is an ordinary member function
of a template class, we want to check if DECL is a specialization
if this. */
- if (TREE_CODE (friend) == FUNCTION_DECL
- && DECL_TEMPLATE_INFO (friend)
- && !DECL_USE_TEMPLATE (friend))
+ if (TREE_CODE (friend_decl) == FUNCTION_DECL
+ && DECL_TEMPLATE_INFO (friend_decl)
+ && !DECL_USE_TEMPLATE (friend_decl))
{
/* We want a TEMPLATE_DECL for `is_specialization_of'. */
- friend = DECL_TI_TEMPLATE (friend);
+ friend_decl = DECL_TI_TEMPLATE (friend_decl);
need_template = false;
}
- else if (TREE_CODE (friend) == TEMPLATE_DECL
- && !PRIMARY_TEMPLATE_P (friend))
+ else if (TREE_CODE (friend_decl) == TEMPLATE_DECL
+ && !PRIMARY_TEMPLATE_P (friend_decl))
need_template = false;
/* There is nothing to do if this is not a template friend. */
- if (TREE_CODE (friend) != TEMPLATE_DECL)
+ if (TREE_CODE (friend_decl) != TEMPLATE_DECL)
return false;
- if (is_specialization_of (decl, friend))
+ if (is_specialization_of (decl, friend_decl))
return true;
/* [temp.friend/6]
@@ -1075,14 +1075,14 @@ is_specialization_of_friend (tree decl, tree friend)
nonzero. To determine if DECL is a friend of FRIEND, we first
check if the enclosing class is a specialization of another. */
- template_depth = template_class_depth (DECL_CONTEXT (friend));
+ template_depth = template_class_depth (DECL_CONTEXT (friend_decl));
if (template_depth
&& DECL_CLASS_SCOPE_P (decl)
&& is_specialization_of (TYPE_NAME (DECL_CONTEXT (decl)),
- CLASSTYPE_TI_TEMPLATE (DECL_CONTEXT (friend))))
+ CLASSTYPE_TI_TEMPLATE (DECL_CONTEXT (friend_decl))))
{
/* Next, we check the members themselves. In order to handle
- a few tricky cases, such as when FRIEND's are
+ a few tricky cases, such as when FRIEND_DECL's are
template <class T> friend void A<T>::g(T t);
template <class T> template <T t> friend void A<T>::h();
@@ -1122,7 +1122,7 @@ is_specialization_of_friend (tree decl, tree friend)
tree friend_args_type;
tree decl_args_type;
- /* Make sure that both DECL and FRIEND are templates or
+ /* Make sure that both DECL and FRIEND_DECL are templates or
non-templates. */
is_template = DECL_TEMPLATE_INFO (decl)
&& PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (decl));
@@ -1132,7 +1132,7 @@ is_specialization_of_friend (tree decl, tree friend)
{
/* If both are templates, check template parameter list. */
tree friend_parms
- = tsubst_template_parms (DECL_TEMPLATE_PARMS (friend),
+ = tsubst_template_parms (DECL_TEMPLATE_PARMS (friend_decl),
args, tf_none);
if (!comp_template_parms
(DECL_TEMPLATE_PARMS (DECL_TI_TEMPLATE (decl)),
@@ -1144,7 +1144,7 @@ is_specialization_of_friend (tree decl, tree friend)
else
decl_type = TREE_TYPE (decl);
- friend_type = tsubst_function_type (TREE_TYPE (friend), args,
+ friend_type = tsubst_function_type (TREE_TYPE (friend_decl), args,
tf_none, NULL_TREE);
if (friend_type == error_mark_node)
return false;
@@ -1157,7 +1157,7 @@ is_specialization_of_friend (tree decl, tree friend)
`this' parameter. */
friend_args_type = TYPE_ARG_TYPES (friend_type);
decl_args_type = TYPE_ARG_TYPES (decl_type);
- if (DECL_NONSTATIC_MEMBER_FUNCTION_P (friend))
+ if (DECL_NONSTATIC_MEMBER_FUNCTION_P (friend_decl))
friend_args_type = TREE_CHAIN (friend_args_type);
if (DECL_NONSTATIC_MEMBER_FUNCTION_P (decl))
decl_args_type = TREE_CHAIN (decl_args_type);
@@ -1170,7 +1170,7 @@ is_specialization_of_friend (tree decl, tree friend)
bool is_template;
tree decl_type = TREE_TYPE (decl);
- /* Make sure that both DECL and FRIEND are templates or
+ /* Make sure that both DECL and FRIEND_DECL are templates or
non-templates. */
is_template
= CLASSTYPE_TEMPLATE_INFO (decl_type)
@@ -1184,12 +1184,12 @@ is_specialization_of_friend (tree decl, tree friend)
/* If both are templates, check the name of the two
TEMPLATE_DECL's first because is_friend didn't. */
if (DECL_NAME (CLASSTYPE_TI_TEMPLATE (decl_type))
- != DECL_NAME (friend))
+ != DECL_NAME (friend_decl))
return false;
/* Now check template parameter list. */
friend_parms
- = tsubst_template_parms (DECL_TEMPLATE_PARMS (friend),
+ = tsubst_template_parms (DECL_TEMPLATE_PARMS (friend_decl),
args, tf_none);
return comp_template_parms
(DECL_TEMPLATE_PARMS (CLASSTYPE_TI_TEMPLATE (decl_type)),
@@ -1197,7 +1197,7 @@ is_specialization_of_friend (tree decl, tree friend)
}
else
return (DECL_NAME (decl)
- == DECL_NAME (friend));
+ == DECL_NAME (friend_decl));
}
}
return false;
@@ -4241,7 +4241,7 @@ fold_non_dependent_expr (tree expr)
/* EXPR is an expression which is used in a constant-expression context.
For instance, it could be a VAR_DECL with a constant initializer.
- Extract the innest constant expression.
+ Extract the innermost constant expression.
This is basically a more powerful version of
integral_constant_value, which can be used also in templates where
@@ -5536,7 +5536,7 @@ lookup_template_class (tree d1,
int entering_scope,
tsubst_flags_t complain)
{
- tree template = NULL_TREE, parmlist;
+ tree templ = NULL_TREE, parmlist;
tree t;
timevar_push (TV_NAME_LOOKUP);
@@ -5545,18 +5545,18 @@ lookup_template_class (tree d1,
{
tree value = innermost_non_namespace_value (d1);
if (value && DECL_TEMPLATE_TEMPLATE_PARM_P (value))
- template = value;
+ templ = value;
else
{
if (context)
push_decl_namespace (context);
- template = lookup_name (d1);
- template = maybe_get_template_decl_from_type_decl (template);
+ templ = lookup_name (d1);
+ templ = maybe_get_template_decl_from_type_decl (templ);
if (context)
pop_decl_namespace ();
}
- if (template)
- context = DECL_CONTEXT (template);
+ if (templ)
+ context = DECL_CONTEXT (templ);
}
else if (TREE_CODE (d1) == TYPE_DECL && MAYBE_CLASS_TYPE_P (TREE_TYPE (d1)))
{
@@ -5569,37 +5569,37 @@ lookup_template_class (tree d1,
if (CLASSTYPE_TEMPLATE_INFO (type))
{
- template = CLASSTYPE_TI_TEMPLATE (type);
- d1 = DECL_NAME (template);
+ templ = CLASSTYPE_TI_TEMPLATE (type);
+ d1 = DECL_NAME (templ);
}
}
else if (TREE_CODE (d1) == ENUMERAL_TYPE
|| (TYPE_P (d1) && MAYBE_CLASS_TYPE_P (d1)))
{
- template = TYPE_TI_TEMPLATE (d1);
- d1 = DECL_NAME (template);
+ templ = TYPE_TI_TEMPLATE (d1);
+ d1 = DECL_NAME (templ);
}
else if (TREE_CODE (d1) == TEMPLATE_DECL
&& TREE_CODE (DECL_TEMPLATE_RESULT (d1)) == TYPE_DECL)
{
- template = d1;
- d1 = DECL_NAME (template);
- context = DECL_CONTEXT (template);
+ templ = d1;
+ d1 = DECL_NAME (templ);
+ context = DECL_CONTEXT (templ);
}
/* Issue an error message if we didn't find a template. */
- if (! template)
+ if (! templ)
{
if (complain & tf_error)
error ("%qT is not a template", d1);
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
}
- if (TREE_CODE (template) != TEMPLATE_DECL
+ if (TREE_CODE (templ) != TEMPLATE_DECL
/* Make sure it's a user visible template, if it was named by
the user. */
- || ((complain & tf_user) && !DECL_TEMPLATE_PARM_P (template)
- && !PRIMARY_TEMPLATE_P (template)))
+ || ((complain & tf_user) && !DECL_TEMPLATE_PARM_P (templ)
+ && !PRIMARY_TEMPLATE_P (templ)))
{
if (complain & tf_error)
{
@@ -5612,7 +5612,7 @@ lookup_template_class (tree d1,
complain &= ~tf_user;
- if (DECL_TEMPLATE_TEMPLATE_PARM_P (template))
+ if (DECL_TEMPLATE_TEMPLATE_PARM_P (templ))
{
/* Create a new TEMPLATE_DECL and TEMPLATE_TEMPLATE_PARM node to store
template arguments */
@@ -5621,7 +5621,7 @@ lookup_template_class (tree d1,
tree arglist2;
tree outer;
- parmlist = DECL_INNERMOST_TEMPLATE_PARMS (template);
+ parmlist = DECL_INNERMOST_TEMPLATE_PARMS (templ);
/* Consider an example where a template template parameter declared as
@@ -5639,7 +5639,7 @@ lookup_template_class (tree d1,
level 1, and T at level 2, while the template arguments at level 1
becomes {std::vector} and the inner level 2 is {int}. */
- outer = DECL_CONTEXT (template);
+ outer = DECL_CONTEXT (templ);
if (outer)
outer = TI_ARGS (get_template_info (DECL_TEMPLATE_RESULT (outer)));
else if (current_template_parms)
@@ -5650,21 +5650,21 @@ lookup_template_class (tree d1,
if (outer)
arglist = add_to_template_args (outer, arglist);
- arglist2 = coerce_template_parms (parmlist, arglist, template,
+ arglist2 = coerce_template_parms (parmlist, arglist, templ,
complain,
/*require_all_args=*/true,
/*use_default_args=*/true);
if (arglist2 == error_mark_node
|| (!uses_template_parms (arglist2)
- && check_instantiated_args (template, arglist2, complain)))
+ && check_instantiated_args (templ, arglist2, complain)))
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
- parm = bind_template_template_parm (TREE_TYPE (template), arglist2);
+ parm = bind_template_template_parm (TREE_TYPE (templ), arglist2);
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, parm);
}
else
{
- tree template_type = TREE_TYPE (template);
+ tree template_type = TREE_TYPE (templ);
tree gen_tmpl;
tree type_decl;
tree found = NULL_TREE;
@@ -5672,7 +5672,7 @@ lookup_template_class (tree d1,
int parm_depth;
int is_partial_instantiation;
- gen_tmpl = most_general_template (template);
+ gen_tmpl = most_general_template (templ);
parmlist = DECL_TEMPLATE_PARMS (gen_tmpl);
parm_depth = TMPL_PARMS_DEPTH (parmlist);
arg_depth = TMPL_ARGS_DEPTH (arglist);
@@ -5692,7 +5692,7 @@ lookup_template_class (tree d1,
<class U> struct S1<T>::S2'. We must fill in the missing
arguments. */
arglist
- = add_outermost_template_args (TYPE_TI_ARGS (TREE_TYPE (template)),
+ = add_outermost_template_args (TYPE_TI_ARGS (TREE_TYPE (templ)),
arglist);
arg_depth = TMPL_ARGS_DEPTH (arglist);
}
@@ -5702,7 +5702,7 @@ lookup_template_class (tree d1,
/* From here on, we're only interested in the most general
template. */
- template = gen_tmpl;
+ templ = gen_tmpl;
/* Calculate the BOUND_ARGS. These will be the args that are
actually tsubst'd into the definition to create the
@@ -5716,12 +5716,12 @@ lookup_template_class (tree d1,
tree bound_args = make_tree_vec (parm_depth);
for (i = saved_depth,
- t = DECL_TEMPLATE_PARMS (template);
+ t = DECL_TEMPLATE_PARMS (templ);
i > 0 && t != NULL_TREE;
--i, t = TREE_CHAIN (t))
{
tree a = coerce_template_parms (TREE_VALUE (t),
- arglist, template,
+ arglist, templ,
complain,
/*require_all_args=*/true,
/*use_default_args=*/true);
@@ -5752,7 +5752,7 @@ lookup_template_class (tree d1,
arglist
= coerce_template_parms (INNERMOST_TEMPLATE_PARMS (parmlist),
INNERMOST_TEMPLATE_ARGS (arglist),
- template,
+ templ,
complain,
/*require_all_args=*/true,
/*use_default_args=*/true);
@@ -5774,7 +5774,7 @@ lookup_template_class (tree d1,
{
found = template_type;
- if (!entering_scope && PRIMARY_TEMPLATE_P (template))
+ if (!entering_scope && PRIMARY_TEMPLATE_P (templ))
{
tree ctx;
@@ -5796,7 +5796,7 @@ lookup_template_class (tree d1,
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, found);
/* If we already have this specialization, return it. */
- found = retrieve_specialization (template, arglist,
+ found = retrieve_specialization (templ, arglist,
/*class_specializations_p=*/false);
if (found)
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, found);
@@ -5810,22 +5810,22 @@ lookup_template_class (tree d1,
/* If the deduced arguments are invalid, then the binding
failed. */
if (!is_partial_instantiation
- && check_instantiated_args (template,
+ && check_instantiated_args (templ,
INNERMOST_TEMPLATE_ARGS (arglist),
complain))
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
if (!is_partial_instantiation
- && !PRIMARY_TEMPLATE_P (template)
- && TREE_CODE (CP_DECL_CONTEXT (template)) == NAMESPACE_DECL)
+ && !PRIMARY_TEMPLATE_P (templ)
+ && TREE_CODE (CP_DECL_CONTEXT (templ)) == NAMESPACE_DECL)
{
- found = xref_tag_from_type (TREE_TYPE (template),
- DECL_NAME (template),
+ found = xref_tag_from_type (TREE_TYPE (templ),
+ DECL_NAME (templ),
/*tag_scope=*/ts_global);
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, found);
}
- context = tsubst (DECL_CONTEXT (template), arglist,
+ context = tsubst (DECL_CONTEXT (templ), arglist,
complain, in_decl);
if (!context)
context = global_namespace;
@@ -5855,7 +5855,7 @@ lookup_template_class (tree d1,
/* A local class. Make sure the decl gets registered properly. */
if (context == current_function_decl)
- pushtag (DECL_NAME (template), t, /*tag_scope=*/ts_current);
+ pushtag (DECL_NAME (templ), t, /*tag_scope=*/ts_current);
if (comp_template_args (CLASSTYPE_TI_ARGS (template_type), arglist))
/* This instantiation is another name for the primary
@@ -5875,7 +5875,7 @@ lookup_template_class (tree d1,
{
TYPE_CONTEXT (t) = FROB_CONTEXT (context);
- type_decl = create_implicit_typedef (DECL_NAME (template), t);
+ type_decl = create_implicit_typedef (DECL_NAME (templ), t);
DECL_CONTEXT (type_decl) = TYPE_CONTEXT (t);
TYPE_STUB_DECL (t) = type_decl;
DECL_SOURCE_LOCATION (type_decl)
@@ -5888,8 +5888,6 @@ lookup_template_class (tree d1,
= TREE_PRIVATE (TYPE_STUB_DECL (template_type));
TREE_PROTECTED (type_decl)
= TREE_PROTECTED (TYPE_STUB_DECL (template_type));
- DECL_IN_SYSTEM_HEADER (type_decl)
- = DECL_IN_SYSTEM_HEADER (template);
if (CLASSTYPE_VISIBILITY_SPECIFIED (template_type))
{
DECL_VISIBILITY_SPECIFIED (type_decl) = 1;
@@ -5900,15 +5898,15 @@ lookup_template_class (tree d1,
template is the immediate parent if this is a full
instantiation. */
if (parm_depth == 1 || is_partial_instantiation
- || !PRIMARY_TEMPLATE_P (template))
+ || !PRIMARY_TEMPLATE_P (templ))
/* This case is easy; there are no member templates involved. */
- found = template;
+ found = templ;
else
{
/* This is a full instantiation of a member template. Look
for a partial instantiation of which this is an instance. */
- for (found = DECL_TEMPLATE_INSTANTIATIONS (template);
+ for (found = DECL_TEMPLATE_INSTANTIATIONS (templ);
found; found = TREE_CHAIN (found))
{
int success;
@@ -5953,15 +5951,15 @@ lookup_template_class (tree d1,
Create the partial instantiation.
*/
TREE_VEC_LENGTH (arglist)--;
- found = tsubst (template, arglist, complain, NULL_TREE);
+ found = tsubst (templ, arglist, complain, NULL_TREE);
TREE_VEC_LENGTH (arglist)++;
}
}
SET_TYPE_TEMPLATE_INFO (t, tree_cons (found, arglist, NULL_TREE));
- DECL_TEMPLATE_INSTANTIATIONS (template)
+ DECL_TEMPLATE_INSTANTIATIONS (templ)
= tree_cons (arglist, t,
- DECL_TEMPLATE_INSTANTIATIONS (template));
+ DECL_TEMPLATE_INSTANTIATIONS (templ));
if (TREE_CODE (t) == ENUMERAL_TYPE
&& !is_partial_instantiation)
@@ -6292,7 +6290,7 @@ static int last_template_error_tick;
static int
push_tinst_level (tree d)
{
- struct tinst_level *new;
+ struct tinst_level *new_level;
if (tinst_depth >= max_tinst_depth)
{
@@ -6312,12 +6310,12 @@ push_tinst_level (tree d)
return 0;
}
- new = GGC_NEW (struct tinst_level);
- new->decl = d;
- new->locus = input_location;
- new->in_system_header_p = in_system_header;
- new->next = current_tinst_level;
- current_tinst_level = new;
+ new_level = GGC_NEW (struct tinst_level);
+ new_level->decl = d;
+ new_level->locus = input_location;
+ new_level->in_system_header_p = in_system_header;
+ new_level->next = current_tinst_level;
+ current_tinst_level = new_level;
++tinst_depth;
#ifdef GATHER_STATISTICS
@@ -6338,7 +6336,6 @@ pop_tinst_level (void)
/* Restore the filename and line number stashed away when we started
this instantiation. */
input_location = current_tinst_level->locus;
- in_system_header = current_tinst_level->in_system_header_p;
current_tinst_level = current_tinst_level->next;
--tinst_depth;
++tinst_level_tick;
@@ -6404,7 +6401,7 @@ tsubst_friend_function (tree decl, tree args)
/* Friend functions are looked up in the containing namespace scope.
We must enter that scope, to avoid finding member functions of the
- current cless with same name. */
+ current class with same name. */
push_nested_namespace (ns);
fns = tsubst_expr (DECL_TI_TEMPLATE (decl), args,
tf_warning_or_error, NULL_TREE,
@@ -6839,7 +6836,7 @@ apply_late_template_attributes (tree *decl_p, tree attributes, int attr_flags,
tree
instantiate_class_template (tree type)
{
- tree template, args, pattern, t, member;
+ tree templ, args, pattern, t, member;
tree typedecl;
tree pbinfo;
tree base_list;
@@ -6853,12 +6850,12 @@ instantiate_class_template (tree type)
return type;
/* Figure out which template is being instantiated. */
- template = most_general_template (CLASSTYPE_TI_TEMPLATE (type));
- gcc_assert (TREE_CODE (template) == TEMPLATE_DECL);
+ templ = most_general_template (CLASSTYPE_TI_TEMPLATE (type));
+ gcc_assert (TREE_CODE (templ) == TEMPLATE_DECL);
/* Determine what specialization of the original template to
instantiate. */
- t = most_specialized_class (type, template);
+ t = most_specialized_class (type, templ);
if (t == error_mark_node)
{
TYPE_BEING_DEFINED (type) = 1;
@@ -6881,7 +6878,7 @@ instantiate_class_template (tree type)
}
else
{
- pattern = TREE_TYPE (template);
+ pattern = TREE_TYPE (templ);
args = CLASSTYPE_TI_ARGS (type);
}
@@ -6910,7 +6907,6 @@ instantiate_class_template (tree type)
if tsubsting causes an error. */
typedecl = TYPE_MAIN_DECL (type);
input_location = DECL_SOURCE_LOCATION (typedecl);
- in_system_header = DECL_IN_SYSTEM_HEADER (typedecl);
TYPE_HAS_USER_CONSTRUCTOR (type) = TYPE_HAS_USER_CONSTRUCTOR (pattern);
TYPE_HAS_NEW_OPERATOR (type) = TYPE_HAS_NEW_OPERATOR (pattern);
@@ -7108,7 +7104,7 @@ instantiate_class_template (tree type)
{
tree r;
- /* The the file and line for this declaration, to
+ /* The file and line for this declaration, to
assist in error message reporting. Since we
called push_tinst_level above, we don't need to
restore these. */
@@ -7267,7 +7263,7 @@ instantiate_class_template (tree type)
/* Build new DECL_FRIENDLIST. */
tree r;
- /* The the file and line for this declaration, to
+ /* The file and line for this declaration, to
assist in error message reporting. Since we
called push_tinst_level above, we don't need to
restore these. */
@@ -7303,7 +7299,7 @@ instantiate_class_template (tree type)
/* Now that the class is complete, instantiate default arguments for
any member functions. We don't do this earlier because the
default arguments may reference members of the class. */
- if (!PRIMARY_TEMPLATE_P (template))
+ if (!PRIMARY_TEMPLATE_P (templ))
for (t = TYPE_METHODS (type); t; t = TREE_CHAIN (t))
if (TREE_CODE (t) == FUNCTION_DECL
/* Implicitly generated member functions will not have template
@@ -8765,13 +8761,6 @@ tsubst_function_type (tree t,
if (arg_types == error_mark_node)
return error_mark_node;
- if (TYPE_QUALS (return_type) != TYPE_UNQUALIFIED
- && in_decl != NULL_TREE
- && !TREE_NO_WARNING (in_decl)
- && (SCALAR_TYPE_P (return_type) || VOID_TYPE_P (return_type)))
- warning (OPT_Wignored_qualifiers,
- "type qualifiers ignored on function return type");
-
/* Construct a new type node and return it. */
if (TREE_CODE (t) == FUNCTION_TYPE)
fntype = build_function_type (return_type, arg_types);
@@ -9750,7 +9739,7 @@ tsubst_qualified_id (tree qualified_id, tree args,
if (complain & tf_error)
qualified_name_lookup_error (scope,
TREE_OPERAND (qualified_id, 1),
- expr);
+ expr, input_location);
return error_mark_node;
}
@@ -9759,7 +9748,7 @@ tsubst_qualified_id (tree qualified_id, tree args,
if (expr == error_mark_node && complain & tf_error)
qualified_name_lookup_error (scope, TREE_OPERAND (qualified_id, 1),
- expr);
+ expr, input_location);
else if (TYPE_P (scope))
{
expr = (adjust_result_of_qualified_name_lookup
@@ -10491,7 +10480,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
/*is_type_p=*/false,
/*complain=*/false);
if (decl == error_mark_node || TREE_CODE (decl) == TREE_LIST)
- qualified_name_lookup_error (scope, name, decl);
+ qualified_name_lookup_error (scope, name, decl, input_location);
else
do_local_using_decl (decl, scope, name);
}
@@ -10938,7 +10927,8 @@ tsubst_copy_and_build (tree t,
/*done=*/true,
/*address_p=*/false,
/*template_arg_p=*/false,
- &error_msg);
+ &error_msg,
+ input_location);
if (error_msg)
error (error_msg);
if (!function_p && TREE_CODE (decl) == IDENTIFIER_NODE)
@@ -10949,26 +10939,26 @@ tsubst_copy_and_build (tree t,
case TEMPLATE_ID_EXPR:
{
tree object;
- tree template = RECUR (TREE_OPERAND (t, 0));
+ tree templ = RECUR (TREE_OPERAND (t, 0));
tree targs = TREE_OPERAND (t, 1);
if (targs)
targs = tsubst_template_args (targs, args, complain, in_decl);
- if (TREE_CODE (template) == COMPONENT_REF)
+ if (TREE_CODE (templ) == COMPONENT_REF)
{
- object = TREE_OPERAND (template, 0);
- template = TREE_OPERAND (template, 1);
+ object = TREE_OPERAND (templ, 0);
+ templ = TREE_OPERAND (templ, 1);
}
else
object = NULL_TREE;
- template = lookup_template_function (template, targs);
+ templ = lookup_template_function (templ, targs);
if (object)
- return build3 (COMPONENT_REF, TREE_TYPE (template),
- object, template, NULL_TREE);
+ return build3 (COMPONENT_REF, TREE_TYPE (templ),
+ object, templ, NULL_TREE);
else
- return baselink_for_fns (template);
+ return baselink_for_fns (templ);
}
case INDIRECT_REF:
@@ -11183,7 +11173,7 @@ tsubst_copy_and_build (tree t,
tree init = RECUR (TREE_OPERAND (t, 3));
if (TREE_OPERAND (t, 3) && !init)
- /* If there was an initializer in the the original tree, but
+ /* If there was an initializer in the original tree, but
it instantiated to an empty list, then we should pass on
VOID_ZERO_NODE to tell build_new that it was an empty
initializer () rather than no initializer. This can only
@@ -11467,7 +11457,8 @@ tsubst_copy_and_build (tree t,
}
else
{
- qualified_name_lookup_error (object_type, tmpl, member);
+ qualified_name_lookup_error (object_type, tmpl, member,
+ input_location);
return error_mark_node;
}
}
@@ -13572,7 +13563,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
/* CV qualifications for methods can never be deduced, they must
match exactly. We need to check them explicitly here,
because type_unification_real treats them as any other
- cvqualified parameter. */
+ cv-qualified parameter. */
if (TREE_CODE (parm) == METHOD_TYPE
&& (!check_cv_quals_for_unify
(UNIFY_ALLOW_NONE,
@@ -14619,8 +14610,9 @@ do_decl_instantiation (tree decl, tree storage)
;
else if (storage == ridpointers[(int) RID_EXTERN])
{
- if (pedantic && !in_system_header && (cxx_dialect == cxx98))
- pedwarn ("ISO C++ 1998 forbids the use of %<extern%> on explicit "
+ if (!in_system_header && (cxx_dialect == cxx98))
+ pedwarn (OPT_pedantic,
+ "ISO C++ 1998 forbids the use of %<extern%> on explicit "
"instantiations");
extern_p = 1;
}
@@ -14706,16 +14698,17 @@ do_type_instantiation (tree t, tree storage, tsubst_flags_t complain)
if (storage != NULL_TREE)
{
- if (pedantic && !in_system_header)
+ if (!in_system_header)
{
if (storage == ridpointers[(int) RID_EXTERN])
{
if (cxx_dialect == cxx98)
- pedwarn("ISO C++ 1998 forbids the use of %<extern%> on "
+ pedwarn(OPT_pedantic,
+ "ISO C++ 1998 forbids the use of %<extern%> on "
"explicit instantiations");
}
else
- pedwarn("ISO C++ forbids the use of %qE on explicit "
+ pedwarn(OPT_pedantic, "ISO C++ forbids the use of %qE on explicit "
"instantiations", storage);
}
@@ -15021,7 +15014,6 @@ instantiate_decl (tree d, int defer_ok,
bool pattern_defined;
int need_push;
location_t saved_loc = input_location;
- int saved_in_system_header = in_system_header;
bool external_p;
/* This function should only be used to instantiate templates for
@@ -15104,7 +15096,6 @@ instantiate_decl (tree d, int defer_ok,
mark_definable (d);
input_location = DECL_SOURCE_LOCATION (d);
- in_system_header = DECL_IN_SYSTEM_HEADER (d);
/* If D is a member of an explicitly instantiated class template,
and no definition is available, treat it like an implicit
@@ -15153,7 +15144,8 @@ instantiate_decl (tree d, int defer_ok,
if (external_p
/* ... but we instantiate inline functions so that we can inline
them and ... */
- && ! (TREE_CODE (d) == FUNCTION_DECL && DECL_INLINE (d))
+ && ! (TREE_CODE (d) == FUNCTION_DECL
+ && possibly_inlined_p (d))
/* ... we instantiate static data members whose values are
needed in integral constant expressions. */
&& ! (TREE_CODE (d) == VAR_DECL
@@ -15230,9 +15222,7 @@ instantiate_decl (tree d, int defer_ok,
/* Instantiate inline functions so that the inliner can do its
job, even though we'll not be emitting a copy of this
function. */
- if (!(TREE_CODE (d) == FUNCTION_DECL
- && flag_inline_trees
- && DECL_DECLARED_INLINE_P (d)))
+ if (!(TREE_CODE (d) == FUNCTION_DECL && possibly_inlined_p (d)))
goto out;
}
@@ -15376,7 +15366,6 @@ instantiate_decl (tree d, int defer_ok,
out:
input_location = saved_loc;
- in_system_header = saved_in_system_header;
pop_deferring_access_checks ();
pop_tinst_level ();
@@ -15394,7 +15383,6 @@ instantiate_pending_templates (int retries)
{
int reconsider;
location_t saved_loc = input_location;
- int saved_in_system_header = in_system_header;
/* Instantiating templates may trigger vtable generation. This in turn
may require further template instantiations. We place a limit here
@@ -15478,7 +15466,6 @@ instantiate_pending_templates (int retries)
while (reconsider);
input_location = saved_loc;
- in_system_header = saved_in_system_header;
}
/* Substitute ARGVEC into T, which is a list of initializers for
diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c
index 8a36f0b77b7..d2e544b0f9e 100644
--- a/gcc/cp/rtti.c
+++ b/gcc/cp/rtti.c
@@ -1408,7 +1408,7 @@ emit_support_tinfos (void)
{
&void_type_node,
&boolean_type_node,
- &wchar_type_node,
+ &wchar_type_node, &char16_type_node, &char32_type_node,
&char_type_node, &signed_char_type_node, &unsigned_char_type_node,
&short_integer_type_node, &short_unsigned_type_node,
&integer_type_node, &unsigned_type_node,
diff --git a/gcc/cp/search.c b/gcc/cp/search.c
index cee29240e9e..7fc040bc8c4 100644
--- a/gcc/cp/search.c
+++ b/gcc/cp/search.c
@@ -1912,6 +1912,20 @@ check_final_overrider (tree overrider, tree basefn)
return 0;
}
+ if (DECL_DELETED_FN (basefn) != DECL_DELETED_FN (overrider))
+ {
+ if (DECL_DELETED_FN (overrider))
+ {
+ error ("deleted function %q+D", overrider);
+ error ("overriding non-deleted function %q+D", basefn);
+ }
+ else
+ {
+ error ("non-deleted function %q+D", overrider);
+ error ("overriding deleted function %q+D", basefn);
+ }
+ return 0;
+ }
return 1;
}
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index fa65e9b2804..5ada42241fb 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -46,6 +46,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-iterator.h"
#include "vec.h"
#include "target.h"
+#include "gimple.h"
/* There routines provide a modular interface to perform many parsing
operations. They may therefore be used during actual parsing, or
@@ -2502,29 +2503,33 @@ finish_base_specifier (tree base, tree access, bool virtual_p)
}
/* Issue a diagnostic that NAME cannot be found in SCOPE. DECL is
- what we found when we tried to do the lookup. */
+ what we found when we tried to do the lookup.
+ LOCATION is the location of the NAME identifier;
+ The location is used in the error message*/
void
-qualified_name_lookup_error (tree scope, tree name, tree decl)
+qualified_name_lookup_error (tree scope, tree name,
+ tree decl, location_t location)
{
if (scope == error_mark_node)
; /* We already complained. */
else if (TYPE_P (scope))
{
if (!COMPLETE_TYPE_P (scope))
- error ("incomplete type %qT used in nested name specifier", scope);
+ error ("%Hincomplete type %qT used in nested name specifier",
+ &location, scope);
else if (TREE_CODE (decl) == TREE_LIST)
{
- error ("reference to %<%T::%D%> is ambiguous", scope, name);
+ error ("%Hreference to %<%T::%D%> is ambiguous", &location, scope, name);
print_candidates (decl);
}
else
- error ("%qD is not a member of %qT", name, scope);
+ error ("%H%qD is not a member of %qT", &location, name, scope);
}
else if (scope != global_namespace)
- error ("%qD is not a member of %qD", name, scope);
+ error ("%H%qD is not a member of %qD", &location, name, scope);
else
- error ("%<::%D%> has not been declared", name);
+ error ("%H%<::%D%> has not been declared", &location, name);
}
/* If FNS is a member function, a set of member functions, or a
@@ -2589,7 +2594,6 @@ baselink_for_fns (tree fns)
the use of "this" explicit.
Upon return, *IDK will be filled in appropriately. */
-
tree
finish_id_expression (tree id_expression,
tree decl,
@@ -2602,7 +2606,8 @@ finish_id_expression (tree id_expression,
bool done,
bool address_p,
bool template_arg_p,
- const char **error_msg)
+ const char **error_msg,
+ location_t location)
{
/* Initialize the output parameters. */
*idk = CP_ID_KIND_NONE;
@@ -2632,7 +2637,7 @@ finish_id_expression (tree id_expression,
/* If the qualifying type is non-dependent (and the name
does not name a conversion operator to a dependent
type), issue an error. */
- qualified_name_lookup_error (scope, id_expression, decl);
+ qualified_name_lookup_error (scope, id_expression, decl, location);
return error_mark_node;
}
else if (!scope)
@@ -3197,6 +3202,8 @@ expand_or_defer_fn (tree fn)
return;
}
+ gcc_assert (gimple_body (fn));
+
/* Replace AGGR_INIT_EXPRs with appropriate CALL_EXPRs. */
cp_walk_tree_without_duplicates (&DECL_SAVED_TREE (fn),
simplify_aggr_init_exprs_r,
@@ -4673,8 +4680,20 @@ classtype_has_nothrow_assign_or_copy_p (tree type, bool assign_p)
return false;
for (; fns; fns = OVL_NEXT (fns))
- if (!TREE_NOTHROW (OVL_CURRENT (fns)))
- return false;
+ {
+ tree fn = OVL_CURRENT (fns);
+
+ if (assign_p)
+ {
+ if (copy_fn_p (fn) == 0)
+ continue;
+ }
+ else if (copy_fn_p (fn) <= 0)
+ continue;
+
+ if (!TYPE_NOTHROW_P (TREE_TYPE (fn)))
+ return false;
+ }
return true;
}
@@ -4708,7 +4727,8 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree type2)
type1 = strip_array_types (type1);
return (trait_expr_value (CPTK_HAS_TRIVIAL_CONSTRUCTOR, type1, type2)
|| (CLASS_TYPE_P (type1)
- && (t = locate_ctor (type1, NULL)) && TREE_NOTHROW (t)));
+ && (t = locate_ctor (type1, NULL))
+ && TYPE_NOTHROW_P (TREE_TYPE (t))));
case CPTK_HAS_TRIVIAL_CONSTRUCTOR:
type1 = strip_array_types (type1);
@@ -4726,7 +4746,7 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree type2)
case CPTK_HAS_TRIVIAL_DESTRUCTOR:
type1 = strip_array_types (type1);
- return (pod_type_p (type1)
+ return (pod_type_p (type1) || type_code1 == REFERENCE_TYPE
|| (CLASS_TYPE_P (type1)
&& TYPE_HAS_TRIVIAL_DESTRUCTOR (type1)));
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index b7c0a8d33b8..0522ae2786f 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -683,7 +683,7 @@ c_build_qualified_type (tree type, int type_quals)
arrays correctly. In particular, if TYPE is an array of T's, and
TYPE_QUALS is non-empty, returns an array of qualified T's.
- FLAGS determines how to deal with illformed qualifications. If
+ FLAGS determines how to deal with ill-formed qualifications. If
tf_ignore_bad_quals is set, then bad qualifications are dropped
(this is permitted if TYPE was introduced via a typedef or template
type parameter). If bad qualifications are dropped and tf_warning
@@ -795,8 +795,8 @@ cp_build_qualified_type_real (tree type,
return make_pack_expansion (t);
}
- /* A reference or method type shall not be cv qualified.
- [dcl.ref], [dct.fct] */
+ /* A reference or method type shall not be cv-qualified.
+ [dcl.ref], [dcl.fct] */
if (type_quals & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE)
&& (TREE_CODE (type) == REFERENCE_TYPE
|| TREE_CODE (type) == METHOD_TYPE))
@@ -2594,17 +2594,17 @@ stabilize_expr (tree exp, tree* initp)
return exp;
}
-/* Add NEW, an expression whose value we don't care about, after the
+/* Add NEW_EXPR, an expression whose value we don't care about, after the
similar expression ORIG. */
tree
-add_stmt_to_compound (tree orig, tree new)
+add_stmt_to_compound (tree orig, tree new_expr)
{
- if (!new || !TREE_SIDE_EFFECTS (new))
+ if (!new_expr || !TREE_SIDE_EFFECTS (new_expr))
return orig;
if (!orig || !TREE_SIDE_EFFECTS (orig))
- return new;
- return build2 (COMPOUND_EXPR, void_type_node, orig, new);
+ return new_expr;
+ return build2 (COMPOUND_EXPR, void_type_node, orig, new_expr);
}
/* Like stabilize_expr, but for a call whose arguments we want to
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 409f34068d4..fcf52dc9db4 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -511,9 +511,10 @@ composite_pointer_type (tree t1, tree t2, tree arg1, tree arg2,
tree attributes;
tree result_type;
- if (pedantic && TYPE_PTRFN_P (t2) && (complain & tf_error))
- pedwarn ("ISO C++ forbids %s between pointer of type %<void *%> "
- "and pointer-to-function", location);
+ if (TYPE_PTRFN_P (t2) && (complain & tf_error))
+ pedwarn (OPT_pedantic, "ISO C++ forbids %s "
+ "between pointer of type %<void *%> and pointer-to-function",
+ location);
result_type
= cp_build_qualified_type (void_type_node,
(cp_type_quals (TREE_TYPE (t1))
@@ -1278,8 +1279,9 @@ cxx_sizeof_or_alignof_type (tree type, enum tree_code op, bool complain)
type = non_reference (type);
if (TREE_CODE (type) == METHOD_TYPE)
{
- if (complain && (pedantic || warn_pointer_arith))
- pedwarn ("invalid application of %qs to a member function",
+ if (complain)
+ pedwarn (pedantic ? OPT_pedantic : OPT_Wpointer_arith,
+ "invalid application of %qs to a member function",
operator_name_info[(int) op].name);
value = size_one_node;
}
@@ -1645,7 +1647,7 @@ decay_conversion (tree exp)
return exp;
}
-/* Perform prepatory conversions, as part of the "usual arithmetic
+/* Perform preparatory conversions, as part of the "usual arithmetic
conversions". In particular, as per [expr]:
Whenever an lvalue expression appears as an operand of an
@@ -1696,18 +1698,6 @@ perform_integral_promotions (tree expr)
return expr;
}
-/* Take the address of an inline function without setting TREE_ADDRESSABLE
- or TREE_USED. */
-
-tree
-inline_conversion (tree exp)
-{
- if (TREE_CODE (exp) == FUNCTION_DECL)
- exp = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (exp)), exp);
-
- return exp;
-}
-
/* Returns nonzero iff exp is a STRING_CST or the result of applying
decay_conversion to one. */
@@ -2315,10 +2305,10 @@ finish_class_member_access_expr (tree object, tree name, bool template_p,
if (is_template_id)
{
- tree template = member;
+ tree templ = member;
- if (BASELINK_P (template))
- template = lookup_template_function (template, template_args);
+ if (BASELINK_P (templ))
+ templ = lookup_template_function (templ, template_args);
else
{
if (complain & tf_error)
@@ -2596,8 +2586,8 @@ build_array_ref (tree array, tree idx)
return error_mark_node;
}
- if (pedantic && !lvalue_p (array))
- pedwarn ("ISO C++ forbids subscripting non-lvalue array");
+ if (!lvalue_p (array))
+ pedwarn (OPT_pedantic, "ISO C++ forbids subscripting non-lvalue array");
/* Note in C++ it is valid to subscript a `register' array, since
it is valid to take the address of something with that
@@ -2822,17 +2812,11 @@ cp_build_function_call (tree function, tree params, tsubst_flags_t complain)
fndecl = function;
/* Convert anything with function type to a pointer-to-function. */
- if (pedantic && DECL_MAIN_P (function) && (complain & tf_error))
- pedwarn ("ISO C++ forbids calling %<::main%> from within program");
-
- /* Differs from default_conversion by not setting TREE_ADDRESSABLE
- (because calling an inline function does not mean the function
- needs to be separately compiled). */
+ if (DECL_MAIN_P (function) && (complain & tf_error))
+ pedwarn (OPT_pedantic,
+ "ISO C++ forbids calling %<::main%> from within program");
- if (DECL_INLINE (function))
- function = inline_conversion (function);
- else
- function = build_addr_func (function);
+ function = build_addr_func (function);
}
else
{
@@ -3299,7 +3283,7 @@ cp_build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
TREE_TYPE (type1)))
return pointer_diff (op0, op1, common_type (type0, type1));
/* In all other cases except pointer - int, the usual arithmetic
- rules aply. */
+ rules apply. */
else if (!(code0 == POINTER_TYPE && code1 == INTEGER_TYPE))
{
common = 1;
@@ -3821,7 +3805,7 @@ cp_build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
For them, this optimization is safe only if
both args are zero-extended or both are sign-extended.
Otherwise, we might change the result.
- Eg, (short)-1 | (unsigned short)-1 is (int)-1
+ E.g., (short)-1 | (unsigned short)-1 is (int)-1
but calculated in (unsigned short) it would be (unsigned short)-1. */
if (shorten && none_complex)
@@ -4101,15 +4085,12 @@ pointer_diff (tree op0, tree op1, tree ptrtype)
if (!complete_type_or_else (target_type, NULL_TREE))
return error_mark_node;
- if (pedantic || warn_pointer_arith)
- {
- if (TREE_CODE (target_type) == VOID_TYPE)
- permerror ("ISO C++ forbids using pointer of type %<void *%> in subtraction");
- if (TREE_CODE (target_type) == FUNCTION_TYPE)
- permerror ("ISO C++ forbids using pointer to a function in subtraction");
- if (TREE_CODE (target_type) == METHOD_TYPE)
- permerror ("ISO C++ forbids using pointer to a method in subtraction");
- }
+ if (TREE_CODE (target_type) == VOID_TYPE)
+ permerror ("ISO C++ forbids using pointer of type %<void *%> in subtraction");
+ if (TREE_CODE (target_type) == FUNCTION_TYPE)
+ permerror ("ISO C++ forbids using pointer to a function in subtraction");
+ if (TREE_CODE (target_type) == METHOD_TYPE)
+ permerror ("ISO C++ forbids using pointer to a method in subtraction");
/* First do the subtraction as integers;
then drop through to build the divide operator. */
@@ -4559,7 +4540,7 @@ cp_build_unary_op (enum tree_code code, tree xarg, int noconvert,
arg = build1 (CONVERT_EXPR, type, arg);
return arg;
}
- else if (pedantic && DECL_MAIN_P (arg))
+ else if (DECL_MAIN_P (arg))
{
/* ARM $3.4 */
if (complain & tf_error)
@@ -4655,7 +4636,7 @@ cp_build_unary_op (enum tree_code code, tree xarg, int noconvert,
/* Even if we're not being pedantic, we cannot allow this
extension when we're instantiating in a SFINAE
context. */
- if (! lvalue_p (arg) && (pedantic || complain == tf_none))
+ if (! lvalue_p (arg) && complain == tf_none)
{
if (complain & tf_error)
permerror ("ISO C++ forbids taking the address of a cast to a non-lvalue expression");
@@ -5443,7 +5424,8 @@ convert_member_func_to_ptr (tree type, tree expr)
|| TREE_CODE (intype) == METHOD_TYPE);
if (pedantic || warn_pmf2ptr)
- pedwarn ("converting from %qT to %qT", intype, type);
+ pedwarn (pedantic ? OPT_pedantic : OPT_Wpmf_conversions,
+ "converting from %qT to %qT", intype, type);
if (TREE_CODE (intype) == METHOD_TYPE)
expr = build_addr_func (expr);
@@ -6980,7 +6962,6 @@ check_return_expr (tree retval, bool *no_warning)
else
permerror ("return-statement with a value, in function "
"returning 'void'");
-
current_function_returns_null = 1;
/* There's really no value to return, after all. */
@@ -7347,7 +7328,8 @@ cp_apply_type_quals_to_decl (int type_quals, tree decl)
if (pedantic)
{
tree bad_type = build_qualified_type (type, type_quals);
- pedwarn ("ignoring %qV qualifiers added to function type %qT",
+ pedwarn (OPT_pedantic,
+ "ignoring %qV qualifiers added to function type %qT",
bad_type, type);
}
diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c
index 4cf8021964f..ee686fecf33 100644
--- a/gcc/cp/typeck2.c
+++ b/gcc/cp/typeck2.c
@@ -345,7 +345,7 @@ cxx_incomplete_type_diagnostic (const_tree value, const_tree type, int diag_type
if (diag_type == 1)
p_msg = warning0;
else if (diag_type == 2)
- p_msg = pedwarn;
+ p_msg = pedwarn0;
else
p_msg = error;
@@ -727,17 +727,26 @@ digest_init_r (tree type, tree init, bool nested)
{
tree char_type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (init)));
- if (char_type != char_type_node
- && TYPE_PRECISION (typ1) == BITS_PER_UNIT)
+ if (TYPE_PRECISION (typ1) == BITS_PER_UNIT)
{
- error ("char-array initialized from wide string");
- return error_mark_node;
+ if (char_type != char_type_node)
+ {
+ error ("char-array initialized from wide string");
+ return error_mark_node;
+ }
}
- if (char_type == char_type_node
- && TYPE_PRECISION (typ1) != BITS_PER_UNIT)
+ else
{
- error ("int-array initialized from non-wide string");
- return error_mark_node;
+ if (char_type == char_type_node)
+ {
+ error ("int-array initialized from non-wide string");
+ return error_mark_node;
+ }
+ else if (char_type != typ1)
+ {
+ error ("int-array initialized from incompatible wide string");
+ return error_mark_node;
+ }
}
TREE_TYPE (init) = type;
diff --git a/gcc/cse.c b/gcc/cse.c
index 86c0f5408da..273e590323b 100644
--- a/gcc/cse.c
+++ b/gcc/cse.c
@@ -913,18 +913,18 @@ make_new_qty (unsigned int reg, enum machine_mode mode)
OLD is not changing; NEW is. */
static void
-make_regs_eqv (unsigned int new, unsigned int old)
+make_regs_eqv (unsigned int new_reg, unsigned int old_reg)
{
unsigned int lastr, firstr;
- int q = REG_QTY (old);
+ int q = REG_QTY (old_reg);
struct qty_table_elem *ent;
ent = &qty_table[q];
/* Nothing should become eqv until it has a "non-invalid" qty number. */
- gcc_assert (REGNO_QTY_VALID_P (old));
+ gcc_assert (REGNO_QTY_VALID_P (old_reg));
- REG_QTY (new) = q;
+ REG_QTY (new_reg) = q;
firstr = ent->first_reg;
lastr = ent->last_reg;
@@ -937,19 +937,19 @@ make_regs_eqv (unsigned int new, unsigned int old)
that not only can they not be allocated by the compiler, but
they cannot be used in substitutions or canonicalizations
either. */
- && (new >= FIRST_PSEUDO_REGISTER || REGNO_REG_CLASS (new) != NO_REGS)
- && ((new < FIRST_PSEUDO_REGISTER && FIXED_REGNO_P (new))
- || (new >= FIRST_PSEUDO_REGISTER
+ && (new_reg >= FIRST_PSEUDO_REGISTER || REGNO_REG_CLASS (new_reg) != NO_REGS)
+ && ((new_reg < FIRST_PSEUDO_REGISTER && FIXED_REGNO_P (new_reg))
+ || (new_reg >= FIRST_PSEUDO_REGISTER
&& (firstr < FIRST_PSEUDO_REGISTER
- || (bitmap_bit_p (cse_ebb_live_out, new)
+ || (bitmap_bit_p (cse_ebb_live_out, new_reg)
&& !bitmap_bit_p (cse_ebb_live_out, firstr))
- || (bitmap_bit_p (cse_ebb_live_in, new)
+ || (bitmap_bit_p (cse_ebb_live_in, new_reg)
&& !bitmap_bit_p (cse_ebb_live_in, firstr))))))
{
- reg_eqv_table[firstr].prev = new;
- reg_eqv_table[new].next = firstr;
- reg_eqv_table[new].prev = -1;
- ent->first_reg = new;
+ reg_eqv_table[firstr].prev = new_reg;
+ reg_eqv_table[new_reg].next = firstr;
+ reg_eqv_table[new_reg].prev = -1;
+ ent->first_reg = new_reg;
}
else
{
@@ -959,15 +959,15 @@ make_regs_eqv (unsigned int new, unsigned int old)
equivalent for anything. */
while (lastr < FIRST_PSEUDO_REGISTER && reg_eqv_table[lastr].prev >= 0
&& (REGNO_REG_CLASS (lastr) == NO_REGS || ! FIXED_REGNO_P (lastr))
- && new >= FIRST_PSEUDO_REGISTER)
+ && new_reg >= FIRST_PSEUDO_REGISTER)
lastr = reg_eqv_table[lastr].prev;
- reg_eqv_table[new].next = reg_eqv_table[lastr].next;
+ reg_eqv_table[new_reg].next = reg_eqv_table[lastr].next;
if (reg_eqv_table[lastr].next >= 0)
- reg_eqv_table[reg_eqv_table[lastr].next].prev = new;
+ reg_eqv_table[reg_eqv_table[lastr].next].prev = new_reg;
else
- qty_table[q].last_reg = new;
- reg_eqv_table[lastr].next = new;
- reg_eqv_table[new].prev = lastr;
+ qty_table[q].last_reg = new_reg;
+ reg_eqv_table[lastr].next = new_reg;
+ reg_eqv_table[new_reg].prev = lastr;
}
}
@@ -1584,7 +1584,7 @@ insert (rtx x, struct table_elt *classp, unsigned int hash, enum machine_mode mo
static void
merge_equiv_classes (struct table_elt *class1, struct table_elt *class2)
{
- struct table_elt *elt, *next, *new;
+ struct table_elt *elt, *next, *new_elt;
/* Ensure we start with the head of the classes. */
class1 = class1->first_same_value;
@@ -1628,8 +1628,8 @@ merge_equiv_classes (struct table_elt *class1, struct table_elt *class2)
rehash_using_reg (exp);
hash = HASH (exp, mode);
}
- new = insert (exp, class1, hash, mode);
- new->in_memory = hash_arg_in_memory;
+ new_elt = insert (exp, class1, hash, mode);
+ new_elt->in_memory = hash_arg_in_memory;
}
}
}
@@ -2648,12 +2648,12 @@ validate_canon_reg (rtx *xloc, rtx insn)
{
if (*xloc)
{
- rtx new = canon_reg (*xloc, insn);
+ rtx new_rtx = canon_reg (*xloc, insn);
/* If replacing pseudo with hard reg or vice versa, ensure the
insn remains valid. Likewise if the insn has MATCH_DUPs. */
- gcc_assert (insn && new);
- validate_change (insn, xloc, new, 1);
+ gcc_assert (insn && new_rtx);
+ validate_change (insn, xloc, new_rtx, 1);
}
}
@@ -2948,7 +2948,7 @@ fold_rtx (rtx x, rtx insn)
enum machine_mode mode;
const char *fmt;
int i;
- rtx new = 0;
+ rtx new_rtx = 0;
int changed = 0;
/* Operands of X. */
@@ -2974,8 +2974,8 @@ fold_rtx (rtx x, rtx insn)
{
case MEM:
case SUBREG:
- if ((new = equiv_constant (x)) != NULL_RTX)
- return new;
+ if ((new_rtx = equiv_constant (x)) != NULL_RTX)
+ return new_rtx;
return x;
case CONST:
@@ -3150,7 +3150,7 @@ fold_rtx (rtx x, rtx insn)
if (const_arg0 != 0 && GET_CODE (const_arg0) == CONST)
is_const = 1, const_arg0 = XEXP (const_arg0, 0);
- new = simplify_unary_operation (code, mode,
+ new_rtx = simplify_unary_operation (code, mode,
const_arg0 ? const_arg0 : folded_arg0,
mode_arg0);
/* NEG of PLUS could be converted into MINUS, but that causes
@@ -3158,12 +3158,12 @@ fold_rtx (rtx x, rtx insn)
(CONST (MINUS (CONST_INT) (SYMBOL_REF)))
which many ports mistakenly treat as LEGITIMATE_CONSTANT_P.
FIXME: those ports should be fixed. */
- if (new != 0 && is_const
- && GET_CODE (new) == PLUS
- && (GET_CODE (XEXP (new, 0)) == SYMBOL_REF
- || GET_CODE (XEXP (new, 0)) == LABEL_REF)
- && GET_CODE (XEXP (new, 1)) == CONST_INT)
- new = gen_rtx_CONST (mode, new);
+ if (new_rtx != 0 && is_const
+ && GET_CODE (new_rtx) == PLUS
+ && (GET_CODE (XEXP (new_rtx, 0)) == SYMBOL_REF
+ || GET_CODE (XEXP (new_rtx, 0)) == LABEL_REF)
+ && GET_CODE (XEXP (new_rtx, 1)) == CONST_INT)
+ new_rtx = gen_rtx_CONST (mode, new_rtx);
}
break;
@@ -3324,7 +3324,7 @@ fold_rtx (rtx x, rtx insn)
{
rtx op0 = const_arg0 ? const_arg0 : folded_arg0;
rtx op1 = const_arg1 ? const_arg1 : folded_arg1;
- new = simplify_relational_operation (code, mode, mode_arg0, op0, op1);
+ new_rtx = simplify_relational_operation (code, mode, mode_arg0, op0, op1);
}
break;
@@ -3560,7 +3560,7 @@ fold_rtx (rtx x, rtx insn)
break;
}
- new = simplify_binary_operation (code, mode,
+ new_rtx = simplify_binary_operation (code, mode,
const_arg0 ? const_arg0 : folded_arg0,
const_arg1 ? const_arg1 : folded_arg1);
break;
@@ -3575,7 +3575,7 @@ fold_rtx (rtx x, rtx insn)
case RTX_TERNARY:
case RTX_BITFIELD_OPS:
- new = simplify_ternary_operation (code, mode, mode_arg0,
+ new_rtx = simplify_ternary_operation (code, mode, mode_arg0,
const_arg0 ? const_arg0 : folded_arg0,
const_arg1 ? const_arg1 : folded_arg1,
const_arg2 ? const_arg2 : XEXP (x, 2));
@@ -3585,7 +3585,7 @@ fold_rtx (rtx x, rtx insn)
break;
}
- return new ? new : x;
+ return new_rtx ? new_rtx : x;
}
/* Return a constant value currently equivalent to X.
@@ -3609,16 +3609,16 @@ equiv_constant (rtx x)
if (GET_CODE (x) == SUBREG)
{
- rtx new;
+ rtx new_rtx;
/* See if we previously assigned a constant value to this SUBREG. */
- if ((new = lookup_as_function (x, CONST_INT)) != 0
- || (new = lookup_as_function (x, CONST_DOUBLE)) != 0
- || (new = lookup_as_function (x, CONST_FIXED)) != 0)
- return new;
+ if ((new_rtx = lookup_as_function (x, CONST_INT)) != 0
+ || (new_rtx = lookup_as_function (x, CONST_DOUBLE)) != 0
+ || (new_rtx = lookup_as_function (x, CONST_FIXED)) != 0)
+ return new_rtx;
if (REG_P (SUBREG_REG (x))
- && (new = equiv_constant (SUBREG_REG (x))) != 0)
+ && (new_rtx = equiv_constant (SUBREG_REG (x))) != 0)
return simplify_subreg (GET_MODE (x), SUBREG_REG (x),
GET_MODE (SUBREG_REG (x)), SUBREG_BYTE (x));
@@ -4161,9 +4161,9 @@ cse_insn (rtx insn)
{
rtx dest = SET_DEST (sets[i].rtl);
rtx src = SET_SRC (sets[i].rtl);
- rtx new = canon_reg (src, insn);
+ rtx new_rtx = canon_reg (src, insn);
- validate_change (insn, &SET_SRC (sets[i].rtl), new, 1);
+ validate_change (insn, &SET_SRC (sets[i].rtl), new_rtx, 1);
if (GET_CODE (dest) == ZERO_EXTRACT)
{
@@ -4811,12 +4811,12 @@ cse_insn (rtx insn)
else if (validate_unshare_change
(insn, &SET_SRC (sets[i].rtl), trial, 0))
{
- rtx new = canon_reg (SET_SRC (sets[i].rtl), insn);
+ rtx new_rtx = canon_reg (SET_SRC (sets[i].rtl), insn);
/* The result of apply_change_group can be ignored; see
canon_reg. */
- validate_change (insn, &SET_SRC (sets[i].rtl), new, 1);
+ validate_change (insn, &SET_SRC (sets[i].rtl), new_rtx, 1);
apply_change_group ();
break;
@@ -5016,10 +5016,10 @@ cse_insn (rtx insn)
and hope for the best. */
if (n_sets == 1)
{
- rtx new, note;
+ rtx new_rtx, note;
- new = emit_jump_insn_before (gen_jump (XEXP (src, 0)), insn);
- JUMP_LABEL (new) = XEXP (src, 0);
+ new_rtx = emit_jump_insn_before (gen_jump (XEXP (src, 0)), insn);
+ JUMP_LABEL (new_rtx) = XEXP (src, 0);
LABEL_NUSES (XEXP (src, 0))++;
/* Make sure to copy over REG_NON_LOCAL_GOTO. */
@@ -5027,11 +5027,11 @@ cse_insn (rtx insn)
if (note)
{
XEXP (note, 1) = NULL_RTX;
- REG_NOTES (new) = note;
+ REG_NOTES (new_rtx) = note;
}
delete_insn_and_edges (insn);
- insn = new;
+ insn = new_rtx;
}
else
INSN_CODE (insn) = -1;
@@ -5674,11 +5674,11 @@ cse_process_notes_1 (rtx x, rtx object, bool *changed)
case ZERO_EXTEND:
case SUBREG:
{
- rtx new = cse_process_notes (XEXP (x, 0), object, changed);
+ rtx new_rtx = cse_process_notes (XEXP (x, 0), object, changed);
/* We don't substitute VOIDmode constants into these rtx,
since they would impede folding. */
- if (GET_MODE (new) != VOIDmode)
- validate_change (object, &XEXP (x, 0), new, 0);
+ if (GET_MODE (new_rtx) != VOIDmode)
+ validate_change (object, &XEXP (x, 0), new_rtx, 0);
return x;
}
@@ -5694,9 +5694,9 @@ cse_process_notes_1 (rtx x, rtx object, bool *changed)
&& (CONSTANT_P (ent->const_rtx)
|| REG_P (ent->const_rtx)))
{
- rtx new = gen_lowpart (GET_MODE (x), ent->const_rtx);
- if (new)
- return copy_rtx (new);
+ rtx new_rtx = gen_lowpart (GET_MODE (x), ent->const_rtx);
+ if (new_rtx)
+ return copy_rtx (new_rtx);
}
}
@@ -5718,10 +5718,10 @@ cse_process_notes_1 (rtx x, rtx object, bool *changed)
static rtx
cse_process_notes (rtx x, rtx object, bool *changed)
{
- rtx new = cse_process_notes_1 (x, object, changed);
- if (new != x)
+ rtx new_rtx = cse_process_notes_1 (x, object, changed);
+ if (new_rtx != x)
*changed = true;
- return new;
+ return new_rtx;
}
diff --git a/gcc/dbgcnt.def b/gcc/dbgcnt.def
index 7a59af30e20..fa7557912d6 100644
--- a/gcc/dbgcnt.def
+++ b/gcc/dbgcnt.def
@@ -166,6 +166,7 @@ DEBUG_COUNTER (jump_bypass)
DEBUG_COUNTER (local_alloc_for_sched)
DEBUG_COUNTER (postreload_cse)
DEBUG_COUNTER (pre_insn)
+DEBUG_COUNTER (treepre_insert)
DEBUG_COUNTER (sched2_func)
DEBUG_COUNTER (sched_block)
DEBUG_COUNTER (sched_func)
@@ -174,4 +175,3 @@ DEBUG_COUNTER (sched_region)
DEBUG_COUNTER (sms_sched_loop)
DEBUG_COUNTER (split_for_sched2)
DEBUG_COUNTER (tail_call)
-
diff --git a/gcc/defaults.h b/gcc/defaults.h
index 3eecd8db81a..80294305850 100644
--- a/gcc/defaults.h
+++ b/gcc/defaults.h
@@ -551,6 +551,12 @@ along with GCC; see the file COPYING3. If not see
#define PUSH_ARGS_REVERSED 0
#endif
+/* Default value for the alignment (in bits) a C conformant malloc has to
+ provide. This default is intended to be safe and always correct. */
+#ifndef MALLOC_ABI_ALIGNMENT
+#define MALLOC_ABI_ALIGNMENT BITS_PER_WORD
+#endif
+
/* If PREFERRED_STACK_BOUNDARY is not defined, set it to STACK_BOUNDARY.
STACK_BOUNDARY is required. */
#ifndef PREFERRED_STACK_BOUNDARY
diff --git a/gcc/df-core.c b/gcc/df-core.c
index 8e6a4e14825..1ea30122254 100644
--- a/gcc/df-core.c
+++ b/gcc/df-core.c
@@ -622,7 +622,7 @@ df_remove_problem (struct dataflow *dflow)
int j;
for (j = i + 1; j < df->num_problems_defined; j++)
df->problems_in_order[j-1] = df->problems_in_order[j];
- df->problems_in_order[j] = NULL;
+ df->problems_in_order[j-1] = NULL;
df->num_problems_defined--;
break;
}
diff --git a/gcc/df-problems.c b/gcc/df-problems.c
index 0c46bdaa496..abb34d0596a 100644
--- a/gcc/df-problems.c
+++ b/gcc/df-problems.c
@@ -3170,24 +3170,24 @@ df_kill_notes (rtx insn, rtx *old_dead_notes, rtx *old_unused_notes)
static inline rtx
df_set_note (enum reg_note note_type, rtx insn, rtx old, rtx reg)
{
- rtx this = old;
+ rtx curr = old;
rtx prev = NULL;
- while (this)
- if (XEXP (this, 0) == reg)
+ while (curr)
+ if (XEXP (curr, 0) == reg)
{
if (prev)
- XEXP (prev, 1) = XEXP (this, 1);
+ XEXP (prev, 1) = XEXP (curr, 1);
else
- old = XEXP (this, 1);
- XEXP (this, 1) = REG_NOTES (insn);
- REG_NOTES (insn) = this;
+ old = XEXP (curr, 1);
+ XEXP (curr, 1) = REG_NOTES (insn);
+ REG_NOTES (insn) = curr;
return old;
}
else
{
- prev = this;
- this = XEXP (this, 1);
+ prev = curr;
+ curr = XEXP (curr, 1);
}
/* Did not find the note. */
diff --git a/gcc/df-scan.c b/gcc/df-scan.c
index 5818717651d..0ce48b5d1e0 100644
--- a/gcc/df-scan.c
+++ b/gcc/df-scan.c
@@ -1887,10 +1887,10 @@ df_insn_change_bb (rtx insn, basic_block new_bb)
/* Helper function for df_ref_change_reg_with_loc. */
static void
-df_ref_change_reg_with_loc_1 (struct df_reg_info *old, struct df_reg_info *new,
+df_ref_change_reg_with_loc_1 (struct df_reg_info *old_df, struct df_reg_info *new_df,
int new_regno, rtx loc)
{
- struct df_ref *the_ref = old->reg_chain;
+ struct df_ref *the_ref = old_df->reg_chain;
while (the_ref)
{
@@ -1908,18 +1908,18 @@ df_ref_change_reg_with_loc_1 (struct df_reg_info *old, struct df_reg_info *new,
if (prev_ref)
prev_ref->next_reg = next_ref;
else
- old->reg_chain = next_ref;
+ old_df->reg_chain = next_ref;
if (next_ref)
next_ref->prev_reg = prev_ref;
- old->n_refs--;
+ old_df->n_refs--;
/* Put the ref into the new regno chain. */
the_ref->prev_reg = NULL;
- the_ref->next_reg = new->reg_chain;
- if (new->reg_chain)
- new->reg_chain->prev_reg = the_ref;
- new->reg_chain = the_ref;
- new->n_refs++;
+ the_ref->next_reg = new_df->reg_chain;
+ if (new_df->reg_chain)
+ new_df->reg_chain->prev_reg = the_ref;
+ new_df->reg_chain = the_ref;
+ new_df->n_refs++;
df_set_bb_dirty (DF_REF_BB (the_ref));
/* Need to resort the record that the ref was in because the
diff --git a/gcc/diagnostic.c b/gcc/diagnostic.c
index 5a6aaee914d..49b3f9a058f 100644
--- a/gcc/diagnostic.c
+++ b/gcc/diagnostic.c
@@ -299,13 +299,14 @@ void
diagnostic_report_diagnostic (diagnostic_context *context,
diagnostic_info *diagnostic)
{
+ location_t location = diagnostic->location;
bool maybe_print_warnings_as_errors_message = false;
const char *saved_format_spec;
/* Give preference to being able to inhibit warnings, before they
get reclassified to something else. */
if (diagnostic->kind == DK_WARNING
- && !diagnostic_report_warnings_p ())
+ && !diagnostic_report_warnings_p (location))
return;
if (context->lock > 0)
@@ -470,8 +471,8 @@ inform (const char *gmsgid, ...)
va_end (ap);
}
-/* A warning. Use this for code which is correct according to the
- relevant language specification but is likely to be buggy anyway. */
+/* A warning at INPUT_LOCATION. Use this for code which is correct according
+ to the relevant language specification but is likely to be buggy anyway. */
void
warning (int opt, const char *gmsgid, ...)
{
@@ -498,6 +499,22 @@ warning0 (const char *gmsgid, ...)
va_end (ap);
}
+/* A warning at LOCATION. Use this for code which is correct according to the
+ relevant language specification but is likely to be buggy anyway. */
+void
+warning_at (location_t location, int opt, const char *gmsgid, ...)
+{
+ diagnostic_info diagnostic;
+ va_list ap;
+
+ va_start (ap, gmsgid);
+ diagnostic_set_info (&diagnostic, gmsgid, &ap, location, DK_WARNING);
+ diagnostic.option_index = opt;
+
+ report_diagnostic (&diagnostic);
+ va_end (ap);
+}
+
/* A "pedantic" warning: issues a warning unless -pedantic-errors was
given on the command line, in which case it issues an error. Use
this for diagnostics required by the relevant language standard,
@@ -505,16 +522,34 @@ warning0 (const char *gmsgid, ...)
Note that these diagnostics are issued independent of the setting
of the -pedantic command-line switch. To get a warning enabled
- only with that switch, write "if (pedantic) pedwarn (...);" */
+ only with that switch, use either "if (pedantic) pedwarn
+ (OPT_pedantic,...)" or just "pedwarn (OPT_pedantic,..)". To get a
+ pedwarn independently of the -pedantic switch use "pedwarn (0,...)". */
+
+void
+pedwarn (int opt, const char *gmsgid, ...)
+{
+ diagnostic_info diagnostic;
+ va_list ap;
+
+ va_start (ap, gmsgid);
+ diagnostic_set_info (&diagnostic, gmsgid, &ap, input_location,
+ pedantic_warning_kind ());
+ diagnostic.option_index = opt;
+
+ report_diagnostic (&diagnostic);
+ va_end (ap);
+}
+
void
-pedwarn (const char *gmsgid, ...)
+pedwarn0 (const char *gmsgid, ...)
{
diagnostic_info diagnostic;
va_list ap;
va_start (ap, gmsgid);
diagnostic_set_info (&diagnostic, gmsgid, &ap, input_location,
- pedantic_warning_kind ());
+ pedantic_warning_kind ());
report_diagnostic (&diagnostic);
va_end (ap);
}
diff --git a/gcc/diagnostic.h b/gcc/diagnostic.h
index a249574d4aa..8906cc48ca0 100644
--- a/gcc/diagnostic.h
+++ b/gcc/diagnostic.h
@@ -183,9 +183,9 @@ extern diagnostic_context *global_dc;
#define sorrycount diagnostic_kind_count (global_dc, DK_SORRY)
/* Returns nonzero if warnings should be emitted. */
-#define diagnostic_report_warnings_p() \
+#define diagnostic_report_warnings_p(LOC) \
(!inhibit_warnings \
- && !(in_system_header && !warn_system_headers))
+ && !(in_system_header_at (LOC) && !warn_system_headers))
#define report_diagnostic(D) diagnostic_report_diagnostic (global_dc, D)
@@ -215,14 +215,24 @@ extern char *diagnostic_build_prefix (diagnostic_info *);
extern char *file_name_as_prefix (const char *);
/* In tree-pretty-print.c */
+extern void print_declaration (pretty_printer *, tree, int, int);
extern int dump_generic_node (pretty_printer *, tree, int, int, bool);
extern void print_generic_stmt (FILE *, tree, int);
extern void print_generic_stmt_indented (FILE *, tree, int, int);
extern void print_generic_expr (FILE *, tree, int);
extern void print_generic_decl (FILE *, tree, int);
+extern void debug_c_tree (tree);
+extern void dump_omp_clauses (pretty_printer *, tree, int, int);
+/* In gimple-pretty-print.c */
extern void debug_generic_expr (tree);
extern void debug_generic_stmt (tree);
extern void debug_tree_chain (tree);
-extern void debug_c_tree (tree);
+extern void debug_gimple_stmt (gimple);
+extern void debug_gimple_seq (gimple_seq);
+extern void print_gimple_seq (FILE *, gimple_seq, int, int);
+extern void print_gimple_stmt (FILE *, gimple, int, int);
+extern void print_gimple_expr (FILE *, gimple, int, int);
+extern void dump_gimple_stmt (pretty_printer *, gimple, int, int);
+
#endif /* ! GCC_DIAGNOSTIC_H */
diff --git a/gcc/doc/c-tree.texi b/gcc/doc/c-tree.texi
index 1f019763d09..6eef7d12ef3 100644
--- a/gcc/doc/c-tree.texi
+++ b/gcc/doc/c-tree.texi
@@ -1330,6 +1330,8 @@ a containing function, and the back end must take appropriate action.
@findex DECL_GLOBAL_CTOR_P
@findex DECL_GLOBAL_DTOR_P
@findex GLOBAL_INIT_PRIORITY
+@findex DECL_FUNCTION_SPECIFIC_TARGET
+@findex DECL_FUNCTION_SPECIFIC_OPTIMIZATION
The following macros and functions can be used on a @code{FUNCTION_DECL}:
@ftable @code
@@ -1514,6 +1516,17 @@ is of the form `@code{()}'.
This predicate holds if the function an overloaded
@code{operator delete[]}.
+@item DECL_FUNCTION_SPECIFIC_TARGET
+This macro returns a tree node that holds the target options that are
+to be used to compile this particular function or @code{NULL_TREE} if
+the function is to be compiled with the target options specified on
+the command line.
+
+@item DECL_FUNCTION_SPECIFIC_OPTIMIZATION
+This macro returns a tree node that holds the optimization options
+that are to be used to compile this particular function or
+@code{NULL_TREE} if the function is to be compiled with the
+optimization options specified on the command line.
@end ftable
@c ---------------------------------------------------------------------
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 56e89265b49..4c82dc60f2c 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -1792,6 +1792,8 @@ the enclosing block.
@cindex functions that are passed arguments in registers on the 386
@cindex functions that pop the argument stack on the 386
@cindex functions that do not pop the argument stack on the 386
+@cindex functions that have different compilation options on the 386
+@cindex functions that have different optimization options
In GNU C, you declare certain things about functions called in your program
which help the compiler optimize function calls and check your code more
@@ -1945,8 +1947,7 @@ body.
Generally, inlining into a function is limited. For a function marked with
this attribute, every call inside this function will be inlined, if possible.
Whether the function itself is considered for inlining depends on its size and
-the current inlining parameters. The @code{flatten} attribute only works
-reliably in unit-at-a-time mode.
+the current inlining parameters.
@item error ("@var{message}")
@cindex @code{error} function attribute
@@ -2663,6 +2664,207 @@ with the notable exceptions of @code{qsort} and @code{bsearch} that
take function pointer arguments. The @code{nothrow} attribute is not
implemented in GCC versions earlier than 3.3.
+@item option
+@cindex @code{option} function attribute
+The @code{option} attribute is used to specify that a function is to
+be compiled with different target options than specified on the
+command line. This can be used for instance to have functions
+compiled with a different ISA (instruction set architecture) than the
+default. You can also use the @samp{#pragma GCC option} pragma to set
+more than one function to be compiled with specific target options.
+@xref{Function Specific Option Pragmas}, for details about the
+@samp{#pragma GCC option} pragma.
+
+For instance on a 386, you could compile one function with
+@code{option("sse4.1,arch=core2")} and another with
+@code{option("sse4a,arch=amdfam10")} that would be equivalent to
+compiling the first function with @option{-msse4.1} and
+@option{-march=core2} options, and the second function with
+@option{-msse4a} and @option{-march=amdfam10} options. It is up to the
+user to make sure that a function is only invoked on a machine that
+supports the particular ISA it was compiled for (for example by using
+@code{cpuid} on 386 to determine what feature bits and architecture
+family are used).
+
+@smallexample
+int core2_func (void) __attribute__ ((__option__ ("arch=core2")));
+int sse3_func (void) __attribute__ ((__option__ ("sse3")));
+@end smallexample
+
+On the 386, the following options are allowed:
+
+@table @samp
+@item abm
+@itemx no-abm
+@cindex option("abm")
+Enable/disable the generation of the advanced bit instructions.
+
+@item aes
+@itemx no-aes
+@cindex @code{option("aes")} attribute
+Enable/disable the generation of the AES instructions.
+
+@item mmx
+@itemx no-mmx
+@cindex @code{option("mmx")} attribute
+Enable/disable the generation of the MMX instructions.
+
+@item pclmul
+@itemx no-pclmul
+@cindex @code{option("pclmul")} attribute
+Enable/disable the generation of the PCLMUL instructions.
+
+@item popcnt
+@itemx no-popcnt
+@cindex @code{option("popcnt")} attribute
+Enable/disable the generation of the POPCNT instruction.
+
+@item sse
+@itemx no-sse
+@cindex @code{option("sse")} attribute
+Enable/disable the generation of the SSE instructions.
+
+@item sse2
+@itemx no-sse2
+@cindex @code{option("sse2")} attribute
+Enable/disable the generation of the SSE2 instructions.
+
+@item sse3
+@itemx no-sse3
+@cindex @code{option("sse3")} attribute
+Enable/disable the generation of the SSE3 instructions.
+
+@item sse4
+@itemx no-sse4
+@cindex @code{option("sse4")} attribute
+Enable/disable the generation of the SSE4 instructions (both SSE4.1
+and SSE4.2).
+
+@item sse4.1
+@itemx no-sse4.1
+@cindex @code{option("sse4.1")} attribute
+Enable/disable the generation of the sse4.1 instructions.
+
+@item sse4.2
+@itemx no-sse4.2
+@cindex @code{option("sse4.2")} attribute
+Enable/disable the generation of the sse4.2 instructions.
+
+@item sse4a
+@itemx no-sse4a
+@cindex @code{option("sse4a")} attribute
+Enable/disable the generation of the SSE4A instructions.
+
+@item sse5
+@itemx no-sse5
+@cindex @code{option("sse5")} attribute
+Enable/disable the generation of the SSE5 instructions.
+
+@item ssse3
+@itemx no-ssse3
+@cindex @code{option("ssse3")} attribute
+Enable/disable the generation of the SSSE3 instructions.
+
+@item cld
+@itemx no-cld
+@cindex @code{option("cld")} attribute
+Enable/disable the generation of the CLD before string moves.
+
+@item fancy-math-387
+@itemx no-fancy-math-387
+@cindex @code{option("fancy-math-387")} attribute
+Enable/disable the generation of the @code{sin}, @code{cos}, and
+@code{sqrt} instructions on the 387 floating point unit.
+
+@item fused-madd
+@itemx no-fused-madd
+@cindex @code{option("fused-madd")} attribute
+Enable/disable the generation of the fused multiply/add instructions.
+
+@item ieee-fp
+@itemx no-ieee-fp
+@cindex @code{option("ieee-fp")} attribute
+Enable/disable the generation of floating point that depends on IEEE arithmetic.
+
+@item inline-all-stringops
+@itemx no-inline-all-stringops
+@cindex @code{option("inline-all-stringops")} attribute
+Enable/disable inlining of string operations.
+
+@item inline-stringops-dynamically
+@itemx no-inline-stringops-dynamically
+@cindex @code{option("inline-stringops-dynamically")} attribute
+Enable/disable the generation of the inline code to do small string
+operations and calling the library routines for large operations.
+
+@item align-stringops
+@itemx no-align-stringops
+@cindex @code{option("align-stringops")} attribute
+Do/do not align destination of inlined string operations.
+
+@item recip
+@itemx no-recip
+@cindex @code{option("recip")} attribute
+Enable/disable the generation of RCPSS, RCPPS, RSQRTSS and RSQRTPS
+instructions followed an additional Newton-Rhapson step instead of
+doing a floating point division.
+
+@item arch=@var{ARCH}
+@cindex @code{option("arch=@var{ARCH}")} attribute
+Specify the architecture to generate code for in compiling the function.
+
+@item tune=@var{TUNE}
+@cindex @code{option("tune=@var{TUNE}")} attribute
+Specify the architecture to tune for in compiling the function.
+
+@item fpmath=@var{FPMATH}
+@cindex @code{option("fpmath=@var{FPMATH}")} attribute
+Specify which floating point unit to use. The
+@code{option("fpmath=sse,387")} option must be specified as
+@code{option("fpmath=sse+387")} because the comma would separate
+different options.
+@end table
+
+On the 386, you can use either multiple strings to specify multiple
+options, or you can separate the option with a comma (@code{,}).
+
+On the 386, the inliner will not inline a function that has different
+target options than the caller, unless the callee has a subset of the
+target options of the caller. For example a function declared with
+@code{option("sse5")} can inline a function with
+@code{option("sse2")}, since @code{-msse5} implies @code{-msse2}.
+
+The @code{option} attribute is not implemented in GCC versions earlier
+than 4.4, and at present only the 386 uses it.
+
+@item optimize
+@cindex @code{optimize} function attribute
+The @code{optimize} attribute is used to specify that a function is to
+be compiled with different optimization options than specified on the
+command line. Arguments can either be numbers or strings. Numbers
+are assumed to be an optimization level. Strings that begin with
+@code{O} are assumed to be an optimization option, while other options
+are assumed to be used with a @code{-f} prefix. You can also use the
+@samp{#pragma GCC optimize} pragma to set the optimization options
+that affect more than one function.
+@xref{Function Specific Option Pragmas}, for details about the
+@samp{#pragma GCC option} pragma.
+
+This can be used for instance to have frequently executed functions
+compiled with more aggressive optimization options that produce faster
+and larger code, while other functions can be called with less
+aggressive options. On some targets, the @code{hot} attribute implies
+@code{optimize("O3")}, and @code{cold} attribute implies
+@code{optimize("Os")}.
+
+@smallexample
+int fast_func (void) __attribute__ ((__optimize__ ("O3,unroll-loops")));
+int slow_func (void) __attribute__ ((__optimize__ ("Os")));
+@end smallexample
+
+The inliner will not inline functions with a higher optimization level
+than the caller or different space/time trade offs.
+
@item pure
@cindex @code{pure} function attribute
Many functions have no effects except the return value and their
@@ -2698,7 +2900,12 @@ all hot functions appears close together improving locality.
When profile feedback is available, via @option{-fprofile-use}, hot functions
are automatically detected and this attribute is ignored.
-The @code{hot} attribute is not implemented in GCC versions earlier than 4.3.
+The @code{hot} attribute is not implemented in GCC versions earlier
+than 4.3.
+
+Starting with GCC 4.4, the @code{cold} attribute sets
+@code{optimize("O3")} to turn on more aggressive optimization on the
+the i386, x86_64, and IA-64 targets.
@item cold
@cindex @code{cold} function attribute
@@ -2715,7 +2922,11 @@ occasions.
When profile feedback is available, via @option{-fprofile-use}, hot functions
are automatically detected and this attribute is ignored.
-The @code{hot} attribute is not implemented in GCC versions earlier than 4.3.
+The @code{cold} attribute is not implemented in GCC versions earlier than 4.3.
+
+Starting with GCC 4.4, the @code{cold} attribute sets
+@code{optimize("Os")} to save space on the the i386, x86_64, and IA-64
+targets.
@item regparm (@var{number})
@cindex @code{regparm} attribute
@@ -4240,10 +4451,16 @@ The @code{deprecated} attribute can also be used for functions and
variables (@pxref{Function Attributes}, @pxref{Variable Attributes}.)
@item may_alias
-Accesses to objects with types with this attribute are not subjected to
-type-based alias analysis, but are instead assumed to be able to alias
-any other type of objects, just like the @code{char} type. See
-@option{-fstrict-aliasing} for more information on aliasing issues.
+Accesses through pointers to types with this attribute are not subject
+to type-based alias analysis, but are instead assumed to be able to alias
+any other type of objects. In the context of 6.5/7 an lvalue expression
+dereferencing such a pointer is treated like having a character type.
+See @option{-fstrict-aliasing} for more information on aliasing issues.
+This extension exists to support some vector APIs, in which pointers to
+one vector type are permitted to alias pointers to a different vector type.
+
+Note that an object of a type with this attribute does not have any
+special semantics.
Example of use:
@@ -9120,9 +9337,10 @@ always specify the signedness.
@item
Compiling with @option{-maltivec} adds keywords @code{__vector},
-@code{__pixel}, and @code{__bool}. Macros @option{vector},
-@code{pixel}, and @code{bool} are defined in @code{<altivec.h>} and can
-be undefined.
+@code{vector}, @code{__pixel}, @code{pixel}, @code{__bool} and
+@code{bool}. When compiling ISO C, the context-sensitive substitution
+of the keywords @code{vector}, @code{pixel} and @code{bool} is
+disabled. To use them, you must include @code{<altivec.h>} instead.
@item
GCC allows using a @code{typedef} name as the type specifier for a
@@ -11102,6 +11320,7 @@ for further explanation.
* Diagnostic Pragmas::
* Visibility Pragmas::
* Push/Pop Macro Pragmas::
+* Function Specific Option Pragmas::
@end menu
@node ARM Pragmas
@@ -11397,6 +11616,35 @@ strict control over project policies.
@end table
+GCC also offers a simple mechanism for printing messages during
+compilation.
+
+@table @code
+@item #pragma message @var{string}
+@cindex pragma, diagnostic
+
+Prints @var{string} as a compiler message on compilation. The message
+is informational only, and is neither a compilation warning nor an error.
+
+@smallexample
+#pragma message "Compiling " __FILE__ "..."
+@end smallexample
+
+@var{string} may be parenthesized, and is printed with location
+information. For example,
+
+@smallexample
+#define DO_PRAGMA(x) _Pragma (#x)
+#define TODO(x) DO_PRAGMA(message ("TODO - " #x))
+
+TODO(Remember to fix this)
+@end smallexample
+
+prints @samp{/tmp/file.c:4: note: #pragma message:
+TODO - Remember to fix this}.
+
+@end table
+
@node Visibility Pragmas
@subsection Visibility Pragmas
@@ -11452,6 +11700,80 @@ int x [X];
In this example, the definition of X as 1 is saved by @code{#pragma
push_macro} and restored by @code{#pragma pop_macro}.
+@node Function Specific Option Pragmas
+@subsection Function Specific Option Pragmas
+
+@table @code
+@item #pragma GCC option (@var{"string"}...)
+@cindex pragma GCC option
+
+This pragma allows you to set target specific options for functions
+defined later in the source file. One or more strings can be
+specified. Each function that is defined after this point will be as
+if @code{attribute((option("STRING")))} was specified for that
+function. The parenthesis around the options is optional.
+@xref{Function Attributes}, for more information about the
+@code{option} attribute and the attribute syntax.
+
+The @samp{#pragma GCC option} pragma is not implemented in GCC
+versions earlier than 4.4, and is currently only implemented for the
+386 and x86_64 backend.
+@end table
+
+@table @code
+@item #pragma GCC option (push)
+@itemx #pragma GCC option (pop)
+@cindex pragma GCC option
+
+These pragmas maintain a stack of the current options. It is
+intended for include files where you temporarily want to switch to
+using a different @samp{#pragma GCC option} and then to pop back to
+the previous options.
+@end table
+
+@table @code
+@item #pragma GCC option (reset)
+@cindex pragma, target option
+@cindex pragma GCC option
+
+This pragma clears the current @code{#pragma GCC options} to use the
+default switches as specified on the command line.
+@end table
+@table @code
+@item #pragma GCC optimize (@var{"string"}...)
+@cindex pragma GCC optimize
+
+This pragma allows you to set global optimization options for functions
+defined later in the source file. One or more strings can be
+specified. Each function that is defined after this point will be as
+if @code{attribute((optimize("STRING")))} was specified for that
+function. The parenthesis around the options is optional.
+@xref{Function Attributes}, for more information about the
+@code{optimize} attribute and the attribute syntax.
+
+The @samp{#pragma GCC optimize} pragma is not implemented in GCC
+versions earlier than 4.4.
+@end table
+
+@table @code
+@item #pragma GCC optimize (push)
+@itemx #pragma GCC optimize (pop)
+@cindex pragma GCC optimize
+
+These pragmas maintain a stack of the current optimization options.
+It is intended for include files where you temporarily want to switch
+to using a different @code{#pragma GCC optimize} and then to pop back
+to the previous optimizations.
+@end table
+
+@table @code
+@item #pragma GCC optimize reset
+@cindex pragma GCC optimize
+
+This pragma clears the current @code{#pragma GCC optimize} to use the
+default switches as specified on the command line.
+@end table
+
@node Unnamed Fields
@section Unnamed struct/union fields within structs/unions
@cindex struct
diff --git a/gcc/doc/install.texi b/gcc/doc/install.texi
index 86c2f46a49e..453709970e7 100644
--- a/gcc/doc/install.texi
+++ b/gcc/doc/install.texi
@@ -386,7 +386,7 @@ Necessary to build GCC during development because the generated output
files are not included in the SVN repository. They are included in
releases.
-@item Texinfo version 4.4 (or later)
+@item Texinfo version 4.7 (or later)
Necessary for running @command{makeinfo} when modifying @file{*.texi}
files to test your changes.
@@ -1765,7 +1765,7 @@ build machinery, not of GCC itself) that is used even if you only
build the C front end.
When building from SVN or snapshots, or if you modify Texinfo
-documentation, you need version 4.4 or later of Texinfo installed if you
+documentation, you need version 4.7 or later of Texinfo installed if you
want Info documentation to be regenerated. Releases contain Info
documentation pre-built for the unmodified documentation in the release.
@@ -2362,7 +2362,7 @@ If you find a bug, please report it following the
@uref{../bugs.html,,bug reporting guidelines}.
If you want to print the GCC manuals, do @samp{cd @var{objdir}; make
-dvi}. You will need to have @command{texi2dvi} (version at least 4.4)
+dvi}. You will need to have @command{texi2dvi} (version at least 4.7)
and @TeX{} installed. This creates a number of @file{.dvi} files in
subdirectories of @file{@var{objdir}}; these may be converted for
printing with programs such as @command{dvips}. Alternately, by using
@@ -3427,15 +3427,17 @@ applications. There are no standard Unix configurations.
@end html
@heading @anchor{m68k-x-x}m68k-*-*
By default, @samp{m68k-*-aout}, @samp{m68k-*-coff*},
-@samp{m68k-*-elf*}, @samp{m68k-*-rtems} and @samp{m68k-*-uclinux}
+@samp{m68k-*-elf*}, @samp{m68k-*-rtems}, @samp{m68k-*-uclinux} and
+@samp{m68k-*-linux}
build libraries for both M680x0 and ColdFire processors. If you only
need the M680x0 libraries, you can omit the ColdFire ones by passing
@option{--with-arch=m68k} to @command{configure}. Alternatively, you
can omit the M680x0 libraries by passing @option{--with-arch=cf} to
-@command{configure}. These targets default to 5206 code when
+@command{configure}. These targets default to 5206 or 5475 code as
+appropriate for the target system when
configured with @option{--with-arch=cf} and 68020 code otherwise.
-The @samp{m68k-*-linux-gnu}, @samp{m68k-*-netbsd} and
+The @samp{m68k-*-netbsd} and
@samp{m68k-*-openbsd} targets also support the @option{--with-arch}
option. They will generate ColdFire CFV4e code when configured with
@option{--with-arch=cf} and 68020 code otherwise.
@@ -3673,9 +3675,7 @@ or newer for a working GCC@.
<hr />
@end html
@heading @anchor{powerpc-x-netbsd}powerpc-*-netbsd*
-PowerPC system in big endian mode running NetBSD@. To build the
-documentation you will need Texinfo version 4.4 (NetBSD 1.5.1 included
-Texinfo version 3.12).
+PowerPC system in big endian mode running NetBSD@.
@html
<hr />
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 6587ccd11b3..df598b0efb6 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -231,8 +231,9 @@ Objective-C and Objective-C++ Dialects}.
-Wno-attributes -Wc++-compat -Wc++0x-compat -Wcast-align -Wcast-qual @gol
-Wchar-subscripts -Wclobbered -Wcomment @gol
-Wconversion -Wcoverage-mismatch -Wno-deprecated @gol
--Wno-deprecated-declarations -Wdisabled-optimization -Wno-div-by-zero @gol
--Wempty-body -Wenum-compare -Wno-endif-labels @gol
+-Wno-deprecated-declarations -Wdisabled-optimization @gol
+-Wdisallowed-function-list=@var{sym},@var{sym},@dots{} @gol
+-Wno-div-by-zero -Wempty-body -Wenum-compare -Wno-endif-labels @gol
-Werror -Werror=* @gol
-Wfatal-errors -Wfloat-equal -Wformat -Wformat=2 @gol
-Wno-format-contains-nul -Wno-format-extra-args -Wformat-nonliteral @gol
@@ -311,7 +312,7 @@ Objective-C and Objective-C++ Dialects}.
-p -pg -print-file-name=@var{library} -print-libgcc-file-name @gol
-print-multi-directory -print-multi-lib @gol
-print-prog-name=@var{program} -print-search-dirs -Q @gol
--print-sysroot-headers-suffix @gol
+-print-sysroot -print-sysroot-headers-suffix @gol
-save-temps -time}
@item Optimization Options
@@ -328,8 +329,8 @@ Objective-C and Objective-C++ Dialects}.
-fearly-inlining -fexpensive-optimizations -ffast-math @gol
-ffinite-math-only -ffloat-store -fforward-propagate @gol
-ffunction-sections -fgcse -fgcse-after-reload -fgcse-las -fgcse-lm @gol
--fgcse-sm -fif-conversion -fif-conversion2 -finline-functions @gol
--finline-functions-called-once -finline-limit=@var{n} @gol
+-fgcse-sm -fif-conversion -fif-conversion2 -findirect-inlining @gol
+-finline-functions -finline-functions-called-once -finline-limit=@var{n} @gol
-finline-small-functions -fipa-cp -fipa-marix-reorg -fipa-pta @gol
-fipa-pure-const -fipa-reference -fipa-struct-reorg @gol
-fipa-type-escape -fira -fira-algorithm=@var{algorithm} @gol
@@ -564,6 +565,7 @@ Objective-C and Objective-C++ Dialects}.
-maes -mpclmul @gol
-msse4a -m3dnow -mpopcnt -mabm -msse5 @gol
-mthreads -mno-align-stringops -minline-all-stringops @gol
+-minline-stringops-dynamically -mstringop-strategy=@var{alg} @gol
-mpush-args -maccumulate-outgoing-args -m128bit-long-double @gol
-m96bit-long-double -mregparm=@var{num} -msseregparm @gol
-mveclibabi=@var{type} -mpc32 -mpc64 -mpc80 -mstackrealign @gol
@@ -4105,6 +4107,13 @@ minimum maximum, so we do not diagnose overlength strings in C++@.
This option is implied by @option{-pedantic}, and can be disabled with
@option{-Wno-overlength-strings}.
+
+@item -Wdisallowed-function-list=@var{sym},@var{sym},@dots{}
+@opindex Wdisallowed-function-list
+
+If any of @var{sym} is called, GCC will issue a warning. This can be useful
+in enforcing coding conventions that ban calls to certain functions, for
+example, @code{alloca}, @code{malloc}, etc.
@end table
@node Debugging Options
@@ -5069,6 +5078,14 @@ variable @env{GCC_EXEC_PREFIX} to the directory where you installed them.
Don't forget the trailing @samp{/}.
@xref{Environment Variables}.
+@item -print-sysroot
+@opindex print-sysroot
+Print the target sysroot directory that will be used during
+compilation. This is the target sysroot specified either at configure
+time or or using the @option{--sysroot} option, possibly with an extra
+suffix that depends on compilation options. If no target sysroot is
+specified, the option prints nothing.
+
@item -print-sysroot-headers-suffix
@opindex print-sysroot-headers-suffix
Print the suffix added to the target sysroot when searching for
@@ -5122,14 +5139,10 @@ Turning on optimization flags makes the compiler attempt to improve
the performance and/or code size at the expense of compilation time
and possibly the ability to debug the program.
-The compiler performs optimization based on the knowledge it has of
-the program. Optimization levels @option{-O} and above, in
-particular, enable @emph{unit-at-a-time} mode, which allows the
-compiler to consider information gained from later functions in
-the file when compiling a function. Compiling multiple files at
-once to a single output file in @emph{unit-at-a-time} mode allows
-the compiler to use information gained from all of the files when
-compiling each of them.
+The compiler performs optimization based on the knowledge it has of the
+program. Compiling multiple files at once to a single output file mode allows
+the compiler to use information gained from all of the files when compiling
+each of them.
Not all optimizations are controlled directly by a flag. Only
optimizations that have a flag are listed.
@@ -5196,6 +5209,7 @@ also turns on the following optimization flags:
-fdelete-null-pointer-checks @gol
-fexpensive-optimizations @gol
-fgcse -fgcse-lm @gol
+-findirect-inlining @gol
-foptimize-sibling-calls @gol
-fpeephole2 @gol
-fregmove @gol
@@ -5213,8 +5227,8 @@ invoking @option{-O2} on programs that use computed gotos.
@item -O3
@opindex O3
-Optimize yet more. @option{-O3} turns on all optimizations specified by
-@option{-O2} and also turns on the @option{-finline-functions},
+Optimize yet more. @option{-O3} turns on all optimizations specified
+by @option{-O2} and also turns on the @option{-finline-functions},
@option{-funswitch-loops}, @option{-fpredictive-commoning},
@option{-fgcse-after-reload} and @option{-ftree-vectorize} options.
@@ -5316,6 +5330,15 @@ in this way.
Enabled at level @option{-O2}.
+@item -findirect-inlining
+@opindex findirect-inlining
+Inline also indirect calls that are discovered to be known at compile
+time thanks to previous inlining. This option has any effect only
+when inlining itself is turned on by the @option{-finline-functions}
+or @option{-finline-small-functions} options.
+
+Enabled at level @option{-O2}.
+
@item -finline-functions
@opindex finline-functions
Integrate all simple functions into their callers. The compiler
@@ -5335,7 +5358,7 @@ caller even if they are not marked @code{inline}. If a call to a given
function is integrated, then the function is not output as assembler code
in its own right.
-Enabled if @option{-funit-at-a-time} is enabled.
+Enabled at levels @option{-O1}, @option{-O2}, @option{-O3} and @option{-Os}.
@item -fearly-inlining
@opindex fearly-inlining
@@ -6356,39 +6379,11 @@ Enabled at levels @option{-O2}, @option{-O3}.
@item -funit-at-a-time
@opindex funit-at-a-time
-Parse the whole compilation unit before starting to produce code.
-This allows some extra optimizations to take place but consumes
-more memory (in general). There are some compatibility issues
-with @emph{unit-at-a-time} mode:
-@itemize @bullet
-@item
-enabling @emph{unit-at-a-time} mode may change the order
-in which functions, variables, and top-level @code{asm} statements
-are emitted, and will likely break code relying on some particular
-ordering. The majority of such top-level @code{asm} statements,
-though, can be replaced by @code{section} attributes. The
-@option{fno-toplevel-reorder} option may be used to keep the ordering
-used in the input file, at the cost of some optimizations.
-
-@item
-@emph{unit-at-a-time} mode removes unreferenced static variables
-and functions. This may result in undefined references
-when an @code{asm} statement refers directly to variables or functions
-that are otherwise unused. In that case either the variable/function
-shall be listed as an operand of the @code{asm} statement operand or,
-in the case of top-level @code{asm} statements the attribute @code{used}
-shall be used on the declaration.
-
-@item
-Static functions now can use non-standard passing conventions that
-may break @code{asm} statements calling functions directly. Again,
-attribute @code{used} will prevent this behavior.
-@end itemize
-
-As a temporary workaround, @option{-fno-unit-at-a-time} can be used,
-but this scheme may not be supported by future releases of GCC@.
+This option is left for compatibility reasons. @option{-funit-at-a-time}
+has no effect, while @option{-fno-unit-at-a-time} implies
+@option{-fno-toplevel-reorder} and @option{-fno-section-anchors}.
-Enabled at levels @option{-O}, @option{-O2}, @option{-O3}, @option{-Os}.
+Enabled by default.
@item -fno-toplevel-reorder
@opindex fno-toplevel-reorder
@@ -6399,6 +6394,10 @@ will not be removed. This option is intended to support existing code
which relies on a particular ordering. For new code, it is better to
use attributes.
+Enabled at level @option{-O0}. When disabled explicitly, it also imply
+@option{-fno-section-anchors} that is otherwise enabled at @option{-O0} on some
+targets.
+
@item -fweb
@opindex fweb
Constructs webs as commonly used for register allocation purposes and assign
@@ -6984,12 +6983,10 @@ limit after inlining inlining is constrained by
@option{--param large-function-growth}. This parameter is useful primarily
to avoid extreme compilation time caused by non-linear algorithms used by the
backend.
-This parameter is ignored when @option{-funit-at-a-time} is not used.
The default value is 2700.
@item large-function-growth
Specifies maximal growth of large function caused by inlining in percents.
-This parameter is ignored when @option{-funit-at-a-time} is not used.
The default value is 100 which limits large function growth to 2.0 times
the original size.
@@ -7006,7 +7003,6 @@ before applying @option{--param inline-unit-growth}. The default is 10000
@item inline-unit-growth
Specifies maximal overall growth of the compilation unit caused by inlining.
-This parameter is ignored when @option{-funit-at-a-time} is not used.
The default value is 30 which limits unit growth to 1.3 times the original
size.
@@ -7380,7 +7376,8 @@ duplicated when threading jumps.
@item max-fields-for-field-sensitive
Maximum number of fields in a structure we will treat in
-a field sensitive manner during pointer analysis.
+a field sensitive manner during pointer analysis. The default is zero
+for -O0, and -O1 and 100 for -Os, -O2, and -O3.
@item prefetch-latency
Estimate on average number of instructions that are executed before
@@ -10620,6 +10617,8 @@ code that expects temporaries to be 80bit.
This is the default choice for the x86-64 compiler.
@item sse,387
+@itemx sse+387
+@itemx both
Attempt to utilize both instruction sets at once. This effectively double the
amount of available registers and on chips with separate execution units for
387 and SSE the execution resources too. Use this option with care, as it is
@@ -15662,7 +15661,7 @@ for any cases where this rule is relaxed.
@item Each of the following options must be the same when building and using
the precompiled header:
-@gccoptlist{-fexceptions -funit-at-a-time}
+@gccoptlist{-fexceptions}
@item
Some other command-line options starting with @option{-f},
diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi
index c0018a77d12..66ca3e98fd0 100644
--- a/gcc/doc/md.texi
+++ b/gcc/doc/md.texi
@@ -2483,6 +2483,10 @@ to store doubleword values.
A register suitable for use in an indirect jump. This will always be
@code{$25} for @option{-mabicalls}.
+@item v
+Register @code{$3}. Do not use this constraint in new code;
+it is retained only for compatibility with glibc.
+
@item y
Equivalent to @code{r}; retained for backwards compatibility.
@@ -4217,7 +4221,8 @@ it may provide the value 4 for this operand.
Optional operands 5 and 6 specify expected alignment and size of block
respectively. The expected alignment differs from alignment in operand 4
in a way that the blocks are not required to be aligned according to it in
-all cases. Expected size, when unknown, is set to @code{(const_int -1)}.
+all cases. This expected alignment is also in bytes, just like operand 4.
+Expected size, when unknown, is set to @code{(const_int -1)}.
Descriptions of multiple @code{movmem@var{m}} patterns can only be
beneficial if the patterns for smaller modes have fewer restrictions
@@ -4254,7 +4259,8 @@ operand.
Optional operands 5 and 6 specify expected alignment and size of block
respectively. The expected alignment differs from alignment in operand 4
in a way that the blocks are not required to be aligned according to it in
-all cases. Expected size, when unknown, is set to @code{(const_int -1)}.
+all cases. This expected alignment is also in bytes, just like operand 4.
+Expected size, when unknown, is set to @code{(const_int -1)}.
The use for multiple @code{setmem@var{m}} is as for @code{movmem@var{m}}.
diff --git a/gcc/doc/options.texi b/gcc/doc/options.texi
index e13279b962b..4581ead6da6 100644
--- a/gcc/doc/options.texi
+++ b/gcc/doc/options.texi
@@ -35,8 +35,11 @@ has been declared in this way, it can be used as an option property.
@xref{Option properties}.
@item
-An option definition record. These records have the following fields:
+A target specific save record to save additional information. These
+records have two fields: the string @samp{TargetSave}, and a
+declaration type to go in the @code{cl_target_option} structure.
+@item
@enumerate
@item
the name of the option, with the leading ``-'' removed
@@ -124,7 +127,10 @@ This property cannot be used alongside @code{Joined} or @code{Separate}.
@item UInteger
The option's argument is a non-negative integer. The option parser
will check and convert the argument before passing it to the relevant
-option handler.
+option handler. @code{UInteger} should also be used on options like
+@code{-falign-loops} where both @code{-falign-loops} and
+@code{-falign-loops}=@var{n} are supported to make sure the saved
+options are given a full integer.
@item Var(@var{var})
The state of this option should be stored in variable @var{var}.
@@ -221,4 +227,9 @@ The option should only be accepted if preprocessor condition
option will be present even if @var{cond} is false; @var{cond} simply
controls whether the option is accepted and whether it is printed in
the @option{--help} output.
+
+@item Save
+Build the @code{cl_target_option} structure to hold a copy of the
+option, add the functions @code{cl_target_option_save} and
+@code{cl_target_option_restore} to save and restore the options.
@end table
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index b0f9aee3f5a..bc1fce72b6f 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -833,10 +833,9 @@ specified, 1 if @option{-O} is specified, and 0 if neither is specified.
@var{size} is nonzero if @option{-Os} is specified and zero otherwise.
-You should not use this macro to change options that are not
-machine-specific. These should uniformly selected by the same
-optimization level on all supported machines. Use this macro to enable
-machine-specific optimizations.
+This macro is run once at program startup and when the optimization
+options are changed via @code{#pragma GCC optimize} or by using the
+@code{optimize} attribute.
@strong{Do not examine @code{write_symbols} in
this macro!} The debugging options are not supposed to alter the
@@ -1095,6 +1094,11 @@ bits. Note that this is not the biggest alignment that is supported,
just the biggest alignment that, when violated, may cause a fault.
@end defmac
+@defmac MALLOC_ABI_ALIGNMENT
+Alignment, in bits, a C conformant malloc implementation has to
+provide. If not defined, the default value is @code{BITS_PER_WORD}.
+@end defmac
+
@defmac MINIMUM_ATOMIC_ALIGNMENT
If defined, the smallest alignment, in bits, that can be given to an
object that can be referenced in one operation, without disturbing any
@@ -2254,6 +2258,16 @@ possible since doing so will allow GCC to perform better register
allocation.
@end defmac
+@deftypefn {Target Hook} bool TARGET_HARD_REGNO_SCRATCH_OK (unsigned int @var{regno})
+This target hook should return @code{true} if it is OK to use a hard register
+@var{regno} as scratch reg in peephole2.
+
+One common use of this macro is to prevent using of a register that
+is not saved by a prologue in an interrupt handler.
+
+The default version of this hook always returns @code{true}.
+@end deftypefn
+
@defmac AVOID_CCMODE_COPIES
Define this macro if the compiler should avoid copies to/from @code{CCmode}
registers. You should only define this macro if support for copying to/from
@@ -4212,6 +4226,18 @@ This hook returns a type node for @code{va_list} for the target.
The default version of the hook returns @code{void*}.
@end deftypefn
+@deftypefn {Target Hook} tree TARGET_FN_ABI_VA_LIST (tree @var{fndecl})
+This hook returns the va_list type of the calling convention specified by
+@var{fndecl}.
+The default version of this hook returns @code{va_list_type_node}.
+@end deftypefn
+
+@deftypefn {Target Hook} tree TARGET_CANONICAL_VA_LIST_TYPE (tree @var{type})
+This hook returns the va_list type of the calling convention specified by the
+type of @var{type}. If @var{type} is not a valid va_list type, it returns
+@code{NULL_TREE}.
+@end deftypefn
+
@deftypefn {Target Hook} tree TARGET_GIMPLIFY_VA_ARG_EXPR (tree @var{valist}, tree @var{type}, tree *@var{pre_p}, tree *@var{post_p})
This hook performs target-specific gimplification of
@code{VA_ARG_EXPR}. The first two parameters correspond to the
@@ -4342,6 +4368,20 @@ function use different registers for the return value, this macro
should recognize only the caller's register numbers.
@end defmac
+@defmac TARGET_ENUM_VA_LIST (@var{idx}, @var{pname}, @var{ptype})
+This target macro is used in function @code{c_common_nodes_and_builtins}
+to iterate through the target specific builtin types for va_list. The
+variable @var{idx} is used as iterator. @var{pname} has to be a pointer
+to a @code{const char *} and @var{ptype} a pointer to a @code{tree} typed
+variable.
+The arguments @var{pname} and @var{ptype} are used to store the result of
+this macro and are set to the name of the va_list builtin type and its
+internal type.
+If the return value of this macro is zero, then there is no more element.
+Otherwise the @var{IDX} should be increased for the next call of this
+macro to iterate through all types.
+@end defmac
+
@defmac APPLY_RESULT_SIZE
Define this macro if @samp{untyped_call} and @samp{untyped_return}
need more space than is implied by @code{FUNCTION_VALUE_REGNO_P} for
@@ -9255,6 +9295,51 @@ attributes, @code{false} otherwise. By default, if a function has a
target specific attribute attached to it, it will not be inlined.
@end deftypefn
+@deftypefn {Target Hook} bool TARGET_VALID_OPTION_ATTRIBUTE_P (tree @var{fndecl}, tree @var{name}, tree @var{args}, int @var{flags})
+This hook is called to parse the @code{attribute(option("..."))}, and
+it allows the function to set different target machine compile time
+options for the current function that might be different than the
+options specified on the command line. The hook should return
+@code{true} if the options are valid.
+
+The hook should set the @var{DECL_FUNCTION_SPECIFIC_TARGET} field in
+the function declaration to hold a pointer to a target specific
+@var{struct cl_target_option} structure.
+@end deftypefn
+
+@deftypefn {Target Hook} void TARGET_OPTION_SAVE (struct cl_target_option *@var{ptr})
+This hook is called to save any additional target specific information
+in the @var{struct cl_target_option} structure for function specific
+options.
+@xref{Option file format}.
+@end deftypefn
+
+@deftypefn {Target Hook} void TARGET_OPTION_RESTORE (struct cl_target_option *@var{ptr})
+This hook is called to restore any additional target specific
+information in the @var{struct cl_target_option} structure for
+function specific options.
+@end deftypefn
+
+@deftypefn {Target Hook} void TARGET_OPTION_PRINT (struct cl_target_option *@var{ptr})
+This hook is called to print any additional target specific
+information in the @var{struct cl_target_option} structure for
+function specific options.
+@end deftypefn
+
+@deftypefn {Target Hook} bool TARGET_OPTION_PRAGMA_PARSE (target @var{args})
+This target hook parses the options for @code{#pragma GCC option} to
+set the machine specific options for functions that occur later in the
+input stream. The options should be the same as handled by the
+@code{TARGET_VALID_OPTION_ATTRIBUTE_P} hook.
+@end deftypefn
+
+@deftypefn {Target Hook} bool TARGET_CAN_INLINE_P (tree @var{caller}, tree @var{callee})
+This target hook returns @code{false} if the @var{caller} function
+cannot inline @var{callee}, based on target specific information. By
+default, inlining is not allowed if the callee function has function
+specific target options and the caller does not use the same options.
+@end deftypefn
+
@node Emulated TLS
@section Emulating TLS
@cindex Emulated TLS
diff --git a/gcc/dojump.c b/gcc/dojump.c
index 43373481955..fb8d139b111 100644
--- a/gcc/dojump.c
+++ b/gcc/dojump.c
@@ -71,8 +71,7 @@ clear_pending_stack_adjust (void)
{
if (optimize > 0
&& (! flag_omit_frame_pointer || cfun->calls_alloca)
- && EXIT_IGNORE_STACK
- && ! (DECL_INLINE (current_function_decl) && ! flag_no_inline))
+ && EXIT_IGNORE_STACK)
discard_pending_stack_adjust ();
}
diff --git a/gcc/domwalk.c b/gcc/domwalk.c
index cec95a5f932..8f779225432 100644
--- a/gcc/domwalk.c
+++ b/gcc/domwalk.c
@@ -144,7 +144,7 @@ walk_dominator_tree (struct dom_walk_data *walk_data, basic_block bb)
{
void *bd = NULL;
basic_block dest;
- block_stmt_iterator bsi;
+ gimple_stmt_iterator gsi;
bool is_interesting;
basic_block *worklist = XNEWVEC (basic_block, n_basic_blocks * 2);
int sp = 0;
@@ -168,8 +168,8 @@ walk_dominator_tree (struct dom_walk_data *walk_data, basic_block bb)
{
bool recycled;
- /* First get some local data, reusing any local data pointer we may
- have saved. */
+ /* First get some local data, reusing any local data
+ pointer we may have saved. */
if (VEC_length (void_p, walk_data->free_block_data) > 0)
{
bd = VEC_pop (void_p, walk_data->free_block_data);
@@ -199,13 +199,14 @@ walk_dominator_tree (struct dom_walk_data *walk_data, basic_block bb)
if (is_interesting && walk_data->before_dom_children_walk_stmts)
{
if (walk_data->walk_stmts_backward)
- for (bsi = bsi_last (bb); !bsi_end_p (bsi); bsi_prev (&bsi))
+ for (gsi = gsi_last (bb_seq (bb)); !gsi_end_p (gsi);
+ gsi_prev (&gsi))
(*walk_data->before_dom_children_walk_stmts) (walk_data, bb,
- bsi);
+ gsi);
else
- for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
(*walk_data->before_dom_children_walk_stmts) (walk_data, bb,
- bsi);
+ gsi);
}
/* Callback for operations to execute before we have walked the
@@ -239,13 +240,14 @@ walk_dominator_tree (struct dom_walk_data *walk_data, basic_block bb)
if (is_interesting && walk_data->after_dom_children_walk_stmts)
{
if (walk_data->walk_stmts_backward)
- for (bsi = bsi_last (bb); !bsi_end_p (bsi); bsi_prev (&bsi))
+ for (gsi = gsi_last (bb_seq (bb)); !gsi_end_p (gsi);
+ gsi_prev (&gsi))
(*walk_data->after_dom_children_walk_stmts) (walk_data, bb,
- bsi);
+ gsi);
else
- for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
(*walk_data->after_dom_children_walk_stmts) (walk_data, bb,
- bsi);
+ gsi);
}
/* Callback for operations to execute after we have walked the
diff --git a/gcc/domwalk.h b/gcc/domwalk.h
index 3fc6810207e..61117ef7d45 100644
--- a/gcc/domwalk.h
+++ b/gcc/domwalk.h
@@ -66,7 +66,7 @@ struct dom_walk_data
/* Function to call to walk statements before the recursive walk
of the dominator children. */
void (*before_dom_children_walk_stmts) (struct dom_walk_data *,
- basic_block, block_stmt_iterator);
+ basic_block, gimple_stmt_iterator);
/* Function to call after the statement walk occurring before the
recursive walk of the dominator children. */
@@ -81,7 +81,7 @@ struct dom_walk_data
/* Function to call to walk statements after the recursive walk
of the dominator children. */
void (*after_dom_children_walk_stmts) (struct dom_walk_data *,
- basic_block, block_stmt_iterator);
+ basic_block, gimple_stmt_iterator);
/* Function to call after the statement walk occurring after the
recursive walk of the dominator children.
diff --git a/gcc/dse.c b/gcc/dse.c
index 71d34620110..4d5120160fa 100644
--- a/gcc/dse.c
+++ b/gcc/dse.c
@@ -1295,7 +1295,7 @@ record_store (rtx body, bb_info_t bb_info)
{
insn_info_t next = ptr->next_local_store;
store_info_t s_info = ptr->store_rec;
- bool delete = true;
+ bool del = true;
/* Skip the clobbers. We delete the active insn if this insn
shadows the set. To have been put on the active list, it
@@ -1304,7 +1304,7 @@ record_store (rtx body, bb_info_t bb_info)
s_info = s_info->next;
if (s_info->alias_set != spill_alias_set)
- delete = false;
+ del = false;
else if (s_info->alias_set)
{
struct clear_alias_mode_holder *entry
@@ -1317,7 +1317,7 @@ record_store (rtx body, bb_info_t bb_info)
if ((GET_MODE (mem) == GET_MODE (s_info->mem))
&& (GET_MODE (mem) == entry->mode))
{
- delete = true;
+ del = true;
s_info->positions_needed = (unsigned HOST_WIDE_INT) 0;
}
if (dump_file)
@@ -1352,9 +1352,9 @@ record_store (rtx body, bb_info_t bb_info)
/* An insn can be deleted if every position of every one of
its s_infos is zero. */
if (s_info->positions_needed != (unsigned HOST_WIDE_INT) 0)
- delete = false;
+ del = false;
- if (delete)
+ if (del)
{
insn_info_t insn_to_delete = ptr;
@@ -2080,7 +2080,7 @@ remove_useless_values (cselib_val *base)
while (insn_info)
{
store_info_t store_info = insn_info->store_rec;
- bool delete = false;
+ bool del = false;
/* If ANY of the store_infos match the cselib group that is
being deleted, then the insn can not be deleted. */
@@ -2089,13 +2089,13 @@ remove_useless_values (cselib_val *base)
if ((store_info->group_id == -1)
&& (store_info->cse_base == base))
{
- delete = true;
+ del = true;
break;
}
store_info = store_info->next;
}
- if (delete)
+ if (del)
{
if (last)
last->next_local_store = insn_info->next_local_store;
diff --git a/gcc/dwarf2asm.c b/gcc/dwarf2asm.c
index ea19b793df5..43d57e9fa8f 100644
--- a/gcc/dwarf2asm.c
+++ b/gcc/dwarf2asm.c
@@ -730,11 +730,11 @@ splay_tree_compare_strings (splay_tree_key k1, splay_tree_key k2)
/* Put X, a SYMBOL_REF, in memory. Return a SYMBOL_REF to the allocated
memory. Differs from force_const_mem in that a single pool is used for
the entire unit of translation, and the memory is not guaranteed to be
- "near" the function in any interesting sense. PUBLIC controls whether
+ "near" the function in any interesting sense. IS_PUBLIC controls whether
the symbol can be shared across the entire application (or DSO). */
static rtx
-dw2_force_const_mem (rtx x, bool public)
+dw2_force_const_mem (rtx x, bool is_public)
{
splay_tree_node node;
const char *str;
@@ -755,7 +755,7 @@ dw2_force_const_mem (rtx x, bool public)
{
tree id;
- if (public && USE_LINKONCE_INDIRECT)
+ if (is_public && USE_LINKONCE_INDIRECT)
{
char *ref_name = XALLOCAVEC (char, strlen (str) + sizeof "DW.ref.");
@@ -829,7 +829,7 @@ dw2_output_indirect_constants (void)
reference is shared across the entire application (or DSO). */
void
-dw2_asm_output_encoded_addr_rtx (int encoding, rtx addr, bool public,
+dw2_asm_output_encoded_addr_rtx (int encoding, rtx addr, bool is_public,
const char *comment, ...)
{
int size;
@@ -870,7 +870,7 @@ dw2_asm_output_encoded_addr_rtx (int encoding, rtx addr, bool public,
the constant pool for this function. Moreover, we'd like to
share these constants across the entire unit of translation and
even, if possible, across the entire application (or DSO). */
- addr = dw2_force_const_mem (addr, public);
+ addr = dw2_force_const_mem (addr, is_public);
encoding &= ~DW_EH_PE_indirect;
goto restart;
}
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 80bdc0a4bb0..a8e06efb22d 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -1579,6 +1579,32 @@ dwarf2out_frame_debug_expr (rtx expr, const char *label)
&& (!MEM_P (SET_DEST (elem)) || GET_CODE (expr) == SEQUENCE)
&& (RTX_FRAME_RELATED_P (elem) || par_index == 0))
dwarf2out_frame_debug_expr (elem, label);
+ else if (GET_CODE (elem) == SET
+ && par_index != 0
+ && !RTX_FRAME_RELATED_P (elem))
+ {
+ /* Stack adjustment combining might combine some post-prologue
+ stack adjustment into a prologue stack adjustment. */
+ HOST_WIDE_INT offset = stack_adjust_offset (elem);
+
+ if (offset != 0)
+ {
+ if (cfa.reg == STACK_POINTER_REGNUM)
+ cfa.offset += offset;
+
+#ifndef STACK_GROWS_DOWNWARD
+ offset = -offset;
+#endif
+
+ args_size += offset;
+ if (args_size < 0)
+ args_size = 0;
+
+ def_cfa_1 (label, &cfa);
+ if (flag_asynchronous_unwind_tables)
+ dwarf2out_args_size (label, args_size);
+ }
+ }
}
return;
}
@@ -4315,7 +4341,7 @@ static void tree_add_const_value_attribute (dw_die_ref, tree);
static void add_name_attribute (dw_die_ref, const char *);
static void add_comp_dir_attribute (dw_die_ref);
static void add_bound_info (dw_die_ref, enum dwarf_attribute, tree);
-static void add_subscript_info (dw_die_ref, tree);
+static void add_subscript_info (dw_die_ref, tree, bool);
static void add_byte_size_attribute (dw_die_ref, tree);
static void add_bit_offset_attribute (dw_die_ref, tree);
static void add_bit_size_attribute (dw_die_ref, tree);
@@ -9610,9 +9636,8 @@ loc_descriptor_from_tree_1 (tree loc, int want_address)
CASE_CONVERT:
case VIEW_CONVERT_EXPR:
case SAVE_EXPR:
- case GIMPLE_MODIFY_STMT:
- return loc_descriptor_from_tree_1 (GENERIC_TREE_OPERAND (loc, 0),
- want_address);
+ case MODIFY_EXPR:
+ return loc_descriptor_from_tree_1 (TREE_OPERAND (loc, 0), want_address);
case COMPONENT_REF:
case BIT_FIELD_REF:
@@ -10416,14 +10441,12 @@ static tree
reference_to_unused (tree * tp, int * walk_subtrees,
void * data ATTRIBUTE_UNUSED)
{
- if (! EXPR_P (*tp) && ! GIMPLE_STMT_P (*tp) && ! CONSTANT_CLASS_P (*tp))
+ if (! EXPR_P (*tp) && ! CONSTANT_CLASS_P (*tp))
*walk_subtrees = 0;
if (DECL_P (*tp) && ! TREE_PUBLIC (*tp) && ! TREE_USED (*tp)
&& ! TREE_ASM_WRITTEN (*tp))
return *tp;
- else if (!flag_unit_at_a_time)
- return NULL_TREE;
/* ??? The C++ FE emits debug information for using decls, so
putting gcc_unreachable here falls over. See PR31899. For now
be conservative. */
@@ -11194,36 +11217,21 @@ add_bound_info (dw_die_ref subrange_die, enum dwarf_attribute bound_attr, tree b
}
}
-/* Note that the block of subscript information for an array type also
- includes information about the element type of type given array type. */
+/* Add subscript info to TYPE_DIE, describing an array TYPE, collapsing
+ possibly nested array subscripts in a flat sequence if COLLAPSE_P is true.
+ Note that the block of subscript information for an array type also
+ includes information about the element type of the given array type. */
static void
-add_subscript_info (dw_die_ref type_die, tree type)
+add_subscript_info (dw_die_ref type_die, tree type, bool collapse_p)
{
-#ifndef MIPS_DEBUGGING_INFO
unsigned dimension_number;
-#endif
tree lower, upper;
dw_die_ref subrange_die;
- /* The GNU compilers represent multidimensional array types as sequences of
- one dimensional array types whose element types are themselves array
- types. Here we squish that down, so that each multidimensional array
- type gets only one array_type DIE in the Dwarf debugging info. The draft
- Dwarf specification say that we are allowed to do this kind of
- compression in C (because there is no difference between an array or
- arrays and a multidimensional array in C) but for other source languages
- (e.g. Ada) we probably shouldn't do this. */
-
- /* ??? The SGI dwarf reader fails for multidimensional arrays with a
- const enum type. E.g. const enum machine_mode insn_operand_mode[2][10].
- We work around this by disabling this feature. See also
- gen_array_type_die. */
-#ifndef MIPS_DEBUGGING_INFO
for (dimension_number = 0;
- TREE_CODE (type) == ARRAY_TYPE;
+ TREE_CODE (type) == ARRAY_TYPE && (dimension_number == 0 || collapse_p);
type = TREE_TYPE (type), dimension_number++)
-#endif
{
tree domain = TYPE_DOMAIN (type);
@@ -11747,13 +11755,29 @@ gen_array_type_die (tree type, dw_die_ref context_die)
{
dw_die_ref scope_die = scope_die_for (type, context_die);
dw_die_ref array_die;
+
+ /* GNU compilers represent multidimensional array types as sequences of one
+ dimensional array types whose element types are themselves array types.
+ We sometimes squish that down to a single array_type DIE with multiple
+ subscripts in the Dwarf debugging info. The draft Dwarf specification
+ say that we are allowed to do this kind of compression in C, because
+ there is no difference between an array of arrays and a multidimensional
+ array. We don't do this for Ada to remain as close as possible to the
+ actual representation, which is especially important against the language
+ flexibilty wrt arrays of variable size. */
+
+ bool collapse_nested_arrays = !is_ada ();
tree element_type;
+
+ /* ??? The SGI dwarf reader fails for array of array of enum types
+ (e.g. const enum machine_mode insn_operand_mode[2][10]) unless the inner
+ array type comes before the outer array type. We thus call gen_type_die
+ before we new_die and must prevent nested array types collapsing for this
+ target. */
- /* ??? The SGI dwarf reader fails for array of array of enum types unless
- the inner array type comes before the outer array type. Thus we must
- call gen_type_die before we call new_die. See below also. */
#ifdef MIPS_DEBUGGING_INFO
gen_type_die (TREE_TYPE (type), context_die);
+ collapse_nested_arrays = false;
#endif
array_die = new_die (DW_TAG_array_type, scope_die, type);
@@ -11792,19 +11816,16 @@ gen_array_type_die (tree type, dw_die_ref context_die)
add_AT_flag (array_die, DW_AT_declaration, 1);
else
#endif
- add_subscript_info (array_die, type);
+ add_subscript_info (array_die, type, collapse_nested_arrays);
- /* Add representation of the type of the elements of this array type. */
+ /* Add representation of the type of the elements of this array type and
+ emit the corresponding DIE if we haven't done it already. */
element_type = TREE_TYPE (type);
-
- /* ??? The SGI dwarf reader fails for multidimensional arrays with a
- const enum type. E.g. const enum machine_mode insn_operand_mode[2][10].
- We work around this by disabling this feature. See also
- add_subscript_info. */
+ if (collapse_nested_arrays)
+ while (TREE_CODE (element_type) == ARRAY_TYPE)
+ element_type = TREE_TYPE (element_type);
+
#ifndef MIPS_DEBUGGING_INFO
- while (TREE_CODE (element_type) == ARRAY_TYPE)
- element_type = TREE_TYPE (element_type);
-
gen_type_die (element_type, context_die);
#endif
diff --git a/gcc/ebitmap.h b/gcc/ebitmap.h
index 8efb4375ecc..2916e44b223 100644
--- a/gcc/ebitmap.h
+++ b/gcc/ebitmap.h
@@ -121,7 +121,7 @@ ebitmap_iter_init (ebitmap_iterator *i, ebitmap bmp, unsigned int min)
static inline bool
ebitmap_iter_cond (ebitmap_iterator *i, unsigned int *n)
{
- unsigned int ourn;
+ unsigned int ourn = 0;
if (i->size == 0)
return false;
diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c
index 22c7979a773..65fa8e457ec 100644
--- a/gcc/emit-rtl.c
+++ b/gcc/emit-rtl.c
@@ -890,12 +890,12 @@ gen_reg_rtx (enum machine_mode mode)
if (reg_rtx_no == crtl->emit.regno_pointer_align_length)
{
int old_size = crtl->emit.regno_pointer_align_length;
- char *new;
+ char *tmp;
rtx *new1;
- new = XRESIZEVEC (char, crtl->emit.regno_pointer_align, old_size * 2);
- memset (new + old_size, 0, old_size);
- crtl->emit.regno_pointer_align = (unsigned char *) new;
+ tmp = XRESIZEVEC (char, crtl->emit.regno_pointer_align, old_size * 2);
+ memset (tmp + old_size, 0, old_size);
+ crtl->emit.regno_pointer_align = (unsigned char *) tmp;
new1 = GGC_RESIZEVEC (rtx, regno_reg_rtx, old_size * 2);
memset (new1 + old_size, 0, old_size * sizeof (rtx));
@@ -913,9 +913,9 @@ gen_reg_rtx (enum machine_mode mode)
to the REG_OFFSET. */
static void
-update_reg_offset (rtx new, rtx reg, int offset)
+update_reg_offset (rtx new_rtx, rtx reg, int offset)
{
- REG_ATTRS (new) = get_reg_attrs (REG_EXPR (reg),
+ REG_ATTRS (new_rtx) = get_reg_attrs (REG_EXPR (reg),
REG_OFFSET (reg) + offset);
}
@@ -926,10 +926,10 @@ rtx
gen_rtx_REG_offset (rtx reg, enum machine_mode mode, unsigned int regno,
int offset)
{
- rtx new = gen_rtx_REG (mode, regno);
+ rtx new_rtx = gen_rtx_REG (mode, regno);
- update_reg_offset (new, reg, offset);
- return new;
+ update_reg_offset (new_rtx, reg, offset);
+ return new_rtx;
}
/* Generate a new pseudo-register with the same attributes as REG, but
@@ -938,10 +938,10 @@ gen_rtx_REG_offset (rtx reg, enum machine_mode mode, unsigned int regno,
rtx
gen_reg_rtx_offset (rtx reg, enum machine_mode mode, int offset)
{
- rtx new = gen_reg_rtx (mode);
+ rtx new_rtx = gen_reg_rtx (mode);
- update_reg_offset (new, reg, offset);
- return new;
+ update_reg_offset (new_rtx, reg, offset);
+ return new_rtx;
}
/* Adjust REG in-place so that it has mode MODE. It is assumed that the
@@ -1372,18 +1372,18 @@ operand_subword (rtx op, unsigned int offset, int validate_address, enum machine
/* Form a new MEM at the requested address. */
if (MEM_P (op))
{
- rtx new = adjust_address_nv (op, word_mode, offset * UNITS_PER_WORD);
+ rtx new_rtx = adjust_address_nv (op, word_mode, offset * UNITS_PER_WORD);
if (! validate_address)
- return new;
+ return new_rtx;
else if (reload_completed)
{
- if (! strict_memory_address_p (word_mode, XEXP (new, 0)))
+ if (! strict_memory_address_p (word_mode, XEXP (new_rtx, 0)))
return 0;
}
else
- return replace_equiv_address (new, XEXP (new, 0));
+ return replace_equiv_address (new_rtx, XEXP (new_rtx, 0));
}
/* Rest can be handled by simplify_subreg. */
@@ -1486,7 +1486,7 @@ mem_expr_equal_p (const_tree expr1, const_tree expr2)
return 0;
}
-/* Given REF, a MEM, and T, either the type of X or the expression
+/* Given REF (a MEM) and T, either the type of X or the expression
corresponding to REF, set the memory attributes. OBJECTP is nonzero
if we are making a new object of this type. BITPOS is nonzero if
there is an offset outstanding on T that will be applied later. */
@@ -1834,7 +1834,7 @@ set_mem_size (rtx mem, rtx size)
static rtx
change_address_1 (rtx memref, enum machine_mode mode, rtx addr, int validate)
{
- rtx new;
+ rtx new_rtx;
gcc_assert (MEM_P (memref));
if (mode == VOIDmode)
@@ -1856,9 +1856,9 @@ change_address_1 (rtx memref, enum machine_mode mode, rtx addr, int validate)
if (rtx_equal_p (addr, XEXP (memref, 0)) && mode == GET_MODE (memref))
return memref;
- new = gen_rtx_MEM (mode, addr);
- MEM_COPY_ATTRIBUTES (new, memref);
- return new;
+ new_rtx = gen_rtx_MEM (mode, addr);
+ MEM_COPY_ATTRIBUTES (new_rtx, memref);
+ return new_rtx;
}
/* Like change_address_1 with VALIDATE nonzero, but we are not saying in what
@@ -1867,31 +1867,31 @@ change_address_1 (rtx memref, enum machine_mode mode, rtx addr, int validate)
rtx
change_address (rtx memref, enum machine_mode mode, rtx addr)
{
- rtx new = change_address_1 (memref, mode, addr, 1), size;
- enum machine_mode mmode = GET_MODE (new);
+ rtx new_rtx = change_address_1 (memref, mode, addr, 1), size;
+ enum machine_mode mmode = GET_MODE (new_rtx);
unsigned int align;
size = mmode == BLKmode ? 0 : GEN_INT (GET_MODE_SIZE (mmode));
align = mmode == BLKmode ? BITS_PER_UNIT : GET_MODE_ALIGNMENT (mmode);
/* If there are no changes, just return the original memory reference. */
- if (new == memref)
+ if (new_rtx == memref)
{
if (MEM_ATTRS (memref) == 0
|| (MEM_EXPR (memref) == NULL
&& MEM_OFFSET (memref) == NULL
&& MEM_SIZE (memref) == size
&& MEM_ALIGN (memref) == align))
- return new;
+ return new_rtx;
- new = gen_rtx_MEM (mmode, XEXP (memref, 0));
- MEM_COPY_ATTRIBUTES (new, memref);
+ new_rtx = gen_rtx_MEM (mmode, XEXP (memref, 0));
+ MEM_COPY_ATTRIBUTES (new_rtx, memref);
}
- MEM_ATTRS (new)
+ MEM_ATTRS (new_rtx)
= get_mem_attrs (MEM_ALIAS_SET (memref), 0, 0, size, align, mmode);
- return new;
+ return new_rtx;
}
/* Return a memory reference like MEMREF, but with its mode changed
@@ -1905,7 +1905,7 @@ adjust_address_1 (rtx memref, enum machine_mode mode, HOST_WIDE_INT offset,
int validate, int adjust)
{
rtx addr = XEXP (memref, 0);
- rtx new;
+ rtx new_rtx;
rtx memoffset = MEM_OFFSET (memref);
rtx size = 0;
unsigned int memalign = MEM_ALIGN (memref);
@@ -1934,7 +1934,7 @@ adjust_address_1 (rtx memref, enum machine_mode mode, HOST_WIDE_INT offset,
addr = plus_constant (addr, offset);
}
- new = change_address_1 (memref, mode, addr, validate);
+ new_rtx = change_address_1 (memref, mode, addr, validate);
/* Compute the new values of the memory attributes due to this adjustment.
We add the offsets and update the alignment. */
@@ -1950,17 +1950,17 @@ adjust_address_1 (rtx memref, enum machine_mode mode, HOST_WIDE_INT offset,
(unsigned HOST_WIDE_INT) (offset & -offset) * BITS_PER_UNIT);
/* We can compute the size in a number of ways. */
- if (GET_MODE (new) != BLKmode)
- size = GEN_INT (GET_MODE_SIZE (GET_MODE (new)));
+ if (GET_MODE (new_rtx) != BLKmode)
+ size = GEN_INT (GET_MODE_SIZE (GET_MODE (new_rtx)));
else if (MEM_SIZE (memref))
size = plus_constant (MEM_SIZE (memref), -offset);
- MEM_ATTRS (new) = get_mem_attrs (MEM_ALIAS_SET (memref), MEM_EXPR (memref),
- memoffset, size, memalign, GET_MODE (new));
+ MEM_ATTRS (new_rtx) = get_mem_attrs (MEM_ALIAS_SET (memref), MEM_EXPR (memref),
+ memoffset, size, memalign, GET_MODE (new_rtx));
/* At some point, we should validate that this offset is within the object,
if all the appropriate values are known. */
- return new;
+ return new_rtx;
}
/* Return a memory reference like MEMREF, but with its mode changed
@@ -1983,9 +1983,9 @@ adjust_automodify_address_1 (rtx memref, enum machine_mode mode, rtx addr,
rtx
offset_address (rtx memref, rtx offset, unsigned HOST_WIDE_INT pow2)
{
- rtx new, addr = XEXP (memref, 0);
+ rtx new_rtx, addr = XEXP (memref, 0);
- new = simplify_gen_binary (PLUS, Pmode, addr, offset);
+ new_rtx = simplify_gen_binary (PLUS, Pmode, addr, offset);
/* At this point we don't know _why_ the address is invalid. It
could have secondary memory references, multiplies or anything.
@@ -1994,28 +1994,28 @@ offset_address (rtx memref, rtx offset, unsigned HOST_WIDE_INT pow2)
being able to recognize the magic around pic_offset_table_rtx.
This stuff is fragile, and is yet another example of why it is
bad to expose PIC machinery too early. */
- if (! memory_address_p (GET_MODE (memref), new)
+ if (! memory_address_p (GET_MODE (memref), new_rtx)
&& GET_CODE (addr) == PLUS
&& XEXP (addr, 0) == pic_offset_table_rtx)
{
addr = force_reg (GET_MODE (addr), addr);
- new = simplify_gen_binary (PLUS, Pmode, addr, offset);
+ new_rtx = simplify_gen_binary (PLUS, Pmode, addr, offset);
}
- update_temp_slot_address (XEXP (memref, 0), new);
- new = change_address_1 (memref, VOIDmode, new, 1);
+ update_temp_slot_address (XEXP (memref, 0), new_rtx);
+ new_rtx = change_address_1 (memref, VOIDmode, new_rtx, 1);
/* If there are no changes, just return the original memory reference. */
- if (new == memref)
- return new;
+ if (new_rtx == memref)
+ return new_rtx;
/* Update the alignment to reflect the offset. Reset the offset, which
we don't know. */
- MEM_ATTRS (new)
+ MEM_ATTRS (new_rtx)
= get_mem_attrs (MEM_ALIAS_SET (memref), MEM_EXPR (memref), 0, 0,
MIN (MEM_ALIGN (memref), pow2 * BITS_PER_UNIT),
- GET_MODE (new));
- return new;
+ GET_MODE (new_rtx));
+ return new_rtx;
}
/* Return a memory reference like MEMREF, but with its address changed to
@@ -2048,14 +2048,14 @@ replace_equiv_address_nv (rtx memref, rtx addr)
rtx
widen_memory_access (rtx memref, enum machine_mode mode, HOST_WIDE_INT offset)
{
- rtx new = adjust_address_1 (memref, mode, offset, 1, 1);
- tree expr = MEM_EXPR (new);
- rtx memoffset = MEM_OFFSET (new);
+ rtx new_rtx = adjust_address_1 (memref, mode, offset, 1, 1);
+ tree expr = MEM_EXPR (new_rtx);
+ rtx memoffset = MEM_OFFSET (new_rtx);
unsigned int size = GET_MODE_SIZE (mode);
/* If there are no changes, just return the original memory reference. */
- if (new == memref)
- return new;
+ if (new_rtx == memref)
+ return new_rtx;
/* If we don't know what offset we were at within the expression, then
we can't know if we've overstepped the bounds. */
@@ -2117,10 +2117,10 @@ widen_memory_access (rtx memref, enum machine_mode mode, HOST_WIDE_INT offset)
/* The widened memory may alias other stuff, so zap the alias set. */
/* ??? Maybe use get_alias_set on any remaining expression. */
- MEM_ATTRS (new) = get_mem_attrs (0, expr, memoffset, GEN_INT (size),
- MEM_ALIGN (new), mode);
+ MEM_ATTRS (new_rtx) = get_mem_attrs (0, expr, memoffset, GEN_INT (size),
+ MEM_ALIGN (new_rtx), mode);
- return new;
+ return new_rtx;
}
/* Return a newly created CODE_LABEL rtx with a unique label number. */
@@ -5464,27 +5464,27 @@ init_emit_once (int line_numbers)
rtx
emit_copy_of_insn_after (rtx insn, rtx after)
{
- rtx new, link;
+ rtx new_rtx, link;
switch (GET_CODE (insn))
{
case INSN:
- new = emit_insn_after (copy_insn (PATTERN (insn)), after);
+ new_rtx = emit_insn_after (copy_insn (PATTERN (insn)), after);
break;
case JUMP_INSN:
- new = emit_jump_insn_after (copy_insn (PATTERN (insn)), after);
+ new_rtx = emit_jump_insn_after (copy_insn (PATTERN (insn)), after);
break;
case CALL_INSN:
- new = emit_call_insn_after (copy_insn (PATTERN (insn)), after);
+ new_rtx = emit_call_insn_after (copy_insn (PATTERN (insn)), after);
if (CALL_INSN_FUNCTION_USAGE (insn))
- CALL_INSN_FUNCTION_USAGE (new)
+ CALL_INSN_FUNCTION_USAGE (new_rtx)
= copy_insn (CALL_INSN_FUNCTION_USAGE (insn));
- SIBLING_CALL_P (new) = SIBLING_CALL_P (insn);
- RTL_CONST_CALL_P (new) = RTL_CONST_CALL_P (insn);
- RTL_PURE_CALL_P (new) = RTL_PURE_CALL_P (insn);
- RTL_LOOPING_CONST_OR_PURE_CALL_P (new)
+ SIBLING_CALL_P (new_rtx) = SIBLING_CALL_P (insn);
+ RTL_CONST_CALL_P (new_rtx) = RTL_CONST_CALL_P (insn);
+ RTL_PURE_CALL_P (new_rtx) = RTL_PURE_CALL_P (insn);
+ RTL_LOOPING_CONST_OR_PURE_CALL_P (new_rtx)
= RTL_LOOPING_CONST_OR_PURE_CALL_P (insn);
break;
@@ -5493,14 +5493,14 @@ emit_copy_of_insn_after (rtx insn, rtx after)
}
/* Update LABEL_NUSES. */
- mark_jump_label (PATTERN (new), new, 0);
+ mark_jump_label (PATTERN (new_rtx), new_rtx, 0);
- INSN_LOCATOR (new) = INSN_LOCATOR (insn);
+ INSN_LOCATOR (new_rtx) = INSN_LOCATOR (insn);
/* If the old insn is frame related, then so is the new one. This is
primarily needed for IA-64 unwind info which marks epilogue insns,
which may be duplicated by the basic block reordering code. */
- RTX_FRAME_RELATED_P (new) = RTX_FRAME_RELATED_P (insn);
+ RTX_FRAME_RELATED_P (new_rtx) = RTX_FRAME_RELATED_P (insn);
/* Copy all REG_NOTES except REG_LABEL_OPERAND since mark_jump_label
will make them. REG_LABEL_TARGETs are created there too, but are
@@ -5509,14 +5509,14 @@ emit_copy_of_insn_after (rtx insn, rtx after)
if (REG_NOTE_KIND (link) != REG_LABEL_OPERAND)
{
if (GET_CODE (link) == EXPR_LIST)
- add_reg_note (new, REG_NOTE_KIND (link),
+ add_reg_note (new_rtx, REG_NOTE_KIND (link),
copy_insn_1 (XEXP (link, 0)));
else
- add_reg_note (new, REG_NOTE_KIND (link), XEXP (link, 0));
+ add_reg_note (new_rtx, REG_NOTE_KIND (link), XEXP (link, 0));
}
- INSN_CODE (new) = INSN_CODE (insn);
- return new;
+ INSN_CODE (new_rtx) = INSN_CODE (insn);
+ return new_rtx;
}
static GTY((deletable)) rtx hard_reg_clobbers [NUM_MACHINE_MODES][FIRST_PSEUDO_REGISTER];
diff --git a/gcc/except.c b/gcc/except.c
index 1d9a73639b6..962dd0b8b64 100644
--- a/gcc/except.c
+++ b/gcc/except.c
@@ -86,7 +86,7 @@ along with GCC; see the file COPYING3. If not see
/* Protect cleanup actions with must-not-throw regions, with a call
to the given failure handler. */
-tree (*lang_protect_cleanup_actions) (void);
+gimple (*lang_protect_cleanup_actions) (void);
/* Return true if type A catches type B. */
int (*lang_eh_type_covers) (tree a, tree b);
@@ -419,30 +419,30 @@ init_eh_for_function (void)
static struct eh_region *
gen_eh_region (enum eh_region_type type, struct eh_region *outer)
{
- struct eh_region *new;
+ struct eh_region *new_eh;
#ifdef ENABLE_CHECKING
gcc_assert (doing_eh (0));
#endif
/* Insert a new blank region as a leaf in the tree. */
- new = GGC_CNEW (struct eh_region);
- new->type = type;
- new->outer = outer;
+ new_eh = GGC_CNEW (struct eh_region);
+ new_eh->type = type;
+ new_eh->outer = outer;
if (outer)
{
- new->next_peer = outer->inner;
- outer->inner = new;
+ new_eh->next_peer = outer->inner;
+ outer->inner = new_eh;
}
else
{
- new->next_peer = cfun->eh->region_tree;
- cfun->eh->region_tree = new;
+ new_eh->next_peer = cfun->eh->region_tree;
+ cfun->eh->region_tree = new_eh;
}
- new->region_number = ++cfun->eh->last_region_number;
+ new_eh->region_number = ++cfun->eh->last_region_number;
- return new;
+ return new_eh;
}
struct eh_region *
@@ -3047,19 +3047,19 @@ action_record_hash (const void *pentry)
static int
add_action_record (htab_t ar_hash, int filter, int next)
{
- struct action_record **slot, *new, tmp;
+ struct action_record **slot, *new_ar, tmp;
tmp.filter = filter;
tmp.next = next;
slot = (struct action_record **) htab_find_slot (ar_hash, &tmp, INSERT);
- if ((new = *slot) == NULL)
+ if ((new_ar = *slot) == NULL)
{
- new = XNEW (struct action_record);
- new->offset = VARRAY_ACTIVE_SIZE (crtl->eh.action_record_data) + 1;
- new->filter = filter;
- new->next = next;
- *slot = new;
+ new_ar = XNEW (struct action_record);
+ new_ar->offset = VARRAY_ACTIVE_SIZE (crtl->eh.action_record_data) + 1;
+ new_ar->filter = filter;
+ new_ar->next = next;
+ *slot = new_ar;
/* The filter value goes in untouched. The link to the next
record is a "self-relative" byte offset, or zero to indicate
@@ -3072,7 +3072,7 @@ add_action_record (htab_t ar_hash, int filter, int next)
push_sleb128 (&crtl->eh.action_record_data, next);
}
- return new->offset;
+ return new_ar->offset;
}
static int
@@ -3550,7 +3550,7 @@ static void
output_ttype (tree type, int tt_format, int tt_format_size)
{
rtx value;
- bool public = true;
+ bool is_public = true;
if (type == NULL_TREE)
value = const0_rtx;
@@ -3573,7 +3573,7 @@ output_ttype (tree type, int tt_format, int tt_format_size)
node = varpool_node (type);
if (node)
varpool_mark_needed_node (node);
- public = TREE_PUBLIC (type);
+ is_public = TREE_PUBLIC (type);
}
}
else
@@ -3588,7 +3588,7 @@ output_ttype (tree type, int tt_format, int tt_format_size)
assemble_integer (value, tt_format_size,
tt_format_size * BITS_PER_UNIT, 1);
else
- dw2_asm_output_encoded_addr_rtx (tt_format, value, public, NULL);
+ dw2_asm_output_encoded_addr_rtx (tt_format, value, is_public, NULL);
}
void
diff --git a/gcc/except.h b/gcc/except.h
index ae3264e6f3e..8f9efb26382 100644
--- a/gcc/except.h
+++ b/gcc/except.h
@@ -108,20 +108,13 @@ extern void dump_eh_tree (FILE *, struct function *);
extern bool eh_region_outer_p (struct function *, int, int);
extern int eh_region_outermost (struct function *, int, int);
-/* tree-eh.c */
-extern void add_stmt_to_eh_region_fn (struct function *, tree, int);
-extern bool remove_stmt_from_eh_region_fn (struct function *, tree);
-extern int lookup_stmt_eh_region_fn (struct function *, const_tree);
-extern int lookup_stmt_eh_region (const_tree);
-extern bool verify_eh_edges (tree);
-
/* If non-NULL, this is a function that returns an expression to be
executed if an unhandled exception is propagated out of a cleanup
region. For example, in C++, an exception thrown by a destructor
during stack unwinding is required to result in a call to
`std::terminate', so the C++ version of this function returns a
CALL_EXPR for `std::terminate'. */
-extern tree (*lang_protect_cleanup_actions) (void);
+extern gimple (*lang_protect_cleanup_actions) (void);
/* Return true if type A catches type B. */
extern int (*lang_eh_type_covers) (tree a, tree b);
@@ -175,7 +168,7 @@ extern tree (*lang_eh_runtime_type) (tree);
struct throw_stmt_node GTY(())
{
- tree stmt;
+ gimple stmt;
int region_nr;
};
diff --git a/gcc/explow.c b/gcc/explow.c
index d573836d293..0c941d5b337 100644
--- a/gcc/explow.c
+++ b/gcc/explow.c
@@ -874,10 +874,10 @@ round_push (rtx size)
if (GET_CODE (size) == CONST_INT)
{
- HOST_WIDE_INT new = (INTVAL (size) + align - 1) / align * align;
+ HOST_WIDE_INT new_size = (INTVAL (size) + align - 1) / align * align;
- if (INTVAL (size) != new)
- size = GEN_INT (new);
+ if (INTVAL (size) != new_size)
+ size = GEN_INT (new_size);
}
else
{
@@ -1136,10 +1136,10 @@ allocate_dynamic_stack_space (rtx size, rtx target, int known_align)
if (GET_CODE (size) == CONST_INT)
{
- HOST_WIDE_INT new = INTVAL (size) / align * align;
+ HOST_WIDE_INT new_size = INTVAL (size) / align * align;
- if (INTVAL (size) != new)
- size = GEN_INT (new);
+ if (INTVAL (size) != new_size)
+ size = GEN_INT (new_size);
}
else
{
diff --git a/gcc/expmed.c b/gcc/expmed.c
index bf045fee360..d5127b3c344 100644
--- a/gcc/expmed.c
+++ b/gcc/expmed.c
@@ -2050,7 +2050,7 @@ expand_shift (enum tree_code code, enum machine_mode mode, rtx shifted,
optab lrotate_optab = rotl_optab;
optab rrotate_optab = rotr_optab;
enum machine_mode op1_mode;
- int try;
+ int attempt;
op1 = expand_normal (amount);
op1_mode = GET_MODE (op1);
@@ -2105,13 +2105,13 @@ expand_shift (enum tree_code code, enum machine_mode mode, rtx shifted,
return shifted;
}
- for (try = 0; temp == 0 && try < 3; try++)
+ for (attempt = 0; temp == 0 && attempt < 3; attempt++)
{
enum optab_methods methods;
- if (try == 0)
+ if (attempt == 0)
methods = OPTAB_DIRECT;
- else if (try == 1)
+ else if (attempt == 1)
methods = OPTAB_WIDEN;
else
methods = OPTAB_LIB_WIDEN;
diff --git a/gcc/expr.c b/gcc/expr.c
index 33616d6900e..4984780fe32 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -1360,7 +1360,8 @@ emit_block_move_via_movmem (rtx x, rtx y, rtx size, unsigned int align,
pat = GEN_FCN ((int) code) (x, y, op2, opalign);
else
pat = GEN_FCN ((int) code) (x, y, op2, opalign,
- GEN_INT (expected_align),
+ GEN_INT (expected_align
+ / BITS_PER_UNIT),
GEN_INT (expected_size));
if (pat)
{
@@ -2780,7 +2781,8 @@ set_storage_via_setmem (rtx object, rtx size, rtx val, unsigned int align,
pat = GEN_FCN ((int) code) (object, opsize, opchar, opalign);
else
pat = GEN_FCN ((int) code) (object, opsize, opchar, opalign,
- GEN_INT (expected_align),
+ GEN_INT (expected_align
+ / BITS_PER_UNIT),
GEN_INT (expected_size));
if (pat)
{
@@ -6537,9 +6539,6 @@ safe_from_p (const_rtx x, tree exp, int top_p)
case tcc_type:
/* Should never get a type here. */
gcc_unreachable ();
-
- case tcc_gimple_stmt:
- gcc_unreachable ();
}
/* If we have an rtl, find any enclosed object. Then see if we conflict
@@ -7046,8 +7045,7 @@ expand_expr_real (tree exp, rtx target, enum machine_mode tmode,
/* Handle ERROR_MARK before anybody tries to access its type. */
if (TREE_CODE (exp) == ERROR_MARK
- || TREE_CODE (exp) == PREDICT_EXPR
- || (!GIMPLE_TUPLE_P (exp) && TREE_CODE (TREE_TYPE (exp)) == ERROR_MARK))
+ || (TREE_CODE (TREE_TYPE (exp)) == ERROR_MARK))
{
ret = CONST0_RTX (tmode);
return ret ? ret : const0_rtx;
@@ -7055,7 +7053,8 @@ expand_expr_real (tree exp, rtx target, enum machine_mode tmode,
if (flag_non_call_exceptions)
{
- rn = lookup_stmt_eh_region (exp);
+ rn = lookup_expr_eh_region (exp);
+
/* If rn < 0, then either (1) tree-ssa not used or (2) doesn't throw. */
if (rn >= 0)
last = get_last_insn ();
@@ -7129,18 +7128,9 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
type) \
: (expr))
- if (GIMPLE_STMT_P (exp))
- {
- type = void_type_node;
- mode = VOIDmode;
- unsignedp = 0;
- }
- else
- {
- type = TREE_TYPE (exp);
- mode = TYPE_MODE (type);
- unsignedp = TYPE_UNSIGNED (type);
- }
+ type = TREE_TYPE (exp);
+ mode = TYPE_MODE (type);
+ unsignedp = TYPE_UNSIGNED (type);
ignore = (target == const0_rtx
|| ((code == NOP_EXPR || code == CONVERT_EXPR
@@ -9088,16 +9078,6 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
tree lhs = TREE_OPERAND (exp, 0);
tree rhs = TREE_OPERAND (exp, 1);
gcc_assert (ignore);
- expand_assignment (lhs, rhs, false);
- return const0_rtx;
- }
-
- case GIMPLE_MODIFY_STMT:
- {
- tree lhs = GIMPLE_STMT_OPERAND (exp, 0);
- tree rhs = GIMPLE_STMT_OPERAND (exp, 1);
-
- gcc_assert (ignore);
/* Check for |= or &= of a bitfield of size one into another bitfield
of size 1. In this case, (unless we need the result of the
@@ -9356,17 +9336,8 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
case VEC_PACK_TRUNC_EXPR:
case VEC_PACK_SAT_EXPR:
case VEC_PACK_FIX_TRUNC_EXPR:
- {
- mode = TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0)));
- goto binop;
- }
-
- case OMP_ATOMIC_LOAD:
- case OMP_ATOMIC_STORE:
- /* OMP expansion is not run when there were errors, so these codes
- can get here. */
- gcc_assert (errorcount != 0);
- return NULL_RTX;
+ mode = TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0)));
+ goto binop;
default:
return lang_hooks.expand_expr (exp, original_target, tmode,
diff --git a/gcc/expr.h b/gcc/expr.h
index beb44bd80b7..39a51fcfe13 100644
--- a/gcc/expr.h
+++ b/gcc/expr.h
@@ -342,6 +342,9 @@ extern rtx emit_store_flag_force (rtx, enum rtx_code, rtx, rtx,
/* Functions from builtins.c: */
extern rtx expand_builtin (tree, rtx, rtx, enum machine_mode, int);
extern tree std_build_builtin_va_list (void);
+extern tree std_fn_abi_va_list (tree);
+extern tree std_canonical_va_list_type (tree);
+
extern void std_expand_builtin_va_start (tree, rtx);
extern rtx default_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
extern void expand_builtin_setjmp_setup (rtx, rtx);
diff --git a/gcc/final.c b/gcc/final.c
index cbdb3f1bfdd..787c43abad5 100644
--- a/gcc/final.c
+++ b/gcc/final.c
@@ -410,7 +410,7 @@ get_attr_length_1 (rtx insn ATTRIBUTE_UNUSED,
length = asm_insn_count (body) * fallback_fn (insn);
else if (GET_CODE (body) == SEQUENCE)
for (i = 0; i < XVECLEN (body, 0); i++)
- length += get_attr_length (XVECEXP (body, 0, i));
+ length += get_attr_length_1 (XVECEXP (body, 0, i), fallback_fn);
else
length = fallback_fn (insn);
break;
@@ -1377,20 +1377,20 @@ shorten_branches (rtx first ATTRIBUTE_UNUSED)
static int
asm_insn_count (rtx body)
{
- const char *template;
+ const char *templ;
int count = 1;
if (GET_CODE (body) == ASM_INPUT)
- template = XSTR (body, 0);
+ templ = XSTR (body, 0);
else
- template = decode_asm_operands (body, NULL, NULL, NULL, NULL, NULL);
+ templ = decode_asm_operands (body, NULL, NULL, NULL, NULL, NULL);
- if (!*template)
+ if (!*templ)
return 0;
- for (; *template; template++)
- if (IS_ASM_LOGICAL_LINE_SEPARATOR (*template, template)
- || *template == '\n')
+ for (; *templ; templ++)
+ if (IS_ASM_LOGICAL_LINE_SEPARATOR (*templ, templ)
+ || *templ == '\n')
count++;
return count;
@@ -2039,7 +2039,7 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
{
rtx body = PATTERN (insn);
int insn_code_number;
- const char *template;
+ const char *templ;
#ifdef HAVE_conditional_execution
/* Reset this early so it is correct for ASM statements. */
@@ -2556,12 +2556,12 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
#endif
/* Find the proper template for this insn. */
- template = get_insn_template (insn_code_number, insn);
+ templ = get_insn_template (insn_code_number, insn);
/* If the C code returns 0, it means that it is a jump insn
which follows a deleted test insn, and that test insn
needs to be reinserted. */
- if (template == 0)
+ if (templ == 0)
{
rtx prev;
@@ -2584,12 +2584,12 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
/* If the template is the string "#", it means that this insn must
be split. */
- if (template[0] == '#' && template[1] == '\0')
+ if (templ[0] == '#' && templ[1] == '\0')
{
- rtx new = try_split (body, insn, 0);
+ rtx new_rtx = try_split (body, insn, 0);
/* If we didn't split the insn, go away. */
- if (new == insn && PATTERN (new) == body)
+ if (new_rtx == insn && PATTERN (new_rtx) == body)
fatal_insn ("could not split insn", insn);
#ifdef HAVE_ATTR_length
@@ -2599,7 +2599,7 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
gcc_unreachable ();
#endif
- return new;
+ return new_rtx;
}
#ifdef TARGET_UNWIND_INFO
@@ -2610,7 +2610,7 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
#endif
/* Output assembler code from the template. */
- output_asm_insn (template, recog_data.operand);
+ output_asm_insn (templ, recog_data.operand);
/* If necessary, report the effect that the instruction has on
the unwind info. We've already done this for delay slots
@@ -2739,11 +2739,11 @@ alter_subreg (rtx *xp)
}
else
{
- rtx new = simplify_subreg (GET_MODE (x), y, GET_MODE (y),
+ rtx new_rtx = simplify_subreg (GET_MODE (x), y, GET_MODE (y),
SUBREG_BYTE (x));
- if (new != 0)
- *xp = new;
+ if (new_rtx != 0)
+ *xp = new_rtx;
else if (REG_P (y))
{
/* Simplify_subreg can't handle some REG cases, but we have to. */
@@ -3097,7 +3097,7 @@ output_asm_operand_names (rtx *operands, int *oporder, int nops)
of the operand, with no other punctuation. */
void
-output_asm_insn (const char *template, rtx *operands)
+output_asm_insn (const char *templ, rtx *operands)
{
const char *p;
int c;
@@ -3110,11 +3110,11 @@ output_asm_insn (const char *template, rtx *operands)
/* An insn may return a null string template
in a case where no assembler code is needed. */
- if (*template == 0)
+ if (*templ == 0)
return;
memset (opoutput, 0, sizeof opoutput);
- p = template;
+ p = templ;
putc ('\t', asm_out_file);
#ifdef ASM_OUTPUT_OPCODE
@@ -3344,6 +3344,14 @@ output_operand (rtx x, int code ATTRIBUTE_UNUSED)
gcc_assert (!x || !REG_P (x) || REGNO (x) < FIRST_PSEUDO_REGISTER);
PRINT_OPERAND (asm_out_file, x, code);
+ if (x && MEM_P (x) && GET_CODE (XEXP (x, 0)) == SYMBOL_REF)
+ {
+ tree t;
+ x = XEXP (x, 0);
+ t = SYMBOL_REF_DECL (x);
+ if (t)
+ assemble_external (t);
+ }
}
/* Print a memory reference operand for address X
diff --git a/gcc/flags.h b/gcc/flags.h
index 86392646b15..b5d22a8b23b 100644
--- a/gcc/flags.h
+++ b/gcc/flags.h
@@ -143,11 +143,6 @@ extern HOST_WIDE_INT larger_than_size;
extern bool warn_frame_larger_than;
extern HOST_WIDE_INT frame_larger_than_size;
-/* Temporarily suppress certain warnings.
- This is set while reading code from a system header file. */
-
-extern int in_system_header;
-
/* Nonzero for -dp: annotate the assembly with a comment describing the
pattern and alternative used. */
@@ -292,6 +287,13 @@ extern bool flag_speculative_prefetching_set;
instrumentation. */
extern bool flag_instrument_functions_exclude_p (tree fndecl);
+/* Emit warning if the function call is disallowed under
+ -Wdisallowed-function-list=... */
+extern void warn_if_disallowed_function_p (const_tree fncall);
+
+/* True, if the -Wdisallowed-function-list=... option has been specified. */
+extern bool warn_disallowed_functions;
+
/* True if the given mode has a NaN representation and the treatment of
NaN operands is important. Certain optimizations, such as folding
x * 0 into 0, are not correct for NaN operands, and are normally
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index fc72b9b38a2..f8085dc3709 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -65,6 +65,7 @@ along with GCC; see the file COPYING3. If not see
#include "hashtab.h"
#include "langhooks.h"
#include "md5.h"
+#include "gimple.h"
/* Nonzero if we are folding constants inside an initializer; zero
otherwise. */
@@ -949,7 +950,7 @@ fold_defer_overflow_warnings (void)
deferred code. */
void
-fold_undefer_overflow_warnings (bool issue, const_tree stmt, int code)
+fold_undefer_overflow_warnings (bool issue, const_gimple stmt, int code)
{
const char *warnmsg;
location_t locus;
@@ -971,7 +972,7 @@ fold_undefer_overflow_warnings (bool issue, const_tree stmt, int code)
if (!issue || warnmsg == NULL)
return;
- if (stmt != NULL_TREE && TREE_NO_WARNING (stmt))
+ if (gimple_no_warning_p (stmt))
return;
/* Use the smallest code level when deciding to issue the
@@ -982,10 +983,10 @@ fold_undefer_overflow_warnings (bool issue, const_tree stmt, int code)
if (!issue_strict_overflow_warning (code))
return;
- if (stmt == NULL_TREE || !expr_has_location (stmt))
+ if (stmt == NULL)
locus = input_location;
else
- locus = expr_location (stmt);
+ locus = gimple_location (stmt);
warning (OPT_Wstrict_overflow, "%H%s", &locus, warnmsg);
}
@@ -995,7 +996,7 @@ fold_undefer_overflow_warnings (bool issue, const_tree stmt, int code)
void
fold_undefer_and_ignore_overflow_warnings (void)
{
- fold_undefer_overflow_warnings (false, NULL_TREE, 0);
+ fold_undefer_overflow_warnings (false, NULL, 0);
}
/* Whether we are deferring overflow warnings. */
@@ -2396,7 +2397,8 @@ fold_convert_const (enum tree_code code, tree type, tree arg1)
if (TREE_TYPE (arg1) == type)
return arg1;
- if (POINTER_TYPE_P (type) || INTEGRAL_TYPE_P (type))
+ if (POINTER_TYPE_P (type) || INTEGRAL_TYPE_P (type)
+ || TREE_CODE (type) == OFFSET_TYPE)
{
if (TREE_CODE (arg1) == INTEGER_CST)
return fold_convert_const_int_from_int (type, arg1);
@@ -2638,7 +2640,7 @@ fold_convert (tree type, tree arg)
case VOID_TYPE:
tem = fold_ignored_result (arg);
- if (TREE_CODE (tem) == GIMPLE_MODIFY_STMT)
+ if (TREE_CODE (tem) == MODIFY_EXPR)
return tem;
return fold_build1 (NOP_EXPR, type, tem);
@@ -2681,7 +2683,6 @@ maybe_lvalue_p (const_tree x)
case WITH_CLEANUP_EXPR:
case COMPOUND_EXPR:
case MODIFY_EXPR:
- case GIMPLE_MODIFY_STMT:
case TARGET_EXPR:
case COND_EXPR:
case BIND_EXPR:
@@ -7846,17 +7847,16 @@ fold_unary (enum tree_code code, tree type, tree op0)
return fold_convert (type, fold_addr_expr (base));
}
- if ((TREE_CODE (op0) == MODIFY_EXPR
- || TREE_CODE (op0) == GIMPLE_MODIFY_STMT)
- && TREE_CONSTANT (GENERIC_TREE_OPERAND (op0, 1))
+ if (TREE_CODE (op0) == MODIFY_EXPR
+ && TREE_CONSTANT (TREE_OPERAND (op0, 1))
/* Detect assigning a bitfield. */
- && !(TREE_CODE (GENERIC_TREE_OPERAND (op0, 0)) == COMPONENT_REF
+ && !(TREE_CODE (TREE_OPERAND (op0, 0)) == COMPONENT_REF
&& DECL_BIT_FIELD
- (TREE_OPERAND (GENERIC_TREE_OPERAND (op0, 0), 1))))
+ (TREE_OPERAND (TREE_OPERAND (op0, 0), 1))))
{
/* Don't leave an assignment inside a conversion
unless assigning a bitfield. */
- tem = fold_build1 (code, type, GENERIC_TREE_OPERAND (op0, 1));
+ tem = fold_build1 (code, type, TREE_OPERAND (op0, 1));
/* First do the assignment, then return converted constant. */
tem = build2 (COMPOUND_EXPR, TREE_TYPE (tem), op0, tem);
TREE_NO_WARNING (tem) = 1;
@@ -9248,8 +9248,7 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
tree t1 = NULL_TREE;
bool strict_overflow_p;
- gcc_assert ((IS_EXPR_CODE_CLASS (kind)
- || IS_GIMPLE_STMT_CODE_CLASS (kind))
+ gcc_assert (IS_EXPR_CODE_CLASS (kind)
&& TREE_CODE_LENGTH (code) == 2
&& op0 != NULL_TREE
&& op1 != NULL_TREE);
@@ -13168,8 +13167,7 @@ fold (tree expr)
return expr;
}
- if (IS_EXPR_CODE_CLASS (kind)
- || IS_GIMPLE_STMT_CODE_CLASS (kind))
+ if (IS_EXPR_CODE_CLASS (kind))
{
tree type = TREE_TYPE (t);
tree op0, op1, op2;
@@ -14109,7 +14107,7 @@ tree_single_nonnegative_warnv_p (tree t, bool *strict_overflow_p)
*STRICT_OVERFLOW_P. */
bool
-tree_call_nonnegative_warnv_p (enum tree_code code, tree type, tree fndecl,
+tree_call_nonnegative_warnv_p (tree type, tree fndecl,
tree arg0, tree arg1, bool *strict_overflow_p)
{
if (fndecl && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
@@ -14230,7 +14228,7 @@ tree_call_nonnegative_warnv_p (enum tree_code code, tree type, tree fndecl,
default:
break;
}
- return tree_simple_nonnegative_warnv_p (code,
+ return tree_simple_nonnegative_warnv_p (CALL_EXPR,
type);
}
@@ -14272,10 +14270,9 @@ tree_invalid_nonnegative_warnv_p (tree t, bool *strict_overflow_p)
else
break;
}
- if ((TREE_CODE (t) == MODIFY_EXPR
- || TREE_CODE (t) == GIMPLE_MODIFY_STMT)
- && GENERIC_TREE_OPERAND (t, 0) == temp)
- return tree_expr_nonnegative_warnv_p (GENERIC_TREE_OPERAND (t, 1),
+ if (TREE_CODE (t) == MODIFY_EXPR
+ && TREE_OPERAND (t, 0) == temp)
+ return tree_expr_nonnegative_warnv_p (TREE_OPERAND (t, 1),
strict_overflow_p);
return false;
@@ -14286,8 +14283,7 @@ tree_invalid_nonnegative_warnv_p (tree t, bool *strict_overflow_p)
tree arg0 = call_expr_nargs (t) > 0 ? CALL_EXPR_ARG (t, 0) : NULL_TREE;
tree arg1 = call_expr_nargs (t) > 1 ? CALL_EXPR_ARG (t, 1) : NULL_TREE;
- return tree_call_nonnegative_warnv_p (TREE_CODE (t),
- TREE_TYPE (t),
+ return tree_call_nonnegative_warnv_p (TREE_TYPE (t),
get_callee_fndecl (t),
arg0,
arg1,
@@ -14295,8 +14291,7 @@ tree_invalid_nonnegative_warnv_p (tree t, bool *strict_overflow_p)
}
case COMPOUND_EXPR:
case MODIFY_EXPR:
- case GIMPLE_MODIFY_STMT:
- return tree_expr_nonnegative_warnv_p (GENERIC_TREE_OPERAND (t, 1),
+ return tree_expr_nonnegative_warnv_p (TREE_OPERAND (t, 1),
strict_overflow_p);
case BIND_EXPR:
return tree_expr_nonnegative_warnv_p (expr_last (TREE_OPERAND (t, 1)),
@@ -14671,9 +14666,8 @@ tree_expr_nonzero_warnv_p (tree t, bool *strict_overflow_p)
case COMPOUND_EXPR:
case MODIFY_EXPR:
- case GIMPLE_MODIFY_STMT:
case BIND_EXPR:
- return tree_expr_nonzero_warnv_p (GENERIC_TREE_OPERAND (t, 1),
+ return tree_expr_nonzero_warnv_p (TREE_OPERAND (t, 1),
strict_overflow_p);
case SAVE_EXPR:
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index 7b641f077ba..b2afedfce13 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,428 @@
+2008-07-28 Tobias Burnus <burnus@net-b.de>
+
+ * Make-lang.in: Remove -Wno-* from fortran-warn.
+
+2008-07-28 Richard Guenther <rguenther@suse.de>
+
+ Merge from gimple-tuples-branch.
+
+ 2008-07-18 Aldy Hernandez <aldyh@redhat.com>
+
+ * trans-expr.c: Include gimple.h instead of tree-gimple.h.
+ * trans-array.c: Same.
+ * trans-openmp.c: Same.
+ * trans-stmt.c: Same.
+ * f95-lang.c: Same.
+ * trans-io.c: Same.
+ * trans-decl.c: Same.
+ * trans-intrinsic.c: Same.
+ * trans.c: Same. Include tree-iterator.h.
+ * Make-lang.in (trans.o): Depend on tree-iterator.h
+
+ 2008-07-14 Aldy Hernandez <aldyh@redhat.com>
+
+ * trans-array.h (gfc_conv_descriptor_data_set_internal):
+ Rename to gfc_conv_descriptor_data_set.
+ (gfc_conv_descriptor_data_set_tuples): Remove.
+ * trans-array.c (gfc_conv_descriptor_data_get): Rename
+ from gfc_conv_descriptor_data_set_internal.
+ Remove last argument to gfc_add_modify.
+ (gfc_trans_allocate_array_storage): Rename gfc_add_modify_expr to
+ gfc_add_modify.
+ (gfc_trans_create_temp_array): Same.
+ (gfc_conv_array_transpose): Same.
+ (gfc_grow_array): Same.
+ (gfc_put_offset_into_var): Same.
+ (gfc_trans_array_ctor_element): Same.
+ (gfc_trans_array_constructor_subarray): Same.
+ (gfc_trans_array_constructor_value): Same.
+ (gfc_trans_scalarized_loop_end): Same.
+ (gfc_array_init_size): Same.
+ (gfc_array_allocate): Same.
+ (gfc_trans_array_bounds): Same.
+ (gfc_trans_auto_array_allocation): Same.
+ (gfc_trans_g77_array): Same.
+ (gfc_trans_dummy_array_bias): Same.
+ (gfc_conv_expr_descriptor): Same.
+ (structure_alloc_comps): Same.
+ * trans-expr.c: Same.
+ * trans-openmp.c (gfc_omp_clause_default_ctor): Same.
+ Rename gfc_conv_descriptor_data_set_tuples to
+ gfc_conv_descriptor_data_set.
+ (gfc_omp_clause_copy_ctor): Change build_gimple_modify_stmt to
+ build2_v.
+ (gfc_omp_clause_assign_op): Same.
+ (gfc_trans_omp_array_reduction): Rename gfc_add_modify_expr to
+ gfc_add_modify.
+ (gfc_trans_omp_atomic): Same.
+ (gfc_trans_omp_do): Same. Change GIMPLE_MODIFY_STMT to MODIFY_EXPR.
+ Rename gfc_add_modify_stmt to gfc_add_modify.
+ * trans-stmt.c: Rename gfc_add_modify_expr to
+ gfc_add_modify.
+ * trans.c: Rename gfc_add_modify_expr to
+ gfc_add_modify.
+ (gfc_add_modify): Remove last argument.
+ Rename GIMPLE_MODIFY_STMT to MODIFY_EXPR.
+ * trans.h: Remove gfc_add_modify_expr, gfc_add_modify_stmt.
+ Add prototype for gfc_add_modify.
+ * f95-lang.c (union lang_tree_node): Rename GENERIC_NEXT to TREE_CHAIN.
+ * trans-decl.c: Rename gfc_add_modify_stmt to gfc_add_modify.
+ * trans-io.c: Same.
+ * trans-intrinsic.c: Same.
+
+ 2008-02-25 Aldy Hernandez <aldyh@redhat.com>
+
+ * Make-lang.in (fortran-warn): Add -Wno-format.
+
+ 2008-02-19 Diego Novillo <dnovillo@google.com>
+
+ http://gcc.gnu.org/ml/gcc-patches/2008-02/msg00804.html
+
+ * fortran/Make-lang.in (fortran-warn): Remove.
+
+ 2007-11-22 Aldy Hernandez <aldyh@redhat.com>
+
+ * trans-expr.c (gfc_trans_string_copy): Use "void *" when building a
+ memset.
+
+ 2007-11-10 Aldy Hernandez <aldyh@redhat.com>
+
+ * Make-lang.in (fortran-warn): Set to -Wno-format.
+ * trans.c (gfc_trans_code): Update comment to say GENERIC.
+ Call tree_annotate_all_with_locus instead of annotate_all_with_locus.
+
+2008-07-27 Tobias Burnus <burnus@net-b.de>
+
+ PR fortran/36132
+ PR fortran/29952
+ PR fortran/36909
+ * trans.c (gfc_trans_runtime_check): Allow run-time warning besides
+ run-time error.
+ * trans.h (gfc_trans_runtime_check): Update declaration.
+ * trans-array.c (gfc_trans_array_ctor_element,gfc_trans_array_bound_check,
+ gfc_conv_array_ref,gfc_conv_ss_startstride,gfc_trans_dummy_array_bias):
+ Updated gfc_trans_runtime_check calls.
+ (gfc_conv_array_parameter): Implement flag_check_array_temporaries,
+ fix packing/unpacking for nonpresent optional actuals to optional
+ formals.
+ * trans-array.h (gfc_conv_array_parameter): Update declaration.
+ * trans-expr.c (gfc_conv_substring,gfc_trans_arrayfunc_assign,
+ gfc_conv_function_call): Updated gfc_trans_runtime_check calls.
+ (gfc_conv_function_call): Update gfc_conv_array_parameter calls.
+ * trans-expr.c (gfc_trans_goto): Updated gfc_trans_runtime_check
+ calls.
+ * trans-io.c (set_string,gfc_conv_intrinsic_repeat): Ditto.
+ (gfc_conv_intrinsic_transfer,gfc_conv_intrinsic_loc): Same for
+ gfc_conv_array_parameter.
+ * trans-intrinsics.c (gfc_conv_intrinsic_bound): Ditto.
+ * trans-decl.c (gfc_build_builtin_function_decls): Add
+ gfor_fndecl_runtime_warning_at.
+ * lang.opt: New option fcheck-array-temporaries.
+ * gfortran.h (gfc_options): New flag_check_array_temporaries.
+ * options.c (gfc_init_options, gfc_handle_option): Handle flag.
+ * invoke.texi: New option fcheck-array-temporaries.
+
+2008-07-24 Jan Hubicka <jh@suse.cz>
+
+ * fortran/options.c (gfc_post_options): Remove flag_unline_trees code.
+
+2008-07-24 Daniel Kraft <d@domob.eu>
+
+ PR fortran/33141
+ * lang.opt (Wnonstd-intrinsics): Removed option.
+ (Wintrinsics-std), (Wintrinsic-shadow): New options.
+ * invoke.texi (Option Summary): Removed -Wnonstd-intrinsics
+ from the list and added -Wintrinsics-std and -Wintrinsic-shadow.
+ (Error and Warning Options): Documented the new options and removed
+ the documentation for -Wnonstd-intrinsics.
+ * gfortran.h (gfc_option_t): New members warn_intrinsic_shadow and
+ warn_intrinsics_std, removed warn_nonstd_intrinsics.
+ (gfc_is_intrinsic): Renamed from gfc_intrinsic_name.
+ (gfc_warn_intrinsic_shadow), (gfc_check_intrinsic_standard): New.
+ * decl.c (match_procedure_decl): Replaced gfc_intrinsic_name by
+ the new name gfc_is_intrinsic.
+ (warn_intrinsic_shadow): New helper method.
+ (gfc_match_function_decl), (gfc_match_subroutine): Call the new method
+ warn_intrinsic_shadow to check the just-parsed procedure.
+ * expr.c (check_init_expr): Call new gfc_is_intrinsic to check whether
+ the function called is really an intrinsic in the selected standard.
+ * intrinsic.c (gfc_is_intrinsic): Renamed from gfc_intrinsic_name and
+ extended to take into account the selected standard settings when trying
+ to find out whether a symbol is an intrinsic or not.
+ (gfc_check_intrinsic_standard): Made public and extended.
+ (gfc_intrinsic_func_interface), (gfc_intrinsic_sub_interface): Removed
+ the calls to check_intrinsic_standard, this check now happens inside
+ gfc_is_intrinsic.
+ (gfc_warn_intrinsic_shadow): New method defined.
+ * options.c (gfc_init_options): Initialize new warning flags to false
+ and removed intialization of Wnonstd-intrinsics flag.
+ (gfc_post_options): Removed logic for Wnonstd-intrinsics flag.
+ (set_Wall): Set new warning flags and removed Wnonstd-intrinsics flag.
+ (gfc_handle_option): Handle the new flags and removed handling of the
+ old Wnonstd-intrinsics flag.
+ * primary.c (gfc_match_rvalue): Replaced call to gfc_intrinsic_name by
+ the new name gfc_is_intrinsic.
+ * resolve.c (resolve_actual_arglist): Ditto.
+ (resolve_generic_f), (resolve_unknown_f): Ditto.
+ (is_external_proc): Ditto.
+ (resolve_generic_s), (resolve_unknown_s): Ditto.
+ (resolve_symbol): Ditto and ensure for symbols declared INTRINSIC that
+ they are really available in the selected standard setting.
+
+2008-07-24 Daniel Kraft <d@domob.eu>
+
+ * match.c (gfc_match): Add assertion to catch wrong calls trying to
+ match upper-case characters.
+
+2008-07-24 Thomas Koenig <tkoenig@gcc.gnu.org>
+
+ PR fortran/29952
+ * gfortran.h: Add "warn_array_temp" to gfc_option_t.
+ * lang.opt: Add -Warray-temporaries.
+ * invoke.texi: Document -Warray-temporaries
+ * trans-array.h (gfc_trans_create_temp_array): Add argument of
+ type *locus.
+ (gfc_conv_loop_setup): Likewise.
+ * trans-array.c (gfc_trans_create_temp_array): If
+ -Warray-temporaries is given and locus is present, warn about
+ creation of array temporaries.
+ (gfc_trans_array_constructor_subarray): Add locus to call
+ of gfc_conv_loop_setup.
+ (gfc_trans_array_constructor): Add where argument. Pass where
+ argument to call of gfc_trans_create_temp_array.
+ (gfc_add_loop_ss_code): Add where argument. Pass where argument
+ to recursive call of gfc_add_loop_ss_code and to call of
+ gfc_trans_array_constructor.
+ (gfc_conv_loop_setup): Add where argument. Pass where argument
+ to calls to gfc_add_loop_ss_code and to gfc_trans_create_temp_array.
+ (gfc_conv_expr_descriptor): Pass location to call of
+ gfc_conv_loop_setup.
+ (gfc_conv_array_parameter): If -Warray-temporaries is given,
+ warn about creation of temporary arrays.
+ * trans-expr.c (gfc_conv_subref_array_arg): Add where argument
+ to call to gfc_conv_loop_setup.
+ (gfc_conv_function_call): Add where argument to call to
+ gfc_trans_creat_temp_array.
+ (gfc_trans_subarray_assign): Likewise.
+ (gfc_trans_assignment_1): Add where argument to call to
+ gfc_conv_loop_setup.
+ * trans-stmt.c (gfc_conv_elemental_dependencies): Add where
+ argument to call to gfc_trans_create_temp_array.
+ (gfc_trans_call): Add where argument to call to gfc_conv_loop_setup.
+ (generate_loop_for_temp_to_lhs): Likewise.
+ (generate_loop_for_rhs_to_temp): Likewise.
+ (compute_inner_temp_size): Likewise.
+ (gfc_trans-pointer_assign_need_temp): Likewise.
+ (gfc_evaluate_where_mask): Likewise.
+ (gfc_trans_where_assign): Likewise.
+ (gfc_trans_where_3): Likewise.
+ * trans-io.c (transfer_srray_component): Add where argument
+ to function. Add where argument to call to gfc_conv_loop_setup.
+ (transfer_expr): Add where argument to call to
+ transfer_array_component.
+ (gfc_trans_transfer): Add where expression to call to
+ gfc_conv_loop_setup.
+ * trans-intrinsic.c (gfc_conv_intrinsic_anyall): Add
+ where argument to call to gfc_conv_loop_setup.
+ (gfc_conv_intrinsic_count): Likewise.
+ (gfc_conv_intrinsic_arith): Likewise.
+ (gfc_conv_intrinsic_dot_product): Likewise.
+ (gfc_conv_intrinsic_minmaxloc): Likewise.
+ (gfc_conv_intrinsic_minmaxval): Likewise.
+ (gfc_conv_intrinsic_array_transfer): Warn about
+ creation of temporary array.
+ Add where argument to call to gfc_trans_create_temp_array.
+ * options.c (gfc_init_options): Initialize gfc_option.warn_array_temp.
+ (gfc_handle_option): Set gfc_option.warn_array_temp.
+
+2008-07-23 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
+
+ PR 35058
+ * f95-lang.c (gfc_mark_addressable): All calls to pedwarn changed.
+
+2008-07-22 Daniel Kraft <d@domob.eu>
+
+ PR fortran/29835
+ * io.c (error_element), (format_locus): New static globals.
+ (unexpected_element): Spelled out this message fully.
+ (next_char): Keep track of locus when not MODE_STRING.
+ (next_char_not_space): Remember last parsed element in error_element.
+ (format_lex): Fix two indentation errors.
+ (check_format): Use format_locus and possibly error_element for a
+ slightly better error message on invalid format.
+ (check_format_string): Set format_locus to start of the string
+ expression used as format.
+
+2008-07-21 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
+
+ * expr.c (gfc_check_pointer_assign): Fix typo in string.
+ * io.c (check_format): Fix typo in string. Fix comment typos.
+ * parse.c (gfc_global_used): Likewise.
+ * resolve.c (resolve_allocate_expr): Likewise.
+ * symbol.c (gfc_set_default_type): Likewise.
+ * arith.c: Fix typos in comments.
+ * array.c: Likewise.
+ * data.c: Likewise.
+ * decl.c: Likewise.
+ * dependency.c: Likewise.
+ * f95-lang.c: Likewise.
+ * gfortran.h: Likewise.
+ * matchexp.c: Likewise.
+ * module.c: Likewise.
+ * primary.c: Likewise.
+ * scanner.c: Likewise.
+ * trans-array.c: Likewise.
+ * trans-common.c: Likewise.
+ * trans-decl.c: Likewise.
+ * trans-expr.c: Likewise.
+ * trans-intrinsic.c: Likewise.
+ * trans-types.c: Likewise.
+ * trans.c: Likewise.
+ * trans.h: Likewise.
+
+2008-07-19 Tobias Burnus <burnus@net-b.de>
+
+ PR fortran/36795
+ * matchexp.c (gfc_get_parentheses): Remove obsolete workaround,
+ which caused the generation of wrong code.
+
+2008-07-19 Tobias Burnus <burnus@net-b.de>
+
+ PR fortran/36342
+ * scanner.c (load_file): Add argument to destinguish between
+ true filename and displayed filename.
+ (include_line,gfc_new_file): Adapt accordingly.
+
+2008-07-19 Tobias Burnus <burnus@net-b.de>
+
+ * check.c (gfc_check_cshift,gfc_check_eoshift,gfc_check_unpack): Add rank
+ checks for cshift's shift and eoshift's shift and boundary args.
+ (gfc_check_unpack): Add rank and shape tests for unpack.
+
+2008-07-19 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * gfortran.h (new): Remove macro.
+ * array.c (gfc_append_constructor, match_array_list,
+ gfc_match_array_constructor): Likewise.
+ * bbt.c (insert, gfc_insert_bbt): Likewise.
+ * decl.c (var_element, top_var_list, top_val_list, gfc_match_data,
+ get_proc_name): Likewise.
+ * expr.c (gfc_copy_actual_arglist): Likewise.
+ * interface.c (compare_actual_formal, check_new_interface,
+ gfc_add_interface): Likewise.
+ * intrinsic.c gfc_convert_type_warn, gfc_convert_chartype):
+ Likewise.
+ * io.c (match_io_iterator, match_io_list): Likewise.
+ * match.c (match_forall_header): Likewise.
+ * matchexp.c (build_node): Likewise.
+ * module.c (gfc_match_use): Likewise.
+ * scanner.c (load_file): Likewise.
+ * st.c (gfc_append_code): Likewise.
+ * symbol.c (save_symbol_data, gfc_get_sym_tree, gfc_undo_symbols,
+ gfc_commit_symbols): Likewise.
+ * trans-common.c (build_field): Likewise.
+ * trans-decl.c (gfc_finish_var_decl): Likewise.
+ * trans-expr.c (gfc_free_interface_mapping,
+ gfc_get_interface_mapping_charlen, gfc_add_interface_mapping,
+ gfc_finish_interface_mapping,
+ gfc_apply_interface_mapping_to_expr): Likewise.
+ * trans.h (gfc_interface_sym_mapping): Likewise.
+
+2008-07-19 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * gfortran.h (operator): Remove macro.
+ (gfc_namespace, gfc_expr): Avoid C++ keywords.
+ * arith.c (eval_intrinsic, eval_intrinsic_f2, eval_intrinsic_f3):
+ Likewise.
+ * decl.c (access_attr_decl): Likewise.
+ * dependency.c (gfc_dep_compare_expr): Likewise.
+ * dump-parse-tree.c (show_expr, show_uop, show_namespace):
+ Likewise.
+ * expr.c (gfc_copy_expr, gfc_type_convert_binary,
+ simplify_intrinsic_op, check_intrinsic_op): Likewise.
+ * interface.c (fold_unary, gfc_match_generic_spec,
+ gfc_match_interface, gfc_match_end_interface,
+ check_operator_interface, check_uop_interfaces,
+ gfc_check_interfaces, gfc_extend_expr, gfc_extend_assign,
+ gfc_add_interface, gfc_current_interface_head,
+ gfc_set_current_interface_head): Likewise.
+ * iresolve.c (gfc_resolve_dot_product, gfc_resolve_matmul):
+ Likewise.
+ * matchexp.c (gfc_get_parentheses, build_node): Likewise.
+ * module.c (gfc_use_rename, gfc_match_use, find_use_name_n,
+ number_use_names, mio_expr, load_operator_interfaces, read_module,
+ write_operator, write_module): Likewise.
+ * openmp.c (resolve_omp_atomic): Likewise.
+ * resolve.c (resolve_operator, gfc_resolve_character_operator,
+ gfc_resolve_uops): Likewise.
+ * symbol.c (free_uop_tree, gfc_free_namespace): Likewise.
+ * trans-expr.c (gfc_conv_expr_op): Likewise.
+ * trans-openmp.c (gfc_trans_omp_atomic): Likewise.
+
+2008-07-19 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * gfortran.h (protected): Remove macro.
+ * dump-parse-tree.c (show_attr): Avoid C++ keywords.
+ * expr.c (gfc_check_pointer_assign): Likewise.
+ * interface.c (compare_parameter_protected): Likewise.
+ * intrinsic.c (enum class, add_sym, add_sym_0, add_sym_1,
+ add_sym_1s, add_sym_1m, add_sym_2, add_sym_2s, add_sym_3,
+ add_sym_3ml, add_sym_3red, add_sym_3s, add_sym_4, add_sym_4s,
+ add_sym_5s): Likewise.
+ * match.c (gfc_match_assignment, gfc_match_pointer_assignment):
+ Likewise.
+ * module.c (mio_symbol_attribute): Likewise.
+ * primary.c (match_variable): Likewise.
+ * resolve.c (resolve_equivalence): Likewise.
+ * symbol.c (check_conflict, gfc_add_protected, gfc_copy_attr):
+ Likewise.
+ * trans-types.c (gfc_get_array_type_bounds): Likewise.
+
+2008-07-18 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * arith.c (eval_type_intrinsic0): Avoid C++ keywords.
+ * gfortran.h (try, protected, operator, new): Likewise.
+
+2008-07-17 Tobias Burnus <burnus@net-b.de>
+
+ PR fortran/36825
+ PR fortran/36824
+ * array.c (gfc_match_array_spec): Fix array-rank check.
+ * resolve.c (resolve_fl_derived): Fix constentness check
+ for the array dimensions.
+
+2008-07-14 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
+
+ * Make-lang.in (gfortranspec.o): Fix dependencies.
+
+2008-07-13 Jerry DeLisle <jvdelisle@gcc.gnu.org>
+
+ PR fortran/36725
+ * io.c: Add error check for g0 edit descriptor followed by '.'.
+
+2008-07-12 Daniel Kraft <d@domob.eu>
+
+ * resolve.c (resolve_fl_derived): Allow pointer components to empty
+ derived types fixing a missing part of PR fortran/33221.
+
+2008-07-10 Daniel Kraft <d@domob.eu>
+
+ * gfc-internals.texi (section gfc_expr): Created documentation about
+ the gfc_expr internal data structure.
+
+2008-07-07 Thomas Koenig <tkoenig@gcc.gnu.org>
+
+ PR fortran/36670
+ * iresolve.c (gfc_resolve_product): Set shape of return
+ value from array.
+ (gfc_resolve_sum): Likewise.
+
+2008-07-07 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/36726
+ * f95-lang.c (poplevel): Don't ever add subblocks to
+ global_binding_level.
+
2008-07-02 Janus Weil <janus@gcc.gnu.org>
Tobias Burnus <burnus@net-b.de>
Paul Thomas <pault@gcc.gnu.org>
diff --git a/gcc/fortran/Make-lang.in b/gcc/fortran/Make-lang.in
index 6acdbbefd7b..20ac249057d 100644
--- a/gcc/fortran/Make-lang.in
+++ b/gcc/fortran/Make-lang.in
@@ -77,7 +77,8 @@ fortran: f951$(exeext)
# Tell GNU make to ignore files by these names if they exist.
.PHONY: fortran
-gfortranspec.o: $(srcdir)/fortran/gfortranspec.c $(SYSTEM_H) $(TM_H) $(GCC_H) $(CONFIG_H)
+gfortranspec.o: $(srcdir)/fortran/gfortranspec.c $(SYSTEM_H) $(TM_H) $(GCC_H) \
+ $(CONFIG_H) coretypes.h intl.h
(SHLIB_LINK='$(SHLIB_LINK)'; \
$(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(DRIVER_DEFINES) \
$(INCLUDES) $(srcdir)/fortran/gfortranspec.c)
@@ -310,9 +311,9 @@ fortran/f95-lang.o: $(GFORTRAN_TRANS_DEPS) fortran/mathbuiltins.def \
$(BUILTINS_DEF) fortran/types.def
fortran/scanner.o: toplev.h fortran/cpp.h
fortran/convert.o: $(GFORTRAN_TRANS_DEPS)
-fortran/trans.o: $(GFORTRAN_TRANS_DEPS)
+fortran/trans.o: $(GFORTRAN_TRANS_DEPS) tree-iterator.h
fortran/trans-decl.o: $(GFORTRAN_TRANS_DEPS) gt-fortran-trans-decl.h \
- $(CGRAPH_H) $(TARGET_H) $(FUNCTION_H) $(FLAGS_H) $(RTL_H) $(TREE_GIMPLE_H) \
+ $(CGRAPH_H) $(TARGET_H) $(FUNCTION_H) $(FLAGS_H) $(RTL_H) $(GIMPLE_H) \
$(TREE_DUMP_H)
fortran/trans-types.o: $(GFORTRAN_TRANS_DEPS) gt-fortran-trans-types.h \
$(REAL_H) toplev.h $(TARGET_H) $(FLAGS_H) dwarf2out.h
diff --git a/gcc/fortran/arith.c b/gcc/fortran/arith.c
index bd3214584dd..2e21b840e2a 100644
--- a/gcc/fortran/arith.c
+++ b/gcc/fortran/arith.c
@@ -1092,7 +1092,7 @@ gfc_arith_concat (gfc_expr *op1, gfc_expr *op2, gfc_expr **resultp)
}
/* Comparison between real values; returns 0 if (op1 .op. op2) is true.
- This function mimics mpr_cmp but takes NaN into account. */
+ This function mimics mpfr_cmp but takes NaN into account. */
static int
compare_real (gfc_expr *op1, gfc_expr *op2, gfc_intrinsic_op op)
@@ -1159,7 +1159,7 @@ gfc_compare_expr (gfc_expr *op1, gfc_expr *op2, gfc_intrinsic_op op)
/* Compare a pair of complex numbers. Naturally, this is only for
- equality and nonequality. */
+ equality and inequality. */
static int
compare_complex (gfc_expr *op1, gfc_expr *op2)
@@ -1552,7 +1552,7 @@ eval_f;
operands are array constructors. */
static gfc_expr *
-eval_intrinsic (gfc_intrinsic_op operator,
+eval_intrinsic (gfc_intrinsic_op op,
eval_f eval, gfc_expr *op1, gfc_expr *op2)
{
gfc_expr temp, *result;
@@ -1561,7 +1561,7 @@ eval_intrinsic (gfc_intrinsic_op operator,
gfc_clear_ts (&temp.ts);
- switch (operator)
+ switch (op)
{
/* Logical unary */
case INTRINSIC_NOT:
@@ -1650,19 +1650,19 @@ eval_intrinsic (gfc_intrinsic_op operator,
temp.expr_type = EXPR_OP;
gfc_clear_ts (&temp.ts);
- temp.value.op.operator = operator;
+ temp.value.op.op = op;
temp.value.op.op1 = op1;
temp.value.op.op2 = op2;
gfc_type_convert_binary (&temp);
- if (operator == INTRINSIC_EQ || operator == INTRINSIC_NE
- || operator == INTRINSIC_GE || operator == INTRINSIC_GT
- || operator == INTRINSIC_LE || operator == INTRINSIC_LT
- || operator == INTRINSIC_EQ_OS || operator == INTRINSIC_NE_OS
- || operator == INTRINSIC_GE_OS || operator == INTRINSIC_GT_OS
- || operator == INTRINSIC_LE_OS || operator == INTRINSIC_LT_OS)
+ if (op == INTRINSIC_EQ || op == INTRINSIC_NE
+ || op == INTRINSIC_GE || op == INTRINSIC_GT
+ || op == INTRINSIC_LE || op == INTRINSIC_LT
+ || op == INTRINSIC_EQ_OS || op == INTRINSIC_NE_OS
+ || op == INTRINSIC_GE_OS || op == INTRINSIC_GT_OS
+ || op == INTRINSIC_LE_OS || op == INTRINSIC_LT_OS)
{
temp.ts.type = BT_LOGICAL;
temp.ts.kind = gfc_default_logical_kind;
@@ -1690,7 +1690,7 @@ eval_intrinsic (gfc_intrinsic_op operator,
}
/* Try to combine the operators. */
- if (operator == INTRINSIC_POWER && op2->ts.type != BT_INTEGER)
+ if (op == INTRINSIC_POWER && op2->ts.type != BT_INTEGER)
goto runtime;
if (op1->expr_type != EXPR_CONSTANT
@@ -1725,7 +1725,7 @@ runtime:
result->ts = temp.ts;
result->expr_type = EXPR_OP;
- result->value.op.operator = operator;
+ result->value.op.op = op;
result->value.op.op1 = op1;
result->value.op.op2 = op2;
@@ -1739,12 +1739,12 @@ runtime:
/* Modify type of expression for zero size array. */
static gfc_expr *
-eval_type_intrinsic0 (gfc_intrinsic_op operator, gfc_expr *op)
+eval_type_intrinsic0 (gfc_intrinsic_op iop, gfc_expr *op)
{
if (op == NULL)
gfc_internal_error ("eval_type_intrinsic0(): op NULL");
- switch (operator)
+ switch (iop)
{
case INTRINSIC_GE:
case INTRINSIC_GE_OS:
@@ -1806,7 +1806,7 @@ reduce_binary0 (gfc_expr *op1, gfc_expr *op2)
static gfc_expr *
-eval_intrinsic_f2 (gfc_intrinsic_op operator,
+eval_intrinsic_f2 (gfc_intrinsic_op op,
arith (*eval) (gfc_expr *, gfc_expr **),
gfc_expr *op1, gfc_expr *op2)
{
@@ -1816,22 +1816,22 @@ eval_intrinsic_f2 (gfc_intrinsic_op operator,
if (op2 == NULL)
{
if (gfc_zero_size_array (op1))
- return eval_type_intrinsic0 (operator, op1);
+ return eval_type_intrinsic0 (op, op1);
}
else
{
result = reduce_binary0 (op1, op2);
if (result != NULL)
- return eval_type_intrinsic0 (operator, result);
+ return eval_type_intrinsic0 (op, result);
}
f.f2 = eval;
- return eval_intrinsic (operator, f, op1, op2);
+ return eval_intrinsic (op, f, op1, op2);
}
static gfc_expr *
-eval_intrinsic_f3 (gfc_intrinsic_op operator,
+eval_intrinsic_f3 (gfc_intrinsic_op op,
arith (*eval) (gfc_expr *, gfc_expr *, gfc_expr **),
gfc_expr *op1, gfc_expr *op2)
{
@@ -1840,10 +1840,10 @@ eval_intrinsic_f3 (gfc_intrinsic_op operator,
result = reduce_binary0 (op1, op2);
if (result != NULL)
- return eval_type_intrinsic0(operator, result);
+ return eval_type_intrinsic0(op, result);
f.f3 = eval;
- return eval_intrinsic (operator, f, op1, op2);
+ return eval_intrinsic (op, f, op1, op2);
}
@@ -2084,7 +2084,7 @@ arith_error (arith rc, gfc_typespec *from, gfc_typespec *to, locus *where)
gfc_internal_error ("gfc_arith_error(): Bad error code");
}
- /* TODO: Do something about the error, ie, throw exception, return
+ /* TODO: Do something about the error, i.e., throw exception, return
NaN, etc. */
}
diff --git a/gcc/fortran/array.c b/gcc/fortran/array.c
index c6bb5e857b9..7216d1f472e 100644
--- a/gcc/fortran/array.c
+++ b/gcc/fortran/array.c
@@ -437,7 +437,7 @@ gfc_match_array_spec (gfc_array_spec **asp)
goto cleanup;
}
- if (as->rank > 7
+ if (as->rank >= 7
&& gfc_notify_std (GFC_STD_F2008, "Fortran 2008: Array "
"specification at %C with more than 7 dimensions")
== FAILURE)
@@ -592,7 +592,7 @@ gfc_start_constructor (bt type, int kind, locus *where)
node onto the constructor. */
void
-gfc_append_constructor (gfc_expr *base, gfc_expr *new)
+gfc_append_constructor (gfc_expr *base, gfc_expr *new_expr)
{
gfc_constructor *c;
@@ -608,9 +608,9 @@ gfc_append_constructor (gfc_expr *base, gfc_expr *new)
c = c->next;
}
- c->expr = new;
+ c->expr = new_expr;
- if (new->ts.type != base->ts.type || new->ts.kind != base->ts.kind)
+ if (new_expr->ts.type != base->ts.type || new_expr->ts.kind != base->ts.kind)
gfc_internal_error ("gfc_append_constructor(): New node has wrong kind");
}
@@ -755,7 +755,7 @@ static match match_array_cons_element (gfc_constructor **);
static match
match_array_list (gfc_constructor **result)
{
- gfc_constructor *p, *head, *tail, *new;
+ gfc_constructor *p, *head, *tail, *new_cons;
gfc_iterator iter;
locus old_loc;
gfc_expr *e;
@@ -790,7 +790,7 @@ match_array_list (gfc_constructor **result)
if (m == MATCH_ERROR)
goto cleanup;
- m = match_array_cons_element (&new);
+ m = match_array_cons_element (&new_cons);
if (m == MATCH_ERROR)
goto cleanup;
if (m == MATCH_NO)
@@ -801,8 +801,8 @@ match_array_list (gfc_constructor **result)
goto cleanup; /* Could be a complex constant */
}
- tail->next = new;
- tail = new;
+ tail->next = new_cons;
+ tail = new_cons;
if (gfc_match_char (',') != MATCH_YES)
{
@@ -881,7 +881,7 @@ match_array_cons_element (gfc_constructor **result)
match
gfc_match_array_constructor (gfc_expr **result)
{
- gfc_constructor *head, *tail, *new;
+ gfc_constructor *head, *tail, *new_cons;
gfc_expr *expr;
gfc_typespec ts;
locus where;
@@ -937,18 +937,18 @@ gfc_match_array_constructor (gfc_expr **result)
for (;;)
{
- m = match_array_cons_element (&new);
+ m = match_array_cons_element (&new_cons);
if (m == MATCH_ERROR)
goto cleanup;
if (m == MATCH_NO)
goto syntax;
if (head == NULL)
- head = new;
+ head = new_cons;
else
- tail->next = new;
+ tail->next = new_cons;
- tail = new;
+ tail = new_cons;
if (gfc_match_char (',') == MATCH_NO)
break;
@@ -1577,7 +1577,7 @@ resolve_array_list (gfc_constructor *p)
}
/* Resolve character array constructor. If it has a specified constant character
- length, pad/trunkate the elements here; if the length is not specified and
+ length, pad/truncate the elements here; if the length is not specified and
all elements are of compile-time known length, emit an error as this is
invalid. */
@@ -1675,7 +1675,7 @@ got_charlen:
max_length only if they pass. */
gfc_extract_int (expr->ts.cl->length, &found_length);
- /* Now pad/trunkate the elements accordingly to the specified character
+ /* Now pad/truncate the elements accordingly to the specified character
length. This is ok inside this conditional, as in the case above
(without typespec) all elements are verified to have the same length
anyway. */
diff --git a/gcc/fortran/bbt.c b/gcc/fortran/bbt.c
index e89eb57fd8d..fa60e4fee22 100644
--- a/gcc/fortran/bbt.c
+++ b/gcc/fortran/bbt.c
@@ -93,24 +93,24 @@ rotate_right (gfc_bbt *t)
aborts if we find a duplicate key. */
static gfc_bbt *
-insert (gfc_bbt *new, gfc_bbt *t, compare_fn compare)
+insert (gfc_bbt *new_bbt, gfc_bbt *t, compare_fn compare)
{
int c;
if (t == NULL)
- return new;
+ return new_bbt;
- c = (*compare) (new, t);
+ c = (*compare) (new_bbt, t);
if (c < 0)
{
- t->left = insert (new, t->left, compare);
+ t->left = insert (new_bbt, t->left, compare);
if (t->priority < t->left->priority)
t = rotate_right (t);
}
else if (c > 0)
{
- t->right = insert (new, t->right, compare);
+ t->right = insert (new_bbt, t->right, compare);
if (t->priority < t->right->priority)
t = rotate_left (t);
}
@@ -126,12 +126,12 @@ insert (gfc_bbt *new, gfc_bbt *t, compare_fn compare)
already exists. */
void
-gfc_insert_bbt (void *root, void *new, compare_fn compare)
+gfc_insert_bbt (void *root, void *new_node, compare_fn compare)
{
gfc_bbt **r, *n;
r = (gfc_bbt **) root;
- n = (gfc_bbt *) new;
+ n = (gfc_bbt *) new_node;
n->priority = pseudo_random ();
*r = insert (n, *r, compare);
}
diff --git a/gcc/fortran/check.c b/gcc/fortran/check.c
index c0f9891bd98..4132d83a785 100644
--- a/gcc/fortran/check.c
+++ b/gcc/fortran/check.c
@@ -876,11 +876,16 @@ gfc_check_cshift (gfc_expr *array, gfc_expr *shift, gfc_expr *dim)
if (scalar_check (shift, 1) == FAILURE)
return FAILURE;
}
- else
+ else if (shift->rank != array->rank - 1 && shift->rank != 0)
{
- /* TODO: more requirements on shift parameter. */
+ gfc_error ("SHIFT argument at %L of CSHIFT must have rank %d or be a "
+ "scalar", &shift->where, array->rank - 1);
+ return FAILURE;
}
+ /* TODO: Add shape conformance check between array (w/o dimension dim)
+ and shift. */
+
if (dim_check (dim, 2, true) == FAILURE)
return FAILURE;
@@ -1037,17 +1042,45 @@ gfc_check_eoshift (gfc_expr *array, gfc_expr *shift, gfc_expr *boundary,
if (scalar_check (shift, 2) == FAILURE)
return FAILURE;
}
- else
+ else if (shift->rank != array->rank - 1 && shift->rank != 0)
{
- /* TODO: more weird restrictions on shift. */
+ gfc_error ("SHIFT argument at %L of EOSHIFT must have rank %d or be a "
+ "scalar", &shift->where, array->rank - 1);
+ return FAILURE;
}
+ /* TODO: Add shape conformance check between array (w/o dimension dim)
+ and shift. */
+
if (boundary != NULL)
{
if (same_type_check (array, 0, boundary, 2) == FAILURE)
return FAILURE;
- /* TODO: more restrictions on boundary. */
+ if (array->rank == 1)
+ {
+ if (scalar_check (boundary, 2) == FAILURE)
+ return FAILURE;
+ }
+ else if (boundary->rank != array->rank - 1 && boundary->rank != 0)
+ {
+ gfc_error ("BOUNDARY argument at %L of EOSHIFT must have rank %d or be "
+ "a scalar", &boundary->where, array->rank - 1);
+ return FAILURE;
+ }
+
+ if (shift->rank == boundary->rank)
+ {
+ int i;
+ for (i = 0; i < shift->rank; i++)
+ if (! identical_dimen_shape (shift, i, boundary, i))
+ {
+ gfc_error ("Different shape in dimension %d for SHIFT and "
+ "BOUNDARY arguments of EOSHIFT at %L", shift->rank,
+ &boundary->where);
+ return FAILURE;
+ }
+ }
}
if (dim_check (dim, 4, true) == FAILURE)
@@ -2886,6 +2919,25 @@ gfc_check_unpack (gfc_expr *vector, gfc_expr *mask, gfc_expr *field)
if (same_type_check (vector, 0, field, 2) == FAILURE)
return FAILURE;
+ if (mask->rank != field->rank && field->rank != 0)
+ {
+ gfc_error ("FIELD argument at %L of UNPACK must have the same rank as "
+ "MASK or be a scalar", &field->where);
+ return FAILURE;
+ }
+
+ if (mask->rank == field->rank)
+ {
+ int i;
+ for (i = 0; i < field->rank; i++)
+ if (! identical_dimen_shape (mask, i, field, i))
+ {
+ gfc_error ("Different shape in dimension %d for MASK and FIELD "
+ "arguments of UNPACK at %L", mask->rank, &field->where);
+ return FAILURE;
+ }
+ }
+
return SUCCESS;
}
diff --git a/gcc/fortran/data.c b/gcc/fortran/data.c
index 6cc7223af2f..bda448a8f56 100644
--- a/gcc/fortran/data.c
+++ b/gcc/fortran/data.c
@@ -23,7 +23,7 @@ along with GCC; see the file COPYING3. If not see
/* Notes for DATA statement implementation:
We first assign initial value to each symbol by gfc_assign_data_value
- during resolveing DATA statement. Refer to check_data_variable and
+ during resolving DATA statement. Refer to check_data_variable and
traverse_data_list in resolve.c.
The complexity exists in the handling of array section, implied do
@@ -144,7 +144,7 @@ find_con_by_component (gfc_component *com, gfc_constructor *con)
/* Create a character type initialization expression from RVALUE.
TS [and REF] describe [the substring of] the variable being initialized.
- INIT is thh existing initializer, not NULL. Initialization is performed
+ INIT is the existing initializer, not NULL. Initialization is performed
according to normal assignment rules. */
static gfc_expr *
@@ -754,7 +754,7 @@ formalize_structure_cons (gfc_expr *expr)
}
-/* Make sure an initialization expression is in normalized form. Ie. all
+/* Make sure an initialization expression is in normalized form, i.e., all
elements of the constructors are in the correct order. */
static void
diff --git a/gcc/fortran/decl.c b/gcc/fortran/decl.c
index d23a32946ef..9b5aa7f0f93 100644
--- a/gcc/fortran/decl.c
+++ b/gcc/fortran/decl.c
@@ -231,21 +231,21 @@ syntax:
variable-iterator list. */
static match
-var_element (gfc_data_variable *new)
+var_element (gfc_data_variable *new_var)
{
match m;
gfc_symbol *sym;
- memset (new, 0, sizeof (gfc_data_variable));
+ memset (new_var, 0, sizeof (gfc_data_variable));
if (gfc_match_char ('(') == MATCH_YES)
- return var_list (new);
+ return var_list (new_var);
- m = gfc_match_variable (&new->expr, 0);
+ m = gfc_match_variable (&new_var->expr, 0);
if (m != MATCH_YES)
return m;
- sym = new->expr->symtree->n.sym;
+ sym = new_var->expr->symtree->n.sym;
if (!sym->attr.function && gfc_current_ns->parent
&& gfc_current_ns->parent == sym->ns)
@@ -262,7 +262,7 @@ var_element (gfc_data_variable *new)
sym->name) == FAILURE)
return MATCH_ERROR;
- if (gfc_add_data (&sym->attr, sym->name, &new->expr->where) == FAILURE)
+ if (gfc_add_data (&sym->attr, sym->name, &new_var->expr->where) == FAILURE)
return MATCH_ERROR;
return MATCH_YES;
@@ -274,7 +274,7 @@ var_element (gfc_data_variable *new)
static match
top_var_list (gfc_data *d)
{
- gfc_data_variable var, *tail, *new;
+ gfc_data_variable var, *tail, *new_var;
match m;
tail = NULL;
@@ -287,15 +287,15 @@ top_var_list (gfc_data *d)
if (m == MATCH_ERROR)
return MATCH_ERROR;
- new = gfc_get_data_variable ();
- *new = var;
+ new_var = gfc_get_data_variable ();
+ *new_var = var;
if (tail == NULL)
- d->var = new;
+ d->var = new_var;
else
- tail->next = new;
+ tail->next = new_var;
- tail = new;
+ tail = new_var;
if (gfc_match_char ('/') == MATCH_YES)
break;
@@ -404,7 +404,7 @@ match_data_constant (gfc_expr **result)
static match
top_val_list (gfc_data *data)
{
- gfc_data_value *new, *tail;
+ gfc_data_value *new_val, *tail;
gfc_expr *expr;
match m;
@@ -418,15 +418,15 @@ top_val_list (gfc_data *data)
if (m == MATCH_ERROR)
return MATCH_ERROR;
- new = gfc_get_data_value ();
- mpz_init (new->repeat);
+ new_val = gfc_get_data_value ();
+ mpz_init (new_val->repeat);
if (tail == NULL)
- data->value = new;
+ data->value = new_val;
else
- tail->next = new;
+ tail->next = new_val;
- tail = new;
+ tail = new_val;
if (expr->ts.type != BT_INTEGER || gfc_match_char ('*') != MATCH_YES)
{
@@ -518,26 +518,26 @@ match_old_style_init (const char *name)
match
gfc_match_data (void)
{
- gfc_data *new;
+ gfc_data *new_data;
match m;
set_in_match_data (true);
for (;;)
{
- new = gfc_get_data ();
- new->where = gfc_current_locus;
+ new_data = gfc_get_data ();
+ new_data->where = gfc_current_locus;
- m = top_var_list (new);
+ m = top_var_list (new_data);
if (m != MATCH_YES)
goto cleanup;
- m = top_val_list (new);
+ m = top_val_list (new_data);
if (m != MATCH_YES)
goto cleanup;
- new->next = gfc_current_ns->data;
- gfc_current_ns->data = new;
+ new_data->next = gfc_current_ns->data;
+ gfc_current_ns->data = new_data;
if (gfc_match_eos () == MATCH_YES)
break;
@@ -557,7 +557,7 @@ gfc_match_data (void)
cleanup:
set_in_match_data (false);
- gfc_free_data (new);
+ gfc_free_data (new_data);
return MATCH_ERROR;
}
@@ -762,7 +762,7 @@ get_proc_name (const char *name, gfc_symbol **result, bool module_fcn_entry)
(*result)->ts = sym->ts;
/* Put the symbol in the procedure namespace so that, should
- the ENTRY preceed its specification, the specification
+ the ENTRY precede its specification, the specification
can be applied. */
(*result)->ns = gfc_current_ns;
@@ -781,7 +781,7 @@ get_proc_name (const char *name, gfc_symbol **result, bool module_fcn_entry)
sym = *result;
gfc_current_ns->refs++;
- if (sym && !sym->new && gfc_current_state () != COMP_INTERFACE)
+ if (sym && !sym->gfc_new && gfc_current_state () != COMP_INTERFACE)
{
/* Trap another encompassed procedure with the same name. All
these conditions are necessary to avoid picking up an entry
@@ -4120,8 +4120,8 @@ match_procedure_decl (void)
/* Handle intrinsic procedures. */
if (!(proc_if->attr.external || proc_if->attr.use_assoc
|| proc_if->attr.if_source == IFSRC_IFBODY)
- && (gfc_intrinsic_name (proc_if->name, 0)
- || gfc_intrinsic_name (proc_if->name, 1)))
+ && (gfc_is_intrinsic (proc_if, 0, gfc_current_locus)
+ || gfc_is_intrinsic (proc_if, 1, gfc_current_locus)))
proc_if->attr.intrinsic = 1;
if (proc_if->attr.intrinsic
&& !gfc_intrinsic_actual_ok (proc_if->name, 0))
@@ -4336,6 +4336,22 @@ gfc_match_procedure (void)
}
+/* Warn if a matched procedure has the same name as an intrinsic; this is
+ simply a wrapper around gfc_warn_intrinsic_shadow that interprets the current
+ parser-state-stack to find out whether we're in a module. */
+
+static void
+warn_intrinsic_shadow (const gfc_symbol* sym, bool func)
+{
+ bool in_module;
+
+ in_module = (gfc_state_stack->previous
+ && gfc_state_stack->previous->state == COMP_MODULE);
+
+ gfc_warn_intrinsic_shadow (sym, in_module, func);
+}
+
+
/* Match a function declaration. */
match
@@ -4460,6 +4476,9 @@ gfc_match_function_decl (void)
sym->result = result;
}
+ /* Warn if this procedure has the same name as an intrinsic. */
+ warn_intrinsic_shadow (sym, true);
+
return MATCH_YES;
}
@@ -4842,6 +4861,9 @@ gfc_match_subroutine (void)
if (copy_prefix (&sym->attr, &sym->declared_at) == FAILURE)
return MATCH_ERROR;
+ /* Warn if it has the same name as an intrinsic. */
+ warn_intrinsic_shadow (sym, false);
+
return MATCH_YES;
}
@@ -5630,7 +5652,7 @@ access_attr_decl (gfc_statement st)
interface_type type;
gfc_user_op *uop;
gfc_symbol *sym;
- gfc_intrinsic_op operator;
+ gfc_intrinsic_op op;
match m;
if (gfc_match (" ::") == MATCH_NO && gfc_match_space () == MATCH_NO)
@@ -5638,7 +5660,7 @@ access_attr_decl (gfc_statement st)
for (;;)
{
- m = gfc_match_generic_spec (&type, name, &operator);
+ m = gfc_match_generic_spec (&type, name, &op);
if (m == MATCH_NO)
goto syntax;
if (m == MATCH_ERROR)
@@ -5662,15 +5684,15 @@ access_attr_decl (gfc_statement st)
break;
case INTERFACE_INTRINSIC_OP:
- if (gfc_current_ns->operator_access[operator] == ACCESS_UNKNOWN)
+ if (gfc_current_ns->operator_access[op] == ACCESS_UNKNOWN)
{
- gfc_current_ns->operator_access[operator] =
+ gfc_current_ns->operator_access[op] =
(st == ST_PUBLIC) ? ACCESS_PUBLIC : ACCESS_PRIVATE;
}
else
{
gfc_error ("Access specification of the %s operator at %C has "
- "already been specified", gfc_op2string (operator));
+ "already been specified", gfc_op2string (op));
goto done;
}
@@ -5770,7 +5792,7 @@ syntax:
/* The PRIVATE statement is a bit weird in that it can be an attribute
- declaration, but also works as a standlone statement inside of a
+ declaration, but also works as a standalone statement inside of a
type declaration or a module. */
match
@@ -6341,7 +6363,7 @@ gfc_match_derived_decl (void)
components. The ways this can happen is via a function
definition, an INTRINSIC statement or a subtype in another
derived type that is a pointer. The first part of the AND clause
- is true if a the symbol is not the return value of a function. */
+ is true if the symbol is not the return value of a function. */
if (sym->attr.flavor != FL_DERIVED
&& gfc_add_flavor (&sym->attr, FL_DERIVED, sym->name, NULL) == FAILURE)
return MATCH_ERROR;
diff --git a/gcc/fortran/dependency.c b/gcc/fortran/dependency.c
index 8e7e34332ce..558b7675873 100644
--- a/gcc/fortran/dependency.c
+++ b/gcc/fortran/dependency.c
@@ -37,7 +37,7 @@ typedef enum
{
GFC_DEP_ERROR,
GFC_DEP_EQUAL, /* Identical Ranges. */
- GFC_DEP_FORWARD, /* eg. a(1:3), a(2:4). */
+ GFC_DEP_FORWARD, /* e.g., a(1:3), a(2:4). */
GFC_DEP_OVERLAP, /* May overlap in some other way. */
GFC_DEP_NODEP /* Distinct ranges. */
}
@@ -76,15 +76,15 @@ gfc_dep_compare_expr (gfc_expr *e1, gfc_expr *e2)
int i;
if (e1->expr_type == EXPR_OP
- && (e1->value.op.operator == INTRINSIC_UPLUS
- || e1->value.op.operator == INTRINSIC_PARENTHESES))
+ && (e1->value.op.op == INTRINSIC_UPLUS
+ || e1->value.op.op == INTRINSIC_PARENTHESES))
return gfc_dep_compare_expr (e1->value.op.op1, e2);
if (e2->expr_type == EXPR_OP
- && (e2->value.op.operator == INTRINSIC_UPLUS
- || e2->value.op.operator == INTRINSIC_PARENTHESES))
+ && (e2->value.op.op == INTRINSIC_UPLUS
+ || e2->value.op.op == INTRINSIC_PARENTHESES))
return gfc_dep_compare_expr (e1, e2->value.op.op1);
- if (e1->expr_type == EXPR_OP && e1->value.op.operator == INTRINSIC_PLUS)
+ if (e1->expr_type == EXPR_OP && e1->value.op.op == INTRINSIC_PLUS)
{
/* Compare X+C vs. X. */
if (e1->value.op.op2->expr_type == EXPR_CONSTANT
@@ -93,7 +93,7 @@ gfc_dep_compare_expr (gfc_expr *e1, gfc_expr *e2)
return mpz_sgn (e1->value.op.op2->value.integer);
/* Compare P+Q vs. R+S. */
- if (e2->expr_type == EXPR_OP && e2->value.op.operator == INTRINSIC_PLUS)
+ if (e2->expr_type == EXPR_OP && e2->value.op.op == INTRINSIC_PLUS)
{
int l, r;
@@ -126,7 +126,7 @@ gfc_dep_compare_expr (gfc_expr *e1, gfc_expr *e2)
}
/* Compare X vs. X+C. */
- if (e2->expr_type == EXPR_OP && e2->value.op.operator == INTRINSIC_PLUS)
+ if (e2->expr_type == EXPR_OP && e2->value.op.op == INTRINSIC_PLUS)
{
if (e2->value.op.op2->expr_type == EXPR_CONSTANT
&& e2->value.op.op2->ts.type == BT_INTEGER
@@ -135,7 +135,7 @@ gfc_dep_compare_expr (gfc_expr *e1, gfc_expr *e2)
}
/* Compare X-C vs. X. */
- if (e1->expr_type == EXPR_OP && e1->value.op.operator == INTRINSIC_MINUS)
+ if (e1->expr_type == EXPR_OP && e1->value.op.op == INTRINSIC_MINUS)
{
if (e1->value.op.op2->expr_type == EXPR_CONSTANT
&& e1->value.op.op2->ts.type == BT_INTEGER
@@ -143,7 +143,7 @@ gfc_dep_compare_expr (gfc_expr *e1, gfc_expr *e2)
return -mpz_sgn (e1->value.op.op2->value.integer);
/* Compare P-Q vs. R-S. */
- if (e2->expr_type == EXPR_OP && e2->value.op.operator == INTRINSIC_MINUS)
+ if (e2->expr_type == EXPR_OP && e2->value.op.op == INTRINSIC_MINUS)
{
int l, r;
@@ -163,7 +163,7 @@ gfc_dep_compare_expr (gfc_expr *e1, gfc_expr *e2)
}
/* Compare X vs. X-C. */
- if (e2->expr_type == EXPR_OP && e2->value.op.operator == INTRINSIC_MINUS)
+ if (e2->expr_type == EXPR_OP && e2->value.op.op == INTRINSIC_MINUS)
{
if (e2->value.op.op2->expr_type == EXPR_CONSTANT
&& e2->value.op.op2->ts.type == BT_INTEGER
@@ -196,7 +196,7 @@ gfc_dep_compare_expr (gfc_expr *e1, gfc_expr *e2)
case EXPR_OP:
/* Intrinsic operators are the same if their operands are the same. */
- if (e1->value.op.operator != e2->value.op.operator)
+ if (e1->value.op.op != e2->value.op.op)
return -2;
if (e1->value.op.op2 == 0)
{
@@ -523,7 +523,7 @@ gfc_check_fncall_dependency (gfc_expr *other, sym_intent intent,
/* Return 1 if e1 and e2 are equivalenced arrays, either
- directly or indirectly; ie. equivalence (a,b) for a and b
+ directly or indirectly; i.e., equivalence (a,b) for a and b
or equivalence (a,c),(b,c). This function uses the equiv_
lists, generated in trans-common(add_equivalences), that are
guaranteed to pick up indirect equivalences. We explicitly
@@ -1183,7 +1183,7 @@ gfc_dep_resolver (gfc_ref *lref, gfc_ref *rref)
while (lref && rref)
{
/* We're resolving from the same base symbol, so both refs should be
- the same type. We traverse the reference chain intil we find ranges
+ the same type. We traverse the reference chain until we find ranges
that are not equal. */
gcc_assert (lref->type == rref->type);
switch (lref->type)
diff --git a/gcc/fortran/dump-parse-tree.c b/gcc/fortran/dump-parse-tree.c
index 80ff5bcecb7..80ddda20c54 100644
--- a/gcc/fortran/dump-parse-tree.c
+++ b/gcc/fortran/dump-parse-tree.c
@@ -437,7 +437,7 @@ show_expr (gfc_expr *p)
case EXPR_OP:
fputc ('(', dumpfile);
- switch (p->value.op.operator)
+ switch (p->value.op.op)
{
case INTRINSIC_UPLUS:
fputs ("U+ ", dumpfile);
@@ -570,7 +570,7 @@ show_attr (symbol_attribute *attr)
fputs (" OPTIONAL", dumpfile);
if (attr->pointer)
fputs (" POINTER", dumpfile);
- if (attr->protected)
+ if (attr->is_protected)
fputs (" PROTECTED", dumpfile);
if (attr->value)
fputs (" VALUE", dumpfile);
@@ -737,7 +737,7 @@ show_uop (gfc_user_op *uop)
show_indent ();
fprintf (dumpfile, "%s:", uop->name);
- for (intr = uop->operator; intr; intr = intr->next)
+ for (intr = uop->op; intr; intr = intr->next)
fprintf (dumpfile, " %s", intr->sym->name);
}
@@ -1897,7 +1897,7 @@ show_namespace (gfc_namespace *ns)
for (op = GFC_INTRINSIC_BEGIN; op != GFC_INTRINSIC_END; op++)
{
/* User operator interfaces */
- intr = ns->operator[op];
+ intr = ns->op[op];
if (intr == NULL)
continue;
diff --git a/gcc/fortran/expr.c b/gcc/fortran/expr.c
index 12987e6b748..4d0c2c33f64 100644
--- a/gcc/fortran/expr.c
+++ b/gcc/fortran/expr.c
@@ -65,24 +65,24 @@ gfc_free_actual_arglist (gfc_actual_arglist *a1)
gfc_actual_arglist *
gfc_copy_actual_arglist (gfc_actual_arglist *p)
{
- gfc_actual_arglist *head, *tail, *new;
+ gfc_actual_arglist *head, *tail, *new_arg;
head = tail = NULL;
for (; p; p = p->next)
{
- new = gfc_get_actual_arglist ();
- *new = *p;
+ new_arg = gfc_get_actual_arglist ();
+ *new_arg = *p;
- new->expr = gfc_copy_expr (p->expr);
- new->next = NULL;
+ new_arg->expr = gfc_copy_expr (p->expr);
+ new_arg->next = NULL;
if (head == NULL)
- head = new;
+ head = new_arg;
else
- tail->next = new;
+ tail->next = new_arg;
- tail = new;
+ tail = new_arg;
}
return head;
@@ -480,7 +480,7 @@ gfc_copy_expr (gfc_expr *p)
break;
case EXPR_OP:
- switch (q->value.op.operator)
+ switch (q->value.op.op)
{
case INTRINSIC_NOT:
case INTRINSIC_PARENTHESES:
@@ -659,7 +659,7 @@ gfc_type_convert_binary (gfc_expr *e)
e->ts = op1->ts;
/* Special case for ** operator. */
- if (e->value.op.operator == INTRINSIC_POWER)
+ if (e->value.op.op == INTRINSIC_POWER)
goto done;
gfc_convert_type (e->value.op.op2, &e->ts, 2);
@@ -830,12 +830,12 @@ simplify_intrinsic_op (gfc_expr *p, int type)
gfc_intrinsic_op op;
gfc_expr *op1, *op2, *result;
- if (p->value.op.operator == INTRINSIC_USER)
+ if (p->value.op.op == INTRINSIC_USER)
return SUCCESS;
op1 = p->value.op.op1;
op2 = p->value.op.op2;
- op = p->value.op.operator;
+ op = p->value.op.op;
if (gfc_simplify_expr (op1, type) == FAILURE)
return FAILURE;
@@ -1840,7 +1840,7 @@ check_intrinsic_op (gfc_expr *e, try (*check_function) (gfc_expr *))
if ((*check_function) (op1) == FAILURE)
return FAILURE;
- switch (e->value.op.operator)
+ switch (e->value.op.op)
{
case INTRINSIC_UPLUS:
case INTRINSIC_UMINUS:
@@ -1883,7 +1883,7 @@ check_intrinsic_op (gfc_expr *e, try (*check_function) (gfc_expr *))
if (!numeric_type (et0 (op1)) || !numeric_type (et0 (op2)))
goto not_numeric;
- if (e->value.op.operator == INTRINSIC_POWER
+ if (e->value.op.op == INTRINSIC_POWER
&& check_function == check_init_expr && et0 (op2) != BT_INTEGER)
{
if (gfc_notify_std (GFC_STD_F2003,"Fortran 2003: Noninteger "
@@ -2160,7 +2160,6 @@ check_init_expr (gfc_expr *e)
{
match m;
try t;
- gfc_intrinsic_sym *isym;
if (e == NULL)
return SUCCESS;
@@ -2179,7 +2178,12 @@ check_init_expr (gfc_expr *e)
if ((m = check_specification_function (e)) != MATCH_YES)
{
- if ((m = gfc_intrinsic_func_interface (e, 0)) != MATCH_YES)
+ gfc_intrinsic_sym* isym;
+ gfc_symbol* sym;
+
+ sym = e->symtree->n.sym;
+ if (!gfc_is_intrinsic (sym, 0, e->where)
+ || (m = gfc_intrinsic_func_interface (e, 0)) != MATCH_YES)
{
gfc_error ("Function '%s' in initialization expression at %L "
"must be an intrinsic or a specification function",
@@ -2201,7 +2205,7 @@ check_init_expr (gfc_expr *e)
/* Try to scalarize an elemental intrinsic function that has an
array argument. */
- isym = gfc_find_function (e->symtree->n.sym->name);
+ isym = gfc_find_function (e->symtree->n.sym->name);
if (isym && isym->elemental
&& (t = scalarize_intrinsic_call (e)) == SUCCESS)
break;
@@ -3000,9 +3004,9 @@ gfc_check_pointer_assign (gfc_expr *lvalue, gfc_expr *rvalue)
return FAILURE;
}
- if (attr.protected && attr.use_assoc)
+ if (attr.is_protected && attr.use_assoc)
{
- gfc_error ("Pointer assigment target has PROTECTED "
+ gfc_error ("Pointer assignment target has PROTECTED "
"attribute at %L", &rvalue->where);
return FAILURE;
}
diff --git a/gcc/fortran/f95-lang.c b/gcc/fortran/f95-lang.c
index 794cc41a2d0..d2768b112dd 100644
--- a/gcc/fortran/f95-lang.c
+++ b/gcc/fortran/f95-lang.c
@@ -29,7 +29,7 @@ along with GCC; see the file COPYING3. If not see
#include "system.h"
#include "coretypes.h"
#include "tree.h"
-#include "tree-gimple.h"
+#include "gimple.h"
#include "flags.h"
#include "langhooks.h"
#include "langhooks-def.h"
@@ -62,7 +62,7 @@ GTY(())
union lang_tree_node
GTY((desc ("TREE_CODE (&%h.generic) == IDENTIFIER_NODE"),
- chain_next ("(union lang_tree_node *)GENERIC_NEXT (&%h.generic)")))
+ chain_next ("(union lang_tree_node *)TREE_CHAIN (&%h.generic)")))
{
union tree_node GTY((tag ("0"),
@@ -236,7 +236,7 @@ gfc_be_parse_file (int set_yydebug ATTRIBUTE_UNUSED)
cgraph_finalize_compilation_unit ();
cgraph_optimize ();
- /* Tell the frontent about any errors. */
+ /* Tell the frontend about any errors. */
gfc_get_errors (&warnings, &errors);
errorcount += errors;
warningcount += warnings;
@@ -435,6 +435,10 @@ poplevel (int keep, int reverse, int functionbody)
DECL_INITIAL (current_function_decl) = block_node;
BLOCK_VARS (block_node) = 0;
}
+ else if (current_binding_level == global_binding_level)
+ /* When using gfc_start_block/gfc_finish_block from middle-end hooks,
+ don't add newly created BLOCKs as subblocks of global_binding_level. */
+ ;
else if (block_node)
{
current_binding_level->blocks
@@ -543,7 +547,7 @@ gfc_init_decl_processing (void)
only use it for actual characters, not for INTEGER(1). Also, we
want double_type_node to actually have double precision. */
build_common_tree_nodes (false, false);
- /* x86_64 minw32 has a sizetype of "unsigned long long", most other hosts
+ /* x86_64 mingw32 has a sizetype of "unsigned long long", most other hosts
have a sizetype of "unsigned long". Therefore choose the correct size
in mostly target independent way. */
if (TYPE_MODE (long_unsigned_type_node) == ptr_mode)
@@ -600,8 +604,8 @@ gfc_mark_addressable (tree exp)
IDENTIFIER_POINTER (DECL_NAME (x)));
return false;
}
- pedwarn ("register variable %qs used in nested function",
- IDENTIFIER_POINTER (DECL_NAME (x)));
+ pedwarn0 ("register variable %qs used in nested function",
+ IDENTIFIER_POINTER (DECL_NAME (x)));
}
else if (DECL_REGISTER (x) && !TREE_ADDRESSABLE (x))
{
@@ -625,7 +629,7 @@ gfc_mark_addressable (tree exp)
}
#endif
- pedwarn ("address of register variable %qs requested",
+ pedwarn0 ("address of register variable %qs requested",
IDENTIFIER_POINTER (DECL_NAME (x)));
}
diff --git a/gcc/fortran/gfc-internals.texi b/gcc/fortran/gfc-internals.texi
index dfe5d161842..330db81c59c 100644
--- a/gcc/fortran/gfc-internals.texi
+++ b/gcc/fortran/gfc-internals.texi
@@ -285,8 +285,10 @@ structures.
@menu
* gfc_code:: Representation of Executable Statements.
+* gfc_expr:: Representation of Values and Expressions.
@end menu
+
@c gfc_code
@c --------
@@ -403,6 +405,153 @@ case-block, and @code{extx.case_list} contains the case-values this block
corresponds to. The @code{block} member links to the next case in the list.
+@c gfc_expr
+@c --------
+
+@node gfc_expr
+@section @code{gfc_expr}
+@tindex @code{gfc_expr}
+@tindex @code{struct gfc_expr}
+
+Expressions and ``values'', including constants, variable-, array- and
+component-references as well as complex expressions consisting of operators and
+function calls are internally represented as one or a whole tree of
+@code{gfc_expr} objects. The member @code{expr_type} specifies the overall
+type of an expression (for instance, @code{EXPR_CONSTANT} for constants or
+@code{EXPR_VARIABLE} for variable references). The members @code{ts} and
+@code{rank} as well as @code{shape}, which can be @code{NULL}, specify
+the type, rank and, if applicable, shape of the whole expression or expression
+tree of which the current structure is the root. @code{where} is the locus of
+this expression in the source code.
+
+Depending on the flavour of the expression being described by the object
+(that is, the value of its @code{expr_type} member), the corresponding structure
+in the @code{value} union will usually contain additional data describing the
+expression's value in a type-specific manner. The @code{ref} member is used to
+build chains of (array-, component- and substring-) references if the expression
+in question contains such references, see below for details.
+
+
+@subsection Constants
+
+Scalar constants are represented by @code{gfc_expr} nodes with their
+@code{expr_type} set to @code{EXPR_CONSTANT}. The constant's value shall
+already be known at compile-time and is stored in the @code{logical},
+@code{integer}, @code{real}, @code{complex} or @code{character} struct inside
+@code{value}, depending on the constant's type specification.
+
+
+@subsection Operators
+
+Operator-expressions are expressions that are the result of the execution of
+some operator on one or two operands. The expressions have an @code{expr_type}
+of @code{EXPR_OP}. Their @code{value.op} structure contains additional data.
+
+@code{op1} and optionally @code{op2} if the operator is binary point to the
+two operands, and @code{operator} or @code{uop} describe the operator that
+should be evaluated on these operands, where @code{uop} describes a user-defined
+operator.
+
+
+@subsection Function Calls
+
+If the expression is the return value of a function-call, its @code{expr_type}
+is set to @code{EXPR_FUNCTION}, and @code{symtree} must point to the symtree
+identifying the function to be called. @code{value.function.actual} holds the
+actual arguments given to the function as a linked list of
+@code{gfc_actual_arglist} nodes.
+
+The other members of @code{value.function} describe the function being called
+in more detail, containing a link to the intrinsic symbol or user-defined
+function symbol if the call is to an intrinsic or external function,
+respectively. These values are determined during resolution-phase from the
+structure's @code{symtree} member.
+
+
+@subsection Array- and Structure-Constructors
+
+Array- and structure-constructors (one could probably call them ``array-'' and
+``derived-type constants'') are @code{gfc_expr} structures with their
+@code{expr_type} member set to @code{EXPR_ARRAY} or @code{EXPR_STRUCTURE},
+respectively. For structure constructors, @code{symtree} points to the
+derived-type symbol for the type being constructed.
+
+The values for initializing each array element or structure component are
+stored as linked-list of @code{gfc_constructor} nodes in the
+@code{value.constructor} member.
+
+
+@subsection Null
+
+@code{NULL} is a special value for pointers; it can be of different base types.
+Such a @code{NULL} value is represented in the internal tree by a
+@code{gfc_expr} node with @code{expr_type} @code{EXPR_NULL}. If the base type
+of the @code{NULL} expression is known, it is stored in @code{ts} (that's for
+instance the case for default-initializers of @code{ALLOCATABLE} components),
+but this member can also be set to @code{BT_UNKNOWN} if the information is not
+available (for instance, when the expression is a pointer-initializer
+@code{NULL()}).
+
+
+@subsection Variables and Reference Expressions
+
+Variable references are @code{gfc_expr} structures with their @code{expr_type}
+set to @code{EXPR_VARIABLE}; their @code{symtree} should point to the variable
+that is referenced.
+
+For this type of expression, it's also possible to chain array-, component-
+or substring-references to the original expression to get something like
+@samp{struct%component(2:5)}, where @code{component} is either an array or
+a @code{CHARACTER} member of @code{struct} that is of some derived-type. Such a
+chain of references is achieved by a linked list headed by @code{ref} of the
+@code{gfc_expr} node. For the example above it would be (@samp{==|} is the
+last @code{NULL} pointer):
+
+@smallexample
+EXPR_VARIABLE(struct) ==> REF_COMPONENT(component) ==> REF_ARRAY(2:5) ==|
+@end smallexample
+
+If @code{component} is a string rather than an array, the last element would be
+a @code{REF_SUBSTRING} reference, of course. If the variable itself or some
+component referenced is an array and the expression should reference the whole
+array rather than being followed by an array-element or -section reference, a
+@code{REF_ARRAY} reference must be built as the last element in the chain with
+an array-reference type of @code{AR_FULL}. Consider this example code:
+
+@smallexample
+TYPE :: mytype
+ INTEGER :: array(42)
+END TYPE mytype
+
+TYPE(mytype) :: variable
+INTEGER :: local_array(5)
+
+CALL do_something (variable%array, local_array)
+@end smallexample
+
+The @code{gfc_expr} nodes representing the arguments to the @samp{do_something}
+call will have a reference-chain like this:
+
+@smallexample
+EXPR_VARIABLE(variable) ==> REF_COMPONENT(array) ==> REF_ARRAY(FULL) ==|
+EXPR_VARIABLE(local_array) ==> REF_ARRAY(FULL) ==|
+@end smallexample
+
+
+@subsection Constant Substring References
+
+@code{EXPR_SUBSTRING} is a special type of expression that encodes a substring
+reference of a constant string, as in the following code snippet:
+
+@smallexample
+x = "abcde"(1:2)
+@end smallexample
+
+In this case, @code{value.character} contains the full string's data as if it
+was a string constant, but the @code{ref} member is also set and points to a
+substring reference as described in the subsection above.
+
+
@c ---------------------------------------------------------------------
@c LibGFortran
@c ---------------------------------------------------------------------
diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h
index aa2296c72a5..398a9a69acb 100644
--- a/gcc/fortran/gfortran.h
+++ b/gcc/fortran/gfortran.h
@@ -78,7 +78,7 @@ char *alloca ();
#define stringize(x) expand_macro(x)
#define expand_macro(x) # x
-/* For a the runtime library, a standard prefix is a requirement to
+/* For the runtime library, a standard prefix is a requirement to
avoid cluttering the namespace with things nobody asked for. It's
ugly to look at and a pain to type when you add the prefix by hand,
so we hide it behind a macro. */
@@ -114,9 +114,11 @@ io_kind;
following enum makes things much more readable. We also start
values off at one instead of zero. */
+/* FIXME: This macro is temporary until we convert everything. */
+#define try gfc_try
typedef enum
{ SUCCESS = 1, FAILURE }
-try;
+gfc_try;
/* This is returned by gfc_notification_std to know if, given the flags
that were given (-std=, -pedantic) we should issue an error, a warning
@@ -302,7 +304,7 @@ extern const mstring save_status[];
enum gfc_isym_id
{
/* GFC_ISYM_NONE is used for intrinsics which will never be seen by
- the backend (eg. KIND). */
+ the backend (e.g. KIND). */
GFC_ISYM_NONE = 0,
GFC_ISYM_ABORT,
GFC_ISYM_ABS,
@@ -625,7 +627,7 @@ typedef struct
ENUM_BITFIELD (save_state) save:2;
unsigned data:1, /* Symbol is named in a DATA statement. */
- protected:1, /* Symbol has been marked as protected. */
+ is_protected:1, /* Symbol has been marked as protected. */
use_assoc:1, /* Symbol has been use-associated. */
use_only:1, /* Symbol has been use-associated, with ONLY. */
use_rename:1, /* Symbol has been use-associated and renamed. */
@@ -691,7 +693,7 @@ typedef struct
unsigned cray_pointer:1, cray_pointee:1;
/* The symbol is a derived type with allocatable components, pointer
- components or private components, possibly nested. zer_comp
+ components or private components, possibly nested. zero_comp
is true if the derived type has no component at all. */
unsigned alloc_comp:1, pointer_comp:1, private_comp:1, zero_comp:1;
@@ -980,13 +982,12 @@ gfc_interface;
#define gfc_get_interface() XCNEW (gfc_interface)
-
/* User operator nodes. These are like stripped down symbols. */
typedef struct
{
const char *name;
- gfc_interface *operator;
+ gfc_interface *op;
struct gfc_namespace *ns;
gfc_access access;
}
@@ -1052,7 +1053,7 @@ typedef struct gfc_symbol
the old symbol. */
struct gfc_symbol *old_symbol, *tlink;
- unsigned mark:1, new:1;
+ unsigned mark:1, gfc_new:1;
/* Nonzero if all equivalences associated with this symbol have been
processed. */
unsigned equiv_built:1;
@@ -1179,7 +1180,7 @@ typedef struct gfc_namespace
/* Points to the equivalence groups produced by trans_common. */
struct gfc_equiv_list *equiv_lists;
- gfc_interface *operator[GFC_INTRINSIC_OPS];
+ gfc_interface *op[GFC_INTRINSIC_OPS];
/* Points to the parent namespace, i.e. the namespace of a module or
procedure in which the procedure belonging to this namespace is
@@ -1490,7 +1491,7 @@ typedef struct gfc_expr
struct
{
- gfc_intrinsic_op operator;
+ gfc_intrinsic_op op;
gfc_user_op *uop;
struct gfc_expr *op1, *op2;
}
@@ -1871,7 +1872,10 @@ typedef struct
int warn_surprising;
int warn_tabs;
int warn_underflow;
+ int warn_intrinsic_shadow;
+ int warn_intrinsics_std;
int warn_character_truncation;
+ int warn_array_temp;
int max_errors;
int flag_all_intrinsics;
@@ -1891,6 +1895,7 @@ typedef struct
int flag_automatic;
int flag_backslash;
int flag_backtrace;
+ int flag_check_array_temporaries;
int flag_allow_leading_underscore;
int flag_dump_core;
int flag_external_blas;
@@ -1913,7 +1918,6 @@ typedef struct
int warn_std;
int allow_std;
- int warn_nonstd_intrinsics;
int fshort_enums;
int convert;
int record_marker;
@@ -1959,7 +1963,7 @@ typedef struct gfc_finalizer
{
struct gfc_finalizer* next;
gfc_symbol* procedure;
- locus where; /* Where the FINAL declaration occured. */
+ locus where; /* Where the FINAL declaration occurred. */
}
gfc_finalizer;
@@ -2253,7 +2257,7 @@ try gfc_convert_type_warn (gfc_expr *, gfc_typespec *, int, int);
try gfc_convert_chartype (gfc_expr *, gfc_typespec *);
int gfc_generic_intrinsic (const char *);
int gfc_specific_intrinsic (const char *);
-int gfc_intrinsic_name (const char *, int);
+bool gfc_is_intrinsic (gfc_symbol*, int, locus);
int gfc_intrinsic_actual_ok (const char *, const bool);
gfc_intrinsic_sym *gfc_find_function (const char *);
gfc_intrinsic_sym *gfc_find_subroutine (const char *);
@@ -2261,6 +2265,10 @@ gfc_intrinsic_sym *gfc_find_subroutine (const char *);
match gfc_intrinsic_func_interface (gfc_expr *, int);
match gfc_intrinsic_sub_interface (gfc_code *, int);
+void gfc_warn_intrinsic_shadow (const gfc_symbol*, bool, bool);
+try gfc_check_intrinsic_standard (const gfc_intrinsic_sym*, const char**,
+ bool, locus);
+
/* match.c -- FIXME */
void gfc_free_iterator (gfc_iterator *, int);
void gfc_free_forall_iterator (gfc_forall_iterator *);
diff --git a/gcc/fortran/interface.c b/gcc/fortran/interface.c
index a20319976bb..d4809f0d5fb 100644
--- a/gcc/fortran/interface.c
+++ b/gcc/fortran/interface.c
@@ -95,32 +95,32 @@ gfc_free_interface (gfc_interface *intr)
minus respectively, leaving the rest unchanged. */
static gfc_intrinsic_op
-fold_unary (gfc_intrinsic_op operator)
+fold_unary (gfc_intrinsic_op op)
{
- switch (operator)
+ switch (op)
{
case INTRINSIC_UPLUS:
- operator = INTRINSIC_PLUS;
+ op = INTRINSIC_PLUS;
break;
case INTRINSIC_UMINUS:
- operator = INTRINSIC_MINUS;
+ op = INTRINSIC_MINUS;
break;
default:
break;
}
- return operator;
+ return op;
}
/* Match a generic specification. Depending on which type of
- interface is found, the 'name' or 'operator' pointers may be set.
+ interface is found, the 'name' or 'op' pointers may be set.
This subroutine doesn't return MATCH_NO. */
match
gfc_match_generic_spec (interface_type *type,
char *name,
- gfc_intrinsic_op *operator)
+ gfc_intrinsic_op *op)
{
char buffer[GFC_MAX_SYMBOL_LEN + 1];
match m;
@@ -129,14 +129,14 @@ gfc_match_generic_spec (interface_type *type,
if (gfc_match (" assignment ( = )") == MATCH_YES)
{
*type = INTERFACE_INTRINSIC_OP;
- *operator = INTRINSIC_ASSIGN;
+ *op = INTRINSIC_ASSIGN;
return MATCH_YES;
}
if (gfc_match (" operator ( %o )", &i) == MATCH_YES)
{ /* Operator i/f */
*type = INTERFACE_INTRINSIC_OP;
- *operator = fold_unary (i);
+ *op = fold_unary (i);
return MATCH_YES;
}
@@ -184,12 +184,12 @@ gfc_match_interface (void)
char name[GFC_MAX_SYMBOL_LEN + 1];
interface_type type;
gfc_symbol *sym;
- gfc_intrinsic_op operator;
+ gfc_intrinsic_op op;
match m;
m = gfc_match_space ();
- if (gfc_match_generic_spec (&type, name, &operator) == MATCH_ERROR)
+ if (gfc_match_generic_spec (&type, name, &op) == MATCH_ERROR)
return MATCH_ERROR;
/* If we're not looking at the end of the statement now, or if this
@@ -229,7 +229,7 @@ gfc_match_interface (void)
break;
case INTERFACE_INTRINSIC_OP:
- current_interface.op = operator;
+ current_interface.op = op;
break;
case INTERFACE_NAMELESS:
@@ -275,12 +275,12 @@ gfc_match_end_interface (void)
{
char name[GFC_MAX_SYMBOL_LEN + 1];
interface_type type;
- gfc_intrinsic_op operator;
+ gfc_intrinsic_op op;
match m;
m = gfc_match_space ();
- if (gfc_match_generic_spec (&type, name, &operator) == MATCH_ERROR)
+ if (gfc_match_generic_spec (&type, name, &op) == MATCH_ERROR)
return MATCH_ERROR;
/* If we're not looking at the end of the statement now, or if this
@@ -308,7 +308,7 @@ gfc_match_end_interface (void)
break;
case INTERFACE_INTRINSIC_OP:
- if (type != current_interface.type || operator != current_interface.op)
+ if (type != current_interface.type || op != current_interface.op)
{
if (current_interface.op == INTRINSIC_ASSIGN)
@@ -538,7 +538,7 @@ find_keyword_arg (const char *name, gfc_formal_arglist *f)
interfaces for that operator are legal. */
static void
-check_operator_interface (gfc_interface *intr, gfc_intrinsic_op operator)
+check_operator_interface (gfc_interface *intr, gfc_intrinsic_op op)
{
gfc_formal_arglist *formal;
sym_intent i1, i2;
@@ -585,10 +585,10 @@ check_operator_interface (gfc_interface *intr, gfc_intrinsic_op operator)
/* Only +, - and .not. can be unary operators.
.not. cannot be a binary operator. */
- if (args == 0 || args > 2 || (args == 1 && operator != INTRINSIC_PLUS
- && operator != INTRINSIC_MINUS
- && operator != INTRINSIC_NOT)
- || (args == 2 && operator == INTRINSIC_NOT))
+ if (args == 0 || args > 2 || (args == 1 && op != INTRINSIC_PLUS
+ && op != INTRINSIC_MINUS
+ && op != INTRINSIC_NOT)
+ || (args == 2 && op == INTRINSIC_NOT))
{
gfc_error ("Operator interface at %L has the wrong number of arguments",
&intr->sym->declared_at);
@@ -597,7 +597,7 @@ check_operator_interface (gfc_interface *intr, gfc_intrinsic_op operator)
/* Check that intrinsics are mapped to functions, except
INTRINSIC_ASSIGN which should map to a subroutine. */
- if (operator == INTRINSIC_ASSIGN)
+ if (op == INTRINSIC_ASSIGN)
{
if (!sym->attr.subroutine)
{
@@ -638,7 +638,7 @@ check_operator_interface (gfc_interface *intr, gfc_intrinsic_op operator)
}
/* Check intents on operator interfaces. */
- if (operator == INTRINSIC_ASSIGN)
+ if (op == INTRINSIC_ASSIGN)
{
if (i1 != INTENT_OUT && i1 != INTENT_INOUT)
gfc_error ("First argument of defined assignment at %L must be "
@@ -674,7 +674,7 @@ check_operator_interface (gfc_interface *intr, gfc_intrinsic_op operator)
((t) == BT_INTEGER || (t) == BT_REAL || (t) == BT_COMPLEX)
/* Unary ops are easy, do them first. */
- if (operator == INTRINSIC_NOT)
+ if (op == INTRINSIC_NOT)
{
if (t1 == BT_LOGICAL)
goto bad_repl;
@@ -682,7 +682,7 @@ check_operator_interface (gfc_interface *intr, gfc_intrinsic_op operator)
return;
}
- if (args == 1 && (operator == INTRINSIC_PLUS || operator == INTRINSIC_MINUS))
+ if (args == 1 && (op == INTRINSIC_PLUS || op == INTRINSIC_MINUS))
{
if (IS_NUMERIC_TYPE (t1))
goto bad_repl;
@@ -702,7 +702,7 @@ check_operator_interface (gfc_interface *intr, gfc_intrinsic_op operator)
if (r1 != r2 && r1 != 0 && r2 != 0)
return;
- switch (operator)
+ switch (op)
{
case INTRINSIC_EQ:
case INTRINSIC_EQ_OS:
@@ -1243,7 +1243,7 @@ check_uop_interfaces (gfc_user_op *uop)
gfc_namespace *ns;
sprintf (interface_name, "operator interface '%s'", uop->name);
- if (check_interface0 (uop->operator, interface_name))
+ if (check_interface0 (uop->op, interface_name))
return;
for (ns = gfc_current_ns; ns; ns = ns->parent)
@@ -1252,7 +1252,7 @@ check_uop_interfaces (gfc_user_op *uop)
if (uop2 == NULL)
continue;
- check_interface1 (uop->operator, uop2->operator, 0,
+ check_interface1 (uop->op, uop2->op, 0,
interface_name, true);
}
}
@@ -1288,76 +1288,76 @@ gfc_check_interfaces (gfc_namespace *ns)
sprintf (interface_name, "intrinsic '%s' operator",
gfc_op2string (i));
- if (check_interface0 (ns->operator[i], interface_name))
+ if (check_interface0 (ns->op[i], interface_name))
continue;
- check_operator_interface (ns->operator[i], i);
+ check_operator_interface (ns->op[i], i);
for (ns2 = ns; ns2; ns2 = ns2->parent)
{
- if (check_interface1 (ns->operator[i], ns2->operator[i], 0,
+ if (check_interface1 (ns->op[i], ns2->op[i], 0,
interface_name, true))
goto done;
switch (i)
{
case INTRINSIC_EQ:
- if (check_interface1 (ns->operator[i], ns2->operator[INTRINSIC_EQ_OS],
+ if (check_interface1 (ns->op[i], ns2->op[INTRINSIC_EQ_OS],
0, interface_name, true)) goto done;
break;
case INTRINSIC_EQ_OS:
- if (check_interface1 (ns->operator[i], ns2->operator[INTRINSIC_EQ],
+ if (check_interface1 (ns->op[i], ns2->op[INTRINSIC_EQ],
0, interface_name, true)) goto done;
break;
case INTRINSIC_NE:
- if (check_interface1 (ns->operator[i], ns2->operator[INTRINSIC_NE_OS],
+ if (check_interface1 (ns->op[i], ns2->op[INTRINSIC_NE_OS],
0, interface_name, true)) goto done;
break;
case INTRINSIC_NE_OS:
- if (check_interface1 (ns->operator[i], ns2->operator[INTRINSIC_NE],
+ if (check_interface1 (ns->op[i], ns2->op[INTRINSIC_NE],
0, interface_name, true)) goto done;
break;
case INTRINSIC_GT:
- if (check_interface1 (ns->operator[i], ns2->operator[INTRINSIC_GT_OS],
+ if (check_interface1 (ns->op[i], ns2->op[INTRINSIC_GT_OS],
0, interface_name, true)) goto done;
break;
case INTRINSIC_GT_OS:
- if (check_interface1 (ns->operator[i], ns2->operator[INTRINSIC_GT],
+ if (check_interface1 (ns->op[i], ns2->op[INTRINSIC_GT],
0, interface_name, true)) goto done;
break;
case INTRINSIC_GE:
- if (check_interface1 (ns->operator[i], ns2->operator[INTRINSIC_GE_OS],
+ if (check_interface1 (ns->op[i], ns2->op[INTRINSIC_GE_OS],
0, interface_name, true)) goto done;
break;
case INTRINSIC_GE_OS:
- if (check_interface1 (ns->operator[i], ns2->operator[INTRINSIC_GE],
+ if (check_interface1 (ns->op[i], ns2->op[INTRINSIC_GE],
0, interface_name, true)) goto done;
break;
case INTRINSIC_LT:
- if (check_interface1 (ns->operator[i], ns2->operator[INTRINSIC_LT_OS],
+ if (check_interface1 (ns->op[i], ns2->op[INTRINSIC_LT_OS],
0, interface_name, true)) goto done;
break;
case INTRINSIC_LT_OS:
- if (check_interface1 (ns->operator[i], ns2->operator[INTRINSIC_LT],
+ if (check_interface1 (ns->op[i], ns2->op[INTRINSIC_LT],
0, interface_name, true)) goto done;
break;
case INTRINSIC_LE:
- if (check_interface1 (ns->operator[i], ns2->operator[INTRINSIC_LE_OS],
+ if (check_interface1 (ns->op[i], ns2->op[INTRINSIC_LE_OS],
0, interface_name, true)) goto done;
break;
case INTRINSIC_LE_OS:
- if (check_interface1 (ns->operator[i], ns2->operator[INTRINSIC_LE],
+ if (check_interface1 (ns->op[i], ns2->op[INTRINSIC_LE],
0, interface_name, true)) goto done;
break;
@@ -1565,7 +1565,7 @@ compare_parameter_protected (gfc_symbol *formal, gfc_expr *actual)
if (actual->expr_type != EXPR_VARIABLE)
return 1;
- if (!actual->symtree->n.sym->attr.protected)
+ if (!actual->symtree->n.sym->attr.is_protected)
return 1;
if (!actual->symtree->n.sym->attr.use_assoc)
@@ -1823,7 +1823,7 @@ static int
compare_actual_formal (gfc_actual_arglist **ap, gfc_formal_arglist *formal,
int ranks_must_agree, int is_elemental, locus *where)
{
- gfc_actual_arglist **new, *a, *actual, temp;
+ gfc_actual_arglist **new_arg, *a, *actual, temp;
gfc_formal_arglist *f;
int i, n, na;
unsigned long actual_size, formal_size;
@@ -1837,10 +1837,10 @@ compare_actual_formal (gfc_actual_arglist **ap, gfc_formal_arglist *formal,
for (f = formal; f; f = f->next)
n++;
- new = (gfc_actual_arglist **) alloca (n * sizeof (gfc_actual_arglist *));
+ new_arg = (gfc_actual_arglist **) alloca (n * sizeof (gfc_actual_arglist *));
for (i = 0; i < n; i++)
- new[i] = NULL;
+ new_arg[i] = NULL;
na = 0;
f = formal;
@@ -1868,7 +1868,7 @@ compare_actual_formal (gfc_actual_arglist **ap, gfc_formal_arglist *formal,
return 0;
}
- if (new[i] != NULL)
+ if (new_arg[i] != NULL)
{
if (where)
gfc_error ("Keyword argument '%s' at %L is already associated "
@@ -2113,14 +2113,14 @@ compare_actual_formal (gfc_actual_arglist **ap, gfc_formal_arglist *formal,
if (a == actual)
na = i;
- new[i++] = a;
+ new_arg[i++] = a;
}
/* Make sure missing actual arguments are optional. */
i = 0;
for (f = formal; f; f = f->next, i++)
{
- if (new[i] != NULL)
+ if (new_arg[i] != NULL)
continue;
if (f->sym == NULL)
{
@@ -2142,27 +2142,27 @@ compare_actual_formal (gfc_actual_arglist **ap, gfc_formal_arglist *formal,
argument list with null arguments in the right places. The head
of the list remains the head. */
for (i = 0; i < n; i++)
- if (new[i] == NULL)
- new[i] = gfc_get_actual_arglist ();
+ if (new_arg[i] == NULL)
+ new_arg[i] = gfc_get_actual_arglist ();
if (na != 0)
{
- temp = *new[0];
- *new[0] = *actual;
+ temp = *new_arg[0];
+ *new_arg[0] = *actual;
*actual = temp;
- a = new[0];
- new[0] = new[na];
- new[na] = a;
+ a = new_arg[0];
+ new_arg[0] = new_arg[na];
+ new_arg[na] = a;
}
for (i = 0; i < n - 1; i++)
- new[i]->next = new[i + 1];
+ new_arg[i]->next = new_arg[i + 1];
- new[i]->next = NULL;
+ new_arg[i]->next = NULL;
if (*ap == NULL && n > 0)
- *ap = new[0];
+ *ap = new_arg[0];
/* Note the types of omitted optional arguments. */
for (a = *ap, f = formal; a; a = a->next, f = f->next)
@@ -2566,7 +2566,7 @@ gfc_extend_expr (gfc_expr *e)
actual->next->expr = e->value.op.op2;
}
- i = fold_unary (e->value.op.operator);
+ i = fold_unary (e->value.op.op);
if (i == INTRINSIC_USER)
{
@@ -2576,7 +2576,7 @@ gfc_extend_expr (gfc_expr *e)
if (uop == NULL)
continue;
- sym = gfc_search_interface (uop->operator, 0, &actual);
+ sym = gfc_search_interface (uop->op, 0, &actual);
if (sym != NULL)
break;
}
@@ -2591,48 +2591,48 @@ gfc_extend_expr (gfc_expr *e)
{
case INTRINSIC_EQ:
case INTRINSIC_EQ_OS:
- sym = gfc_search_interface (ns->operator[INTRINSIC_EQ], 0, &actual);
+ sym = gfc_search_interface (ns->op[INTRINSIC_EQ], 0, &actual);
if (sym == NULL)
- sym = gfc_search_interface (ns->operator[INTRINSIC_EQ_OS], 0, &actual);
+ sym = gfc_search_interface (ns->op[INTRINSIC_EQ_OS], 0, &actual);
break;
case INTRINSIC_NE:
case INTRINSIC_NE_OS:
- sym = gfc_search_interface (ns->operator[INTRINSIC_NE], 0, &actual);
+ sym = gfc_search_interface (ns->op[INTRINSIC_NE], 0, &actual);
if (sym == NULL)
- sym = gfc_search_interface (ns->operator[INTRINSIC_NE_OS], 0, &actual);
+ sym = gfc_search_interface (ns->op[INTRINSIC_NE_OS], 0, &actual);
break;
case INTRINSIC_GT:
case INTRINSIC_GT_OS:
- sym = gfc_search_interface (ns->operator[INTRINSIC_GT], 0, &actual);
+ sym = gfc_search_interface (ns->op[INTRINSIC_GT], 0, &actual);
if (sym == NULL)
- sym = gfc_search_interface (ns->operator[INTRINSIC_GT_OS], 0, &actual);
+ sym = gfc_search_interface (ns->op[INTRINSIC_GT_OS], 0, &actual);
break;
case INTRINSIC_GE:
case INTRINSIC_GE_OS:
- sym = gfc_search_interface (ns->operator[INTRINSIC_GE], 0, &actual);
+ sym = gfc_search_interface (ns->op[INTRINSIC_GE], 0, &actual);
if (sym == NULL)
- sym = gfc_search_interface (ns->operator[INTRINSIC_GE_OS], 0, &actual);
+ sym = gfc_search_interface (ns->op[INTRINSIC_GE_OS], 0, &actual);
break;
case INTRINSIC_LT:
case INTRINSIC_LT_OS:
- sym = gfc_search_interface (ns->operator[INTRINSIC_LT], 0, &actual);
+ sym = gfc_search_interface (ns->op[INTRINSIC_LT], 0, &actual);
if (sym == NULL)
- sym = gfc_search_interface (ns->operator[INTRINSIC_LT_OS], 0, &actual);
+ sym = gfc_search_interface (ns->op[INTRINSIC_LT_OS], 0, &actual);
break;
case INTRINSIC_LE:
case INTRINSIC_LE_OS:
- sym = gfc_search_interface (ns->operator[INTRINSIC_LE], 0, &actual);
+ sym = gfc_search_interface (ns->op[INTRINSIC_LE], 0, &actual);
if (sym == NULL)
- sym = gfc_search_interface (ns->operator[INTRINSIC_LE_OS], 0, &actual);
+ sym = gfc_search_interface (ns->op[INTRINSIC_LE_OS], 0, &actual);
break;
default:
- sym = gfc_search_interface (ns->operator[i], 0, &actual);
+ sym = gfc_search_interface (ns->op[i], 0, &actual);
}
if (sym != NULL)
@@ -2704,7 +2704,7 @@ gfc_extend_assign (gfc_code *c, gfc_namespace *ns)
for (; ns; ns = ns->parent)
{
- sym = gfc_search_interface (ns->operator[INTRINSIC_ASSIGN], 1, &actual);
+ sym = gfc_search_interface (ns->op[INTRINSIC_ASSIGN], 1, &actual);
if (sym != NULL)
break;
}
@@ -2732,16 +2732,16 @@ gfc_extend_assign (gfc_code *c, gfc_namespace *ns)
procedures can be present without interfaces. */
static try
-check_new_interface (gfc_interface *base, gfc_symbol *new)
+check_new_interface (gfc_interface *base, gfc_symbol *new_sym)
{
gfc_interface *ip;
for (ip = base; ip; ip = ip->next)
{
- if (ip->sym == new)
+ if (ip->sym == new_sym)
{
gfc_error ("Entity '%s' at %C is already present in the interface",
- new->name);
+ new_sym->name);
return FAILURE;
}
}
@@ -2753,7 +2753,7 @@ check_new_interface (gfc_interface *base, gfc_symbol *new)
/* Add a symbol to the current interface. */
try
-gfc_add_interface (gfc_symbol *new)
+gfc_add_interface (gfc_symbol *new_sym)
{
gfc_interface **head, *intr;
gfc_namespace *ns;
@@ -2771,52 +2771,52 @@ gfc_add_interface (gfc_symbol *new)
{
case INTRINSIC_EQ:
case INTRINSIC_EQ_OS:
- if (check_new_interface (ns->operator[INTRINSIC_EQ], new) == FAILURE ||
- check_new_interface (ns->operator[INTRINSIC_EQ_OS], new) == FAILURE)
+ if (check_new_interface (ns->op[INTRINSIC_EQ], new_sym) == FAILURE ||
+ check_new_interface (ns->op[INTRINSIC_EQ_OS], new_sym) == FAILURE)
return FAILURE;
break;
case INTRINSIC_NE:
case INTRINSIC_NE_OS:
- if (check_new_interface (ns->operator[INTRINSIC_NE], new) == FAILURE ||
- check_new_interface (ns->operator[INTRINSIC_NE_OS], new) == FAILURE)
+ if (check_new_interface (ns->op[INTRINSIC_NE], new_sym) == FAILURE ||
+ check_new_interface (ns->op[INTRINSIC_NE_OS], new_sym) == FAILURE)
return FAILURE;
break;
case INTRINSIC_GT:
case INTRINSIC_GT_OS:
- if (check_new_interface (ns->operator[INTRINSIC_GT], new) == FAILURE ||
- check_new_interface (ns->operator[INTRINSIC_GT_OS], new) == FAILURE)
+ if (check_new_interface (ns->op[INTRINSIC_GT], new_sym) == FAILURE ||
+ check_new_interface (ns->op[INTRINSIC_GT_OS], new_sym) == FAILURE)
return FAILURE;
break;
case INTRINSIC_GE:
case INTRINSIC_GE_OS:
- if (check_new_interface (ns->operator[INTRINSIC_GE], new) == FAILURE ||
- check_new_interface (ns->operator[INTRINSIC_GE_OS], new) == FAILURE)
+ if (check_new_interface (ns->op[INTRINSIC_GE], new_sym) == FAILURE ||
+ check_new_interface (ns->op[INTRINSIC_GE_OS], new_sym) == FAILURE)
return FAILURE;
break;
case INTRINSIC_LT:
case INTRINSIC_LT_OS:
- if (check_new_interface (ns->operator[INTRINSIC_LT], new) == FAILURE ||
- check_new_interface (ns->operator[INTRINSIC_LT_OS], new) == FAILURE)
+ if (check_new_interface (ns->op[INTRINSIC_LT], new_sym) == FAILURE ||
+ check_new_interface (ns->op[INTRINSIC_LT_OS], new_sym) == FAILURE)
return FAILURE;
break;
case INTRINSIC_LE:
case INTRINSIC_LE_OS:
- if (check_new_interface (ns->operator[INTRINSIC_LE], new) == FAILURE ||
- check_new_interface (ns->operator[INTRINSIC_LE_OS], new) == FAILURE)
+ if (check_new_interface (ns->op[INTRINSIC_LE], new_sym) == FAILURE ||
+ check_new_interface (ns->op[INTRINSIC_LE_OS], new_sym) == FAILURE)
return FAILURE;
break;
default:
- if (check_new_interface (ns->operator[current_interface.op], new) == FAILURE)
+ if (check_new_interface (ns->op[current_interface.op], new_sym) == FAILURE)
return FAILURE;
}
- head = &current_interface.ns->operator[current_interface.op];
+ head = &current_interface.ns->op[current_interface.op];
break;
case INTERFACE_GENERIC:
@@ -2826,7 +2826,7 @@ gfc_add_interface (gfc_symbol *new)
if (sym == NULL)
continue;
- if (check_new_interface (sym->generic, new) == FAILURE)
+ if (check_new_interface (sym->generic, new_sym) == FAILURE)
return FAILURE;
}
@@ -2834,11 +2834,11 @@ gfc_add_interface (gfc_symbol *new)
break;
case INTERFACE_USER_OP:
- if (check_new_interface (current_interface.uop->operator, new)
+ if (check_new_interface (current_interface.uop->op, new_sym)
== FAILURE)
return FAILURE;
- head = &current_interface.uop->operator;
+ head = &current_interface.uop->op;
break;
default:
@@ -2846,7 +2846,7 @@ gfc_add_interface (gfc_symbol *new)
}
intr = gfc_get_interface ();
- intr->sym = new;
+ intr->sym = new_sym;
intr->where = gfc_current_locus;
intr->next = *head;
@@ -2862,7 +2862,7 @@ gfc_current_interface_head (void)
switch (current_interface.type)
{
case INTERFACE_INTRINSIC_OP:
- return current_interface.ns->operator[current_interface.op];
+ return current_interface.ns->op[current_interface.op];
break;
case INTERFACE_GENERIC:
@@ -2870,7 +2870,7 @@ gfc_current_interface_head (void)
break;
case INTERFACE_USER_OP:
- return current_interface.uop->operator;
+ return current_interface.uop->op;
break;
default:
@@ -2885,7 +2885,7 @@ gfc_set_current_interface_head (gfc_interface *i)
switch (current_interface.type)
{
case INTERFACE_INTRINSIC_OP:
- current_interface.ns->operator[current_interface.op] = i;
+ current_interface.ns->op[current_interface.op] = i;
break;
case INTERFACE_GENERIC:
@@ -2893,7 +2893,7 @@ gfc_set_current_interface_head (gfc_interface *i)
break;
case INTERFACE_USER_OP:
- current_interface.uop->operator = i;
+ current_interface.uop->op = i;
break;
default:
diff --git a/gcc/fortran/intrinsic.c b/gcc/fortran/intrinsic.c
index df412757823..e5eec7ef4aa 100644
--- a/gcc/fortran/intrinsic.c
+++ b/gcc/fortran/intrinsic.c
@@ -48,7 +48,7 @@ static enum
{ SZ_NOTHING = 0, SZ_SUBS, SZ_FUNCS, SZ_CONVS }
sizing;
-enum class
+enum klass
{ NO_CLASS = 0, CLASS_ELEMENTAL, CLASS_INQUIRY, CLASS_TRANSFORMATIONAL };
#define ACTUAL_NO 0
@@ -243,7 +243,7 @@ do_check (gfc_intrinsic_sym *specific, gfc_actual_arglist *arg)
ZABS ZCOS ZEXP ZLOG ZSIN ZSQRT. */
static void
-add_sym (const char *name, gfc_isym_id id, enum class cl, int actual_ok, bt type, int kind,
+add_sym (const char *name, gfc_isym_id id, enum klass cl, int actual_ok, bt type, int kind,
int standard, gfc_check_f check, gfc_simplify_f simplify,
gfc_resolve_f resolve, ...)
{
@@ -332,7 +332,7 @@ add_sym (const char *name, gfc_isym_id id, enum class cl, int actual_ok, bt type
0 arguments. */
static void
-add_sym_0 (const char *name, gfc_isym_id id, enum class cl, int actual_ok, bt type,
+add_sym_0 (const char *name, gfc_isym_id id, enum klass cl, int actual_ok, bt type,
int kind, int standard,
try (*check) (void),
gfc_expr *(*simplify) (void),
@@ -374,7 +374,7 @@ add_sym_0s (const char *name, gfc_isym_id id, int standard, void (*resolve) (gfc
1 arguments. */
static void
-add_sym_1 (const char *name, gfc_isym_id id, enum class cl, int actual_ok, bt type,
+add_sym_1 (const char *name, gfc_isym_id id, enum klass cl, int actual_ok, bt type,
int kind, int standard,
try (*check) (gfc_expr *),
gfc_expr *(*simplify) (gfc_expr *),
@@ -399,7 +399,7 @@ add_sym_1 (const char *name, gfc_isym_id id, enum class cl, int actual_ok, bt ty
1 arguments. */
static void
-add_sym_1s (const char *name, gfc_isym_id id, enum class cl, bt type, int kind, int standard,
+add_sym_1s (const char *name, gfc_isym_id id, enum klass cl, bt type, int kind, int standard,
try (*check) (gfc_expr *),
gfc_expr *(*simplify) (gfc_expr *),
void (*resolve) (gfc_code *),
@@ -423,7 +423,7 @@ add_sym_1s (const char *name, gfc_isym_id id, enum class cl, bt type, int kind,
function. MAX et al take 2 or more arguments. */
static void
-add_sym_1m (const char *name, gfc_isym_id id, enum class cl, int actual_ok, bt type,
+add_sym_1m (const char *name, gfc_isym_id id, enum klass cl, int actual_ok, bt type,
int kind, int standard,
try (*check) (gfc_actual_arglist *),
gfc_expr *(*simplify) (gfc_expr *),
@@ -450,7 +450,7 @@ add_sym_1m (const char *name, gfc_isym_id id, enum class cl, int actual_ok, bt t
2 arguments. */
static void
-add_sym_2 (const char *name, gfc_isym_id id, enum class cl, int actual_ok, bt type,
+add_sym_2 (const char *name, gfc_isym_id id, enum klass cl, int actual_ok, bt type,
int kind, int standard,
try (*check) (gfc_expr *, gfc_expr *),
gfc_expr *(*simplify) (gfc_expr *, gfc_expr *),
@@ -477,7 +477,7 @@ add_sym_2 (const char *name, gfc_isym_id id, enum class cl, int actual_ok, bt ty
2 arguments. */
static void
-add_sym_2s (const char *name, gfc_isym_id id, enum class cl, bt type, int kind, int standard,
+add_sym_2s (const char *name, gfc_isym_id id, enum klass cl, bt type, int kind, int standard,
try (*check) (gfc_expr *, gfc_expr *),
gfc_expr *(*simplify) (gfc_expr *, gfc_expr *),
void (*resolve) (gfc_code *),
@@ -503,7 +503,7 @@ add_sym_2s (const char *name, gfc_isym_id id, enum class cl, bt type, int kind,
3 arguments. */
static void
-add_sym_3 (const char *name, gfc_isym_id id, enum class cl, int actual_ok, bt type,
+add_sym_3 (const char *name, gfc_isym_id id, enum klass cl, int actual_ok, bt type,
int kind, int standard,
try (*check) (gfc_expr *, gfc_expr *, gfc_expr *),
gfc_expr *(*simplify) (gfc_expr *, gfc_expr *, gfc_expr *),
@@ -532,7 +532,7 @@ add_sym_3 (const char *name, gfc_isym_id id, enum class cl, int actual_ok, bt ty
might have to be reordered. */
static void
-add_sym_3ml (const char *name, gfc_isym_id id, enum class cl, int actual_ok, bt type,
+add_sym_3ml (const char *name, gfc_isym_id id, enum klass cl, int actual_ok, bt type,
int kind, int standard,
try (*check) (gfc_actual_arglist *),
gfc_expr *(*simplify) (gfc_expr *, gfc_expr *, gfc_expr *),
@@ -561,7 +561,7 @@ add_sym_3ml (const char *name, gfc_isym_id id, enum class cl, int actual_ok, bt
their argument also might have to be reordered. */
static void
-add_sym_3red (const char *name, gfc_isym_id id, enum class cl, int actual_ok, bt type,
+add_sym_3red (const char *name, gfc_isym_id id, enum klass cl, int actual_ok, bt type,
int kind, int standard,
try (*check) (gfc_actual_arglist *),
gfc_expr *(*simplify) (gfc_expr *, gfc_expr *, gfc_expr *),
@@ -590,7 +590,7 @@ add_sym_3red (const char *name, gfc_isym_id id, enum class cl, int actual_ok, bt
3 arguments. */
static void
-add_sym_3s (const char *name, gfc_isym_id id, enum class cl, bt type, int kind, int standard,
+add_sym_3s (const char *name, gfc_isym_id id, enum klass cl, bt type, int kind, int standard,
try (*check) (gfc_expr *, gfc_expr *, gfc_expr *),
gfc_expr *(*simplify) (gfc_expr *, gfc_expr *, gfc_expr *),
void (*resolve) (gfc_code *),
@@ -618,7 +618,7 @@ add_sym_3s (const char *name, gfc_isym_id id, enum class cl, bt type, int kind,
4 arguments. */
static void
-add_sym_4 (const char *name, gfc_isym_id id, enum class cl, int actual_ok, bt type,
+add_sym_4 (const char *name, gfc_isym_id id, enum klass cl, int actual_ok, bt type,
int kind, int standard,
try (*check) (gfc_expr *, gfc_expr *, gfc_expr *, gfc_expr *),
gfc_expr *(*simplify) (gfc_expr *, gfc_expr *, gfc_expr *,
@@ -651,7 +651,7 @@ add_sym_4 (const char *name, gfc_isym_id id, enum class cl, int actual_ok, bt ty
4 arguments. */
static void
-add_sym_4s (const char *name, gfc_isym_id id, enum class cl, bt type, int kind, int standard,
+add_sym_4s (const char *name, gfc_isym_id id, enum klass cl, bt type, int kind, int standard,
try (*check) (gfc_expr *, gfc_expr *, gfc_expr *, gfc_expr *),
gfc_expr *(*simplify) (gfc_expr *, gfc_expr *, gfc_expr *,
gfc_expr *),
@@ -682,7 +682,7 @@ add_sym_4s (const char *name, gfc_isym_id id, enum class cl, bt type, int kind,
5 arguments. */
static void
-add_sym_5s (const char *name, gfc_isym_id id, enum class cl, bt type, int kind, int standard,
+add_sym_5s (const char *name, gfc_isym_id id, enum klass cl, bt type, int kind, int standard,
try (*check) (gfc_expr *, gfc_expr *, gfc_expr *, gfc_expr *,
gfc_expr *),
gfc_expr *(*simplify) (gfc_expr *, gfc_expr *, gfc_expr *,
@@ -807,15 +807,47 @@ gfc_intrinsic_actual_ok (const char *name, const bool subroutine_flag)
}
-/* Given a string, figure out if it is the name of an intrinsic
- subroutine or function. There are no generic intrinsic
- subroutines, they are all specific. */
+/* Given a symbol, find out if it is (and is to be treated) an intrinsic. If
+ it's name refers to an intrinsic but this intrinsic is not included in the
+ selected standard, this returns FALSE and sets the symbol's external
+ attribute. */
-int
-gfc_intrinsic_name (const char *name, int subroutine_flag)
+bool
+gfc_is_intrinsic (gfc_symbol* sym, int subroutine_flag, locus loc)
{
- return subroutine_flag ? gfc_find_subroutine (name) != NULL
- : gfc_find_function (name) != NULL;
+ gfc_intrinsic_sym* isym;
+ const char* symstd;
+
+ /* If INTRINSIC/EXTERNAL state is already known, return. */
+ if (sym->attr.intrinsic)
+ return true;
+ if (sym->attr.external)
+ return false;
+
+ if (subroutine_flag)
+ isym = gfc_find_subroutine (sym->name);
+ else
+ isym = gfc_find_function (sym->name);
+
+ /* No such intrinsic available at all? */
+ if (!isym)
+ return false;
+
+ /* See if this intrinsic is allowed in the current standard. */
+ if (gfc_check_intrinsic_standard (isym, &symstd, false, loc) == FAILURE)
+ {
+ if (gfc_option.warn_intrinsics_std)
+ gfc_warning_now ("The intrinsic '%s' at %L is not included in the"
+ " selected standard but %s and '%s' will be treated as"
+ " if declared EXTERNAL. Use an appropriate -std=*"
+ " option or define -fall-intrinsics to allow this"
+ " intrinsic.", sym->name, &loc, symstd, sym->name);
+ sym->attr.external = 1;
+
+ return false;
+ }
+
+ return true;
}
@@ -3448,21 +3480,82 @@ check_specific (gfc_intrinsic_sym *specific, gfc_expr *expr, int error_flag)
/* Check whether an intrinsic belongs to whatever standard the user
- has chosen. */
+ has chosen, taking also into account -fall-intrinsics. Here, no
+ warning/error is emitted; but if symstd is not NULL, it is pointed to a
+ textual representation of the symbols standard status (like
+ "new in Fortran 2008", "a GNU extension" or "obsolescent in Fortran 95") that
+ can be used to construct a detailed warning/error message in case of
+ a FAILURE. */
-static try
-check_intrinsic_standard (const char *name, int standard, locus *where)
+try
+gfc_check_intrinsic_standard (const gfc_intrinsic_sym* isym,
+ const char** symstd, bool silent, locus where)
{
- /* Do not warn about GNU-extensions if -std=gnu. */
- if (!gfc_option.warn_nonstd_intrinsics
- || (standard == GFC_STD_GNU && gfc_option.warn_std & GFC_STD_GNU))
+ const char* symstd_msg;
+
+ /* For -fall-intrinsics, just succeed. */
+ if (gfc_option.flag_all_intrinsics)
return SUCCESS;
- if (gfc_notify_std (standard, "Intrinsic '%s' at %L is not included "
- "in the selected standard", name, where) == FAILURE)
- return FAILURE;
+ /* Find the symbol's standard message for later usage. */
+ switch (isym->standard)
+ {
+ case GFC_STD_F77:
+ symstd_msg = "available since Fortran 77";
+ break;
- return SUCCESS;
+ case GFC_STD_F95_OBS:
+ symstd_msg = "obsolescent in Fortran 95";
+ break;
+
+ case GFC_STD_F95_DEL:
+ symstd_msg = "deleted in Fortran 95";
+ break;
+
+ case GFC_STD_F95:
+ symstd_msg = "new in Fortran 95";
+ break;
+
+ case GFC_STD_F2003:
+ symstd_msg = "new in Fortran 2003";
+ break;
+
+ case GFC_STD_F2008:
+ symstd_msg = "new in Fortran 2008";
+ break;
+
+ case GFC_STD_GNU:
+ symstd_msg = "a GNU Fortran extension";
+ break;
+
+ case GFC_STD_LEGACY:
+ symstd_msg = "for backward compatibility";
+ break;
+
+ default:
+ gfc_internal_error ("Invalid standard code on intrinsic '%s' (%d)",
+ isym->name, isym->standard);
+ }
+
+ /* If warning about the standard, warn and succeed. */
+ if (gfc_option.warn_std & isym->standard)
+ {
+ /* Do only print a warning if not a GNU extension. */
+ if (!silent && isym->standard != GFC_STD_GNU)
+ gfc_warning ("Intrinsic '%s' (is %s) is used at %L",
+ isym->name, _(symstd_msg), &where);
+
+ return SUCCESS;
+ }
+
+ /* If allowing the symbol's standard, succeed, too. */
+ if (gfc_option.allow_std & isym->standard)
+ return SUCCESS;
+
+ /* Otherwise, fail. */
+ if (symstd)
+ *symstd = _(symstd_msg);
+ return FAILURE;
}
@@ -3508,9 +3601,6 @@ gfc_intrinsic_func_interface (gfc_expr *expr, int error_flag)
return MATCH_NO;
}
- if (check_intrinsic_standard (name, isym->standard, &expr->where) == FAILURE)
- return MATCH_ERROR;
-
if ((isym->id == GFC_ISYM_REAL || isym->id == GFC_ISYM_DBLE
|| isym->id == GFC_ISYM_CMPLX)
&& gfc_init_expr
@@ -3605,9 +3695,6 @@ gfc_intrinsic_sub_interface (gfc_code *c, int error_flag)
if (isym == NULL)
return MATCH_NO;
- if (check_intrinsic_standard (name, isym->standard, &c->loc) == FAILURE)
- return MATCH_ERROR;
-
gfc_suppress_error = !error_flag;
init_arglist (isym);
@@ -3680,7 +3767,7 @@ gfc_convert_type_warn (gfc_expr *expr, gfc_typespec *ts, int eflag, int wflag)
gfc_intrinsic_sym *sym;
gfc_typespec from_ts;
locus old_where;
- gfc_expr *new;
+ gfc_expr *new_expr;
int rank;
mpz_t *shape;
@@ -3722,29 +3809,29 @@ gfc_convert_type_warn (gfc_expr *expr, gfc_typespec *ts, int eflag, int wflag)
rank = expr->rank;
shape = expr->shape;
- new = gfc_get_expr ();
- *new = *expr;
-
- new = gfc_build_conversion (new);
- new->value.function.name = sym->lib_name;
- new->value.function.isym = sym;
- new->where = old_where;
- new->rank = rank;
- new->shape = gfc_copy_shape (shape, rank);
-
- gfc_get_ha_sym_tree (sym->name, &new->symtree);
- new->symtree->n.sym->ts = *ts;
- new->symtree->n.sym->attr.flavor = FL_PROCEDURE;
- new->symtree->n.sym->attr.function = 1;
- new->symtree->n.sym->attr.elemental = 1;
- new->symtree->n.sym->attr.pure = 1;
- new->symtree->n.sym->attr.referenced = 1;
- gfc_intrinsic_symbol(new->symtree->n.sym);
- gfc_commit_symbol (new->symtree->n.sym);
-
- *expr = *new;
-
- gfc_free (new);
+ new_expr = gfc_get_expr ();
+ *new_expr = *expr;
+
+ new_expr = gfc_build_conversion (new_expr);
+ new_expr->value.function.name = sym->lib_name;
+ new_expr->value.function.isym = sym;
+ new_expr->where = old_where;
+ new_expr->rank = rank;
+ new_expr->shape = gfc_copy_shape (shape, rank);
+
+ gfc_get_ha_sym_tree (sym->name, &new_expr->symtree);
+ new_expr->symtree->n.sym->ts = *ts;
+ new_expr->symtree->n.sym->attr.flavor = FL_PROCEDURE;
+ new_expr->symtree->n.sym->attr.function = 1;
+ new_expr->symtree->n.sym->attr.elemental = 1;
+ new_expr->symtree->n.sym->attr.pure = 1;
+ new_expr->symtree->n.sym->attr.referenced = 1;
+ gfc_intrinsic_symbol(new_expr->symtree->n.sym);
+ gfc_commit_symbol (new_expr->symtree->n.sym);
+
+ *expr = *new_expr;
+
+ gfc_free (new_expr);
expr->ts = *ts;
if (gfc_is_constant_expr (expr->value.function.actual->expr)
@@ -3779,7 +3866,7 @@ gfc_convert_chartype (gfc_expr *expr, gfc_typespec *ts)
gfc_intrinsic_sym *sym;
gfc_typespec from_ts;
locus old_where;
- gfc_expr *new;
+ gfc_expr *new_expr;
int rank;
mpz_t *shape;
@@ -3794,28 +3881,28 @@ gfc_convert_chartype (gfc_expr *expr, gfc_typespec *ts)
rank = expr->rank;
shape = expr->shape;
- new = gfc_get_expr ();
- *new = *expr;
+ new_expr = gfc_get_expr ();
+ *new_expr = *expr;
- new = gfc_build_conversion (new);
- new->value.function.name = sym->lib_name;
- new->value.function.isym = sym;
- new->where = old_where;
- new->rank = rank;
- new->shape = gfc_copy_shape (shape, rank);
+ new_expr = gfc_build_conversion (new_expr);
+ new_expr->value.function.name = sym->lib_name;
+ new_expr->value.function.isym = sym;
+ new_expr->where = old_where;
+ new_expr->rank = rank;
+ new_expr->shape = gfc_copy_shape (shape, rank);
- gfc_get_ha_sym_tree (sym->name, &new->symtree);
- new->symtree->n.sym->ts = *ts;
- new->symtree->n.sym->attr.flavor = FL_PROCEDURE;
- new->symtree->n.sym->attr.function = 1;
- new->symtree->n.sym->attr.elemental = 1;
- new->symtree->n.sym->attr.referenced = 1;
- gfc_intrinsic_symbol(new->symtree->n.sym);
- gfc_commit_symbol (new->symtree->n.sym);
+ gfc_get_ha_sym_tree (sym->name, &new_expr->symtree);
+ new_expr->symtree->n.sym->ts = *ts;
+ new_expr->symtree->n.sym->attr.flavor = FL_PROCEDURE;
+ new_expr->symtree->n.sym->attr.function = 1;
+ new_expr->symtree->n.sym->attr.elemental = 1;
+ new_expr->symtree->n.sym->attr.referenced = 1;
+ gfc_intrinsic_symbol(new_expr->symtree->n.sym);
+ gfc_commit_symbol (new_expr->symtree->n.sym);
- *expr = *new;
+ *expr = *new_expr;
- gfc_free (new);
+ gfc_free (new_expr);
expr->ts = *ts;
if (gfc_is_constant_expr (expr->value.function.actual->expr)
@@ -3827,3 +3914,42 @@ gfc_convert_chartype (gfc_expr *expr, gfc_typespec *ts)
return SUCCESS;
}
+
+
+/* Check if the passed name is name of an intrinsic (taking into account the
+ current -std=* and -fall-intrinsic settings). If it is, see if we should
+ warn about this as a user-procedure having the same name as an intrinsic
+ (-Wintrinsic-shadow enabled) and do so if we should. */
+
+void
+gfc_warn_intrinsic_shadow (const gfc_symbol* sym, bool in_module, bool func)
+{
+ gfc_intrinsic_sym* isym;
+
+ /* If the warning is disabled, do nothing at all. */
+ if (!gfc_option.warn_intrinsic_shadow)
+ return;
+
+ /* Try to find an intrinsic of the same name. */
+ if (func)
+ isym = gfc_find_function (sym->name);
+ else
+ isym = gfc_find_subroutine (sym->name);
+
+ /* If no intrinsic was found with this name or it's not included in the
+ selected standard, everything's fine. */
+ if (!isym || gfc_check_intrinsic_standard (isym, NULL, true,
+ sym->declared_at) == FAILURE)
+ return;
+
+ /* Emit the warning. */
+ if (in_module)
+ gfc_warning ("'%s' declared at %L may shadow the intrinsic of the same"
+ " name. In order to call the intrinsic, explicit INTRINSIC"
+ " declarations may be required.",
+ sym->name, &sym->declared_at);
+ else
+ gfc_warning ("'%s' declared at %L is also the name of an intrinsic. It can"
+ " only be called via an explicit interface or if declared"
+ " EXTERNAL.", sym->name, &sym->declared_at);
+}
diff --git a/gcc/fortran/invoke.texi b/gcc/fortran/invoke.texi
index 445b4a7d1a9..f633187a01c 100644
--- a/gcc/fortran/invoke.texi
+++ b/gcc/fortran/invoke.texi
@@ -137,9 +137,9 @@ by type. Explanations are in the following sections.
and warnings}.
@gccoptlist{-fmax-errors=@var{n} @gol
-fsyntax-only -pedantic -pedantic-errors @gol
--Wall -Waliasing -Wampersand -Wcharacter-truncation -Wconversion @gol
--Wimplicit-interface -Wline-truncation -Wnonstd-intrinsics -Wsurprising @gol
--Wno-tabs -Wunderflow -Wunused-parameter}
+-Wall -Waliasing -Wampersand -Warray-bounds -Wcharacter-truncation @gol
+-Wconversion -Wimplicit-interface -Wline-truncation -Wintrinsics-std @gol
+-Wsurprising -Wno-tabs -Wunderflow -Wunused-parameter -Wintrinsics-shadow}
@item Debugging Options
@xref{Debugging Options,,Options for debugging your program or GNU Fortran}.
@@ -164,7 +164,7 @@ and warnings}.
@xref{Code Gen Options,,Options for code generation conventions}.
@gccoptlist{-fno-automatic -ff2c -fno-underscoring
-fsecond-underscore @gol
--fbounds-check -fmax-stack-var-size=@var{n} @gol
+-fbounds-check -fcheck-array-temporaries -fmax-stack-var-size=@var{n} @gol
-fpack-derived -frepack-arrays -fshort-enums -fexternal-blas @gol
-fblas-matmul-limit=@var{n} -frecursive -finit-local-zero @gol
-finit-integer=@var{n} -finit-real=@var{<zero|inf|-inf|nan>} @gol
@@ -211,7 +211,9 @@ form is determined by the file extension.
Accept all of the intrinsic procedures provided in libgfortran
without regard to the setting of @option{-std}. In particular,
this option can be quite useful with @option{-std=f95}. Additionally,
-@command{gfortran} will ignore @option{-Wnonstd-intrinsics}.
+@command{gfortran} will ignore @option{-Wintrinsics-std} and will never try
+to link to an @code{EXTERNAL} version if the intrinsic is not included in the
+selected standard.
@item -fd-lines-as-code
@item -fd-lines-as-comments
@@ -662,8 +664,8 @@ warnings.
Enables commonly used warning options pertaining to usage that
we recommend avoiding and that we believe are easy to avoid.
This currently includes @option{-Waliasing},
-@option{-Wampersand}, @option{-Wsurprising}, @option{-Wnonstd-intrinsics},
-@option{-Wno-tabs}, and @option{-Wline-truncation}.
+@option{-Wampersand}, @option{-Wsurprising}, @option{-Wintrinsics-std},
+@option{-Wno-tabs}, @option{-Wintrinsic-shadow} and @option{-Wline-truncation}.
@item -Waliasing
@opindex @code{Waliasing}
@@ -698,6 +700,13 @@ given in a continued character constant, GNU Fortran assumes continuation
at the first non-comment, non-whitespace character after the ampersand
that initiated the continuation.
+@item -Warray-temporaries
+@opindex @code{Warray-temporaries}
+@cindex warnings, array temporaries
+Warn about array temporaries generated by the compiler. The information
+generated by this warning is sometimes useful in optimization, in order to
+avoid such temporaries.
+
@item -Wcharacter-truncation
@opindex @code{Wcharacter-truncation}
@cindex warnings, character truncation
@@ -721,11 +730,15 @@ Warn if a procedure is called without an explicit interface.
Note this only checks that an explicit interface is present. It does not
check that the declared interfaces are consistent across program units.
-@item -Wnonstd-intrinsics
-@opindex @code{Wnonstd-intrinsics}
+@item -Wintrinsics-std
+@opindex @code{Wintrinsics-std}
@cindex warnings, non-standard intrinsics
-Warn if the user tries to use an intrinsic that does not belong to the
-standard the user has chosen via the @option{-std} option.
+@cindex warnings, intrinsics of other standards
+Warn if @command{gfortran} finds a procedure named like an intrinsic not
+available in the currently selected standard (with @option{-std}) and treats
+it as @code{EXTERNAL} procedure because of this. @option{-fall-intrinsics} can
+be used to never trigger this behaviour and always link to the intrinsic
+regardless of the selected standard.
@item -Wsurprising
@opindex @code{Wsurprising}
@@ -765,6 +778,15 @@ is active for @option{-pedantic}, @option{-std=f95}, @option{-std=f2003},
Produce a warning when numerical constant expressions are
encountered, which yield an UNDERFLOW during compilation.
+@item -Wintrinsic-shadow
+@opindex @code{Wintrinsic-shadow}
+@cindex warnings, intrinsic
+@cindex intrinsic
+Warn if a user-defined procedure or module procedure has the same name as an
+intrinsic; in this case, an explicit interface or @code{EXTERNAL} or
+@code{INTRINSIC} declaration might be needed to get calls later resolved to
+the desired intrinsic/procedure.
+
@item -Wunused-parameter
@opindex @code{Wunused-parameter}
@cindex warnings, unused parameter
@@ -1146,6 +1168,17 @@ the compilation of the main program.
In the future this may also include other forms of checking, e.g., checking
substring references.
+
+@item fcheck-array-temporaries
+@opindex @code{fcheck-array-temporaries}
+@cindex checking array temporaries
+Warns at run time when for passing an actual argument a temporary array
+had to be generated. The information generated by this warning is
+sometimes useful in optimization, in order to avoid such temporaries.
+
+Note: The warning is only printed once per location.
+
+
@item -fmax-stack-var-size=@var{n}
@opindex @code{fmax-stack-var-size}
This option specifies the size in bytes of the largest array that will be put
diff --git a/gcc/fortran/io.c b/gcc/fortran/io.c
index 3494e8e863f..188cf95ad06 100644
--- a/gcc/fortran/io.c
+++ b/gcc/fortran/io.c
@@ -119,6 +119,8 @@ format_token;
process. */
static gfc_char_t *format_string;
static int format_length, use_last_char;
+static char error_element;
+static locus format_locus;
static format_token saved_token;
@@ -165,6 +167,9 @@ next_char (int in_string)
if (mode == MODE_COPY)
*format_string++ = c;
+ if (mode != MODE_STRING)
+ format_locus = gfc_current_locus;
+
c = gfc_wide_toupper (c);
return c;
}
@@ -186,7 +191,7 @@ next_char_not_space (bool *error)
char c;
do
{
- c = next_char (0);
+ error_element = c = next_char (0);
if (c == '\t')
{
if (gfc_option.allow_std & GFC_STD_GNU)
@@ -431,14 +436,14 @@ format_lex (void)
{
if (gfc_notify_std (GFC_STD_F2003, "Fortran 2003: DP format "
"specifier not allowed at %C") == FAILURE)
- return FMT_ERROR;
+ return FMT_ERROR;
token = FMT_DP;
}
else if (c == 'C')
{
if (gfc_notify_std (GFC_STD_F2003, "Fortran 2003: DC format "
"specifier not allowed at %C") == FAILURE)
- return FMT_ERROR;
+ return FMT_ERROR;
token = FMT_DC;
}
else
@@ -474,9 +479,11 @@ check_format (bool is_input)
{
const char *posint_required = _("Positive width required");
const char *nonneg_required = _("Nonnegative width required");
- const char *unexpected_element = _("Unexpected element");
+ const char *unexpected_element = _("Unexpected element '%c' in format string"
+ " at %L");
const char *unexpected_end = _("Unexpected end of format string");
const char *zero_width = _("Zero width in format descriptor");
+ const char *g0_precision = _("Specifying precision with G0 not allowed");
const char *error;
format_token t, u;
@@ -694,9 +701,19 @@ data_desc:
error = zero_width;
goto syntax;
}
- else
- return gfc_notify_std (GFC_STD_F2008, "Fortran F2008: 'G0' in "
- "format at %C");
+
+ if (gfc_notify_std (GFC_STD_F2008, "Fortran 2008: 'G0' in "
+ "format at %C") == FAILURE)
+ return FAILURE;
+
+ u = format_lex ();
+ if (u == FMT_PERIOD)
+ {
+ error = g0_precision;
+ goto syntax;
+ }
+ saved_token = u;
+ goto between_desc;
}
if (u == FMT_ERROR)
@@ -949,10 +966,11 @@ extension_optional_comma:
goto format_item;
syntax:
- gfc_error ("%s in format string at %C", error);
+ if (error == unexpected_element)
+ gfc_error (error, error_element, &format_locus);
+ else
+ gfc_error ("%s in format string at %L", error, &format_locus);
fail:
- /* TODO: More elaborate measures are needed to show where a problem
- is within a format string that has been calculated. */
rv = FAILURE;
finished:
@@ -971,6 +989,12 @@ check_format_string (gfc_expr *e, bool is_input)
mode = MODE_STRING;
format_string = e->value.character.string;
+
+ /* More elaborate measures are needed to show where a problem is within a
+ format string that has been calculated, but that's probably not worth the
+ effort. */
+ format_locus = e->where;
+
return check_format (is_input);
}
@@ -2478,9 +2502,9 @@ gfc_resolve_dt (gfc_dt *dt)
else
{
/* At this point, we have an extra comma. If io_unit has arrived as
- type chracter, we assume its really the "format" form of the I/O
+ type character, we assume its really the "format" form of the I/O
statement. We set the io_unit to the default unit and format to
- the chracter expression. See F95 Standard section 9.4. */
+ the character expression. See F95 Standard section 9.4. */
io_kind k;
k = dt->extra_comma->value.iokind;
if (e->ts.type == BT_CHARACTER && (k == M_READ || k == M_PRINT))
@@ -2612,7 +2636,7 @@ static match match_io_element (io_kind, gfc_code **);
static match
match_io_iterator (io_kind k, gfc_code **result)
{
- gfc_code *head, *tail, *new;
+ gfc_code *head, *tail, *new_code;
gfc_iterator *iter;
locus old_loc;
match m;
@@ -2648,7 +2672,7 @@ match_io_iterator (io_kind k, gfc_code **result)
break;
}
- m = match_io_element (k, &new);
+ m = match_io_element (k, &new_code);
if (m == MATCH_ERROR)
goto cleanup;
if (m == MATCH_NO)
@@ -2658,7 +2682,7 @@ match_io_iterator (io_kind k, gfc_code **result)
goto cleanup;
}
- tail = gfc_append_code (tail, new);
+ tail = gfc_append_code (tail, new_code);
if (gfc_match_char (',') != MATCH_YES)
{
@@ -2672,15 +2696,15 @@ match_io_iterator (io_kind k, gfc_code **result)
if (gfc_match_char (')') != MATCH_YES)
goto syntax;
- new = gfc_get_code ();
- new->op = EXEC_DO;
- new->ext.iterator = iter;
+ new_code = gfc_get_code ();
+ new_code->op = EXEC_DO;
+ new_code->ext.iterator = iter;
- new->block = gfc_get_code ();
- new->block->op = EXEC_DO;
- new->block->next = head;
+ new_code->block = gfc_get_code ();
+ new_code->block->op = EXEC_DO;
+ new_code->block->next = head;
- *result = new;
+ *result = new_code;
return MATCH_YES;
syntax:
@@ -2788,7 +2812,7 @@ match_io_element (io_kind k, gfc_code **cpp)
static match
match_io_list (io_kind k, gfc_code **head_p)
{
- gfc_code *head, *tail, *new;
+ gfc_code *head, *tail, *new_code;
match m;
*head_p = head = tail = NULL;
@@ -2797,15 +2821,15 @@ match_io_list (io_kind k, gfc_code **head_p)
for (;;)
{
- m = match_io_element (k, &new);
+ m = match_io_element (k, &new_code);
if (m == MATCH_ERROR)
goto cleanup;
if (m == MATCH_NO)
goto syntax;
- tail = gfc_append_code (tail, new);
+ tail = gfc_append_code (tail, new_code);
if (head == NULL)
- head = new;
+ head = new_code;
if (gfc_match_eos () == MATCH_YES)
break;
diff --git a/gcc/fortran/iresolve.c b/gcc/fortran/iresolve.c
index 64a24e80007..f447ba279cf 100644
--- a/gcc/fortran/iresolve.c
+++ b/gcc/fortran/iresolve.c
@@ -705,7 +705,7 @@ gfc_resolve_dot_product (gfc_expr *f, gfc_expr *a, gfc_expr *b)
temp.expr_type = EXPR_OP;
gfc_clear_ts (&temp.ts);
- temp.value.op.operator = INTRINSIC_NONE;
+ temp.value.op.op = INTRINSIC_NONE;
temp.value.op.op1 = a;
temp.value.op.op2 = b;
gfc_type_convert_binary (&temp);
@@ -1332,7 +1332,7 @@ gfc_resolve_matmul (gfc_expr *f, gfc_expr *a, gfc_expr *b)
{
temp.expr_type = EXPR_OP;
gfc_clear_ts (&temp.ts);
- temp.value.op.operator = INTRINSIC_NONE;
+ temp.value.op.op = INTRINSIC_NONE;
temp.value.op.op1 = a;
temp.value.op.op2 = b;
gfc_type_convert_binary (&temp);
@@ -1788,6 +1788,7 @@ gfc_resolve_product (gfc_expr *f, gfc_expr *array, gfc_expr *dim,
if (dim != NULL)
{
f->rank = array->rank - 1;
+ f->shape = gfc_copy_shape_excluding (array->shape, array->rank, dim);
gfc_resolve_dim_arg (dim);
}
@@ -2271,6 +2272,7 @@ gfc_resolve_sum (gfc_expr *f, gfc_expr *array, gfc_expr *dim, gfc_expr *mask)
if (dim != NULL)
{
f->rank = array->rank - 1;
+ f->shape = gfc_copy_shape_excluding (array->shape, array->rank, dim);
gfc_resolve_dim_arg (dim);
}
diff --git a/gcc/fortran/lang.opt b/gcc/fortran/lang.opt
index f0f6c6a756d..93211952c12 100644
--- a/gcc/fortran/lang.opt
+++ b/gcc/fortran/lang.opt
@@ -76,6 +76,10 @@ Wampersand
Fortran Warning
Warn about missing ampersand in continued character constants
+Warray-temporaries
+Fortran Warning
+Warn about creation of array temporaries
+
Wcharacter-truncation
Fortran Warning
Warn about truncated character expressions
@@ -92,9 +96,9 @@ Wline-truncation
Fortran Warning
Warn about truncated source lines
-Wnonstd-intrinsics
+Wintrinsics-std
Fortran Warning
-Warn about usage of non-standard intrinsics
+Warn on intrinsics not part of the selected standard
Wreturn-type
Fortran Warning
@@ -112,6 +116,10 @@ Wunderflow
Fortran Warning
Warn about underflow of numerical constant expressions
+Wintrinsic-shadow
+Fortran Warning
+Warn if a user-procedure has the same name as an intrinsic
+
cpp
Fortran Joined Separate Negative(nocpp)
Enable preprocessing
@@ -148,6 +156,10 @@ fblas-matmul-limit=
Fortran RejectNegative Joined UInteger
-fblas-matmul-limit=<n> Size of the smallest matrix for which matmul will use BLAS
+fcheck-array-temporaries
+Fortran
+Produce a warning at runtime if a array temporary has been created for a procedure argument
+
fconvert=big-endian
Fortran RejectNegative
Use big-endian format for unformatted files
diff --git a/gcc/fortran/match.c b/gcc/fortran/match.c
index d501d682475..42fe7943aea 100644
--- a/gcc/fortran/match.c
+++ b/gcc/fortran/match.c
@@ -1187,6 +1187,11 @@ loop:
}
default:
+
+ /* gfc_next_ascii_char converts characters to lower-case, so we shouldn't
+ expect an upper case character here! */
+ gcc_assert (TOLOWER (c) == c);
+
if (c == gfc_next_ascii_char ())
goto loop;
break;
@@ -1287,7 +1292,7 @@ gfc_match_assignment (void)
return MATCH_NO;
}
- if (lvalue->symtree->n.sym->attr.protected
+ if (lvalue->symtree->n.sym->attr.is_protected
&& lvalue->symtree->n.sym->attr.use_assoc)
{
gfc_current_locus = old_loc;
@@ -1347,7 +1352,7 @@ gfc_match_pointer_assignment (void)
if (m != MATCH_YES)
goto cleanup;
- if (lvalue->symtree->n.sym->attr.protected
+ if (lvalue->symtree->n.sym->attr.is_protected
&& lvalue->symtree->n.sym->attr.use_assoc)
{
gfc_error ("Assigning to a PROTECTED pointer at %C");
@@ -3836,7 +3841,7 @@ cleanup:
static match
match_forall_header (gfc_forall_iterator **phead, gfc_expr **mask)
{
- gfc_forall_iterator *head, *tail, *new;
+ gfc_forall_iterator *head, *tail, *new_iter;
gfc_expr *msk;
match m;
@@ -3848,27 +3853,27 @@ match_forall_header (gfc_forall_iterator **phead, gfc_expr **mask)
if (gfc_match_char ('(') != MATCH_YES)
return MATCH_NO;
- m = match_forall_iterator (&new);
+ m = match_forall_iterator (&new_iter);
if (m == MATCH_ERROR)
goto cleanup;
if (m == MATCH_NO)
goto syntax;
- head = tail = new;
+ head = tail = new_iter;
for (;;)
{
if (gfc_match_char (',') != MATCH_YES)
break;
- m = match_forall_iterator (&new);
+ m = match_forall_iterator (&new_iter);
if (m == MATCH_ERROR)
goto cleanup;
if (m == MATCH_YES)
{
- tail->next = new;
- tail = new;
+ tail->next = new_iter;
+ tail = new_iter;
continue;
}
diff --git a/gcc/fortran/matchexp.c b/gcc/fortran/matchexp.c
index a9e90c99454..f7573655316 100644
--- a/gcc/fortran/matchexp.c
+++ b/gcc/fortran/matchexp.c
@@ -130,19 +130,12 @@ gfc_get_parentheses (gfc_expr *e)
{
gfc_expr *e2;
- /* This is a temporary fix, awaiting the patch for various
- other character problems. The resolution and translation
- of substrings and concatenations are so kludged up that
- putting parentheses around them breaks everything. */
- if (e->ts.type == BT_CHARACTER && e->ref)
- return e;
-
e2 = gfc_get_expr();
e2->expr_type = EXPR_OP;
e2->ts = e->ts;
e2->rank = e->rank;
e2->where = e->where;
- e2->value.op.operator = INTRINSIC_PARENTHESES;
+ e2->value.op.op = INTRINSIC_PARENTHESES;
e2->value.op.op1 = e;
e2->value.op.op2 = NULL;
return e2;
@@ -208,20 +201,20 @@ syntax:
/* Build an operator expression node. */
static gfc_expr *
-build_node (gfc_intrinsic_op operator, locus *where,
+build_node (gfc_intrinsic_op op, locus *where,
gfc_expr *op1, gfc_expr *op2)
{
- gfc_expr *new;
+ gfc_expr *new_expr;
- new = gfc_get_expr ();
- new->expr_type = EXPR_OP;
- new->value.op.operator = operator;
- new->where = *where;
+ new_expr = gfc_get_expr ();
+ new_expr->expr_type = EXPR_OP;
+ new_expr->value.op.op = op;
+ new_expr->where = *where;
- new->value.op.op1 = op1;
- new->value.op.op2 = op2;
+ new_expr->value.op.op1 = op1;
+ new_expr->value.op.op2 = op2;
- return new;
+ return new_expr;
}
@@ -261,7 +254,7 @@ match_level_1 (gfc_expr **result)
/* As a GNU extension we support an expanded level-2 expression syntax.
Via this extension we support (arbitrary) nesting of unary plus and
minus operations following unary and binary operators, such as **.
- The grammar of section 7.1.1.3 is effectively rewitten as:
+ The grammar of section 7.1.1.3 is effectively rewritten as:
R704 mult-operand is level-1-expr [ power-op ext-mult-operand ]
R704' ext-mult-operand is add-op ext-mult-operand
diff --git a/gcc/fortran/module.c b/gcc/fortran/module.c
index 67b09c767e9..a418bb9d9a4 100644
--- a/gcc/fortran/module.c
+++ b/gcc/fortran/module.c
@@ -20,7 +20,7 @@ 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/>. */
-/* The syntax of gfortran modules resembles that of lisp lists, ie a
+/* The syntax of gfortran modules resembles that of lisp lists, i.e. a
sequence of atoms, which can be left or right parenthesis, names,
integers or strings. Parenthesis are always matched which allows
us to skip over sections at high speed without having to know
@@ -169,7 +169,7 @@ typedef struct gfc_use_rename
char local_name[GFC_MAX_SYMBOL_LEN + 1], use_name[GFC_MAX_SYMBOL_LEN + 1];
struct gfc_use_rename *next;
int found;
- gfc_intrinsic_op operator;
+ gfc_intrinsic_op op;
locus where;
}
gfc_use_rename;
@@ -446,7 +446,7 @@ associate_integer_pointer (pointer_info *p, void *gp)
either store the pointer from an already-known value or create a
fixup structure in order to store things later. Returns zero if
the reference has been actually stored, or nonzero if the reference
- must be fixed later (ie associate_integer_pointer must be called
+ must be fixed later (i.e., associate_integer_pointer must be called
sometime later. Returns the pointer_info structure. */
static pointer_info *
@@ -502,9 +502,9 @@ match
gfc_match_use (void)
{
char name[GFC_MAX_SYMBOL_LEN + 1], module_nature[GFC_MAX_SYMBOL_LEN + 1];
- gfc_use_rename *tail = NULL, *new;
+ gfc_use_rename *tail = NULL, *new_use;
interface_type type, type2;
- gfc_intrinsic_op operator;
+ gfc_intrinsic_op op;
match m;
specified_int = false;
@@ -581,20 +581,20 @@ gfc_match_use (void)
for (;;)
{
/* Get a new rename struct and add it to the rename list. */
- new = gfc_get_use_rename ();
- new->where = gfc_current_locus;
- new->found = 0;
+ new_use = gfc_get_use_rename ();
+ new_use->where = gfc_current_locus;
+ new_use->found = 0;
if (gfc_rename_list == NULL)
- gfc_rename_list = new;
+ gfc_rename_list = new_use;
else
- tail->next = new;
- tail = new;
+ tail->next = new_use;
+ tail = new_use;
/* See what kind of interface we're dealing with. Assume it is
not an operator. */
- new->operator = INTRINSIC_NONE;
- if (gfc_match_generic_spec (&type, name, &operator) == MATCH_ERROR)
+ new_use->op = INTRINSIC_NONE;
+ if (gfc_match_generic_spec (&type, name, &op) == MATCH_ERROR)
goto cleanup;
switch (type)
@@ -614,16 +614,16 @@ gfc_match_use (void)
goto cleanup;
if (type == INTERFACE_USER_OP)
- new->operator = INTRINSIC_USER;
+ new_use->op = INTRINSIC_USER;
if (only_flag)
{
if (m != MATCH_YES)
- strcpy (new->use_name, name);
+ strcpy (new_use->use_name, name);
else
{
- strcpy (new->local_name, name);
- m = gfc_match_generic_spec (&type2, new->use_name, &operator);
+ strcpy (new_use->local_name, name);
+ m = gfc_match_generic_spec (&type2, new_use->use_name, &op);
if (type != type2)
goto syntax;
if (m == MATCH_NO)
@@ -636,9 +636,9 @@ gfc_match_use (void)
{
if (m != MATCH_YES)
goto syntax;
- strcpy (new->local_name, name);
+ strcpy (new_use->local_name, name);
- m = gfc_match_generic_spec (&type2, new->use_name, &operator);
+ m = gfc_match_generic_spec (&type2, new_use->use_name, &op);
if (type != type2)
goto syntax;
if (m == MATCH_NO)
@@ -647,8 +647,8 @@ gfc_match_use (void)
goto cleanup;
}
- if (strcmp (new->use_name, module_name) == 0
- || strcmp (new->local_name, module_name) == 0)
+ if (strcmp (new_use->use_name, module_name) == 0
+ || strcmp (new_use->local_name, module_name) == 0)
{
gfc_error ("The name '%s' at %C has already been used as "
"an external module name.", module_name);
@@ -657,7 +657,7 @@ gfc_match_use (void)
break;
case INTERFACE_INTRINSIC_OP:
- new->operator = operator;
+ new_use->op = op;
break;
default:
@@ -698,8 +698,8 @@ find_use_name_n (const char *name, int *inst, bool interface)
for (u = gfc_rename_list; u; u = u->next)
{
if (strcmp (u->use_name, name) != 0
- || (u->operator == INTRINSIC_USER && !interface)
- || (u->operator != INTRINSIC_USER && interface))
+ || (u->op == INTRINSIC_USER && !interface)
+ || (u->op != INTRINSIC_USER && interface))
continue;
if (++i == *inst)
break;
@@ -746,12 +746,12 @@ number_use_names (const char *name, bool interface)
/* Try to find the operator in the current list. */
static gfc_use_rename *
-find_use_operator (gfc_intrinsic_op operator)
+find_use_operator (gfc_intrinsic_op op)
{
gfc_use_rename *u;
for (u = gfc_rename_list; u; u = u->next)
- if (u->operator == operator)
+ if (u->op == op)
return u;
return NULL;
@@ -1741,7 +1741,7 @@ mio_symbol_attribute (symbol_attribute *attr)
MIO_NAME (ab_attribute) (AB_OPTIONAL, attr_bits);
if (attr->pointer)
MIO_NAME (ab_attribute) (AB_POINTER, attr_bits);
- if (attr->protected)
+ if (attr->is_protected)
MIO_NAME (ab_attribute) (AB_PROTECTED, attr_bits);
if (attr->value)
MIO_NAME (ab_attribute) (AB_VALUE, attr_bits);
@@ -1836,7 +1836,7 @@ mio_symbol_attribute (symbol_attribute *attr)
attr->pointer = 1;
break;
case AB_PROTECTED:
- attr->protected = 1;
+ attr->is_protected = 1;
break;
case AB_VALUE:
attr->value = 1;
@@ -2873,10 +2873,10 @@ mio_expr (gfc_expr **ep)
switch (e->expr_type)
{
case EXPR_OP:
- e->value.op.operator
- = MIO_NAME (gfc_intrinsic_op) (e->value.op.operator, intrinsics);
+ e->value.op.op
+ = MIO_NAME (gfc_intrinsic_op) (e->value.op.op, intrinsics);
- switch (e->value.op.operator)
+ switch (e->value.op.op)
{
case INTRINSIC_UPLUS:
case INTRINSIC_UMINUS:
@@ -3062,7 +3062,7 @@ mio_namelist (gfc_symbol *sym)
}
-/* Save/restore lists of gfc_interface stuctures. When loading an
+/* Save/restore lists of gfc_interface structures. When loading an
interface, we are really appending to the existing list of
interfaces. Checking for duplicate and ambiguous interfaces has to
be done later when all symbols have been loaded. */
@@ -3272,7 +3272,7 @@ find_symtree_for_symbol (gfc_symtree *st, gfc_symbol *sym)
}
-/* A recursive function to look for a speficic symbol by name and by
+/* A recursive function to look for a specific symbol by name and by
module. Whilst several symtrees might point to one symbol, its
is sufficient for the purposes here than one exist. Note that
generic interfaces are distinguished as are symbols that have been
@@ -3383,16 +3383,16 @@ load_operator_interfaces (void)
if (i == 1)
{
uop = gfc_get_uop (p);
- pi = mio_interface_rest (&uop->operator);
+ pi = mio_interface_rest (&uop->op);
}
else
{
if (gfc_find_uop (p, NULL))
continue;
uop = gfc_get_uop (p);
- uop->operator = gfc_get_interface ();
- uop->operator->where = gfc_current_locus;
- add_fixup (pi->integer, &uop->operator->sym);
+ uop->op = gfc_get_interface ();
+ uop->op->where = gfc_current_locus;
+ add_fixup (pi->integer, &uop->op->sym);
}
}
}
@@ -3954,7 +3954,7 @@ read_module (void)
u->found = 1;
}
- mio_interface (&gfc_current_ns->operator[i]);
+ mio_interface (&gfc_current_ns->op[i]);
}
mio_rparen ();
@@ -3984,14 +3984,14 @@ read_module (void)
if (u->found)
continue;
- if (u->operator == INTRINSIC_NONE)
+ if (u->op == INTRINSIC_NONE)
{
gfc_error ("Symbol '%s' referenced at %L not found in module '%s'",
u->use_name, &u->where, module_name);
continue;
}
- if (u->operator == INTRINSIC_USER)
+ if (u->op == INTRINSIC_USER)
{
gfc_error ("User operator '%s' referenced at %L not found "
"in module '%s'", u->use_name, &u->where, module_name);
@@ -3999,7 +3999,7 @@ read_module (void)
}
gfc_error ("Intrinsic operator '%s' referenced at %L not found "
- "in module '%s'", gfc_op2string (u->operator), &u->where,
+ "in module '%s'", gfc_op2string (u->op), &u->where,
module_name);
}
@@ -4319,11 +4319,11 @@ write_operator (gfc_user_op *uop)
static char nullstring[] = "";
const char *p = nullstring;
- if (uop->operator == NULL
+ if (uop->op == NULL
|| !gfc_check_access (uop->access, uop->ns->default_access))
return;
- mio_symbol_interface (&uop->name, &p, &uop->operator);
+ mio_symbol_interface (&uop->name, &p, &uop->op);
}
@@ -4395,7 +4395,7 @@ write_module (void)
mio_interface (gfc_check_access (gfc_current_ns->operator_access[i],
gfc_current_ns->default_access)
- ? &gfc_current_ns->operator[i] : NULL);
+ ? &gfc_current_ns->op[i] : NULL);
}
mio_rparen ();
diff --git a/gcc/fortran/openmp.c b/gcc/fortran/openmp.c
index 28f1cc24dfd..9ac9a4aec91 100644
--- a/gcc/fortran/openmp.c
+++ b/gcc/fortran/openmp.c
@@ -1093,7 +1093,7 @@ resolve_omp_atomic (gfc_code *code)
if (expr2->expr_type == EXPR_OP)
{
gfc_expr *v = NULL, *e, *c;
- gfc_intrinsic_op op = expr2->value.op.operator;
+ gfc_intrinsic_op op = expr2->value.op.op;
gfc_intrinsic_op alt_op = INTRINSIC_NONE;
switch (op)
@@ -1156,8 +1156,8 @@ resolve_omp_atomic (gfc_code *code)
else if ((c = is_conversion (e, true)) != NULL)
q = &e->value.function.actual->expr;
else if (e->expr_type != EXPR_OP
- || (e->value.op.operator != op
- && e->value.op.operator != alt_op)
+ || (e->value.op.op != op
+ && e->value.op.op != alt_op)
|| e->rank != 0)
break;
else
@@ -1176,7 +1176,7 @@ resolve_omp_atomic (gfc_code *code)
if (p != NULL)
{
e = *p;
- switch (e->value.op.operator)
+ switch (e->value.op.op)
{
case INTRINSIC_MINUS:
case INTRINSIC_DIVIDE:
diff --git a/gcc/fortran/options.c b/gcc/fortran/options.c
index 8480364bc52..1f05f35359f 100644
--- a/gcc/fortran/options.c
+++ b/gcc/fortran/options.c
@@ -69,12 +69,15 @@ gfc_init_options (unsigned int argc, const char **argv)
gfc_option.warn_aliasing = 0;
gfc_option.warn_ampersand = 0;
gfc_option.warn_character_truncation = 0;
+ gfc_option.warn_array_temp = 0;
gfc_option.warn_conversion = 0;
gfc_option.warn_implicit_interface = 0;
gfc_option.warn_line_truncation = 0;
gfc_option.warn_surprising = 0;
gfc_option.warn_tabs = 1;
gfc_option.warn_underflow = 1;
+ gfc_option.warn_intrinsic_shadow = 0;
+ gfc_option.warn_intrinsics_std = 0;
gfc_option.max_errors = 25;
gfc_option.flag_all_intrinsics = 0;
@@ -98,6 +101,7 @@ gfc_init_options (unsigned int argc, const char **argv)
gfc_option.flag_backslash = 0;
gfc_option.flag_module_private = 0;
gfc_option.flag_backtrace = 0;
+ gfc_option.flag_check_array_temporaries = 0;
gfc_option.flag_allow_leading_underscore = 0;
gfc_option.flag_dump_core = 0;
gfc_option.flag_external_blas = 0;
@@ -123,8 +127,6 @@ gfc_init_options (unsigned int argc, const char **argv)
set_default_std_flags ();
- gfc_option.warn_nonstd_intrinsics = 0;
-
/* -fshort-enums can be default on some targets. */
gfc_option.fshort_enums = targetm.default_short_enums ();
@@ -292,13 +294,9 @@ gfc_post_options (const char **pfilename)
gfc_warning_now ("'-fd-lines-as-code' has no effect in free form");
}
- flag_inline_trees = 1;
-
/* Use tree inlining. */
if (!flag_no_inline)
flag_no_inline = 1;
- if (flag_inline_functions)
- flag_inline_trees = 2;
/* If -pedantic, warn about the use of GNU extensions. */
if (pedantic && (gfc_option.allow_std & GFC_STD_GNU) != 0)
@@ -354,9 +352,6 @@ gfc_post_options (const char **pfilename)
gfc_option.warn_tabs = 0;
}
- if (gfc_option.flag_all_intrinsics)
- gfc_option.warn_nonstd_intrinsics = 0;
-
gfc_cpp_post_options ();
/* FIXME: return gfc_cpp_preprocess_only ();
@@ -378,10 +373,11 @@ set_Wall (int setting)
gfc_option.warn_aliasing = setting;
gfc_option.warn_ampersand = setting;
gfc_option.warn_line_truncation = setting;
- gfc_option.warn_nonstd_intrinsics = setting;
gfc_option.warn_surprising = setting;
gfc_option.warn_tabs = !setting;
gfc_option.warn_underflow = setting;
+ gfc_option.warn_intrinsic_shadow = setting;
+ gfc_option.warn_intrinsics_std = setting;
gfc_option.warn_character_truncation = setting;
set_Wunused (setting);
@@ -485,6 +481,10 @@ gfc_handle_option (size_t scode, const char *arg, int value)
gfc_option.warn_ampersand = value;
break;
+ case OPT_Warray_temporaries:
+ gfc_option.warn_array_temp = value;
+ break;
+
case OPT_Wcharacter_truncation:
gfc_option.warn_character_truncation = value;
break;
@@ -517,6 +517,10 @@ gfc_handle_option (size_t scode, const char *arg, int value)
gfc_option.warn_underflow = value;
break;
+ case OPT_Wintrinsic_shadow:
+ gfc_option.warn_intrinsic_shadow = value;
+ break;
+
case OPT_fall_intrinsics:
gfc_option.flag_all_intrinsics = 1;
break;
@@ -537,6 +541,10 @@ gfc_handle_option (size_t scode, const char *arg, int value)
gfc_option.flag_backtrace = value;
break;
+ case OPT_fcheck_array_temporaries:
+ gfc_option.flag_check_array_temporaries = value;
+ break;
+
case OPT_fdump_core:
gfc_option.flag_dump_core = value;
break;
@@ -778,8 +786,8 @@ gfc_handle_option (size_t scode, const char *arg, int value)
gfc_option.warn_std = 0;
break;
- case OPT_Wnonstd_intrinsics:
- gfc_option.warn_nonstd_intrinsics = value;
+ case OPT_Wintrinsics_std:
+ gfc_option.warn_intrinsics_std = value;
break;
case OPT_fshort_enums:
diff --git a/gcc/fortran/parse.c b/gcc/fortran/parse.c
index 781efbc205d..1a479627668 100644
--- a/gcc/fortran/parse.c
+++ b/gcc/fortran/parse.c
@@ -1533,7 +1533,7 @@ unexpected_statement (gfc_statement st)
issue an error and return FAILURE. Otherwise we return SUCCESS.
Individual parsers need to verify that the statements seen are
- valid before calling here, ie ENTRY statements are not allowed in
+ valid before calling here, i.e., ENTRY statements are not allowed in
INTERFACE blocks. The following diagram is taken from the standard:
+---------------------------------------+
@@ -3413,7 +3413,7 @@ gfc_global_used (gfc_gsymbol *sym, locus *where)
name = "MODULE";
break;
default:
- gfc_internal_error ("gfc_gsymbol_type(): Bad type");
+ gfc_internal_error ("gfc_global_used(): Bad type");
name = NULL;
}
@@ -3688,7 +3688,7 @@ done:
duplicate_main:
/* If we see a duplicate main program, shut down. If the second
- instance is an implied main program, ie data decls or executable
+ instance is an implied main program, i.e. data decls or executable
statements, we're in for lots of errors. */
gfc_error ("Two main PROGRAMs at %L and %C", &prog_locus);
reject_statement ();
diff --git a/gcc/fortran/primary.c b/gcc/fortran/primary.c
index c67f2bd1873..782f38e4425 100644
--- a/gcc/fortran/primary.c
+++ b/gcc/fortran/primary.c
@@ -2413,8 +2413,8 @@ gfc_match_rvalue (gfc_expr **result)
goto function0;
if (sym->attr.flavor == FL_UNKNOWN) sym->attr.flavor = FL_PROCEDURE;
- if (gfc_intrinsic_name (sym->name, 0)
- || gfc_intrinsic_name (sym->name, 1))
+ if (gfc_is_intrinsic (sym, 0, gfc_current_locus)
+ || gfc_is_intrinsic (sym, 1, gfc_current_locus))
sym->attr.intrinsic = 1;
e = gfc_get_expr ();
e->expr_type = EXPR_VARIABLE;
@@ -2689,7 +2689,7 @@ gfc_match_rvalue (gfc_expr **result)
}
-/* Match a variable, ie something that can be assigned to. This
+/* Match a variable, i.e. something that can be assigned to. This
starts as a symbol, can be a structure component or an array
reference. It can be a function if the function doesn't have a
separate RESULT variable. If the symbol has not been previously
@@ -2714,7 +2714,7 @@ match_variable (gfc_expr **result, int equiv_flag, int host_flag)
we force the changed_symbols mechanism to work by setting
host_flag to 0. This prevents valid symbols that have the name
of keywords, such as 'end', being turned into variables by
- failed matching to assignments for, eg., END INTERFACE. */
+ failed matching to assignments for, e.g., END INTERFACE. */
if (gfc_current_state () == COMP_MODULE
|| gfc_current_state () == COMP_INTERFACE
|| gfc_current_state () == COMP_CONTAINS)
@@ -2739,7 +2739,7 @@ match_variable (gfc_expr **result, int equiv_flag, int host_flag)
switch (sym->attr.flavor)
{
case FL_VARIABLE:
- if (sym->attr.protected && sym->attr.use_assoc)
+ if (sym->attr.is_protected && sym->attr.use_assoc)
{
gfc_error ("Assigning to PROTECTED variable at %C");
return MATCH_ERROR;
diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c
index c0ec7847747..0b27da18fd0 100644
--- a/gcc/fortran/resolve.c
+++ b/gcc/fortran/resolve.c
@@ -1,4 +1,4 @@
-/* Perform type resolution on the various stuctures.
+/* Perform type resolution on the various structures.
Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
Free Software Foundation, Inc.
Contributed by Andy Vaught
@@ -1076,7 +1076,7 @@ resolve_actual_arglist (gfc_actual_arglist *arg, procedure_type ptype)
if (!sym->attr.intrinsic
&& !(sym->attr.external || sym->attr.use_assoc
|| sym->attr.if_source == IFSRC_IFBODY)
- && gfc_intrinsic_name (sym->name, sym->attr.subroutine))
+ && gfc_is_intrinsic (sym, sym->attr.subroutine, e->where))
sym->attr.intrinsic = 1;
if (sym->attr.proc == PROC_ST_FUNCTION)
@@ -1535,7 +1535,7 @@ generic:
/* Last ditch attempt. See if the reference is to an intrinsic
that possesses a matching interface. 14.1.2.4 */
- if (sym && !gfc_intrinsic_name (sym->name, 0))
+ if (sym && !gfc_is_intrinsic (sym, 0, expr->where))
{
gfc_error ("There is no specific function for the generic '%s' at %L",
expr->symtree->n.sym->name, &expr->where);
@@ -1568,7 +1568,7 @@ resolve_specific_f0 (gfc_symbol *sym, gfc_expr *expr)
gfc_intrinsic_sym *isym;
isym = gfc_find_function (sym->ts.interface->name);
- /* Existance of isym should be checked already. */
+ /* Existence of isym should be checked already. */
gcc_assert (isym);
sym->ts.type = isym->ts.type;
@@ -1673,7 +1673,7 @@ resolve_unknown_f (gfc_expr *expr)
/* See if we have an intrinsic function reference. */
- if (gfc_intrinsic_name (sym->name, 0))
+ if (gfc_is_intrinsic (sym, 0, expr->where))
{
if (gfc_intrinsic_func_interface (expr, 1) == MATCH_YES)
return SUCCESS;
@@ -1721,13 +1721,13 @@ is_external_proc (gfc_symbol *sym)
{
if (!sym->attr.dummy && !sym->attr.contained
&& !(sym->attr.intrinsic
- || gfc_intrinsic_name (sym->name, sym->attr.subroutine))
+ || gfc_is_intrinsic (sym, sym->attr.subroutine, sym->declared_at))
&& sym->attr.proc != PROC_ST_FUNCTION
&& !sym->attr.use_assoc
&& sym->name)
return true;
- else
- return false;
+
+ return false;
}
@@ -2469,7 +2469,7 @@ generic:
that possesses a matching interface. 14.1.2.4 */
sym = c->symtree->n.sym;
- if (!gfc_intrinsic_name (sym->name, 1))
+ if (!gfc_is_intrinsic (sym, 1, c->loc))
{
gfc_error ("There is no specific subroutine for the generic '%s' at %L",
sym->name, &c->loc);
@@ -2644,7 +2644,7 @@ resolve_specific_s0 (gfc_code *c, gfc_symbol *sym)
isym = gfc_find_function (sym->ts.interface->name);
- /* Existance of isym should be checked already. */
+ /* Existence of isym should be checked already. */
gcc_assert (isym);
sym->ts.type = isym->ts.type;
@@ -2748,7 +2748,7 @@ resolve_unknown_s (gfc_code *c)
/* See if we have an intrinsic function reference. */
- if (gfc_intrinsic_name (sym->name, 1))
+ if (gfc_is_intrinsic (sym, 1, c->loc))
{
if (gfc_intrinsic_sub_interface (c, 1) == MATCH_YES)
return SUCCESS;
@@ -2903,7 +2903,7 @@ resolve_operator (gfc_expr *e)
/* Resolve all subnodes-- give them types. */
- switch (e->value.op.operator)
+ switch (e->value.op.op)
{
default:
if (gfc_resolve_expr (e->value.op.op2) == FAILURE)
@@ -2933,7 +2933,7 @@ resolve_operator (gfc_expr *e)
goto bad_op;
}
- switch (e->value.op.operator)
+ switch (e->value.op.op)
{
case INTRINSIC_UPLUS:
case INTRINSIC_UMINUS:
@@ -2946,7 +2946,7 @@ resolve_operator (gfc_expr *e)
}
sprintf (msg, _("Operand of unary numeric operator '%s' at %%L is %s"),
- gfc_op2string (e->value.op.operator), gfc_typename (&e->ts));
+ gfc_op2string (e->value.op.op), gfc_typename (&e->ts));
goto bad_op;
case INTRINSIC_PLUS:
@@ -2962,7 +2962,7 @@ resolve_operator (gfc_expr *e)
sprintf (msg,
_("Operands of binary numeric operator '%s' at %%L are %s/%s"),
- gfc_op2string (e->value.op.operator), gfc_typename (&op1->ts),
+ gfc_op2string (e->value.op.op), gfc_typename (&op1->ts),
gfc_typename (&op2->ts));
goto bad_op;
@@ -2996,7 +2996,7 @@ resolve_operator (gfc_expr *e)
}
sprintf (msg, _("Operands of logical operator '%s' at %%L are %s/%s"),
- gfc_op2string (e->value.op.operator), gfc_typename (&op1->ts),
+ gfc_op2string (e->value.op.op), gfc_typename (&op1->ts),
gfc_typename (&op2->ts));
goto bad_op;
@@ -3053,19 +3053,19 @@ resolve_operator (gfc_expr *e)
if (op1->ts.type == BT_LOGICAL && op2->ts.type == BT_LOGICAL)
sprintf (msg,
_("Logicals at %%L must be compared with %s instead of %s"),
- (e->value.op.operator == INTRINSIC_EQ
- || e->value.op.operator == INTRINSIC_EQ_OS)
- ? ".eqv." : ".neqv.", gfc_op2string (e->value.op.operator));
+ (e->value.op.op == INTRINSIC_EQ
+ || e->value.op.op == INTRINSIC_EQ_OS)
+ ? ".eqv." : ".neqv.", gfc_op2string (e->value.op.op));
else
sprintf (msg,
_("Operands of comparison operator '%s' at %%L are %s/%s"),
- gfc_op2string (e->value.op.operator), gfc_typename (&op1->ts),
+ gfc_op2string (e->value.op.op), gfc_typename (&op1->ts),
gfc_typename (&op2->ts));
goto bad_op;
case INTRINSIC_USER:
- if (e->value.op.uop->operator == NULL)
+ if (e->value.op.uop->op == NULL)
sprintf (msg, _("Unknown operator '%s' at %%L"), e->value.op.uop->name);
else if (op2 == NULL)
sprintf (msg, _("Operand of user operator '%s' at %%L is %s"),
@@ -3091,7 +3091,7 @@ resolve_operator (gfc_expr *e)
t = SUCCESS;
- switch (e->value.op.operator)
+ switch (e->value.op.op)
{
case INTRINSIC_PLUS:
case INTRINSIC_MINUS:
@@ -3185,7 +3185,7 @@ resolve_operator (gfc_expr *e)
{
t = gfc_simplify_expr (e, 0);
/* Some calls do not succeed in simplification and return FAILURE
- even though there is no error; eg. variable references to
+ even though there is no error; e.g. variable references to
PARAMETER arrays. */
if (!gfc_is_constant_expr (e))
t = SUCCESS;
@@ -4217,7 +4217,7 @@ gfc_resolve_character_operator (gfc_expr *e)
gfc_expr *e1 = NULL;
gfc_expr *e2 = NULL;
- gcc_assert (e->value.op.operator == INTRINSIC_CONCAT);
+ gcc_assert (e->value.op.op == INTRINSIC_CONCAT);
if (op1->ts.cl && op1->ts.cl->length)
e1 = gfc_copy_expr (op1->ts.cl->length);
@@ -4873,7 +4873,7 @@ check_symbols:
|| (ar->end[i] != NULL
&& gfc_find_sym_in_expr (sym, ar->end[i])))
{
- gfc_error ("'%s' must not appear an the array specification at "
+ gfc_error ("'%s' must not appear in the array specification at "
"%L in the same ALLOCATE statement where it is "
"itself allocated", sym->name, &ar->where);
return FAILURE;
@@ -5999,7 +5999,7 @@ gfc_resolve_blocks (gfc_code *b, gfc_namespace *ns)
/* Does everything to resolve an ordinary assignment. Returns true
- if this is an interface asignment. */
+ if this is an interface assignment. */
static bool
resolve_ordinary_assign (gfc_code *code, gfc_namespace *ns)
{
@@ -7251,7 +7251,7 @@ resolve_fl_procedure (gfc_symbol *sym, int mp_flag)
}
/* Ensure that derived type for are not of a private type. Internal
- module procedures are excluded by 2.2.3.3 - ie. they are not
+ module procedures are excluded by 2.2.3.3 - i.e., they are not
externally accessible and can access all the objects accessible in
the host. */
if (!(sym->ns->parent
@@ -7563,7 +7563,7 @@ gfc_resolve_finalizers (gfc_symbol* derived)
prev_link = &list->next;
continue;
- /* Remove wrong nodes immediatelly from the list so we don't risk any
+ /* Remove wrong nodes immediately from the list so we don't risk any
troubles in the future when they might fail later expectations. */
error:
result = FAILURE;
@@ -7657,7 +7657,8 @@ resolve_fl_derived (gfc_symbol *sym)
}
if (c->ts.type == BT_DERIVED && c->pointer
- && c->ts.derived->components == NULL)
+ && c->ts.derived->components == NULL
+ && !c->ts.derived->attr.zero_comp)
{
gfc_error ("The pointer component '%s' of '%s' at %L is a type "
"that has not been declared", c->name, sym->name,
@@ -7681,8 +7682,8 @@ resolve_fl_derived (gfc_symbol *sym)
for (i = 0; i < c->as->rank; i++)
{
if (c->as->lower[i] == NULL
- || !gfc_is_constant_expr (c->as->lower[i])
|| (resolve_index_expr (c->as->lower[i]) == FAILURE)
+ || !gfc_is_constant_expr (c->as->lower[i])
|| c->as->upper[i] == NULL
|| (resolve_index_expr (c->as->upper[i]) == FAILURE)
|| !gfc_is_constant_expr (c->as->upper[i]))
@@ -7960,24 +7961,45 @@ resolve_symbol (gfc_symbol *sym)
type to avoid spurious warnings. */
if (sym->attr.flavor != FL_MODULE && sym->attr.intrinsic)
{
- if (gfc_intrinsic_name (sym->name, 0))
+ gfc_intrinsic_sym* isym;
+ const char* symstd;
+
+ /* We already know this one is an intrinsic, so we don't call
+ gfc_is_intrinsic for full checking but rather use gfc_find_function and
+ gfc_find_subroutine directly to check whether it is a function or
+ subroutine. */
+
+ if ((isym = gfc_find_function (sym->name)))
{
if (sym->ts.type != BT_UNKNOWN && gfc_option.warn_surprising)
- gfc_warning ("Type specified for intrinsic function '%s' at %L is ignored",
- sym->name, &sym->declared_at);
+ gfc_warning ("Type specified for intrinsic function '%s' at %L is"
+ " ignored", sym->name, &sym->declared_at);
}
- else if (gfc_intrinsic_name (sym->name, 1))
+ else if ((isym = gfc_find_subroutine (sym->name)))
{
if (sym->ts.type != BT_UNKNOWN)
{
- gfc_error ("Intrinsic subroutine '%s' at %L shall not have a type specifier",
- sym->name, &sym->declared_at);
+ gfc_error ("Intrinsic subroutine '%s' at %L shall not have a type"
+ " specifier", sym->name, &sym->declared_at);
return;
}
}
else
{
- gfc_error ("Intrinsic '%s' at %L does not exist", sym->name, &sym->declared_at);
+ gfc_error ("'%s' declared INTRINSIC at %L does not exist",
+ sym->name, &sym->declared_at);
+ return;
+ }
+
+ /* Check it is actually available in the standard settings. */
+ if (gfc_check_intrinsic_standard (isym, &symstd, false, sym->declared_at)
+ == FAILURE)
+ {
+ gfc_error ("The intrinsic '%s' declared INTRINSIC at %L is not"
+ " available in the current standard settings but %s. Use"
+ " an appropriate -std=* option or enable -fall-intrinsics"
+ " in order to use it.",
+ sym->name, &sym->declared_at, symstd);
return;
}
}
@@ -8641,7 +8663,7 @@ resolve_data (gfc_data *d)
is storage associated with any such variable, shall not be used in the
following contexts: (clients of this function). */
-/* Determines if a variable is not 'pure', ie not assignable within a pure
+/* Determines if a variable is not 'pure', i.e., not assignable within a pure
procedure. Returns zero if assignment is OK, nonzero if there is a
problem. */
int
@@ -8961,7 +8983,7 @@ resolve_equivalence (gfc_equiv *eq)
sym = e->symtree->n.sym;
- if (sym->attr.protected)
+ if (sym->attr.is_protected)
cnt_protected++;
if (cnt_protected > 0 && cnt_protected != object)
{
@@ -9164,7 +9186,7 @@ gfc_resolve_uops (gfc_symtree *symtree)
gfc_resolve_uops (symtree->left);
gfc_resolve_uops (symtree->right);
- for (itr = symtree->n.uop->operator; itr; itr = itr->next)
+ for (itr = symtree->n.uop->op; itr; itr = itr->next)
{
sym = itr->sym;
if (!sym->attr.function)
diff --git a/gcc/fortran/scanner.c b/gcc/fortran/scanner.c
index 48f148d300a..c0becf05e2c 100644
--- a/gcc/fortran/scanner.c
+++ b/gcc/fortran/scanner.c
@@ -1672,7 +1672,7 @@ preprocessor_line (gfc_char_t *c)
}
-static try load_file (const char *, bool);
+static try load_file (const char *, const char *, bool);
/* include_line()-- Checks a line buffer to see if it is an include
line. If so, we call load_file() recursively to load the included
@@ -1743,7 +1743,7 @@ include_line (gfc_char_t *line)
read by anything else. */
filename = gfc_widechar_to_char (begin, -1);
- load_file (filename, false);
+ load_file (filename, NULL, false);
gfc_free (filename);
return true;
}
@@ -1752,7 +1752,7 @@ include_line (gfc_char_t *line)
/* Load a file into memory by calling load_line until the file ends. */
static try
-load_file (const char *filename, bool initial)
+load_file (const char *realfilename, const char *displayedname, bool initial)
{
gfc_char_t *line;
gfc_linebuf *b;
@@ -1760,6 +1760,9 @@ load_file (const char *filename, bool initial)
FILE *input;
int len, line_len;
bool first_line;
+ const char *filename;
+
+ filename = displayedname ? displayedname : realfilename;
for (f = current_file; f; f = f->up)
if (strcmp (filename, f->filename) == 0)
@@ -1776,7 +1779,7 @@ load_file (const char *filename, bool initial)
gfc_src_file = NULL;
}
else
- input = gfc_open_file (filename);
+ input = gfc_open_file (realfilename);
if (input == NULL)
{
gfc_error_now ("Can't open file '%s'", filename);
@@ -1785,7 +1788,7 @@ load_file (const char *filename, bool initial)
}
else
{
- input = gfc_open_included_file (filename, false, false);
+ input = gfc_open_included_file (realfilename, false, false);
if (input == NULL)
{
gfc_error_now ("Can't open included file '%s'", filename);
@@ -1840,11 +1843,11 @@ load_file (const char *filename, bool initial)
&& line[2] == (unsigned char) '\xBF')))
{
int n = line[1] == (unsigned char) '\xBB' ? 3 : 2;
- gfc_char_t *new = gfc_get_wide_string (line_len);
+ gfc_char_t *new_char = gfc_get_wide_string (line_len);
- wide_strcpy (new, &line[n]);
+ wide_strcpy (new_char, &line[n]);
gfc_free (line);
- line = new;
+ line = new_char;
len -= n;
}
@@ -1914,7 +1917,7 @@ load_file (const char *filename, bool initial)
/* Open a new file and start scanning from that file. Returns SUCCESS
- if everything went OK, FAILURE otherwise. If form == FORM_UKNOWN
+ if everything went OK, FAILURE otherwise. If form == FORM_UNKNOWN
it tries to determine the source form from the filename, defaulting
to free form. */
@@ -1927,10 +1930,10 @@ gfc_new_file (void)
{
result = gfc_cpp_preprocess (gfc_source_file);
if (!gfc_cpp_preprocess_only ())
- result = load_file (gfc_cpp_temporary_file (), true);
+ result = load_file (gfc_cpp_temporary_file (), gfc_source_file, true);
}
else
- result = load_file (gfc_source_file, true);
+ result = load_file (gfc_source_file, NULL, true);
gfc_current_locus.lb = line_head;
gfc_current_locus.nextc = (line_head == NULL) ? NULL : line_head->line;
diff --git a/gcc/fortran/st.c b/gcc/fortran/st.c
index ba5656b24d5..790dec6cf58 100644
--- a/gcc/fortran/st.c
+++ b/gcc/fortran/st.c
@@ -58,20 +58,20 @@ gfc_get_code (void)
its tail, returning a pointer to the new tail. */
gfc_code *
-gfc_append_code (gfc_code *tail, gfc_code *new)
+gfc_append_code (gfc_code *tail, gfc_code *new_code)
{
if (tail != NULL)
{
while (tail->next != NULL)
tail = tail->next;
- tail->next = new;
+ tail->next = new_code;
}
- while (new->next != NULL)
- new = new->next;
+ while (new_code->next != NULL)
+ new_code = new_code->next;
- return new;
+ return new_code;
}
diff --git a/gcc/fortran/symbol.c b/gcc/fortran/symbol.c
index f91ef9157c0..121f62ea2cb 100644
--- a/gcc/fortran/symbol.c
+++ b/gcc/fortran/symbol.c
@@ -272,7 +272,7 @@ gfc_set_default_type (gfc_symbol *sym, int error_flag, gfc_namespace *ns)
{
/* Dummy args to a BIND(C) routine may not be interoperable if
they are implicitly typed. */
- gfc_warning_now ("Implicity declared variable '%s' at %L may not "
+ gfc_warning_now ("Implicitly declared variable '%s' at %L may not "
"be C interoperable but it is a dummy argument to "
"the BIND(C) procedure '%s' at %L", sym->name,
&(sym->declared_at), sym->ns->proc_name->name,
@@ -344,14 +344,14 @@ check_conflict (symbol_attribute *attr, const char *name, locus *where)
*intent_in = "INTENT(IN)", *intrinsic = "INTRINSIC",
*intent_out = "INTENT(OUT)", *intent_inout = "INTENT(INOUT)",
*allocatable = "ALLOCATABLE", *elemental = "ELEMENTAL",
- *private = "PRIVATE", *recursive = "RECURSIVE",
+ *privat = "PRIVATE", *recursive = "RECURSIVE",
*in_common = "COMMON", *result = "RESULT", *in_namelist = "NAMELIST",
- *public = "PUBLIC", *optional = "OPTIONAL", *entry = "ENTRY",
+ *publik = "PUBLIC", *optional = "OPTIONAL", *entry = "ENTRY",
*function = "FUNCTION", *subroutine = "SUBROUTINE",
*dimension = "DIMENSION", *in_equivalence = "EQUIVALENCE",
*use_assoc = "USE ASSOCIATED", *cray_pointer = "CRAY POINTER",
*cray_pointee = "CRAY POINTEE", *data = "DATA", *value = "VALUE",
- *volatile_ = "VOLATILE", *protected = "PROTECTED",
+ *volatile_ = "VOLATILE", *is_protected = "PROTECTED",
*is_bind_c = "BIND(C)", *procedure = "PROCEDURE";
static const char *threadprivate = "THREADPRIVATE";
@@ -383,9 +383,9 @@ check_conflict (symbol_attribute *attr, const char *name, locus *where)
if (attr->optional)
a1 = optional;
if (attr->access == ACCESS_PRIVATE)
- a1 = private;
+ a1 = privat;
if (attr->access == ACCESS_PUBLIC)
- a1 = public;
+ a1 = publik;
if (attr->intent != INTENT_UNKNOWN)
a1 = intent;
@@ -541,9 +541,9 @@ check_conflict (symbol_attribute *attr, const char *name, locus *where)
goto conflict;
}
- conf (protected, intrinsic)
- conf (protected, external)
- conf (protected, in_common)
+ conf (is_protected, intrinsic)
+ conf (is_protected, external)
+ conf (is_protected, in_common)
conf (volatile_, intrinsic)
conf (volatile_, external)
@@ -558,7 +558,7 @@ check_conflict (symbol_attribute *attr, const char *name, locus *where)
conf (procedure, allocatable)
conf (procedure, dimension)
conf (procedure, intrinsic)
- conf (procedure, protected)
+ conf (procedure, is_protected)
conf (procedure, target)
conf (procedure, value)
conf (procedure, volatile_)
@@ -585,7 +585,7 @@ check_conflict (symbol_attribute *attr, const char *name, locus *where)
conf2 (dummy);
conf2 (volatile_);
conf2 (pointer);
- conf2 (protected);
+ conf2 (is_protected);
conf2 (target);
conf2 (external);
conf2 (intrinsic);
@@ -599,7 +599,7 @@ check_conflict (symbol_attribute *attr, const char *name, locus *where)
if (attr->access == ACCESS_PUBLIC || attr->access == ACCESS_PRIVATE)
{
- a2 = attr->access == ACCESS_PUBLIC ? public : private;
+ a2 = attr->access == ACCESS_PUBLIC ? publik : privat;
gfc_error ("%s attribute applied to %s %s at %L", a2, a1,
name, where);
return FAILURE;
@@ -684,7 +684,7 @@ check_conflict (symbol_attribute *attr, const char *name, locus *where)
conf2 (subroutine);
conf2 (entry);
conf2 (pointer);
- conf2 (protected);
+ conf2 (is_protected);
conf2 (target);
conf2 (dummy);
conf2 (in_common);
@@ -976,7 +976,7 @@ gfc_add_protected (symbol_attribute *attr, const char *name, locus *where)
if (check_used (attr, name, where))
return FAILURE;
- if (attr->protected)
+ if (attr->is_protected)
{
if (gfc_notify_std (GFC_STD_LEGACY,
"Duplicate PROTECTED attribute specified at %L",
@@ -985,7 +985,7 @@ gfc_add_protected (symbol_attribute *attr, const char *name, locus *where)
return FAILURE;
}
- attr->protected = 1;
+ attr->is_protected = 1;
return check_conflict (attr, name, where);
}
@@ -1582,7 +1582,7 @@ gfc_copy_attr (symbol_attribute *dest, symbol_attribute *src, locus *where)
goto fail;
if (src->pointer && gfc_add_pointer (dest, where) == FAILURE)
goto fail;
- if (src->protected && gfc_add_protected (dest, NULL, where) == FAILURE)
+ if (src->is_protected && gfc_add_protected (dest, NULL, where) == FAILURE)
goto fail;
if (src->save && gfc_add_save (dest, NULL, where) == FAILURE)
goto fail;
@@ -2451,7 +2451,7 @@ static void
save_symbol_data (gfc_symbol *sym)
{
- if (sym->new || sym->old_symbol != NULL)
+ if (sym->gfc_new || sym->old_symbol != NULL)
return;
sym->old_symbol = XCNEW (gfc_symbol);
@@ -2495,7 +2495,7 @@ gfc_get_sym_tree (const char *name, gfc_namespace *ns, gfc_symtree **result)
p->old_symbol = NULL;
p->tlink = changed_syms;
p->mark = 1;
- p->new = 1;
+ p->gfc_new = 1;
changed_syms = p;
st = gfc_new_symtree (&ns->sym_root, name);
@@ -2643,7 +2643,7 @@ gfc_undo_symbols (void)
{
q = p->tlink;
- if (p->new)
+ if (p->gfc_new)
{
/* Symbol was new. */
if (p->attr.in_common && p->common_block->head)
@@ -2779,7 +2779,7 @@ gfc_commit_symbols (void)
q = p->tlink;
p->tlink = NULL;
p->mark = 0;
- p->new = 0;
+ p->gfc_new = 0;
free_old_symbol (p);
}
changed_syms = NULL;
@@ -2808,7 +2808,7 @@ gfc_commit_symbol (gfc_symbol *sym)
sym->tlink = NULL;
sym->mark = 0;
- sym->new = 0;
+ sym->gfc_new = 0;
free_old_symbol (sym);
}
@@ -2843,7 +2843,7 @@ free_uop_tree (gfc_symtree *uop_tree)
free_uop_tree (uop_tree->left);
free_uop_tree (uop_tree->right);
- gfc_free_interface (uop_tree->n.uop->operator);
+ gfc_free_interface (uop_tree->n.uop->op);
gfc_free (uop_tree->n.uop);
gfc_free (uop_tree);
@@ -2997,7 +2997,7 @@ gfc_free_namespace (gfc_namespace *ns)
gfc_free_equiv_lists (ns->equiv_lists);
for (i = GFC_INTRINSIC_BEGIN; i != GFC_INTRINSIC_END; i++)
- gfc_free_interface (ns->operator[i]);
+ gfc_free_interface (ns->op[i]);
gfc_free_data (ns->data);
p = ns->contained;
diff --git a/gcc/fortran/trans-array.c b/gcc/fortran/trans-array.c
index 2a966988dec..fe6b63de90b 100644
--- a/gcc/fortran/trans-array.c
+++ b/gcc/fortran/trans-array.c
@@ -39,7 +39,7 @@ along with GCC; see the file COPYING3. If not see
In fortran all the rhs values of an assignment must be evaluated before
any assignments take place. This can require a temporary array to store the
values. We also require a temporary when we are passing array expressions
- or vector subecripts as procedure parameters.
+ or vector subscripts as procedure parameters.
Array sections are passed without copying to a temporary. These use the
scalarizer to determine the shape of the section. The flag
@@ -80,7 +80,7 @@ along with GCC; see the file COPYING3. If not see
#include "system.h"
#include "coretypes.h"
#include "tree.h"
-#include "tree-gimple.h"
+#include "gimple.h"
#include "ggc.h"
#include "toplev.h"
#include "real.h"
@@ -161,12 +161,10 @@ gfc_conv_descriptor_data_get (tree desc)
This function gets called through the following macros:
gfc_conv_descriptor_data_set
- gfc_conv_descriptor_data_set_tuples. */
+ gfc_conv_descriptor_data_set. */
void
-gfc_conv_descriptor_data_set_internal (stmtblock_t *block,
- tree desc, tree value,
- bool tuples_p)
+gfc_conv_descriptor_data_set (stmtblock_t *block, tree desc, tree value)
{
tree field, type, t;
@@ -177,7 +175,7 @@ gfc_conv_descriptor_data_set_internal (stmtblock_t *block,
gcc_assert (DATA_FIELD == 0);
t = fold_build3 (COMPONENT_REF, TREE_TYPE (field), desc, field, NULL_TREE);
- gfc_add_modify (block, t, fold_convert (TREE_TYPE (field), value), tuples_p);
+ gfc_add_modify (block, t, fold_convert (TREE_TYPE (field), value));
}
@@ -547,7 +545,7 @@ gfc_trans_allocate_array_storage (stmtblock_t * pre, stmtblock_t * post,
/* The offset is zero because we create temporaries with a zero
lower bound. */
tmp = gfc_conv_descriptor_offset (desc);
- gfc_add_modify_expr (pre, tmp, gfc_index_zero_node);
+ gfc_add_modify (pre, tmp, gfc_index_zero_node);
if (dealloc && !onstack)
{
@@ -576,7 +574,7 @@ tree
gfc_trans_create_temp_array (stmtblock_t * pre, stmtblock_t * post,
gfc_loopinfo * loop, gfc_ss_info * info,
tree eltype, bool dynamic, bool dealloc,
- bool callee_alloc)
+ bool callee_alloc, locus * where)
{
tree type;
tree desc;
@@ -589,6 +587,10 @@ gfc_trans_create_temp_array (stmtblock_t * pre, stmtblock_t * post,
int dim;
gcc_assert (info->dimen > 0);
+
+ if (gfc_option.warn_array_temp && where)
+ gfc_warning ("Creating array temporary at %L", where);
+
/* Set the lower bound to zero. */
for (dim = 0; dim < info->dimen; dim++)
{
@@ -623,7 +625,7 @@ gfc_trans_create_temp_array (stmtblock_t * pre, stmtblock_t * post,
/* Fill in the array dtype. */
tmp = gfc_conv_descriptor_dtype (desc);
- gfc_add_modify_expr (pre, tmp, gfc_get_dtype (TREE_TYPE (desc)));
+ gfc_add_modify (pre, tmp, gfc_get_dtype (TREE_TYPE (desc)));
/*
Fill in the bounds and stride. This is a packed array, so:
@@ -657,13 +659,13 @@ gfc_trans_create_temp_array (stmtblock_t * pre, stmtblock_t * post,
/* Store the stride and bound components in the descriptor. */
tmp = gfc_conv_descriptor_stride (desc, gfc_rank_cst[n]);
- gfc_add_modify_expr (pre, tmp, size);
+ gfc_add_modify (pre, tmp, size);
tmp = gfc_conv_descriptor_lbound (desc, gfc_rank_cst[n]);
- gfc_add_modify_expr (pre, tmp, gfc_index_zero_node);
+ gfc_add_modify (pre, tmp, gfc_index_zero_node);
tmp = gfc_conv_descriptor_ubound (desc, gfc_rank_cst[n]);
- gfc_add_modify_expr (pre, tmp, loop->to[n]);
+ gfc_add_modify (pre, tmp, loop->to[n]);
tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
loop->to[n], gfc_index_one_node);
@@ -748,7 +750,7 @@ gfc_conv_array_transpose (gfc_se * se, gfc_expr * expr)
se->expr = dest;
/* Copy across the dtype field. */
- gfc_add_modify_expr (&se->pre,
+ gfc_add_modify (&se->pre,
gfc_conv_descriptor_dtype (dest),
gfc_conv_descriptor_dtype (src));
@@ -765,15 +767,15 @@ gfc_conv_array_transpose (gfc_se * se, gfc_expr * expr)
dest_index = gfc_rank_cst[n];
src_index = gfc_rank_cst[1 - n];
- gfc_add_modify_expr (&se->pre,
+ gfc_add_modify (&se->pre,
gfc_conv_descriptor_stride (dest, dest_index),
gfc_conv_descriptor_stride (src, src_index));
- gfc_add_modify_expr (&se->pre,
+ gfc_add_modify (&se->pre,
gfc_conv_descriptor_lbound (dest, dest_index),
gfc_conv_descriptor_lbound (src, src_index));
- gfc_add_modify_expr (&se->pre,
+ gfc_add_modify (&se->pre,
gfc_conv_descriptor_ubound (dest, dest_index),
gfc_conv_descriptor_ubound (src, src_index));
@@ -799,7 +801,7 @@ gfc_conv_array_transpose (gfc_se * se, gfc_expr * expr)
else
dest_info->offset = gfc_index_zero_node;
- gfc_add_modify_expr (&se->pre,
+ gfc_add_modify (&se->pre,
gfc_conv_descriptor_offset (dest),
dest_info->offset);
@@ -843,7 +845,7 @@ gfc_grow_array (stmtblock_t * pblock, tree desc, tree extra)
/* Add EXTRA to the upper bound. */
tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type, ubound, extra);
- gfc_add_modify_expr (pblock, ubound, tmp);
+ gfc_add_modify (pblock, ubound, tmp);
/* Get the value of the current data pointer. */
arg0 = gfc_conv_descriptor_data_get (desc);
@@ -953,7 +955,7 @@ gfc_put_offset_into_var (stmtblock_t * pblock, tree * poffset,
/* We should have already created the offset variable. We cannot
create it here because we may be in an inner scope. */
gcc_assert (*offsetvar != NULL_TREE);
- gfc_add_modify_expr (pblock, *offsetvar, *poffset);
+ gfc_add_modify (pblock, *offsetvar, *poffset);
*poffset = *offsetvar;
TREE_USED (*offsetvar) = 1;
}
@@ -992,7 +994,7 @@ gfc_trans_array_ctor_element (stmtblock_t * pblock, tree desc,
{
/* The temporary is an array of pointers. */
se->expr = fold_convert (TREE_TYPE (tmp), se->expr);
- gfc_add_modify_expr (&se->pre, tmp, se->expr);
+ gfc_add_modify (&se->pre, tmp, se->expr);
}
else
{
@@ -1007,7 +1009,7 @@ gfc_trans_array_ctor_element (stmtblock_t * pblock, tree desc,
{
if (first_len)
{
- gfc_add_modify_expr (&se->pre, first_len_val,
+ gfc_add_modify (&se->pre, first_len_val,
se->string_length);
first_len = false;
}
@@ -1018,7 +1020,7 @@ gfc_trans_array_ctor_element (stmtblock_t * pblock, tree desc,
tree cond = fold_build2 (NE_EXPR, boolean_type_node,
first_len_val, se->string_length);
gfc_trans_runtime_check
- (cond, &se->pre, &expr->where,
+ (true, false, cond, &se->pre, &expr->where,
"Different CHARACTER lengths (%ld/%ld) in array constructor",
fold_convert (long_integer_type_node, first_len_val),
fold_convert (long_integer_type_node, se->string_length));
@@ -1029,7 +1031,7 @@ gfc_trans_array_ctor_element (stmtblock_t * pblock, tree desc,
{
/* TODO: Should the frontend already have done this conversion? */
se->expr = fold_convert (TREE_TYPE (tmp), se->expr);
- gfc_add_modify_expr (&se->pre, tmp, se->expr);
+ gfc_add_modify (&se->pre, tmp, se->expr);
}
gfc_add_block_to_block (pblock, &se->pre);
@@ -1070,7 +1072,7 @@ gfc_trans_array_constructor_subarray (stmtblock_t * pblock,
/* Initialize the loop. */
gfc_conv_ss_startstride (&loop);
- gfc_conv_loop_setup (&loop);
+ gfc_conv_loop_setup (&loop, &expr->where);
/* Make sure the constructed array has room for the new data. */
if (dynamic)
@@ -1100,7 +1102,7 @@ gfc_trans_array_constructor_subarray (stmtblock_t * pblock,
/* Increment the offset. */
tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
*poffset, gfc_index_one_node);
- gfc_add_modify_expr (&body, *poffset, tmp);
+ gfc_add_modify (&body, *poffset, tmp);
/* Finish the loop. */
gfc_trans_scalarizing_loops (&loop, &body);
@@ -1239,7 +1241,7 @@ gfc_trans_array_constructor_value (stmtblock_t * pblock, tree type,
}
if (!INTEGER_CST_P (*poffset))
{
- gfc_add_modify_expr (&body, *offsetvar, *poffset);
+ gfc_add_modify (&body, *offsetvar, *poffset);
*poffset = *offsetvar;
}
}
@@ -1285,13 +1287,13 @@ gfc_trans_array_constructor_value (stmtblock_t * pblock, tree type,
/* Make a temporary, store the current value in that
and return it, once the loop is done. */
tmp_loopvar = gfc_create_var (TREE_TYPE (loopvar), "loopvar");
- gfc_add_modify_expr (pblock, tmp_loopvar, loopvar);
+ gfc_add_modify (pblock, tmp_loopvar, loopvar);
/* Initialize the loop. */
gfc_init_se (&se, NULL);
gfc_conv_expr_val (&se, c->iterator->start);
gfc_add_block_to_block (pblock, &se.pre);
- gfc_add_modify_expr (pblock, loopvar, se.expr);
+ gfc_add_modify (pblock, loopvar, se.expr);
gfc_init_se (&se, NULL);
gfc_conv_expr_val (&se, c->iterator->end);
@@ -1344,7 +1346,7 @@ gfc_trans_array_constructor_value (stmtblock_t * pblock, tree type,
/* Increase loop variable by step. */
tmp = fold_build2 (PLUS_EXPR, TREE_TYPE (loopvar), loopvar, step);
- gfc_add_modify_expr (&body, loopvar, tmp);
+ gfc_add_modify (&body, loopvar, tmp);
/* Finish the loop. */
tmp = gfc_finish_block (&body);
@@ -1356,7 +1358,7 @@ gfc_trans_array_constructor_value (stmtblock_t * pblock, tree type,
gfc_add_expr_to_block (pblock, tmp);
/* Restore the original value of the loop counter. */
- gfc_add_modify_expr (pblock, loopvar, tmp_loopvar);
+ gfc_add_modify (pblock, loopvar, tmp_loopvar);
}
}
mpz_clear (size);
@@ -1645,7 +1647,7 @@ gfc_trans_constant_array_constructor (gfc_loopinfo * loop,
/* Helper routine of gfc_trans_array_constructor to determine if the
bounds of the loop specified by LOOP are constant and simple enough
to use with gfc_trans_constant_array_constructor. Returns the
- the iteration count of the loop if suitable, and NULL_TREE otherwise. */
+ iteration count of the loop if suitable, and NULL_TREE otherwise. */
static tree
constant_array_constructor_loop_size (gfc_loopinfo * loop)
@@ -1683,7 +1685,7 @@ constant_array_constructor_loop_size (gfc_loopinfo * loop)
simplest method. */
static void
-gfc_trans_array_constructor (gfc_loopinfo * loop, gfc_ss * ss)
+gfc_trans_array_constructor (gfc_loopinfo * loop, gfc_ss * ss, locus * where)
{
gfc_constructor *c;
tree offset;
@@ -1809,7 +1811,7 @@ gfc_trans_array_constructor (gfc_loopinfo * loop, gfc_ss * ss)
loopfrom = NULL_TREE;
gfc_trans_create_temp_array (&loop->pre, &loop->post, loop, &ss->data.info,
- type, dynamic, true, false);
+ type, dynamic, true, false, where);
if (loopfrom != NULL_TREE)
{
@@ -1896,13 +1898,14 @@ gfc_set_vector_loop_bounds (gfc_loopinfo * loop, gfc_ss_info * info)
but before the actual scalarizing loops. */
static void
-gfc_add_loop_ss_code (gfc_loopinfo * loop, gfc_ss * ss, bool subscript)
+gfc_add_loop_ss_code (gfc_loopinfo * loop, gfc_ss * ss, bool subscript,
+ locus * where)
{
gfc_se se;
int n;
- /* TODO: This can generate bad code if there are ordering dependencies.
- eg. a callee allocated function and an unknown size constructor. */
+ /* TODO: This can generate bad code if there are ordering dependencies,
+ e.g., a callee allocated function and an unknown size constructor. */
gcc_assert (ss != NULL);
for (; ss != gfc_ss_terminator; ss = ss->loop_chain)
@@ -1950,7 +1953,8 @@ gfc_add_loop_ss_code (gfc_loopinfo * loop, gfc_ss * ss, bool subscript)
/* Add the expressions for scalar and vector subscripts. */
for (n = 0; n < GFC_MAX_DIMENSIONS; n++)
if (ss->data.info.subscript[n])
- gfc_add_loop_ss_code (loop, ss->data.info.subscript[n], true);
+ gfc_add_loop_ss_code (loop, ss->data.info.subscript[n], true,
+ where);
gfc_set_vector_loop_bounds (loop, &ss->data.info);
break;
@@ -1993,7 +1997,7 @@ gfc_add_loop_ss_code (gfc_loopinfo * loop, gfc_ss * ss, bool subscript)
gfc_add_block_to_block (&loop->pre, &se.pre);
gfc_add_block_to_block (&loop->post, &se.post);
}
- gfc_trans_array_constructor (loop, ss);
+ gfc_trans_array_constructor (loop, ss, where);
break;
case GFC_SS_TEMP:
@@ -2229,7 +2233,7 @@ gfc_trans_array_bound_check (gfc_se * se, tree descriptor, tree index, int n,
else
asprintf (&msg, "%s, lower bound of dimension %d exceeded (%%ld < %%ld)",
gfc_msg_fault, n+1);
- gfc_trans_runtime_check (fault, &se->pre, where, msg,
+ gfc_trans_runtime_check (true, false, fault, &se->pre, where, msg,
fold_convert (long_integer_type_node, index),
fold_convert (long_integer_type_node, tmp));
gfc_free (msg);
@@ -2245,7 +2249,7 @@ gfc_trans_array_bound_check (gfc_se * se, tree descriptor, tree index, int n,
else
asprintf (&msg, "%s, upper bound of dimension %d exceeded (%%ld > %%ld)",
gfc_msg_fault, n+1);
- gfc_trans_runtime_check (fault, &se->pre, where, msg,
+ gfc_trans_runtime_check (true, false, fault, &se->pre, where, msg,
fold_convert (long_integer_type_node, index),
fold_convert (long_integer_type_node, tmp));
gfc_free (msg);
@@ -2439,7 +2443,7 @@ gfc_conv_array_ref (gfc_se * se, gfc_array_ref * ar, gfc_symbol * sym,
asprintf (&msg, "%s for array '%s', "
"lower bound of dimension %d exceeded (%%ld < %%ld)",
gfc_msg_fault, sym->name, n+1);
- gfc_trans_runtime_check (cond, &se->pre, where, msg,
+ gfc_trans_runtime_check (true, false, cond, &se->pre, where, msg,
fold_convert (long_integer_type_node,
indexse.expr),
fold_convert (long_integer_type_node, tmp));
@@ -2456,7 +2460,7 @@ gfc_conv_array_ref (gfc_se * se, gfc_array_ref * ar, gfc_symbol * sym,
asprintf (&msg, "%s for array '%s', "
"upper bound of dimension %d exceeded (%%ld > %%ld)",
gfc_msg_fault, sym->name, n+1);
- gfc_trans_runtime_check (cond, &se->pre, where, msg,
+ gfc_trans_runtime_check (true, false, cond, &se->pre, where, msg,
fold_convert (long_integer_type_node,
indexse.expr),
fold_convert (long_integer_type_node, tmp));
@@ -2634,7 +2638,7 @@ gfc_trans_scalarized_loop_end (gfc_loopinfo * loop, int n,
loopbody = gfc_finish_block (pbody);
/* Initialize the loopvar. */
- gfc_add_modify_expr (&loop->code[n], loop->loopvar[n], loop->from[n]);
+ gfc_add_modify (&loop->code[n], loop->loopvar[n], loop->from[n]);
exit_label = gfc_build_label_decl (NULL_TREE);
@@ -2655,7 +2659,7 @@ gfc_trans_scalarized_loop_end (gfc_loopinfo * loop, int n,
/* Increment the loopvar. */
tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
loop->loopvar[n], gfc_index_one_node);
- gfc_add_modify_expr (&block, loop->loopvar[n], tmp);
+ gfc_add_modify (&block, loop->loopvar[n], tmp);
/* Build the loop. */
tmp = gfc_finish_block (&block);
@@ -3020,7 +3024,8 @@ gfc_conv_ss_startstride (gfc_loopinfo * loop)
asprintf (&msg, "Zero stride is not allowed, for dimension %d "
"of array '%s'", info->dim[n]+1,
ss->expr->symtree->name);
- gfc_trans_runtime_check (tmp, &inner, &ss->expr->where, msg);
+ gfc_trans_runtime_check (true, false, tmp, &inner,
+ &ss->expr->where, msg);
gfc_free (msg);
desc = ss->data.info.descriptor;
@@ -3062,7 +3067,8 @@ gfc_conv_ss_startstride (gfc_loopinfo * loop)
asprintf (&msg, "%s, lower bound of dimension %d of array '%s'"
" exceeded (%%ld < %%ld)", gfc_msg_fault,
info->dim[n]+1, ss->expr->symtree->name);
- gfc_trans_runtime_check (tmp, &inner, &ss->expr->where, msg,
+ gfc_trans_runtime_check (true, false, tmp, &inner,
+ &ss->expr->where, msg,
fold_convert (long_integer_type_node,
info->start[n]),
fold_convert (long_integer_type_node,
@@ -3078,7 +3084,8 @@ gfc_conv_ss_startstride (gfc_loopinfo * loop)
asprintf (&msg, "%s, upper bound of dimension %d of array "
"'%s' exceeded (%%ld > %%ld)", gfc_msg_fault,
info->dim[n]+1, ss->expr->symtree->name);
- gfc_trans_runtime_check (tmp, &inner, &ss->expr->where, msg,
+ gfc_trans_runtime_check (true, false, tmp, &inner,
+ &ss->expr->where, msg,
fold_convert (long_integer_type_node, info->start[n]),
fold_convert (long_integer_type_node, ubound));
gfc_free (msg);
@@ -3100,7 +3107,8 @@ gfc_conv_ss_startstride (gfc_loopinfo * loop)
asprintf (&msg, "%s, lower bound of dimension %d of array '%s'"
" exceeded (%%ld < %%ld)", gfc_msg_fault,
info->dim[n]+1, ss->expr->symtree->name);
- gfc_trans_runtime_check (tmp, &inner, &ss->expr->where, msg,
+ gfc_trans_runtime_check (true, false, tmp, &inner,
+ &ss->expr->where, msg,
fold_convert (long_integer_type_node,
tmp2),
fold_convert (long_integer_type_node,
@@ -3115,7 +3123,8 @@ gfc_conv_ss_startstride (gfc_loopinfo * loop)
asprintf (&msg, "%s, upper bound of dimension %d of array "
"'%s' exceeded (%%ld > %%ld)", gfc_msg_fault,
info->dim[n]+1, ss->expr->symtree->name);
- gfc_trans_runtime_check (tmp, &inner, &ss->expr->where, msg,
+ gfc_trans_runtime_check (true, false, tmp, &inner,
+ &ss->expr->where, msg,
fold_convert (long_integer_type_node, tmp2),
fold_convert (long_integer_type_node, ubound));
gfc_free (msg);
@@ -3138,7 +3147,8 @@ gfc_conv_ss_startstride (gfc_loopinfo * loop)
asprintf (&msg, "%s, size mismatch for dimension %d "
"of array '%s' (%%ld/%%ld)", gfc_msg_bounds,
info->dim[n]+1, ss->expr->symtree->name);
- gfc_trans_runtime_check (tmp3, &inner, &ss->expr->where, msg,
+ gfc_trans_runtime_check (true, false, tmp3, &inner,
+ &ss->expr->where, msg,
fold_convert (long_integer_type_node, tmp),
fold_convert (long_integer_type_node, size[n]));
gfc_free (msg);
@@ -3327,7 +3337,7 @@ gfc_conv_resolve_dependencies (gfc_loopinfo * loop, gfc_ss * dest,
moved outside the loop. */
void
-gfc_conv_loop_setup (gfc_loopinfo * loop)
+gfc_conv_loop_setup (gfc_loopinfo * loop, locus * where)
{
int n;
int dim;
@@ -3493,7 +3503,7 @@ gfc_conv_loop_setup (gfc_loopinfo * loop)
/* Add all the scalar code that can be taken out of the loops.
This may include calculating the loop bounds, so do it before
allocating the temporary. */
- gfc_add_loop_ss_code (loop, loop->ss, false);
+ gfc_add_loop_ss_code (loop, loop->ss, false, where);
/* If we want a temporary then create it. */
if (loop->temp_ss != NULL)
@@ -3515,7 +3525,7 @@ gfc_conv_loop_setup (gfc_loopinfo * loop)
loop->temp_ss->data.info.dimen = n;
gfc_trans_create_temp_array (&loop->pre, &loop->post, loop,
&loop->temp_ss->data.info, tmp, false, true,
- false);
+ false, where);
}
for (n = 0; n < loop->temp_dim; n++)
@@ -3609,7 +3619,7 @@ gfc_array_init_size (tree descriptor, int rank, tree * poffset,
/* Set the dtype. */
tmp = gfc_conv_descriptor_dtype (descriptor);
- gfc_add_modify_expr (pblock, tmp, gfc_get_dtype (TREE_TYPE (descriptor)));
+ gfc_add_modify (pblock, tmp, gfc_get_dtype (TREE_TYPE (descriptor)));
or_expr = NULL_TREE;
@@ -3640,7 +3650,7 @@ gfc_array_init_size (tree descriptor, int rank, tree * poffset,
}
}
tmp = gfc_conv_descriptor_lbound (descriptor, gfc_rank_cst[n]);
- gfc_add_modify_expr (pblock, tmp, se.expr);
+ gfc_add_modify (pblock, tmp, se.expr);
/* Work out the offset for this component. */
tmp = fold_build2 (MULT_EXPR, gfc_array_index_type, se.expr, stride);
@@ -3657,11 +3667,11 @@ gfc_array_init_size (tree descriptor, int rank, tree * poffset,
gfc_add_block_to_block (pblock, &se.pre);
tmp = gfc_conv_descriptor_ubound (descriptor, gfc_rank_cst[n]);
- gfc_add_modify_expr (pblock, tmp, se.expr);
+ gfc_add_modify (pblock, tmp, se.expr);
/* Store the stride. */
tmp = gfc_conv_descriptor_stride (descriptor, gfc_rank_cst[n]);
- gfc_add_modify_expr (pblock, tmp, stride);
+ gfc_add_modify (pblock, tmp, stride);
/* Calculate the size of this dimension. */
size = fold_build2 (PLUS_EXPR, gfc_array_index_type, se.expr, size);
@@ -3701,11 +3711,11 @@ gfc_array_init_size (tree descriptor, int rank, tree * poffset,
var = gfc_create_var (TREE_TYPE (size), "size");
gfc_start_block (&thenblock);
- gfc_add_modify_expr (&thenblock, var, gfc_index_zero_node);
+ gfc_add_modify (&thenblock, var, gfc_index_zero_node);
thencase = gfc_finish_block (&thenblock);
gfc_start_block (&elseblock);
- gfc_add_modify_expr (&elseblock, var, size);
+ gfc_add_modify (&elseblock, var, size);
elsecase = gfc_finish_block (&elseblock);
tmp = gfc_evaluate_now (or_expr, pblock);
@@ -3791,7 +3801,7 @@ gfc_array_allocate (gfc_se * se, gfc_expr * expr, tree pstat)
gfc_add_expr_to_block (&se->pre, tmp);
tmp = gfc_conv_descriptor_offset (se->expr);
- gfc_add_modify_expr (&se->pre, tmp, offset);
+ gfc_add_modify (&se->pre, tmp, offset);
if (expr->ts.type == BT_DERIVED
&& expr->ts.derived->attr.alloc_comp)
@@ -3989,7 +3999,7 @@ gfc_trans_array_bounds (tree type, gfc_symbol * sym, tree * poffset,
gfc_init_se (&se, NULL);
gfc_conv_expr_type (&se, as->lower[dim], gfc_array_index_type);
gfc_add_block_to_block (pblock, &se.pre);
- gfc_add_modify_expr (pblock, lbound, se.expr);
+ gfc_add_modify (pblock, lbound, se.expr);
}
ubound = GFC_TYPE_ARRAY_UBOUND (type, dim);
if (as->upper[dim] && !INTEGER_CST_P (ubound))
@@ -3997,7 +4007,7 @@ gfc_trans_array_bounds (tree type, gfc_symbol * sym, tree * poffset,
gfc_init_se (&se, NULL);
gfc_conv_expr_type (&se, as->upper[dim], gfc_array_index_type);
gfc_add_block_to_block (pblock, &se.pre);
- gfc_add_modify_expr (pblock, ubound, se.expr);
+ gfc_add_modify (pblock, ubound, se.expr);
}
/* The offset of this dimension. offset = offset - lbound * stride. */
tmp = fold_build2 (MULT_EXPR, gfc_array_index_type, lbound, size);
@@ -4017,7 +4027,7 @@ gfc_trans_array_bounds (tree type, gfc_symbol * sym, tree * poffset,
tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type, ubound, tmp);
tmp = fold_build2 (MULT_EXPR, gfc_array_index_type, size, tmp);
if (stride)
- gfc_add_modify_expr (pblock, stride, tmp);
+ gfc_add_modify (pblock, stride, tmp);
else
stride = gfc_evaluate_now (tmp, pblock);
@@ -4027,7 +4037,7 @@ gfc_trans_array_bounds (tree type, gfc_symbol * sym, tree * poffset,
stride, gfc_index_zero_node);
tmp = fold_build3 (COND_EXPR, gfc_array_index_type, tmp,
stride, gfc_index_zero_node);
- gfc_add_modify_expr (pblock, stride, tmp);
+ gfc_add_modify (pblock, stride, tmp);
}
size = stride;
@@ -4100,7 +4110,7 @@ gfc_trans_auto_array_allocation (tree decl, gfc_symbol * sym, tree fnbody)
if (sym->attr.cray_pointee)
{
if (TREE_CODE (GFC_TYPE_ARRAY_OFFSET (type)) == VAR_DECL)
- gfc_add_modify_expr (&block, GFC_TYPE_ARRAY_OFFSET (type), offset);
+ gfc_add_modify (&block, GFC_TYPE_ARRAY_OFFSET (type), offset);
gfc_add_expr_to_block (&block, fnbody);
return gfc_finish_block (&block);
}
@@ -4113,11 +4123,11 @@ gfc_trans_auto_array_allocation (tree decl, gfc_symbol * sym, tree fnbody)
/* Allocate memory to hold the data. */
tmp = gfc_call_malloc (&block, TREE_TYPE (decl), size);
- gfc_add_modify_expr (&block, decl, tmp);
+ gfc_add_modify (&block, decl, tmp);
/* Set offset of the array. */
if (TREE_CODE (GFC_TYPE_ARRAY_OFFSET (type)) == VAR_DECL)
- gfc_add_modify_expr (&block, GFC_TYPE_ARRAY_OFFSET (type), offset);
+ gfc_add_modify (&block, GFC_TYPE_ARRAY_OFFSET (type), offset);
/* Automatic arrays should not have initializers. */
@@ -4165,13 +4175,13 @@ gfc_trans_g77_array (gfc_symbol * sym, tree body)
/* Set the offset. */
if (TREE_CODE (GFC_TYPE_ARRAY_OFFSET (type)) == VAR_DECL)
- gfc_add_modify_expr (&block, GFC_TYPE_ARRAY_OFFSET (type), offset);
+ gfc_add_modify (&block, GFC_TYPE_ARRAY_OFFSET (type), offset);
/* Set the pointer itself if we aren't using the parameter directly. */
if (TREE_CODE (parm) != PARM_DECL)
{
tmp = convert (TREE_TYPE (parm), GFC_DECL_SAVED_DESCRIPTOR (parm));
- gfc_add_modify_expr (&block, parm, tmp);
+ gfc_add_modify (&block, parm, tmp);
}
stmt = gfc_finish_block (&block);
@@ -4266,7 +4276,7 @@ gfc_trans_dummy_array_bias (gfc_symbol * sym, tree tmpdesc, tree body)
TREE_USED (partial) = 1;
tmp = gfc_conv_descriptor_stride (dumdesc, gfc_rank_cst[0]);
tmp = fold_build2 (EQ_EXPR, boolean_type_node, tmp, gfc_index_one_node);
- gfc_add_modify_expr (&block, partial, tmp);
+ gfc_add_modify (&block, partial, tmp);
}
else
{
@@ -4286,7 +4296,7 @@ gfc_trans_dummy_array_bias (gfc_symbol * sym, tree tmpdesc, tree body)
tmp = fold_build3 (COND_EXPR, gfc_array_index_type, tmp,
gfc_index_one_node, stride);
stride = GFC_TYPE_ARRAY_STRIDE (type, 0);
- gfc_add_modify_expr (&block, stride, tmp);
+ gfc_add_modify (&block, stride, tmp);
/* Allow the user to disable array repacking. */
stmt_unpacked = NULL_TREE;
@@ -4299,6 +4309,9 @@ gfc_trans_dummy_array_bias (gfc_symbol * sym, tree tmpdesc, tree body)
stmt_unpacked = build_call_expr (gfor_fndecl_in_pack, 1, tmp);
stride = gfc_index_one_node;
+
+ if (gfc_option.warn_array_temp)
+ gfc_warning ("Creating array temporary at %L", &loc);
}
/* This is for the case where the array data is used directly without
@@ -4317,7 +4330,7 @@ gfc_trans_dummy_array_bias (gfc_symbol * sym, tree tmpdesc, tree body)
}
else
tmp = stmt_packed != NULL_TREE ? stmt_packed : stmt_unpacked;
- gfc_add_modify_expr (&block, tmpdesc, fold_convert (type, tmp));
+ gfc_add_modify (&block, tmpdesc, fold_convert (type, tmp));
offset = gfc_index_zero_node;
size = gfc_index_one_node;
@@ -4344,7 +4357,7 @@ gfc_trans_dummy_array_bias (gfc_symbol * sym, tree tmpdesc, tree body)
gfc_conv_expr_type (&se, sym->as->lower[n],
gfc_array_index_type);
gfc_add_block_to_block (&block, &se.pre);
- gfc_add_modify_expr (&block, lbound, se.expr);
+ gfc_add_modify (&block, lbound, se.expr);
}
ubound = GFC_TYPE_ARRAY_UBOUND (type, n);
@@ -4358,7 +4371,7 @@ gfc_trans_dummy_array_bias (gfc_symbol * sym, tree tmpdesc, tree body)
gfc_conv_expr_type (&se, sym->as->upper[n],
gfc_array_index_type);
gfc_add_block_to_block (&block, &se.pre);
- gfc_add_modify_expr (&block, ubound, se.expr);
+ gfc_add_modify (&block, ubound, se.expr);
}
/* Check the sizes match. */
@@ -4374,7 +4387,7 @@ gfc_trans_dummy_array_bias (gfc_symbol * sym, tree tmpdesc, tree body)
tmp = fold_build2 (NE_EXPR, gfc_array_index_type, tmp, stride2);
asprintf (&msg, "%s for dimension %d of array '%s'",
gfc_msg_bounds, n+1, sym->name);
- gfc_trans_runtime_check (tmp, &block, &loc, msg);
+ gfc_trans_runtime_check (true, false, tmp, &block, &loc, msg);
gfc_free (msg);
}
}
@@ -4385,7 +4398,7 @@ gfc_trans_dummy_array_bias (gfc_symbol * sym, tree tmpdesc, tree body)
tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
dubound, dlbound);
tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type, tmp, lbound);
- gfc_add_modify_expr (&block, ubound, tmp);
+ gfc_add_modify (&block, ubound, tmp);
}
/* The offset of this dimension. offset = offset - lbound * stride. */
tmp = fold_build2 (MULT_EXPR, gfc_array_index_type, lbound, stride);
@@ -4425,7 +4438,7 @@ gfc_trans_dummy_array_bias (gfc_symbol * sym, tree tmpdesc, tree body)
stmt_unpacked, stmt_packed);
else
tmp = (stmt_packed != NULL_TREE) ? stmt_packed : stmt_unpacked;
- gfc_add_modify_expr (&block, stride, tmp);
+ gfc_add_modify (&block, stride, tmp);
}
}
else
@@ -4441,14 +4454,14 @@ gfc_trans_dummy_array_bias (gfc_symbol * sym, tree tmpdesc, tree body)
ubound, tmp);
tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
GFC_TYPE_ARRAY_STRIDE (type, n), tmp);
- gfc_add_modify_expr (&block, stride, tmp);
+ gfc_add_modify (&block, stride, tmp);
}
}
}
/* Set the offset. */
if (TREE_CODE (GFC_TYPE_ARRAY_OFFSET (type)) == VAR_DECL)
- gfc_add_modify_expr (&block, GFC_TYPE_ARRAY_OFFSET (type), offset);
+ gfc_add_modify (&block, GFC_TYPE_ARRAY_OFFSET (type), offset);
gfc_trans_vla_type_sizes (sym, &block);
@@ -4536,7 +4549,7 @@ gfc_get_dataptr_offset (stmtblock_t *block, tree parm, tree desc, tree offset,
tmp = gfc_build_array_ref (tmp, offset, NULL);
/* Offset the data pointer for pointer assignments from arrays with
- subreferences; eg. my_integer => my_type(:)%integer_component. */
+ subreferences; e.g. my_integer => my_type(:)%integer_component. */
if (subref)
{
/* Go past the array reference. */
@@ -4635,7 +4648,7 @@ get_elemental_fcn_charlen (gfc_expr *expr, gfc_se *se)
arg = expr->value.function.actual;
gfc_init_interface_mapping (&mapping);
- /* Set se = NULL in the calls to the interface mapping, to supress any
+ /* Set se = NULL in the calls to the interface mapping, to suppress any
backend stuff. */
for (; arg != NULL; arg = arg->next, formal = formal ? formal->next : NULL)
{
@@ -4743,7 +4756,7 @@ gfc_conv_expr_descriptor (gfc_se * se, gfc_expr * expr, gfc_ss * ss)
if (se->direct_byref)
{
/* Copy the descriptor for pointer assignments. */
- gfc_add_modify_expr (&se->pre, se->expr, desc);
+ gfc_add_modify (&se->pre, se->expr, desc);
/* Add any offsets from subreferences. */
gfc_get_dataptr_offset (&se->pre, se->expr, desc, NULL_TREE,
@@ -4871,7 +4884,7 @@ gfc_conv_expr_descriptor (gfc_se * se, gfc_expr * expr, gfc_ss * ss)
gfc_add_ss_to_loop (&loop, loop.temp_ss);
}
- gfc_conv_loop_setup (&loop);
+ gfc_conv_loop_setup (&loop, & expr->where);
if (need_tmp)
{
@@ -4976,7 +4989,7 @@ gfc_conv_expr_descriptor (gfc_se * se, gfc_expr * expr, gfc_ss * ss)
/* Set the dtype. */
tmp = gfc_conv_descriptor_dtype (parm);
- gfc_add_modify_expr (&loop.pre, tmp, gfc_get_dtype (parmtype));
+ gfc_add_modify (&loop.pre, tmp, gfc_get_dtype (parmtype));
/* Set offset for assignments to pointer only to zero if it is not
the full array. */
@@ -5045,11 +5058,11 @@ gfc_conv_expr_descriptor (gfc_se * se, gfc_expr * expr, gfc_ss * ss)
from = gfc_index_one_node;
}
tmp = gfc_conv_descriptor_lbound (parm, gfc_rank_cst[dim]);
- gfc_add_modify_expr (&loop.pre, tmp, from);
+ gfc_add_modify (&loop.pre, tmp, from);
/* Set the new upper bound. */
tmp = gfc_conv_descriptor_ubound (parm, gfc_rank_cst[dim]);
- gfc_add_modify_expr (&loop.pre, tmp, to);
+ gfc_add_modify (&loop.pre, tmp, to);
/* Multiply the stride by the section stride to get the
total stride. */
@@ -5074,7 +5087,7 @@ gfc_conv_expr_descriptor (gfc_se * se, gfc_expr * expr, gfc_ss * ss)
/* Store the new stride. */
tmp = gfc_conv_descriptor_stride (parm, gfc_rank_cst[dim]);
- gfc_add_modify_expr (&loop.pre, tmp, stride);
+ gfc_add_modify (&loop.pre, tmp, stride);
dim++;
}
@@ -5091,14 +5104,14 @@ gfc_conv_expr_descriptor (gfc_se * se, gfc_expr * expr, gfc_ss * ss)
{
/* Set the offset. */
tmp = gfc_conv_descriptor_offset (parm);
- gfc_add_modify_expr (&loop.pre, tmp, base);
+ gfc_add_modify (&loop.pre, tmp, base);
}
else
{
/* Only the callee knows what the correct offset it, so just set
it to zero here. */
tmp = gfc_conv_descriptor_offset (parm);
- gfc_add_modify_expr (&loop.pre, tmp, gfc_index_zero_node);
+ gfc_add_modify (&loop.pre, tmp, gfc_index_zero_node);
}
desc = parm;
}
@@ -5124,7 +5137,8 @@ gfc_conv_expr_descriptor (gfc_se * se, gfc_expr * expr, gfc_ss * ss)
/* TODO: Optimize passing g77 arrays. */
void
-gfc_conv_array_parameter (gfc_se * se, gfc_expr * expr, gfc_ss * ss, int g77)
+gfc_conv_array_parameter (gfc_se * se, gfc_expr * expr, gfc_ss * ss, int g77,
+ const gfc_symbol *fsym, const char *proc_name)
{
tree ptr;
tree desc;
@@ -5219,15 +5233,61 @@ gfc_conv_array_parameter (gfc_se * se, gfc_expr * expr, gfc_ss * ss, int g77)
{
desc = se->expr;
/* Repack the array. */
+
+ if (gfc_option.warn_array_temp)
+ {
+ if (fsym)
+ gfc_warning ("Creating array temporary at %L for argument '%s'",
+ &expr->where, fsym->name);
+ else
+ gfc_warning ("Creating array temporary at %L", &expr->where);
+ }
+
ptr = build_call_expr (gfor_fndecl_in_pack, 1, desc);
+
+ if (fsym && fsym->attr.optional && sym && sym->attr.optional)
+ {
+ tmp = gfc_conv_expr_present (sym);
+ ptr = build3 (COND_EXPR, TREE_TYPE (se->expr), tmp, ptr,
+ null_pointer_node);
+ }
+
ptr = gfc_evaluate_now (ptr, &se->pre);
+
se->expr = ptr;
+ if (gfc_option.flag_check_array_temporaries)
+ {
+ char * msg;
+
+ if (fsym && proc_name)
+ asprintf (&msg, "An array temporary was created for argument "
+ "'%s' of procedure '%s'", fsym->name, proc_name);
+ else
+ asprintf (&msg, "An array temporary was created");
+
+ tmp = build_fold_indirect_ref (desc);
+ tmp = gfc_conv_array_data (tmp);
+ tmp = fold_build2 (NE_EXPR, boolean_type_node,
+ fold_convert (TREE_TYPE (tmp), ptr), tmp);
+
+ if (fsym && fsym->attr.optional && sym && sym->attr.optional)
+ tmp = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
+ gfc_conv_expr_present (sym), tmp);
+
+ gfc_trans_runtime_check (false, true, tmp, &se->pre,
+ &expr->where, msg);
+ gfc_free (msg);
+ }
+
gfc_start_block (&block);
/* Copy the data back. */
- tmp = build_call_expr (gfor_fndecl_in_unpack, 2, desc, ptr);
- gfc_add_expr_to_block (&block, tmp);
+ if (fsym == NULL || fsym->attr.intent != INTENT_IN)
+ {
+ tmp = build_call_expr (gfor_fndecl_in_unpack, 2, desc, ptr);
+ gfc_add_expr_to_block (&block, tmp);
+ }
/* Free the temporary. */
tmp = gfc_call_free (convert (pvoid_type_node, ptr));
@@ -5242,6 +5302,11 @@ gfc_conv_array_parameter (gfc_se * se, gfc_expr * expr, gfc_ss * ss, int g77)
tmp = gfc_conv_array_data (tmp);
tmp = fold_build2 (NE_EXPR, boolean_type_node,
fold_convert (TREE_TYPE (tmp), ptr), tmp);
+
+ if (fsym && fsym->attr.optional && sym && sym->attr.optional)
+ tmp = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
+ gfc_conv_expr_present (sym), tmp);
+
tmp = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt ());
gfc_add_expr_to_block (&block, tmp);
@@ -5521,7 +5586,7 @@ structure_alloc_comps (gfc_symbol * der_type, tree decl,
{
rank = c->as ? c->as->rank : 0;
tmp = fold_convert (TREE_TYPE (dcmp), comp);
- gfc_add_modify_expr (&fnblock, dcmp, tmp);
+ gfc_add_modify (&fnblock, dcmp, tmp);
tmp = structure_alloc_comps (c->ts.derived, comp, dcmp,
rank, purpose);
gfc_add_expr_to_block (&fnblock, tmp);
@@ -5865,7 +5930,7 @@ gfc_walk_op_expr (gfc_ss * ss, gfc_expr * expr)
if (head == ss)
{
/* First operand is scalar. We build the chain in reverse order, so
- add the scarar SS after the second operand. */
+ add the scalar SS after the second operand. */
head = head2;
while (head && head->next != ss)
head = head->next;
diff --git a/gcc/fortran/trans-array.h b/gcc/fortran/trans-array.h
index 2b644c7880b..18de51c8437 100644
--- a/gcc/fortran/trans-array.h
+++ b/gcc/fortran/trans-array.h
@@ -32,7 +32,8 @@ void gfc_set_loop_bounds_from_array_spec (gfc_interface_mapping *,
/* Generate code to create a temporary array. */
tree gfc_trans_create_temp_array (stmtblock_t *, stmtblock_t *, gfc_loopinfo *,
- gfc_ss_info *, tree, bool, bool, bool);
+ gfc_ss_info *, tree, bool, bool, bool,
+ locus *);
/* Generate function entry code for allocation of compiler allocated array
variables. */
@@ -88,7 +89,7 @@ void gfc_trans_scalarizing_loops (gfc_loopinfo *, stmtblock_t *);
/* Mark the end of the main loop body and the start of the copying loop. */
void gfc_trans_scalarized_loop_boundary (gfc_loopinfo *, stmtblock_t *);
/* Initialize the scalarization loop parameters. */
-void gfc_conv_loop_setup (gfc_loopinfo *);
+void gfc_conv_loop_setup (gfc_loopinfo *, locus *);
/* Resolve array assignment dependencies. */
void gfc_conv_resolve_dependencies (gfc_loopinfo *, gfc_ss *, gfc_ss *);
/* Build a null array descriptor constructor. */
@@ -104,7 +105,8 @@ void gfc_conv_tmp_ref (gfc_se *);
/* Evaluate an array expression. */
void gfc_conv_expr_descriptor (gfc_se *, gfc_expr *, gfc_ss *);
/* Convert an array for passing as an actual function parameter. */
-void gfc_conv_array_parameter (gfc_se *, gfc_expr *, gfc_ss *, int);
+void gfc_conv_array_parameter (gfc_se *, gfc_expr *, gfc_ss *, int,
+ const gfc_symbol *, const char *);
/* Evaluate and transpose a matrix expression. */
void gfc_conv_array_transpose (gfc_se *, gfc_expr *);
@@ -118,11 +120,7 @@ tree gfc_conv_array_ubound (tree, int);
/* Build expressions for accessing components of an array descriptor. */
tree gfc_conv_descriptor_data_get (tree);
-void gfc_conv_descriptor_data_set_internal (stmtblock_t *, tree, tree, bool);
-#define gfc_conv_descriptor_data_set(BLOCK, T1, T2) \
- gfc_conv_descriptor_data_set_internal ((BLOCK), (T1), (T2), false)
-#define gfc_conv_descriptor_data_set_tuples(BLOCK, T1, T2) \
- gfc_conv_descriptor_data_set_internal ((BLOCK), (T1), (T2), true)
+void gfc_conv_descriptor_data_set (stmtblock_t *, tree, tree);
tree gfc_conv_descriptor_data_addr (tree);
tree gfc_conv_descriptor_offset (tree);
tree gfc_conv_descriptor_dtype (tree);
diff --git a/gcc/fortran/trans-common.c b/gcc/fortran/trans-common.c
index 5c91bf57946..8c30309b81f 100644
--- a/gcc/fortran/trans-common.c
+++ b/gcc/fortran/trans-common.c
@@ -321,10 +321,10 @@ build_field (segment_info *h, tree union_type, record_layout_info rli)
/* If this field is volatile, mark it. */
if (h->sym->attr.volatile_)
{
- tree new;
+ tree new_type;
TREE_THIS_VOLATILE (field) = 1;
- new = build_qualified_type (TREE_TYPE (field), TYPE_QUAL_VOLATILE);
- TREE_TYPE (field) = new;
+ new_type = build_qualified_type (TREE_TYPE (field), TYPE_QUAL_VOLATILE);
+ TREE_TYPE (field) = new_type;
}
h->field = field;
@@ -955,7 +955,7 @@ find_equivalence (segment_info *n)
segment list multiple times to include indirect equivalences. Since
a new segment_info can inserted at the beginning of the segment list,
depending on its offset, we have to force a final pass through the
- loop by demanding that completion sees a pass with no matches; ie.
+ loop by demanding that completion sees a pass with no matches; i.e.,
all symbols with equiv_built set and no new equivalences found. */
static void
diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c
index e960fa026b1..1dfa05cc46f 100644
--- a/gcc/fortran/trans-decl.c
+++ b/gcc/fortran/trans-decl.c
@@ -26,7 +26,7 @@ along with GCC; see the file COPYING3. If not see
#include "coretypes.h"
#include "tree.h"
#include "tree-dump.h"
-#include "tree-gimple.h"
+#include "gimple.h"
#include "ggc.h"
#include "toplev.h"
#include "tm.h"
@@ -79,6 +79,7 @@ tree gfor_fndecl_stop_numeric;
tree gfor_fndecl_stop_string;
tree gfor_fndecl_runtime_error;
tree gfor_fndecl_runtime_error_at;
+tree gfor_fndecl_runtime_warning_at;
tree gfor_fndecl_os_error;
tree gfor_fndecl_generate_error;
tree gfor_fndecl_set_fpe;
@@ -461,7 +462,7 @@ gfc_finish_decl (tree decl)
static void
gfc_finish_var_decl (tree decl, gfc_symbol * sym)
{
- tree new;
+ tree new_type;
/* TREE_ADDRESSABLE means the address of this variable is actually needed.
This is the equivalent of the TARGET variables.
We also need to set this if the variable is passed by reference in a
@@ -525,7 +526,7 @@ gfc_finish_var_decl (tree decl, gfc_symbol * sym)
a default initializer; this must be applied each time the variable
comes into scope it therefore need not be static. These variables
are SAVE_NONE but have an initializer. Otherwise explicitly
- intitialized variables are SAVE_IMPLICIT and explicitly saved are
+ initialized variables are SAVE_IMPLICIT and explicitly saved are
SAVE_EXPLICIT. */
if (!sym->attr.use_assoc
&& (sym->attr.save != SAVE_NONE || sym->attr.data
@@ -535,8 +536,8 @@ gfc_finish_var_decl (tree decl, gfc_symbol * sym)
if (sym->attr.volatile_)
{
TREE_THIS_VOLATILE (decl) = 1;
- new = build_qualified_type (TREE_TYPE (decl), TYPE_QUAL_VOLATILE);
- TREE_TYPE (decl) = new;
+ new_type = build_qualified_type (TREE_TYPE (decl), TYPE_QUAL_VOLATILE);
+ TREE_TYPE (decl) = new_type;
}
/* Keep variables larger than max-stack-var-size off stack. */
@@ -1584,7 +1585,7 @@ create_function_arglist (gfc_symbol * sym)
if (f->sym->attr.proc_pointer)
type = build_pointer_type (type);
- /* Build a the argument declaration. */
+ /* Build the argument declaration. */
parm = build_decl (PARM_DECL, gfc_sym_identifier (f->sym), type);
/* Fill in arg stuff. */
@@ -2455,6 +2456,10 @@ gfc_build_builtin_function_decls (void)
/* The runtime_error_at function does not return. */
TREE_THIS_VOLATILE (gfor_fndecl_runtime_error_at) = 1;
+ gfor_fndecl_runtime_warning_at =
+ gfc_build_library_function_decl (get_identifier (PREFIX("runtime_warning_at")),
+ void_type_node, -2, pchar_type_node,
+ pchar_type_node);
gfor_fndecl_generate_error =
gfc_build_library_function_decl (get_identifier (PREFIX("generate_error")),
void_type_node, 3, pvoid_type_node,
@@ -2571,7 +2576,7 @@ gfc_trans_assign_aux_var (gfc_symbol * sym, tree fnbody)
/* Set the initial value to length. See the comments in
function gfc_add_assign_aux_vars in this file. */
- gfc_add_modify_expr (&body, GFC_DECL_STRING_LEN (sym->backend_decl),
+ gfc_add_modify (&body, GFC_DECL_STRING_LEN (sym->backend_decl),
build_int_cst (NULL_TREE, -2));
gfc_add_expr_to_block (&body, fnbody);
@@ -2602,7 +2607,7 @@ gfc_trans_vla_one_sizepos (tree *tp, stmtblock_t *body)
var = gfc_create_var_np (TREE_TYPE (t), NULL);
gfc_add_decl_to_function (var);
- gfc_add_modify_expr (body, var, val);
+ gfc_add_modify (body, var, val);
if (TREE_CODE (t) == SAVE_EXPR)
TREE_OPERAND (t, 0) = var;
*tp = var;
@@ -3407,7 +3412,7 @@ gfc_generate_function_code (gfc_namespace * ns)
{
tree alternate_return;
alternate_return = gfc_get_fake_result_decl (sym, 0);
- gfc_add_modify_expr (&body, alternate_return, integer_zero_node);
+ gfc_add_modify (&body, alternate_return, integer_zero_node);
}
if (ns->entries)
diff --git a/gcc/fortran/trans-expr.c b/gcc/fortran/trans-expr.c
index 570e07b5a06..05ee3902e34 100644
--- a/gcc/fortran/trans-expr.c
+++ b/gcc/fortran/trans-expr.c
@@ -30,7 +30,7 @@ along with GCC; see the file COPYING3. If not see
#include "ggc.h"
#include "toplev.h"
#include "real.h"
-#include "tree-gimple.h"
+#include "gimple.h"
#include "langhooks.h"
#include "flags.h"
#include "gfortran.h"
@@ -115,7 +115,7 @@ gfc_make_safe_expr (gfc_se * se)
/* We need a temporary for this result. */
var = gfc_create_var (TREE_TYPE (se->expr), NULL);
- gfc_add_modify_expr (&se->pre, var, se->expr);
+ gfc_add_modify (&se->pre, var, se->expr);
se->expr = var;
}
@@ -257,7 +257,7 @@ gfc_conv_string_length (gfc_charlen * cl, stmtblock_t * pblock)
gfc_add_block_to_block (pblock, &se.pre);
if (cl->backend_decl)
- gfc_add_modify_expr (pblock, cl->backend_decl, se.expr);
+ gfc_add_modify (pblock, cl->backend_decl, se.expr);
else
cl->backend_decl = gfc_evaluate_now (se.expr, pblock);
}
@@ -328,7 +328,7 @@ gfc_conv_substring (gfc_se * se, gfc_ref * ref, int kind,
else
asprintf (&msg, "Substring out of bounds: lower bound (%%ld)"
"is less than one");
- gfc_trans_runtime_check (fault, &se->pre, where, msg,
+ gfc_trans_runtime_check (true, false, fault, &se->pre, where, msg,
fold_convert (long_integer_type_node,
start.expr));
gfc_free (msg);
@@ -344,7 +344,7 @@ gfc_conv_substring (gfc_se * se, gfc_ref * ref, int kind,
else
asprintf (&msg, "Substring out of bounds: upper bound (%%ld) "
"exceeds string length (%%ld)");
- gfc_trans_runtime_check (fault, &se->pre, where, msg,
+ gfc_trans_runtime_check (true, false, fault, &se->pre, where, msg,
fold_convert (long_integer_type_node, end.expr),
fold_convert (long_integer_type_node,
se->string_length));
@@ -993,7 +993,7 @@ gfc_conv_string_tmp (gfc_se * se, tree type, tree len)
fold_build2 (MULT_EXPR, TREE_TYPE (len), len,
fold_convert (TREE_TYPE (len),
TYPE_SIZE (type))));
- gfc_add_modify_expr (&se->pre, var, tmp);
+ gfc_add_modify (&se->pre, var, tmp);
/* Free the temporary afterwards. */
tmp = gfc_call_free (convert (pvoid_type_node, var));
@@ -1079,7 +1079,7 @@ gfc_conv_expr_op (gfc_se * se, gfc_expr * expr)
checkstring = 0;
lop = 0;
- switch (expr->value.op.operator)
+ switch (expr->value.op.op)
{
case INTRINSIC_PARENTHESES:
if (expr->ts.type == BT_REAL
@@ -1460,9 +1460,9 @@ gfc_free_interface_mapping (gfc_interface_mapping * mapping)
for (sym = mapping->syms; sym; sym = nextsym)
{
nextsym = sym->next;
- gfc_free_symbol (sym->new->n.sym);
+ gfc_free_symbol (sym->new_sym->n.sym);
gfc_free_expr (sym->expr);
- gfc_free (sym->new);
+ gfc_free (sym->new_sym);
gfc_free (sym);
}
for (cl = mapping->charlens; cl; cl = nextcl)
@@ -1481,14 +1481,14 @@ static gfc_charlen *
gfc_get_interface_mapping_charlen (gfc_interface_mapping * mapping,
gfc_charlen * cl)
{
- gfc_charlen *new;
+ gfc_charlen *new_charlen;
- new = gfc_get_charlen ();
- new->next = mapping->charlens;
- new->length = gfc_copy_expr (cl->length);
+ new_charlen = gfc_get_charlen ();
+ new_charlen->next = mapping->charlens;
+ new_charlen->length = gfc_copy_expr (cl->length);
- mapping->charlens = new;
- return new;
+ mapping->charlens = new_charlen;
+ return new_charlen;
}
@@ -1509,7 +1509,7 @@ gfc_get_interface_mapping_array (stmtblock_t * block, gfc_symbol * sym,
type = gfc_get_nodesc_array_type (type, sym->as, packed);
var = gfc_create_var (type, "ifm");
- gfc_add_modify_expr (block, var, fold_convert (type, data));
+ gfc_add_modify (block, var, fold_convert (type, data));
return var;
}
@@ -1597,7 +1597,7 @@ gfc_add_interface_mapping (gfc_interface_mapping * mapping,
sm = XCNEW (gfc_interface_sym_mapping);
sm->next = mapping->syms;
sm->old = sym;
- sm->new = new_symtree;
+ sm->new_sym = new_symtree;
sm->expr = gfc_copy_expr (expr);
mapping->syms = sm;
@@ -1689,10 +1689,10 @@ gfc_finish_interface_mapping (gfc_interface_mapping * mapping,
gfc_se se;
for (sym = mapping->syms; sym; sym = sym->next)
- if (sym->new->n.sym->ts.type == BT_CHARACTER
- && !sym->new->n.sym->ts.cl->backend_decl)
+ if (sym->new_sym->n.sym->ts.type == BT_CHARACTER
+ && !sym->new_sym->n.sym->ts.cl->backend_decl)
{
- expr = sym->new->n.sym->ts.cl->length;
+ expr = sym->new_sym->n.sym->ts.cl->length;
gfc_apply_interface_mapping_to_expr (mapping, expr);
gfc_init_se (&se, NULL);
gfc_conv_expr (&se, expr);
@@ -1701,7 +1701,7 @@ gfc_finish_interface_mapping (gfc_interface_mapping * mapping,
gfc_add_block_to_block (pre, &se.pre);
gfc_add_block_to_block (post, &se.post);
- sym->new->n.sym->ts.cl->backend_decl = se.expr;
+ sym->new_sym->n.sym->ts.cl->backend_decl = se.expr;
}
}
@@ -1927,12 +1927,12 @@ gfc_apply_interface_mapping_to_expr (gfc_interface_mapping * mapping,
/* ...and to the expression's symbol, if it has one. */
/* TODO Find out why the condition on expr->symtree had to be moved into
- the loop rather than being ouside it, as originally. */
+ the loop rather than being outside it, as originally. */
for (sym = mapping->syms; sym; sym = sym->next)
if (expr->symtree && sym->old == expr->symtree->n.sym)
{
- if (sym->new->n.sym->backend_decl)
- expr->symtree = sym->new;
+ if (sym->new_sym->n.sym->backend_decl)
+ expr->symtree = sym->new_sym;
else if (sym->expr)
gfc_replace_expr (expr, gfc_copy_expr (sym->expr));
}
@@ -1964,9 +1964,9 @@ gfc_apply_interface_mapping_to_expr (gfc_interface_mapping * mapping,
for (sym = mapping->syms; sym; sym = sym->next)
if (sym->old == expr->value.function.esym)
{
- expr->value.function.esym = sym->new->n.sym;
+ expr->value.function.esym = sym->new_sym->n.sym;
gfc_map_fcn_formal_to_actual (expr, sym->expr, mapping);
- expr->value.function.esym->result = sym->new->n.sym;
+ expr->value.function.esym->result = sym->new_sym->n.sym;
}
break;
@@ -2059,7 +2059,7 @@ gfc_conv_subref_array_arg (gfc_se * parmse, gfc_expr * expr,
gfc_add_ss_to_loop (&loop, loop.temp_ss);
/* Setup the scalarizing loops. */
- gfc_conv_loop_setup (&loop);
+ gfc_conv_loop_setup (&loop, &expr->where);
/* Pass the temporary descriptor back to the caller. */
info = &loop.temp_ss->data.info;
@@ -2124,7 +2124,7 @@ gfc_conv_subref_array_arg (gfc_se * parmse, gfc_expr * expr,
gfc_conv_ss_startstride (&loop2);
/* Setup the scalarizing loops. */
- gfc_conv_loop_setup (&loop2);
+ gfc_conv_loop_setup (&loop2, &expr->where);
gfc_copy_loopinfo_to_se (&lse, &loop2);
gfc_copy_loopinfo_to_se (&rse, &loop2);
@@ -2165,7 +2165,7 @@ gfc_conv_subref_array_arg (gfc_se * parmse, gfc_expr * expr,
tmp_index = fold_build2 (MINUS_EXPR, gfc_array_index_type,
tmp_index, rse.loop->from[0]);
- gfc_add_modify_expr (&rse.loop->code[0], offset, tmp_index);
+ gfc_add_modify (&rse.loop->code[0], offset, tmp_index);
tmp_index = fold_build2 (PLUS_EXPR, gfc_array_index_type,
rse.loop->loopvar[0], offset);
@@ -2299,7 +2299,7 @@ gfc_conv_function_call (gfc_se * se, gfc_symbol * sym,
f = f || !sym->attr.always_explicit;
argss = gfc_walk_expr (arg->expr);
- gfc_conv_array_parameter (se, arg->expr, argss, f);
+ gfc_conv_array_parameter (se, arg->expr, argss, f, NULL, NULL);
}
/* TODO -- the following two lines shouldn't be necessary, but
@@ -2535,7 +2535,8 @@ gfc_conv_function_call (gfc_se * se, gfc_symbol * sym,
gfc_conv_subref_array_arg (&parmse, e, f,
fsym ? fsym->attr.intent : INTENT_INOUT);
else
- gfc_conv_array_parameter (&parmse, e, argss, f);
+ gfc_conv_array_parameter (&parmse, e, argss, f, fsym,
+ sym->name);
/* If an ALLOCATABLE dummy argument has INTENT(OUT) and is
allocated on entry, it must be deallocated. */
@@ -2691,7 +2692,7 @@ gfc_conv_function_call (gfc_se * se, gfc_symbol * sym,
{
if (se->direct_byref)
{
- /* Sometimes, too much indirection can be applied; eg. for
+ /* Sometimes, too much indirection can be applied; e.g. for
function_result = array_valued_recursive_function. */
if (TREE_TYPE (TREE_TYPE (se->expr))
&& TREE_TYPE (TREE_TYPE (TREE_TYPE (se->expr)))
@@ -2717,7 +2718,8 @@ gfc_conv_function_call (gfc_se * se, gfc_symbol * sym,
mustn't be deallocated. */
callee_alloc = sym->attr.allocatable || sym->attr.pointer;
gfc_trans_create_temp_array (&se->pre, &se->post, se->loop, info, tmp,
- false, !sym->attr.pointer, callee_alloc);
+ false, !sym->attr.pointer, callee_alloc,
+ &se->ss->expr->where);
/* Pass the temporary as the first argument. */
tmp = info->descriptor;
@@ -2835,7 +2837,8 @@ gfc_conv_function_call (gfc_se * se, gfc_symbol * sym,
tmp = gfc_conv_descriptor_data_get (info->descriptor);
tmp = fold_build2 (NE_EXPR, boolean_type_node,
tmp, info->data);
- gfc_trans_runtime_check (tmp, &se->pre, NULL, gfc_msg_fault);
+ gfc_trans_runtime_check (true, false, tmp, &se->pre, NULL,
+ gfc_msg_fault);
}
se->expr = info->descriptor;
/* Bundle in the string length. */
@@ -2892,9 +2895,9 @@ fill_with_spaces (tree start, tree type, tree size)
/* Initialize variables. */
gfc_init_block (&block);
i = gfc_create_var (sizetype, "i");
- gfc_add_modify_expr (&block, i, fold_convert (sizetype, size));
+ gfc_add_modify (&block, i, fold_convert (sizetype, size));
el = gfc_create_var (build_pointer_type (type), "el");
- gfc_add_modify_expr (&block, el, fold_convert (TREE_TYPE (el), start));
+ gfc_add_modify (&block, el, fold_convert (TREE_TYPE (el), start));
exit_label = gfc_build_label_decl (NULL_TREE);
TREE_USED (exit_label) = 1;
@@ -2910,14 +2913,14 @@ fill_with_spaces (tree start, tree type, tree size)
gfc_add_expr_to_block (&loop, tmp);
/* Assignment. */
- gfc_add_modify_expr (&loop, fold_build1 (INDIRECT_REF, type, el),
+ gfc_add_modify (&loop, fold_build1 (INDIRECT_REF, type, el),
build_int_cst (type,
lang_hooks.to_target_charset (' ')));
/* Increment loop variables. */
- gfc_add_modify_expr (&loop, i, fold_build2 (MINUS_EXPR, sizetype, i,
+ gfc_add_modify (&loop, i, fold_build2 (MINUS_EXPR, sizetype, i,
TYPE_SIZE_UNIT (type)));
- gfc_add_modify_expr (&loop, el, fold_build2 (POINTER_PLUS_EXPR,
+ gfc_add_modify (&loop, el, fold_build2 (POINTER_PLUS_EXPR,
TREE_TYPE (el), el,
TYPE_SIZE_UNIT (type)));
@@ -2986,7 +2989,7 @@ gfc_trans_string_copy (stmtblock_t * block, tree dlength, tree dest,
if (dsc != NULL_TREE && ssc != NULL_TREE
&& TREE_TYPE (dsc) == TREE_TYPE (ssc))
{
- gfc_add_modify_expr (block, dsc, ssc);
+ gfc_add_modify (block, dsc, ssc);
return;
}
@@ -3132,7 +3135,7 @@ gfc_conv_statement_function (gfc_se * se, gfc_expr * expr)
gfc_conv_expr (&lse, args->expr);
gfc_add_block_to_block (&se->pre, &lse.pre);
- gfc_add_modify_expr (&se->pre, temp_vars[n], lse.expr);
+ gfc_add_modify (&se->pre, temp_vars[n], lse.expr);
gfc_add_block_to_block (&se->pre, &lse.post);
}
@@ -3335,7 +3338,7 @@ gfc_trans_subarray_assign (tree dest, gfc_component * cm, gfc_expr * expr)
gfc_conv_ss_startstride (&loop);
/* Setup the scalarizing loops. */
- gfc_conv_loop_setup (&loop);
+ gfc_conv_loop_setup (&loop, &expr->where);
/* Setup the gfc_se structures. */
gfc_copy_loopinfo_to_se (&lse, &loop);
@@ -3417,7 +3420,7 @@ gfc_trans_subcomponent_assign (tree dest, gfc_component * cm, gfc_expr * expr)
se.want_pointer = 1;
gfc_conv_expr (&se, expr);
gfc_add_block_to_block (&block, &se.pre);
- gfc_add_modify_expr (&block, dest,
+ gfc_add_modify (&block, dest,
fold_convert (TREE_TYPE (dest), se.expr));
gfc_add_block_to_block (&block, &se.post);
}
@@ -3438,7 +3441,7 @@ gfc_trans_subcomponent_assign (tree dest, gfc_component * cm, gfc_expr * expr)
gfc_add_block_to_block (&block, &se.pre);
tmp = fold_convert (TREE_TYPE (dest), se.expr);
- gfc_add_modify_expr (&block, dest, tmp);
+ gfc_add_modify (&block, dest, tmp);
if (cm->ts.type == BT_DERIVED && cm->ts.derived->attr.alloc_comp)
tmp = gfc_copy_alloc_comp (cm->ts.derived, se.expr, dest,
@@ -3456,7 +3459,7 @@ gfc_trans_subcomponent_assign (tree dest, gfc_component * cm, gfc_expr * expr)
/* Shift the lbound and ubound of temporaries to being unity, rather
than zero, based. Calculate the offset for all cases. */
offset = gfc_conv_descriptor_offset (dest);
- gfc_add_modify_expr (&block, offset, gfc_index_zero_node);
+ gfc_add_modify (&block, offset, gfc_index_zero_node);
tmp2 =gfc_create_var (gfc_array_index_type, NULL);
for (n = 0; n < expr->rank; n++)
{
@@ -3467,21 +3470,21 @@ gfc_trans_subcomponent_assign (tree dest, gfc_component * cm, gfc_expr * expr)
tmp = gfc_conv_descriptor_ubound (dest, gfc_rank_cst[n]);
span = fold_build2 (MINUS_EXPR, gfc_array_index_type, tmp,
gfc_conv_descriptor_lbound (dest, gfc_rank_cst[n]));
- gfc_add_modify_expr (&block, tmp,
+ gfc_add_modify (&block, tmp,
fold_build2 (PLUS_EXPR,
gfc_array_index_type,
span, gfc_index_one_node));
tmp = gfc_conv_descriptor_lbound (dest, gfc_rank_cst[n]);
- gfc_add_modify_expr (&block, tmp, gfc_index_one_node);
+ gfc_add_modify (&block, tmp, gfc_index_one_node);
}
tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
gfc_conv_descriptor_lbound (dest,
gfc_rank_cst[n]),
gfc_conv_descriptor_stride (dest,
gfc_rank_cst[n]));
- gfc_add_modify_expr (&block, tmp2, tmp);
+ gfc_add_modify (&block, tmp2, tmp);
tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type, offset, tmp2);
- gfc_add_modify_expr (&block, offset, tmp);
+ gfc_add_modify (&block, offset, tmp);
}
}
else
@@ -3496,7 +3499,7 @@ gfc_trans_subcomponent_assign (tree dest, gfc_component * cm, gfc_expr * expr)
{
gfc_init_se (&se, NULL);
gfc_conv_expr (&se, expr);
- gfc_add_modify_expr (&block, dest,
+ gfc_add_modify (&block, dest,
fold_convert (TREE_TYPE (dest), se.expr));
}
else
@@ -3742,7 +3745,7 @@ gfc_conv_expr_val (gfc_se * se, gfc_expr * expr)
if (se->post.head)
{
val = gfc_create_var (TREE_TYPE (se->expr), NULL);
- gfc_add_modify_expr (&se->pre, val, se->expr);
+ gfc_add_modify (&se->pre, val, se->expr);
se->expr = val;
gfc_add_block_to_block (&se->pre, &se->post);
}
@@ -3788,7 +3791,7 @@ gfc_conv_expr_reference (gfc_se * se, gfc_expr * expr)
if (se->post.head)
{
var = gfc_create_var (TREE_TYPE (se->expr), NULL);
- gfc_add_modify_expr (&se->pre, var, se->expr);
+ gfc_add_modify (&se->pre, var, se->expr);
gfc_add_block_to_block (&se->pre, &se->post);
se->expr = var;
}
@@ -3802,7 +3805,7 @@ gfc_conv_expr_reference (gfc_se * se, gfc_expr * expr)
se->want_pointer = 1;
gfc_conv_expr (se, expr);
var = gfc_create_var (TREE_TYPE (se->expr), NULL);
- gfc_add_modify_expr (&se->pre, var, se->expr);
+ gfc_add_modify (&se->pre, var, se->expr);
se->expr = var;
return;
}
@@ -3823,7 +3826,7 @@ gfc_conv_expr_reference (gfc_se * se, gfc_expr * expr)
else
{
var = gfc_create_var (TREE_TYPE (se->expr), NULL);
- gfc_add_modify_expr (&se->pre, var, se->expr);
+ gfc_add_modify (&se->pre, var, se->expr);
}
gfc_add_block_to_block (&se->pre, &se->post);
@@ -3876,7 +3879,7 @@ gfc_trans_pointer_assignment (gfc_expr * expr1, gfc_expr * expr2)
gfc_add_block_to_block (&block, &lse.pre);
gfc_add_block_to_block (&block, &rse.pre);
- gfc_add_modify_expr (&block, lse.expr,
+ gfc_add_modify (&block, lse.expr,
fold_convert (TREE_TYPE (lse.expr), rse.expr));
gfc_add_block_to_block (&block, &rse.post);
gfc_add_block_to_block (&block, &lse.post);
@@ -3909,7 +3912,7 @@ gfc_trans_pointer_assignment (gfc_expr * expr1, gfc_expr * expr2)
tmp = fold_convert (gfc_array_index_type, size_in_bytes (tmp));
if (!INTEGER_CST_P (tmp))
gfc_add_block_to_block (&lse.post, &rse.pre);
- gfc_add_modify_expr (&lse.post, GFC_DECL_SPAN(decl), tmp);
+ gfc_add_modify (&lse.post, GFC_DECL_SPAN(decl), tmp);
}
break;
@@ -3923,7 +3926,7 @@ gfc_trans_pointer_assignment (gfc_expr * expr1, gfc_expr * expr2)
lse.expr = tmp;
lse.direct_byref = 1;
gfc_conv_expr_descriptor (&lse, expr2, rss);
- gfc_add_modify_expr (&lse.pre, desc, tmp);
+ gfc_add_modify (&lse.pre, desc, tmp);
break;
}
gfc_add_block_to_block (&block, &lse.pre);
@@ -3934,7 +3937,7 @@ gfc_trans_pointer_assignment (gfc_expr * expr1, gfc_expr * expr2)
/* Makes sure se is suitable for passing as a function string parameter. */
-/* TODO: Need to check all callers fo this function. It may be abused. */
+/* TODO: Need to check all callers of this function. It may be abused. */
void
gfc_conv_string_parameter (gfc_se * se)
@@ -4035,7 +4038,7 @@ gfc_trans_scalar_assign (gfc_se * lse, gfc_se * rse, gfc_typespec ts,
gfc_add_block_to_block (&block, &rse->pre);
gfc_add_block_to_block (&block, &lse->pre);
- gfc_add_modify_expr (&block, lse->expr,
+ gfc_add_modify (&block, lse->expr,
fold_convert (TREE_TYPE (lse->expr), rse->expr));
/* Do a deep copy if the rhs is a variable, if it is not the
@@ -4052,7 +4055,7 @@ gfc_trans_scalar_assign (gfc_se * lse, gfc_se * rse, gfc_typespec ts,
gfc_add_block_to_block (&block, &lse->pre);
gfc_add_block_to_block (&block, &rse->pre);
- gfc_add_modify_expr (&block, lse->expr,
+ gfc_add_modify (&block, lse->expr,
fold_convert (TREE_TYPE (lse->expr), rse->expr));
}
@@ -4142,7 +4145,7 @@ gfc_trans_arrayfunc_assign (gfc_expr * expr1, gfc_expr * expr2)
gfc_start_block (&se.pre);
se.want_pointer = 1;
- gfc_conv_array_parameter (&se, expr1, ss, 0);
+ gfc_conv_array_parameter (&se, expr1, ss, 0, NULL, NULL);
se.direct_byref = 1;
se.ss = gfc_walk_expr (expr2);
@@ -4415,7 +4418,7 @@ gfc_trans_assignment_1 (gfc_expr * expr1, gfc_expr * expr2, bool init_flag)
/* Resolve any data dependencies in the statement. */
gfc_conv_resolve_dependencies (&loop, lss, rss);
/* Setup the scalarizing loops. */
- gfc_conv_loop_setup (&loop);
+ gfc_conv_loop_setup (&loop, &expr2->where);
/* Setup the gfc_se structures. */
gfc_copy_loopinfo_to_se (&lse, &loop);
diff --git a/gcc/fortran/trans-intrinsic.c b/gcc/fortran/trans-intrinsic.c
index 31780240cd2..a56f4c1fabb 100644
--- a/gcc/fortran/trans-intrinsic.c
+++ b/gcc/fortran/trans-intrinsic.c
@@ -30,7 +30,7 @@ along with GCC; see the file COPYING3. If not see
#include "ggc.h"
#include "toplev.h"
#include "real.h"
-#include "tree-gimple.h"
+#include "gimple.h"
#include "flags.h"
#include "gfortran.h"
#include "arith.h"
@@ -864,7 +864,8 @@ gfc_conv_intrinsic_bound (gfc_se * se, gfc_expr * expr, int upper)
tmp = gfc_rank_cst[GFC_TYPE_ARRAY_RANK (TREE_TYPE (desc))];
tmp = fold_build2 (GE_EXPR, boolean_type_node, bound, tmp);
cond = fold_build2 (TRUTH_ORIF_EXPR, boolean_type_node, cond, tmp);
- gfc_trans_runtime_check (cond, &se->pre, &expr->where, gfc_msg_fault);
+ gfc_trans_runtime_check (true, false, cond, &se->pre, &expr->where,
+ gfc_msg_fault);
}
}
@@ -1315,7 +1316,7 @@ gfc_conv_intrinsic_char (gfc_se * se, gfc_expr * expr)
var = gfc_create_var (type, "char");
arg[0] = fold_build1 (NOP_EXPR, type, arg[0]);
- gfc_add_modify_expr (&se->pre, var, arg[0]);
+ gfc_add_modify (&se->pre, var, arg[0]);
se->expr = gfc_build_addr_expr (build_pointer_type (type), var);
se->string_length = integer_one_node;
}
@@ -1478,7 +1479,7 @@ gfc_conv_intrinsic_minmax (gfc_se * se, gfc_expr * expr, int op)
args[0] = gfc_evaluate_now (args[0], &se->pre);
mvar = gfc_create_var (type, "M");
- gfc_add_modify_expr (&se->pre, mvar, args[0]);
+ gfc_add_modify (&se->pre, mvar, args[0]);
for (i = 1, argexpr = argexpr->next; i < nargs; i++)
{
tree cond, isnan;
@@ -1717,7 +1718,7 @@ gfc_conv_intrinsic_anyall (gfc_se * se, gfc_expr * expr, int op)
tmp = convert (type, boolean_true_node);
else
tmp = convert (type, boolean_false_node);
- gfc_add_modify_expr (&se->pre, resvar, tmp);
+ gfc_add_modify (&se->pre, resvar, tmp);
/* Walk the arguments. */
arrayss = gfc_walk_expr (actual->expr);
@@ -1731,7 +1732,7 @@ gfc_conv_intrinsic_anyall (gfc_se * se, gfc_expr * expr, int op)
/* Initialize the loop. */
gfc_conv_ss_startstride (&loop);
- gfc_conv_loop_setup (&loop);
+ gfc_conv_loop_setup (&loop, &expr->where);
gfc_mark_ss_chain_used (arrayss, 1);
/* Generate the loop body. */
@@ -1743,7 +1744,7 @@ gfc_conv_intrinsic_anyall (gfc_se * se, gfc_expr * expr, int op)
tmp = convert (type, boolean_false_node);
else
tmp = convert (type, boolean_true_node);
- gfc_add_modify_expr (&block, resvar, tmp);
+ gfc_add_modify (&block, resvar, tmp);
/* And break out of the loop. */
tmp = build1_v (GOTO_EXPR, exit_label);
@@ -1801,7 +1802,7 @@ gfc_conv_intrinsic_count (gfc_se * se, gfc_expr * expr)
type = gfc_typenode_for_spec (&expr->ts);
/* Initialize the result. */
resvar = gfc_create_var (type, "count");
- gfc_add_modify_expr (&se->pre, resvar, build_int_cst (type, 0));
+ gfc_add_modify (&se->pre, resvar, build_int_cst (type, 0));
/* Walk the arguments. */
arrayss = gfc_walk_expr (actual->expr);
@@ -1813,7 +1814,7 @@ gfc_conv_intrinsic_count (gfc_se * se, gfc_expr * expr)
/* Initialize the loop. */
gfc_conv_ss_startstride (&loop);
- gfc_conv_loop_setup (&loop);
+ gfc_conv_loop_setup (&loop, &expr->where);
gfc_mark_ss_chain_used (arrayss, 1);
/* Generate the loop body. */
@@ -1874,7 +1875,7 @@ gfc_conv_intrinsic_arith (gfc_se * se, gfc_expr * expr, int op)
else
tmp = gfc_build_const (type, integer_one_node);
- gfc_add_modify_expr (&se->pre, resvar, tmp);
+ gfc_add_modify (&se->pre, resvar, tmp);
/* Walk the arguments. */
actual = expr->value.function.actual;
@@ -1901,7 +1902,7 @@ gfc_conv_intrinsic_arith (gfc_se * se, gfc_expr * expr, int op)
/* Initialize the loop. */
gfc_conv_ss_startstride (&loop);
- gfc_conv_loop_setup (&loop);
+ gfc_conv_loop_setup (&loop, &expr->where);
gfc_mark_ss_chain_used (arrayss, 1);
if (maskss)
@@ -1931,7 +1932,7 @@ gfc_conv_intrinsic_arith (gfc_se * se, gfc_expr * expr, int op)
gfc_add_block_to_block (&block, &arrayse.pre);
tmp = fold_build2 (op, type, resvar, arrayse.expr);
- gfc_add_modify_expr (&block, resvar, tmp);
+ gfc_add_modify (&block, resvar, tmp);
gfc_add_block_to_block (&block, &arrayse.post);
if (maskss)
@@ -1998,7 +1999,7 @@ gfc_conv_intrinsic_dot_product (gfc_se * se, gfc_expr * expr)
else
tmp = gfc_build_const (type, integer_zero_node);
- gfc_add_modify_expr (&se->pre, resvar, tmp);
+ gfc_add_modify (&se->pre, resvar, tmp);
/* Walk argument #1. */
actual = expr->value.function.actual;
@@ -2019,7 +2020,7 @@ gfc_conv_intrinsic_dot_product (gfc_se * se, gfc_expr * expr)
/* Initialize the loop. */
gfc_conv_ss_startstride (&loop);
- gfc_conv_loop_setup (&loop);
+ gfc_conv_loop_setup (&loop, &expr->where);
gfc_mark_ss_chain_used (arrayss1, 1);
gfc_mark_ss_chain_used (arrayss2, 1);
@@ -2055,7 +2056,7 @@ gfc_conv_intrinsic_dot_product (gfc_se * se, gfc_expr * expr)
tmp = fold_build2 (MULT_EXPR, type, arrayse1.expr, arrayse2.expr);
tmp = fold_build2 (PLUS_EXPR, type, resvar, tmp);
}
- gfc_add_modify_expr (&block, resvar, tmp);
+ gfc_add_modify (&block, resvar, tmp);
/* Finish up the loop block and the loop. */
tmp = gfc_finish_block (&block);
@@ -2145,7 +2146,7 @@ gfc_conv_intrinsic_minmaxloc (gfc_se * se, gfc_expr * expr, int op)
possible value is HUGE in both cases. */
if (op == GT_EXPR)
tmp = fold_build1 (NEGATE_EXPR, TREE_TYPE (tmp), tmp);
- gfc_add_modify_expr (&se->pre, limit, tmp);
+ gfc_add_modify (&se->pre, limit, tmp);
if (op == GT_EXPR && expr->ts.type == BT_INTEGER)
tmp = fold_build2 (MINUS_EXPR, TREE_TYPE (tmp), tmp,
@@ -2159,14 +2160,14 @@ gfc_conv_intrinsic_minmaxloc (gfc_se * se, gfc_expr * expr, int op)
/* Initialize the loop. */
gfc_conv_ss_startstride (&loop);
- gfc_conv_loop_setup (&loop);
+ gfc_conv_loop_setup (&loop, &expr->where);
gcc_assert (loop.dimen == 1);
/* Initialize the position to zero, following Fortran 2003. We are free
to do this because Fortran 95 allows the result of an entirely false
mask to be processor dependent. */
- gfc_add_modify_expr (&loop.pre, pos, gfc_index_zero_node);
+ gfc_add_modify (&loop.pre, pos, gfc_index_zero_node);
gfc_mark_ss_chain_used (arrayss, 1);
if (maskss)
@@ -2199,7 +2200,7 @@ gfc_conv_intrinsic_minmaxloc (gfc_se * se, gfc_expr * expr, int op)
gfc_start_block (&ifblock);
/* Assign the value to the limit... */
- gfc_add_modify_expr (&ifblock, limit, arrayse.expr);
+ gfc_add_modify (&ifblock, limit, arrayse.expr);
/* Remember where we are. An offset must be added to the loop
counter to obtain the required position. */
@@ -2209,11 +2210,11 @@ gfc_conv_intrinsic_minmaxloc (gfc_se * se, gfc_expr * expr, int op)
else
tmp = build_int_cst (gfc_array_index_type, 1);
- gfc_add_modify_expr (&block, offset, tmp);
+ gfc_add_modify (&block, offset, tmp);
tmp = fold_build2 (PLUS_EXPR, TREE_TYPE (pos),
loop.loopvar[0], offset);
- gfc_add_modify_expr (&ifblock, pos, tmp);
+ gfc_add_modify (&ifblock, pos, tmp);
ifbody = gfc_finish_block (&ifblock);
@@ -2257,7 +2258,7 @@ gfc_conv_intrinsic_minmaxloc (gfc_se * se, gfc_expr * expr, int op)
the pos variable the same way as above. */
gfc_init_block (&elseblock);
- gfc_add_modify_expr (&elseblock, pos, gfc_index_zero_node);
+ gfc_add_modify (&elseblock, pos, gfc_index_zero_node);
elsetmp = gfc_finish_block (&elseblock);
tmp = build3_v (COND_EXPR, maskse.expr, tmp, elsetmp);
@@ -2328,7 +2329,7 @@ gfc_conv_intrinsic_minmaxval (gfc_se * se, gfc_expr * expr, int op)
tmp = fold_build2 (MINUS_EXPR, TREE_TYPE (tmp),
tmp, build_int_cst (type, 1));
- gfc_add_modify_expr (&se->pre, limit, tmp);
+ gfc_add_modify (&se->pre, limit, tmp);
/* Walk the arguments. */
actual = expr->value.function.actual;
@@ -2355,7 +2356,7 @@ gfc_conv_intrinsic_minmaxval (gfc_se * se, gfc_expr * expr, int op)
/* Initialize the loop. */
gfc_conv_ss_startstride (&loop);
- gfc_conv_loop_setup (&loop);
+ gfc_conv_loop_setup (&loop, &expr->where);
gfc_mark_ss_chain_used (arrayss, 1);
if (maskss)
@@ -2754,7 +2755,7 @@ gfc_conv_intrinsic_index_scan_verify (gfc_se * se, gfc_expr * expr,
args = (tree *) alloca (sizeof (tree) * 5);
/* Get number of arguments; characters count double due to the
- string length argument. Kind= is not passed to the libary
+ string length argument. Kind= is not passed to the library
and thus ignored. */
if (expr->value.function.actual->next->next->expr == NULL)
num_args = 4;
@@ -3002,12 +3003,12 @@ gfc_conv_intrinsic_spacing (gfc_se * se, gfc_expr * expr)
gfc_add_expr_to_block (&block, tmp);
tmp = fold_build2 (MINUS_EXPR, integer_type_node, e, prec);
- gfc_add_modify_expr (&block, e, fold_build2 (MAX_EXPR, integer_type_node,
+ gfc_add_modify (&block, e, fold_build2 (MAX_EXPR, integer_type_node,
tmp, emin));
tmp = build_call_expr (built_in_decls[scalbn], 2,
build_real_from_int_cst (type, integer_one_node), e);
- gfc_add_modify_expr (&block, res, tmp);
+ gfc_add_modify (&block, res, tmp);
/* Finish by building the IF statement. */
cond = fold_build2 (EQ_EXPR, boolean_type_node, arg,
@@ -3070,7 +3071,7 @@ gfc_conv_intrinsic_rrspacing (gfc_se * se, gfc_expr * expr)
e = gfc_create_var (integer_type_node, NULL);
x = gfc_create_var (type, NULL);
- gfc_add_modify_expr (&se->pre, x,
+ gfc_add_modify (&se->pre, x,
build_call_expr (built_in_decls[fabs], 1, arg));
@@ -3082,7 +3083,7 @@ gfc_conv_intrinsic_rrspacing (gfc_se * se, gfc_expr * expr)
tmp = fold_build2 (MINUS_EXPR, integer_type_node,
build_int_cst (NULL_TREE, prec), e);
tmp = build_call_expr (built_in_decls[scalbn], 2, x, tmp);
- gfc_add_modify_expr (&block, x, tmp);
+ gfc_add_modify (&block, x, tmp);
stmt = gfc_finish_block (&block);
cond = fold_build2 (NE_EXPR, boolean_type_node, x,
@@ -3299,7 +3300,7 @@ gfc_conv_intrinsic_sizeof (gfc_se *se, gfc_expr *expr)
else
tmp = fold_convert (gfc_array_index_type,
size_in_bytes (type));
- gfc_add_modify_expr (&argse.pre, source_bytes, tmp);
+ gfc_add_modify (&argse.pre, source_bytes, tmp);
/* Obtain the size of the array in bytes. */
for (n = 0; n < arg->rank; n++)
@@ -3314,7 +3315,7 @@ gfc_conv_intrinsic_sizeof (gfc_se *se, gfc_expr *expr)
tmp, gfc_index_one_node);
tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
tmp, source_bytes);
- gfc_add_modify_expr (&argse.pre, source_bytes, tmp);
+ gfc_add_modify (&argse.pre, source_bytes, tmp);
}
se->expr = source_bytes;
}
@@ -3434,6 +3435,10 @@ gfc_conv_intrinsic_array_transfer (gfc_se * se, gfc_expr * expr)
&& arg->expr->ref->u.ar.type == AR_FULL))
{
tmp = build_fold_addr_expr (argse.expr);
+
+ if (gfc_option.warn_array_temp)
+ gfc_warning ("Creating array temporary at %L", &expr->where);
+
source = build_call_expr (gfor_fndecl_in_pack, 1, tmp);
source = gfc_evaluate_now (source, &argse.pre);
@@ -3468,13 +3473,13 @@ gfc_conv_intrinsic_array_transfer (gfc_se * se, gfc_expr * expr)
{
tree idx;
idx = gfc_rank_cst[n];
- gfc_add_modify_expr (&argse.pre, source_bytes, tmp);
+ gfc_add_modify (&argse.pre, source_bytes, tmp);
stride = gfc_conv_descriptor_stride (argse.expr, idx);
lower = gfc_conv_descriptor_lbound (argse.expr, idx);
upper = gfc_conv_descriptor_ubound (argse.expr, idx);
tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
upper, lower);
- gfc_add_modify_expr (&argse.pre, extent, tmp);
+ gfc_add_modify (&argse.pre, extent, tmp);
tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
extent, gfc_index_one_node);
tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
@@ -3482,7 +3487,7 @@ gfc_conv_intrinsic_array_transfer (gfc_se * se, gfc_expr * expr)
}
}
- gfc_add_modify_expr (&argse.pre, source_bytes, tmp);
+ gfc_add_modify (&argse.pre, source_bytes, tmp);
gfc_add_block_to_block (&se->pre, &argse.pre);
gfc_add_block_to_block (&se->post, &argse.post);
@@ -3517,7 +3522,7 @@ gfc_conv_intrinsic_array_transfer (gfc_se * se, gfc_expr * expr)
size_in_bytes (mold_type));
dest_word_len = gfc_create_var (gfc_array_index_type, NULL);
- gfc_add_modify_expr (&se->pre, dest_word_len, tmp);
+ gfc_add_modify (&se->pre, dest_word_len, tmp);
/* Finally convert SIZE, if it is present. */
arg = arg->next;
@@ -3546,8 +3551,8 @@ gfc_conv_intrinsic_array_transfer (gfc_se * se, gfc_expr * expr)
else
tmp = source_bytes;
- gfc_add_modify_expr (&se->pre, size_bytes, tmp);
- gfc_add_modify_expr (&se->pre, size_words,
+ gfc_add_modify (&se->pre, size_bytes, tmp);
+ gfc_add_modify (&se->pre, size_words,
fold_build2 (CEIL_DIV_EXPR, gfc_array_index_type,
size_bytes, dest_word_len));
@@ -3564,8 +3569,8 @@ gfc_conv_intrinsic_array_transfer (gfc_se * se, gfc_expr * expr)
tmp, gfc_index_one_node);
tmp = fold_build2 (MIN_EXPR, gfc_array_index_type,
tmp, size_words);
- gfc_add_modify_expr (&se->pre, size_words, tmp);
- gfc_add_modify_expr (&se->pre, size_bytes,
+ gfc_add_modify (&se->pre, size_words, tmp);
+ gfc_add_modify (&se->pre, size_bytes,
fold_build2 (MULT_EXPR, gfc_array_index_type,
size_words, dest_word_len));
upper = fold_build2 (PLUS_EXPR, gfc_array_index_type,
@@ -3587,7 +3592,8 @@ gfc_conv_intrinsic_array_transfer (gfc_se * se, gfc_expr * expr)
FIXME callee_alloc is not set! */
gfc_trans_create_temp_array (&se->pre, &se->post, se->loop,
- info, mold_type, false, true, false);
+ info, mold_type, false, true, false,
+ &expr->where);
/* Cast the pointer to the result. */
tmp = gfc_conv_descriptor_data_get (info->descriptor);
@@ -3627,7 +3633,7 @@ gfc_conv_intrinsic_transfer (gfc_se * se, gfc_expr * expr)
if (ss == gfc_ss_terminator)
gfc_conv_expr_reference (&argse, arg->expr);
else
- gfc_conv_array_parameter (&argse, arg->expr, ss, 1);
+ gfc_conv_array_parameter (&argse, arg->expr, ss, 1, NULL, NULL);
gfc_add_block_to_block (&se->pre, &argse.pre);
gfc_add_block_to_block (&se->post, &argse.post);
ptr = argse.expr;
@@ -3953,7 +3959,7 @@ gfc_conv_intrinsic_repeat (gfc_se * se, gfc_expr * expr)
/* Check that NCOPIES is not negative. */
cond = fold_build2 (LT_EXPR, boolean_type_node, ncopies,
build_int_cst (ncopies_type, 0));
- gfc_trans_runtime_check (cond, &se->pre, &expr->where,
+ gfc_trans_runtime_check (true, false, cond, &se->pre, &expr->where,
"Argument NCOPIES of REPEAT intrinsic is negative "
"(its value is %lld)",
fold_convert (long_integer_type_node, ncopies));
@@ -3965,7 +3971,7 @@ gfc_conv_intrinsic_repeat (gfc_se * se, gfc_expr * expr)
build_int_cst (size_type_node, 0));
tmp = fold_build3 (COND_EXPR, ncopies_type, cond,
build_int_cst (ncopies_type, 0), ncopies);
- gfc_add_modify_expr (&se->pre, n, tmp);
+ gfc_add_modify (&se->pre, n, tmp);
ncopies = n;
/* Check that ncopies is not too large: ncopies should be less than
@@ -3985,7 +3991,7 @@ gfc_conv_intrinsic_repeat (gfc_se * se, gfc_expr * expr)
build_int_cst (size_type_node, 0));
cond = fold_build3 (COND_EXPR, boolean_type_node, tmp, boolean_false_node,
cond);
- gfc_trans_runtime_check (cond, &se->pre, &expr->where,
+ gfc_trans_runtime_check (true, false, cond, &se->pre, &expr->where,
"Argument NCOPIES of REPEAT intrinsic is too large");
/* Compute the destination length. */
@@ -4000,7 +4006,7 @@ gfc_conv_intrinsic_repeat (gfc_se * se, gfc_expr * expr)
memmove (dest + (i * slen * size), src, slen*size); */
gfc_start_block (&block);
count = gfc_create_var (ncopies_type, "count");
- gfc_add_modify_expr (&block, count, build_int_cst (ncopies_type, 0));
+ gfc_add_modify (&block, count, build_int_cst (ncopies_type, 0));
exit_label = gfc_build_label_decl (NULL_TREE);
/* Start the loop body. */
@@ -4031,7 +4037,7 @@ gfc_conv_intrinsic_repeat (gfc_se * se, gfc_expr * expr)
/* Increment count. */
tmp = fold_build2 (PLUS_EXPR, ncopies_type,
count, build_int_cst (TREE_TYPE (count), 1));
- gfc_add_modify_expr (&body, count, tmp);
+ gfc_add_modify (&body, count, tmp);
/* Build the loop. */
tmp = build1_v (LOOP_EXPR, gfc_finish_block (&body));
@@ -4089,13 +4095,13 @@ gfc_conv_intrinsic_loc (gfc_se * se, gfc_expr * expr)
if (ss == gfc_ss_terminator)
gfc_conv_expr_reference (se, arg_expr);
else
- gfc_conv_array_parameter (se, arg_expr, ss, 1);
+ gfc_conv_array_parameter (se, arg_expr, ss, 1, NULL, NULL);
se->expr= convert (gfc_get_int_type (gfc_index_integer_kind), se->expr);
/* Create a temporary variable for loc return value. Without this,
we get an error an ICE in gcc/expr.c(expand_expr_addr_expr_1). */
temp_var = gfc_create_var (gfc_get_int_type (gfc_index_integer_kind), NULL);
- gfc_add_modify_expr (&se->pre, temp_var, se->expr);
+ gfc_add_modify (&se->pre, temp_var, se->expr);
se->expr = temp_var;
}
@@ -4666,7 +4672,7 @@ gfc_walk_intrinsic_libfunc (gfc_ss * ss, gfc_expr * expr)
}
-/* Returns nonzero if the specified intrinsic function call maps directly to a
+/* Returns nonzero if the specified intrinsic function call maps directly to
an external library call. Should only be used for functions that return
arrays. */
diff --git a/gcc/fortran/trans-io.c b/gcc/fortran/trans-io.c
index f210169abe0..e304d1687bf 100644
--- a/gcc/fortran/trans-io.c
+++ b/gcc/fortran/trans-io.c
@@ -24,7 +24,7 @@ along with GCC; see the file COPYING3. If not see
#include "system.h"
#include "coretypes.h"
#include "tree.h"
-#include "tree-gimple.h"
+#include "gimple.h"
#include "ggc.h"
#include "toplev.h"
#include "real.h"
@@ -450,7 +450,7 @@ set_parameter_const (stmtblock_t *block, tree var, enum iofield type,
var, TYPE_FIELDS (TREE_TYPE (var)), NULL_TREE);
tmp = fold_build3 (COMPONENT_REF, TREE_TYPE (p->field), var, p->field,
NULL_TREE);
- gfc_add_modify_expr (block, tmp, build_int_cst (TREE_TYPE (p->field), val));
+ gfc_add_modify (block, tmp, build_int_cst (TREE_TYPE (p->field), val));
return p->mask;
}
@@ -505,7 +505,7 @@ set_parameter_value (stmtblock_t *block, tree var, enum iofield type,
var, TYPE_FIELDS (TREE_TYPE (var)), NULL_TREE);
tmp = fold_build3 (COMPONENT_REF, dest_type, var, p->field, NULL_TREE);
- gfc_add_modify_expr (block, tmp, se.expr);
+ gfc_add_modify (block, tmp, se.expr);
return p->mask;
}
@@ -535,7 +535,7 @@ set_parameter_ref (stmtblock_t *block, stmtblock_t *postblock,
/* If this is for the iostat variable initialize the
user variable to LIBERROR_OK which is zero. */
if (type == IOPARM_common_iostat)
- gfc_add_modify_expr (block, se.expr,
+ gfc_add_modify (block, se.expr,
build_int_cst (TREE_TYPE (se.expr), LIBERROR_OK));
}
else
@@ -549,13 +549,13 @@ set_parameter_ref (stmtblock_t *block, stmtblock_t *postblock,
/* If this is for the iostat variable, initialize the
user variable to LIBERROR_OK which is zero. */
if (type == IOPARM_common_iostat)
- gfc_add_modify_expr (block, tmpvar,
+ gfc_add_modify (block, tmpvar,
build_int_cst (TREE_TYPE (tmpvar), LIBERROR_OK));
addr = build_fold_addr_expr (tmpvar);
/* After the I/O operation, we set the variable from the temporary. */
tmp = convert (TREE_TYPE (se.expr), tmpvar);
- gfc_add_modify_expr (postblock, se.expr, tmp);
+ gfc_add_modify (postblock, se.expr, tmp);
}
if (p->param_type == IOPARM_ptype_common)
@@ -563,7 +563,7 @@ set_parameter_ref (stmtblock_t *block, stmtblock_t *postblock,
var, TYPE_FIELDS (TREE_TYPE (var)), NULL_TREE);
tmp = fold_build3 (COMPONENT_REF, TREE_TYPE (p->field),
var, p->field, NULL_TREE);
- gfc_add_modify_expr (block, tmp, addr);
+ gfc_add_modify (block, tmp, addr);
return p->mask;
}
@@ -668,13 +668,13 @@ set_string (stmtblock_t * block, stmtblock_t * postblock, tree var,
asprintf(&msg, "Label assigned to variable '%s' (%%ld) is not a format "
"label", e->symtree->name);
- gfc_trans_runtime_check (cond, &se.pre, &e->where, msg,
+ gfc_trans_runtime_check (true, false, cond, &se.pre, &e->where, msg,
fold_convert (long_integer_type_node, tmp));
gfc_free (msg);
- gfc_add_modify_expr (&se.pre, io,
+ gfc_add_modify (&se.pre, io,
fold_convert (TREE_TYPE (io), GFC_DECL_ASSIGN_ADDR (se.expr)));
- gfc_add_modify_expr (&se.pre, len, GFC_DECL_STRING_LEN (se.expr));
+ gfc_add_modify (&se.pre, len, GFC_DECL_STRING_LEN (se.expr));
}
else
{
@@ -688,8 +688,8 @@ set_string (stmtblock_t * block, stmtblock_t * postblock, tree var,
gcc_unreachable ();
gfc_conv_string_parameter (&se);
- gfc_add_modify_expr (&se.pre, io, fold_convert (TREE_TYPE (io), se.expr));
- gfc_add_modify_expr (&se.pre, len, se.string_length);
+ gfc_add_modify (&se.pre, io, fold_convert (TREE_TYPE (io), se.expr));
+ gfc_add_modify (&se.pre, len, se.string_length);
}
gfc_add_block_to_block (block, &se.pre);
@@ -764,10 +764,10 @@ set_internal_unit (stmtblock_t * block, stmtblock_t * post_block,
/* The cast is needed for character substrings and the descriptor
data. */
- gfc_add_modify_expr (&se.pre, io, fold_convert (TREE_TYPE (io), tmp));
- gfc_add_modify_expr (&se.pre, len,
+ gfc_add_modify (&se.pre, io, fold_convert (TREE_TYPE (io), tmp));
+ gfc_add_modify (&se.pre, len,
fold_convert (TREE_TYPE (len), se.string_length));
- gfc_add_modify_expr (&se.pre, desc, se.expr);
+ gfc_add_modify (&se.pre, desc, se.expr);
gfc_add_block_to_block (block, &se.pre);
gfc_add_block_to_block (post_block, &se.post);
@@ -865,7 +865,7 @@ set_error_locus (stmtblock_t * block, tree var, locus * where)
str = gfc_build_cstring_const (f->filename);
str = gfc_build_addr_expr (pchar_type_node, str);
- gfc_add_modify_expr (block, locus_file, str);
+ gfc_add_modify (block, locus_file, str);
line = LOCATION_LINE (where->lb->location);
set_parameter_const (block, var, IOPARM_common_line, line);
@@ -1900,7 +1900,7 @@ transfer_expr (gfc_se * se, gfc_typespec * ts, tree addr_expr, gfc_code * code);
recursive. */
static tree
-transfer_array_component (tree expr, gfc_component * cm)
+transfer_array_component (tree expr, gfc_component * cm, locus * where)
{
tree tmp;
stmtblock_t body;
@@ -1944,7 +1944,7 @@ transfer_array_component (tree expr, gfc_component * cm)
gfc_init_loopinfo (&loop);
gfc_add_ss_to_loop (&loop, ss);
gfc_conv_ss_startstride (&loop);
- gfc_conv_loop_setup (&loop);
+ gfc_conv_loop_setup (&loop, where);
gfc_mark_ss_chain_used (ss, 1);
gfc_start_scalarized_body (&loop, &body);
@@ -2089,7 +2089,7 @@ transfer_expr (gfc_se * se, gfc_typespec * ts, tree addr_expr, gfc_code * code)
if (c->dimension)
{
- tmp = transfer_array_component (tmp, c);
+ tmp = transfer_array_component (tmp, c, & code->loc);
gfc_add_expr_to_block (&se->pre, tmp);
}
else
@@ -2213,7 +2213,7 @@ gfc_trans_transfer (gfc_code * code)
/* Initialize the loop. */
gfc_conv_ss_startstride (&loop);
- gfc_conv_loop_setup (&loop);
+ gfc_conv_loop_setup (&loop, &code->expr->where);
/* The main loop body. */
gfc_mark_ss_chain_used (ss, 1);
diff --git a/gcc/fortran/trans-openmp.c b/gcc/fortran/trans-openmp.c
index 6f99800a014..49fd1f6152f 100644
--- a/gcc/fortran/trans-openmp.c
+++ b/gcc/fortran/trans-openmp.c
@@ -23,7 +23,7 @@ along with GCC; see the file COPYING3. If not see
#include "system.h"
#include "coretypes.h"
#include "tree.h"
-#include "tree-gimple.h"
+#include "gimple.h"
#include "ggc.h"
#include "toplev.h"
#include "real.h"
@@ -147,7 +147,7 @@ gfc_omp_clause_default_ctor (tree clause, tree decl, tree outer)
gfc_init_block (&cond_block);
- gfc_add_modify_expr (&cond_block, decl, outer);
+ gfc_add_modify (&cond_block, decl, outer);
rank = gfc_rank_cst[GFC_TYPE_ARRAY_RANK (type) - 1];
size = gfc_conv_descriptor_ubound (decl, rank);
size = fold_build2 (MINUS_EXPR, gfc_array_index_type, size,
@@ -164,11 +164,11 @@ gfc_omp_clause_default_ctor (tree clause, tree decl, tree outer)
ptr = gfc_allocate_array_with_status (&cond_block,
build_int_cst (pvoid_type_node, 0),
size, NULL);
- gfc_conv_descriptor_data_set_tuples (&cond_block, decl, ptr);
+ gfc_conv_descriptor_data_set (&cond_block, decl, ptr);
then_b = gfc_finish_block (&cond_block);
gfc_init_block (&cond_block);
- gfc_conv_descriptor_data_set_tuples (&cond_block, decl, null_pointer_node);
+ gfc_conv_descriptor_data_set (&cond_block, decl, null_pointer_node);
else_b = gfc_finish_block (&cond_block);
cond = fold_build2 (NE_EXPR, boolean_type_node,
@@ -191,7 +191,7 @@ gfc_omp_clause_copy_ctor (tree clause, tree dest, tree src)
if (! GFC_DESCRIPTOR_TYPE_P (type)
|| GFC_TYPE_ARRAY_AKIND (type) != GFC_ARRAY_ALLOCATABLE)
- return build_gimple_modify_stmt (dest, src);
+ return build2_v (MODIFY_EXPR, dest, src);
gcc_assert (OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_FIRSTPRIVATE);
@@ -199,7 +199,7 @@ gfc_omp_clause_copy_ctor (tree clause, tree dest, tree src)
and copied from SRC. */
gfc_start_block (&block);
- gfc_add_modify_expr (&block, dest, src);
+ gfc_add_modify (&block, dest, src);
rank = gfc_rank_cst[GFC_TYPE_ARRAY_RANK (type) - 1];
size = gfc_conv_descriptor_ubound (dest, rank);
size = fold_build2 (MINUS_EXPR, gfc_array_index_type, size,
@@ -216,7 +216,7 @@ gfc_omp_clause_copy_ctor (tree clause, tree dest, tree src)
ptr = gfc_allocate_array_with_status (&block,
build_int_cst (pvoid_type_node, 0),
size, NULL);
- gfc_conv_descriptor_data_set_tuples (&block, dest, ptr);
+ gfc_conv_descriptor_data_set (&block, dest, ptr);
call = build_call_expr (built_in_decls[BUILT_IN_MEMCPY], 3, ptr,
fold_convert (pvoid_type_node,
gfc_conv_descriptor_data_get (src)),
@@ -236,7 +236,7 @@ gfc_omp_clause_assign_op (tree clause ATTRIBUTE_UNUSED, tree dest, tree src)
if (! GFC_DESCRIPTOR_TYPE_P (type)
|| GFC_TYPE_ARRAY_AKIND (type) != GFC_ARRAY_ALLOCATABLE)
- return build_gimple_modify_stmt (dest, src);
+ return build2_v (MODIFY_EXPR, dest, src);
/* Handle copying allocatable arrays. */
gfc_start_block (&block);
@@ -602,7 +602,7 @@ gfc_trans_omp_array_reduction (tree c, gfc_symbol *sym, locus where)
gfc_start_block (&block);
- gfc_add_modify_expr (&block, decl, outer_sym.backend_decl);
+ gfc_add_modify (&block, decl, outer_sym.backend_decl);
rank = gfc_rank_cst[GFC_TYPE_ARRAY_RANK (type) - 1];
size = gfc_conv_descriptor_ubound (decl, rank);
size = fold_build2 (MINUS_EXPR, gfc_array_index_type, size,
@@ -619,7 +619,7 @@ gfc_trans_omp_array_reduction (tree c, gfc_symbol *sym, locus where)
ptr = gfc_allocate_array_with_status (&block,
build_int_cst (pvoid_type_node, 0),
size, NULL);
- gfc_conv_descriptor_data_set_tuples (&block, decl, ptr);
+ gfc_conv_descriptor_data_set (&block, decl, ptr);
gfc_add_expr_to_block (&block, gfc_trans_assignment (e1, e2, false));
stmt = gfc_finish_block (&block);
}
@@ -969,7 +969,7 @@ gfc_trans_omp_atomic (gfc_code *code)
if (expr2->expr_type == EXPR_OP)
{
gfc_expr *e;
- switch (expr2->value.op.operator)
+ switch (expr2->value.op.op)
{
case INTRINSIC_PLUS:
op = PLUS_EXPR;
@@ -1062,7 +1062,7 @@ gfc_trans_omp_atomic (gfc_code *code)
tree accum = gfc_create_var (TREE_TYPE (rse.expr), NULL);
gfc_actual_arglist *arg;
- gfc_add_modify_stmt (&block, accum, rse.expr);
+ gfc_add_modify (&block, accum, rse.expr);
for (arg = expr2->value.function.actual->next->next; arg;
arg = arg->next)
{
@@ -1070,7 +1070,7 @@ gfc_trans_omp_atomic (gfc_code *code)
gfc_conv_expr (&rse, arg->expr);
gfc_add_block_to_block (&block, &rse.pre);
x = fold_build2 (op, TREE_TYPE (accum), accum, rse.expr);
- gfc_add_modify_stmt (&block, accum, x);
+ gfc_add_modify (&block, accum, x);
}
rse.expr = accum;
@@ -1204,11 +1204,11 @@ gfc_trans_omp_do (gfc_code *code, stmtblock_t *pblock,
/* Loop body. */
if (simple)
{
- TREE_VEC_ELT (init, i) = build2_v (GIMPLE_MODIFY_STMT, dovar, from);
+ TREE_VEC_ELT (init, i) = build2_v (MODIFY_EXPR, dovar, from);
TREE_VEC_ELT (cond, i) = fold_build2 (simple > 0 ? LE_EXPR : GE_EXPR,
boolean_type_node, dovar, to);
TREE_VEC_ELT (incr, i) = fold_build2 (PLUS_EXPR, type, dovar, step);
- TREE_VEC_ELT (incr, i) = fold_build2 (GIMPLE_MODIFY_STMT, type, dovar,
+ TREE_VEC_ELT (incr, i) = fold_build2 (MODIFY_EXPR, type, dovar,
TREE_VEC_ELT (incr, i));
}
else
@@ -1225,13 +1225,13 @@ gfc_trans_omp_do (gfc_code *code, stmtblock_t *pblock,
tmp = fold_build2 (TRUNC_DIV_EXPR, type, tmp, step);
tmp = gfc_evaluate_now (tmp, pblock);
count = gfc_create_var (type, "count");
- TREE_VEC_ELT (init, i) = build2_v (GIMPLE_MODIFY_STMT, count,
+ TREE_VEC_ELT (init, i) = build2_v (MODIFY_EXPR, count,
build_int_cst (type, 0));
TREE_VEC_ELT (cond, i) = fold_build2 (LT_EXPR, boolean_type_node,
count, tmp);
TREE_VEC_ELT (incr, i) = fold_build2 (PLUS_EXPR, type, count,
build_int_cst (type, 1));
- TREE_VEC_ELT (incr, i) = fold_build2 (GIMPLE_MODIFY_STMT, type,
+ TREE_VEC_ELT (incr, i) = fold_build2 (MODIFY_EXPR, type,
count, TREE_VEC_ELT (incr, i));
/* Initialize DOVAR. */
@@ -1260,7 +1260,7 @@ gfc_trans_omp_do (gfc_code *code, stmtblock_t *pblock,
than value after iterator increment. */
tmp = gfc_evaluate_now (step, pblock);
tmp = fold_build2 (PLUS_EXPR, type, dovar, tmp);
- tmp = fold_build2 (GIMPLE_MODIFY_STMT, type, dovar, tmp);
+ tmp = fold_build2 (MODIFY_EXPR, type, dovar, tmp);
for (c = omp_clauses; c ; c = OMP_CLAUSE_CHAIN (c))
if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
&& OMP_CLAUSE_DECL (c) == dovar)
@@ -1308,7 +1308,7 @@ gfc_trans_omp_do (gfc_code *code, stmtblock_t *pblock,
dovar_init = nreverse (dovar_init);
while (dovar_init)
{
- gfc_add_modify_stmt (&body, TREE_PURPOSE (dovar_init),
+ gfc_add_modify (&body, TREE_PURPOSE (dovar_init),
TREE_VALUE (dovar_init));
dovar_init = TREE_CHAIN (dovar_init);
}
@@ -1381,7 +1381,7 @@ gfc_trans_omp_parallel (gfc_code *code)
omp_clauses = gfc_trans_omp_clauses (&block, code->ext.omp_clauses,
code->loc);
stmt = gfc_trans_omp_code (code->block->next, true);
- stmt = build4_v (OMP_PARALLEL, stmt, omp_clauses, NULL, NULL);
+ stmt = build2 (OMP_PARALLEL, void_type_node, stmt, omp_clauses);
gfc_add_expr_to_block (&block, stmt);
return gfc_finish_block (&block);
}
@@ -1421,7 +1421,7 @@ gfc_trans_omp_parallel_do (gfc_code *code)
stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0, 0));
else
poplevel (0, 0, 0);
- stmt = build4_v (OMP_PARALLEL, stmt, omp_clauses, NULL, NULL);
+ stmt = build2 (OMP_PARALLEL, void_type_node, stmt, omp_clauses);
OMP_PARALLEL_COMBINED (stmt) = 1;
gfc_add_expr_to_block (&block, stmt);
return gfc_finish_block (&block);
@@ -1446,7 +1446,7 @@ gfc_trans_omp_parallel_sections (gfc_code *code)
stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0, 0));
else
poplevel (0, 0, 0);
- stmt = build4_v (OMP_PARALLEL, stmt, omp_clauses, NULL, NULL);
+ stmt = build2 (OMP_PARALLEL, void_type_node, stmt, omp_clauses);
OMP_PARALLEL_COMBINED (stmt) = 1;
gfc_add_expr_to_block (&block, stmt);
return gfc_finish_block (&block);
@@ -1471,7 +1471,7 @@ gfc_trans_omp_parallel_workshare (gfc_code *code)
stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0, 0));
else
poplevel (0, 0, 0);
- stmt = build4_v (OMP_PARALLEL, stmt, omp_clauses, NULL, NULL);
+ stmt = build2 (OMP_PARALLEL, void_type_node, stmt, omp_clauses);
OMP_PARALLEL_COMBINED (stmt) = 1;
gfc_add_expr_to_block (&block, stmt);
return gfc_finish_block (&block);
@@ -1503,7 +1503,7 @@ gfc_trans_omp_sections (gfc_code *code, gfc_omp_clauses *clauses)
}
stmt = gfc_finish_block (&body);
- stmt = build3_v (OMP_SECTIONS, stmt, omp_clauses, NULL_TREE);
+ stmt = build2 (OMP_SECTIONS, void_type_node, stmt, omp_clauses);
gfc_add_expr_to_block (&block, stmt);
return gfc_finish_block (&block);
@@ -1522,16 +1522,13 @@ static tree
gfc_trans_omp_task (gfc_code *code)
{
stmtblock_t block;
- tree stmt, body_stmt, omp_clauses;
+ tree stmt, omp_clauses;
gfc_start_block (&block);
omp_clauses = gfc_trans_omp_clauses (&block, code->ext.omp_clauses,
code->loc);
- body_stmt = gfc_trans_omp_code (code->block->next, true);
- stmt = make_node (OMP_TASK);
- TREE_TYPE (stmt) = void_type_node;
- OMP_TASK_CLAUSES (stmt) = omp_clauses;
- OMP_TASK_BODY (stmt) = body_stmt;
+ stmt = gfc_trans_omp_code (code->block->next, true);
+ stmt = build2 (OMP_TASK, void_type_node, stmt, omp_clauses);
gfc_add_expr_to_block (&block, stmt);
return gfc_finish_block (&block);
}
diff --git a/gcc/fortran/trans-stmt.c b/gcc/fortran/trans-stmt.c
index 6afac5d3734..bf4305ba9c3 100644
--- a/gcc/fortran/trans-stmt.c
+++ b/gcc/fortran/trans-stmt.c
@@ -25,7 +25,7 @@ along with GCC; see the file COPYING3. If not see
#include "system.h"
#include "coretypes.h"
#include "tree.h"
-#include "tree-gimple.h"
+#include "gimple.h"
#include "ggc.h"
#include "toplev.h"
#include "real.h"
@@ -127,8 +127,8 @@ gfc_trans_label_assign (gfc_code * code)
label_tree = gfc_build_addr_expr (pvoid_type_node, label_tree);
}
- gfc_add_modify_expr (&se.pre, len, len_tree);
- gfc_add_modify_expr (&se.pre, addr, label_tree);
+ gfc_add_modify (&se.pre, len, len_tree);
+ gfc_add_modify (&se.pre, addr, label_tree);
return gfc_finish_block (&se.pre);
}
@@ -154,7 +154,7 @@ gfc_trans_goto (gfc_code * code)
tmp = GFC_DECL_STRING_LEN (se.expr);
tmp = fold_build2 (NE_EXPR, boolean_type_node, tmp,
build_int_cst (TREE_TYPE (tmp), -1));
- gfc_trans_runtime_check (tmp, &se.pre, &loc,
+ gfc_trans_runtime_check (true, false, tmp, &se.pre, &loc,
"Assigned label is not a target label");
assigned_goto = GFC_DECL_ASSIGN_ADDR (se.expr);
@@ -180,7 +180,7 @@ gfc_trans_goto (gfc_code * code)
code = code->block;
}
while (code != NULL);
- gfc_trans_runtime_check (boolean_true_node, &se.pre, &loc,
+ gfc_trans_runtime_check (true, false, boolean_true_node, &se.pre, &loc,
"Assigned label is not in the list");
return gfc_finish_block (&se.pre);
@@ -269,10 +269,11 @@ gfc_conv_elemental_dependencies (gfc_se * se, gfc_se * loopse,
tmp = gfc_typenode_for_spec (&e->ts);
tmp = gfc_trans_create_temp_array (&se->pre, &se->post,
&tmp_loop, info, tmp,
- false, true, false);
- gfc_add_modify_expr (&se->pre, size, tmp);
+ false, true, false,
+ & arg->expr->where);
+ gfc_add_modify (&se->pre, size, tmp);
tmp = fold_convert (pvoid_type_node, info->data);
- gfc_add_modify_expr (&se->pre, data, tmp);
+ gfc_add_modify (&se->pre, data, tmp);
gfc_merge_block_scope (&block);
/* Obtain the argument descriptor for unpacking. */
@@ -293,7 +294,7 @@ gfc_conv_elemental_dependencies (gfc_se * se, gfc_se * loopse,
offset, tmp);
}
info->offset = gfc_create_var (gfc_array_index_type, NULL);
- gfc_add_modify_expr (&se->pre, info->offset, offset);
+ gfc_add_modify (&se->pre, info->offset, offset);
/* Copy the result back using unpack. */
tmp = build_call_expr (gfor_fndecl_in_unpack, 2, parmse.expr, data);
@@ -348,7 +349,7 @@ gfc_trans_call (gfc_code * code, bool dependency_check)
se.expr = convert (gfc_typenode_for_spec (&sym->ts), se.expr);
if (sym->backend_decl == NULL)
sym->backend_decl = gfc_get_symbol_decl (sym);
- gfc_add_modify_expr (&se.pre, sym->backend_decl, se.expr);
+ gfc_add_modify (&se.pre, sym->backend_decl, se.expr);
}
else
gfc_add_expr_to_block (&se.pre, se.expr);
@@ -375,7 +376,7 @@ gfc_trans_call (gfc_code * code, bool dependency_check)
gfc_add_ss_to_loop (&loop, ss);
gfc_conv_ss_startstride (&loop);
- gfc_conv_loop_setup (&loop);
+ gfc_conv_loop_setup (&loop, &code->expr->where);
gfc_mark_ss_chain_used (ss, 1);
/* Convert the arguments, checking for dependencies. */
@@ -733,7 +734,7 @@ gfc_trans_simple_do (gfc_code * code, stmtblock_t *pblock, tree dovar,
type = TREE_TYPE (dovar);
/* Initialize the DO variable: dovar = from. */
- gfc_add_modify_expr (pblock, dovar, from);
+ gfc_add_modify (pblock, dovar, from);
/* Cycle and exit statements are implemented with gotos. */
cycle_label = gfc_build_label_decl (NULL_TREE);
@@ -762,7 +763,7 @@ gfc_trans_simple_do (gfc_code * code, stmtblock_t *pblock, tree dovar,
/* Increment the loop variable. */
tmp = fold_build2 (PLUS_EXPR, type, dovar, step);
- gfc_add_modify_expr (&body, dovar, tmp);
+ gfc_add_modify (&body, dovar, tmp);
/* The loop exit. */
tmp = build1_v (GOTO_EXPR, exit_label);
@@ -910,7 +911,7 @@ gfc_trans_do (gfc_code * code)
tmp = fold_build1 (FIX_TRUNC_EXPR, utype, tmp);
}
countm1 = gfc_create_var (utype, "countm1");
- gfc_add_modify_expr (&block, countm1, tmp);
+ gfc_add_modify (&block, countm1, tmp);
/* Cycle and exit statements are implemented with gotos. */
cycle_label = gfc_build_label_decl (NULL_TREE);
@@ -918,7 +919,7 @@ gfc_trans_do (gfc_code * code)
TREE_USED (exit_label) = 1;
/* Initialize the DO variable: dovar = from. */
- gfc_add_modify_expr (&block, dovar, from);
+ gfc_add_modify (&block, dovar, from);
/* If the loop is empty, go directly to the exit label. */
tmp = fold_build3 (COND_EXPR, void_type_node, empty,
@@ -948,7 +949,7 @@ gfc_trans_do (gfc_code * code)
/* Increment the loop variable. */
tmp = fold_build2 (PLUS_EXPR, type, dovar, step);
- gfc_add_modify_expr (&body, dovar, tmp);
+ gfc_add_modify (&body, dovar, tmp);
/* End with the loop condition. Loop until countm1 == 0. */
cond = fold_build2 (EQ_EXPR, boolean_type_node, countm1,
@@ -960,7 +961,7 @@ gfc_trans_do (gfc_code * code)
/* Decrement the loop count. */
tmp = fold_build2 (MINUS_EXPR, utype, countm1, build_int_cst (utype, 1));
- gfc_add_modify_expr (&body, countm1, tmp);
+ gfc_add_modify (&body, countm1, tmp);
/* End of loop body. */
tmp = gfc_finish_block (&body);
@@ -1478,7 +1479,7 @@ gfc_trans_character_select (gfc_code *code)
tmp = build_call_expr (fndecl, 4, init, build_int_cst (NULL_TREE, n),
se.expr, se.string_length);
case_num = gfc_create_var (integer_type_node, "case_num");
- gfc_add_modify_expr (&block, case_num, tmp);
+ gfc_add_modify (&block, case_num, tmp);
gfc_add_block_to_block (&block, &se.post);
@@ -1608,7 +1609,7 @@ forall_make_variable_temp (gfc_code *c, stmtblock_t *pre, stmtblock_t *post)
{
/* Use the variable offset for the temporary. */
tmp = gfc_conv_descriptor_offset (tse.expr);
- gfc_add_modify_expr (pre, tmp,
+ gfc_add_modify (pre, tmp,
gfc_conv_array_offset (old_sym->backend_decl));
}
}
@@ -1764,7 +1765,7 @@ gfc_trans_forall_loop (forall_info *forall_tmp, tree body,
/* Initialize the mask index outside the FORALL nest. */
if (mask_flag && forall_tmp->mask)
- gfc_add_modify_expr (outer, forall_tmp->maskindex, gfc_index_zero_node);
+ gfc_add_modify (outer, forall_tmp->maskindex, gfc_index_zero_node);
iter = forall_tmp->this_loop;
nvar = forall_tmp->nvar;
@@ -1797,7 +1798,7 @@ gfc_trans_forall_loop (forall_info *forall_tmp, tree body,
/* Increment the loop variable. */
tmp = fold_build2 (PLUS_EXPR, TREE_TYPE (var), var, step);
- gfc_add_modify_expr (&block, var, tmp);
+ gfc_add_modify (&block, var, tmp);
/* Advance to the next mask element. Only do this for the
innermost loop. */
@@ -1806,26 +1807,26 @@ gfc_trans_forall_loop (forall_info *forall_tmp, tree body,
tree maskindex = forall_tmp->maskindex;
tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
maskindex, gfc_index_one_node);
- gfc_add_modify_expr (&block, maskindex, tmp);
+ gfc_add_modify (&block, maskindex, tmp);
}
/* Decrement the loop counter. */
tmp = fold_build2 (MINUS_EXPR, TREE_TYPE (var), count,
build_int_cst (TREE_TYPE (var), 1));
- gfc_add_modify_expr (&block, count, tmp);
+ gfc_add_modify (&block, count, tmp);
body = gfc_finish_block (&block);
/* Loop var initialization. */
gfc_init_block (&block);
- gfc_add_modify_expr (&block, var, start);
+ gfc_add_modify (&block, var, start);
/* Initialize the loop counter. */
tmp = fold_build2 (MINUS_EXPR, TREE_TYPE (var), step, start);
tmp = fold_build2 (PLUS_EXPR, TREE_TYPE (var), end, tmp);
tmp = fold_build2 (TRUNC_DIV_EXPR, TREE_TYPE (var), tmp, step);
- gfc_add_modify_expr (&block, count, tmp);
+ gfc_add_modify (&block, count, tmp);
/* The loop expression. */
tmp = build1_v (LOOP_EXPR, body);
@@ -1917,7 +1918,7 @@ gfc_do_allocate (tree bytesize, tree size, tree * pdata, stmtblock_t * pblock,
*pdata = convert (pvoid_type_node, tmpvar);
tmp = gfc_call_malloc (pblock, TREE_TYPE (tmpvar), bytesize);
- gfc_add_modify_expr (pblock, tmpvar, tmp);
+ gfc_add_modify (pblock, tmpvar, tmp);
}
return tmpvar;
}
@@ -1953,13 +1954,13 @@ generate_loop_for_temp_to_lhs (gfc_expr *expr, tree tmp1, tree count3,
/* Use the scalar assignment as is. */
gfc_add_block_to_block (&block, &lse.pre);
- gfc_add_modify_expr (&block, lse.expr, tmp);
+ gfc_add_modify (&block, lse.expr, tmp);
gfc_add_block_to_block (&block, &lse.post);
/* Increment the count1. */
tmp = fold_build2 (PLUS_EXPR, TREE_TYPE (count1), count1,
gfc_index_one_node);
- gfc_add_modify_expr (&block, count1, tmp);
+ gfc_add_modify (&block, count1, tmp);
tmp = gfc_finish_block (&block);
}
@@ -1977,7 +1978,7 @@ generate_loop_for_temp_to_lhs (gfc_expr *expr, tree tmp1, tree count3,
/* Calculate the bounds of the scalarization. */
gfc_conv_ss_startstride (&loop1);
/* Setup the scalarizing loops. */
- gfc_conv_loop_setup (&loop1);
+ gfc_conv_loop_setup (&loop1, &expr->where);
gfc_mark_ss_chain_used (lss, 1);
@@ -2015,14 +2016,14 @@ generate_loop_for_temp_to_lhs (gfc_expr *expr, tree tmp1, tree count3,
/* Increment count1. */
tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
count1, gfc_index_one_node);
- gfc_add_modify_expr (&body, count1, tmp);
+ gfc_add_modify (&body, count1, tmp);
/* Increment count3. */
if (count3)
{
tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
count3, gfc_index_one_node);
- gfc_add_modify_expr (&body, count3, tmp);
+ gfc_add_modify (&body, count3, tmp);
}
/* Generate the copying loops. */
@@ -2075,7 +2076,7 @@ generate_loop_for_rhs_to_temp (gfc_expr *expr2, tree tmp1, tree count3,
gfc_add_ss_to_loop (&loop, rss);
gfc_conv_ss_startstride (&loop);
- gfc_conv_loop_setup (&loop);
+ gfc_conv_loop_setup (&loop, &expr2->where);
gfc_mark_ss_chain_used (rss, 1);
/* Start the loop body. */
@@ -2116,21 +2117,21 @@ generate_loop_for_rhs_to_temp (gfc_expr *expr2, tree tmp1, tree count3,
/* Increment count1. */
tmp = fold_build2 (PLUS_EXPR, TREE_TYPE (count1), count1,
gfc_index_one_node);
- gfc_add_modify_expr (&block, count1, tmp);
+ gfc_add_modify (&block, count1, tmp);
}
else
{
/* Increment count1. */
tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
count1, gfc_index_one_node);
- gfc_add_modify_expr (&body1, count1, tmp);
+ gfc_add_modify (&body1, count1, tmp);
/* Increment count3. */
if (count3)
{
tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
count3, gfc_index_one_node);
- gfc_add_modify_expr (&body1, count3, tmp);
+ gfc_add_modify (&body1, count3, tmp);
}
/* Generate the copying loops. */
@@ -2197,7 +2198,7 @@ compute_inner_temp_size (gfc_expr *expr1, gfc_expr *expr2,
flag_bounds_check = 0;
gfc_conv_ss_startstride (&loop);
flag_bounds_check = save_flag;
- gfc_conv_loop_setup (&loop);
+ gfc_conv_loop_setup (&loop, &expr2->where);
/* Figure out how many elements we need. */
for (i = 0; i < loop.dimen; i++)
@@ -2256,7 +2257,7 @@ compute_overall_iter_number (forall_info *nested_forall_info, tree inner_size,
/* Otherwise, create a temporary variable to compute the result. */
number = gfc_create_var (gfc_array_index_type, "num");
- gfc_add_modify_expr (block, number, gfc_index_zero_node);
+ gfc_add_modify (block, number, gfc_index_zero_node);
gfc_start_block (&body);
if (inner_size_body)
@@ -2266,7 +2267,7 @@ compute_overall_iter_number (forall_info *nested_forall_info, tree inner_size,
number, inner_size);
else
tmp = inner_size;
- gfc_add_modify_expr (&body, number, tmp);
+ gfc_add_modify (&body, number, tmp);
tmp = gfc_finish_block (&body);
/* Generate loops. */
@@ -2377,13 +2378,13 @@ gfc_trans_assign_need_temp (gfc_expr * expr1, gfc_expr * expr2,
if (wheremask)
{
count = gfc_create_var (gfc_array_index_type, "count");
- gfc_add_modify_expr (block, count, gfc_index_zero_node);
+ gfc_add_modify (block, count, gfc_index_zero_node);
}
else
count = NULL;
/* Initialize count1. */
- gfc_add_modify_expr (block, count1, gfc_index_zero_node);
+ gfc_add_modify (block, count1, gfc_index_zero_node);
/* Calculate the size of temporary needed in the assignment. Return loop, lss
and rss which are used in function generate_loop_for_rhs_to_temp(). */
@@ -2422,11 +2423,11 @@ gfc_trans_assign_need_temp (gfc_expr * expr1, gfc_expr * expr2,
gfc_add_expr_to_block (block, tmp);
/* Reset count1. */
- gfc_add_modify_expr (block, count1, gfc_index_zero_node);
+ gfc_add_modify (block, count1, gfc_index_zero_node);
/* Reset count. */
if (wheremask)
- gfc_add_modify_expr (block, count, gfc_index_zero_node);
+ gfc_add_modify (block, count, gfc_index_zero_node);
/* Generate codes to copy the temporary to lhs. */
tmp = generate_loop_for_temp_to_lhs (expr1, tmp1, count, count1,
@@ -2468,7 +2469,7 @@ gfc_trans_pointer_assign_need_temp (gfc_expr * expr1, gfc_expr * expr2,
tree tmp, tmp1, ptemp1;
count = gfc_create_var (gfc_array_index_type, "count");
- gfc_add_modify_expr (block, count, gfc_index_zero_node);
+ gfc_add_modify (block, count, gfc_index_zero_node);
inner_size = integer_one_node;
lss = gfc_walk_expr (expr1);
@@ -2489,14 +2490,14 @@ gfc_trans_pointer_assign_need_temp (gfc_expr * expr1, gfc_expr * expr2,
rse.want_pointer = 1;
gfc_conv_expr (&rse, expr2);
gfc_add_block_to_block (&body, &rse.pre);
- gfc_add_modify_expr (&body, lse.expr,
+ gfc_add_modify (&body, lse.expr,
fold_convert (TREE_TYPE (lse.expr), rse.expr));
gfc_add_block_to_block (&body, &rse.post);
/* Increment count. */
tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
count, gfc_index_one_node);
- gfc_add_modify_expr (&body, count, tmp);
+ gfc_add_modify (&body, count, tmp);
tmp = gfc_finish_block (&body);
@@ -2506,7 +2507,7 @@ gfc_trans_pointer_assign_need_temp (gfc_expr * expr1, gfc_expr * expr2,
gfc_add_expr_to_block (block, tmp);
/* Reset count. */
- gfc_add_modify_expr (block, count, gfc_index_zero_node);
+ gfc_add_modify (block, count, gfc_index_zero_node);
gfc_start_block (&body);
gfc_init_se (&lse, NULL);
@@ -2515,12 +2516,12 @@ gfc_trans_pointer_assign_need_temp (gfc_expr * expr1, gfc_expr * expr2,
lse.want_pointer = 1;
gfc_conv_expr (&lse, expr1);
gfc_add_block_to_block (&body, &lse.pre);
- gfc_add_modify_expr (&body, lse.expr, rse.expr);
+ gfc_add_modify (&body, lse.expr, rse.expr);
gfc_add_block_to_block (&body, &lse.post);
/* Increment count. */
tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
count, gfc_index_one_node);
- gfc_add_modify_expr (&body, count, tmp);
+ gfc_add_modify (&body, count, tmp);
tmp = gfc_finish_block (&body);
/* Generate body and loops according to the information in
@@ -2538,7 +2539,7 @@ gfc_trans_pointer_assign_need_temp (gfc_expr * expr1, gfc_expr * expr2,
/* Setup the scalarizing loops and bounds. */
gfc_conv_ss_startstride (&loop);
- gfc_conv_loop_setup (&loop);
+ gfc_conv_loop_setup (&loop, &expr2->where);
info = &rss->data.info;
desc = info->descriptor;
@@ -2565,7 +2566,7 @@ gfc_trans_pointer_assign_need_temp (gfc_expr * expr1, gfc_expr * expr2,
/* Increment count. */
tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
count, gfc_index_one_node);
- gfc_add_modify_expr (&body, count, tmp);
+ gfc_add_modify (&body, count, tmp);
tmp = gfc_finish_block (&body);
@@ -2575,13 +2576,13 @@ gfc_trans_pointer_assign_need_temp (gfc_expr * expr1, gfc_expr * expr2,
gfc_add_expr_to_block (block, tmp);
/* Reset count. */
- gfc_add_modify_expr (block, count, gfc_index_zero_node);
+ gfc_add_modify (block, count, gfc_index_zero_node);
parm = gfc_build_array_ref (tmp1, count, NULL);
lss = gfc_walk_expr (expr1);
gfc_init_se (&lse, NULL);
gfc_conv_expr_descriptor (&lse, expr1, lss);
- gfc_add_modify_expr (&lse.pre, lse.expr, parm);
+ gfc_add_modify (&lse.pre, lse.expr, parm);
gfc_start_block (&body);
gfc_add_block_to_block (&body, &lse.pre);
gfc_add_block_to_block (&body, &lse.post);
@@ -2589,7 +2590,7 @@ gfc_trans_pointer_assign_need_temp (gfc_expr * expr1, gfc_expr * expr2,
/* Increment count. */
tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
count, gfc_index_one_node);
- gfc_add_modify_expr (&body, count, tmp);
+ gfc_add_modify (&body, count, tmp);
tmp = gfc_finish_block (&body);
@@ -2821,7 +2822,7 @@ gfc_trans_forall_1 (gfc_code * code, forall_info * nested_forall_info)
/* As the mask array can be very big, prefer compact boolean types. */
tree mask_type = gfc_get_logical_type (gfc_logical_kinds[0].kind);
- gfc_add_modify_expr (&block, maskindex, gfc_index_zero_node);
+ gfc_add_modify (&block, maskindex, gfc_index_zero_node);
/* Start of mask assignment loop body. */
gfc_start_block (&body);
@@ -2835,12 +2836,12 @@ gfc_trans_forall_1 (gfc_code * code, forall_info * nested_forall_info)
se.expr = convert (mask_type, se.expr);
tmp = gfc_build_array_ref (mask, maskindex, NULL);
- gfc_add_modify_expr (&body, tmp, se.expr);
+ gfc_add_modify (&body, tmp, se.expr);
/* Advance to the next mask element. */
tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
maskindex, gfc_index_one_node);
- gfc_add_modify_expr (&body, maskindex, tmp);
+ gfc_add_modify (&body, maskindex, tmp);
/* Generate the loops. */
tmp = gfc_finish_block (&body);
@@ -2998,7 +2999,7 @@ gfc_evaluate_where_mask (gfc_expr * me, forall_info * nested_forall_info,
/* Variable to index the temporary. */
count = gfc_create_var (gfc_array_index_type, "count");
/* Initialize count. */
- gfc_add_modify_expr (block, count, gfc_index_zero_node);
+ gfc_add_modify (block, count, gfc_index_zero_node);
gfc_start_block (&body);
@@ -3019,7 +3020,7 @@ gfc_evaluate_where_mask (gfc_expr * me, forall_info * nested_forall_info,
gfc_add_ss_to_loop (&loop, rss);
gfc_conv_ss_startstride (&loop);
- gfc_conv_loop_setup (&loop);
+ gfc_conv_loop_setup (&loop, &me->where);
gfc_mark_ss_chain_used (rss, 1);
/* Start the loop body. */
@@ -3040,14 +3041,14 @@ gfc_evaluate_where_mask (gfc_expr * me, forall_info * nested_forall_info,
gfc_add_block_to_block (&body1, &lse.pre);
gfc_add_block_to_block (&body1, &rse.pre);
- gfc_add_modify_expr (&body1, cond, fold_convert (mask_type, rse.expr));
+ gfc_add_modify (&body1, cond, fold_convert (mask_type, rse.expr));
if (mask && (cmask || pmask))
{
tmp = gfc_build_array_ref (mask, count, NULL);
if (invert)
tmp = fold_build1 (TRUTH_NOT_EXPR, mask_type, tmp);
- gfc_add_modify_expr (&body1, mtmp, tmp);
+ gfc_add_modify (&body1, mtmp, tmp);
}
if (cmask)
@@ -3056,7 +3057,7 @@ gfc_evaluate_where_mask (gfc_expr * me, forall_info * nested_forall_info,
tmp = cond;
if (mask)
tmp = fold_build2 (TRUTH_AND_EXPR, mask_type, mtmp, tmp);
- gfc_add_modify_expr (&body1, tmp1, tmp);
+ gfc_add_modify (&body1, tmp1, tmp);
}
if (pmask)
@@ -3065,7 +3066,7 @@ gfc_evaluate_where_mask (gfc_expr * me, forall_info * nested_forall_info,
tmp = fold_build1 (TRUTH_NOT_EXPR, mask_type, cond);
if (mask)
tmp = fold_build2 (TRUTH_AND_EXPR, mask_type, mtmp, tmp);
- gfc_add_modify_expr (&body1, tmp1, tmp);
+ gfc_add_modify (&body1, tmp1, tmp);
}
gfc_add_block_to_block (&body1, &lse.post);
@@ -3080,7 +3081,7 @@ gfc_evaluate_where_mask (gfc_expr * me, forall_info * nested_forall_info,
/* Increment count. */
tmp1 = fold_build2 (PLUS_EXPR, gfc_array_index_type, count,
gfc_index_one_node);
- gfc_add_modify_expr (&body1, count, tmp1);
+ gfc_add_modify (&body1, count, tmp1);
/* Generate the copying loops. */
gfc_trans_scalarizing_loops (&loop, &body1);
@@ -3186,7 +3187,7 @@ gfc_trans_where_assign (gfc_expr *expr1, gfc_expr *expr2,
gfc_conv_resolve_dependencies (&loop, lss_section, rss);
/* Setup the scalarizing loops. */
- gfc_conv_loop_setup (&loop);
+ gfc_conv_loop_setup (&loop, &expr2->where);
/* Setup the gfc_se structures. */
gfc_copy_loopinfo_to_se (&lse, &loop);
@@ -3241,7 +3242,7 @@ gfc_trans_where_assign (gfc_expr *expr1, gfc_expr *expr2,
/* Increment count1. */
tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
count1, gfc_index_one_node);
- gfc_add_modify_expr (&body, count1, tmp);
+ gfc_add_modify (&body, count1, tmp);
/* Use the scalar assignment as is. */
gfc_add_block_to_block (&block, &body);
@@ -3257,7 +3258,7 @@ gfc_trans_where_assign (gfc_expr *expr1, gfc_expr *expr2,
expression. */
tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
count1, gfc_index_one_node);
- gfc_add_modify_expr (&body, count1, tmp);
+ gfc_add_modify (&body, count1, tmp);
gfc_trans_scalarized_loop_boundary (&loop, &body);
/* We need to copy the temporary to the actual lhs. */
@@ -3291,14 +3292,14 @@ gfc_trans_where_assign (gfc_expr *expr1, gfc_expr *expr2,
/* Increment count2. */
tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
count2, gfc_index_one_node);
- gfc_add_modify_expr (&body, count2, tmp);
+ gfc_add_modify (&body, count2, tmp);
}
else
{
/* Increment count1. */
tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
count1, gfc_index_one_node);
- gfc_add_modify_expr (&body, count1, tmp);
+ gfc_add_modify (&body, count1, tmp);
}
/* Generate the copying loops. */
@@ -3491,8 +3492,8 @@ gfc_trans_where_2 (gfc_code * code, tree mask, bool invert,
/* Variables to control maskexpr. */
count1 = gfc_create_var (gfc_array_index_type, "count1");
count2 = gfc_create_var (gfc_array_index_type, "count2");
- gfc_add_modify_expr (block, count1, gfc_index_zero_node);
- gfc_add_modify_expr (block, count2, gfc_index_zero_node);
+ gfc_add_modify (block, count1, gfc_index_zero_node);
+ gfc_add_modify (block, count2, gfc_index_zero_node);
tmp = gfc_trans_where_assign (expr1, expr2,
cmask, invert,
@@ -3509,8 +3510,8 @@ gfc_trans_where_2 (gfc_code * code, tree mask, bool invert,
/* Variables to control maskexpr. */
count1 = gfc_create_var (gfc_array_index_type, "count1");
count2 = gfc_create_var (gfc_array_index_type, "count2");
- gfc_add_modify_expr (block, count1, gfc_index_zero_node);
- gfc_add_modify_expr (block, count2, gfc_index_zero_node);
+ gfc_add_modify (block, count1, gfc_index_zero_node);
+ gfc_add_modify (block, count2, gfc_index_zero_node);
tmp = gfc_trans_where_assign (expr1, expr2,
cmask, invert,
@@ -3634,7 +3635,7 @@ gfc_trans_where_3 (gfc_code * cblock, gfc_code * eblock)
}
gfc_conv_ss_startstride (&loop);
- gfc_conv_loop_setup (&loop);
+ gfc_conv_loop_setup (&loop, &tdst->where);
gfc_mark_ss_chain_used (css, 1);
gfc_mark_ss_chain_used (tdss, 1);
@@ -3892,7 +3893,7 @@ gfc_trans_allocate (gfc_code * code)
gfc_init_se (&se, NULL);
gfc_conv_expr_lhs (&se, code->expr);
tmp = convert (TREE_TYPE (se.expr), stat);
- gfc_add_modify_expr (&block, se.expr, tmp);
+ gfc_add_modify (&block, se.expr, tmp);
}
return gfc_finish_block (&block);
@@ -3941,7 +3942,7 @@ gfc_trans_deallocate (gfc_code * code)
apstat = build_fold_addr_expr (astat);
/* Initialize astat to 0. */
- gfc_add_modify_expr (&block, astat, build_int_cst (TREE_TYPE (astat), 0));
+ gfc_add_modify (&block, astat, build_int_cst (TREE_TYPE (astat), 0));
}
else
pstat = apstat = stat = astat = NULL_TREE;
@@ -3996,7 +3997,7 @@ gfc_trans_deallocate (gfc_code * code)
if (code->expr)
{
apstat = fold_build2 (PLUS_EXPR, TREE_TYPE (stat), astat, stat);
- gfc_add_modify_expr (&se.pre, astat, apstat);
+ gfc_add_modify (&se.pre, astat, apstat);
}
tmp = gfc_finish_block (&se.pre);
@@ -4010,7 +4011,7 @@ gfc_trans_deallocate (gfc_code * code)
gfc_init_se (&se, NULL);
gfc_conv_expr_lhs (&se, code->expr);
tmp = convert (TREE_TYPE (se.expr), astat);
- gfc_add_modify_expr (&block, se.expr, tmp);
+ gfc_add_modify (&block, se.expr, tmp);
}
return gfc_finish_block (&block);
diff --git a/gcc/fortran/trans-types.c b/gcc/fortran/trans-types.c
index fa1bf248aec..2928cc68bf2 100644
--- a/gcc/fortran/trans-types.c
+++ b/gcc/fortran/trans-types.c
@@ -361,7 +361,7 @@ gfc_init_kinds (void)
if (kind == 16)
saw_r16 = true;
- /* Careful we don't stumble a wierd internal mode. */
+ /* Careful we don't stumble a weird internal mode. */
gcc_assert (r_index <= 0 || gfc_real_kinds[r_index-1].kind != kind);
/* Or have too many modes for the allocated space. */
gcc_assert (r_index != MAX_REAL_KINDS);
@@ -393,7 +393,7 @@ gfc_init_kinds (void)
gfc_default_integer_kind = 8;
/* Even if the user specified that the default integer kind be 8,
- the numerica storage size isn't 64. In this case, a warning will
+ the numeric storage size isn't 64. In this case, a warning will
be issued when NUMERIC_STORAGE_SIZE is used. */
gfc_numeric_storage_size = 4 * 8;
}
@@ -1065,8 +1065,8 @@ gfc_get_element_type (tree type)
ARRAYS comment.
The data component points to the first element in the array. The
- offset field is the position of the origin of the array (ie element
- (0, 0 ...)). This may be outsite the bounds of the array.
+ offset field is the position of the origin of the array (i.e. element
+ (0, 0 ...)). This may be outside the bounds of the array.
An element is accessed by
data[offset + index0*stride0 + index1*stride1 + index2*stride2]
@@ -1078,7 +1078,7 @@ gfc_get_element_type (tree type)
elements of the origin (2^63 on 64-bit machines). For example
integer, dimension (80000:90000, 80000:90000, 2) :: array
may not work properly on 32-bit machines because 80000*80000 >
- 2^31, so the calculation for stride02 would overflow. This may
+ 2^31, so the calculation for stride2 would overflow. This may
still work, but I haven't checked, and it relies on the overflow
doing the right thing.
@@ -1513,7 +1513,7 @@ gfc_get_array_type_bounds (tree etype, int dimen, tree * lbound,
{
char name[8 + GFC_RANK_DIGITS + GFC_MAX_SYMBOL_LEN];
tree fat_type, base_type, arraytype, lower, upper, stride, tmp, rtype;
- const char *typename;
+ const char *type_name;
int n;
base_type = gfc_get_array_descriptor_base (dimen);
@@ -1523,11 +1523,11 @@ gfc_get_array_type_bounds (tree etype, int dimen, tree * lbound,
if (tmp && TREE_CODE (tmp) == TYPE_DECL)
tmp = DECL_NAME (tmp);
if (tmp)
- typename = IDENTIFIER_POINTER (tmp);
+ type_name = IDENTIFIER_POINTER (tmp);
else
- typename = "unknown";
+ type_name = "unknown";
sprintf (name, "array" GFC_RANK_PRINTF_FORMAT "_%.*s", dimen,
- GFC_MAX_SYMBOL_LEN, typename);
+ GFC_MAX_SYMBOL_LEN, type_name);
TYPE_NAME (fat_type) = get_identifier (name);
GFC_DESCRIPTOR_TYPE_P (fat_type) = 1;
@@ -2163,7 +2163,7 @@ gfc_type_for_size (unsigned bits, int unsignedp)
}
/* Handle TImode as a special case because it is used by some backends
- (eg. ARM) even though it is not available for normal use. */
+ (e.g. ARM) even though it is not available for normal use. */
#if HOST_BITS_PER_WIDE_INT >= 64
if (bits == TYPE_PRECISION (intTI_type_node))
return intTI_type_node;
diff --git a/gcc/fortran/trans.c b/gcc/fortran/trans.c
index 5bd3005a2b3..911e379001a 100644
--- a/gcc/fortran/trans.c
+++ b/gcc/fortran/trans.c
@@ -23,7 +23,8 @@ along with GCC; see the file COPYING3. If not see
#include "system.h"
#include "coretypes.h"
#include "tree.h"
-#include "tree-gimple.h"
+#include "gimple.h"
+#include "tree-iterator.h"
#include "ggc.h"
#include "toplev.h"
#include "defaults.h"
@@ -129,7 +130,7 @@ gfc_create_var (tree type, const char *prefix)
}
-/* If the an expression is not constant, evaluate it now. We assign the
+/* If the expression is not constant, evaluate it now. We assign the
result of the expression to an artificially created variable VAR, and
return a pointer to the VAR_DECL node for this variable. */
@@ -142,19 +143,18 @@ gfc_evaluate_now (tree expr, stmtblock_t * pblock)
return expr;
var = gfc_create_var (TREE_TYPE (expr), NULL);
- gfc_add_modify_expr (pblock, var, expr);
+ gfc_add_modify (pblock, var, expr);
return var;
}
-/* Build a MODIFY_EXPR (or GIMPLE_MODIFY_STMT) node and add it to a
- given statement block PBLOCK. A MODIFY_EXPR is an assignment:
+/* Build a MODIFY_EXPR node and add it to a given statement block PBLOCK.
+ A MODIFY_EXPR is an assignment:
LHS <- RHS. */
void
-gfc_add_modify (stmtblock_t * pblock, tree lhs, tree rhs,
- bool tuples_p)
+gfc_add_modify (stmtblock_t * pblock, tree lhs, tree rhs)
{
tree tmp;
@@ -167,8 +167,7 @@ gfc_add_modify (stmtblock_t * pblock, tree lhs, tree rhs,
|| AGGREGATE_TYPE_P (TREE_TYPE (lhs)));
#endif
- tmp = fold_build2 (tuples_p ? GIMPLE_MODIFY_STMT : MODIFY_EXPR,
- void_type_node, lhs, rhs);
+ tmp = fold_build2 (MODIFY_EXPR, void_type_node, lhs, rhs);
gfc_add_expr_to_block (pblock, tmp);
}
@@ -351,13 +350,14 @@ gfc_build_array_ref (tree base, tree offset, tree decl)
/* Generate a runtime error if COND is true. */
void
-gfc_trans_runtime_check (tree cond, stmtblock_t * pblock, locus * where,
- const char * msgid, ...)
+gfc_trans_runtime_check (bool error, bool once, tree cond, stmtblock_t * pblock,
+ locus * where, const char * msgid, ...)
{
va_list ap;
stmtblock_t block;
tree body;
tree tmp;
+ tree tmpvar = NULL;
tree arg, arg2;
tree *argarray;
tree fntype;
@@ -377,6 +377,14 @@ gfc_trans_runtime_check (tree cond, stmtblock_t * pblock, locus * where,
nargs++;
}
+ if (once)
+ {
+ tmpvar = gfc_create_var (boolean_type_node, "print_warning");
+ TREE_STATIC (tmpvar) = 1;
+ DECL_INITIAL (tmpvar) = boolean_true_node;
+ gfc_add_expr_to_block (pblock, tmpvar);
+ }
+
/* The code to generate the error. */
gfc_start_block (&block);
@@ -408,16 +416,25 @@ gfc_trans_runtime_check (tree cond, stmtblock_t * pblock, locus * where,
argarray[2+i] = va_arg (ap, tree);
va_end (ap);
- /* Build the function call to runtime_error_at; because of the variable
- number of arguments, we can't use build_call_expr directly. */
- fntype = TREE_TYPE (gfor_fndecl_runtime_error_at);
+ /* Build the function call to runtime_(warning,error)_at; because of the
+ variable number of arguments, we can't use build_call_expr directly. */
+ if (error)
+ fntype = TREE_TYPE (gfor_fndecl_runtime_error_at);
+ else
+ fntype = TREE_TYPE (gfor_fndecl_runtime_warning_at);
+
tmp = fold_builtin_call_array (TREE_TYPE (fntype),
fold_build1 (ADDR_EXPR,
build_pointer_type (fntype),
- gfor_fndecl_runtime_error_at),
+ error
+ ? gfor_fndecl_runtime_error_at
+ : gfor_fndecl_runtime_warning_at),
nargs + 2, argarray);
gfc_add_expr_to_block (&block, tmp);
+ if (once)
+ gfc_add_modify (&block, tmpvar, boolean_false_node);
+
body = gfc_finish_block (&block);
if (integer_onep (cond))
@@ -427,7 +444,12 @@ gfc_trans_runtime_check (tree cond, stmtblock_t * pblock, locus * where,
else
{
/* Tell the compiler that this isn't likely. */
- cond = fold_convert (long_integer_type_node, cond);
+ if (once)
+ cond = fold_build2 (TRUTH_AND_EXPR, long_integer_type_node, tmpvar,
+ cond);
+ else
+ cond = fold_convert (long_integer_type_node, cond);
+
tmp = build_int_cst (long_integer_type_node, 0);
cond = build_call_expr (built_in_decls[BUILT_IN_EXPECT], 2, cond, tmp);
cond = fold_convert (boolean_type_node, cond);
@@ -472,7 +494,7 @@ gfc_call_malloc (stmtblock_t * block, tree type, tree size)
size = fold_build2 (MAX_EXPR, size_type_node, size,
build_int_cst (size_type_node, 1));
- gfc_add_modify_expr (&block2, res,
+ gfc_add_modify (&block2, res,
build_call_expr (built_in_decls[BUILT_IN_MALLOC], 1,
size));
null_result = fold_build2 (EQ_EXPR, boolean_type_node, res,
@@ -570,10 +592,10 @@ gfc_allocate_with_status (stmtblock_t * block, tree size, tree status)
stmtblock_t set_status_block;
gfc_start_block (&set_status_block);
- gfc_add_modify_expr (&set_status_block,
+ gfc_add_modify (&set_status_block,
fold_build1 (INDIRECT_REF, status_type, status),
build_int_cst (status_type, LIBERROR_ALLOCATION));
- gfc_add_modify_expr (&set_status_block, res,
+ gfc_add_modify (&set_status_block, res,
build_int_cst (pvoid_type_node, 0));
tmp = fold_build2 (EQ_EXPR, boolean_type_node, status,
@@ -584,7 +606,7 @@ gfc_allocate_with_status (stmtblock_t * block, tree size, tree status)
/* The allocation itself. */
gfc_start_block (&alloc_block);
- gfc_add_modify_expr (&alloc_block, res,
+ gfc_add_modify (&alloc_block, res,
build_call_expr (built_in_decls[BUILT_IN_MALLOC], 1,
fold_build2 (MAX_EXPR, size_type_node,
size,
@@ -666,7 +688,7 @@ gfc_allocate_array_with_status (stmtblock_t * block, tree mem, tree size,
/* If mem is NULL, we call gfc_allocate_with_status. */
gfc_start_block (&alloc_block);
tmp = gfc_allocate_with_status (&alloc_block, size, status);
- gfc_add_modify_expr (&alloc_block, res, fold_convert (type, tmp));
+ gfc_add_modify (&alloc_block, res, fold_convert (type, tmp));
alloc = gfc_finish_block (&alloc_block);
/* Otherwise, we issue a runtime error or set the status variable. */
@@ -685,9 +707,9 @@ gfc_allocate_array_with_status (stmtblock_t * block, tree mem, tree size,
gfc_add_expr_to_block (&set_status_block, tmp);
tmp = gfc_allocate_with_status (&set_status_block, size, status);
- gfc_add_modify_expr (&set_status_block, res, fold_convert (type, tmp));
+ gfc_add_modify (&set_status_block, res, fold_convert (type, tmp));
- gfc_add_modify_expr (&set_status_block,
+ gfc_add_modify (&set_status_block,
fold_build1 (INDIRECT_REF, status_type, status),
build_int_cst (status_type, LIBERROR_ALLOCATION));
@@ -862,7 +884,7 @@ gfc_call_realloc (stmtblock_t * block, tree mem, tree size)
/* Call realloc and check the result. */
tmp = build_call_expr (built_in_decls[BUILT_IN_REALLOC], 2,
fold_convert (pvoid_type_node, mem), size);
- gfc_add_modify_expr (block, res, fold_convert (type, tmp));
+ gfc_add_modify (block, res, fold_convert (type, tmp));
null_result = fold_build2 (EQ_EXPR, boolean_type_node, res,
build_int_cst (pvoid_type_node, 0));
nonzero = fold_build2 (NE_EXPR, boolean_type_node, size,
@@ -962,7 +984,7 @@ gfc_trans_code (gfc_code * code)
gfc_start_block (&block);
- /* Translate statements one by one to GIMPLE trees until we reach
+ /* Translate statements one by one into GENERIC trees until we reach
the end of this gfc_code branch. */
for (; code; code = code->next)
{
@@ -1150,7 +1172,7 @@ gfc_trans_code (gfc_code * code)
if (res != NULL_TREE && ! IS_EMPTY_STMT (res))
{
if (TREE_CODE (res) == STATEMENT_LIST)
- annotate_all_with_locus (&res, input_location);
+ tree_annotate_all_with_location (&res, input_location);
else
SET_EXPR_LOCATION (res, input_location);
diff --git a/gcc/fortran/trans.h b/gcc/fortran/trans.h
index 81c449e91a5..6e09f24ac95 100644
--- a/gcc/fortran/trans.h
+++ b/gcc/fortran/trans.h
@@ -1,5 +1,5 @@
/* Header for code translation functions
- Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 Free Software
+ Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software
Foundation, Inc.
Contributed by Paul Brook
@@ -137,7 +137,7 @@ typedef enum
/* A non-elemental function call returning an array. The call is executed
before entering the scalarization loop, storing the result in a
temporary. This temporary is then used inside the scalarization loop.
- Simple assignments, eg. a(:) = fn() are handles without a temporary
+ Simple assignments, e.g. a(:) = fn(), are handled without a temporary
as a special case. */
GFC_SS_FUNCTION,
@@ -348,12 +348,8 @@ void gfc_trans_vla_type_sizes (gfc_symbol *, stmtblock_t *);
void gfc_add_expr_to_block (stmtblock_t *, tree);
/* Add a block to the end of a block. */
void gfc_add_block_to_block (stmtblock_t *, stmtblock_t *);
-/* Add a MODIFY_EXPR or a GIMPLE_MODIFY_STMT to a block. */
-void gfc_add_modify (stmtblock_t *, tree, tree, bool);
-#define gfc_add_modify_expr(BLOCK, LHS, RHS) \
- gfc_add_modify ((BLOCK), (LHS), (RHS), false)
-#define gfc_add_modify_stmt(BLOCK, LHS, RHS) \
- gfc_add_modify ((BLOCK), (LHS), (RHS), true)
+/* Add a MODIFY_EXPR to a block. */
+void gfc_add_modify (stmtblock_t *, tree, tree);
/* Initialize a statement block. */
void gfc_init_block (stmtblock_t *);
@@ -444,8 +440,9 @@ void gfc_generate_constructors (void);
/* Get the string length of an array constructor. */
bool get_array_ctor_strlen (stmtblock_t *, gfc_constructor *, tree *);
-/* Generate a runtime error check. */
-void gfc_trans_runtime_check (tree, stmtblock_t *, locus *, const char *, ...);
+/* Generate a runtime warning/error check. */
+void gfc_trans_runtime_check (bool, bool, tree, stmtblock_t *, locus *,
+ const char *, ...);
/* Generate a call to free() after checking that its arg is non-NULL. */
tree gfc_call_free (tree);
@@ -510,6 +507,7 @@ extern GTY(()) tree gfor_fndecl_stop_numeric;
extern GTY(()) tree gfor_fndecl_stop_string;
extern GTY(()) tree gfor_fndecl_runtime_error;
extern GTY(()) tree gfor_fndecl_runtime_error_at;
+extern GTY(()) tree gfor_fndecl_runtime_warning_at;
extern GTY(()) tree gfor_fndecl_os_error;
extern GTY(()) tree gfor_fndecl_generate_error;
extern GTY(()) tree gfor_fndecl_set_fpe;
@@ -654,7 +652,7 @@ struct lang_decl GTY(())
#define GFC_TYPE_ARRAY_SIZE(node) (TYPE_LANG_SPECIFIC(node)->size)
#define GFC_TYPE_ARRAY_OFFSET(node) (TYPE_LANG_SPECIFIC(node)->offset)
#define GFC_TYPE_ARRAY_AKIND(node) (TYPE_LANG_SPECIFIC(node)->akind)
-/* Code should use gfc_get_dtype instead of accesing this directly. It may
+/* Code should use gfc_get_dtype instead of accessing this directly. It may
not be known when the type is created. */
#define GFC_TYPE_ARRAY_DTYPE(node) (TYPE_LANG_SPECIFIC(node)->dtype)
#define GFC_TYPE_ARRAY_DATAPTR_TYPE(node) \
@@ -710,7 +708,7 @@ typedef struct gfc_interface_sym_mapping
{
struct gfc_interface_sym_mapping *next;
gfc_symbol *old;
- gfc_symtree *new;
+ gfc_symtree *new_sym;
gfc_expr *expr;
}
gfc_interface_sym_mapping;
diff --git a/gcc/function.c b/gcc/function.c
index d8234da3877..532a94f34c4 100644
--- a/gcc/function.c
+++ b/gcc/function.c
@@ -59,7 +59,7 @@ along with GCC; see the file COPYING3. If not see
#include "langhooks.h"
#include "target.h"
#include "cfglayout.h"
-#include "tree-gimple.h"
+#include "gimple.h"
#include "tree-pass.h"
#include "predict.h"
#include "df.h"
@@ -1547,7 +1547,7 @@ static tree
instantiate_expr (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
{
tree t = *tp;
- if (! EXPR_P (t) && ! GIMPLE_STMT_P (t))
+ if (! EXPR_P (t))
{
*walk_subtrees = 0;
if (DECL_P (t) && DECL_RTL_SET_P (t))
@@ -2364,8 +2364,7 @@ assign_parm_remove_parallels (struct assign_parm_data_one *data)
This can be done with register operations rather than on the
stack, even if we will store the reconstituted parameter on the
stack later. */
- if (GET_CODE (entry_parm) == PARALLEL
- && data->passed_mode != BLKmode)
+ if (GET_CODE (entry_parm) == PARALLEL && GET_MODE (entry_parm) != BLKmode)
{
rtx parmreg = gen_reg_rtx (GET_MODE (entry_parm));
emit_group_store (parmreg, entry_parm, NULL_TREE,
@@ -2421,6 +2420,8 @@ assign_parm_setup_block_p (struct assign_parm_data_one *data)
{
if (data->nominal_mode == BLKmode)
return true;
+ if (GET_MODE (data->entry_parm) == BLKmode)
+ return true;
#ifdef BLOCK_REG_PADDING
/* Only assign_parm_setup_block knows how to deal with register arguments
@@ -3091,7 +3092,7 @@ gimplify_parm_type (tree *tp, int *walk_subtrees, void *data)
else if (TYPE_SIZE (t) && !TREE_CONSTANT (TYPE_SIZE (t))
&& !TYPE_SIZES_GIMPLIFIED (t))
{
- gimplify_type_sizes (t, (tree *) data);
+ gimplify_type_sizes (t, (gimple_seq *) data);
*walk_subtrees = 1;
}
}
@@ -3101,15 +3102,15 @@ gimplify_parm_type (tree *tp, int *walk_subtrees, void *data)
/* Gimplify the parameter list for current_function_decl. This involves
evaluating SAVE_EXPRs of variable sized parameters and generating code
- to implement callee-copies reference parameters. Returns a list of
- statements to add to the beginning of the function, or NULL if nothing
- to do. */
+ to implement callee-copies reference parameters. Returns a sequence of
+ statements to add to the beginning of the function. */
-tree
+gimple_seq
gimplify_parameters (void)
{
struct assign_parm_data_all all;
- tree fnargs, parm, stmts = NULL;
+ tree fnargs, parm;
+ gimple_seq stmts = NULL;
assign_parms_initialize_all (&all);
fnargs = assign_parms_augmented_arg_list (&all);
@@ -3169,12 +3170,11 @@ gimplify_parameters (void)
t = built_in_decls[BUILT_IN_ALLOCA];
t = build_call_expr (t, 1, DECL_SIZE_UNIT (parm));
t = fold_convert (ptr_type, t);
- t = build_gimple_modify_stmt (addr, t);
+ t = build2 (MODIFY_EXPR, TREE_TYPE (addr), addr, t);
gimplify_and_add (t, &stmts);
}
- t = build_gimple_modify_stmt (local, parm);
- gimplify_and_add (t, &stmts);
+ gimplify_assign (local, parm, &stmts);
SET_DECL_VALUE_EXPR (parm, local);
DECL_HAS_VALUE_EXPR_P (parm) = 1;
@@ -3257,13 +3257,13 @@ locate_and_pad_parm (enum machine_mode passed_mode, tree type, int in_regs,
= type ? size_in_bytes (type) : size_int (GET_MODE_SIZE (passed_mode));
where_pad = FUNCTION_ARG_PADDING (passed_mode, type);
boundary = FUNCTION_ARG_BOUNDARY (passed_mode, type);
+ if (boundary > PREFERRED_STACK_BOUNDARY)
+ boundary = PREFERRED_STACK_BOUNDARY;
locate->where_pad = where_pad;
locate->boundary = boundary;
/* Remember if the outgoing parameter requires extra alignment on the
calling function side. */
- if (boundary > PREFERRED_STACK_BOUNDARY)
- boundary = PREFERRED_STACK_BOUNDARY;
if (crtl->stack_alignment_needed < boundary)
crtl->stack_alignment_needed = boundary;
@@ -3730,13 +3730,30 @@ debug_find_var_in_block_tree (tree var, tree block)
static bool in_dummy_function;
-/* Invoke the target hook when setting cfun. */
+/* Invoke the target hook when setting cfun. Update the optimization options
+ if the function uses different options than the default. */
static void
invoke_set_current_function_hook (tree fndecl)
{
if (!in_dummy_function)
- targetm.set_current_function (fndecl);
+ {
+ tree opts = ((fndecl)
+ ? DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl)
+ : optimization_default_node);
+
+ if (!opts)
+ opts = optimization_default_node;
+
+ /* Change optimization options if needed. */
+ if (optimization_current_node != opts)
+ {
+ optimization_current_node = opts;
+ cl_optimization_restore (TREE_OPTIMIZATION (opts));
+ }
+
+ targetm.set_current_function (fndecl);
+ }
}
/* cfun should never be set directly; use this function. */
@@ -3762,22 +3779,12 @@ DEF_VEC_ALLOC_P(function_p,heap);
static VEC(function_p,heap) *cfun_stack;
-/* We save the value of in_system_header here when pushing the first
- function on the cfun stack, and we restore it from here when
- popping the last function. */
-
-static bool saved_in_system_header;
-
/* Push the current cfun onto the stack, and set cfun to new_cfun. */
void
push_cfun (struct function *new_cfun)
{
- if (cfun == NULL)
- saved_in_system_header = in_system_header;
VEC_safe_push (function_p, heap, cfun_stack, cfun);
- if (new_cfun)
- in_system_header = DECL_IN_SYSTEM_HEADER (new_cfun->decl);
set_cfun (new_cfun);
}
@@ -3787,8 +3794,6 @@ void
pop_cfun (void)
{
struct function *new_cfun = VEC_pop (function_p, cfun_stack);
- in_system_header = ((new_cfun == NULL) ? saved_in_system_header
- : DECL_IN_SYSTEM_HEADER (new_cfun->decl));
set_cfun (new_cfun);
}
@@ -3866,11 +3871,7 @@ allocate_struct_function (tree fndecl, bool abstract_p)
void
push_struct_function (tree fndecl)
{
- if (cfun == NULL)
- saved_in_system_header = in_system_header;
VEC_safe_push (function_p, heap, cfun_stack, cfun);
- if (fndecl)
- in_system_header = DECL_IN_SYSTEM_HEADER (fndecl);
allocate_struct_function (fndecl, false);
}
diff --git a/gcc/function.h b/gcc/function.h
index ece44fdc7ac..9de018100d9 100644
--- a/gcc/function.h
+++ b/gcc/function.h
@@ -428,6 +428,10 @@ struct function GTY(())
/* The control flow graph for this function. */
struct control_flow_graph *cfg;
+
+ /* GIMPLE body for this function. */
+ struct gimple_seq_d *gimple_body;
+
/* SSA and dataflow information. */
struct gimple_df *gimple_df;
diff --git a/gcc/fwprop.c b/gcc/fwprop.c
index 6456b0eae02..fbe432974f4 100644
--- a/gcc/fwprop.c
+++ b/gcc/fwprop.c
@@ -184,26 +184,26 @@ canonicalize_address (rtx x)
for a memory access in the given MODE. */
static bool
-should_replace_address (rtx old, rtx new, enum machine_mode mode)
+should_replace_address (rtx old_rtx, rtx new_rtx, enum machine_mode mode)
{
int gain;
- if (rtx_equal_p (old, new) || !memory_address_p (mode, new))
+ if (rtx_equal_p (old_rtx, new_rtx) || !memory_address_p (mode, new_rtx))
return false;
/* Copy propagation is always ok. */
- if (REG_P (old) && REG_P (new))
+ if (REG_P (old_rtx) && REG_P (new_rtx))
return true;
/* Prefer the new address if it is less expensive. */
- gain = address_cost (old, mode) - address_cost (new, mode);
+ gain = address_cost (old_rtx, mode) - address_cost (new_rtx, mode);
/* If the addresses have equivalent cost, prefer the new address
if it has the highest `rtx_cost'. That has the potential of
eliminating the most insns without additional costs, and it
is the same that cse.c used to do. */
if (gain == 0)
- gain = rtx_cost (new, SET) - rtx_cost (old, SET);
+ gain = rtx_cost (new_rtx, SET) - rtx_cost (old_rtx, SET);
return (gain > 0);
}
@@ -244,7 +244,7 @@ enum {
that is because there is no simplify_gen_* function for LO_SUM). */
static bool
-propagate_rtx_1 (rtx *px, rtx old, rtx new, int flags)
+propagate_rtx_1 (rtx *px, rtx old_rtx, rtx new_rtx, int flags)
{
rtx x = *px, tem = NULL_RTX, op0, op1, op2;
enum rtx_code code = GET_CODE (x);
@@ -265,9 +265,9 @@ propagate_rtx_1 (rtx *px, rtx old, rtx new, int flags)
/* If X is OLD_RTX, return NEW_RTX. But not if replacing only within an
address, and we are *not* inside one. */
- if (x == old)
+ if (x == old_rtx)
{
- *px = new;
+ *px = new_rtx;
return can_appear;
}
@@ -277,7 +277,7 @@ propagate_rtx_1 (rtx *px, rtx old, rtx new, int flags)
case RTX_UNARY:
op0 = XEXP (x, 0);
op_mode = GET_MODE (op0);
- valid_ops &= propagate_rtx_1 (&op0, old, new, flags);
+ valid_ops &= propagate_rtx_1 (&op0, old_rtx, new_rtx, flags);
if (op0 == XEXP (x, 0))
return true;
tem = simplify_gen_unary (code, mode, op0, op_mode);
@@ -287,8 +287,8 @@ propagate_rtx_1 (rtx *px, rtx old, rtx new, int flags)
case RTX_COMM_ARITH:
op0 = XEXP (x, 0);
op1 = XEXP (x, 1);
- valid_ops &= propagate_rtx_1 (&op0, old, new, flags);
- valid_ops &= propagate_rtx_1 (&op1, old, new, flags);
+ valid_ops &= propagate_rtx_1 (&op0, old_rtx, new_rtx, flags);
+ valid_ops &= propagate_rtx_1 (&op1, old_rtx, new_rtx, flags);
if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1))
return true;
tem = simplify_gen_binary (code, mode, op0, op1);
@@ -299,8 +299,8 @@ propagate_rtx_1 (rtx *px, rtx old, rtx new, int flags)
op0 = XEXP (x, 0);
op1 = XEXP (x, 1);
op_mode = GET_MODE (op0) != VOIDmode ? GET_MODE (op0) : GET_MODE (op1);
- valid_ops &= propagate_rtx_1 (&op0, old, new, flags);
- valid_ops &= propagate_rtx_1 (&op1, old, new, flags);
+ valid_ops &= propagate_rtx_1 (&op0, old_rtx, new_rtx, flags);
+ valid_ops &= propagate_rtx_1 (&op1, old_rtx, new_rtx, flags);
if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1))
return true;
tem = simplify_gen_relational (code, mode, op_mode, op0, op1);
@@ -312,9 +312,9 @@ propagate_rtx_1 (rtx *px, rtx old, rtx new, int flags)
op1 = XEXP (x, 1);
op2 = XEXP (x, 2);
op_mode = GET_MODE (op0);
- valid_ops &= propagate_rtx_1 (&op0, old, new, flags);
- valid_ops &= propagate_rtx_1 (&op1, old, new, flags);
- valid_ops &= propagate_rtx_1 (&op2, old, new, flags);
+ valid_ops &= propagate_rtx_1 (&op0, old_rtx, new_rtx, flags);
+ valid_ops &= propagate_rtx_1 (&op1, old_rtx, new_rtx, flags);
+ valid_ops &= propagate_rtx_1 (&op2, old_rtx, new_rtx, flags);
if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1) && op2 == XEXP (x, 2))
return true;
if (op_mode == VOIDmode)
@@ -327,7 +327,7 @@ propagate_rtx_1 (rtx *px, rtx old, rtx new, int flags)
if (code == SUBREG)
{
op0 = XEXP (x, 0);
- valid_ops &= propagate_rtx_1 (&op0, old, new, flags);
+ valid_ops &= propagate_rtx_1 (&op0, old_rtx, new_rtx, flags);
if (op0 == XEXP (x, 0))
return true;
tem = simplify_gen_subreg (mode, op0, GET_MODE (SUBREG_REG (x)),
@@ -336,7 +336,7 @@ propagate_rtx_1 (rtx *px, rtx old, rtx new, int flags)
break;
case RTX_OBJ:
- if (code == MEM && x != new)
+ if (code == MEM && x != new_rtx)
{
rtx new_op0;
op0 = XEXP (x, 0);
@@ -346,7 +346,7 @@ propagate_rtx_1 (rtx *px, rtx old, rtx new, int flags)
return true;
op0 = new_op0 = targetm.delegitimize_address (op0);
- valid_ops &= propagate_rtx_1 (&new_op0, old, new,
+ valid_ops &= propagate_rtx_1 (&new_op0, old_rtx, new_rtx,
flags | PR_CAN_APPEAR);
/* Dismiss transformation that we do not want to carry on. */
@@ -359,7 +359,7 @@ propagate_rtx_1 (rtx *px, rtx old, rtx new, int flags)
canonicalize_address (new_op0);
/* Copy propagations are always ok. Otherwise check the costs. */
- if (!(REG_P (old) && REG_P (new))
+ if (!(REG_P (old_rtx) && REG_P (new_rtx))
&& !should_replace_address (op0, new_op0, GET_MODE (x)))
return true;
@@ -374,8 +374,8 @@ propagate_rtx_1 (rtx *px, rtx old, rtx new, int flags)
/* The only simplification we do attempts to remove references to op0
or make it constant -- in both cases, op0's invalidity will not
make the result invalid. */
- propagate_rtx_1 (&op0, old, new, flags | PR_CAN_APPEAR);
- valid_ops &= propagate_rtx_1 (&op1, old, new, flags);
+ propagate_rtx_1 (&op0, old_rtx, new_rtx, flags | PR_CAN_APPEAR);
+ valid_ops &= propagate_rtx_1 (&op1, old_rtx, new_rtx, flags);
if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1))
return true;
@@ -393,9 +393,9 @@ propagate_rtx_1 (rtx *px, rtx old, rtx new, int flags)
else if (code == REG)
{
- if (rtx_equal_p (x, old))
+ if (rtx_equal_p (x, old_rtx))
{
- *px = new;
+ *px = new_rtx;
return can_appear;
}
}
@@ -438,23 +438,23 @@ varying_mem_p (rtx *body, void *data ATTRIBUTE_UNUSED)
Otherwise, we accept simplifications that have a lower or equal cost. */
static rtx
-propagate_rtx (rtx x, enum machine_mode mode, rtx old, rtx new)
+propagate_rtx (rtx x, enum machine_mode mode, rtx old_rtx, rtx new_rtx)
{
rtx tem;
bool collapsed;
int flags;
- if (REG_P (new) && REGNO (new) < FIRST_PSEUDO_REGISTER)
+ if (REG_P (new_rtx) && REGNO (new_rtx) < FIRST_PSEUDO_REGISTER)
return NULL_RTX;
flags = 0;
- if (REG_P (new) || CONSTANT_P (new))
+ if (REG_P (new_rtx) || CONSTANT_P (new_rtx))
flags |= PR_CAN_APPEAR;
- if (!for_each_rtx (&new, varying_mem_p, NULL))
+ if (!for_each_rtx (&new_rtx, varying_mem_p, NULL))
flags |= PR_HANDLE_MEM;
tem = x;
- collapsed = propagate_rtx_1 (&tem, old, copy_rtx (new), flags);
+ collapsed = propagate_rtx_1 (&tem, old_rtx, copy_rtx (new_rtx), flags);
if (tem == x || !collapsed)
return NULL_RTX;
@@ -527,10 +527,15 @@ use_killed_between (struct df_ref *use, rtx def_insn, rtx target_insn)
return true;
/* Check if the reg in USE has only one definition. We already
- know that this definition reaches use, or we wouldn't be here. */
+ know that this definition reaches use, or we wouldn't be here.
+ However, this is invalid for hard registers because if they are
+ live at the beginning of the function it does not mean that we
+ have an uninitialized access. */
regno = DF_REF_REGNO (use);
def = DF_REG_DEF_CHAIN (regno);
- if (def && (def->next_reg == NULL))
+ if (def
+ && def->next_reg == NULL
+ && regno >= FIRST_PSEUDO_REGISTER)
return false;
/* Check locally if we are in the same basic block. */
@@ -717,7 +722,7 @@ update_df (rtx insn, rtx *loc, struct df_ref **use_rec, enum df_ref_type type,
performed. */
static bool
-try_fwprop_subst (struct df_ref *use, rtx *loc, rtx new, rtx def_insn, bool set_reg_equal)
+try_fwprop_subst (struct df_ref *use, rtx *loc, rtx new_rtx, rtx def_insn, bool set_reg_equal)
{
rtx insn = DF_REF_INSN (use);
enum df_ref_type type = DF_REF_TYPE (use);
@@ -731,11 +736,11 @@ try_fwprop_subst (struct df_ref *use, rtx *loc, rtx new, rtx def_insn, bool set_
fprintf (dump_file, "\nIn insn %d, replacing\n ", INSN_UID (insn));
print_inline_rtx (dump_file, *loc, 2);
fprintf (dump_file, "\n with ");
- print_inline_rtx (dump_file, new, 2);
+ print_inline_rtx (dump_file, new_rtx, 2);
fprintf (dump_file, "\n");
}
- validate_unshare_change (insn, loc, new, true);
+ validate_unshare_change (insn, loc, new_rtx, true);
if (!verify_changes (0))
{
if (dump_file)
@@ -766,7 +771,7 @@ try_fwprop_subst (struct df_ref *use, rtx *loc, rtx new, rtx def_insn, bool set_
num_changes++;
df_ref_remove (use);
- if (!CONSTANT_P (new))
+ if (!CONSTANT_P (new_rtx))
{
struct df_insn_info *insn_info = DF_INSN_INFO_GET (def_insn);
update_df (insn, loc, DF_INSN_INFO_USES (insn_info), type, flags);
@@ -784,11 +789,11 @@ try_fwprop_subst (struct df_ref *use, rtx *loc, rtx new, rtx def_insn, bool set_
if (dump_file)
fprintf (dump_file, " Setting REG_EQUAL note\n");
- set_unique_reg_note (insn, REG_EQUAL, copy_rtx (new));
+ set_unique_reg_note (insn, REG_EQUAL, copy_rtx (new_rtx));
/* ??? Is this still necessary if we add the note through
set_unique_reg_note? */
- if (!CONSTANT_P (new))
+ if (!CONSTANT_P (new_rtx))
{
struct df_insn_info *insn_info = DF_INSN_INFO_GET (def_insn);
update_df (insn, loc, DF_INSN_INFO_USES (insn_info),
@@ -845,7 +850,7 @@ forward_propagate_and_simplify (struct df_ref *use, rtx def_insn, rtx def_set)
{
rtx use_insn = DF_REF_INSN (use);
rtx use_set = single_set (use_insn);
- rtx src, reg, new, *loc;
+ rtx src, reg, new_rtx, *loc;
bool set_reg_equal;
enum machine_mode mode;
@@ -888,10 +893,10 @@ forward_propagate_and_simplify (struct df_ref *use, rtx def_insn, rtx def_set)
if (x != src)
{
rtx note = find_reg_note (use_insn, REG_EQUAL, NULL_RTX);
- rtx old = note ? XEXP (note, 0) : SET_SRC (use_set);
- rtx new = simplify_replace_rtx (old, src, x);
- if (old != new)
- set_unique_reg_note (use_insn, REG_EQUAL, copy_rtx (new));
+ rtx old_rtx = note ? XEXP (note, 0) : SET_SRC (use_set);
+ rtx new_rtx = simplify_replace_rtx (old_rtx, src, x);
+ if (old_rtx != new_rtx)
+ set_unique_reg_note (use_insn, REG_EQUAL, copy_rtx (new_rtx));
}
return false;
}
@@ -923,12 +928,12 @@ forward_propagate_and_simplify (struct df_ref *use, rtx def_insn, rtx def_set)
else
mode = GET_MODE (*loc);
- new = propagate_rtx (*loc, mode, reg, src);
+ new_rtx = propagate_rtx (*loc, mode, reg, src);
- if (!new)
+ if (!new_rtx)
return false;
- return try_fwprop_subst (use, loc, new, def_insn, set_reg_equal);
+ return try_fwprop_subst (use, loc, new_rtx, def_insn, set_reg_equal);
}
diff --git a/gcc/gcc.c b/gcc/gcc.c
index 3da40a8c2a7..7914e4b6f35 100644
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -155,6 +155,8 @@ static const char *print_prog_name = NULL;
static int print_multi_directory;
+static int print_sysroot;
+
/* Flag saying to print the relative path we'd use to
find OS libraries given the current compiler flags. */
@@ -1162,6 +1164,7 @@ static const struct option_map option_map[] =
{"--print-multi-directory", "-print-multi-directory", 0},
{"--print-multi-os-directory", "-print-multi-os-directory", 0},
{"--print-prog-name", "-print-prog-name=", "aj"},
+ {"--print-sysroot", "-print-sysroot", 0},
{"--print-sysroot-headers-suffix", "-print-sysroot-headers-suffix", 0},
{"--profile", "-p", 0},
{"--profile-blocks", "-a", 0},
@@ -2973,7 +2976,7 @@ execute (void)
for (argc = 0; commands[i].argv[argc] != NULL; argc++)
;
- argv = alloca ((argc + 3) * sizeof (char *));
+ argv = XALLOCAVEC (const char *, argc + 3);
argv[0] = VALGRIND_PATH;
argv[1] = "-q";
@@ -3244,6 +3247,7 @@ display_help (void)
-print-multi-lib Display the mapping between command line options and\n\
multiple library search directories\n"), stdout);
fputs (_(" -print-multi-os-directory Display the relative path to OS libraries\n"), stdout);
+ fputs (_(" -print-sysroot Display the target libraries directory\n"), stdout);
fputs (_(" -print-sysroot-headers-suffix Display the sysroot suffix used to find headers\n"), stdout);
fputs (_(" -Wa,<options> Pass comma-separated <options> on to the assembler\n"), stdout);
fputs (_(" -Wp,<options> Pass comma-separated <options> on to the preprocessor\n"), stdout);
@@ -3686,6 +3690,8 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"
print_multi_lib = 1;
else if (! strcmp (argv[i], "-print-multi-directory"))
print_multi_directory = 1;
+ else if (! strcmp (argv[i], "-print-sysroot"))
+ print_sysroot = 1;
else if (! strcmp (argv[i], "-print-multi-os-directory"))
print_multi_os_directory = 1;
else if (! strcmp (argv[i], "-print-sysroot-headers-suffix"))
@@ -4126,6 +4132,8 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"
;
else if (! strcmp (argv[i], "-print-multi-directory"))
;
+ else if (! strcmp (argv[i], "-print-sysroot"))
+ ;
else if (! strcmp (argv[i], "-print-multi-os-directory"))
;
else if (! strcmp (argv[i], "-print-sysroot-headers-suffix"))
@@ -6529,6 +6537,18 @@ main (int argc, char **argv)
return (0);
}
+ if (print_sysroot)
+ {
+ if (target_system_root)
+ {
+ if (target_sysroot_suffix)
+ printf ("%s%s\n", target_system_root, target_sysroot_suffix);
+ else
+ printf ("%s\n", target_system_root);
+ }
+ return (0);
+ }
+
if (print_multi_os_directory)
{
if (multilib_os_dir == NULL)
diff --git a/gcc/gcse.c b/gcc/gcse.c
index 0955744855c..008544f0f64 100644
--- a/gcc/gcse.c
+++ b/gcc/gcse.c
@@ -2791,7 +2791,7 @@ find_avail_set (int regno, rtx insn)
static int
cprop_jump (basic_block bb, rtx setcc, rtx jump, rtx from, rtx src)
{
- rtx new, set_src, note_src;
+ rtx new_rtx, set_src, note_src;
rtx set = pc_set (jump);
rtx note = find_reg_equal_equiv_note (jump);
@@ -2823,22 +2823,22 @@ cprop_jump (basic_block bb, rtx setcc, rtx jump, rtx from, rtx src)
else
setcc = NULL_RTX;
- new = simplify_replace_rtx (set_src, from, src);
+ new_rtx = simplify_replace_rtx (set_src, from, src);
/* If no simplification can be made, then try the next register. */
- if (rtx_equal_p (new, SET_SRC (set)))
+ if (rtx_equal_p (new_rtx, SET_SRC (set)))
return 0;
/* If this is now a no-op delete it, otherwise this must be a valid insn. */
- if (new == pc_rtx)
+ if (new_rtx == pc_rtx)
delete_insn (jump);
else
{
/* Ensure the value computed inside the jump insn to be equivalent
to one computed by setcc. */
- if (setcc && modified_in_p (new, setcc))
+ if (setcc && modified_in_p (new_rtx, setcc))
return 0;
- if (! validate_unshare_change (jump, &SET_SRC (set), new, 0))
+ if (! validate_unshare_change (jump, &SET_SRC (set), new_rtx, 0))
{
/* When (some) constants are not valid in a comparison, and there
are two registers to be replaced by constants before the entire
@@ -2849,8 +2849,8 @@ cprop_jump (basic_block bb, rtx setcc, rtx jump, rtx from, rtx src)
we need to attach a note to the branch itself to make this
optimization work. */
- if (!rtx_equal_p (new, note_src))
- set_unique_reg_note (jump, REG_EQUAL, copy_rtx (new));
+ if (!rtx_equal_p (new_rtx, note_src))
+ set_unique_reg_note (jump, REG_EQUAL, copy_rtx (new_rtx));
return 0;
}
@@ -2881,7 +2881,7 @@ cprop_jump (basic_block bb, rtx setcc, rtx jump, rtx from, rtx src)
/* If a conditional jump has been changed into unconditional jump, remove
the jump and make the edge fallthru - this is always called in
cfglayout mode. */
- if (new != pc_rtx && simplejump_p (jump))
+ if (new_rtx != pc_rtx && simplejump_p (jump))
{
edge e;
edge_iterator ei;
@@ -3306,7 +3306,7 @@ find_implicit_sets (void)
{
basic_block bb, dest;
unsigned int count;
- rtx cond, new;
+ rtx cond, new_rtx;
count = 0;
FOR_EACH_BB (bb)
@@ -3327,9 +3327,9 @@ find_implicit_sets (void)
if (dest && single_pred_p (dest)
&& dest != EXIT_BLOCK_PTR)
{
- new = gen_rtx_SET (VOIDmode, XEXP (cond, 0),
+ new_rtx = gen_rtx_SET (VOIDmode, XEXP (cond, 0),
XEXP (cond, 1));
- implicit_sets[dest->index] = new;
+ implicit_sets[dest->index] = new_rtx;
if (dump_file)
{
fprintf(dump_file, "Implicit set of reg %d in ",
@@ -3539,7 +3539,7 @@ bypass_block (basic_block bb, rtx setcc, rtx jump)
unsigned int regno = REGNO (reg_used->reg_rtx);
basic_block dest, old_dest;
struct expr *set;
- rtx src, new;
+ rtx src, new_rtx;
if (regno >= max_gcse_regno)
continue;
@@ -3560,7 +3560,7 @@ bypass_block (basic_block bb, rtx setcc, rtx jump)
SET_DEST (PATTERN (setcc)),
SET_SRC (PATTERN (setcc)));
- new = simplify_replace_rtx (src, reg_used->reg_rtx,
+ new_rtx = simplify_replace_rtx (src, reg_used->reg_rtx,
SET_SRC (set->expr));
/* Jump bypassing may have already placed instructions on
@@ -3568,14 +3568,14 @@ bypass_block (basic_block bb, rtx setcc, rtx jump)
has instructions associated with it, as these insns won't
get executed if the incoming edge is redirected. */
- if (new == pc_rtx)
+ if (new_rtx == pc_rtx)
{
edest = FALLTHRU_EDGE (bb);
dest = edest->insns.r ? NULL : edest->dest;
}
- else if (GET_CODE (new) == LABEL_REF)
+ else if (GET_CODE (new_rtx) == LABEL_REF)
{
- dest = BLOCK_FOR_INSN (XEXP (new, 0));
+ dest = BLOCK_FOR_INSN (XEXP (new_rtx, 0));
/* Don't bypass edges containing instructions. */
edest = find_edge (bb, dest);
if (edest && edest->insns.r)
@@ -4336,7 +4336,7 @@ pre_insert_copies (void)
static rtx
gcse_emit_move_after (rtx src, rtx dest, rtx insn)
{
- rtx new;
+ rtx new_rtx;
rtx set = single_set (insn), set2;
rtx note;
rtx eqv;
@@ -4344,20 +4344,20 @@ gcse_emit_move_after (rtx src, rtx dest, rtx insn)
/* This should never fail since we're creating a reg->reg copy
we've verified to be valid. */
- new = emit_insn_after (gen_move_insn (dest, src), insn);
+ new_rtx = emit_insn_after (gen_move_insn (dest, src), insn);
/* Note the equivalence for local CSE pass. */
- set2 = single_set (new);
+ set2 = single_set (new_rtx);
if (!set2 || !rtx_equal_p (SET_DEST (set2), dest))
- return new;
+ return new_rtx;
if ((note = find_reg_equal_equiv_note (insn)))
eqv = XEXP (note, 0);
else
eqv = SET_SRC (set);
- set_unique_reg_note (new, REG_EQUAL, copy_insn_1 (eqv));
+ set_unique_reg_note (new_rtx, REG_EQUAL, copy_insn_1 (eqv));
- return new;
+ return new_rtx;
}
/* Delete redundant computations.
@@ -5384,7 +5384,7 @@ update_ld_motion_stores (struct expr * expr)
rtx pat = PATTERN (insn);
rtx src = SET_SRC (pat);
rtx reg = expr->reaching_reg;
- rtx copy, new;
+ rtx copy, new_rtx;
/* If we've already copied it, continue. */
if (expr->reaching_reg == src)
@@ -5400,8 +5400,8 @@ update_ld_motion_stores (struct expr * expr)
}
copy = gen_move_insn ( reg, copy_rtx (SET_SRC (pat)));
- new = emit_insn_before (copy, insn);
- record_one_set (REGNO (reg), new);
+ new_rtx = emit_insn_before (copy, insn);
+ record_one_set (REGNO (reg), new_rtx);
SET_SRC (pat) = reg;
df_insn_rescan (insn);
diff --git a/gcc/genattrtab.c b/gcc/genattrtab.c
index 079c81f9552..794a8db1bb1 100644
--- a/gcc/genattrtab.c
+++ b/gcc/genattrtab.c
@@ -1846,11 +1846,11 @@ insert_right_side (enum rtx_code code, rtx exp, rtx term, int insn_code, int ins
if (GET_CODE (exp) == code)
{
- rtx new = insert_right_side (code, XEXP (exp, 1),
- term, insn_code, insn_index);
- if (new != XEXP (exp, 1))
+ rtx new_rtx = insert_right_side (code, XEXP (exp, 1),
+ term, insn_code, insn_index);
+ if (new_rtx != XEXP (exp, 1))
/* Make a copy of this expression and call recursively. */
- newexp = attr_rtx (code, XEXP (exp, 0), new);
+ newexp = attr_rtx (code, XEXP (exp, 0), new_rtx);
else
newexp = exp;
}
@@ -1980,10 +1980,10 @@ evaluate_eq_attr (rtx exp, rtx value, int insn_code, int insn_index)
for (i = 0; i < XVECLEN (value, 0); i += 2)
{
- rtx this = simplify_test_exp_in_temp (XVECEXP (value, 0, i),
- insn_code, insn_index);
+ rtx this_cond = simplify_test_exp_in_temp (XVECEXP (value, 0, i),
+ insn_code, insn_index);
- right = insert_right_side (AND, andexp, this,
+ right = insert_right_side (AND, andexp, this_cond,
insn_code, insn_index);
right = insert_right_side (AND, right,
evaluate_eq_attr (exp,
@@ -1995,7 +1995,7 @@ evaluate_eq_attr (rtx exp, rtx value, int insn_code, int insn_index)
insn_code, insn_index);
/* Add this condition into the AND expression. */
- newexp = attr_rtx (NOT, this);
+ newexp = attr_rtx (NOT, this_cond);
andexp = insert_right_side (AND, andexp, newexp,
insn_code, insn_index);
}
diff --git a/gcc/genemit.c b/gcc/genemit.c
index caf808e99c9..35e5691b94f 100644
--- a/gcc/genemit.c
+++ b/gcc/genemit.c
@@ -357,17 +357,17 @@ gen_insn (rtx insn, int lineno)
for (j = i + 1; j < XVECLEN (insn, 1); j++)
{
- rtx old = XEXP (XVECEXP (p->pattern, 1, j), 0);
- rtx new = XEXP (XVECEXP (insn, 1, j), 0);
+ rtx old_rtx = XEXP (XVECEXP (p->pattern, 1, j), 0);
+ rtx new_rtx = XEXP (XVECEXP (insn, 1, j), 0);
- /* OLD and NEW are the same if both are to be a SCRATCH
+ /* OLD and NEW_INSN are the same if both are to be a SCRATCH
of the same mode,
or if both are registers of the same mode and number. */
- if (! (GET_MODE (old) == GET_MODE (new)
- && ((GET_CODE (old) == MATCH_SCRATCH
- && GET_CODE (new) == MATCH_SCRATCH)
- || (REG_P (old) && REG_P (new)
- && REGNO (old) == REGNO (new)))))
+ if (! (GET_MODE (old_rtx) == GET_MODE (new_rtx)
+ && ((GET_CODE (old_rtx) == MATCH_SCRATCH
+ && GET_CODE (new_rtx) == MATCH_SCRATCH)
+ || (REG_P (old_rtx) && REG_P (new_rtx)
+ && REGNO (old_rtx) == REGNO (new_rtx)))))
break;
}
diff --git a/gcc/gengtype.c b/gcc/gengtype.c
index 72d10781241..adc355a3881 100644
--- a/gcc/gengtype.c
+++ b/gcc/gengtype.c
@@ -1537,7 +1537,7 @@ open_base_files (void)
"hard-reg-set.h", "basic-block.h", "cselib.h", "insn-addr.h",
"optabs.h", "libfuncs.h", "debug.h", "ggc.h", "cgraph.h",
"tree-flow.h", "reload.h", "cpp-id-data.h", "tree-chrec.h",
- "cfglayout.h", "except.h", "output.h", "cfgloop.h", NULL
+ "cfglayout.h", "except.h", "output.h", "gimple.h", "cfgloop.h", NULL
};
const char *const *ifp;
outf_p gtype_desc_c;
@@ -3529,22 +3529,22 @@ write_roots (pair_p variables)
where the GTY(()) tags are only present if is_scalar is _false_. */
void
-note_def_vec (const char *typename, bool is_scalar, struct fileloc *pos)
+note_def_vec (const char *type_name, bool is_scalar, struct fileloc *pos)
{
pair_p fields;
type_p t;
options_p o;
type_p len_ty = create_scalar_type ("unsigned");
- const char *name = concat ("VEC_", typename, "_base", (char *)0);
+ const char *name = concat ("VEC_", type_name, "_base", (char *)0);
if (is_scalar)
{
- t = create_scalar_type (typename);
+ t = create_scalar_type (type_name);
o = 0;
}
else
{
- t = resolve_typedef (typename, pos);
+ t = resolve_typedef (type_name, pos);
o = create_option (0, "length", "%h.num");
}
diff --git a/gcc/gengtype.h b/gcc/gengtype.h
index fef1262a958..916570a8b9c 100644
--- a/gcc/gengtype.h
+++ b/gcc/gengtype.h
@@ -64,7 +64,7 @@ extern pair_p nreverse_pairs (pair_p list);
extern type_p adjust_field_type (type_p, options_p);
extern void note_variable (const char *s, type_p t, options_p o,
struct fileloc *pos);
-extern void note_def_vec (const char *typename, bool is_scalar,
+extern void note_def_vec (const char *type_name, bool is_scalar,
struct fileloc *pos);
extern void note_def_vec_alloc (const char *type, const char *astrat,
struct fileloc *pos);
diff --git a/gcc/genoutput.c b/gcc/genoutput.c
index 3592388bd64..601483d8b2f 100644
--- a/gcc/genoutput.c
+++ b/gcc/genoutput.c
@@ -154,7 +154,7 @@ struct data
{
struct data *next;
const char *name;
- const char *template;
+ const char *template_code;
int code_number;
int index_number;
const char *filename;
@@ -336,7 +336,7 @@ output_insn_data (void)
break;
case INSN_OUTPUT_FORMAT_SINGLE:
{
- const char *p = d->template;
+ const char *p = d->template_code;
char prev = 0;
printf ("#if HAVE_DESIGNATED_INITIALIZERS\n");
@@ -656,36 +656,36 @@ 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)
+process_template (struct data *d, const char *template_code)
{
const char *cp;
int i;
/* Templates starting with * contain straight code to be run. */
- if (template[0] == '*')
+ if (template_code[0] == '*')
{
- d->template = 0;
+ d->template_code = 0;
d->output_format = INSN_OUTPUT_FORMAT_FUNCTION;
puts ("\nstatic const char *");
printf ("output_%d (rtx *operands ATTRIBUTE_UNUSED, rtx insn ATTRIBUTE_UNUSED)\n",
d->code_number);
puts ("{");
- print_rtx_ptr_loc (template);
- puts (template + 1);
+ print_rtx_ptr_loc (template_code);
+ puts (template_code + 1);
puts ("}");
}
/* If the assembler code template starts with a @ it is a newline-separated
list of assembler code templates, one for each alternative. */
- else if (template[0] == '@')
+ else if (template_code[0] == '@')
{
- d->template = 0;
+ d->template_code = 0;
d->output_format = INSN_OUTPUT_FORMAT_MULTI;
printf ("\nstatic const char * const output_%d[] = {\n", d->code_number);
- for (i = 0, cp = &template[1]; *cp; )
+ for (i = 0, cp = &template_code[1]; *cp; )
{
const char *ep, *sp;
@@ -725,7 +725,7 @@ process_template (struct data *d, const char *template)
}
else
{
- d->template = template;
+ d->template_code = template_code;
d->output_format = INSN_OUTPUT_FORMAT_SINGLE;
}
}
@@ -952,7 +952,7 @@ gen_expand (rtx insn, int lineno)
d->n_operands = max_opno + 1;
d->n_dups = num_dups;
- d->template = 0;
+ d->template_code = 0;
d->output_format = INSN_OUTPUT_FORMAT_NONE;
validate_insn_alternatives (d);
@@ -993,7 +993,7 @@ gen_split (rtx split, int lineno)
d->n_operands = max_opno + 1;
d->n_dups = 0;
d->n_alternatives = 0;
- d->template = 0;
+ d->template_code = 0;
d->output_format = INSN_OUTPUT_FORMAT_NONE;
place_operands (d);
@@ -1120,7 +1120,7 @@ note_constraint (rtx exp, int lineno)
{
const char *name = XSTR (exp, 0);
unsigned int namelen = strlen (name);
- struct constraint_data **iter, **slot, *new;
+ struct constraint_data **iter, **slot, *new_cdata;
/* The 'm' constraint is special here since that constraint letter
can be overridden by the back end by defining the
@@ -1173,12 +1173,12 @@ note_constraint (rtx exp, int lineno)
return;
}
}
- new = XNEWVAR (struct constraint_data, sizeof (struct constraint_data) + namelen);
- strcpy ((char *)new + offsetof(struct constraint_data, name), name);
- new->namelen = namelen;
- new->lineno = lineno;
- new->next_this_letter = *slot;
- *slot = new;
+ new_cdata = XNEWVAR (struct constraint_data, sizeof (struct constraint_data) + namelen);
+ strcpy ((char *)new_cdata + offsetof(struct constraint_data, name), name);
+ new_cdata->namelen = namelen;
+ new_cdata->lineno = lineno;
+ new_cdata->next_this_letter = *slot;
+ *slot = new_cdata;
}
/* Return the length of the constraint name beginning at position S
diff --git a/gcc/genrecog.c b/gcc/genrecog.c
index 1713f133314..70ab87745d3 100644
--- a/gcc/genrecog.c
+++ b/gcc/genrecog.c
@@ -474,14 +474,14 @@ extern void debug_decision_list
static struct decision *
new_decision (const char *position, struct decision_head *last)
{
- struct decision *new = XCNEW (struct decision);
+ struct decision *new_decision = XCNEW (struct decision);
- new->success = *last;
- new->position = xstrdup (position);
- new->number = next_number++;
+ new_decision->success = *last;
+ new_decision->position = xstrdup (position);
+ new_decision->number = next_number++;
- last->first = last->last = new;
- return new;
+ last->first = last->last = new_decision;
+ return new_decision;
}
/* Create a new test and link it in at PLACE. */
@@ -877,7 +877,7 @@ add_to_sequence (rtx pattern, struct decision_head *last, const char *position,
enum routine_type insn_type, int top)
{
RTX_CODE code;
- struct decision *this, *sub;
+ struct decision *this_decision, *sub;
struct decision_test *test;
struct decision_test **place;
char *subpos;
@@ -894,8 +894,8 @@ add_to_sequence (rtx pattern, struct decision_head *last, const char *position,
strcpy (subpos, position);
subpos[depth + 1] = 0;
- sub = this = new_decision (position, last);
- place = &this->tests;
+ sub = this_decision = new_decision (position, last);
+ place = &this_decision->tests;
restart:
mode = GET_MODE (pattern);
@@ -1142,20 +1142,20 @@ add_to_sequence (rtx pattern, struct decision_head *last, const char *position,
before any of the nodes we may have added above. */
if (code != UNKNOWN)
{
- place = &this->tests;
+ place = &this_decision->tests;
test = new_decision_test (DT_code, &place);
test->u.code = code;
}
if (mode != VOIDmode)
{
- place = &this->tests;
+ place = &this_decision->tests;
test = new_decision_test (DT_mode, &place);
test->u.mode = mode;
}
/* If we didn't insert any tests or accept nodes, hork. */
- gcc_assert (this->tests);
+ gcc_assert (this_decision->tests);
ret:
free (subpos);
@@ -1592,7 +1592,7 @@ factor_tests (struct decision_head *head)
for (first = head->first; first && first->next; first = next)
{
enum decision_type type;
- struct decision *new, *old_last;
+ struct decision *new_dec, *old_last;
type = first->tests->type;
next = first->next;
@@ -1615,8 +1615,8 @@ factor_tests (struct decision_head *head)
below our first test. */
if (first->tests->next != NULL)
{
- new = new_decision (first->position, &first->success);
- new->tests = first->tests->next;
+ new_dec = new_decision (first->position, &first->success);
+ new_dec->tests = first->tests->next;
first->tests->next = NULL;
}
@@ -1633,14 +1633,14 @@ factor_tests (struct decision_head *head)
if (next->tests->next != NULL)
{
- new = new_decision (next->position, &next->success);
- new->tests = next->tests->next;
+ new_dec = new_decision (next->position, &next->success);
+ new_dec->tests = next->tests->next;
next->tests->next = NULL;
}
- new = next;
+ new_dec = next;
next = next->next;
- new->next = NULL;
- h.first = h.last = new;
+ new_dec->next = NULL;
+ h.first = h.last = new_dec;
merge_trees (head, &h);
}
@@ -2618,25 +2618,25 @@ make_insn_sequence (rtx insn, enum routine_type type)
if (i != XVECLEN (x, 0))
{
- rtx new;
+ rtx new_rtx;
struct decision_head clobber_head;
/* Build a similar insn without the clobbers. */
if (i == 1)
- new = XVECEXP (x, 0, 0);
+ new_rtx = XVECEXP (x, 0, 0);
else
{
int j;
- new = rtx_alloc (PARALLEL);
- XVEC (new, 0) = rtvec_alloc (i);
+ new_rtx = rtx_alloc (PARALLEL);
+ XVEC (new_rtx, 0) = rtvec_alloc (i);
for (j = i - 1; j >= 0; j--)
- XVECEXP (new, 0, j) = XVECEXP (x, 0, j);
+ XVECEXP (new_rtx, 0, j) = XVECEXP (x, 0, j);
}
/* Recognize it. */
memset (&clobber_head, 0, sizeof(clobber_head));
- last = add_to_sequence (new, &clobber_head, "", type, 1);
+ last = add_to_sequence (new_rtx, &clobber_head, "", type, 1);
/* Find the end of the test chain on the last node. */
for (test = last->tests; test->next; test = test->next)
diff --git a/gcc/gensupport.c b/gcc/gensupport.c
index 912b81b79c6..540c30e3575 100644
--- a/gcc/gensupport.c
+++ b/gcc/gensupport.c
@@ -1428,7 +1428,7 @@ record_insn_name (int code, const char *name)
{
static const char *last_real_name = "insn";
static int last_real_code = 0;
- char *new;
+ char *new_name;
if (insn_name_ptr_size <= code)
{
@@ -1442,14 +1442,14 @@ record_insn_name (int code, const char *name)
if (!name || name[0] == '\0')
{
- new = XNEWVAR (char, strlen (last_real_name) + 10);
- sprintf (new, "%s+%d", last_real_name, code - last_real_code);
+ new_name = XNEWVAR (char, strlen (last_real_name) + 10);
+ sprintf (new_name, "%s+%d", last_real_name, code - last_real_code);
}
else
{
- last_real_name = new = xstrdup (name);
+ last_real_name = new_name = xstrdup (name);
last_real_code = code;
}
- insn_name_ptr[code] = new;
+ insn_name_ptr[code] = new_name;
}
diff --git a/gcc/ggc-common.c b/gcc/ggc-common.c
index d1022a1da85..8c0e459fe38 100644
--- a/gcc/ggc-common.c
+++ b/gcc/ggc-common.c
@@ -638,7 +638,7 @@ mmap_gt_pch_get_address (size_t size, int fd)
if (ret == (void *) MAP_FAILED)
ret = NULL;
else
- munmap (ret, size);
+ munmap ((caddr_t) ret, size);
return ret;
}
@@ -662,7 +662,7 @@ mmap_gt_pch_use_address (void *base, size_t size, int fd, size_t offset)
if (size == 0)
return -1;
- addr = mmap (base, size, PROT_READ | PROT_WRITE, MAP_PRIVATE,
+ addr = mmap ((caddr_t) base, size, PROT_READ | PROT_WRITE, MAP_PRIVATE,
fd, offset);
return addr == base ? 1 : -1;
diff --git a/gcc/ggc-page.c b/gcc/ggc-page.c
index 4ac73d4af4f..0afe0d815dd 100644
--- a/gcc/ggc-page.c
+++ b/gcc/ggc-page.c
@@ -172,7 +172,6 @@ along with GCC; see the file COPYING3. If not see
thing you need to do to add a new special allocation size. */
static const size_t extra_order_size_table[] = {
- sizeof (struct stmt_ann_d),
sizeof (struct var_ann_d),
sizeof (struct tree_decl_non_common),
sizeof (struct tree_field_decl),
@@ -184,9 +183,6 @@ static const size_t extra_order_size_table[] = {
sizeof (struct basic_block_def),
sizeof (bitmap_element),
sizeof (bitmap_head),
- /* PHI nodes with one to three arguments are already covered by the
- above sizes. */
- sizeof (struct tree_phi_node) + sizeof (struct phi_arg_d) * 3,
TREE_EXP_SIZE (2),
RTL_SIZE (2), /* MEM, PLUS, etc. */
RTL_SIZE (9), /* INSN */
@@ -799,7 +795,7 @@ alloc_page (unsigned order)
alloc_size = GGC_QUIRE_SIZE * G.pagesize;
else
alloc_size = entry_size + G.pagesize - 1;
- allocation = xmalloc (alloc_size);
+ allocation = XNEWVEC (char, alloc_size);
page = (char *) (((size_t) allocation + G.pagesize - 1) & -G.pagesize);
head_slop = page - allocation;
@@ -842,7 +838,7 @@ alloc_page (unsigned order)
struct page_entry *e, *f = G.free_pages;
for (a = enda - G.pagesize; a != page; a -= G.pagesize)
{
- e = xcalloc (1, page_entry_size);
+ e = XCNEWVAR (struct page_entry, page_entry_size);
e->order = order;
e->bytes = G.pagesize;
e->page = a;
diff --git a/gcc/ggc-zone.c b/gcc/ggc-zone.c
index a80a6a0e979..5031a01b404 100644
--- a/gcc/ggc-zone.c
+++ b/gcc/ggc-zone.c
@@ -541,7 +541,7 @@ lookup_page_table_if_allocated (const void *p)
return NULL;
/* We might have a page entry which does not correspond exactly to a
system page. */
- if (base[L1][L2] && (char *) p < base[L1][L2]->page)
+ if (base[L1][L2] && (const char *) p < base[L1][L2]->page)
return NULL;
return base[L1][L2];
@@ -566,7 +566,7 @@ set_page_table_entry (void *p, page_entry *entry)
goto found;
/* Not found -- allocate a new table. */
- table = xcalloc (1, sizeof(*table));
+ table = XCNEW (struct page_table_chain);
table->next = G.lookup;
table->high_bits = high_bits;
G.lookup = table;
@@ -579,7 +579,7 @@ found:
L2 = LOOKUP_L2 (p);
if (base[L1] == NULL)
- base[L1] = xcalloc (PAGE_L2_SIZE, sizeof (page_entry *));
+ base[L1] = XCNEWVEC (page_entry *, PAGE_L2_SIZE);
base[L1][L2] = entry;
}
@@ -715,7 +715,7 @@ zone_find_object_size (struct small_page_entry *page,
unsigned int start_word = zone_get_object_alloc_word (object_midptr);
unsigned int start_bit = zone_get_object_alloc_bit (object_midptr);
size_t max_size = (page->common.page + SMALL_PAGE_SIZE
- - (char *) object);
+ - (const char *) object);
return zone_object_size_1 (page->alloc_bits, start_word, start_bit,
max_size);
@@ -898,7 +898,7 @@ alloc_small_page (struct alloc_zone *zone)
memory order. */
for (i = G.quire_size - 1; i >= 1; i--)
{
- e = xcalloc (1, G.small_page_overhead);
+ e = XCNEWVAR (struct small_page_entry, G.small_page_overhead);
e->common.page = page + (i << GGC_PAGE_SHIFT);
e->common.zone = zone;
e->next = f;
@@ -908,7 +908,7 @@ alloc_small_page (struct alloc_zone *zone)
zone->free_pages = f;
- entry = xcalloc (1, G.small_page_overhead);
+ entry = XCNEWVAR (struct small_page_entry, G.small_page_overhead);
entry->common.page = page;
entry->common.zone = zone;
set_page_table_entry (page, &entry->common);
@@ -935,7 +935,7 @@ alloc_large_page (size_t size, struct alloc_zone *zone)
size_t needed_size;
needed_size = size + sizeof (struct large_page_entry);
- page = xmalloc (needed_size);
+ page = XNEWVAR (char, needed_size);
entry = (struct large_page_entry *) page;
@@ -1439,7 +1439,7 @@ ggc_free (void *p)
/* Add the chunk to the free list. We don't bother with coalescing,
since we are likely to want a chunk of this size again. */
- free_chunk (p, size, page->zone);
+ free_chunk ((char *)p, size, page->zone);
}
}
@@ -1494,7 +1494,7 @@ gt_ggc_m_S (const void *p)
a STRING_CST. */
gcc_assert (offset == offsetof (struct tree_string, str));
p = ((const char *) p) - offset;
- gt_ggc_mx_lang_tree_node ((void *) p);
+ gt_ggc_mx_lang_tree_node (CONST_CAST(void *, p));
return;
}
@@ -1560,7 +1560,7 @@ int
ggc_marked_p (const void *p)
{
struct page_entry *page;
- const char *ptr = p;
+ const char *ptr = (const char *) p;
page = zone_get_object_page (p);
@@ -1686,7 +1686,7 @@ init_ggc (void)
if (GGC_PAGE_SIZE == G.pagesize)
{
/* We have a good page, might as well hold onto it... */
- e = xcalloc (1, G.small_page_overhead);
+ e = XCNEWVAR (struct small_page_entry, G.small_page_overhead);
e->common.page = p;
e->common.zone = &main_zone;
e->next = main_zone.free_pages;
@@ -1714,7 +1714,7 @@ new_ggc_zone_1 (struct alloc_zone *new_zone, const char * name)
struct alloc_zone *
new_ggc_zone (const char * name)
{
- struct alloc_zone *new_zone = xcalloc (1, sizeof (struct alloc_zone));
+ struct alloc_zone *new_zone = XCNEW (struct alloc_zone);
new_ggc_zone_1 (new_zone, name);
return new_zone;
}
@@ -2301,7 +2301,7 @@ struct ggc_pch_data
struct ggc_pch_data *
init_ggc_pch (void)
{
- return xcalloc (sizeof (struct ggc_pch_data), 1);
+ return XCNEW (struct ggc_pch_data);
}
/* Return which of the page-aligned buckets the object at X, with type
@@ -2380,7 +2380,7 @@ ggc_pch_this_base (struct ggc_pch_data *d, void *base_)
}
if (d->alloc_bits == NULL)
- d->alloc_bits = xcalloc (1, d->alloc_size);
+ d->alloc_bits = XCNEWVAR (alloc_type, d->alloc_size);
}
/* Allocate a place for object X of size SIZE in the PCH file. */
@@ -2516,7 +2516,7 @@ ggc_pch_read (FILE *f, void *addr)
/* Allocate the dummy page entry for the PCH, and set all pages
mapped into the PCH to reference it. */
- pch_page = xcalloc (1, sizeof (struct page_entry));
+ pch_page = XCNEW (struct page_entry);
pch_page->page = pch_zone.page;
pch_page->pch_p = true;
diff --git a/gcc/gimple-iterator.c b/gcc/gimple-iterator.c
new file mode 100644
index 00000000000..a52c83072b4
--- /dev/null
+++ b/gcc/gimple-iterator.c
@@ -0,0 +1,771 @@
+/* Iterator routines for GIMPLE statements.
+ Copyright (C) 2007, 2008 Free Software Foundation, Inc.
+ Contributed by Aldy Hernandez <aldy@quesejoda.com>
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tree.h"
+#include "gimple.h"
+#include "tree-flow.h"
+#include "value-prof.h"
+
+
+/* Mark the statement STMT as modified, and update it. */
+
+static inline void
+update_modified_stmt (gimple stmt)
+{
+ if (!ssa_operands_active ())
+ return;
+ update_stmt_if_modified (stmt);
+}
+
+
+/* Mark the statements in SEQ as modified, and update them. */
+
+static void
+update_modified_stmts (gimple_seq seq)
+{
+ gimple_stmt_iterator gsi;
+
+ if (!ssa_operands_active ())
+ return;
+ for (gsi = gsi_start (seq); !gsi_end_p (gsi); gsi_next (&gsi))
+ update_stmt_if_modified (gsi_stmt (gsi));
+}
+
+
+/* Set BB to be the basic block for all the statements in the list
+ starting at FIRST and LAST. */
+
+static void
+update_bb_for_stmts (gimple_seq_node first, basic_block bb)
+{
+ gimple_seq_node n;
+
+ for (n = first; n; n = n->next)
+ gimple_set_bb (n->stmt, bb);
+}
+
+
+/* Insert the sequence delimited by nodes FIRST and LAST before
+ iterator I. M specifies how to update iterator I after insertion
+ (see enum gsi_iterator_update).
+
+ This routine assumes that there is a forward and backward path
+ between FIRST and LAST (i.e., they are linked in a doubly-linked
+ list). Additionally, if FIRST == LAST, this routine will properly
+ insert a single node. */
+
+static void
+gsi_insert_seq_nodes_before (gimple_stmt_iterator *i,
+ gimple_seq_node first,
+ gimple_seq_node last,
+ enum gsi_iterator_update mode)
+{
+ basic_block bb;
+ gimple_seq_node cur = i->ptr;
+
+ if ((bb = gsi_bb (*i)) != NULL)
+ update_bb_for_stmts (first, bb);
+
+ /* Link SEQ before CUR in the sequence. */
+ if (cur)
+ {
+ first->prev = cur->prev;
+ if (first->prev)
+ first->prev->next = first;
+ else
+ gimple_seq_set_first (i->seq, first);
+ last->next = cur;
+ cur->prev = last;
+ }
+ else
+ {
+ gimple_seq_node itlast = gimple_seq_last (i->seq);
+
+ /* If CUR is NULL, we link at the end of the sequence (this case happens
+ when gsi_after_labels is called for a basic block that contains only
+ labels, so it returns an iterator after the end of the block, and
+ we need to insert before it; it might be cleaner to add a flag to the
+ iterator saying whether we are at the start or end of the list). */
+ first->prev = itlast;
+ if (itlast)
+ itlast->next = first;
+ else
+ gimple_seq_set_first (i->seq, first);
+ gimple_seq_set_last (i->seq, last);
+ }
+
+ /* Update the iterator, if requested. */
+ switch (mode)
+ {
+ case GSI_NEW_STMT:
+ case GSI_CONTINUE_LINKING:
+ i->ptr = first;
+ break;
+ case GSI_SAME_STMT:
+ break;
+ default:
+ gcc_unreachable ();
+ }
+}
+
+
+/* Inserts the sequence of statements SEQ before the statement pointed
+ by iterator I. MODE indicates what to do with the iterator after
+ insertion (see enum gsi_iterator_update).
+
+ This function does not scan for new operands. It is provided for
+ the use of the gimplifier, which manipulates statements for which
+ def/use information has not yet been constructed. Most callers
+ should use gsi_insert_seq_before. */
+
+void
+gsi_insert_seq_before_without_update (gimple_stmt_iterator *i, gimple_seq seq,
+ enum gsi_iterator_update mode)
+{
+ gimple_seq_node first, last;
+
+ if (seq == NULL)
+ return;
+
+ /* Don't allow inserting a sequence into itself. */
+ gcc_assert (seq != i->seq);
+
+ first = gimple_seq_first (seq);
+ last = gimple_seq_last (seq);
+
+ gimple_seq_set_first (seq, NULL);
+ gimple_seq_set_last (seq, NULL);
+ gimple_seq_free (seq);
+
+ /* Empty sequences need no work. */
+ if (!first || !last)
+ {
+ gcc_assert (first == last);
+ return;
+ }
+
+ gsi_insert_seq_nodes_before (i, first, last, mode);
+}
+
+
+/* Inserts the sequence of statements SEQ before the statement pointed
+ by iterator I. MODE indicates what to do with the iterator after
+ insertion (see enum gsi_iterator_update). Scan the statements in SEQ
+ for new operands. */
+
+void
+gsi_insert_seq_before (gimple_stmt_iterator *i, gimple_seq seq,
+ enum gsi_iterator_update mode)
+{
+ update_modified_stmts (seq);
+ gsi_insert_seq_before_without_update (i, seq, mode);
+}
+
+
+/* Insert the sequence delimited by nodes FIRST and LAST after
+ iterator I. M specifies how to update iterator I after insertion
+ (see enum gsi_iterator_update).
+
+ This routine assumes that there is a forward and backward path
+ between FIRST and LAST (i.e., they are linked in a doubly-linked
+ list). Additionally, if FIRST == LAST, this routine will properly
+ insert a single node. */
+
+static void
+gsi_insert_seq_nodes_after (gimple_stmt_iterator *i,
+ gimple_seq_node first,
+ gimple_seq_node last,
+ enum gsi_iterator_update m)
+{
+ basic_block bb;
+ gimple_seq_node cur = i->ptr;
+
+ /* If the iterator is inside a basic block, we need to update the
+ basic block information for all the nodes between FIRST and LAST. */
+ if ((bb = gsi_bb (*i)) != NULL)
+ update_bb_for_stmts (first, bb);
+
+ /* Link SEQ after CUR. */
+ if (cur)
+ {
+ last->next = cur->next;
+ if (last->next)
+ last->next->prev = last;
+ else
+ gimple_seq_set_last (i->seq, last);
+ first->prev = cur;
+ cur->next = first;
+ }
+ else
+ {
+ gcc_assert (!gimple_seq_last (i->seq));
+ gimple_seq_set_first (i->seq, first);
+ gimple_seq_set_last (i->seq, last);
+ }
+
+ /* Update the iterator, if requested. */
+ switch (m)
+ {
+ case GSI_NEW_STMT:
+ i->ptr = first;
+ break;
+ case GSI_CONTINUE_LINKING:
+ i->ptr = last;
+ break;
+ case GSI_SAME_STMT:
+ gcc_assert (cur);
+ break;
+ default:
+ gcc_unreachable ();
+ }
+}
+
+
+/* Links sequence SEQ after the statement pointed-to by iterator I.
+ MODE is as in gsi_insert_after.
+
+ This function does not scan for new operands. It is provided for
+ the use of the gimplifier, which manipulates statements for which
+ def/use information has not yet been constructed. Most callers
+ should use gsi_insert_seq_after. */
+
+void
+gsi_insert_seq_after_without_update (gimple_stmt_iterator *i, gimple_seq seq,
+ enum gsi_iterator_update mode)
+{
+ gimple_seq_node first, last;
+
+ if (seq == NULL)
+ return;
+
+ /* Don't allow inserting a sequence into itself. */
+ gcc_assert (seq != i->seq);
+
+ first = gimple_seq_first (seq);
+ last = gimple_seq_last (seq);
+
+ gimple_seq_set_first (seq, NULL);
+ gimple_seq_set_last (seq, NULL);
+ gimple_seq_free (seq);
+
+ /* Empty sequences need no work. */
+ if (!first || !last)
+ {
+ gcc_assert (first == last);
+ return;
+ }
+
+ gsi_insert_seq_nodes_after (i, first, last, mode);
+}
+
+
+/* Links sequence SEQ after the statement pointed-to by iterator I.
+ MODE is as in gsi_insert_after. Scan the statements in SEQ
+ for new operands. */
+
+void
+gsi_insert_seq_after (gimple_stmt_iterator *i, gimple_seq seq,
+ enum gsi_iterator_update mode)
+{
+ update_modified_stmts (seq);
+ gsi_insert_seq_after_without_update (i, seq, mode);
+}
+
+
+/* Move all statements in the sequence after I to a new sequence.
+ Return this new sequence. */
+
+gimple_seq
+gsi_split_seq_after (gimple_stmt_iterator i)
+{
+ gimple_seq_node cur, next;
+ gimple_seq old_seq, new_seq;
+
+ cur = i.ptr;
+
+ /* How can we possibly split after the end, or before the beginning? */
+ gcc_assert (cur && cur->next);
+ next = cur->next;
+
+ old_seq = i.seq;
+ new_seq = gimple_seq_alloc ();
+
+ gimple_seq_set_first (new_seq, next);
+ gimple_seq_set_last (new_seq, gimple_seq_last (old_seq));
+ gimple_seq_set_last (old_seq, cur);
+ cur->next = NULL;
+ next->prev = NULL;
+
+ return new_seq;
+}
+
+
+/* Move all statements in the sequence before I to a new sequence.
+ Return this new sequence. I is set to the head of the new list. */
+
+gimple_seq
+gsi_split_seq_before (gimple_stmt_iterator *i)
+{
+ gimple_seq_node cur, prev;
+ gimple_seq old_seq, new_seq;
+
+ cur = i->ptr;
+
+ /* How can we possibly split after the end? */
+ gcc_assert (cur);
+ prev = cur->prev;
+
+ old_seq = i->seq;
+ new_seq = gimple_seq_alloc ();
+ i->seq = new_seq;
+
+ /* Set the limits on NEW_SEQ. */
+ gimple_seq_set_first (new_seq, cur);
+ gimple_seq_set_last (new_seq, gimple_seq_last (old_seq));
+
+ /* Cut OLD_SEQ before I. */
+ gimple_seq_set_last (old_seq, prev);
+ cur->prev = NULL;
+ if (prev)
+ prev->next = NULL;
+ else
+ gimple_seq_set_first (old_seq, NULL);
+
+ return new_seq;
+}
+
+
+/* Replace the statement pointed-to by GSI to STMT. If UPDATE_EH_INFO
+ is true, the exception handling information of the original
+ statement is moved to the new statement. */
+
+void
+gsi_replace (gimple_stmt_iterator *gsi, gimple stmt, bool update_eh_info)
+{
+ int eh_region;
+ gimple orig_stmt = gsi_stmt (*gsi);
+
+ if (stmt == orig_stmt)
+ return;
+
+ gimple_set_location (stmt, gimple_location (orig_stmt));
+ gimple_set_bb (stmt, gsi_bb (*gsi));
+
+ /* Preserve EH region information from the original statement, if
+ requested by the caller. */
+ if (update_eh_info)
+ {
+ eh_region = lookup_stmt_eh_region (orig_stmt);
+ if (eh_region >= 0)
+ {
+ remove_stmt_from_eh_region (orig_stmt);
+ add_stmt_to_eh_region (stmt, eh_region);
+ }
+ }
+
+ gimple_duplicate_stmt_histograms (cfun, stmt, cfun, orig_stmt);
+ gimple_remove_stmt_histograms (cfun, orig_stmt);
+ delink_stmt_imm_use (orig_stmt);
+ *gsi_stmt_ptr (gsi) = stmt;
+ gimple_set_modified (stmt, true);
+ update_modified_stmt (stmt);
+}
+
+
+/* Insert statement STMT before the statement pointed-to by iterator I.
+ M specifies how to update iterator I after insertion (see enum
+ gsi_iterator_update).
+
+ This function does not scan for new operands. It is provided for
+ the use of the gimplifier, which manipulates statements for which
+ def/use information has not yet been constructed. Most callers
+ should use gsi_insert_before. */
+
+void
+gsi_insert_before_without_update (gimple_stmt_iterator *i, gimple stmt,
+ enum gsi_iterator_update m)
+{
+ gimple_seq_node n;
+
+ n = GGC_NEW (struct gimple_seq_node_d);
+ n->prev = n->next = NULL;
+ n->stmt = stmt;
+ gsi_insert_seq_nodes_before (i, n, n, m);
+}
+
+/* Insert statement STMT before the statement pointed-to by iterator I.
+ Update STMT's basic block and scan it for new operands. M
+ specifies how to update iterator I after insertion (see enum
+ gsi_iterator_update). */
+
+void
+gsi_insert_before (gimple_stmt_iterator *i, gimple stmt,
+ enum gsi_iterator_update m)
+{
+ update_modified_stmt (stmt);
+ gsi_insert_before_without_update (i, stmt, m);
+}
+
+
+/* Insert statement STMT after the statement pointed-to by iterator I.
+ M specifies how to update iterator I after insertion (see enum
+ gsi_iterator_update).
+
+ This function does not scan for new operands. It is provided for
+ the use of the gimplifier, which manipulates statements for which
+ def/use information has not yet been constructed. Most callers
+ should use gsi_insert_after. */
+
+void
+gsi_insert_after_without_update (gimple_stmt_iterator *i, gimple stmt,
+ enum gsi_iterator_update m)
+{
+ gimple_seq_node n;
+
+ n = GGC_NEW (struct gimple_seq_node_d);
+ n->prev = n->next = NULL;
+ n->stmt = stmt;
+ gsi_insert_seq_nodes_after (i, n, n, m);
+}
+
+
+/* Insert statement STMT after the statement pointed-to by iterator I.
+ Update STMT's basic block and scan it for new operands. M
+ specifies how to update iterator I after insertion (see enum
+ gsi_iterator_update). */
+
+void
+gsi_insert_after (gimple_stmt_iterator *i, gimple stmt,
+ enum gsi_iterator_update m)
+{
+ update_modified_stmt (stmt);
+ gsi_insert_after_without_update (i, stmt, m);
+}
+
+
+/* Remove the current stmt from the sequence. The iterator is updated
+ to point to the next statement.
+
+ REMOVE_PERMANENTLY is true when the statement is going to be removed
+ from the IL and not reinserted elsewhere. In that case we remove the
+ statement pointed to by iterator I from the EH tables, and free its
+ operand caches. Otherwise we do not modify this information. */
+
+void
+gsi_remove (gimple_stmt_iterator *i, bool remove_permanently)
+{
+ gimple_seq_node cur, next, prev;
+ gimple stmt = gsi_stmt (*i);
+
+ /* Free all the data flow information for STMT. */
+ gimple_set_bb (stmt, NULL);
+ delink_stmt_imm_use (stmt);
+ gimple_set_modified (stmt, true);
+
+ if (remove_permanently)
+ {
+ remove_stmt_from_eh_region (stmt);
+ gimple_remove_stmt_histograms (cfun, stmt);
+ }
+
+ /* Update the iterator and re-wire the links in I->SEQ. */
+ cur = i->ptr;
+ next = cur->next;
+ prev = cur->prev;
+
+ if (prev)
+ prev->next = next;
+ else
+ gimple_seq_set_first (i->seq, next);
+
+ if (next)
+ next->prev = prev;
+ else
+ gimple_seq_set_last (i->seq, prev);
+
+ i->ptr = next;
+}
+
+
+/* Finds iterator for STMT. */
+
+gimple_stmt_iterator
+gsi_for_stmt (gimple stmt)
+{
+ gimple_stmt_iterator i;
+ basic_block bb = gimple_bb (stmt);
+
+ if (gimple_code (stmt) == GIMPLE_PHI)
+ i = gsi_start_phis (bb);
+ else
+ i = gsi_start_bb (bb);
+
+ for (; !gsi_end_p (i); gsi_next (&i))
+ if (gsi_stmt (i) == stmt)
+ return i;
+
+ gcc_unreachable ();
+}
+
+
+/* Move the statement at FROM so it comes right after the statement at TO. */
+
+void
+gsi_move_after (gimple_stmt_iterator *from, gimple_stmt_iterator *to)
+{
+ gimple stmt = gsi_stmt (*from);
+ gsi_remove (from, false);
+
+ /* We must have GSI_NEW_STMT here, as gsi_move_after is sometimes used to
+ move statements to an empty block. */
+ gsi_insert_after (to, stmt, GSI_NEW_STMT);
+}
+
+
+/* Move the statement at FROM so it comes right before the statement
+ at TO. */
+
+void
+gsi_move_before (gimple_stmt_iterator *from, gimple_stmt_iterator *to)
+{
+ gimple stmt = gsi_stmt (*from);
+ gsi_remove (from, false);
+
+ /* For consistency with gsi_move_after, it might be better to have
+ GSI_NEW_STMT here; however, that breaks several places that expect
+ that TO does not change. */
+ gsi_insert_before (to, stmt, GSI_SAME_STMT);
+}
+
+
+/* Move the statement at FROM to the end of basic block BB. */
+
+void
+gsi_move_to_bb_end (gimple_stmt_iterator *from, basic_block bb)
+{
+ gimple_stmt_iterator last = gsi_last_bb (bb);
+#ifdef ENABLE_CHECKING
+ gcc_assert (gsi_bb (last) == bb);
+#endif
+
+ /* Have to check gsi_end_p because it could be an empty block. */
+ if (!gsi_end_p (last) && is_ctrl_stmt (gsi_stmt (last)))
+ gsi_move_before (from, &last);
+ else
+ gsi_move_after (from, &last);
+}
+
+
+/* Add STMT to the pending list of edge E. No actual insertion is
+ made until a call to gsi_commit_edge_inserts () is made. */
+
+void
+gsi_insert_on_edge (edge e, gimple stmt)
+{
+ gimple_seq_add_stmt (&PENDING_STMT (e), stmt);
+}
+
+/* Add the sequence of statements SEQ to the pending list of edge E.
+ No actual insertion is made until a call to gsi_commit_edge_inserts
+ is made. */
+
+void
+gsi_insert_seq_on_edge (edge e, gimple_seq seq)
+{
+ gimple_seq_add_seq (&PENDING_STMT (e), seq);
+}
+
+
+/* Insert the statement pointed-to by GSI into edge E. Every attempt
+ is made to place the statement in an existing basic block, but
+ sometimes that isn't possible. When it isn't possible, the edge is
+ split and the statement is added to the new block.
+
+ In all cases, the returned *GSI points to the correct location. The
+ return value is true if insertion should be done after the location,
+ or false if it should be done before the location. If new basic block
+ has to be created, it is stored in *NEW_BB. */
+
+static bool
+gimple_find_edge_insert_loc (edge e, gimple_stmt_iterator *gsi,
+ basic_block *new_bb)
+{
+ basic_block dest, src;
+ gimple tmp;
+
+ dest = e->dest;
+
+ /* If the destination has one predecessor which has no PHI nodes,
+ insert there. Except for the exit block.
+
+ The requirement for no PHI nodes could be relaxed. Basically we
+ would have to examine the PHIs to prove that none of them used
+ the value set by the statement we want to insert on E. That
+ hardly seems worth the effort. */
+restart:
+ if (single_pred_p (dest)
+ && ! phi_nodes (dest)
+ && dest != EXIT_BLOCK_PTR)
+ {
+ *gsi = gsi_start_bb (dest);
+ if (gsi_end_p (*gsi))
+ return true;
+
+ /* Make sure we insert after any leading labels. */
+ tmp = gsi_stmt (*gsi);
+ while (gimple_code (tmp) == GIMPLE_LABEL)
+ {
+ gsi_next (gsi);
+ if (gsi_end_p (*gsi))
+ break;
+ tmp = gsi_stmt (*gsi);
+ }
+
+ if (gsi_end_p (*gsi))
+ {
+ *gsi = gsi_last_bb (dest);
+ return true;
+ }
+ else
+ return false;
+ }
+
+ /* If the source has one successor, the edge is not abnormal and
+ the last statement does not end a basic block, insert there.
+ Except for the entry block. */
+ src = e->src;
+ if ((e->flags & EDGE_ABNORMAL) == 0
+ && single_succ_p (src)
+ && src != ENTRY_BLOCK_PTR)
+ {
+ *gsi = gsi_last_bb (src);
+ if (gsi_end_p (*gsi))
+ return true;
+
+ tmp = gsi_stmt (*gsi);
+ if (!stmt_ends_bb_p (tmp))
+ return true;
+
+ if (gimple_code (tmp) == GIMPLE_RETURN)
+ {
+ gsi_prev (gsi);
+ return true;
+ }
+ }
+
+ /* Otherwise, create a new basic block, and split this edge. */
+ dest = split_edge (e);
+ if (new_bb)
+ *new_bb = dest;
+ e = single_pred_edge (dest);
+ goto restart;
+}
+
+
+/* Similar to gsi_insert_on_edge+gsi_commit_edge_inserts. If a new
+ block has to be created, it is returned. */
+
+basic_block
+gsi_insert_on_edge_immediate (edge e, gimple stmt)
+{
+ gimple_stmt_iterator gsi;
+ basic_block new_bb = NULL;
+
+ gcc_assert (!PENDING_STMT (e));
+
+ if (gimple_find_edge_insert_loc (e, &gsi, &new_bb))
+ gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
+ else
+ gsi_insert_before (&gsi, stmt, GSI_NEW_STMT);
+
+ return new_bb;
+}
+
+/* Insert STMTS on edge E. If a new block has to be created, it
+ is returned. */
+
+basic_block
+gsi_insert_seq_on_edge_immediate (edge e, gimple_seq stmts)
+{
+ gimple_stmt_iterator gsi;
+ basic_block new_bb = NULL;
+
+ gcc_assert (!PENDING_STMT (e));
+
+ if (gimple_find_edge_insert_loc (e, &gsi, &new_bb))
+ gsi_insert_seq_after (&gsi, stmts, GSI_NEW_STMT);
+ else
+ gsi_insert_seq_before (&gsi, stmts, GSI_NEW_STMT);
+
+ return new_bb;
+}
+
+/* This routine will commit all pending edge insertions, creating any new
+ basic blocks which are necessary. */
+
+void
+gsi_commit_edge_inserts (void)
+{
+ basic_block bb;
+ edge e;
+ edge_iterator ei;
+
+ gsi_commit_one_edge_insert (single_succ_edge (ENTRY_BLOCK_PTR), NULL);
+
+ FOR_EACH_BB (bb)
+ FOR_EACH_EDGE (e, ei, bb->succs)
+ gsi_commit_one_edge_insert (e, NULL);
+}
+
+
+/* Commit insertions pending at edge E. If a new block is created, set NEW_BB
+ to this block, otherwise set it to NULL. */
+
+void
+gsi_commit_one_edge_insert (edge e, basic_block *new_bb)
+{
+ if (new_bb)
+ *new_bb = NULL;
+
+ if (PENDING_STMT (e))
+ {
+ gimple_stmt_iterator gsi;
+ gimple_seq seq = PENDING_STMT (e);
+
+ PENDING_STMT (e) = NULL;
+
+ if (gimple_find_edge_insert_loc (e, &gsi, new_bb))
+ gsi_insert_seq_after (&gsi, seq, GSI_NEW_STMT);
+ else
+ gsi_insert_seq_before (&gsi, seq, GSI_NEW_STMT);
+ }
+}
+
+/* Returns iterator at the start of the list of phi nodes of BB. */
+
+gimple_stmt_iterator
+gsi_start_phis (basic_block bb)
+{
+ return gsi_start (phi_nodes (bb));
+}
diff --git a/gcc/gimple-low.c b/gcc/gimple-low.c
index 99175d5b2f1..cc77874b849 100644
--- a/gcc/gimple-low.c
+++ b/gcc/gimple-low.c
@@ -1,4 +1,4 @@
-/* Tree lowering pass. Lowers GIMPLE into unstructured form.
+/* GIMPLE lowering pass. Converts High GIMPLE into Low GIMPLE.
Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
@@ -25,7 +25,8 @@ along with GCC; see the file COPYING3. If not see
#include "tree.h"
#include "rtl.h"
#include "varray.h"
-#include "tree-gimple.h"
+#include "gimple.h"
+#include "tree-iterator.h"
#include "tree-inline.h"
#include "diagnostic.h"
#include "langhooks.h"
@@ -40,76 +41,123 @@ along with GCC; see the file COPYING3. If not see
#include "toplev.h"
#include "tree-pass.h"
+/* The differences between High GIMPLE and Low GIMPLE are the
+ following:
+
+ 1- Lexical scopes are removed (i.e., GIMPLE_BIND disappears).
+
+ 2- GIMPLE_TRY and GIMPLE_CATCH are converted to abnormal control
+ flow and exception regions are built as an on-the-side region
+ hierarchy (See tree-eh.c:lower_eh_constructs).
+
+ 3- Multiple identical return statements are grouped into a single
+ return and gotos to the unique return site. */
+
+/* Match a return statement with a label. During lowering, we identify
+ identical return statements and replace duplicates with a jump to
+ the corresponding label. */
+struct return_statements_t
+{
+ tree label;
+ gimple stmt;
+};
+typedef struct return_statements_t return_statements_t;
+
+DEF_VEC_O(return_statements_t);
+DEF_VEC_ALLOC_O(return_statements_t,heap);
+
struct lower_data
{
/* Block the current statement belongs to. */
tree block;
- /* A TREE_LIST of label and return statements to be moved to the end
+ /* A vector of label and return statements to be moved to the end
of the function. */
- tree return_statements;
+ VEC(return_statements_t,heap) *return_statements;
/* True if the function calls __builtin_setjmp. */
bool calls_builtin_setjmp;
};
-static void lower_stmt (tree_stmt_iterator *, struct lower_data *);
-static void lower_bind_expr (tree_stmt_iterator *, struct lower_data *);
-static void lower_cond_expr (tree_stmt_iterator *, struct lower_data *);
-static void lower_return_expr (tree_stmt_iterator *, struct lower_data *);
-static void lower_builtin_setjmp (tree_stmt_iterator *);
+static void lower_stmt (gimple_stmt_iterator *, struct lower_data *);
+static void lower_gimple_bind (gimple_stmt_iterator *, struct lower_data *);
+static void lower_gimple_return (gimple_stmt_iterator *, struct lower_data *);
+static void lower_builtin_setjmp (gimple_stmt_iterator *);
-/* Lower the body of current_function_decl. */
+
+/* Lower the body of current_function_decl from High GIMPLE into Low
+ GIMPLE. */
static unsigned int
lower_function_body (void)
{
struct lower_data data;
- tree *body_p = &DECL_SAVED_TREE (current_function_decl);
- tree bind = *body_p;
- tree_stmt_iterator i;
- tree t, x;
-
- gcc_assert (TREE_CODE (bind) == BIND_EXPR);
+ gimple_seq body = gimple_body (current_function_decl);
+ gimple_seq lowered_body;
+ gimple_stmt_iterator i;
+ gimple bind;
+ tree t;
+ gimple x;
+
+ /* The gimplifier should've left a body of exactly one statement,
+ namely a GIMPLE_BIND. */
+ gcc_assert (gimple_seq_first (body) == gimple_seq_last (body)
+ && gimple_code (gimple_seq_first_stmt (body)) == GIMPLE_BIND);
memset (&data, 0, sizeof (data));
data.block = DECL_INITIAL (current_function_decl);
BLOCK_SUBBLOCKS (data.block) = NULL_TREE;
BLOCK_CHAIN (data.block) = NULL_TREE;
TREE_ASM_WRITTEN (data.block) = 1;
+ data.return_statements = VEC_alloc (return_statements_t, heap, 8);
+
+ bind = gimple_seq_first_stmt (body);
+ lowered_body = NULL;
+ gimple_seq_add_stmt (&lowered_body, bind);
+ i = gsi_start (lowered_body);
+ lower_gimple_bind (&i, &data);
- *body_p = alloc_stmt_list ();
- i = tsi_start (*body_p);
- tsi_link_after (&i, bind, TSI_NEW_STMT);
- lower_bind_expr (&i, &data);
+ /* Once the old body has been lowered, replace it with the new
+ lowered sequence. */
+ gimple_set_body (current_function_decl, lowered_body);
- i = tsi_last (*body_p);
+ i = gsi_last (lowered_body);
/* If the function falls off the end, we need a null return statement.
- If we've already got one in the return_statements list, we don't
+ If we've already got one in the return_statements vector, we don't
need to do anything special. Otherwise build one by hand. */
- if (block_may_fallthru (*body_p)
- && (data.return_statements == NULL
- || TREE_OPERAND (TREE_VALUE (data.return_statements), 0) != NULL))
+ if (gimple_seq_may_fallthru (lowered_body)
+ && (VEC_empty (return_statements_t, data.return_statements)
+ || gimple_return_retval (VEC_last (return_statements_t,
+ data.return_statements)->stmt) != NULL))
{
- x = build1 (RETURN_EXPR, void_type_node, NULL);
- SET_EXPR_LOCATION (x, cfun->function_end_locus);
- tsi_link_after (&i, x, TSI_CONTINUE_LINKING);
+ x = gimple_build_return (NULL);
+ gimple_set_location (x, cfun->function_end_locus);
+ gsi_insert_after (&i, x, GSI_CONTINUE_LINKING);
}
/* If we lowered any return statements, emit the representative
at the end of the function. */
- for (t = data.return_statements ; t ; t = TREE_CHAIN (t))
+ while (!VEC_empty (return_statements_t, data.return_statements))
{
- x = build1 (LABEL_EXPR, void_type_node, TREE_PURPOSE (t));
- tsi_link_after (&i, x, TSI_CONTINUE_LINKING);
+ return_statements_t t;
+
+ /* Unfortunately, we can't use VEC_pop because it returns void for
+ objects. */
+ t = *VEC_last (return_statements_t, data.return_statements);
+ VEC_truncate (return_statements_t,
+ data.return_statements,
+ VEC_length (return_statements_t,
+ data.return_statements) - 1);
+
+ x = gimple_build_label (t.label);
+ gsi_insert_after (&i, x, GSI_CONTINUE_LINKING);
/* Remove the line number from the representative return statement.
It now fills in for many such returns. Failure to remove this
will result in incorrect results for coverage analysis. */
- x = TREE_VALUE (t);
- SET_EXPR_LOCATION (x, UNKNOWN_LOCATION);
- tsi_link_after (&i, x, TSI_CONTINUE_LINKING);
+ gimple_set_location (t.stmt, UNKNOWN_LOCATION);
+ gsi_insert_after (&i, t.stmt, GSI_CONTINUE_LINKING);
}
/* If the function calls __builtin_setjmp, we need to emit the computed
@@ -123,21 +171,21 @@ lower_function_body (void)
/* This mark will create forward edges from every call site. */
DECL_NONLOCAL (disp_label) = 1;
cfun->has_nonlocal_label = 1;
- x = build1 (LABEL_EXPR, void_type_node, disp_label);
- tsi_link_after (&i, x, TSI_CONTINUE_LINKING);
+ x = gimple_build_label (disp_label);
+ gsi_insert_after (&i, x, GSI_CONTINUE_LINKING);
/* Build 'DISP_VAR = __builtin_setjmp_dispatcher (DISP_LABEL);'
and insert. */
disp_var = create_tmp_var (ptr_type_node, "setjmpvar");
arg = build_addr (disp_label, current_function_decl);
t = implicit_built_in_decls[BUILT_IN_SETJMP_DISPATCHER];
- t = build_call_expr (t, 1, arg);
- x = build_gimple_modify_stmt (disp_var, t);
+ x = gimple_build_call (t, 1, arg);
+ gimple_call_set_lhs (x, disp_var);
/* Build 'goto DISP_VAR;' and insert. */
- tsi_link_after (&i, x, TSI_CONTINUE_LINKING);
- x = build1 (GOTO_EXPR, void_type_node, disp_var);
- tsi_link_after (&i, x, TSI_CONTINUE_LINKING);
+ gsi_insert_after (&i, x, GSI_CONTINUE_LINKING);
+ x = gimple_build_goto (disp_var);
+ gsi_insert_after (&i, x, GSI_CONTINUE_LINKING);
}
gcc_assert (data.block == DECL_INITIAL (current_function_decl));
@@ -145,6 +193,7 @@ lower_function_body (void)
= blocks_nreverse (BLOCK_SUBBLOCKS (data.block));
clear_block_marks (data.block);
+ VEC_free(return_statements_t, heap, data.return_statements);
return 0;
}
@@ -168,134 +217,131 @@ struct gimple_opt_pass pass_lower_cf =
};
-/* Lower the EXPR. Unlike gimplification the statements are not relowered
+/* Lower sequence SEQ. Unlike gimplification the statements are not relowered
when they are changed -- if this has to be done, the lowering routine must
do it explicitly. DATA is passed through the recursion. */
static void
-lower_stmt_body (tree expr, struct lower_data *data)
+lower_sequence (gimple_seq seq, struct lower_data *data)
{
- tree_stmt_iterator tsi;
+ gimple_stmt_iterator gsi;
- for (tsi = tsi_start (expr); !tsi_end_p (tsi); )
- lower_stmt (&tsi, data);
+ for (gsi = gsi_start (seq); !gsi_end_p (gsi); )
+ lower_stmt (&gsi, data);
}
-/* Lower the OpenMP directive statement pointed by TSI. DATA is
+/* Lower the OpenMP directive statement pointed by GSI. DATA is
passed through the recursion. */
static void
-lower_omp_directive (tree_stmt_iterator *tsi, struct lower_data *data)
+lower_omp_directive (gimple_stmt_iterator *gsi, struct lower_data *data)
{
- tree stmt;
+ gimple stmt;
- stmt = tsi_stmt (*tsi);
+ stmt = gsi_stmt (*gsi);
- lower_stmt_body (OMP_BODY (stmt), data);
- tsi_link_before (tsi, stmt, TSI_SAME_STMT);
- tsi_link_before (tsi, OMP_BODY (stmt), TSI_SAME_STMT);
- OMP_BODY (stmt) = NULL_TREE;
- tsi_delink (tsi);
+ lower_sequence (gimple_omp_body (stmt), data);
+ gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
+ gsi_insert_seq_before (gsi, gimple_omp_body (stmt), GSI_SAME_STMT);
+ gimple_omp_set_body (stmt, NULL);
+ gsi_remove (gsi, false);
}
-/* Lower statement TSI. DATA is passed through the recursion. */
+/* Lower statement GSI. DATA is passed through the recursion. */
static void
-lower_stmt (tree_stmt_iterator *tsi, struct lower_data *data)
+lower_stmt (gimple_stmt_iterator *gsi, struct lower_data *data)
{
- tree stmt = tsi_stmt (*tsi);
+ gimple stmt = gsi_stmt (*gsi);
- if (EXPR_HAS_LOCATION (stmt) && data)
- TREE_BLOCK (stmt) = data->block;
+ gimple_set_block (stmt, data->block);
- switch (TREE_CODE (stmt))
+ switch (gimple_code (stmt))
{
- case BIND_EXPR:
- lower_bind_expr (tsi, data);
- return;
- case COND_EXPR:
- lower_cond_expr (tsi, data);
- return;
- case RETURN_EXPR:
- lower_return_expr (tsi, data);
+ case GIMPLE_BIND:
+ lower_gimple_bind (gsi, data);
return;
- case TRY_FINALLY_EXPR:
- case TRY_CATCH_EXPR:
- lower_stmt_body (TREE_OPERAND (stmt, 0), data);
- lower_stmt_body (TREE_OPERAND (stmt, 1), data);
+ case GIMPLE_COND:
+ /* The gimplifier has already lowered this into gotos. */
break;
- case CATCH_EXPR:
- lower_stmt_body (CATCH_BODY (stmt), data);
+
+ case GIMPLE_RETURN:
+ lower_gimple_return (gsi, data);
+ return;
+
+ case GIMPLE_TRY:
+ lower_sequence (gimple_try_eval (stmt), data);
+ lower_sequence (gimple_try_cleanup (stmt), data);
break;
- case EH_FILTER_EXPR:
- lower_stmt_body (EH_FILTER_FAILURE (stmt), data);
+
+ case GIMPLE_CATCH:
+ lower_sequence (gimple_catch_handler (stmt), data);
break;
-
- case NOP_EXPR:
- case ASM_EXPR:
- case GOTO_EXPR:
- case PREDICT_EXPR:
- case LABEL_EXPR:
- case SWITCH_EXPR:
- case CHANGE_DYNAMIC_TYPE_EXPR:
- case OMP_FOR:
- case OMP_SECTIONS:
- case OMP_SECTIONS_SWITCH:
- case OMP_SECTION:
- case OMP_SINGLE:
- case OMP_MASTER:
- case OMP_ORDERED:
- case OMP_CRITICAL:
- case OMP_RETURN:
- case OMP_ATOMIC_LOAD:
- case OMP_ATOMIC_STORE:
- case OMP_CONTINUE:
+
+ case GIMPLE_EH_FILTER:
+ lower_sequence (gimple_eh_filter_failure (stmt), data);
break;
- case GIMPLE_MODIFY_STMT:
- if (TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 1)) == CALL_EXPR)
- stmt = GIMPLE_STMT_OPERAND (stmt, 1);
- else
- break;
- /* FALLTHRU */
+ case GIMPLE_NOP:
+ case GIMPLE_ASM:
+ case GIMPLE_ASSIGN:
+ case GIMPLE_GOTO:
+ case GIMPLE_PREDICT:
+ case GIMPLE_LABEL:
+ case GIMPLE_SWITCH:
+ case GIMPLE_CHANGE_DYNAMIC_TYPE:
+ case GIMPLE_OMP_FOR:
+ case GIMPLE_OMP_SECTIONS:
+ case GIMPLE_OMP_SECTIONS_SWITCH:
+ case GIMPLE_OMP_SECTION:
+ case GIMPLE_OMP_SINGLE:
+ case GIMPLE_OMP_MASTER:
+ case GIMPLE_OMP_ORDERED:
+ case GIMPLE_OMP_CRITICAL:
+ case GIMPLE_OMP_RETURN:
+ case GIMPLE_OMP_ATOMIC_LOAD:
+ case GIMPLE_OMP_ATOMIC_STORE:
+ case GIMPLE_OMP_CONTINUE:
+ break;
- case CALL_EXPR:
+ case GIMPLE_CALL:
{
- tree decl = get_callee_fndecl (stmt);
+ tree decl = gimple_call_fndecl (stmt);
+
if (decl
&& DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL
&& DECL_FUNCTION_CODE (decl) == BUILT_IN_SETJMP)
{
data->calls_builtin_setjmp = true;
- lower_builtin_setjmp (tsi);
+ lower_builtin_setjmp (gsi);
return;
}
}
break;
- case OMP_PARALLEL:
- case OMP_TASK:
- lower_omp_directive (tsi, data);
+ case GIMPLE_OMP_PARALLEL:
+ case GIMPLE_OMP_TASK:
+ lower_omp_directive (gsi, data);
return;
default:
gcc_unreachable ();
}
- tsi_next (tsi);
+ gsi_next (gsi);
}
/* Lower a bind_expr TSI. DATA is passed through the recursion. */
static void
-lower_bind_expr (tree_stmt_iterator *tsi, struct lower_data *data)
+lower_gimple_bind (gimple_stmt_iterator *gsi, struct lower_data *data)
{
tree old_block = data->block;
- tree stmt = tsi_stmt (*tsi);
- tree new_block = BIND_EXPR_BLOCK (stmt);
+ gimple stmt = gsi_stmt (*gsi);
+ tree new_block = gimple_bind_block (stmt);
if (new_block)
{
@@ -325,8 +371,8 @@ lower_bind_expr (tree_stmt_iterator *tsi, struct lower_data *data)
}
}
- record_vars (BIND_EXPR_VARS (stmt));
- lower_stmt_body (BIND_EXPR_BODY (stmt), data);
+ record_vars (gimple_bind_vars (stmt));
+ lower_sequence (gimple_bind_body (stmt), data);
if (new_block)
{
@@ -337,9 +383,9 @@ lower_bind_expr (tree_stmt_iterator *tsi, struct lower_data *data)
data->block = old_block;
}
- /* The BIND_EXPR no longer carries any useful information -- kill it. */
- tsi_link_before (tsi, BIND_EXPR_BODY (stmt), TSI_SAME_STMT);
- tsi_delink (tsi);
+ /* The GIMPLE_BIND no longer carries any useful information -- kill it. */
+ gsi_insert_seq_before (gsi, gimple_bind_body (stmt), GSI_SAME_STMT);
+ gsi_remove (gsi, false);
}
/* Try to determine whether a TRY_CATCH expression can fall through.
@@ -390,6 +436,58 @@ try_catch_may_fallthru (const_tree stmt)
}
}
+
+/* Same as above, but for a GIMPLE_TRY_CATCH. */
+
+static bool
+gimple_try_catch_may_fallthru (gimple stmt)
+{
+ gimple_stmt_iterator i;
+
+ /* We don't handle GIMPLE_TRY_FINALLY. */
+ gcc_assert (gimple_try_kind (stmt) == GIMPLE_TRY_CATCH);
+
+ /* If the TRY block can fall through, the whole TRY_CATCH can
+ fall through. */
+ if (gimple_seq_may_fallthru (gimple_try_eval (stmt)))
+ return true;
+
+ i = gsi_start (gimple_try_cleanup (stmt));
+ switch (gimple_code (gsi_stmt (i)))
+ {
+ case GIMPLE_CATCH:
+ /* We expect to see a sequence of GIMPLE_CATCH stmts, each with a
+ catch expression and a body. The whole try/catch may fall
+ through iff any of the catch bodies falls through. */
+ for (; !gsi_end_p (i); gsi_next (&i))
+ {
+ if (gimple_seq_may_fallthru (gimple_catch_handler (gsi_stmt (i))))
+ return true;
+ }
+ return false;
+
+ case GIMPLE_EH_FILTER:
+ /* The exception filter expression only matters if there is an
+ exception. If the exception does not match EH_FILTER_TYPES,
+ we will execute EH_FILTER_FAILURE, and we will fall through
+ if that falls through. If the exception does match
+ EH_FILTER_TYPES, the stack unwinder will continue up the
+ stack, so we will not fall through. We don't know whether we
+ will throw an exception which matches EH_FILTER_TYPES or not,
+ so we just ignore EH_FILTER_TYPES and assume that we might
+ throw an exception which doesn't match. */
+ return gimple_seq_may_fallthru (gimple_eh_filter_failure (gsi_stmt (i)));
+
+ default:
+ /* This case represents statements to be executed when an
+ exception occurs. Those statements are implicitly followed
+ by a GIMPLE_RESX to resume execution after the exception. So
+ in this case the try/catch never falls through. */
+ return false;
+ }
+}
+
+
/* Try to determine if we can fall out of the bottom of BLOCK. This guess
need not be 100% accurate; simply be conservative and return true if we
don't know. This is used only to avoid stupidly generating extra code.
@@ -440,9 +538,9 @@ block_may_fallthru (const_tree block)
return (block_may_fallthru (TREE_OPERAND (stmt, 0))
&& block_may_fallthru (TREE_OPERAND (stmt, 1)));
- case GIMPLE_MODIFY_STMT:
- if (TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 1)) == CALL_EXPR)
- stmt = GIMPLE_STMT_OPERAND (stmt, 1);
+ case MODIFY_EXPR:
+ if (TREE_CODE (TREE_OPERAND (stmt, 1)) == CALL_EXPR)
+ stmt = TREE_OPERAND (stmt, 1);
else
return true;
/* FALLTHRU */
@@ -459,138 +557,110 @@ block_may_fallthru (const_tree block)
}
}
-/* Lower a cond_expr TSI. DATA is passed through the recursion. */
-static void
-lower_cond_expr (tree_stmt_iterator *tsi, struct lower_data *data)
+/* Try to determine if we can continue executing the statement
+ immediately following STMT. This guess need not be 100% accurate;
+ simply be conservative and return true if we don't know. This is
+ used only to avoid stupidly generating extra code. If we're wrong,
+ we'll just delete the extra code later. */
+
+bool
+gimple_stmt_may_fallthru (gimple stmt)
{
- tree stmt = tsi_stmt (*tsi);
- bool then_is_goto, else_is_goto;
- tree then_branch, else_branch;
- tree then_goto, else_goto;
-
- then_branch = COND_EXPR_THEN (stmt);
- else_branch = COND_EXPR_ELSE (stmt);
+ if (!stmt)
+ return true;
- lower_stmt_body (then_branch, data);
- lower_stmt_body (else_branch, data);
+ switch (gimple_code (stmt))
+ {
+ case GIMPLE_GOTO:
+ case GIMPLE_RETURN:
+ case GIMPLE_RESX:
+ /* Easy cases. If the last statement of the seq implies
+ control transfer, then we can't fall through. */
+ return false;
- then_goto = expr_only (then_branch);
- then_is_goto = then_goto && simple_goto_p (then_goto);
+ case GIMPLE_SWITCH:
+ /* Switch has already been lowered and represents a
+ branch to a selected label and hence can not fall through. */
+ return true;
- else_goto = expr_only (else_branch);
- else_is_goto = else_goto && simple_goto_p (else_goto);
+ case GIMPLE_COND:
+ /* GIMPLE_COND's are already lowered into a two-way branch. They
+ can't fall through. */
+ return false;
- if (!then_is_goto || !else_is_goto)
- {
- tree then_label, else_label, end_label, t;
-
- then_label = NULL_TREE;
- else_label = NULL_TREE;
- end_label = NULL_TREE;
-
- /* Replace the cond_expr with explicit gotos. */
- if (!then_is_goto)
- {
- t = build1 (LABEL_EXPR, void_type_node, NULL_TREE);
- if (TREE_SIDE_EFFECTS (then_branch))
- then_label = t;
- else
- end_label = t;
- then_goto = build_and_jump (&LABEL_EXPR_LABEL (t));
- }
+ case GIMPLE_BIND:
+ return gimple_seq_may_fallthru (gimple_bind_body (stmt));
- if (!else_is_goto)
- {
- t = build1 (LABEL_EXPR, void_type_node, NULL_TREE);
- if (TREE_SIDE_EFFECTS (else_branch))
- else_label = t;
- else
- {
- /* Both THEN and ELSE can be no-ops if one or both contained an
- empty BIND_EXPR that was associated with the toplevel block
- of an inlined function. In that case remove_useless_stmts
- can't have cleaned things up for us; kill the whole
- conditional now. */
- if (end_label)
- {
- tsi_delink (tsi);
- return;
- }
- else
- end_label = t;
- }
- else_goto = build_and_jump (&LABEL_EXPR_LABEL (t));
- }
+ case GIMPLE_TRY:
+ if (gimple_try_kind (stmt) == GIMPLE_TRY_CATCH)
+ return gimple_try_catch_may_fallthru (stmt);
- if (then_label)
- {
- bool may_fallthru = block_may_fallthru (then_branch);
+ /* It must be a GIMPLE_TRY_FINALLY. */
- tsi_link_after (tsi, then_label, TSI_CONTINUE_LINKING);
- tsi_link_after (tsi, then_branch, TSI_CONTINUE_LINKING);
-
- if (else_label && may_fallthru)
- {
- end_label = build1 (LABEL_EXPR, void_type_node, NULL_TREE);
- t = build_and_jump (&LABEL_EXPR_LABEL (end_label));
- tsi_link_after (tsi, t, TSI_CONTINUE_LINKING);
- }
- }
-
- if (else_label)
- {
- tsi_link_after (tsi, else_label, TSI_CONTINUE_LINKING);
- tsi_link_after (tsi, else_branch, TSI_CONTINUE_LINKING);
- }
+ /* The finally clause is always executed after the try clause,
+ so if it does not fall through, then the try-finally will not
+ fall through. Otherwise, if the try clause does not fall
+ through, then when the finally clause falls through it will
+ resume execution wherever the try clause was going. So the
+ whole try-finally will only fall through if both the try
+ clause and the finally clause fall through. */
+ return (gimple_seq_may_fallthru (gimple_try_eval (stmt))
+ && gimple_seq_may_fallthru (gimple_try_cleanup (stmt)));
+
+ case GIMPLE_ASSIGN:
+ return true;
- if (end_label)
- tsi_link_after (tsi, end_label, TSI_CONTINUE_LINKING);
+ case GIMPLE_CALL:
+ /* Functions that do not return do not fall through. */
+ return (gimple_call_flags (stmt) & ECF_NORETURN) == 0;
+
+ default:
+ return true;
}
+}
+
- COND_EXPR_THEN (stmt) = then_goto;
- COND_EXPR_ELSE (stmt) = else_goto;
+/* Same as gimple_stmt_may_fallthru, but for the gimple sequence SEQ. */
- tsi_next (tsi);
+bool
+gimple_seq_may_fallthru (gimple_seq seq)
+{
+ return gimple_stmt_may_fallthru (gimple_seq_last_stmt (seq));
}
-/* Lower a return_expr TSI. DATA is passed through the recursion. */
+
+/* Lower a GIMPLE_RETURN GSI. DATA is passed through the recursion. */
static void
-lower_return_expr (tree_stmt_iterator *tsi, struct lower_data *data)
+lower_gimple_return (gimple_stmt_iterator *gsi, struct lower_data *data)
{
- tree stmt = tsi_stmt (*tsi);
- tree value, t, label;
-
- /* Extract the value being returned. */
- value = TREE_OPERAND (stmt, 0);
- if (value && TREE_CODE (value) == GIMPLE_MODIFY_STMT)
- value = GIMPLE_STMT_OPERAND (value, 1);
+ gimple stmt = gsi_stmt (*gsi);
+ gimple t;
+ int i;
+ return_statements_t tmp_rs;
/* Match this up with an existing return statement that's been created. */
- for (t = data->return_statements; t ; t = TREE_CHAIN (t))
+ for (i = VEC_length (return_statements_t, data->return_statements) - 1;
+ i >= 0; i--)
{
- tree tvalue = TREE_OPERAND (TREE_VALUE (t), 0);
- if (tvalue && TREE_CODE (tvalue) == GIMPLE_MODIFY_STMT)
- tvalue = GIMPLE_STMT_OPERAND (tvalue, 1);
+ tmp_rs = *VEC_index (return_statements_t, data->return_statements, i);
- if (value == tvalue)
- {
- label = TREE_PURPOSE (t);
- goto found;
- }
+ if (gimple_return_retval (stmt) == gimple_return_retval (tmp_rs.stmt))
+ goto found;
}
/* Not found. Create a new label and record the return statement. */
- label = create_artificial_label ();
- data->return_statements = tree_cons (label, stmt, data->return_statements);
+ tmp_rs.label = create_artificial_label ();
+ tmp_rs.stmt = stmt;
+ VEC_safe_push (return_statements_t, heap, data->return_statements, &tmp_rs);
/* Generate a goto statement and remove the return statement. */
found:
- t = build1 (GOTO_EXPR, void_type_node, label);
- SET_EXPR_LOCUS (t, EXPR_LOCUS (stmt));
- tsi_link_before (tsi, t, TSI_SAME_STMT);
- tsi_delink (tsi);
+ t = gimple_build_goto (tmp_rs.label);
+ gimple_set_location (t, gimple_location (stmt));
+ gsi_insert_before (gsi, t, GSI_SAME_STMT);
+ gsi_remove (gsi, false);
}
/* Lower a __builtin_setjmp TSI.
@@ -647,71 +717,66 @@ lower_return_expr (tree_stmt_iterator *tsi, struct lower_data *data)
to the receivers, thus keeping the complexity explosion localized. */
static void
-lower_builtin_setjmp (tree_stmt_iterator *tsi)
+lower_builtin_setjmp (gimple_stmt_iterator *gsi)
{
- tree stmt = tsi_stmt (*tsi);
+ gimple stmt = gsi_stmt (*gsi);
tree cont_label = create_artificial_label ();
tree next_label = create_artificial_label ();
tree dest, t, arg;
+ gimple g;
/* NEXT_LABEL is the label __builtin_longjmp will jump to. Its address is
passed to both __builtin_setjmp_setup and __builtin_setjmp_receiver. */
FORCED_LABEL (next_label) = 1;
- if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT)
- {
- dest = GIMPLE_STMT_OPERAND (stmt, 0);
- stmt = GIMPLE_STMT_OPERAND (stmt, 1);
- }
- else
- dest = NULL_TREE;
+ dest = gimple_call_lhs (stmt);
/* Build '__builtin_setjmp_setup (BUF, NEXT_LABEL)' and insert. */
arg = build_addr (next_label, current_function_decl);
t = implicit_built_in_decls[BUILT_IN_SETJMP_SETUP];
- t = build_call_expr (t, 2, CALL_EXPR_ARG (stmt, 0), arg);
- SET_EXPR_LOCUS (t, EXPR_LOCUS (stmt));
- tsi_link_before (tsi, t, TSI_SAME_STMT);
+ g = gimple_build_call (t, 2, gimple_call_arg (stmt, 0), arg);
+ gimple_set_location (g, gimple_location (stmt));
+ gsi_insert_before (gsi, g, GSI_SAME_STMT);
/* Build 'DEST = 0' and insert. */
if (dest)
{
- t = build_gimple_modify_stmt (dest, fold_convert (TREE_TYPE (dest),
- integer_zero_node));
- SET_EXPR_LOCUS (t, EXPR_LOCUS (stmt));
- tsi_link_before (tsi, t, TSI_SAME_STMT);
+ g = gimple_build_assign (dest, fold_convert (TREE_TYPE (dest),
+ integer_zero_node));
+ gimple_set_location (g, gimple_location (stmt));
+ gsi_insert_before (gsi, g, GSI_SAME_STMT);
}
/* Build 'goto CONT_LABEL' and insert. */
- t = build1 (GOTO_EXPR, void_type_node, cont_label);
- tsi_link_before (tsi, t, TSI_SAME_STMT);
+ g = gimple_build_goto (cont_label);
+ gsi_insert_before (gsi, g, TSI_SAME_STMT);
/* Build 'NEXT_LABEL:' and insert. */
- t = build1 (LABEL_EXPR, void_type_node, next_label);
- tsi_link_before (tsi, t, TSI_SAME_STMT);
+ g = gimple_build_label (next_label);
+ gsi_insert_before (gsi, g, GSI_SAME_STMT);
/* Build '__builtin_setjmp_receiver (NEXT_LABEL)' and insert. */
arg = build_addr (next_label, current_function_decl);
t = implicit_built_in_decls[BUILT_IN_SETJMP_RECEIVER];
- t = build_call_expr (t, 1, arg);
- SET_EXPR_LOCUS (t, EXPR_LOCUS (stmt));
- tsi_link_before (tsi, t, TSI_SAME_STMT);
+ g = gimple_build_call (t, 1, arg);
+ gimple_set_location (g, gimple_location (stmt));
+ gsi_insert_before (gsi, g, GSI_SAME_STMT);
/* Build 'DEST = 1' and insert. */
if (dest)
{
- t = build_gimple_modify_stmt (dest, fold_convert (TREE_TYPE (dest),
- integer_one_node));
- SET_EXPR_LOCUS (t, EXPR_LOCUS (stmt));
- tsi_link_before (tsi, t, TSI_SAME_STMT);
+ g = gimple_build_assign (dest, fold_convert (TREE_TYPE (dest),
+ integer_one_node));
+ gimple_set_location (g, gimple_location (stmt));
+ gsi_insert_before (gsi, g, GSI_SAME_STMT);
}
/* Build 'CONT_LABEL:' and insert. */
- t = build1 (LABEL_EXPR, void_type_node, cont_label);
- tsi_link_before (tsi, t, TSI_SAME_STMT);
+ g = gimple_build_label (cont_label);
+ gsi_insert_before (gsi, g, GSI_SAME_STMT);
/* Remove the call to __builtin_setjmp. */
- tsi_delink (tsi);
+ gsi_remove (gsi, false);
}
diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c
new file mode 100644
index 00000000000..d334d856982
--- /dev/null
+++ b/gcc/gimple-pretty-print.c
@@ -0,0 +1,1857 @@
+/* Pretty formatting of GIMPLE statements and expressions.
+ Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
+ Free Software Foundation, Inc.
+ Contributed by Aldy Hernandez <aldyh@redhat.com> and
+ Diego Novillo <dnovillo@google.com>
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tree.h"
+#include "diagnostic.h"
+#include "real.h"
+#include "hashtab.h"
+#include "tree-flow.h"
+#include "tree-pass.h"
+#include "gimple.h"
+#include "value-prof.h"
+
+#define INDENT(SPACE) \
+ do { int i; for (i = 0; i < SPACE; i++) pp_space (buffer); } while (0)
+
+static pretty_printer buffer;
+static bool initialized = false;
+
+#define GIMPLE_NIY do_niy (buffer,gs)
+
+/* Try to print on BUFFER a default message for the unrecognized
+ gimple statement GS. */
+
+static void
+do_niy (pretty_printer *buffer, gimple gs)
+{
+ pp_printf (buffer, "<<< Unknown GIMPLE statement: %s >>>\n",
+ gimple_code_name[(int) gimple_code (gs)]);
+}
+
+
+/* Initialize the pretty printer on FILE if needed. */
+
+static void
+maybe_init_pretty_print (FILE *file)
+{
+ if (!initialized)
+ {
+ pp_construct (&buffer, NULL, 0);
+ pp_needs_newline (&buffer) = true;
+ initialized = true;
+ }
+
+ buffer.buffer->stream = file;
+}
+
+
+/* Emit a newline and SPC indentantion spaces to BUFFER. */
+
+static void
+newline_and_indent (pretty_printer *buffer, int spc)
+{
+ pp_newline (buffer);
+ INDENT (spc);
+}
+
+
+/* Print the GIMPLE statement GS on stderr. */
+
+void
+debug_gimple_stmt (gimple gs)
+{
+ print_gimple_stmt (stderr, gs, 0, TDF_VOPS|TDF_MEMSYMS);
+ fprintf (stderr, "\n");
+}
+
+
+/* Dump GIMPLE statement G to FILE using SPC indentantion spaces and
+ FLAGS as in dump_gimple_stmt. */
+
+void
+print_gimple_stmt (FILE *file, gimple g, int spc, int flags)
+{
+ maybe_init_pretty_print (file);
+ dump_gimple_stmt (&buffer, g, spc, flags);
+ pp_flush (&buffer);
+}
+
+
+/* Dump GIMPLE statement G to FILE using SPC indentantion spaces and
+ FLAGS as in dump_gimple_stmt. Print only the right-hand side
+ of the statement. */
+
+void
+print_gimple_expr (FILE *file, gimple g, int spc, int flags)
+{
+ flags |= TDF_RHS_ONLY;
+ maybe_init_pretty_print (file);
+ dump_gimple_stmt (&buffer, g, spc, flags);
+}
+
+
+/* Print the GIMPLE sequence SEQ on BUFFER using SPC indentantion
+ spaces and FLAGS as in dump_gimple_stmt. */
+
+static void
+dump_gimple_seq (pretty_printer *buffer, gimple_seq seq, int spc, int flags)
+{
+ gimple_stmt_iterator i;
+
+ for (i = gsi_start (seq); !gsi_end_p (i); gsi_next (&i))
+ {
+ gimple gs = gsi_stmt (i);
+ INDENT (spc);
+ dump_gimple_stmt (buffer, gs, spc, flags);
+ if (!gsi_one_before_end_p (i))
+ pp_newline (buffer);
+ }
+}
+
+
+/* Dump GIMPLE sequence SEQ to FILE using SPC indentantion spaces and
+ FLAGS as in dump_gimple_stmt. */
+
+void
+print_gimple_seq (FILE *file, gimple_seq seq, int spc, int flags)
+{
+ maybe_init_pretty_print (file);
+ dump_gimple_seq (&buffer, seq, spc, flags);
+ pp_flush (&buffer);
+}
+
+
+/* Print the GIMPLE sequence SEQ on stderr. */
+
+void
+debug_gimple_seq (gimple_seq seq)
+{
+ print_gimple_seq (stderr, seq, 0, TDF_VOPS|TDF_MEMSYMS);
+}
+
+
+/* A simple helper to pretty-print some of the gimple tuples in the printf
+ style. The format modifiers are preceeded by '%' and are:
+ 'G' - outputs a string corresponding to the code of the given gimple,
+ 'S' - outputs a gimple_seq with indent of spc + 2,
+ 'T' - outputs the tree t,
+ 'd' - outputs an int as a decimal,
+ 's' - outputs a string,
+ 'n' - outputs a newline,
+ '+' - increases indent by 2 then outputs a newline,
+ '-' - decreases indent by 2 then outputs a newline. */
+
+static void
+dump_gimple_fmt (pretty_printer *buffer, int spc, int flags,
+ const char *fmt, ...)
+{
+ va_list args;
+ const char *c;
+ const char *tmp;
+
+ va_start (args, fmt);
+ for (c = fmt; *c; c++)
+ {
+ if (*c == '%')
+ {
+ gimple_seq seq;
+ tree t;
+ gimple g;
+ switch (*++c)
+ {
+ case 'G':
+ g = va_arg (args, gimple);
+ tmp = gimple_code_name[gimple_code (g)];
+ pp_string (buffer, tmp);
+ break;
+
+ case 'S':
+ seq = va_arg (args, gimple_seq);
+ pp_newline (buffer);
+ dump_gimple_seq (buffer, seq, spc + 2, flags);
+ newline_and_indent (buffer, spc);
+ break;
+
+ case 'T':
+ t = va_arg (args, tree);
+ if (t == NULL_TREE)
+ pp_string (buffer, "NULL");
+ else
+ dump_generic_node (buffer, t, spc, flags, false);
+ break;
+
+ case 'd':
+ pp_decimal_int (buffer, va_arg (args, int));
+ break;
+
+ case 's':
+ pp_string (buffer, va_arg (args, char *));
+ break;
+
+ case 'n':
+ newline_and_indent (buffer, spc);
+ break;
+
+ case '+':
+ spc += 2;
+ newline_and_indent (buffer, spc);
+ break;
+
+ case '-':
+ spc -= 2;
+ newline_and_indent (buffer, spc);
+ break;
+
+ default:
+ gcc_unreachable ();
+ }
+ }
+ else
+ pp_character (buffer, *c);
+ }
+ va_end (args);
+}
+
+
+/* Helper for dump_gimple_assign. Print the unary RHS of the
+ assignment GS. BUFFER, SPC and FLAGS are as in dump_gimple_stmt. */
+
+static void
+dump_unary_rhs (pretty_printer *buffer, gimple gs, int spc, int flags)
+{
+ enum tree_code rhs_code = gimple_assign_rhs_code (gs);
+ tree lhs = gimple_assign_lhs (gs);
+ tree rhs = gimple_assign_rhs1 (gs);
+
+ switch (rhs_code)
+ {
+ case VIEW_CONVERT_EXPR:
+ case ASSERT_EXPR:
+ dump_generic_node (buffer, rhs, spc, flags, false);
+ break;
+
+ case FIXED_CONVERT_EXPR:
+ case FIX_TRUNC_EXPR:
+ case FLOAT_EXPR:
+ CASE_CONVERT:
+ pp_string (buffer, "(");
+ dump_generic_node (buffer, TREE_TYPE (lhs), spc, flags, false);
+ pp_string (buffer, ") ");
+ dump_generic_node (buffer, rhs, spc, flags, false);
+ break;
+
+ case PAREN_EXPR:
+ pp_string (buffer, "((");
+ dump_generic_node (buffer, rhs, spc, flags, false);
+ pp_string (buffer, "))");
+ break;
+
+ case ABS_EXPR:
+ pp_string (buffer, "ABS_EXPR <");
+ dump_generic_node (buffer, rhs, spc, flags, false);
+ pp_string (buffer, ">");
+ break;
+
+ default:
+ if (TREE_CODE_CLASS (rhs_code) == tcc_declaration
+ || TREE_CODE_CLASS (rhs_code) == tcc_constant
+ || TREE_CODE_CLASS (rhs_code) == tcc_reference
+ || rhs_code == SSA_NAME
+ || rhs_code == ADDR_EXPR
+ || rhs_code == CONSTRUCTOR)
+ ; /* do nothing. */
+ else if (rhs_code == BIT_NOT_EXPR)
+ pp_string (buffer, "~");
+ else if (rhs_code == TRUTH_NOT_EXPR)
+ pp_string (buffer, "!");
+ else if (rhs_code == NEGATE_EXPR)
+ pp_string (buffer, "-");
+ else
+ {
+ pp_string (buffer, "[");
+ pp_string (buffer, tree_code_name [rhs_code]);
+ pp_string (buffer, "] ");
+ }
+
+ dump_generic_node (buffer, rhs, spc, flags, false);
+ break;
+ }
+}
+
+
+/* Helper for dump_gimple_assign. Print the binary RHS of the
+ assignment GS. BUFFER, SPC and FLAGS are as in dump_gimple_stmt. */
+
+static void
+dump_binary_rhs (pretty_printer *buffer, gimple gs, int spc, int flags)
+{
+ switch (gimple_assign_rhs_code (gs))
+ {
+ case COMPLEX_EXPR:
+ pp_string (buffer, "COMPLEX_EXPR <");
+ dump_generic_node (buffer, gimple_assign_rhs1 (gs), spc, flags, false);
+ pp_string (buffer, ", ");
+ dump_generic_node (buffer, gimple_assign_rhs2 (gs), spc, flags, false);
+ pp_string (buffer, ">");
+ break;
+
+ case MIN_EXPR:
+ pp_string (buffer, "MIN_EXPR <");
+ dump_generic_node (buffer, gimple_assign_rhs1 (gs), spc, flags, false);
+ pp_string (buffer, ", ");
+ dump_generic_node (buffer, gimple_assign_rhs2 (gs), spc, flags, false);
+ pp_string (buffer, ">");
+ break;
+
+ case MAX_EXPR:
+ pp_string (buffer, "MAX_EXPR <");
+ dump_generic_node (buffer, gimple_assign_rhs1 (gs), spc, flags, false);
+ pp_string (buffer, ", ");
+ dump_generic_node (buffer, gimple_assign_rhs2 (gs), spc, flags, false);
+ pp_string (buffer, ">");
+ break;
+
+ default:
+ dump_generic_node (buffer, gimple_assign_rhs1 (gs), spc, flags, false);
+ pp_space (buffer);
+ pp_string (buffer, op_symbol_code (gimple_assign_rhs_code (gs)));
+ pp_space (buffer);
+ dump_generic_node (buffer, gimple_assign_rhs2 (gs), spc, flags, false);
+ }
+}
+
+
+/* Dump the gimple assignment GS. BUFFER, SPC and FLAGS are as in
+ dump_gimple_stmt. */
+
+static void
+dump_gimple_assign (pretty_printer *buffer, gimple gs, int spc, int flags)
+{
+ if (flags & TDF_RAW)
+ {
+ tree last;
+ if (gimple_num_ops (gs) == 2)
+ last = NULL_TREE;
+ else if (gimple_num_ops (gs) == 3)
+ last = gimple_assign_rhs2 (gs);
+ else
+ gcc_unreachable ();
+
+ dump_gimple_fmt (buffer, spc, flags, "%G <%s, %T, %T, %T>", gs,
+ tree_code_name[gimple_assign_rhs_code (gs)],
+ gimple_assign_lhs (gs), gimple_assign_rhs1 (gs), last);
+ }
+ else
+ {
+ if (!(flags & TDF_RHS_ONLY))
+ {
+ dump_generic_node (buffer, gimple_assign_lhs (gs), spc, flags, false);
+ pp_space (buffer);
+ pp_character (buffer, '=');
+
+ if (gimple_assign_nontemporal_move_p (gs))
+ pp_string (buffer, "{nt}");
+
+ if (gimple_has_volatile_ops (gs))
+ pp_string (buffer, "{v}");
+
+ pp_space (buffer);
+ }
+
+ if (gimple_num_ops (gs) == 2)
+ dump_unary_rhs (buffer, gs, spc, flags);
+ else if (gimple_num_ops (gs) == 3)
+ dump_binary_rhs (buffer, gs, spc, flags);
+ else
+ gcc_unreachable ();
+ if (!(flags & TDF_RHS_ONLY))
+ pp_semicolon(buffer);
+ }
+}
+
+
+/* Dump the return statement GS. BUFFER, SPC and FLAGS are as in
+ dump_gimple_stmt. */
+
+static void
+dump_gimple_return (pretty_printer *buffer, gimple gs, int spc, int flags)
+{
+ tree t;
+
+ t = gimple_return_retval (gs);
+ if (flags & TDF_RAW)
+ dump_gimple_fmt (buffer, spc, flags, "%G <%T>", gs, t);
+ else
+ {
+ pp_string (buffer, "return");
+ if (t)
+ {
+ pp_space (buffer);
+ dump_generic_node (buffer, t, spc, flags, false);
+ }
+ pp_semicolon (buffer);
+ }
+}
+
+
+/* Dump the call arguments for a gimple call. BUFFER, FLAGS are as in
+ dump_gimple_call. */
+
+static void
+dump_gimple_call_args (pretty_printer *buffer, gimple gs, int flags)
+{
+ size_t i;
+
+ for (i = 0; i < gimple_call_num_args (gs); i++)
+ {
+ dump_generic_node (buffer, gimple_call_arg (gs, i), 0, flags, false);
+ if (i < gimple_call_num_args (gs) - 1)
+ pp_string (buffer, ", ");
+ }
+
+ if (gimple_call_va_arg_pack_p (gs))
+ {
+ if (gimple_call_num_args (gs) > 0)
+ {
+ pp_character (buffer, ',');
+ pp_space (buffer);
+ }
+
+ pp_string (buffer, "__builtin_va_arg_pack ()");
+ }
+}
+
+
+/* Dump the call statement GS. BUFFER, SPC and FLAGS are as in
+ dump_gimple_stmt. */
+
+static void
+dump_gimple_call (pretty_printer *buffer, gimple gs, int spc, int flags)
+{
+ tree lhs = gimple_call_lhs (gs);
+
+ if (flags & TDF_RAW)
+ {
+ dump_gimple_fmt (buffer, spc, flags, "%G <%T, %T",
+ gs, gimple_call_fn (gs), lhs);
+ if (gimple_call_num_args (gs) > 0)
+ {
+ pp_string (buffer, ", ");
+ dump_gimple_call_args (buffer, gs, flags);
+ }
+ pp_string (buffer, ">");
+ }
+ else
+ {
+ if (lhs && !(flags & TDF_RHS_ONLY))
+ {
+ dump_generic_node (buffer, lhs, spc, flags, false);
+ pp_string (buffer, " =");
+
+ if (gimple_has_volatile_ops (gs))
+ pp_string (buffer, "{v}");
+
+ pp_space (buffer);
+ }
+ dump_generic_node (buffer, gimple_call_fn (gs), spc, flags, false);
+ pp_string (buffer, " (");
+ dump_gimple_call_args (buffer, gs, flags);
+ pp_string (buffer, ")");
+ if (!(flags & TDF_RHS_ONLY))
+ pp_semicolon (buffer);
+ }
+
+ if (gimple_call_chain (gs))
+ {
+ pp_string (buffer, " [static-chain: ");
+ dump_generic_node (buffer, gimple_call_chain (gs), spc, flags, false);
+ pp_character (buffer, ']');
+ }
+
+ if (gimple_call_return_slot_opt_p (gs))
+ pp_string (buffer, " [return slot optimization]");
+
+ if (gimple_call_tail_p (gs))
+ pp_string (buffer, " [tail call]");
+}
+
+
+/* Dump the switch statement GS. BUFFER, SPC and FLAGS are as in
+ dump_gimple_stmt. */
+
+static void
+dump_gimple_switch (pretty_printer *buffer, gimple gs, int spc, int flags)
+{
+ unsigned int i;
+
+ GIMPLE_CHECK (gs, GIMPLE_SWITCH);
+ if (flags & TDF_RAW)
+ dump_gimple_fmt (buffer, spc, flags, "%G <%T, ", gs,
+ gimple_switch_index (gs));
+ else
+ {
+ pp_string (buffer, "switch (");
+ dump_generic_node (buffer, gimple_switch_index (gs), spc, flags, true);
+ pp_string (buffer, ") <");
+ }
+
+ for (i = 0; i < gimple_switch_num_labels (gs); i++)
+ {
+ tree case_label = gimple_switch_label (gs, i);
+ if (case_label == NULL_TREE)
+ continue;
+
+ dump_generic_node (buffer, case_label, spc, flags, false);
+ pp_string (buffer, " ");
+ dump_generic_node (buffer, CASE_LABEL (case_label), spc, flags, false);
+ if (i < gimple_switch_num_labels (gs) - 1)
+ pp_string (buffer, ", ");
+ }
+ pp_string (buffer, ">");
+}
+
+
+/* Dump the gimple conditional GS. BUFFER, SPC and FLAGS are as in
+ dump_gimple_stmt. */
+
+static void
+dump_gimple_cond (pretty_printer *buffer, gimple gs, int spc, int flags)
+{
+ if (flags & TDF_RAW)
+ dump_gimple_fmt (buffer, spc, flags, "%G <%s, %T, %T, %T, %T>", gs,
+ tree_code_name [gimple_cond_code (gs)],
+ gimple_cond_lhs (gs), gimple_cond_rhs (gs),
+ gimple_cond_true_label (gs), gimple_cond_false_label (gs));
+ else
+ {
+ if (!(flags & TDF_RHS_ONLY))
+ pp_string (buffer, "if (");
+ dump_generic_node (buffer, gimple_cond_lhs (gs), spc, flags, false);
+ pp_space (buffer);
+ pp_string (buffer, op_symbol_code (gimple_cond_code (gs)));
+ pp_space (buffer);
+ dump_generic_node (buffer, gimple_cond_rhs (gs), spc, flags, false);
+ if (!(flags & TDF_RHS_ONLY))
+ {
+ pp_string (buffer, ")");
+
+ if (gimple_cond_true_label (gs))
+ {
+ pp_string (buffer, " goto ");
+ dump_generic_node (buffer, gimple_cond_true_label (gs),
+ spc, flags, false);
+ pp_semicolon (buffer);
+ }
+ if (gimple_cond_false_label (gs))
+ {
+ pp_string (buffer, " else goto ");
+ dump_generic_node (buffer, gimple_cond_false_label (gs),
+ spc, flags, false);
+ pp_semicolon (buffer);
+ }
+ }
+ }
+}
+
+
+/* Dump a GIMPLE_LABEL tuple on the pretty_printer BUFFER, SPC
+ spaces of indent. FLAGS specifies details to show in the dump (see
+ TDF_* in tree-pass.h). */
+
+static void
+dump_gimple_label (pretty_printer *buffer, gimple gs, int spc, int flags)
+{
+ tree label = gimple_label_label (gs);
+ if (flags & TDF_RAW)
+ dump_gimple_fmt (buffer, spc, flags, "%G <%T>", gs, label);
+ else
+ {
+ dump_generic_node (buffer, label, spc, flags, false);
+ pp_string (buffer, ":");
+ }
+ if (DECL_NONLOCAL (label))
+ pp_string (buffer, " [non-local]");
+}
+
+/* Dump a GIMPLE_GOTO tuple on the pretty_printer BUFFER, SPC
+ spaces of indent. FLAGS specifies details to show in the dump (see
+ TDF_* in tree-pass.h). */
+
+static void
+dump_gimple_goto (pretty_printer *buffer, gimple gs, int spc, int flags)
+{
+ tree label = gimple_goto_dest (gs);
+ if (flags & TDF_RAW)
+ dump_gimple_fmt (buffer, spc, flags, "%G <%T>", gs, label);
+ else
+ dump_gimple_fmt (buffer, spc, flags, "goto %T;", label);
+}
+
+
+/* Dump a GIMPLE_BIND tuple on the pretty_printer BUFFER, SPC
+ spaces of indent. FLAGS specifies details to show in the dump (see
+ TDF_* in tree-pass.h). */
+
+static void
+dump_gimple_bind (pretty_printer *buffer, gimple gs, int spc, int flags)
+{
+ if (flags & TDF_RAW)
+ dump_gimple_fmt (buffer, spc, flags, "%G <", gs);
+ else
+ pp_character (buffer, '{');
+ if (!(flags & TDF_SLIM))
+ {
+ tree var;
+
+ for (var = gimple_bind_vars (gs); var; var = TREE_CHAIN (var))
+ {
+ newline_and_indent (buffer, 2);
+ print_declaration (buffer, var, spc, flags);
+ }
+ if (gimple_bind_vars (gs))
+ pp_newline (buffer);
+ }
+ pp_newline (buffer);
+ dump_gimple_seq (buffer, gimple_bind_body (gs), spc + 2, flags);
+ newline_and_indent (buffer, spc);
+ if (flags & TDF_RAW)
+ pp_character (buffer, '>');
+ else
+ pp_character (buffer, '}');
+}
+
+
+/* Dump a GIMPLE_TRY tuple on the pretty_printer BUFFER, SPC spaces of
+ indent. FLAGS specifies details to show in the dump (see TDF_* in
+ tree-pass.h). */
+
+static void
+dump_gimple_try (pretty_printer *buffer, gimple gs, int spc, int flags)
+{
+ if (flags & TDF_RAW)
+ {
+ const char *type;
+ if (gimple_try_kind (gs) == GIMPLE_TRY_CATCH)
+ type = "GIMPLE_TRY_CATCH";
+ else if (gimple_try_kind (gs) == GIMPLE_TRY_FINALLY)
+ type = "GIMPLE_TRY_FINALLY";
+ else
+ type = "UNKNOWN GIMPLE_TRY";
+ dump_gimple_fmt (buffer, spc, flags,
+ "%G <%s,%+EVAL <%S>%nCLEANUP <%S>%->", gs, type,
+ gimple_try_eval (gs), gimple_try_cleanup (gs));
+ }
+ else
+ {
+ pp_string (buffer, "try");
+ newline_and_indent (buffer, spc + 2);
+ pp_string (buffer, "{");
+ pp_newline (buffer);
+
+ dump_gimple_seq (buffer, gimple_try_eval (gs), spc + 4, flags);
+ newline_and_indent (buffer, spc + 2);
+ pp_string (buffer, "}");
+
+ if (gimple_try_kind (gs) == GIMPLE_TRY_CATCH)
+ {
+ newline_and_indent (buffer, spc);
+ pp_string (buffer, "catch");
+ newline_and_indent (buffer, spc + 2);
+ pp_string (buffer, "{");
+ }
+ else if (gimple_try_kind (gs) == GIMPLE_TRY_FINALLY)
+ {
+ newline_and_indent (buffer, spc);
+ pp_string (buffer, "finally");
+ newline_and_indent (buffer, spc + 2);
+ pp_string (buffer, "{");
+ }
+ else
+ pp_string (buffer, " <UNKNOWN GIMPLE_TRY> {");
+
+ pp_newline (buffer);
+ dump_gimple_seq (buffer, gimple_try_cleanup (gs), spc + 4, flags);
+ newline_and_indent (buffer, spc + 2);
+ pp_character (buffer, '}');
+ }
+}
+
+
+/* Dump a GIMPLE_CATCH tuple on the pretty_printer BUFFER, SPC spaces of
+ indent. FLAGS specifies details to show in the dump (see TDF_* in
+ tree-pass.h). */
+
+static void
+dump_gimple_catch (pretty_printer *buffer, gimple gs, int spc, int flags)
+{
+ if (flags & TDF_RAW)
+ dump_gimple_fmt (buffer, spc, flags, "%G <%T, %+CATCH <%S>%->", gs,
+ gimple_catch_types (gs), gimple_catch_handler (gs));
+ else
+ dump_gimple_fmt (buffer, spc, flags, "catch (%T)%+{%S}",
+ gimple_catch_types (gs), gimple_catch_handler (gs));
+}
+
+
+/* Dump a GIMPLE_EH_FILTER tuple on the pretty_printer BUFFER, SPC spaces of
+ indent. FLAGS specifies details to show in the dump (see TDF_* in
+ tree-pass.h). */
+
+static void
+dump_gimple_eh_filter (pretty_printer *buffer, gimple gs, int spc, int flags)
+{
+ if (flags & TDF_RAW)
+ dump_gimple_fmt (buffer, spc, flags, "%G <%T, %+FAILURE <%S>%->", gs,
+ gimple_eh_filter_types (gs),
+ gimple_eh_filter_failure (gs));
+ else
+ dump_gimple_fmt (buffer, spc, flags, "<<<eh_filter (%T)>>>%+{%+%S%-}",
+ gimple_eh_filter_types (gs),
+ gimple_eh_filter_failure (gs));
+}
+
+
+/* Dump a GIMPLE_RESX tuple on the pretty_printer BUFFER, SPC spaces of
+ indent. FLAGS specifies details to show in the dump (see TDF_* in
+ tree-pass.h). */
+
+static void
+dump_gimple_resx (pretty_printer *buffer, gimple gs, int spc, int flags)
+{
+ if (flags & TDF_RAW)
+ dump_gimple_fmt (buffer, spc, flags, "%G <%d>", gs,
+ gimple_resx_region (gs));
+ else
+ dump_gimple_fmt (buffer, spc, flags, "resx %d", gimple_resx_region (gs));
+}
+
+/* Dump a GIMPLE_OMP_FOR tuple on the pretty_printer BUFFER. */
+static void
+dump_gimple_omp_for (pretty_printer *buffer, gimple gs, int spc, int flags)
+{
+ size_t i;
+
+ if (flags & TDF_RAW)
+ {
+ dump_gimple_fmt (buffer, spc, flags, "%G <%+BODY <%S>%nCLAUSES <", gs,
+ gimple_omp_body (gs));
+ dump_omp_clauses (buffer, gimple_omp_for_clauses (gs), spc, flags);
+ dump_gimple_fmt (buffer, spc, flags, " >,");
+ for (i = 0; i < gimple_omp_for_collapse (gs); i++)
+ dump_gimple_fmt (buffer, spc, flags,
+ "%+%T, %T, %T, %s, %T,%n",
+ gimple_omp_for_index (gs, i),
+ gimple_omp_for_initial (gs, i),
+ gimple_omp_for_final (gs, i),
+ tree_code_name[gimple_omp_for_cond (gs, i)],
+ gimple_omp_for_incr (gs, i));
+ dump_gimple_fmt (buffer, spc, flags, "PRE_BODY <%S>%->",
+ gimple_omp_for_pre_body (gs));
+ }
+ else
+ {
+ pp_string (buffer, "#pragma omp for");
+ dump_omp_clauses (buffer, gimple_omp_for_clauses (gs), spc, flags);
+ for (i = 0; i < gimple_omp_for_collapse (gs); i++)
+ {
+ if (i)
+ spc += 2;
+ newline_and_indent (buffer, spc);
+ pp_string (buffer, "for (");
+ dump_generic_node (buffer, gimple_omp_for_index (gs, i), spc,
+ flags, false);
+ pp_string (buffer, " = ");
+ dump_generic_node (buffer, gimple_omp_for_initial (gs, i), spc,
+ flags, false);
+ pp_string (buffer, "; ");
+
+ dump_generic_node (buffer, gimple_omp_for_index (gs, i), spc,
+ flags, false);
+ pp_space (buffer);
+ switch (gimple_omp_for_cond (gs, i))
+ {
+ case LT_EXPR:
+ pp_character (buffer, '<');
+ break;
+ case GT_EXPR:
+ pp_character (buffer, '>');
+ break;
+ case LE_EXPR:
+ pp_string (buffer, "<=");
+ break;
+ case GE_EXPR:
+ pp_string (buffer, ">=");
+ break;
+ default:
+ gcc_unreachable ();
+ }
+ pp_space (buffer);
+ dump_generic_node (buffer, gimple_omp_for_final (gs, i), spc,
+ flags, false);
+ pp_string (buffer, "; ");
+
+ dump_generic_node (buffer, gimple_omp_for_index (gs, i), spc,
+ flags, false);
+ pp_string (buffer, " = ");
+ dump_generic_node (buffer, gimple_omp_for_incr (gs, i), spc,
+ flags, false);
+ pp_character (buffer, ')');
+ }
+
+ if (!gimple_seq_empty_p (gimple_omp_body (gs)))
+ {
+ newline_and_indent (buffer, spc + 2);
+ pp_character (buffer, '{');
+ pp_newline (buffer);
+ dump_gimple_seq (buffer, gimple_omp_body (gs), spc + 4, flags);
+ newline_and_indent (buffer, spc + 2);
+ pp_character (buffer, '}');
+ }
+ }
+}
+
+/* Dump a GIMPLE_OMP_CONTINUE tuple on the pretty_printer BUFFER. */
+
+static void
+dump_gimple_omp_continue (pretty_printer *buffer, gimple gs, int spc, int flags)
+{
+ if (flags & TDF_RAW)
+ {
+ dump_gimple_fmt (buffer, spc, flags, "%G <%T, %T>", gs,
+ gimple_omp_continue_control_def (gs),
+ gimple_omp_continue_control_use (gs));
+ }
+ else
+ {
+ pp_string (buffer, "#pragma omp continue (");
+ dump_generic_node (buffer, gimple_omp_continue_control_def (gs),
+ spc, flags, false);
+ pp_character (buffer, ',');
+ pp_space (buffer);
+ dump_generic_node (buffer, gimple_omp_continue_control_use (gs),
+ spc, flags, false);
+ pp_character (buffer, ')');
+ }
+}
+
+/* Dump a GIMPLE_OMP_SINGLE tuple on the pretty_printer BUFFER. */
+
+static void
+dump_gimple_omp_single (pretty_printer *buffer, gimple gs, int spc, int flags)
+{
+ if (flags & TDF_RAW)
+ {
+ dump_gimple_fmt (buffer, spc, flags, "%G <%+BODY <%S>%nCLAUSES <", gs,
+ gimple_omp_body (gs));
+ dump_omp_clauses (buffer, gimple_omp_single_clauses (gs), spc, flags);
+ dump_gimple_fmt (buffer, spc, flags, " >");
+ }
+ else
+ {
+ pp_string (buffer, "#pragma omp single");
+ dump_omp_clauses (buffer, gimple_omp_single_clauses (gs), spc, flags);
+ if (!gimple_seq_empty_p (gimple_omp_body (gs)))
+ {
+ newline_and_indent (buffer, spc + 2);
+ pp_character (buffer, '{');
+ pp_newline (buffer);
+ dump_gimple_seq (buffer, gimple_omp_body (gs), spc + 4, flags);
+ newline_and_indent (buffer, spc + 2);
+ pp_character (buffer, '}');
+ }
+ }
+}
+
+/* Dump a GIMPLE_OMP_SECTIONS tuple on the pretty_printer BUFFER. */
+
+static void
+dump_gimple_omp_sections (pretty_printer *buffer, gimple gs, int spc,
+ int flags)
+{
+ if (flags & TDF_RAW)
+ {
+ dump_gimple_fmt (buffer, spc, flags, "%G <%+BODY <%S>%nCLAUSES <", gs,
+ gimple_omp_body (gs));
+ dump_omp_clauses (buffer, gimple_omp_sections_clauses (gs), spc, flags);
+ dump_gimple_fmt (buffer, spc, flags, " >");
+ }
+ else
+ {
+ pp_string (buffer, "#pragma omp sections");
+ if (gimple_omp_sections_control (gs))
+ {
+ pp_string (buffer, " <");
+ dump_generic_node (buffer, gimple_omp_sections_control (gs), spc,
+ flags, false);
+ pp_character (buffer, '>');
+ }
+ dump_omp_clauses (buffer, gimple_omp_sections_clauses (gs), spc, flags);
+ if (!gimple_seq_empty_p (gimple_omp_body (gs)))
+ {
+ newline_and_indent (buffer, spc + 2);
+ pp_character (buffer, '{');
+ pp_newline (buffer);
+ dump_gimple_seq (buffer, gimple_omp_body (gs), spc + 4, flags);
+ newline_and_indent (buffer, spc + 2);
+ pp_character (buffer, '}');
+ }
+ }
+}
+
+/* Dump a GIMPLE_OMP_{MASTER,ORDERED,SECTION} tuple on the pretty_printer
+ BUFFER. */
+
+static void
+dump_gimple_omp_block (pretty_printer *buffer, gimple gs, int spc, int flags)
+{
+ if (flags & TDF_RAW)
+ dump_gimple_fmt (buffer, spc, flags, "%G <%+BODY <%S> >", gs,
+ gimple_omp_body (gs));
+ else
+ {
+ switch (gimple_code (gs))
+ {
+ case GIMPLE_OMP_MASTER:
+ pp_string (buffer, "#pragma omp master");
+ break;
+ case GIMPLE_OMP_ORDERED:
+ pp_string (buffer, "#pragma omp ordered");
+ break;
+ case GIMPLE_OMP_SECTION:
+ pp_string (buffer, "#pragma omp section");
+ break;
+ default:
+ gcc_unreachable ();
+ }
+ if (!gimple_seq_empty_p (gimple_omp_body (gs)))
+ {
+ newline_and_indent (buffer, spc + 2);
+ pp_character (buffer, '{');
+ pp_newline (buffer);
+ dump_gimple_seq (buffer, gimple_omp_body (gs), spc + 4, flags);
+ newline_and_indent (buffer, spc + 2);
+ pp_character (buffer, '}');
+ }
+ }
+}
+
+/* Dump a GIMPLE_OMP_CRITICAL tuple on the pretty_printer BUFFER. */
+
+static void
+dump_gimple_omp_critical (pretty_printer *buffer, gimple gs, int spc,
+ int flags)
+{
+ if (flags & TDF_RAW)
+ dump_gimple_fmt (buffer, spc, flags, "%G <%+BODY <%S> >", gs,
+ gimple_omp_body (gs));
+ else
+ {
+ pp_string (buffer, "#pragma omp critical");
+ if (gimple_omp_critical_name (gs))
+ {
+ pp_string (buffer, " (");
+ dump_generic_node (buffer, gimple_omp_critical_name (gs), spc,
+ flags, false);
+ pp_character (buffer, ')');
+ }
+ if (!gimple_seq_empty_p (gimple_omp_body (gs)))
+ {
+ newline_and_indent (buffer, spc + 2);
+ pp_character (buffer, '{');
+ pp_newline (buffer);
+ dump_gimple_seq (buffer, gimple_omp_body (gs), spc + 4, flags);
+ newline_and_indent (buffer, spc + 2);
+ pp_character (buffer, '}');
+ }
+ }
+}
+
+/* Dump a GIMPLE_OMP_RETURN tuple on the pretty_printer BUFFER. */
+
+static void
+dump_gimple_omp_return (pretty_printer *buffer, gimple gs, int spc, int flags)
+{
+ if (flags & TDF_RAW)
+ {
+ dump_gimple_fmt (buffer, spc, flags, "%G <nowait=%d>", gs,
+ (int) gimple_omp_return_nowait_p (gs));
+ }
+ else
+ {
+ pp_string (buffer, "#pragma omp return");
+ if (gimple_omp_return_nowait_p (gs))
+ pp_string (buffer, "(nowait)");
+ }
+}
+
+/* Dump a GIMPLE_ASM tuple on the pretty_printer BUFFER, SPC spaces of
+ indent. FLAGS specifies details to show in the dump (see TDF_* in
+ tree-pass.h). */
+
+static void
+dump_gimple_asm (pretty_printer *buffer, gimple gs, int spc, int flags)
+{
+ unsigned int i;
+
+ if (flags & TDF_RAW)
+ dump_gimple_fmt (buffer, spc, flags, "%G <%+STRING <%n%s%n>", gs,
+ gimple_asm_string (gs));
+ else
+ {
+ pp_string (buffer, "__asm__");
+ if (gimple_asm_volatile_p (gs))
+ pp_string (buffer, " __volatile__");
+ pp_string (buffer, "(\"");
+ pp_string (buffer, gimple_asm_string (gs));
+ pp_string (buffer, "\"");
+ }
+
+ if (gimple_asm_ninputs (gs)
+ || gimple_asm_noutputs (gs)
+ || gimple_asm_nclobbers (gs))
+ {
+ if (gimple_asm_noutputs (gs))
+ {
+ if (flags & TDF_RAW)
+ {
+ newline_and_indent (buffer, spc + 2);
+ pp_string (buffer, "OUTPUT: ");
+ }
+ else
+ pp_string (buffer, " : ");
+ }
+
+ for (i = 0; i < gimple_asm_noutputs (gs); i++)
+ {
+ dump_generic_node (buffer, gimple_asm_output_op (gs, i), spc, flags,
+ false);
+ if ( i < gimple_asm_noutputs (gs) -1)
+ pp_string (buffer, ", ");
+ }
+
+ if (gimple_asm_ninputs (gs))
+ {
+ if (flags & TDF_RAW)
+ {
+ newline_and_indent (buffer, spc + 2);
+ pp_string (buffer, "INPUT: ");
+ }
+ else
+ pp_string (buffer, " : ");
+ }
+
+ for (i = 0; i < gimple_asm_ninputs (gs); i++)
+ {
+ dump_generic_node (buffer, gimple_asm_input_op (gs, i), spc, flags,
+ false);
+ if (i < gimple_asm_ninputs (gs) -1)
+ pp_string (buffer, " : ");
+ }
+
+ if (gimple_asm_nclobbers (gs))
+ {
+ if (flags & TDF_RAW)
+ {
+ newline_and_indent (buffer, spc + 2);
+ pp_string (buffer, "CLOBBER: ");
+ }
+ else
+ pp_string (buffer, " : ");
+ }
+
+ for (i = 0; i < gimple_asm_nclobbers (gs); i++)
+ {
+ dump_generic_node (buffer, gimple_asm_clobber_op (gs, i), spc, flags,
+ false);
+ if ( i < gimple_asm_nclobbers (gs) -1)
+ pp_string (buffer, ", ");
+ }
+ }
+ if (flags & TDF_RAW)
+ {
+ newline_and_indent (buffer, spc);
+ pp_character (buffer, '>');
+ }
+ else
+ pp_string (buffer, ");");
+}
+
+
+/* Dump the set of decls SYMS. BUFFER, SPC and FLAGS are as in
+ dump_generic_node. */
+
+static void
+dump_symbols (pretty_printer *buffer, bitmap syms, int flags)
+{
+ unsigned i;
+ bitmap_iterator bi;
+
+ if (syms == NULL)
+ pp_string (buffer, "NIL");
+ else
+ {
+ pp_string (buffer, " { ");
+
+ EXECUTE_IF_SET_IN_BITMAP (syms, 0, i, bi)
+ {
+ tree sym = referenced_var_lookup (i);
+ dump_generic_node (buffer, sym, 0, flags, false);
+ pp_string (buffer, " ");
+ }
+
+ pp_string (buffer, "}");
+ }
+}
+
+
+/* Dump a PHI node PHI. BUFFER, SPC and FLAGS are as in
+ dump_gimple_stmt. */
+
+static void
+dump_gimple_phi (pretty_printer *buffer, gimple phi, int spc, int flags)
+{
+ size_t i;
+
+ if (flags & TDF_RAW)
+ dump_gimple_fmt (buffer, spc, flags, "%G <%T, ", phi,
+ gimple_phi_result (phi));
+ else
+ {
+ dump_generic_node (buffer, gimple_phi_result (phi), spc, flags, false);
+ pp_string (buffer, " = PHI <");
+ }
+ for (i = 0; i < gimple_phi_num_args (phi); i++)
+ {
+ dump_generic_node (buffer, gimple_phi_arg_def (phi, i), spc, flags,
+ false);
+ pp_string (buffer, "(");
+ pp_decimal_int (buffer, gimple_phi_arg_edge (phi, i)->src->index);
+ pp_string (buffer, ")");
+ if (i < gimple_phi_num_args (phi) - 1)
+ pp_string (buffer, ", ");
+ }
+ pp_string (buffer, ">");
+}
+
+
+/* Dump a GIMPLE_OMP_PARALLEL tuple on the pretty_printer BUFFER, SPC spaces
+ of indent. FLAGS specifies details to show in the dump (see TDF_* in
+ tree-pass.h). */
+
+static void
+dump_gimple_omp_parallel (pretty_printer *buffer, gimple gs, int spc,
+ int flags)
+{
+ if (flags & TDF_RAW)
+ {
+ dump_gimple_fmt (buffer, spc, flags, "%G <%+BODY <%S>%nCLAUSES <", gs,
+ gimple_omp_body (gs));
+ dump_omp_clauses (buffer, gimple_omp_parallel_clauses (gs), spc, flags);
+ dump_gimple_fmt (buffer, spc, flags, " >, %T, %T%n>",
+ gimple_omp_parallel_child_fn (gs),
+ gimple_omp_parallel_data_arg (gs));
+ }
+ else
+ {
+ gimple_seq body;
+ pp_string (buffer, "#pragma omp parallel");
+ dump_omp_clauses (buffer, gimple_omp_parallel_clauses (gs), spc, flags);
+ if (gimple_omp_parallel_child_fn (gs))
+ {
+ pp_string (buffer, " [child fn: ");
+ dump_generic_node (buffer, gimple_omp_parallel_child_fn (gs),
+ spc, flags, false);
+ pp_string (buffer, " (");
+ if (gimple_omp_parallel_data_arg (gs))
+ dump_generic_node (buffer, gimple_omp_parallel_data_arg (gs),
+ spc, flags, false);
+ else
+ pp_string (buffer, "???");
+ pp_string (buffer, ")]");
+ }
+ body = gimple_omp_body (gs);
+ if (body && gimple_code (gimple_seq_first_stmt (body)) != GIMPLE_BIND)
+ {
+ newline_and_indent (buffer, spc + 2);
+ pp_character (buffer, '{');
+ pp_newline (buffer);
+ dump_gimple_seq (buffer, body, spc + 4, flags);
+ newline_and_indent (buffer, spc + 2);
+ pp_character (buffer, '}');
+ }
+ else if (body)
+ {
+ pp_newline (buffer);
+ dump_gimple_seq (buffer, body, spc + 2, flags);
+ }
+ }
+}
+
+
+/* Dump a GIMPLE_OMP_TASK tuple on the pretty_printer BUFFER, SPC spaces
+ of indent. FLAGS specifies details to show in the dump (see TDF_* in
+ tree-pass.h). */
+
+static void
+dump_gimple_omp_task (pretty_printer *buffer, gimple gs, int spc,
+ int flags)
+{
+ if (flags & TDF_RAW)
+ {
+ dump_gimple_fmt (buffer, spc, flags, "%G <%+BODY <%S>%nCLAUSES <", gs,
+ gimple_omp_body (gs));
+ dump_omp_clauses (buffer, gimple_omp_task_clauses (gs), spc, flags);
+ dump_gimple_fmt (buffer, spc, flags, " >, %T, %T, %T, %T, %T%n>",
+ gimple_omp_task_child_fn (gs),
+ gimple_omp_task_data_arg (gs),
+ gimple_omp_task_copy_fn (gs),
+ gimple_omp_task_arg_size (gs),
+ gimple_omp_task_arg_size (gs));
+ }
+ else
+ {
+ gimple_seq body;
+ pp_string (buffer, "#pragma omp task");
+ dump_omp_clauses (buffer, gimple_omp_task_clauses (gs), spc, flags);
+ if (gimple_omp_task_child_fn (gs))
+ {
+ pp_string (buffer, " [child fn: ");
+ dump_generic_node (buffer, gimple_omp_task_child_fn (gs),
+ spc, flags, false);
+ pp_string (buffer, " (");
+ if (gimple_omp_task_data_arg (gs))
+ dump_generic_node (buffer, gimple_omp_task_data_arg (gs),
+ spc, flags, false);
+ else
+ pp_string (buffer, "???");
+ pp_string (buffer, ")]");
+ }
+ body = gimple_omp_body (gs);
+ if (body && gimple_code (gimple_seq_first_stmt (body)) != GIMPLE_BIND)
+ {
+ newline_and_indent (buffer, spc + 2);
+ pp_character (buffer, '{');
+ pp_newline (buffer);
+ dump_gimple_seq (buffer, body, spc + 4, flags);
+ newline_and_indent (buffer, spc + 2);
+ pp_character (buffer, '}');
+ }
+ else if (body)
+ {
+ pp_newline (buffer);
+ dump_gimple_seq (buffer, body, spc + 2, flags);
+ }
+ }
+}
+
+
+/* Dump a GIMPLE_OMP_ATOMIC_LOAD tuple on the pretty_printer BUFFER, SPC
+ spaces of indent. FLAGS specifies details to show in the dump (see TDF_*
+ in tree-pass.h). */
+
+static void
+dump_gimple_omp_atomic_load (pretty_printer *buffer, gimple gs, int spc,
+ int flags)
+{
+ if (flags & TDF_RAW)
+ {
+ dump_gimple_fmt (buffer, spc, flags, "%G <%T, %T>", gs,
+ gimple_omp_atomic_load_lhs (gs),
+ gimple_omp_atomic_load_rhs (gs));
+ }
+ else
+ {
+ pp_string (buffer, "#pragma omp atomic_load");
+ newline_and_indent (buffer, spc + 2);
+ dump_generic_node (buffer, gimple_omp_atomic_load_lhs (gs),
+ spc, flags, false);
+ pp_space (buffer);
+ pp_character (buffer, '=');
+ pp_space (buffer);
+ pp_character (buffer, '*');
+ dump_generic_node (buffer, gimple_omp_atomic_load_rhs (gs),
+ spc, flags, false);
+ }
+}
+
+/* Dump a GIMPLE_OMP_ATOMIC_STORE tuple on the pretty_printer BUFFER, SPC
+ spaces of indent. FLAGS specifies details to show in the dump (see TDF_*
+ in tree-pass.h). */
+
+static void
+dump_gimple_omp_atomic_store (pretty_printer *buffer, gimple gs, int spc,
+ int flags)
+{
+ if (flags & TDF_RAW)
+ {
+ dump_gimple_fmt (buffer, spc, flags, "%G <%T>", gs,
+ gimple_omp_atomic_store_val (gs));
+ }
+ else
+ {
+ pp_string (buffer, "#pragma omp atomic_store (");
+ dump_generic_node (buffer, gimple_omp_atomic_store_val (gs),
+ spc, flags, false);
+ pp_character (buffer, ')');
+ }
+}
+
+/* Dump a GIMPLE_CHANGE_DYNAMIC_TYPE statement GS. BUFFER, SPC and
+ FLAGS are as in dump_gimple_stmt. */
+
+static void
+dump_gimple_cdt (pretty_printer *buffer, gimple gs, int spc, int flags)
+{
+ if (flags & TDF_RAW)
+ dump_gimple_fmt (buffer, spc, flags, "%G <%T, %T>", gs,
+ gimple_cdt_new_type (gs), gimple_cdt_location (gs));
+ else
+ {
+ pp_string (buffer, "<<<change_dynamic_type (");
+ dump_generic_node (buffer, gimple_cdt_new_type (gs), spc + 2, flags,
+ false);
+ pp_string (buffer, ") ");
+ dump_generic_node (buffer, gimple_cdt_location (gs), spc + 2, flags,
+ false);
+ pp_string (buffer, ")>>>");
+ }
+}
+
+
+/* Dump all the memory operands for statement GS. BUFFER, SPC and
+ FLAGS are as in dump_gimple_stmt. */
+
+static void
+dump_gimple_mem_ops (pretty_printer *buffer, gimple gs, int spc, int flags)
+{
+ struct voptype_d *vdefs;
+ struct voptype_d *vuses;
+ int i, n;
+
+ if (!ssa_operands_active () || !gimple_references_memory_p (gs))
+ return;
+
+ /* Even if the statement doesn't have virtual operators yet, it may
+ contain symbol information (this happens before aliases have been
+ computed). */
+ if ((flags & TDF_MEMSYMS)
+ && gimple_vuse_ops (gs) == NULL
+ && gimple_vdef_ops (gs) == NULL)
+ {
+ if (gimple_loaded_syms (gs))
+ {
+ pp_string (buffer, "# LOADS: ");
+ dump_symbols (buffer, gimple_loaded_syms (gs), flags);
+ newline_and_indent (buffer, spc);
+ }
+
+ if (gimple_stored_syms (gs))
+ {
+ pp_string (buffer, "# STORES: ");
+ dump_symbols (buffer, gimple_stored_syms (gs), flags);
+ newline_and_indent (buffer, spc);
+ }
+
+ return;
+ }
+
+ vuses = gimple_vuse_ops (gs);
+ while (vuses)
+ {
+ pp_string (buffer, "# VUSE <");
+
+ n = VUSE_NUM (vuses);
+ for (i = 0; i < n; i++)
+ {
+ dump_generic_node (buffer, VUSE_OP (vuses, i), spc + 2, flags, false);
+ if (i < n - 1)
+ pp_string (buffer, ", ");
+ }
+
+ pp_string (buffer, ">");
+
+ if (flags & TDF_MEMSYMS)
+ dump_symbols (buffer, gimple_loaded_syms (gs), flags);
+
+ newline_and_indent (buffer, spc);
+ vuses = vuses->next;
+ }
+
+ vdefs = gimple_vdef_ops (gs);
+ while (vdefs)
+ {
+ pp_string (buffer, "# ");
+ dump_generic_node (buffer, VDEF_RESULT (vdefs), spc + 2, flags, false);
+ pp_string (buffer, " = VDEF <");
+
+ n = VDEF_NUM (vdefs);
+ for (i = 0; i < n; i++)
+ {
+ dump_generic_node (buffer, VDEF_OP (vdefs, i), spc + 2, flags, 0);
+ if (i < n - 1)
+ pp_string (buffer, ", ");
+ }
+
+ pp_string (buffer, ">");
+
+ if ((flags & TDF_MEMSYMS) && vdefs->next == NULL)
+ dump_symbols (buffer, gimple_stored_syms (gs), flags);
+
+ newline_and_indent (buffer, spc);
+ vdefs = vdefs->next;
+ }
+}
+
+
+/* Dump the gimple statement GS on the pretty printer BUFFER, SPC
+ spaces of indent. FLAGS specifies details to show in the dump (see
+ TDF_* in tree-pass.h). */
+
+void
+dump_gimple_stmt (pretty_printer *buffer, gimple gs, int spc, int flags)
+{
+ if (!gs)
+ return;
+
+ if (flags & TDF_STMTADDR)
+ pp_printf (buffer, "<&%p> ", (void *) gs);
+
+ if ((flags & TDF_LINENO) && gimple_has_location (gs))
+ {
+ expanded_location xloc = expand_location (gimple_location (gs));
+ pp_character (buffer, '[');
+ if (xloc.file)
+ {
+ pp_string (buffer, xloc.file);
+ pp_string (buffer, " : ");
+ }
+ pp_decimal_int (buffer, xloc.line);
+ pp_string (buffer, "] ");
+ }
+
+ if ((flags & (TDF_VOPS|TDF_MEMSYMS))
+ && gimple_has_mem_ops (gs))
+ dump_gimple_mem_ops (buffer, gs, spc, flags);
+
+ switch (gimple_code (gs))
+ {
+ case GIMPLE_ASM:
+ dump_gimple_asm (buffer, gs, spc, flags);
+ break;
+
+ case GIMPLE_ASSIGN:
+ dump_gimple_assign (buffer, gs, spc, flags);
+ break;
+
+ case GIMPLE_BIND:
+ dump_gimple_bind (buffer, gs, spc, flags);
+ break;
+
+ case GIMPLE_CALL:
+ dump_gimple_call (buffer, gs, spc, flags);
+ break;
+
+ case GIMPLE_COND:
+ dump_gimple_cond (buffer, gs, spc, flags);
+ break;
+
+ case GIMPLE_LABEL:
+ dump_gimple_label (buffer, gs, spc, flags);
+ break;
+
+ case GIMPLE_GOTO:
+ dump_gimple_goto (buffer, gs, spc, flags);
+ break;
+
+ case GIMPLE_NOP:
+ pp_string (buffer, "GIMPLE_NOP");
+ break;
+
+ case GIMPLE_RETURN:
+ dump_gimple_return (buffer, gs, spc, flags);
+ break;
+
+ case GIMPLE_SWITCH:
+ dump_gimple_switch (buffer, gs, spc, flags);
+ break;
+
+ case GIMPLE_TRY:
+ dump_gimple_try (buffer, gs, spc, flags);
+ break;
+
+ case GIMPLE_PHI:
+ dump_gimple_phi (buffer, gs, spc, flags);
+ break;
+
+ case GIMPLE_OMP_PARALLEL:
+ dump_gimple_omp_parallel (buffer, gs, spc, flags);
+ break;
+
+ case GIMPLE_OMP_TASK:
+ dump_gimple_omp_task (buffer, gs, spc, flags);
+ break;
+
+ case GIMPLE_OMP_ATOMIC_LOAD:
+ dump_gimple_omp_atomic_load (buffer, gs, spc, flags);
+
+ break;
+
+ case GIMPLE_OMP_ATOMIC_STORE:
+ dump_gimple_omp_atomic_store (buffer, gs, spc, flags);
+ break;
+
+ case GIMPLE_OMP_FOR:
+ dump_gimple_omp_for (buffer, gs, spc, flags);
+ break;
+
+ case GIMPLE_OMP_CONTINUE:
+ dump_gimple_omp_continue (buffer, gs, spc, flags);
+ break;
+
+ case GIMPLE_OMP_SINGLE:
+ dump_gimple_omp_single (buffer, gs, spc, flags);
+ break;
+
+ case GIMPLE_OMP_RETURN:
+ dump_gimple_omp_return (buffer, gs, spc, flags);
+ break;
+
+ case GIMPLE_OMP_SECTIONS:
+ dump_gimple_omp_sections (buffer, gs, spc, flags);
+ break;
+
+ case GIMPLE_OMP_SECTIONS_SWITCH:
+ pp_string (buffer, "GIMPLE_SECTIONS_SWITCH");
+ break;
+
+ case GIMPLE_OMP_MASTER:
+ case GIMPLE_OMP_ORDERED:
+ case GIMPLE_OMP_SECTION:
+ dump_gimple_omp_block (buffer, gs, spc, flags);
+ break;
+
+ case GIMPLE_OMP_CRITICAL:
+ dump_gimple_omp_critical (buffer, gs, spc, flags);
+ break;
+
+ case GIMPLE_CHANGE_DYNAMIC_TYPE:
+ dump_gimple_cdt (buffer, gs, spc, flags);
+ break;
+
+ case GIMPLE_CATCH:
+ dump_gimple_catch (buffer, gs, spc, flags);
+ break;
+
+ case GIMPLE_EH_FILTER:
+ dump_gimple_eh_filter (buffer, gs, spc, flags);
+ break;
+
+ case GIMPLE_RESX:
+ dump_gimple_resx (buffer, gs, spc, flags);
+ break;
+
+ case GIMPLE_PREDICT:
+ pp_string (buffer, "// predicted ");
+ if (gimple_predict_outcome (gs))
+ pp_string (buffer, "likely by ");
+ else
+ pp_string (buffer, "unlikely by ");
+ pp_string (buffer, predictor_name (gimple_predict_predictor (gs)));
+ pp_string (buffer, " predictor.");
+ break;
+
+ default:
+ GIMPLE_NIY;
+ }
+
+ /* If we're building a diagnostic, the formatted text will be
+ written into BUFFER's stream by the caller; otherwise, write it
+ now. */
+ if (!(flags & TDF_DIAGNOSTIC))
+ pp_write_text_to_stream (buffer);
+}
+
+
+/* Dumps header of basic block BB to buffer BUFFER indented by INDENT
+ spaces and details described by flags. */
+
+static void
+dump_bb_header (pretty_printer *buffer, basic_block bb, int indent, int flags)
+{
+ edge e;
+ gimple stmt;
+ edge_iterator ei;
+
+ if (flags & TDF_BLOCKS)
+ {
+ INDENT (indent);
+ pp_string (buffer, "# BLOCK ");
+ pp_decimal_int (buffer, bb->index);
+ if (bb->frequency)
+ {
+ pp_string (buffer, " freq:");
+ pp_decimal_int (buffer, bb->frequency);
+ }
+ if (bb->count)
+ {
+ pp_string (buffer, " count:");
+ pp_widest_integer (buffer, bb->count);
+ }
+
+ if (flags & TDF_LINENO)
+ {
+ gimple_stmt_iterator gsi;
+
+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+ if (get_lineno (gsi_stmt (gsi)) != -1)
+ {
+ pp_string (buffer, ", starting at line ");
+ pp_decimal_int (buffer, get_lineno (gsi_stmt (gsi)));
+ break;
+ }
+ }
+ newline_and_indent (buffer, indent);
+
+ pp_string (buffer, "# PRED:");
+ pp_write_text_to_stream (buffer);
+ FOR_EACH_EDGE (e, ei, bb->preds)
+ if (flags & TDF_SLIM)
+ {
+ pp_string (buffer, " ");
+ if (e->src == ENTRY_BLOCK_PTR)
+ pp_string (buffer, "ENTRY");
+ else
+ pp_decimal_int (buffer, e->src->index);
+ }
+ else
+ dump_edge_info (buffer->buffer->stream, e, 0);
+ pp_newline (buffer);
+ }
+ else
+ {
+ stmt = first_stmt (bb);
+ if (!stmt || gimple_code (stmt) != GIMPLE_LABEL)
+ {
+ INDENT (indent - 2);
+ pp_string (buffer, "<bb ");
+ pp_decimal_int (buffer, bb->index);
+ pp_string (buffer, ">:");
+ pp_newline (buffer);
+ }
+ }
+ pp_write_text_to_stream (buffer);
+ check_bb_profile (bb, buffer->buffer->stream);
+}
+
+
+/* Dumps end of basic block BB to buffer BUFFER indented by INDENT
+ spaces. */
+
+static void
+dump_bb_end (pretty_printer *buffer, basic_block bb, int indent, int flags)
+{
+ edge e;
+ edge_iterator ei;
+
+ INDENT (indent);
+ pp_string (buffer, "# SUCC:");
+ pp_write_text_to_stream (buffer);
+ FOR_EACH_EDGE (e, ei, bb->succs)
+ if (flags & TDF_SLIM)
+ {
+ pp_string (buffer, " ");
+ if (e->dest == EXIT_BLOCK_PTR)
+ pp_string (buffer, "EXIT");
+ else
+ pp_decimal_int (buffer, e->dest->index);
+ }
+ else
+ dump_edge_info (buffer->buffer->stream, e, 1);
+ pp_newline (buffer);
+}
+
+
+/* Dump PHI nodes of basic block BB to BUFFER with details described
+ by FLAGS and indented by INDENT spaces. */
+
+static void
+dump_phi_nodes (pretty_printer *buffer, basic_block bb, int indent, int flags)
+{
+ gimple_stmt_iterator i;
+
+ for (i = gsi_start_phis (bb); !gsi_end_p (i); gsi_next (&i))
+ {
+ gimple phi = gsi_stmt (i);
+ if (is_gimple_reg (gimple_phi_result (phi)) || (flags & TDF_VOPS))
+ {
+ INDENT (indent);
+ pp_string (buffer, "# ");
+ dump_gimple_phi (buffer, phi, indent, flags);
+ pp_newline (buffer);
+ }
+ }
+}
+
+
+/* Dump jump to basic block BB that is represented implicitly in the cfg
+ to BUFFER. */
+
+static void
+pp_cfg_jump (pretty_printer *buffer, basic_block bb)
+{
+ gimple stmt;
+
+ stmt = first_stmt (bb);
+
+ pp_string (buffer, "goto <bb ");
+ pp_decimal_int (buffer, bb->index);
+ pp_string (buffer, ">");
+ if (stmt && gimple_code (stmt) == GIMPLE_LABEL)
+ {
+ pp_string (buffer, " (");
+ dump_generic_node (buffer, gimple_label_label (stmt), 0, 0, false);
+ pp_string (buffer, ")");
+ pp_semicolon (buffer);
+ }
+ else
+ pp_semicolon (buffer);
+}
+
+
+/* Dump edges represented implicitly in basic block BB to BUFFER, indented
+ by INDENT spaces, with details given by FLAGS. */
+
+static void
+dump_implicit_edges (pretty_printer *buffer, basic_block bb, int indent,
+ int flags)
+{
+ edge e;
+ edge_iterator ei;
+ gimple stmt;
+
+ stmt = last_stmt (bb);
+
+ if (stmt && gimple_code (stmt) == GIMPLE_COND)
+ {
+ edge true_edge, false_edge;
+
+ /* When we are emitting the code or changing CFG, it is possible that
+ the edges are not yet created. When we are using debug_bb in such
+ a situation, we do not want it to crash. */
+ if (EDGE_COUNT (bb->succs) != 2)
+ return;
+ extract_true_false_edges_from_block (bb, &true_edge, &false_edge);
+
+ INDENT (indent + 2);
+ pp_cfg_jump (buffer, true_edge->dest);
+ newline_and_indent (buffer, indent);
+ pp_string (buffer, "else");
+ newline_and_indent (buffer, indent + 2);
+ pp_cfg_jump (buffer, false_edge->dest);
+ pp_newline (buffer);
+ return;
+ }
+
+ /* If there is a fallthru edge, we may need to add an artificial
+ goto to the dump. */
+ FOR_EACH_EDGE (e, ei, bb->succs)
+ if (e->flags & EDGE_FALLTHRU)
+ break;
+
+ if (e && e->dest != bb->next_bb)
+ {
+ INDENT (indent);
+
+ if ((flags & TDF_LINENO)
+ && e->goto_locus != UNKNOWN_LOCATION
+ )
+ {
+ expanded_location goto_xloc;
+ goto_xloc = expand_location (e->goto_locus);
+ pp_character (buffer, '[');
+ if (goto_xloc.file)
+ {
+ pp_string (buffer, goto_xloc.file);
+ pp_string (buffer, " : ");
+ }
+ pp_decimal_int (buffer, goto_xloc.line);
+ pp_string (buffer, "] ");
+ }
+
+ pp_cfg_jump (buffer, e->dest);
+ pp_newline (buffer);
+ }
+}
+
+
+/* Dumps basic block BB to buffer BUFFER with details described by FLAGS and
+ indented by INDENT spaces. */
+
+static void
+gimple_dump_bb_buff (pretty_printer *buffer, basic_block bb, int indent,
+ int flags)
+{
+ gimple_stmt_iterator gsi;
+ gimple stmt;
+ int label_indent = indent - 2;
+
+ if (label_indent < 0)
+ label_indent = 0;
+
+ dump_bb_header (buffer, bb, indent, flags);
+ dump_phi_nodes (buffer, bb, indent, flags);
+
+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+ {
+ int curr_indent;
+
+ stmt = gsi_stmt (gsi);
+
+ curr_indent = gimple_code (stmt) == GIMPLE_LABEL ? label_indent : indent;
+
+ INDENT (curr_indent);
+ dump_gimple_stmt (buffer, stmt, curr_indent, flags);
+ pp_newline (buffer);
+ dump_histograms_for_stmt (cfun, buffer->buffer->stream, stmt);
+ }
+
+ dump_implicit_edges (buffer, bb, indent, flags);
+
+ if (flags & TDF_BLOCKS)
+ dump_bb_end (buffer, bb, indent, flags);
+}
+
+
+/* Dumps basic block BB to FILE with details described by FLAGS and
+ indented by INDENT spaces. */
+
+void
+gimple_dump_bb (basic_block bb, FILE *file, int indent, int flags)
+{
+ maybe_init_pretty_print (file);
+ gimple_dump_bb_buff (&buffer, bb, indent, flags);
+ pp_flush (&buffer);
+}
diff --git a/gcc/gimple.c b/gcc/gimple.c
new file mode 100644
index 00000000000..69cfd4e1db8
--- /dev/null
+++ b/gcc/gimple.c
@@ -0,0 +1,3144 @@
+/* Gimple IR support functions.
+
+ Copyright 2007, 2008 Free Software Foundation, Inc.
+ Contributed by Aldy Hernandez <aldyh@redhat.com>
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tree.h"
+#include "ggc.h"
+#include "errors.h"
+#include "hard-reg-set.h"
+#include "basic-block.h"
+#include "gimple.h"
+#include "diagnostic.h"
+#include "tree-flow.h"
+#include "value-prof.h"
+#include "flags.h"
+
+#define DEFGSCODE(SYM, NAME, STRUCT) NAME,
+const char *const gimple_code_name[] = {
+#include "gimple.def"
+};
+#undef DEFGSCODE
+
+/* All the tuples have their operand vector at the very bottom
+ of the structure. Therefore, the offset required to find the
+ operands vector the size of the structure minus the size of the 1
+ element tree array at the end (see gimple_ops). */
+#define DEFGSCODE(SYM, NAME, STRUCT) (sizeof (STRUCT) - sizeof (tree)),
+const size_t gimple_ops_offset_[] = {
+#include "gimple.def"
+};
+#undef DEFGSCODE
+
+#ifdef GATHER_STATISTICS
+/* Gimple stats. */
+
+int gimple_alloc_counts[(int) gimple_alloc_kind_all];
+int gimple_alloc_sizes[(int) gimple_alloc_kind_all];
+
+/* Keep in sync with gimple.h:enum gimple_alloc_kind. */
+static const char * const gimple_alloc_kind_names[] = {
+ "assignments",
+ "phi nodes",
+ "conditionals",
+ "sequences",
+ "everything else"
+};
+
+#endif /* GATHER_STATISTICS */
+
+/* A cache of gimple_seq objects. Sequences are created and destroyed
+ fairly often during gimplification. */
+static GTY ((deletable)) struct gimple_seq_d *gimple_seq_cache;
+
+/* Private API manipulation functions shared only with some
+ other files. */
+extern void gimple_set_stored_syms (gimple, bitmap, bitmap_obstack *);
+extern void gimple_set_loaded_syms (gimple, bitmap, bitmap_obstack *);
+
+/* Gimple tuple constructors.
+ Note: Any constructor taking a ``gimple_seq'' as a parameter, can
+ be passed a NULL to start with an empty sequence. */
+
+/* Set the code for statement G to CODE. */
+
+static inline void
+gimple_set_code (gimple g, enum gimple_code code)
+{
+ g->gsbase.code = code;
+}
+
+
+/* Return the GSS_* identifier for the given GIMPLE statement CODE. */
+
+static enum gimple_statement_structure_enum
+gss_for_code (enum gimple_code code)
+{
+ switch (code)
+ {
+ case GIMPLE_ASSIGN:
+ case GIMPLE_CALL:
+ case GIMPLE_RETURN: return GSS_WITH_MEM_OPS;
+ case GIMPLE_COND:
+ case GIMPLE_GOTO:
+ case GIMPLE_LABEL:
+ case GIMPLE_CHANGE_DYNAMIC_TYPE:
+ case GIMPLE_SWITCH: return GSS_WITH_OPS;
+ case GIMPLE_ASM: return GSS_ASM;
+ case GIMPLE_BIND: return GSS_BIND;
+ case GIMPLE_CATCH: return GSS_CATCH;
+ case GIMPLE_EH_FILTER: return GSS_EH_FILTER;
+ case GIMPLE_NOP: return GSS_BASE;
+ case GIMPLE_PHI: return GSS_PHI;
+ case GIMPLE_RESX: return GSS_RESX;
+ case GIMPLE_TRY: return GSS_TRY;
+ case GIMPLE_WITH_CLEANUP_EXPR: return GSS_WCE;
+ case GIMPLE_OMP_CRITICAL: return GSS_OMP_CRITICAL;
+ case GIMPLE_OMP_FOR: return GSS_OMP_FOR;
+ case GIMPLE_OMP_MASTER:
+ case GIMPLE_OMP_ORDERED:
+ case GIMPLE_OMP_SECTION: return GSS_OMP;
+ case GIMPLE_OMP_RETURN:
+ case GIMPLE_OMP_SECTIONS_SWITCH: return GSS_BASE;
+ case GIMPLE_OMP_CONTINUE: return GSS_OMP_CONTINUE;
+ case GIMPLE_OMP_PARALLEL: return GSS_OMP_PARALLEL;
+ case GIMPLE_OMP_TASK: return GSS_OMP_TASK;
+ case GIMPLE_OMP_SECTIONS: return GSS_OMP_SECTIONS;
+ case GIMPLE_OMP_SINGLE: return GSS_OMP_SINGLE;
+ case GIMPLE_OMP_ATOMIC_LOAD: return GSS_OMP_ATOMIC_LOAD;
+ case GIMPLE_OMP_ATOMIC_STORE: return GSS_OMP_ATOMIC_STORE;
+ case GIMPLE_PREDICT: return GSS_BASE;
+ default: gcc_unreachable ();
+ }
+}
+
+
+/* Return the number of bytes needed to hold a GIMPLE statement with
+ code CODE. */
+
+static size_t
+gimple_size (enum gimple_code code)
+{
+ enum gimple_statement_structure_enum gss = gss_for_code (code);
+
+ if (gss == GSS_WITH_OPS)
+ return sizeof (struct gimple_statement_with_ops);
+ else if (gss == GSS_WITH_MEM_OPS)
+ return sizeof (struct gimple_statement_with_memory_ops);
+
+ switch (code)
+ {
+ case GIMPLE_ASM:
+ return sizeof (struct gimple_statement_asm);
+ case GIMPLE_NOP:
+ return sizeof (struct gimple_statement_base);
+ case GIMPLE_BIND:
+ return sizeof (struct gimple_statement_bind);
+ case GIMPLE_CATCH:
+ return sizeof (struct gimple_statement_catch);
+ case GIMPLE_EH_FILTER:
+ return sizeof (struct gimple_statement_eh_filter);
+ case GIMPLE_TRY:
+ return sizeof (struct gimple_statement_try);
+ case GIMPLE_RESX:
+ return sizeof (struct gimple_statement_resx);
+ case GIMPLE_OMP_CRITICAL:
+ return sizeof (struct gimple_statement_omp_critical);
+ case GIMPLE_OMP_FOR:
+ return sizeof (struct gimple_statement_omp_for);
+ case GIMPLE_OMP_PARALLEL:
+ return sizeof (struct gimple_statement_omp_parallel);
+ case GIMPLE_OMP_TASK:
+ return sizeof (struct gimple_statement_omp_task);
+ case GIMPLE_OMP_SECTION:
+ case GIMPLE_OMP_MASTER:
+ case GIMPLE_OMP_ORDERED:
+ return sizeof (struct gimple_statement_omp);
+ case GIMPLE_OMP_RETURN:
+ return sizeof (struct gimple_statement_base);
+ case GIMPLE_OMP_CONTINUE:
+ return sizeof (struct gimple_statement_omp_continue);
+ case GIMPLE_OMP_SECTIONS:
+ return sizeof (struct gimple_statement_omp_sections);
+ case GIMPLE_OMP_SECTIONS_SWITCH:
+ return sizeof (struct gimple_statement_base);
+ case GIMPLE_OMP_SINGLE:
+ return sizeof (struct gimple_statement_omp_single);
+ case GIMPLE_OMP_ATOMIC_LOAD:
+ return sizeof (struct gimple_statement_omp_atomic_load);
+ case GIMPLE_OMP_ATOMIC_STORE:
+ return sizeof (struct gimple_statement_omp_atomic_store);
+ case GIMPLE_WITH_CLEANUP_EXPR:
+ return sizeof (struct gimple_statement_wce);
+ case GIMPLE_CHANGE_DYNAMIC_TYPE:
+ return sizeof (struct gimple_statement_with_ops);
+ case GIMPLE_PREDICT:
+ return sizeof (struct gimple_statement_base);
+ default:
+ break;
+ }
+
+ gcc_unreachable ();
+}
+
+
+/* Allocate memory for a GIMPLE statement with code CODE and NUM_OPS
+ operands. */
+
+#define gimple_alloc(c, n) gimple_alloc_stat (c, n MEM_STAT_INFO)
+static gimple
+gimple_alloc_stat (enum gimple_code code, unsigned num_ops MEM_STAT_DECL)
+{
+ size_t size;
+ gimple stmt;
+
+ size = gimple_size (code);
+ if (num_ops > 0)
+ size += sizeof (tree) * (num_ops - 1);
+
+#ifdef GATHER_STATISTICS
+ {
+ enum gimple_alloc_kind kind = gimple_alloc_kind (code);
+ gimple_alloc_counts[(int) kind]++;
+ gimple_alloc_sizes[(int) kind] += size;
+ }
+#endif
+
+ stmt = (gimple) ggc_alloc_cleared_stat (size PASS_MEM_STAT);
+ gimple_set_code (stmt, code);
+ gimple_set_num_ops (stmt, num_ops);
+
+ /* Do not call gimple_set_modified here as it has other side
+ effects and this tuple is still not completely built. */
+ stmt->gsbase.modified = 1;
+
+ return stmt;
+}
+
+/* Set SUBCODE to be the code of the expression computed by statement G. */
+
+static inline void
+gimple_set_subcode (gimple g, unsigned subcode)
+{
+ /* We only have 16 bits for the RHS code. Assert that we are not
+ overflowing it. */
+ gcc_assert (subcode < (1 << 16));
+ g->gsbase.subcode = subcode;
+}
+
+
+
+/* Build a tuple with operands. CODE is the statement to build (which
+ must be one of the GIMPLE_WITH_OPS tuples). SUBCODE is the sub-code
+ for the new tuple. NUM_OPS is the number of operands to allocate. */
+
+#define gimple_build_with_ops(c, s, n) \
+ gimple_build_with_ops_stat (c, s, n MEM_STAT_INFO)
+
+static gimple
+gimple_build_with_ops_stat (enum gimple_code code, enum tree_code subcode,
+ unsigned num_ops MEM_STAT_DECL)
+{
+ gimple s = gimple_alloc_stat (code, num_ops PASS_MEM_STAT);
+ gimple_set_subcode (s, subcode);
+
+ return s;
+}
+
+
+/* Build a GIMPLE_RETURN statement returning RETVAL. */
+
+gimple
+gimple_build_return (tree retval)
+{
+ gimple s = gimple_build_with_ops (GIMPLE_RETURN, 0, 1);
+ if (retval)
+ gimple_return_set_retval (s, retval);
+ return s;
+}
+
+/* Helper for gimple_build_call, gimple_build_call_vec and
+ gimple_build_call_from_tree. Build the basic components of a
+ GIMPLE_CALL statement to function FN with NARGS arguments. */
+
+static inline gimple
+gimple_build_call_1 (tree fn, unsigned nargs)
+{
+ gimple s = gimple_build_with_ops (GIMPLE_CALL, 0, nargs + 3);
+ gimple_set_op (s, 1, fn);
+ return s;
+}
+
+
+/* Build a GIMPLE_CALL statement to function FN with the arguments
+ specified in vector ARGS. */
+
+gimple
+gimple_build_call_vec (tree fn, VEC(tree, heap) *args)
+{
+ unsigned i;
+ unsigned nargs = VEC_length (tree, args);
+ gimple call = gimple_build_call_1 (fn, nargs);
+
+ for (i = 0; i < nargs; i++)
+ gimple_call_set_arg (call, i, VEC_index (tree, args, i));
+
+ return call;
+}
+
+
+/* Build a GIMPLE_CALL statement to function FN. NARGS is the number of
+ arguments. The ... are the arguments. */
+
+gimple
+gimple_build_call (tree fn, unsigned nargs, ...)
+{
+ va_list ap;
+ gimple call;
+ unsigned i;
+
+ gcc_assert (TREE_CODE (fn) == FUNCTION_DECL || is_gimple_call_addr (fn));
+
+ call = gimple_build_call_1 (fn, nargs);
+
+ va_start (ap, nargs);
+ for (i = 0; i < nargs; i++)
+ gimple_call_set_arg (call, i, va_arg (ap, tree));
+ va_end (ap);
+
+ return call;
+}
+
+
+/* Build a GIMPLE_CALL statement from CALL_EXPR T. Note that T is
+ assumed to be in GIMPLE form already. Minimal checking is done of
+ this fact. */
+
+gimple
+gimple_build_call_from_tree (tree t)
+{
+ unsigned i, nargs;
+ gimple call;
+ tree fndecl = get_callee_fndecl (t);
+
+ gcc_assert (TREE_CODE (t) == CALL_EXPR);
+
+ nargs = call_expr_nargs (t);
+ call = gimple_build_call_1 (fndecl ? fndecl : CALL_EXPR_FN (t), nargs);
+
+ for (i = 0; i < nargs; i++)
+ gimple_call_set_arg (call, i, CALL_EXPR_ARG (t, i));
+
+ gimple_set_block (call, TREE_BLOCK (t));
+
+ /* Carry all the CALL_EXPR flags to the new GIMPLE_CALL. */
+ gimple_call_set_chain (call, CALL_EXPR_STATIC_CHAIN (t));
+ gimple_call_set_tail (call, CALL_EXPR_TAILCALL (t));
+ gimple_call_set_cannot_inline (call, CALL_CANNOT_INLINE_P (t));
+ gimple_call_set_return_slot_opt (call, CALL_EXPR_RETURN_SLOT_OPT (t));
+ gimple_call_set_from_thunk (call, CALL_FROM_THUNK_P (t));
+ gimple_call_set_va_arg_pack (call, CALL_EXPR_VA_ARG_PACK (t));
+
+ return call;
+}
+
+
+/* Extract the operands and code for expression EXPR into *SUBCODE_P,
+ *OP1_P and *OP2_P respectively. */
+
+void
+extract_ops_from_tree (tree expr, enum tree_code *subcode_p, tree *op1_p,
+ tree *op2_p)
+{
+ enum gimple_rhs_class class;
+
+ *subcode_p = TREE_CODE (expr);
+ class = get_gimple_rhs_class (*subcode_p);
+
+ if (class == GIMPLE_BINARY_RHS)
+ {
+ *op1_p = TREE_OPERAND (expr, 0);
+ *op2_p = TREE_OPERAND (expr, 1);
+ }
+ else if (class == GIMPLE_UNARY_RHS)
+ {
+ *op1_p = TREE_OPERAND (expr, 0);
+ *op2_p = NULL_TREE;
+ }
+ else if (class == GIMPLE_SINGLE_RHS)
+ {
+ *op1_p = expr;
+ *op2_p = NULL_TREE;
+ }
+ else
+ gcc_unreachable ();
+}
+
+
+/* Build a GIMPLE_ASSIGN statement.
+
+ LHS of the assignment.
+ RHS of the assignment which can be unary or binary. */
+
+gimple
+gimple_build_assign_stat (tree lhs, tree rhs MEM_STAT_DECL)
+{
+ enum tree_code subcode;
+ tree op1, op2;
+
+ extract_ops_from_tree (rhs, &subcode, &op1, &op2);
+ return gimple_build_assign_with_ops_stat (subcode, lhs, op1, op2
+ PASS_MEM_STAT);
+}
+
+
+/* Build a GIMPLE_ASSIGN statement with sub-code SUBCODE and operands
+ OP1 and OP2. If OP2 is NULL then SUBCODE must be of class
+ GIMPLE_UNARY_RHS or GIMPLE_SINGLE_RHS. */
+
+gimple
+gimple_build_assign_with_ops_stat (enum tree_code subcode, tree lhs, tree op1,
+ tree op2 MEM_STAT_DECL)
+{
+ unsigned num_ops;
+ gimple p;
+
+ /* Need 1 operand for LHS and 1 or 2 for the RHS (depending on the
+ code). */
+ num_ops = get_gimple_rhs_num_ops (subcode) + 1;
+
+ p = gimple_build_with_ops_stat (GIMPLE_ASSIGN, subcode, num_ops
+ PASS_MEM_STAT);
+ gimple_assign_set_lhs (p, lhs);
+ gimple_assign_set_rhs1 (p, op1);
+ if (op2)
+ {
+ gcc_assert (num_ops > 2);
+ gimple_assign_set_rhs2 (p, op2);
+ }
+
+ return p;
+}
+
+
+/* Build a new GIMPLE_ASSIGN tuple and append it to the end of *SEQ_P.
+
+ DST/SRC are the destination and source respectively. You can pass
+ ungimplified trees in DST or SRC, in which case they will be
+ converted to a gimple operand if necessary.
+
+ This function returns the newly created GIMPLE_ASSIGN tuple. */
+
+inline gimple
+gimplify_assign (tree dst, tree src, gimple_seq *seq_p)
+{
+ tree t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
+ gimplify_and_add (t, seq_p);
+ ggc_free (t);
+ return gimple_seq_last_stmt (*seq_p);
+}
+
+
+/* Build a GIMPLE_COND statement.
+
+ PRED is the condition used to compare LHS and the RHS.
+ T_LABEL is the label to jump to if the condition is true.
+ F_LABEL is the label to jump to otherwise. */
+
+gimple
+gimple_build_cond (enum tree_code pred_code, tree lhs, tree rhs,
+ tree t_label, tree f_label)
+{
+ gimple p;
+
+ gcc_assert (TREE_CODE_CLASS (pred_code) == tcc_comparison);
+ p = gimple_build_with_ops (GIMPLE_COND, pred_code, 4);
+ gimple_cond_set_lhs (p, lhs);
+ gimple_cond_set_rhs (p, rhs);
+ gimple_cond_set_true_label (p, t_label);
+ gimple_cond_set_false_label (p, f_label);
+ return p;
+}
+
+
+/* Extract operands for a GIMPLE_COND statement out of COND_EXPR tree COND. */
+
+void
+gimple_cond_get_ops_from_tree (tree cond, enum tree_code *code_p,
+ tree *lhs_p, tree *rhs_p)
+{
+ gcc_assert (TREE_CODE_CLASS (TREE_CODE (cond)) == tcc_comparison
+ || TREE_CODE (cond) == TRUTH_NOT_EXPR
+ || is_gimple_min_invariant (cond)
+ || SSA_VAR_P (cond));
+
+ extract_ops_from_tree (cond, code_p, lhs_p, rhs_p);
+
+ /* Canonicalize conditionals of the form 'if (!VAL)'. */
+ if (*code_p == TRUTH_NOT_EXPR)
+ {
+ *code_p = EQ_EXPR;
+ gcc_assert (*lhs_p && *rhs_p == NULL_TREE);
+ *rhs_p = fold_convert (TREE_TYPE (*lhs_p), integer_zero_node);
+ }
+ /* Canonicalize conditionals of the form 'if (VAL)' */
+ else if (TREE_CODE_CLASS (*code_p) != tcc_comparison)
+ {
+ *code_p = NE_EXPR;
+ gcc_assert (*lhs_p && *rhs_p == NULL_TREE);
+ *rhs_p = fold_convert (TREE_TYPE (*lhs_p), integer_zero_node);
+ }
+}
+
+
+/* Build a GIMPLE_COND statement from the conditional expression tree
+ COND. T_LABEL and F_LABEL are as in gimple_build_cond. */
+
+gimple
+gimple_build_cond_from_tree (tree cond, tree t_label, tree f_label)
+{
+ enum tree_code code;
+ tree lhs, rhs;
+
+ gimple_cond_get_ops_from_tree (cond, &code, &lhs, &rhs);
+ return gimple_build_cond (code, lhs, rhs, t_label, f_label);
+}
+
+/* Set code, lhs, and rhs of a GIMPLE_COND from a suitable
+ boolean expression tree COND. */
+
+void
+gimple_cond_set_condition_from_tree (gimple stmt, tree cond)
+{
+ enum tree_code code;
+ tree lhs, rhs;
+
+ gimple_cond_get_ops_from_tree (cond, &code, &lhs, &rhs);
+ gimple_cond_set_condition (stmt, code, lhs, rhs);
+}
+
+/* Build a GIMPLE_LABEL statement for LABEL. */
+
+gimple
+gimple_build_label (tree label)
+{
+ gimple p = gimple_build_with_ops (GIMPLE_LABEL, 0, 1);
+ gimple_label_set_label (p, label);
+ return p;
+}
+
+/* Build a GIMPLE_GOTO statement to label DEST. */
+
+gimple
+gimple_build_goto (tree dest)
+{
+ gimple p = gimple_build_with_ops (GIMPLE_GOTO, 0, 1);
+ gimple_goto_set_dest (p, dest);
+ return p;
+}
+
+
+/* Build a GIMPLE_NOP statement. */
+
+gimple
+gimple_build_nop (void)
+{
+ return gimple_alloc (GIMPLE_NOP, 0);
+}
+
+
+/* Build a GIMPLE_BIND statement.
+ VARS are the variables in BODY.
+ BLOCK is the containing block. */
+
+gimple
+gimple_build_bind (tree vars, gimple_seq body, tree block)
+{
+ gimple p = gimple_alloc (GIMPLE_BIND, 0);
+ gimple_bind_set_vars (p, vars);
+ if (body)
+ gimple_bind_set_body (p, body);
+ if (block)
+ gimple_bind_set_block (p, block);
+ return p;
+}
+
+/* Helper function to set the simple fields of a asm stmt.
+
+ STRING is a pointer to a string that is the asm blocks assembly code.
+ NINPUT is the number of register inputs.
+ NOUTPUT is the number of register outputs.
+ NCLOBBERS is the number of clobbered registers.
+ */
+
+static inline gimple
+gimple_build_asm_1 (const char *string, unsigned ninputs, unsigned noutputs,
+ unsigned nclobbers)
+{
+ gimple p;
+ int size = strlen (string);
+
+ p = gimple_build_with_ops (GIMPLE_ASM, 0, ninputs + noutputs + nclobbers);
+
+ p->gimple_asm.ni = ninputs;
+ p->gimple_asm.no = noutputs;
+ p->gimple_asm.nc = nclobbers;
+ p->gimple_asm.string = ggc_alloc_string (string, size);
+
+#ifdef GATHER_STATISTICS
+ gimple_alloc_sizes[(int) gimple_alloc_kind (GIMPLE_ASM)] += size;
+#endif
+
+ return p;
+}
+
+/* Build a GIMPLE_ASM statement.
+
+ STRING is the assembly code.
+ NINPUT is the number of register inputs.
+ NOUTPUT is the number of register outputs.
+ NCLOBBERS is the number of clobbered registers.
+ INPUTS is a vector of the input register parameters.
+ OUTPUTS is a vector of the output register parameters.
+ CLOBBERS is a vector of the clobbered register parameters. */
+
+gimple
+gimple_build_asm_vec (const char *string, VEC(tree,gc)* inputs,
+ VEC(tree,gc)* outputs, VEC(tree,gc)* clobbers)
+{
+ gimple p;
+ unsigned i;
+
+ p = gimple_build_asm_1 (string,
+ VEC_length (tree, inputs),
+ VEC_length (tree, outputs),
+ VEC_length (tree, clobbers));
+
+ for (i = 0; i < VEC_length (tree, inputs); i++)
+ gimple_asm_set_input_op (p, i, VEC_index (tree, inputs, i));
+
+ for (i = 0; i < VEC_length (tree, outputs); i++)
+ gimple_asm_set_output_op (p, i, VEC_index (tree, outputs, i));
+
+ for (i = 0; i < VEC_length (tree, clobbers); i++)
+ gimple_asm_set_clobber_op (p, i, VEC_index (tree, clobbers, i));
+
+ return p;
+}
+
+/* Build a GIMPLE_ASM statement.
+
+ STRING is the assembly code.
+ NINPUT is the number of register inputs.
+ NOUTPUT is the number of register outputs.
+ NCLOBBERS is the number of clobbered registers.
+ ... are trees for each input, output and clobbered register. */
+
+gimple
+gimple_build_asm (const char *string, unsigned ninputs, unsigned noutputs,
+ unsigned nclobbers, ...)
+{
+ gimple p;
+ unsigned i;
+ va_list ap;
+
+ p = gimple_build_asm_1 (string, ninputs, noutputs, nclobbers);
+
+ va_start (ap, nclobbers);
+
+ for (i = 0; i < ninputs; i++)
+ gimple_asm_set_input_op (p, i, va_arg (ap, tree));
+
+ for (i = 0; i < noutputs; i++)
+ gimple_asm_set_output_op (p, i, va_arg (ap, tree));
+
+ for (i = 0; i < nclobbers; i++)
+ gimple_asm_set_clobber_op (p, i, va_arg (ap, tree));
+
+ va_end (ap);
+
+ return p;
+}
+
+/* Build a GIMPLE_CATCH statement.
+
+ TYPES are the catch types.
+ HANDLER is the exception handler. */
+
+gimple
+gimple_build_catch (tree types, gimple_seq handler)
+{
+ gimple p = gimple_alloc (GIMPLE_CATCH, 0);
+ gimple_catch_set_types (p, types);
+ if (handler)
+ gimple_catch_set_handler (p, handler);
+
+ return p;
+}
+
+/* Build a GIMPLE_EH_FILTER statement.
+
+ TYPES are the filter's types.
+ FAILURE is the filter's failure action. */
+
+gimple
+gimple_build_eh_filter (tree types, gimple_seq failure)
+{
+ gimple p = gimple_alloc (GIMPLE_EH_FILTER, 0);
+ gimple_eh_filter_set_types (p, types);
+ if (failure)
+ gimple_eh_filter_set_failure (p, failure);
+
+ return p;
+}
+
+/* Build a GIMPLE_TRY statement.
+
+ EVAL is the expression to evaluate.
+ CLEANUP is the cleanup expression.
+ KIND is either GIMPLE_TRY_CATCH or GIMPLE_TRY_FINALLY depending on
+ whether this is a try/catch or a try/finally respectively. */
+
+gimple
+gimple_build_try (gimple_seq eval, gimple_seq cleanup,
+ enum gimple_try_flags kind)
+{
+ gimple p;
+
+ gcc_assert (kind == GIMPLE_TRY_CATCH || kind == GIMPLE_TRY_FINALLY);
+ p = gimple_alloc (GIMPLE_TRY, 0);
+ gimple_set_subcode (p, kind);
+ if (eval)
+ gimple_try_set_eval (p, eval);
+ if (cleanup)
+ gimple_try_set_cleanup (p, cleanup);
+
+ return p;
+}
+
+/* Construct a GIMPLE_WITH_CLEANUP_EXPR statement.
+
+ CLEANUP is the cleanup expression. */
+
+gimple
+gimple_build_wce (gimple_seq cleanup)
+{
+ gimple p = gimple_alloc (GIMPLE_WITH_CLEANUP_EXPR, 0);
+ if (cleanup)
+ gimple_wce_set_cleanup (p, cleanup);
+
+ return p;
+}
+
+
+/* Build a GIMPLE_RESX statement.
+
+ REGION is the region number from which this resx causes control flow to
+ leave. */
+
+gimple
+gimple_build_resx (int region)
+{
+ gimple p = gimple_alloc (GIMPLE_RESX, 0);
+ gimple_resx_set_region (p, region);
+ return p;
+}
+
+
+/* The helper for constructing a gimple switch statement.
+ INDEX is the switch's index.
+ NLABELS is the number of labels in the switch excluding the default.
+ DEFAULT_LABEL is the default label for the switch statement. */
+
+static inline gimple
+gimple_build_switch_1 (unsigned nlabels, tree index, tree default_label)
+{
+ /* nlabels + 1 default label + 1 index. */
+ gimple p = gimple_build_with_ops (GIMPLE_SWITCH, 0, nlabels + 1 + 1);
+ gimple_switch_set_index (p, index);
+ gimple_switch_set_default_label (p, default_label);
+ return p;
+}
+
+
+/* Build a GIMPLE_SWITCH statement.
+
+ INDEX is the switch's index.
+ NLABELS is the number of labels in the switch excluding the DEFAULT_LABEL.
+ ... are the labels excluding the default. */
+
+gimple
+gimple_build_switch (unsigned nlabels, tree index, tree default_label, ...)
+{
+ va_list al;
+ unsigned i;
+ gimple p;
+
+ p = gimple_build_switch_1 (nlabels, index, default_label);
+
+ /* Store the rest of the labels. */
+ va_start (al, default_label);
+ for (i = 1; i <= nlabels; i++)
+ gimple_switch_set_label (p, i, va_arg (al, tree));
+ va_end (al);
+
+ return p;
+}
+
+
+/* Build a GIMPLE_SWITCH statement.
+
+ INDEX is the switch's index.
+ DEFAULT_LABEL is the default label
+ ARGS is a vector of labels excluding the default. */
+
+gimple
+gimple_build_switch_vec (tree index, tree default_label, VEC(tree, heap) *args)
+{
+ unsigned i;
+ unsigned nlabels = VEC_length (tree, args);
+ gimple p = gimple_build_switch_1 (nlabels, index, default_label);
+
+ /* Put labels in labels[1 - (nlabels + 1)].
+ Default label is in labels[0]. */
+ for (i = 1; i <= nlabels; i++)
+ gimple_switch_set_label (p, i, VEC_index (tree, args, i - 1));
+
+ return p;
+}
+
+
+/* Build a GIMPLE_OMP_CRITICAL statement.
+
+ BODY is the sequence of statements for which only one thread can execute.
+ NAME is optional identifier for this critical block. */
+
+gimple
+gimple_build_omp_critical (gimple_seq body, tree name)
+{
+ gimple p = gimple_alloc (GIMPLE_OMP_CRITICAL, 0);
+ gimple_omp_critical_set_name (p, name);
+ if (body)
+ gimple_omp_set_body (p, body);
+
+ return p;
+}
+
+/* Build a GIMPLE_OMP_FOR statement.
+
+ BODY is sequence of statements inside the for loop.
+ CLAUSES, are any of the OMP loop construct's clauses: private, firstprivate,
+ lastprivate, reductions, ordered, schedule, and nowait.
+ COLLAPSE is the collapse count.
+ PRE_BODY is the sequence of statements that are loop invariant. */
+
+gimple
+gimple_build_omp_for (gimple_seq body, tree clauses, size_t collapse,
+ gimple_seq pre_body)
+{
+ gimple p = gimple_alloc (GIMPLE_OMP_FOR, 0);
+ if (body)
+ gimple_omp_set_body (p, body);
+ gimple_omp_for_set_clauses (p, clauses);
+ p->gimple_omp_for.collapse = collapse;
+ p->gimple_omp_for.iter = GGC_CNEWVEC (struct gimple_omp_for_iter, collapse);
+ if (pre_body)
+ gimple_omp_for_set_pre_body (p, pre_body);
+
+ return p;
+}
+
+
+/* Build a GIMPLE_OMP_PARALLEL statement.
+
+ BODY is sequence of statements which are executed in parallel.
+ CLAUSES, are the OMP parallel construct's clauses.
+ CHILD_FN is the function created for the parallel threads to execute.
+ DATA_ARG are the shared data argument(s). */
+
+gimple
+gimple_build_omp_parallel (gimple_seq body, tree clauses, tree child_fn,
+ tree data_arg)
+{
+ gimple p = gimple_alloc (GIMPLE_OMP_PARALLEL, 0);
+ if (body)
+ gimple_omp_set_body (p, body);
+ gimple_omp_parallel_set_clauses (p, clauses);
+ gimple_omp_parallel_set_child_fn (p, child_fn);
+ gimple_omp_parallel_set_data_arg (p, data_arg);
+
+ return p;
+}
+
+
+/* Build a GIMPLE_OMP_TASK statement.
+
+ BODY is sequence of statements which are executed by the explicit task.
+ CLAUSES, are the OMP parallel construct's clauses.
+ CHILD_FN is the function created for the parallel threads to execute.
+ DATA_ARG are the shared data argument(s).
+ COPY_FN is the optional function for firstprivate initialization.
+ ARG_SIZE and ARG_ALIGN are size and alignment of the data block. */
+
+gimple
+gimple_build_omp_task (gimple_seq body, tree clauses, tree child_fn,
+ tree data_arg, tree copy_fn, tree arg_size,
+ tree arg_align)
+{
+ gimple p = gimple_alloc (GIMPLE_OMP_TASK, 0);
+ if (body)
+ gimple_omp_set_body (p, body);
+ gimple_omp_task_set_clauses (p, clauses);
+ gimple_omp_task_set_child_fn (p, child_fn);
+ gimple_omp_task_set_data_arg (p, data_arg);
+ gimple_omp_task_set_copy_fn (p, copy_fn);
+ gimple_omp_task_set_arg_size (p, arg_size);
+ gimple_omp_task_set_arg_align (p, arg_align);
+
+ return p;
+}
+
+
+/* Build a GIMPLE_OMP_SECTION statement for a sections statement.
+
+ BODY is the sequence of statements in the section. */
+
+gimple
+gimple_build_omp_section (gimple_seq body)
+{
+ gimple p = gimple_alloc (GIMPLE_OMP_SECTION, 0);
+ if (body)
+ gimple_omp_set_body (p, body);
+
+ return p;
+}
+
+
+/* Build a GIMPLE_OMP_MASTER statement.
+
+ BODY is the sequence of statements to be executed by just the master. */
+
+gimple
+gimple_build_omp_master (gimple_seq body)
+{
+ gimple p = gimple_alloc (GIMPLE_OMP_MASTER, 0);
+ if (body)
+ gimple_omp_set_body (p, body);
+
+ return p;
+}
+
+
+/* Build a GIMPLE_OMP_CONTINUE statement.
+
+ CONTROL_DEF is the definition of the control variable.
+ CONTROL_USE is the use of the control variable. */
+
+gimple
+gimple_build_omp_continue (tree control_def, tree control_use)
+{
+ gimple p = gimple_alloc (GIMPLE_OMP_CONTINUE, 0);
+ gimple_omp_continue_set_control_def (p, control_def);
+ gimple_omp_continue_set_control_use (p, control_use);
+ return p;
+}
+
+/* Build a GIMPLE_OMP_ORDERED statement.
+
+ BODY is the sequence of statements inside a loop that will executed in
+ sequence. */
+
+gimple
+gimple_build_omp_ordered (gimple_seq body)
+{
+ gimple p = gimple_alloc (GIMPLE_OMP_ORDERED, 0);
+ if (body)
+ gimple_omp_set_body (p, body);
+
+ return p;
+}
+
+
+/* Build a GIMPLE_OMP_RETURN statement.
+ WAIT_P is true if this is a non-waiting return. */
+
+gimple
+gimple_build_omp_return (bool wait_p)
+{
+ gimple p = gimple_alloc (GIMPLE_OMP_RETURN, 0);
+ if (wait_p)
+ gimple_omp_return_set_nowait (p);
+
+ return p;
+}
+
+
+/* Build a GIMPLE_OMP_SECTIONS statement.
+
+ BODY is a sequence of section statements.
+ CLAUSES are any of the OMP sections contsruct's clauses: private,
+ firstprivate, lastprivate, reduction, and nowait. */
+
+gimple
+gimple_build_omp_sections (gimple_seq body, tree clauses)
+{
+ gimple p = gimple_alloc (GIMPLE_OMP_SECTIONS, 0);
+ if (body)
+ gimple_omp_set_body (p, body);
+ gimple_omp_sections_set_clauses (p, clauses);
+
+ return p;
+}
+
+
+/* Build a GIMPLE_OMP_SECTIONS_SWITCH. */
+
+gimple
+gimple_build_omp_sections_switch (void)
+{
+ return gimple_alloc (GIMPLE_OMP_SECTIONS_SWITCH, 0);
+}
+
+
+/* Build a GIMPLE_OMP_SINGLE statement.
+
+ BODY is the sequence of statements that will be executed once.
+ CLAUSES are any of the OMP single construct's clauses: private, firstprivate,
+ copyprivate, nowait. */
+
+gimple
+gimple_build_omp_single (gimple_seq body, tree clauses)
+{
+ gimple p = gimple_alloc (GIMPLE_OMP_SINGLE, 0);
+ if (body)
+ gimple_omp_set_body (p, body);
+ gimple_omp_single_set_clauses (p, clauses);
+
+ return p;
+}
+
+
+/* Build a GIMPLE_CHANGE_DYNAMIC_TYPE statement. TYPE is the new type
+ for the location PTR. */
+
+gimple
+gimple_build_cdt (tree type, tree ptr)
+{
+ gimple p = gimple_build_with_ops (GIMPLE_CHANGE_DYNAMIC_TYPE, 0, 2);
+ gimple_cdt_set_new_type (p, type);
+ gimple_cdt_set_location (p, ptr);
+
+ return p;
+}
+
+
+/* Build a GIMPLE_OMP_ATOMIC_LOAD statement. */
+
+gimple
+gimple_build_omp_atomic_load (tree lhs, tree rhs)
+{
+ gimple p = gimple_alloc (GIMPLE_OMP_ATOMIC_LOAD, 0);
+ gimple_omp_atomic_load_set_lhs (p, lhs);
+ gimple_omp_atomic_load_set_rhs (p, rhs);
+ return p;
+}
+
+/* Build a GIMPLE_OMP_ATOMIC_STORE statement.
+
+ VAL is the value we are storing. */
+
+gimple
+gimple_build_omp_atomic_store (tree val)
+{
+ gimple p = gimple_alloc (GIMPLE_OMP_ATOMIC_STORE, 0);
+ gimple_omp_atomic_store_set_val (p, val);
+ return p;
+}
+
+/* Build a GIMPLE_PREDICT statement. PREDICT is one of the predictors from
+ predict.def, OUTCOME is NOT_TAKEN or TAKEN. */
+
+gimple
+gimple_build_predict (enum br_predictor predictor, enum prediction outcome)
+{
+ gimple p = gimple_alloc (GIMPLE_PREDICT, 0);
+ /* Ensure all the predictors fit into the lower bits of the subcode. */
+ gcc_assert (END_PREDICTORS <= GF_PREDICT_TAKEN);
+ gimple_predict_set_predictor (p, predictor);
+ gimple_predict_set_outcome (p, outcome);
+ return p;
+}
+
+/* Return which gimple structure is used by T. The enums here are defined
+ in gsstruct.def. */
+
+enum gimple_statement_structure_enum
+gimple_statement_structure (gimple gs)
+{
+ return gss_for_code (gimple_code (gs));
+}
+
+#if defined ENABLE_GIMPLE_CHECKING && (GCC_VERSION >= 2007)
+/* Complain of a gimple type mismatch and die. */
+
+void
+gimple_check_failed (const_gimple gs, const char *file, int line,
+ const char *function, enum gimple_code code,
+ enum tree_code subcode)
+{
+ internal_error ("gimple check: expected %s(%s), have %s(%s) in %s, at %s:%d",
+ gimple_code_name[code],
+ tree_code_name[subcode],
+ gimple_code_name[gimple_code (gs)],
+ gs->gsbase.subcode > 0
+ ? tree_code_name[gs->gsbase.subcode]
+ : "",
+ function, trim_filename (file), line);
+}
+
+
+/* Similar to gimple_check_failed, except that instead of specifying a
+ dozen codes, use the knowledge that they're all sequential. */
+
+void
+gimple_range_check_failed (const_gimple gs, const char *file, int line,
+ const char *function, enum gimple_code c1,
+ enum gimple_code c2)
+{
+ char *buffer;
+ unsigned length = 0;
+ enum gimple_code c;
+
+ for (c = c1; c <= c2; ++c)
+ length += 4 + strlen (gimple_code_name[c]);
+
+ length += strlen ("expected ");
+ buffer = XALLOCAVAR (char, length);
+ length = 0;
+
+ for (c = c1; c <= c2; ++c)
+ {
+ const char *prefix = length ? " or " : "expected ";
+
+ strcpy (buffer + length, prefix);
+ length += strlen (prefix);
+ strcpy (buffer + length, gimple_code_name[c]);
+ length += strlen (gimple_code_name[c]);
+ }
+
+ internal_error ("gimple check: %s, have %s in %s, at %s:%d",
+ buffer, gimple_code_name[gimple_code (gs)],
+ function, trim_filename (file), line);
+}
+#endif /* ENABLE_GIMPLE_CHECKING */
+
+
+/* Allocate a new GIMPLE sequence in GC memory and return it. If
+ there are free sequences in GIMPLE_SEQ_CACHE return one of those
+ instead. */
+
+gimple_seq
+gimple_seq_alloc (void)
+{
+ gimple_seq seq = gimple_seq_cache;
+ if (seq)
+ {
+ gimple_seq_cache = gimple_seq_cache->next_free;
+ gcc_assert (gimple_seq_cache != seq);
+ memset (seq, 0, sizeof (*seq));
+ }
+ else
+ {
+ seq = (gimple_seq) ggc_alloc_cleared (sizeof (*seq));
+#ifdef GATHER_STATISTICS
+ gimple_alloc_counts[(int) gimple_alloc_kind_seq]++;
+ gimple_alloc_sizes[(int) gimple_alloc_kind_seq] += sizeof (*seq);
+#endif
+ }
+
+ return seq;
+}
+
+/* Return SEQ to the free pool of GIMPLE sequences. */
+
+void
+gimple_seq_free (gimple_seq seq)
+{
+ if (seq == NULL)
+ return;
+
+ gcc_assert (gimple_seq_first (seq) == NULL);
+ gcc_assert (gimple_seq_last (seq) == NULL);
+
+ /* If this triggers, it's a sign that the same list is being freed
+ twice. */
+ gcc_assert (seq != gimple_seq_cache || gimple_seq_cache == NULL);
+
+ /* Add SEQ to the pool of free sequences. */
+ seq->next_free = gimple_seq_cache;
+ gimple_seq_cache = seq;
+}
+
+
+/* Link gimple statement GS to the end of the sequence *SEQ_P. If
+ *SEQ_P is NULL, a new sequence is allocated. */
+
+void
+gimple_seq_add_stmt (gimple_seq *seq_p, gimple gs)
+{
+ gimple_stmt_iterator si;
+
+ if (gs == NULL)
+ return;
+
+ if (*seq_p == NULL)
+ *seq_p = gimple_seq_alloc ();
+
+ si = gsi_last (*seq_p);
+ gsi_insert_after (&si, gs, GSI_NEW_STMT);
+}
+
+
+/* Append sequence SRC to the end of sequence *DST_P. If *DST_P is
+ NULL, a new sequence is allocated. */
+
+void
+gimple_seq_add_seq (gimple_seq *dst_p, gimple_seq src)
+{
+ gimple_stmt_iterator si;
+
+ if (src == NULL)
+ return;
+
+ if (*dst_p == NULL)
+ *dst_p = gimple_seq_alloc ();
+
+ si = gsi_last (*dst_p);
+ gsi_insert_seq_after (&si, src, GSI_NEW_STMT);
+}
+
+
+/* Helper function of empty_body_p. Return true if STMT is an empty
+ statement. */
+
+static bool
+empty_stmt_p (gimple stmt)
+{
+ if (gimple_code (stmt) == GIMPLE_NOP)
+ return true;
+ if (gimple_code (stmt) == GIMPLE_BIND)
+ return empty_body_p (gimple_bind_body (stmt));
+ return false;
+}
+
+
+/* Return true if BODY contains nothing but empty statements. */
+
+bool
+empty_body_p (gimple_seq body)
+{
+ gimple_stmt_iterator i;
+
+
+ if (gimple_seq_empty_p (body))
+ return true;
+ for (i = gsi_start (body); !gsi_end_p (i); gsi_next (&i))
+ if (!empty_stmt_p (gsi_stmt (i)))
+ return false;
+
+ return true;
+}
+
+
+/* Perform a deep copy of sequence SRC and return the result. */
+
+gimple_seq
+gimple_seq_copy (gimple_seq src)
+{
+ gimple_stmt_iterator gsi;
+ gimple_seq new = gimple_seq_alloc ();
+ gimple stmt;
+
+ for (gsi = gsi_start (src); !gsi_end_p (gsi); gsi_next (&gsi))
+ {
+ stmt = gimple_copy (gsi_stmt (gsi));
+ gimple_seq_add_stmt (&new, stmt);
+ }
+
+ return new;
+}
+
+
+/* Walk all the statements in the sequence SEQ calling walk_gimple_stmt
+ on each one. WI is as in walk_gimple_stmt.
+
+ If walk_gimple_stmt returns non-NULL, the walk is stopped, the
+ value is stored in WI->CALLBACK_RESULT and the statement that
+ produced the value is returned.
+
+ Otherwise, all the statements are walked and NULL returned. */
+
+gimple
+walk_gimple_seq (gimple_seq seq, walk_stmt_fn callback_stmt,
+ walk_tree_fn callback_op, struct walk_stmt_info *wi)
+{
+ gimple_stmt_iterator gsi;
+
+ for (gsi = gsi_start (seq); !gsi_end_p (gsi); gsi_next (&gsi))
+ {
+ tree ret = walk_gimple_stmt (&gsi, callback_stmt, callback_op, wi);
+ if (ret)
+ {
+ /* If CALLBACK_STMT or CALLBACK_OP return a value, WI must exist
+ to hold it. */
+ gcc_assert (wi);
+ wi->callback_result = ret;
+ return gsi_stmt (gsi);
+ }
+ }
+
+ if (wi)
+ wi->callback_result = NULL_TREE;
+
+ return NULL;
+}
+
+
+/* Helper function for walk_gimple_stmt. Walk operands of a GIMPLE_ASM. */
+
+static tree
+walk_gimple_asm (gimple stmt, walk_tree_fn callback_op,
+ struct walk_stmt_info *wi)
+{
+ tree ret;
+ unsigned noutputs;
+ const char **oconstraints;
+ unsigned i;
+ const char *constraint;
+ bool allows_mem, allows_reg, is_inout;
+
+ noutputs = gimple_asm_noutputs (stmt);
+ oconstraints = (const char **) alloca ((noutputs) * sizeof (const char *));
+
+ if (wi)
+ wi->is_lhs = true;
+
+ for (i = 0; i < noutputs; i++)
+ {
+ tree op = gimple_asm_output_op (stmt, i);
+ constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (op)));
+ oconstraints[i] = constraint;
+ parse_output_constraint (&constraint, i, 0, 0, &allows_mem, &allows_reg,
+ &is_inout);
+ if (wi)
+ wi->val_only = (allows_reg || !allows_mem);
+ ret = walk_tree (&TREE_VALUE (op), callback_op, wi, NULL);
+ if (ret)
+ return ret;
+ }
+
+ for (i = 0; i < gimple_asm_ninputs (stmt); i++)
+ {
+ tree op = gimple_asm_input_op (stmt, i);
+ constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (op)));
+ parse_input_constraint (&constraint, 0, 0, noutputs, 0,
+ oconstraints, &allows_mem, &allows_reg);
+ if (wi)
+ wi->val_only = (allows_reg || !allows_mem);
+
+ /* Although input "m" is not really a LHS, we need a lvalue. */
+ if (wi)
+ wi->is_lhs = !wi->val_only;
+ ret = walk_tree (&TREE_VALUE (op), callback_op, wi, NULL);
+ if (ret)
+ return ret;
+ }
+
+ if (wi)
+ {
+ wi->is_lhs = false;
+ wi->val_only = true;
+ }
+
+ return NULL_TREE;
+}
+
+
+/* Helper function of WALK_GIMPLE_STMT. Walk every tree operand in
+ STMT. CALLBACK_OP and WI are as in WALK_GIMPLE_STMT.
+
+ CALLBACK_OP is called on each operand of STMT via walk_tree.
+ Additional parameters to walk_tree must be stored in WI. For each operand
+ OP, walk_tree is called as:
+
+ walk_tree (&OP, CALLBACK_OP, WI, WI->PSET)
+
+ If CALLBACK_OP returns non-NULL for an operand, the remaining
+ operands are not scanned.
+
+ The return value is that returned by the last call to walk_tree, or
+ NULL_TREE if no CALLBACK_OP is specified. */
+
+inline tree
+walk_gimple_op (gimple stmt, walk_tree_fn callback_op,
+ struct walk_stmt_info *wi)
+{
+ struct pointer_set_t *pset = (wi) ? wi->pset : NULL;
+ unsigned i;
+ tree ret = NULL_TREE;
+
+ switch (gimple_code (stmt))
+ {
+ case GIMPLE_ASSIGN:
+ /* Walk the RHS operands. A formal temporary LHS may use a
+ COMPONENT_REF RHS. */
+ if (wi)
+ wi->val_only = !is_gimple_formal_tmp_var (gimple_assign_lhs (stmt));
+
+ for (i = 1; i < gimple_num_ops (stmt); i++)
+ {
+ ret = walk_tree (gimple_op_ptr (stmt, i), callback_op, wi,
+ pset);
+ if (ret)
+ return ret;
+ }
+
+ /* Walk the LHS. If the RHS is appropriate for a memory, we
+ may use a COMPONENT_REF on the LHS. */
+ if (wi)
+ {
+ /* If the RHS has more than 1 operand, it is not appropriate
+ for the memory. */
+ wi->val_only = !is_gimple_mem_rhs (gimple_assign_rhs1 (stmt))
+ || !gimple_assign_single_p (stmt);
+ wi->is_lhs = true;
+ }
+
+ ret = walk_tree (gimple_op_ptr (stmt, 0), callback_op, wi, pset);
+ if (ret)
+ return ret;
+
+ if (wi)
+ {
+ wi->val_only = true;
+ wi->is_lhs = false;
+ }
+ break;
+
+ case GIMPLE_CALL:
+ if (wi)
+ wi->is_lhs = false;
+
+ ret = walk_tree (gimple_call_chain_ptr (stmt), callback_op, wi, pset);
+ if (ret)
+ return ret;
+
+ ret = walk_tree (gimple_call_fn_ptr (stmt), callback_op, wi, pset);
+ if (ret)
+ return ret;
+
+ for (i = 0; i < gimple_call_num_args (stmt); i++)
+ {
+ ret = walk_tree (gimple_call_arg_ptr (stmt, i), callback_op, wi,
+ pset);
+ if (ret)
+ return ret;
+ }
+
+ if (wi)
+ wi->is_lhs = true;
+
+ ret = walk_tree (gimple_call_lhs_ptr (stmt), callback_op, wi, pset);
+ if (ret)
+ return ret;
+
+ if (wi)
+ wi->is_lhs = false;
+ break;
+
+ case GIMPLE_CATCH:
+ ret = walk_tree (gimple_catch_types_ptr (stmt), callback_op, wi,
+ pset);
+ if (ret)
+ return ret;
+ break;
+
+ case GIMPLE_EH_FILTER:
+ ret = walk_tree (gimple_eh_filter_types_ptr (stmt), callback_op, wi,
+ pset);
+ if (ret)
+ return ret;
+ break;
+
+ case GIMPLE_CHANGE_DYNAMIC_TYPE:
+ ret = walk_tree (gimple_cdt_location_ptr (stmt), callback_op, wi, pset);
+ if (ret)
+ return ret;
+
+ ret = walk_tree (gimple_cdt_new_type_ptr (stmt), callback_op, wi, pset);
+ if (ret)
+ return ret;
+ break;
+
+ case GIMPLE_ASM:
+ ret = walk_gimple_asm (stmt, callback_op, wi);
+ if (ret)
+ return ret;
+ break;
+
+ case GIMPLE_OMP_CONTINUE:
+ ret = walk_tree (gimple_omp_continue_control_def_ptr (stmt),
+ callback_op, wi, pset);
+ if (ret)
+ return ret;
+
+ ret = walk_tree (gimple_omp_continue_control_use_ptr (stmt),
+ callback_op, wi, pset);
+ if (ret)
+ return ret;
+ break;
+
+ case GIMPLE_OMP_CRITICAL:
+ ret = walk_tree (gimple_omp_critical_name_ptr (stmt), callback_op, wi,
+ pset);
+ if (ret)
+ return ret;
+ break;
+
+ case GIMPLE_OMP_FOR:
+ ret = walk_tree (gimple_omp_for_clauses_ptr (stmt), callback_op, wi,
+ pset);
+ if (ret)
+ return ret;
+ for (i = 0; i < gimple_omp_for_collapse (stmt); i++)
+ {
+ ret = walk_tree (gimple_omp_for_index_ptr (stmt, i), callback_op,
+ wi, pset);
+ if (ret)
+ return ret;
+ ret = walk_tree (gimple_omp_for_initial_ptr (stmt, i), callback_op,
+ wi, pset);
+ if (ret)
+ return ret;
+ ret = walk_tree (gimple_omp_for_final_ptr (stmt, i), callback_op,
+ wi, pset);
+ if (ret)
+ return ret;
+ ret = walk_tree (gimple_omp_for_incr_ptr (stmt, i), callback_op,
+ wi, pset);
+ }
+ if (ret)
+ return ret;
+ break;
+
+ case GIMPLE_OMP_PARALLEL:
+ ret = walk_tree (gimple_omp_parallel_clauses_ptr (stmt), callback_op,
+ wi, pset);
+ if (ret)
+ return ret;
+ ret = walk_tree (gimple_omp_parallel_child_fn_ptr (stmt), callback_op,
+ wi, pset);
+ if (ret)
+ return ret;
+ ret = walk_tree (gimple_omp_parallel_data_arg_ptr (stmt), callback_op,
+ wi, pset);
+ if (ret)
+ return ret;
+ break;
+
+ case GIMPLE_OMP_TASK:
+ ret = walk_tree (gimple_omp_task_clauses_ptr (stmt), callback_op,
+ wi, pset);
+ if (ret)
+ return ret;
+ ret = walk_tree (gimple_omp_task_child_fn_ptr (stmt), callback_op,
+ wi, pset);
+ if (ret)
+ return ret;
+ ret = walk_tree (gimple_omp_task_data_arg_ptr (stmt), callback_op,
+ wi, pset);
+ if (ret)
+ return ret;
+ ret = walk_tree (gimple_omp_task_copy_fn_ptr (stmt), callback_op,
+ wi, pset);
+ if (ret)
+ return ret;
+ ret = walk_tree (gimple_omp_task_arg_size_ptr (stmt), callback_op,
+ wi, pset);
+ if (ret)
+ return ret;
+ ret = walk_tree (gimple_omp_task_arg_align_ptr (stmt), callback_op,
+ wi, pset);
+ if (ret)
+ return ret;
+ break;
+
+ case GIMPLE_OMP_SECTIONS:
+ ret = walk_tree (gimple_omp_sections_clauses_ptr (stmt), callback_op,
+ wi, pset);
+ if (ret)
+ return ret;
+
+ ret = walk_tree (gimple_omp_sections_control_ptr (stmt), callback_op,
+ wi, pset);
+ if (ret)
+ return ret;
+
+ break;
+
+ case GIMPLE_OMP_SINGLE:
+ ret = walk_tree (gimple_omp_single_clauses_ptr (stmt), callback_op, wi,
+ pset);
+ if (ret)
+ return ret;
+ break;
+
+ case GIMPLE_OMP_ATOMIC_LOAD:
+ ret = walk_tree (gimple_omp_atomic_load_lhs_ptr (stmt), callback_op, wi,
+ pset);
+ if (ret)
+ return ret;
+
+ ret = walk_tree (gimple_omp_atomic_load_rhs_ptr (stmt), callback_op, wi,
+ pset);
+ if (ret)
+ return ret;
+ break;
+
+ case GIMPLE_OMP_ATOMIC_STORE:
+ ret = walk_tree (gimple_omp_atomic_store_val_ptr (stmt), callback_op,
+ wi, pset);
+ if (ret)
+ return ret;
+ break;
+
+ /* Tuples that do not have operands. */
+ case GIMPLE_NOP:
+ case GIMPLE_RESX:
+ case GIMPLE_OMP_RETURN:
+ case GIMPLE_PREDICT:
+ break;
+
+ default:
+ {
+ enum gimple_statement_structure_enum gss;
+ gss = gimple_statement_structure (stmt);
+ if (gss == GSS_WITH_OPS || gss == GSS_WITH_MEM_OPS)
+ for (i = 0; i < gimple_num_ops (stmt); i++)
+ {
+ ret = walk_tree (gimple_op_ptr (stmt, i), callback_op, wi, pset);
+ if (ret)
+ return ret;
+ }
+ }
+ break;
+ }
+
+ return NULL_TREE;
+}
+
+
+/* Walk the current statement in GSI (optionally using traversal state
+ stored in WI). If WI is NULL, no state is kept during traversal.
+ The callback CALLBACK_STMT is called. If CALLBACK_STMT indicates
+ that it has handled all the operands of the statement, its return
+ value is returned. Otherwise, the return value from CALLBACK_STMT
+ is discarded and its operands are scanned.
+
+ If CALLBACK_STMT is NULL or it didn't handle the operands,
+ CALLBACK_OP is called on each operand of the statement via
+ walk_gimple_op. If walk_gimple_op returns non-NULL for any
+ operand, the remaining operands are not scanned. In this case, the
+ return value from CALLBACK_OP is returned.
+
+ In any other case, NULL_TREE is returned. */
+
+tree
+walk_gimple_stmt (gimple_stmt_iterator *gsi, walk_stmt_fn callback_stmt,
+ walk_tree_fn callback_op, struct walk_stmt_info *wi)
+{
+ gimple ret;
+ tree tree_ret;
+ gimple stmt = gsi_stmt (*gsi);
+
+ if (wi)
+ wi->gsi = *gsi;
+
+ if (wi && wi->want_locations && gimple_has_location (stmt))
+ input_location = gimple_location (stmt);
+
+ ret = NULL;
+
+ /* Invoke the statement callback. Return if the callback handled
+ all of STMT operands by itself. */
+ if (callback_stmt)
+ {
+ bool handled_ops = false;
+ tree_ret = callback_stmt (gsi, &handled_ops, wi);
+ if (handled_ops)
+ return tree_ret;
+
+ /* If CALLBACK_STMT did not handle operands, it should not have
+ a value to return. */
+ gcc_assert (tree_ret == NULL);
+
+ /* Re-read stmt in case the callback changed it. */
+ stmt = gsi_stmt (*gsi);
+ }
+
+ /* If CALLBACK_OP is defined, invoke it on every operand of STMT. */
+ if (callback_op)
+ {
+ tree_ret = walk_gimple_op (stmt, callback_op, wi);
+ if (tree_ret)
+ return tree_ret;
+ }
+
+ /* If STMT can have statements inside (e.g. GIMPLE_BIND), walk them. */
+ switch (gimple_code (stmt))
+ {
+ case GIMPLE_BIND:
+ ret = walk_gimple_seq (gimple_bind_body (stmt), callback_stmt,
+ callback_op, wi);
+ if (ret)
+ return wi->callback_result;
+ break;
+
+ case GIMPLE_CATCH:
+ ret = walk_gimple_seq (gimple_catch_handler (stmt), callback_stmt,
+ callback_op, wi);
+ if (ret)
+ return wi->callback_result;
+ break;
+
+ case GIMPLE_EH_FILTER:
+ ret = walk_gimple_seq (gimple_eh_filter_failure (stmt), callback_stmt,
+ callback_op, wi);
+ if (ret)
+ return wi->callback_result;
+ break;
+
+ case GIMPLE_TRY:
+ ret = walk_gimple_seq (gimple_try_eval (stmt), callback_stmt, callback_op,
+ wi);
+ if (ret)
+ return wi->callback_result;
+
+ ret = walk_gimple_seq (gimple_try_cleanup (stmt), callback_stmt,
+ callback_op, wi);
+ if (ret)
+ return wi->callback_result;
+ break;
+
+ case GIMPLE_OMP_FOR:
+ ret = walk_gimple_seq (gimple_omp_for_pre_body (stmt), callback_stmt,
+ callback_op, wi);
+ if (ret)
+ return wi->callback_result;
+
+ /* FALL THROUGH. */
+ case GIMPLE_OMP_CRITICAL:
+ case GIMPLE_OMP_MASTER:
+ case GIMPLE_OMP_ORDERED:
+ case GIMPLE_OMP_SECTION:
+ case GIMPLE_OMP_PARALLEL:
+ case GIMPLE_OMP_TASK:
+ case GIMPLE_OMP_SECTIONS:
+ case GIMPLE_OMP_SINGLE:
+ ret = walk_gimple_seq (gimple_omp_body (stmt), callback_stmt, callback_op,
+ wi);
+ if (ret)
+ return wi->callback_result;
+ break;
+
+ case GIMPLE_WITH_CLEANUP_EXPR:
+ ret = walk_gimple_seq (gimple_wce_cleanup (stmt), callback_stmt,
+ callback_op, wi);
+ if (ret)
+ return wi->callback_result;
+ break;
+
+ default:
+ gcc_assert (!gimple_has_substatements (stmt));
+ break;
+ }
+
+ return NULL;
+}
+
+
+/* Set sequence SEQ to be the GIMPLE body for function FN. */
+
+void
+gimple_set_body (tree fndecl, gimple_seq seq)
+{
+ struct function *fn = DECL_STRUCT_FUNCTION (fndecl);
+ if (fn == NULL)
+ {
+ /* If FNDECL still does not have a function structure associated
+ with it, then it does not make sense for it to receive a
+ GIMPLE body. */
+ gcc_assert (seq == NULL);
+ }
+ else
+ fn->gimple_body = seq;
+}
+
+
+/* Return the body of GIMPLE statements for function FN. */
+
+gimple_seq
+gimple_body (tree fndecl)
+{
+ struct function *fn = DECL_STRUCT_FUNCTION (fndecl);
+ return fn ? fn->gimple_body : NULL;
+}
+
+
+/* Detect flags from a GIMPLE_CALL. This is just like
+ call_expr_flags, but for gimple tuples. */
+
+int
+gimple_call_flags (const_gimple stmt)
+{
+ int flags;
+ tree decl = gimple_call_fndecl (stmt);
+ tree t;
+
+ if (decl)
+ flags = flags_from_decl_or_type (decl);
+ else
+ {
+ t = TREE_TYPE (gimple_call_fn (stmt));
+ if (t && TREE_CODE (t) == POINTER_TYPE)
+ flags = flags_from_decl_or_type (TREE_TYPE (t));
+ else
+ flags = 0;
+ }
+
+ return flags;
+}
+
+
+/* Return true if GS is a copy assignment. */
+
+bool
+gimple_assign_copy_p (gimple gs)
+{
+ return gimple_code (gs) == GIMPLE_ASSIGN
+ && get_gimple_rhs_class (gimple_assign_rhs_code (gs))
+ == GIMPLE_SINGLE_RHS
+ && is_gimple_val (gimple_op (gs, 1));
+}
+
+
+/* Return true if GS is a SSA_NAME copy assignment. */
+
+bool
+gimple_assign_ssa_name_copy_p (gimple gs)
+{
+ return (gimple_code (gs) == GIMPLE_ASSIGN
+ && (get_gimple_rhs_class (gimple_assign_rhs_code (gs))
+ == GIMPLE_SINGLE_RHS)
+ && TREE_CODE (gimple_assign_lhs (gs)) == SSA_NAME
+ && TREE_CODE (gimple_assign_rhs1 (gs)) == SSA_NAME);
+}
+
+
+/* Return true if GS is an assignment with a singleton RHS, i.e.,
+ there is no operator associated with the assignment itself.
+ Unlike gimple_assign_copy_p, this predicate returns true for
+ any RHS operand, including those that perform an operation
+ and do not have the semantics of a copy, such as COND_EXPR. */
+
+bool
+gimple_assign_single_p (gimple gs)
+{
+ return (gimple_code (gs) == GIMPLE_ASSIGN
+ && get_gimple_rhs_class (gimple_assign_rhs_code (gs))
+ == GIMPLE_SINGLE_RHS);
+}
+
+/* Return true if GS is an assignment with a unary RHS, but the
+ operator has no effect on the assigned value. The logic is adapted
+ from STRIP_NOPS. This predicate is intended to be used in tuplifying
+ instances in which STRIP_NOPS was previously applied to the RHS of
+ an assignment.
+
+ NOTE: In the use cases that led to the creation of this function
+ and of gimple_assign_single_p, it is typical to test for either
+ condition and to proceed in the same manner. In each case, the
+ assigned value is represented by the single RHS operand of the
+ assignment. I suspect there may be cases where gimple_assign_copy_p,
+ gimple_assign_single_p, or equivalent logic is used where a similar
+ treatment of unary NOPs is appropriate. */
+
+bool
+gimple_assign_unary_nop_p (gimple gs)
+{
+ return (gimple_code (gs) == GIMPLE_ASSIGN
+ && (gimple_assign_rhs_code (gs) == NOP_EXPR
+ || gimple_assign_rhs_code (gs) == CONVERT_EXPR
+ || gimple_assign_rhs_code (gs) == NON_LVALUE_EXPR)
+ && gimple_assign_rhs1 (gs) != error_mark_node
+ && (TYPE_MODE (TREE_TYPE (gimple_assign_lhs (gs)))
+ == TYPE_MODE (TREE_TYPE (gimple_assign_rhs1 (gs)))));
+}
+
+/* Set BB to be the basic block holding G. */
+
+void
+gimple_set_bb (gimple stmt, basic_block bb)
+{
+ stmt->gsbase.bb = bb;
+
+ /* If the statement is a label, add the label to block-to-labels map
+ so that we can speed up edge creation for GIMPLE_GOTOs. */
+ if (cfun->cfg && gimple_code (stmt) == GIMPLE_LABEL)
+ {
+ tree t;
+ int uid;
+
+ t = gimple_label_label (stmt);
+ uid = LABEL_DECL_UID (t);
+ if (uid == -1)
+ {
+ unsigned old_len = VEC_length (basic_block, label_to_block_map);
+ LABEL_DECL_UID (t) = uid = cfun->cfg->last_label_uid++;
+ if (old_len <= (unsigned) uid)
+ {
+ unsigned new_len = 3 * uid / 2;
+
+ VEC_safe_grow_cleared (basic_block, gc, label_to_block_map,
+ new_len);
+ }
+ }
+
+ VEC_replace (basic_block, label_to_block_map, uid, bb);
+ }
+}
+
+
+/* Fold the expression computed by STMT. If the expression can be
+ folded, return the folded result, otherwise return NULL. STMT is
+ not modified. */
+
+tree
+gimple_fold (const_gimple stmt)
+{
+ switch (gimple_code (stmt))
+ {
+ case GIMPLE_COND:
+ return fold_binary (gimple_cond_code (stmt),
+ boolean_type_node,
+ gimple_cond_lhs (stmt),
+ gimple_cond_rhs (stmt));
+
+ case GIMPLE_ASSIGN:
+ switch (get_gimple_rhs_class (gimple_assign_rhs_code (stmt)))
+ {
+ case GIMPLE_UNARY_RHS:
+ return fold_unary (gimple_assign_rhs_code (stmt),
+ TREE_TYPE (gimple_assign_lhs (stmt)),
+ gimple_assign_rhs1 (stmt));
+ case GIMPLE_BINARY_RHS:
+ return fold_binary (gimple_assign_rhs_code (stmt),
+ TREE_TYPE (gimple_assign_lhs (stmt)),
+ gimple_assign_rhs1 (stmt),
+ gimple_assign_rhs2 (stmt));
+ case GIMPLE_SINGLE_RHS:
+ return fold (gimple_assign_rhs1 (stmt));
+ default:;
+ }
+ break;
+
+ case GIMPLE_SWITCH:
+ return gimple_switch_index (stmt);
+
+ case GIMPLE_CALL:
+ return NULL_TREE;
+
+ default:
+ break;
+ }
+
+ gcc_unreachable ();
+}
+
+
+/* Modify the RHS of the assignment pointed-to by GSI using the
+ operands in the expression tree EXPR.
+
+ NOTE: The statement pointed-to by GSI may be reallocated if it
+ did not have enough operand slots.
+
+ This function is useful to convert an existing tree expression into
+ the flat representation used for the RHS of a GIMPLE assignment.
+ It will reallocate memory as needed to expand or shrink the number
+ of operand slots needed to represent EXPR.
+
+ NOTE: If you find yourself building a tree and then calling this
+ function, you are most certainly doing it the slow way. It is much
+ better to build a new assignment or to use the function
+ gimple_assign_set_rhs_with_ops, which does not require an
+ expression tree to be built. */
+
+void
+gimple_assign_set_rhs_from_tree (gimple_stmt_iterator *gsi, tree expr)
+{
+ enum tree_code subcode;
+ tree op1, op2;
+
+ extract_ops_from_tree (expr, &subcode, &op1, &op2);
+ gimple_assign_set_rhs_with_ops (gsi, subcode, op1, op2);
+}
+
+
+/* Set the RHS of assignment statement pointed-to by GSI to CODE with
+ operands OP1 and OP2.
+
+ NOTE: The statement pointed-to by GSI may be reallocated if it
+ did not have enough operand slots. */
+
+void
+gimple_assign_set_rhs_with_ops (gimple_stmt_iterator *gsi, enum tree_code code,
+ tree op1, tree op2)
+{
+ unsigned new_rhs_ops = get_gimple_rhs_num_ops (code);
+ gimple stmt = gsi_stmt (*gsi);
+
+ /* If the new CODE needs more operands, allocate a new statement. */
+ if (gimple_num_ops (stmt) < new_rhs_ops + 1)
+ {
+ tree lhs = gimple_assign_lhs (stmt);
+ gimple new_stmt = gimple_alloc (gimple_code (stmt), new_rhs_ops + 1);
+ memcpy (new_stmt, stmt, gimple_size (gimple_code (stmt)));
+ gsi_replace (gsi, new_stmt, true);
+ stmt = new_stmt;
+
+ /* The LHS needs to be reset as this also changes the SSA name
+ on the LHS. */
+ gimple_assign_set_lhs (stmt, lhs);
+ }
+
+ gimple_set_num_ops (stmt, new_rhs_ops + 1);
+ gimple_set_subcode (stmt, code);
+ gimple_assign_set_rhs1 (stmt, op1);
+ if (new_rhs_ops > 1)
+ gimple_assign_set_rhs2 (stmt, op2);
+}
+
+
+/* Return the LHS of a statement that performs an assignment,
+ either a GIMPLE_ASSIGN or a GIMPLE_CALL. Returns NULL_TREE
+ for a call to a function that returns no value, or for a
+ statement other than an assignment or a call. */
+
+tree
+gimple_get_lhs (const_gimple stmt)
+{
+ enum tree_code code = gimple_code (stmt);
+
+ if (code == GIMPLE_ASSIGN)
+ return gimple_assign_lhs (stmt);
+ else if (code == GIMPLE_CALL)
+ return gimple_call_lhs (stmt);
+ else
+ return NULL_TREE;
+}
+
+
+/* Set the LHS of a statement that performs an assignment,
+ either a GIMPLE_ASSIGN or a GIMPLE_CALL. */
+
+void
+gimple_set_lhs (gimple stmt, tree lhs)
+{
+ enum tree_code code = gimple_code (stmt);
+
+ if (code == GIMPLE_ASSIGN)
+ gimple_assign_set_lhs (stmt, lhs);
+ else if (code == GIMPLE_CALL)
+ gimple_call_set_lhs (stmt, lhs);
+ else
+ gcc_unreachable();
+}
+
+
+/* Return a deep copy of statement STMT. All the operands from STMT
+ are reallocated and copied using unshare_expr. The DEF, USE, VDEF
+ and VUSE operand arrays are set to empty in the new copy. */
+
+gimple
+gimple_copy (gimple stmt)
+{
+ enum gimple_code code = gimple_code (stmt);
+ unsigned num_ops = gimple_num_ops (stmt);
+ gimple copy = gimple_alloc (code, num_ops);
+ unsigned i;
+
+ /* Shallow copy all the fields from STMT. */
+ memcpy (copy, stmt, gimple_size (code));
+
+ /* If STMT has sub-statements, deep-copy them as well. */
+ if (gimple_has_substatements (stmt))
+ {
+ gimple_seq new_seq;
+ tree t;
+
+ switch (gimple_code (stmt))
+ {
+ case GIMPLE_BIND:
+ new_seq = gimple_seq_copy (gimple_bind_body (stmt));
+ gimple_bind_set_body (copy, new_seq);
+ gimple_bind_set_vars (copy, unshare_expr (gimple_bind_vars (stmt)));
+ gimple_bind_set_block (copy, gimple_bind_block (stmt));
+ break;
+
+ case GIMPLE_CATCH:
+ new_seq = gimple_seq_copy (gimple_catch_handler (stmt));
+ gimple_catch_set_handler (copy, new_seq);
+ t = unshare_expr (gimple_catch_types (stmt));
+ gimple_catch_set_types (copy, t);
+ break;
+
+ case GIMPLE_EH_FILTER:
+ new_seq = gimple_seq_copy (gimple_eh_filter_failure (stmt));
+ gimple_eh_filter_set_failure (copy, new_seq);
+ t = unshare_expr (gimple_eh_filter_types (stmt));
+ gimple_eh_filter_set_types (copy, t);
+ break;
+
+ case GIMPLE_TRY:
+ new_seq = gimple_seq_copy (gimple_try_eval (stmt));
+ gimple_try_set_eval (copy, new_seq);
+ new_seq = gimple_seq_copy (gimple_try_cleanup (stmt));
+ gimple_try_set_cleanup (copy, new_seq);
+ break;
+
+ case GIMPLE_OMP_FOR:
+ new_seq = gimple_seq_copy (gimple_omp_for_pre_body (stmt));
+ gimple_omp_for_set_pre_body (copy, new_seq);
+ t = unshare_expr (gimple_omp_for_clauses (stmt));
+ gimple_omp_for_set_clauses (copy, t);
+ copy->gimple_omp_for.iter
+ = GGC_NEWVEC (struct gimple_omp_for_iter,
+ gimple_omp_for_collapse (stmt));
+ for (i = 0; i < gimple_omp_for_collapse (stmt); i++)
+ {
+ gimple_omp_for_set_cond (copy, i,
+ gimple_omp_for_cond (stmt, i));
+ gimple_omp_for_set_index (copy, i,
+ gimple_omp_for_index (stmt, i));
+ t = unshare_expr (gimple_omp_for_initial (stmt, i));
+ gimple_omp_for_set_initial (copy, i, t);
+ t = unshare_expr (gimple_omp_for_final (stmt, i));
+ gimple_omp_for_set_final (copy, i, t);
+ t = unshare_expr (gimple_omp_for_incr (stmt, i));
+ gimple_omp_for_set_incr (copy, i, t);
+ }
+ goto copy_omp_body;
+
+ case GIMPLE_OMP_PARALLEL:
+ t = unshare_expr (gimple_omp_parallel_clauses (stmt));
+ gimple_omp_parallel_set_clauses (copy, t);
+ t = unshare_expr (gimple_omp_parallel_child_fn (stmt));
+ gimple_omp_parallel_set_child_fn (copy, t);
+ t = unshare_expr (gimple_omp_parallel_data_arg (stmt));
+ gimple_omp_parallel_set_data_arg (copy, t);
+ goto copy_omp_body;
+
+ case GIMPLE_OMP_TASK:
+ t = unshare_expr (gimple_omp_task_clauses (stmt));
+ gimple_omp_task_set_clauses (copy, t);
+ t = unshare_expr (gimple_omp_task_child_fn (stmt));
+ gimple_omp_task_set_child_fn (copy, t);
+ t = unshare_expr (gimple_omp_task_data_arg (stmt));
+ gimple_omp_task_set_data_arg (copy, t);
+ t = unshare_expr (gimple_omp_task_copy_fn (stmt));
+ gimple_omp_task_set_copy_fn (copy, t);
+ t = unshare_expr (gimple_omp_task_arg_size (stmt));
+ gimple_omp_task_set_arg_size (copy, t);
+ t = unshare_expr (gimple_omp_task_arg_align (stmt));
+ gimple_omp_task_set_arg_align (copy, t);
+ goto copy_omp_body;
+
+ case GIMPLE_OMP_CRITICAL:
+ t = unshare_expr (gimple_omp_critical_name (stmt));
+ gimple_omp_critical_set_name (copy, t);
+ goto copy_omp_body;
+
+ case GIMPLE_OMP_SECTIONS:
+ t = unshare_expr (gimple_omp_sections_clauses (stmt));
+ gimple_omp_sections_set_clauses (copy, t);
+ t = unshare_expr (gimple_omp_sections_control (stmt));
+ gimple_omp_sections_set_control (copy, t);
+ /* FALLTHRU */
+
+ case GIMPLE_OMP_SINGLE:
+ case GIMPLE_OMP_SECTION:
+ case GIMPLE_OMP_MASTER:
+ case GIMPLE_OMP_ORDERED:
+ copy_omp_body:
+ new_seq = gimple_seq_copy (gimple_omp_body (stmt));
+ gimple_omp_set_body (copy, new_seq);
+ break;
+
+ case GIMPLE_WITH_CLEANUP_EXPR:
+ new_seq = gimple_seq_copy (gimple_wce_cleanup (stmt));
+ gimple_wce_set_cleanup (copy, new_seq);
+ break;
+
+ default:
+ gcc_unreachable ();
+ }
+ }
+
+ /* Make copy of operands. */
+ if (num_ops > 0)
+ {
+ for (i = 0; i < num_ops; i++)
+ gimple_set_op (copy, i, unshare_expr (gimple_op (stmt, i)));
+
+ /* Clear out SSA operand vectors on COPY. Note that we cannot
+ call the API functions for setting addresses_taken, stores
+ and loads. These functions free the previous values, and we
+ cannot do that on COPY as it will affect the original
+ statement. */
+ if (gimple_has_ops (stmt))
+ {
+ gimple_set_def_ops (copy, NULL);
+ gimple_set_use_ops (copy, NULL);
+ copy->gsops.opbase.addresses_taken = NULL;
+ }
+
+ if (gimple_has_mem_ops (stmt))
+ {
+ gimple_set_vdef_ops (copy, NULL);
+ gimple_set_vuse_ops (copy, NULL);
+ copy->gsmem.membase.stores = NULL;
+ copy->gsmem.membase.loads = NULL;
+ }
+
+ update_stmt (copy);
+ }
+
+ return copy;
+}
+
+
+/* Set the MODIFIED flag to MODIFIEDP, iff the gimple statement G has
+ a MODIFIED field. */
+
+void
+gimple_set_modified (gimple s, bool modifiedp)
+{
+ if (gimple_has_ops (s))
+ {
+ s->gsbase.modified = (unsigned) modifiedp;
+
+ if (modifiedp
+ && cfun->gimple_df
+ && is_gimple_call (s)
+ && gimple_call_noreturn_p (s))
+ VEC_safe_push (gimple, gc, MODIFIED_NORETURN_CALLS (cfun), s);
+ }
+}
+
+
+/* Return true if statement S has side-effects. We consider a
+ statement to have side effects if:
+
+ - It is a GIMPLE_CALL not marked with ECF_PURE or ECF_CONST.
+ - Any of its operands are marked TREE_THIS_VOLATILE or TREE_SIDE_EFFECTS. */
+
+bool
+gimple_has_side_effects (const_gimple s)
+{
+ unsigned i;
+
+ /* We don't have to scan the arguments to check for
+ volatile arguments, though, at present, we still
+ do a scan to check for TREE_SIDE_EFFECTS. */
+ if (gimple_has_volatile_ops (s))
+ return true;
+
+ if (is_gimple_call (s))
+ {
+ unsigned nargs = gimple_call_num_args (s);
+
+ if (!(gimple_call_flags (s) & (ECF_CONST | ECF_PURE)))
+ return true;
+ else if (gimple_call_flags (s) & ECF_LOOPING_CONST_OR_PURE)
+ /* An infinite loop is considered a side effect. */
+ return true;
+
+ if (gimple_call_lhs (s)
+ && TREE_SIDE_EFFECTS (gimple_call_lhs (s)))
+ {
+ gcc_assert (gimple_has_volatile_ops (s));
+ return true;
+ }
+
+ if (TREE_SIDE_EFFECTS (gimple_call_fn (s)))
+ return true;
+
+ for (i = 0; i < nargs; i++)
+ if (TREE_SIDE_EFFECTS (gimple_call_arg (s, i)))
+ {
+ gcc_assert (gimple_has_volatile_ops (s));
+ return true;
+ }
+
+ return false;
+ }
+ else
+ {
+ for (i = 0; i < gimple_num_ops (s); i++)
+ if (TREE_SIDE_EFFECTS (gimple_op (s, i)))
+ {
+ gcc_assert (gimple_has_volatile_ops (s));
+ return true;
+ }
+ }
+
+ return false;
+}
+
+/* Return true if the RHS of statement S has side effects.
+ We may use it to determine if it is admissable to replace
+ an assignment or call with a copy of a previously-computed
+ value. In such cases, side-effects due the the LHS are
+ preserved. */
+
+bool
+gimple_rhs_has_side_effects (const_gimple s)
+{
+ unsigned i;
+
+ if (is_gimple_call (s))
+ {
+ unsigned nargs = gimple_call_num_args (s);
+
+ if (!(gimple_call_flags (s) & (ECF_CONST | ECF_PURE)))
+ return true;
+
+ /* We cannot use gimple_has_volatile_ops here,
+ because we must ignore a volatile LHS. */
+ if (TREE_SIDE_EFFECTS (gimple_call_fn (s))
+ || TREE_THIS_VOLATILE (gimple_call_fn (s)))
+ {
+ gcc_assert (gimple_has_volatile_ops (s));
+ return true;
+ }
+
+ for (i = 0; i < nargs; i++)
+ if (TREE_SIDE_EFFECTS (gimple_call_arg (s, i))
+ || TREE_THIS_VOLATILE (gimple_call_arg (s, i)))
+ return true;
+
+ return false;
+ }
+ else if (is_gimple_assign (s))
+ {
+ /* Skip the first operand, the LHS. */
+ for (i = 1; i < gimple_num_ops (s); i++)
+ if (TREE_SIDE_EFFECTS (gimple_op (s, i))
+ || TREE_THIS_VOLATILE (gimple_op (s, i)))
+ {
+ gcc_assert (gimple_has_volatile_ops (s));
+ return true;
+ }
+ }
+ else
+ {
+ /* For statements without an LHS, examine all arguments. */
+ for (i = 0; i < gimple_num_ops (s); i++)
+ if (TREE_SIDE_EFFECTS (gimple_op (s, i))
+ || TREE_THIS_VOLATILE (gimple_op (s, i)))
+ {
+ gcc_assert (gimple_has_volatile_ops (s));
+ return true;
+ }
+ }
+
+ return false;
+}
+
+
+/* Helper for gimple_could_trap_p and gimple_assign_rhs_could_trap_p.
+ Return true if S can trap. If INCLUDE_LHS is true and S is a
+ GIMPLE_ASSIGN, the LHS of the assignment is also checked.
+ Otherwise, only the RHS of the assignment is checked. */
+
+static bool
+gimple_could_trap_p_1 (gimple s, bool include_lhs)
+{
+ unsigned i, start;
+ tree t, div = NULL_TREE;
+ enum tree_code op;
+
+ start = (is_gimple_assign (s) && !include_lhs) ? 1 : 0;
+
+ for (i = start; i < gimple_num_ops (s); i++)
+ if (tree_could_trap_p (gimple_op (s, i)))
+ return true;
+
+ switch (gimple_code (s))
+ {
+ case GIMPLE_ASM:
+ return gimple_asm_volatile_p (s);
+
+ case GIMPLE_CALL:
+ t = gimple_call_fndecl (s);
+ /* Assume that calls to weak functions may trap. */
+ if (!t || !DECL_P (t) || DECL_WEAK (t))
+ return true;
+ return false;
+
+ case GIMPLE_ASSIGN:
+ t = gimple_expr_type (s);
+ op = gimple_assign_rhs_code (s);
+ if (get_gimple_rhs_class (op) == GIMPLE_BINARY_RHS)
+ div = gimple_assign_rhs2 (s);
+ return (operation_could_trap_p (op, FLOAT_TYPE_P (t),
+ (INTEGRAL_TYPE_P (t)
+ && TYPE_OVERFLOW_TRAPS (t)),
+ div));
+
+ default:
+ break;
+ }
+
+ return false;
+
+}
+
+
+/* Return true if statement S can trap. */
+
+bool
+gimple_could_trap_p (gimple s)
+{
+ return gimple_could_trap_p_1 (s, true);
+}
+
+
+/* Return true if RHS of a GIMPLE_ASSIGN S can trap. */
+
+bool
+gimple_assign_rhs_could_trap_p (gimple s)
+{
+ gcc_assert (is_gimple_assign (s));
+ return gimple_could_trap_p_1 (s, false);
+}
+
+
+/* Print debugging information for gimple stmts generated. */
+
+void
+dump_gimple_statistics (void)
+{
+#ifdef GATHER_STATISTICS
+ int i, total_tuples = 0, total_bytes = 0;
+
+ fprintf (stderr, "\nGIMPLE statements\n");
+ fprintf (stderr, "Kind Stmts Bytes\n");
+ fprintf (stderr, "---------------------------------------\n");
+ for (i = 0; i < (int) gimple_alloc_kind_all; ++i)
+ {
+ fprintf (stderr, "%-20s %7d %10d\n", gimple_alloc_kind_names[i],
+ gimple_alloc_counts[i], gimple_alloc_sizes[i]);
+ total_tuples += gimple_alloc_counts[i];
+ total_bytes += gimple_alloc_sizes[i];
+ }
+ fprintf (stderr, "---------------------------------------\n");
+ fprintf (stderr, "%-20s %7d %10d\n", "Total", total_tuples, total_bytes);
+ fprintf (stderr, "---------------------------------------\n");
+#else
+ fprintf (stderr, "No gimple statistics\n");
+#endif
+}
+
+
+/* Deep copy SYMS into the set of symbols stored by STMT. If SYMS is
+ NULL or empty, the storage used is freed up. */
+
+void
+gimple_set_stored_syms (gimple stmt, bitmap syms, bitmap_obstack *obs)
+{
+ gcc_assert (gimple_has_mem_ops (stmt));
+
+ if (syms == NULL || bitmap_empty_p (syms))
+ BITMAP_FREE (stmt->gsmem.membase.stores);
+ else
+ {
+ if (stmt->gsmem.membase.stores == NULL)
+ stmt->gsmem.membase.stores = BITMAP_ALLOC (obs);
+
+ bitmap_copy (stmt->gsmem.membase.stores, syms);
+ }
+}
+
+
+/* Deep copy SYMS into the set of symbols loaded by STMT. If SYMS is
+ NULL or empty, the storage used is freed up. */
+
+void
+gimple_set_loaded_syms (gimple stmt, bitmap syms, bitmap_obstack *obs)
+{
+ gcc_assert (gimple_has_mem_ops (stmt));
+
+ if (syms == NULL || bitmap_empty_p (syms))
+ BITMAP_FREE (stmt->gsmem.membase.loads);
+ else
+ {
+ if (stmt->gsmem.membase.loads == NULL)
+ stmt->gsmem.membase.loads = BITMAP_ALLOC (obs);
+
+ bitmap_copy (stmt->gsmem.membase.loads, syms);
+ }
+}
+
+
+/* Return the number of operands needed on the RHS of a GIMPLE
+ assignment for an expression with tree code CODE. */
+
+unsigned
+get_gimple_rhs_num_ops (enum tree_code code)
+{
+ enum gimple_rhs_class rhs_class = get_gimple_rhs_class (code);
+
+ if (rhs_class == GIMPLE_UNARY_RHS || rhs_class == GIMPLE_SINGLE_RHS)
+ return 1;
+ else if (rhs_class == GIMPLE_BINARY_RHS)
+ return 2;
+ else
+ gcc_unreachable ();
+}
+
+#define DEFTREECODE(SYM, STRING, TYPE, NARGS) \
+ (unsigned char) \
+ ((TYPE) == tcc_unary ? GIMPLE_UNARY_RHS \
+ : ((TYPE) == tcc_binary \
+ || (TYPE) == tcc_comparison) ? GIMPLE_BINARY_RHS \
+ : ((TYPE) == tcc_constant \
+ || (TYPE) == tcc_declaration \
+ || (TYPE) == tcc_reference) ? GIMPLE_SINGLE_RHS \
+ : ((SYM) == TRUTH_AND_EXPR \
+ || (SYM) == TRUTH_OR_EXPR \
+ || (SYM) == TRUTH_XOR_EXPR) ? GIMPLE_BINARY_RHS \
+ : (SYM) == TRUTH_NOT_EXPR ? GIMPLE_UNARY_RHS \
+ : ((SYM) == COND_EXPR \
+ || (SYM) == CONSTRUCTOR \
+ || (SYM) == OBJ_TYPE_REF \
+ || (SYM) == ASSERT_EXPR \
+ || (SYM) == ADDR_EXPR \
+ || (SYM) == WITH_SIZE_EXPR \
+ || (SYM) == EXC_PTR_EXPR \
+ || (SYM) == SSA_NAME \
+ || (SYM) == FILTER_EXPR \
+ || (SYM) == POLYNOMIAL_CHREC \
+ || (SYM) == DOT_PROD_EXPR \
+ || (SYM) == VEC_COND_EXPR \
+ || (SYM) == REALIGN_LOAD_EXPR) ? GIMPLE_SINGLE_RHS \
+ : GIMPLE_INVALID_RHS),
+#define END_OF_BASE_TREE_CODES (unsigned char) GIMPLE_INVALID_RHS,
+
+const unsigned char gimple_rhs_class_table[] = {
+#include "all-tree.def"
+};
+
+#undef DEFTREECODE
+#undef END_OF_BASE_TREE_CODES
+
+/* For the definitive definition of GIMPLE, see doc/tree-ssa.texi. */
+
+/* Validation of GIMPLE expressions. */
+
+/* Return true if OP is an acceptable tree node to be used as a GIMPLE
+ operand. */
+
+bool
+is_gimple_operand (const_tree op)
+{
+ return op && get_gimple_rhs_class (TREE_CODE (op)) == GIMPLE_SINGLE_RHS;
+}
+
+
+/* Return true if T is a GIMPLE RHS for an assignment to a temporary. */
+
+bool
+is_gimple_formal_tmp_rhs (tree t)
+{
+ if (is_gimple_lvalue (t) || is_gimple_val (t))
+ return true;
+
+ return get_gimple_rhs_class (TREE_CODE (t)) != GIMPLE_INVALID_RHS;
+}
+
+/* Returns true iff T is a valid RHS for an assignment to a renamed
+ user -- or front-end generated artificial -- variable. */
+
+bool
+is_gimple_reg_rhs (tree t)
+{
+ /* If the RHS of the MODIFY_EXPR may throw or make a nonlocal goto
+ and the LHS is a user variable, then we need to introduce a formal
+ temporary. This way the optimizers can determine that the user
+ variable is only modified if evaluation of the RHS does not throw.
+
+ Don't force a temp of a non-renamable type; the copy could be
+ arbitrarily expensive. Instead we will generate a VDEF for
+ the assignment. */
+
+ if (is_gimple_reg_type (TREE_TYPE (t)) && tree_could_throw_p (t))
+ return false;
+
+ return is_gimple_formal_tmp_rhs (t);
+}
+
+/* Returns true iff T is a valid RHS for an assignment to an un-renamed
+ LHS, or for a call argument. */
+
+bool
+is_gimple_mem_rhs (tree t)
+{
+ /* If we're dealing with a renamable type, either source or dest must be
+ a renamed variable. */
+ if (is_gimple_reg_type (TREE_TYPE (t)))
+ return is_gimple_val (t);
+ else
+ return is_gimple_formal_tmp_rhs (t);
+}
+
+/* Return true if T is a valid LHS for a GIMPLE assignment expression. */
+
+bool
+is_gimple_lvalue (tree t)
+{
+ return (is_gimple_addressable (t)
+ || TREE_CODE (t) == WITH_SIZE_EXPR
+ /* These are complex lvalues, but don't have addresses, so they
+ go here. */
+ || TREE_CODE (t) == BIT_FIELD_REF);
+}
+
+/* Return true if T is a GIMPLE condition. */
+
+bool
+is_gimple_condexpr (tree t)
+{
+ return (is_gimple_val (t) || (COMPARISON_CLASS_P (t)
+ && !tree_could_trap_p (t)
+ && is_gimple_val (TREE_OPERAND (t, 0))
+ && is_gimple_val (TREE_OPERAND (t, 1))));
+}
+
+/* Return true if T is something whose address can be taken. */
+
+bool
+is_gimple_addressable (tree t)
+{
+ return (is_gimple_id (t) || handled_component_p (t) || INDIRECT_REF_P (t));
+}
+
+/* Return true if T is a valid gimple constant. */
+
+bool
+is_gimple_constant (const_tree t)
+{
+ switch (TREE_CODE (t))
+ {
+ case INTEGER_CST:
+ case REAL_CST:
+ case FIXED_CST:
+ case STRING_CST:
+ case COMPLEX_CST:
+ case VECTOR_CST:
+ return true;
+
+ /* Vector constant constructors are gimple invariant. */
+ case CONSTRUCTOR:
+ if (TREE_TYPE (t) && TREE_CODE (TREE_TYPE (t)) == VECTOR_TYPE)
+ return TREE_CONSTANT (t);
+ else
+ return false;
+
+ default:
+ return false;
+ }
+}
+
+/* Return true if T is a gimple address. */
+
+bool
+is_gimple_address (const_tree t)
+{
+ tree op;
+
+ if (TREE_CODE (t) != ADDR_EXPR)
+ return false;
+
+ op = TREE_OPERAND (t, 0);
+ while (handled_component_p (op))
+ {
+ if ((TREE_CODE (op) == ARRAY_REF
+ || TREE_CODE (op) == ARRAY_RANGE_REF)
+ && !is_gimple_val (TREE_OPERAND (op, 1)))
+ return false;
+
+ op = TREE_OPERAND (op, 0);
+ }
+
+ if (CONSTANT_CLASS_P (op) || INDIRECT_REF_P (op))
+ return true;
+
+ switch (TREE_CODE (op))
+ {
+ case PARM_DECL:
+ case RESULT_DECL:
+ case LABEL_DECL:
+ case FUNCTION_DECL:
+ case VAR_DECL:
+ case CONST_DECL:
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+/* Return true if T is a gimple invariant address. */
+
+bool
+is_gimple_invariant_address (const_tree t)
+{
+ tree op;
+
+ if (TREE_CODE (t) != ADDR_EXPR)
+ return false;
+
+ op = TREE_OPERAND (t, 0);
+ while (handled_component_p (op))
+ {
+ switch (TREE_CODE (op))
+ {
+ case ARRAY_REF:
+ case ARRAY_RANGE_REF:
+ if (!is_gimple_constant (TREE_OPERAND (op, 1))
+ || TREE_OPERAND (op, 2) != NULL_TREE
+ || TREE_OPERAND (op, 3) != NULL_TREE)
+ return false;
+ break;
+
+ case COMPONENT_REF:
+ if (TREE_OPERAND (op, 2) != NULL_TREE)
+ return false;
+ break;
+
+ default:;
+ }
+ op = TREE_OPERAND (op, 0);
+ }
+
+ return CONSTANT_CLASS_P (op) || decl_address_invariant_p (op);
+}
+
+/* Return true if T is a GIMPLE minimal invariant. It's a restricted
+ form of function invariant. */
+
+bool
+is_gimple_min_invariant (const_tree t)
+{
+ if (TREE_CODE (t) == ADDR_EXPR)
+ return is_gimple_invariant_address (t);
+
+ return is_gimple_constant (t);
+}
+
+/* Return true if T looks like a valid GIMPLE statement. */
+
+bool
+is_gimple_stmt (tree t)
+{
+ const enum tree_code code = TREE_CODE (t);
+
+ switch (code)
+ {
+ case NOP_EXPR:
+ /* The only valid NOP_EXPR is the empty statement. */
+ return IS_EMPTY_STMT (t);
+
+ case BIND_EXPR:
+ case COND_EXPR:
+ /* These are only valid if they're void. */
+ return TREE_TYPE (t) == NULL || VOID_TYPE_P (TREE_TYPE (t));
+
+ case SWITCH_EXPR:
+ case GOTO_EXPR:
+ case RETURN_EXPR:
+ case LABEL_EXPR:
+ case CASE_LABEL_EXPR:
+ case TRY_CATCH_EXPR:
+ case TRY_FINALLY_EXPR:
+ case EH_FILTER_EXPR:
+ case CATCH_EXPR:
+ case CHANGE_DYNAMIC_TYPE_EXPR:
+ case ASM_EXPR:
+ case RESX_EXPR:
+ case STATEMENT_LIST:
+ case OMP_PARALLEL:
+ case OMP_FOR:
+ case OMP_SECTIONS:
+ case OMP_SECTION:
+ case OMP_SINGLE:
+ case OMP_MASTER:
+ case OMP_ORDERED:
+ case OMP_CRITICAL:
+ case OMP_TASK:
+ /* These are always void. */
+ return true;
+
+ case CALL_EXPR:
+ case MODIFY_EXPR:
+ case PREDICT_EXPR:
+ /* These are valid regardless of their type. */
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+/* Return true if T is a variable. */
+
+bool
+is_gimple_variable (tree t)
+{
+ return (TREE_CODE (t) == VAR_DECL
+ || TREE_CODE (t) == PARM_DECL
+ || TREE_CODE (t) == RESULT_DECL
+ || TREE_CODE (t) == SSA_NAME);
+}
+
+/* Return true if T is a GIMPLE identifier (something with an address). */
+
+bool
+is_gimple_id (tree t)
+{
+ return (is_gimple_variable (t)
+ || TREE_CODE (t) == FUNCTION_DECL
+ || TREE_CODE (t) == LABEL_DECL
+ || TREE_CODE (t) == CONST_DECL
+ /* Allow string constants, since they are addressable. */
+ || TREE_CODE (t) == STRING_CST);
+}
+
+/* Return true if TYPE is a suitable type for a scalar register variable. */
+
+bool
+is_gimple_reg_type (tree type)
+{
+ /* In addition to aggregate types, we also exclude complex types if not
+ optimizing because they can be subject to partial stores in GNU C by
+ means of the __real__ and __imag__ operators and we cannot promote
+ them to total stores (see gimplify_modify_expr_complex_part). */
+ return !(AGGREGATE_TYPE_P (type)
+ || (TREE_CODE (type) == COMPLEX_TYPE && !optimize));
+
+}
+
+/* Return true if T is a non-aggregate register variable. */
+
+bool
+is_gimple_reg (tree t)
+{
+ if (TREE_CODE (t) == SSA_NAME)
+ t = SSA_NAME_VAR (t);
+
+ if (MTAG_P (t))
+ return false;
+
+ if (!is_gimple_variable (t))
+ return false;
+
+ if (!is_gimple_reg_type (TREE_TYPE (t)))
+ return false;
+
+ /* A volatile decl is not acceptable because we can't reuse it as
+ needed. We need to copy it into a temp first. */
+ if (TREE_THIS_VOLATILE (t))
+ return false;
+
+ /* We define "registers" as things that can be renamed as needed,
+ which with our infrastructure does not apply to memory. */
+ if (needs_to_live_in_memory (t))
+ return false;
+
+ /* Hard register variables are an interesting case. For those that
+ are call-clobbered, we don't know where all the calls are, since
+ we don't (want to) take into account which operations will turn
+ into libcalls at the rtl level. For those that are call-saved,
+ we don't currently model the fact that calls may in fact change
+ global hard registers, nor do we examine ASM_CLOBBERS at the tree
+ level, and so miss variable changes that might imply. All around,
+ it seems safest to not do too much optimization with these at the
+ tree level at all. We'll have to rely on the rtl optimizers to
+ clean this up, as there we've got all the appropriate bits exposed. */
+ if (TREE_CODE (t) == VAR_DECL && DECL_HARD_REGISTER (t))
+ return false;
+
+ /* Complex and vector values must have been put into SSA-like form.
+ That is, no assignments to the individual components. */
+ if (TREE_CODE (TREE_TYPE (t)) == COMPLEX_TYPE
+ || TREE_CODE (TREE_TYPE (t)) == VECTOR_TYPE)
+ return DECL_GIMPLE_REG_P (t);
+
+ return true;
+}
+
+
+/* Returns true if T is a GIMPLE formal temporary variable. */
+
+bool
+is_gimple_formal_tmp_var (tree t)
+{
+ if (TREE_CODE (t) == SSA_NAME)
+ return true;
+
+ return TREE_CODE (t) == VAR_DECL && DECL_GIMPLE_FORMAL_TEMP_P (t);
+}
+
+/* Returns true if T is a GIMPLE formal temporary register variable. */
+
+bool
+is_gimple_formal_tmp_reg (tree t)
+{
+ /* The intent of this is to get hold of a value that won't change.
+ An SSA_NAME qualifies no matter if its of a user variable or not. */
+ if (TREE_CODE (t) == SSA_NAME)
+ return true;
+
+ /* We don't know the lifetime characteristics of user variables. */
+ if (!is_gimple_formal_tmp_var (t))
+ return false;
+
+ /* Finally, it must be capable of being placed in a register. */
+ return is_gimple_reg (t);
+}
+
+/* Return true if T is a GIMPLE variable whose address is not needed. */
+
+bool
+is_gimple_non_addressable (tree t)
+{
+ if (TREE_CODE (t) == SSA_NAME)
+ t = SSA_NAME_VAR (t);
+
+ return (is_gimple_variable (t) && ! needs_to_live_in_memory (t));
+}
+
+/* Return true if T is a GIMPLE rvalue, i.e. an identifier or a constant. */
+
+bool
+is_gimple_val (tree t)
+{
+ /* Make loads from volatiles and memory vars explicit. */
+ if (is_gimple_variable (t)
+ && is_gimple_reg_type (TREE_TYPE (t))
+ && !is_gimple_reg (t))
+ return false;
+
+ /* FIXME make these decls. That can happen only when we expose the
+ entire landing-pad construct at the tree level. */
+ if (TREE_CODE (t) == EXC_PTR_EXPR || TREE_CODE (t) == FILTER_EXPR)
+ return true;
+
+ return (is_gimple_variable (t) || is_gimple_min_invariant (t));
+}
+
+/* Similarly, but accept hard registers as inputs to asm statements. */
+
+bool
+is_gimple_asm_val (tree t)
+{
+ if (TREE_CODE (t) == VAR_DECL && DECL_HARD_REGISTER (t))
+ return true;
+
+ return is_gimple_val (t);
+}
+
+/* Return true if T is a GIMPLE minimal lvalue. */
+
+bool
+is_gimple_min_lval (tree t)
+{
+ return (is_gimple_id (t) || TREE_CODE (t) == INDIRECT_REF);
+}
+
+/* Return true if T is a typecast operation. */
+
+bool
+is_gimple_cast (tree t)
+{
+ return (CONVERT_EXPR_P (t)
+ || TREE_CODE (t) == FIX_TRUNC_EXPR);
+}
+
+/* Return true if T is a valid function operand of a CALL_EXPR. */
+
+bool
+is_gimple_call_addr (tree t)
+{
+ return (TREE_CODE (t) == OBJ_TYPE_REF || is_gimple_val (t));
+}
+
+/* If T makes a function call, return the corresponding CALL_EXPR operand.
+ Otherwise, return NULL_TREE. */
+
+tree
+get_call_expr_in (tree t)
+{
+ if (TREE_CODE (t) == MODIFY_EXPR)
+ t = TREE_OPERAND (t, 1);
+ if (TREE_CODE (t) == WITH_SIZE_EXPR)
+ t = TREE_OPERAND (t, 0);
+ if (TREE_CODE (t) == CALL_EXPR)
+ return t;
+ return NULL_TREE;
+}
+
+
+/* Given a memory reference expression T, return its base address.
+ The base address of a memory reference expression is the main
+ object being referenced. For instance, the base address for
+ 'array[i].fld[j]' is 'array'. You can think of this as stripping
+ away the offset part from a memory address.
+
+ This function calls handled_component_p to strip away all the inner
+ parts of the memory reference until it reaches the base object. */
+
+tree
+get_base_address (tree t)
+{
+ while (handled_component_p (t))
+ t = TREE_OPERAND (t, 0);
+
+ if (SSA_VAR_P (t)
+ || TREE_CODE (t) == STRING_CST
+ || TREE_CODE (t) == CONSTRUCTOR
+ || INDIRECT_REF_P (t))
+ return t;
+ else
+ return NULL_TREE;
+}
+
+void
+recalculate_side_effects (tree t)
+{
+ enum tree_code code = TREE_CODE (t);
+ int len = TREE_OPERAND_LENGTH (t);
+ int i;
+
+ switch (TREE_CODE_CLASS (code))
+ {
+ case tcc_expression:
+ switch (code)
+ {
+ case INIT_EXPR:
+ case MODIFY_EXPR:
+ case VA_ARG_EXPR:
+ case PREDECREMENT_EXPR:
+ case PREINCREMENT_EXPR:
+ case POSTDECREMENT_EXPR:
+ case POSTINCREMENT_EXPR:
+ /* All of these have side-effects, no matter what their
+ operands are. */
+ return;
+
+ default:
+ break;
+ }
+ /* Fall through. */
+
+ case tcc_comparison: /* a comparison expression */
+ case tcc_unary: /* a unary arithmetic expression */
+ case tcc_binary: /* a binary arithmetic expression */
+ case tcc_reference: /* a reference */
+ case tcc_vl_exp: /* a function call */
+ TREE_SIDE_EFFECTS (t) = TREE_THIS_VOLATILE (t);
+ for (i = 0; i < len; ++i)
+ {
+ tree op = TREE_OPERAND (t, i);
+ if (op && TREE_SIDE_EFFECTS (op))
+ TREE_SIDE_EFFECTS (t) = 1;
+ }
+ break;
+
+ default:
+ /* Can never be used with non-expressions. */
+ gcc_unreachable ();
+ }
+}
+
+/* Canonicalize a tree T for use in a COND_EXPR as conditional. Returns
+ a canonicalized tree that is valid for a COND_EXPR or NULL_TREE, if
+ we failed to create one. */
+
+tree
+canonicalize_cond_expr_cond (tree t)
+{
+ /* For (bool)x use x != 0. */
+ if (TREE_CODE (t) == NOP_EXPR
+ && TREE_TYPE (t) == boolean_type_node)
+ {
+ tree top0 = TREE_OPERAND (t, 0);
+ t = build2 (NE_EXPR, TREE_TYPE (t),
+ top0, build_int_cst (TREE_TYPE (top0), 0));
+ }
+ /* For !x use x == 0. */
+ else if (TREE_CODE (t) == TRUTH_NOT_EXPR)
+ {
+ tree top0 = TREE_OPERAND (t, 0);
+ t = build2 (EQ_EXPR, TREE_TYPE (t),
+ top0, build_int_cst (TREE_TYPE (top0), 0));
+ }
+ /* For cmp ? 1 : 0 use cmp. */
+ else if (TREE_CODE (t) == COND_EXPR
+ && COMPARISON_CLASS_P (TREE_OPERAND (t, 0))
+ && integer_onep (TREE_OPERAND (t, 1))
+ && integer_zerop (TREE_OPERAND (t, 2)))
+ {
+ tree top0 = TREE_OPERAND (t, 0);
+ t = build2 (TREE_CODE (top0), TREE_TYPE (t),
+ TREE_OPERAND (top0, 0), TREE_OPERAND (top0, 1));
+ }
+
+ if (is_gimple_condexpr (t))
+ return t;
+
+ return NULL_TREE;
+}
+
+#include "gt-gimple.h"
diff --git a/gcc/gimple.def b/gcc/gimple.def
new file mode 100644
index 00000000000..23eaae2e86e
--- /dev/null
+++ b/gcc/gimple.def
@@ -0,0 +1,357 @@
+/* This file contains the definitions of the GIMPLE IR tuples used in GCC.
+
+ Copyright (C) 2007, 2008 Free Software Foundation, Inc.
+ Contributed by Aldy Hernandez <aldyh@redhat.com>
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+/* The format of this file is
+ DEFGSCODE(GIMPLE_symbol, printable name, structure).
+
+ Where symbol is the enumeration name without the ``GIMPLE_''.
+ The argument STRUCTURE is used to compute offsets into each of the
+ tuple structures that contain operands. Since vector operands
+ are at different offsets depending on the particular structure
+ used, these offsets are computed at compile time for efficient
+ lookup at runtime. See gimple_ops().
+
+ If a code does not use operand vectors, STRUCTURE should be NULL. */
+
+/* Error marker. This is used in similar ways as ERROR_MARK in tree.def. */
+DEFGSCODE(GIMPLE_ERROR_MARK, "gimple_error_mark", NULL)
+
+/* IMPORTANT. Do not rearrange the codes between GIMPLE_COND and
+ GIMPLE_RETURN. The ordering is exposed by gimple_has_ops calls.
+ These are all the GIMPLE statements with register operands. */
+
+/* GIMPLE_COND <COND_CODE, OP1, OP2, TRUE_LABEL, FALSE_LABEL>
+ represents the conditional jump:
+
+ if (OP1 COND_CODE OP2) goto TRUE_LABEL else goto FALSE_LABEL
+
+ COND_CODE is the tree code used as the comparison predicate. It
+ must be of class tcc_comparison.
+
+ OP1 and OP2 are the operands used in the comparison. They must be
+ accepted by is_gimple_operand.
+
+ TRUE_LABEL and FALSE_LABEL are the LABEL_DECL nodes used as the
+ jump target for the comparison. */
+DEFGSCODE(GIMPLE_COND, "gimple_cond", struct gimple_statement_with_ops)
+
+/* GIMPLE_GOTO <TARGET> represents unconditional jumps.
+ TARGET is a LABEL_DECL or an expression node for computed GOTOs. */
+DEFGSCODE(GIMPLE_GOTO, "gimple_goto", struct gimple_statement_with_ops)
+
+/* GIMPLE_LABEL <LABEL> represents label statements. LABEL is a
+ LABEL_DECL representing a jump target. */
+DEFGSCODE(GIMPLE_LABEL, "gimple_label", struct gimple_statement_with_ops)
+
+/* GIMPLE_SWITCH <INDEX, DEFAULT_LAB, LAB1, ..., LABN> represents the
+ multiway branch:
+
+ switch (INDEX)
+ {
+ case LAB1: ...; break;
+ ...
+ case LABN: ...; break;
+ default: ...
+ }
+
+ INDEX is the variable evaluated to decide which label to jump to.
+
+ DEFAULT_LAB, LAB1 ... LABN are the tree nodes representing case labels.
+ They must be CASE_LABEL_EXPR nodes. */
+DEFGSCODE(GIMPLE_SWITCH, "gimple_switch", struct gimple_statement_with_ops)
+
+/* GIMPLE_CHANGE_DYNAMIC_TYPE indicates a change in the dynamic type
+ of a memory location. This has no value and generates no
+ executable code. It is only used for type based alias analysis.
+ This is generated by C++ placement new and it's a direct
+ translation from CHANGE_DYNAMIC_TYPE_EXPR. The first operand
+ (gimple_cdt_new_type) is the new type. The second operand
+ (gimple_cdt_location) is the location (pointer) whose type is being
+ changed. */
+DEFGSCODE(GIMPLE_CHANGE_DYNAMIC_TYPE, "gimple_change_dynamic_type",
+ struct gimple_statement_with_ops)
+
+/* IMPORTANT.
+
+ Do not rearrange the codes between GIMPLE_ASSIGN and GIMPLE_RETURN.
+ It's exposed by GIMPLE_RANGE_CHECK calls. These are all the GIMPLE
+ statements with memory and register operands. */
+
+/* GIMPLE_ASSIGN <SUBCODE, LHS, RHS1[, RHS2]> represents the assignment
+ statement
+
+ LHS = RHS1 SUBCODE RHS2.
+
+ SUBCODE is the tree code for the expression computed by the RHS of the
+ assignment. It must be one of the tree codes accepted by
+ get_gimple_rhs_class.
+
+ LHS is the operand on the LHS of the assignment. It must be a tree node
+ accepted by is_gimple_operand.
+
+ RHS1 is the first operand on the RHS of the assignment. It must be a tree
+ node accepted by is_gimple_operand.
+
+ RHS2 is the second operand on the RHS of the assignemnt. It must be a tree
+ node accepted by is_gimple_operand. This argument exists only if SUBCODE is
+ of class GIMPLE_BINARY_RHS. */
+DEFGSCODE(GIMPLE_ASSIGN, "gimple_assign",
+ struct gimple_statement_with_memory_ops)
+
+/* GIMPLE_ASM <STRING, I1, ..., IN, O1, ... OM, C1, ..., CP>
+ represents inline assembly statements.
+
+ STRING is the string containing the assembly statements.
+ I1 ... IN are the N input operands.
+ O1 ... OM are the M output operands.
+ C1 ... CP are the P clobber operands. */
+DEFGSCODE(GIMPLE_ASM, "gimple_asm", struct gimple_statement_asm)
+
+/* GIMPLE_CALL <FN, LHS, ARG1, ..., ARGN[, CHAIN]> represents function
+ calls.
+
+ FN is the callee. It must be accepted by is_gimple_call_addr.
+
+ LHS is the operand where the return value from FN is stored. It may
+ be NULL.
+
+ ARG1 ... ARGN are the arguments. They must all be accepted by
+ is_gimple_operand.
+
+ CHAIN is the optional static chain link for nested functions. */
+DEFGSCODE(GIMPLE_CALL, "gimple_call",
+ struct gimple_statement_with_memory_ops)
+
+/* GIMPLE_RETURN <RETVAL> represents return statements.
+
+ RETVAL is the value to return or NULL. If a value is returned it
+ must be accepted by is_gimple_operand. */
+DEFGSCODE(GIMPLE_RETURN, "gimple_return",
+ struct gimple_statement_with_memory_ops)
+
+/* GIMPLE_BIND <VARS, BLOCK, BODY> represents a lexical scope.
+ VARS is the set of variables declared in that scope.
+ BLOCK is the symbol binding block used for debug information.
+ BODY is the sequence of statements in the scope. */
+DEFGSCODE(GIMPLE_BIND, "gimple_bind", NULL)
+
+/* GIMPLE_CATCH <TYPES, HANDLER> represents a typed exception handler.
+ TYPES is the type (or list of types) handled. HANDLER is the
+ sequence of statements that handle these types. */
+DEFGSCODE(GIMPLE_CATCH, "gimple_catch", NULL)
+
+/* GIMPLE_EH_FILTER <TYPES, FAILURE> represents an exception
+ specification. TYPES is a list of allowed types and FAILURE is the
+ sequence of statements to execute on failure. */
+DEFGSCODE(GIMPLE_EH_FILTER, "gimple_eh_filter", NULL)
+
+/* GIMPLE_PHI <RESULT, ARG1, ..., ARGN> represents the PHI node
+
+ RESULT = PHI <ARG1, ..., ARGN>
+
+ RESULT is the SSA name created by this PHI node.
+
+ ARG1 ... ARGN are the arguments to the PHI node. N must be
+ exactly the same as the number of incoming edges to the basic block
+ holding the PHI node. Every argument is either an SSA name or a
+ tree node of class tcc_constant. */
+DEFGSCODE(GIMPLE_PHI, "gimple_phi", NULL)
+
+/* GIMPLE_RESX <REGION> resumes execution after an exception.
+ REGION is the region number being left. */
+DEFGSCODE(GIMPLE_RESX, "gimple_resx", NULL)
+
+/* GIMPLE_TRY <TRY_KIND, EVAL, CLEANUP>
+ represents a try/catch or a try/finally statement.
+
+ TRY_KIND is either GIMPLE_TRY_CATCH or GIMPLE_TRY_FINALLY.
+
+ EVAL is the sequence of statements to execute on entry to GIMPLE_TRY.
+
+ CLEANUP is the sequence of statements to execute according to
+ TRY_KIND. If TRY_KIND is GIMPLE_TRY_CATCH, CLEANUP is only exected
+ if an exception is thrown during execution of EVAL. If TRY_KIND is
+ GIMPLE_TRY_FINALLY, CLEANUP is always executed after executing EVAL
+ (regardless of whether EVAL finished normally, or jumped out or an
+ exception was thrown). */
+DEFGSCODE(GIMPLE_TRY, "gimple_try", NULL)
+
+/* GIMPLE_NOP represents the "do nothing" statement. */
+DEFGSCODE(GIMPLE_NOP, "gimple_nop", NULL)
+
+
+/* IMPORTANT.
+
+ Do not rearrange any of the GIMPLE_OMP_* codes. This ordering is
+ exposed by the range check in gimple_omp_subcode(). */
+
+
+/* Tuples used for lowering of OMP_ATOMIC. Although the form of the OMP_ATOMIC
+ expression is very simple (just in form mem op= expr), various implicit
+ conversions may cause the expression to become more complex, so that it does
+ not fit the gimple grammar very well. To overcome this problem, OMP_ATOMIC
+ is rewritten as a sequence of two codes in gimplification:
+
+ GIMPLE_OMP_LOAD (tmp, mem)
+ val = some computations involving tmp;
+ GIMPLE_OMP_STORE (val). */
+DEFGSCODE(GIMPLE_OMP_ATOMIC_LOAD, "gimple_omp_atomic_load", NULL)
+DEFGSCODE(GIMPLE_OMP_ATOMIC_STORE, "gimple_omp_atomic_store", NULL)
+
+/* GIMPLE_OMP_CONTINUE marks the location of the loop or sections
+ iteration in partially lowered OpenMP code. */
+DEFGSCODE(GIMPLE_OMP_CONTINUE, "gimple_omp_continue", NULL)
+
+/* GIMPLE_OMP_CRITICAL <NAME, BODY> represents
+
+ #pragma omp critical [name]
+
+ NAME is the name given to the critical section.
+ BODY is the sequence of statements that are inside the critical section. */
+DEFGSCODE(GIMPLE_OMP_CRITICAL, "gimple_omp_critical", NULL)
+
+/* GIMPLE_OMP_FOR <BODY, CLAUSES, INDEX, INITIAL, FINAL, COND, INCR, PRE_BODY>
+ represents
+
+ PRE_BODY
+ #pragma omp for [clause1 ... clauseN]
+ for (INDEX = INITIAL; INDEX COND FINAL; INDEX {+=,-=} INCR)
+ BODY
+
+ BODY is the loop body.
+
+ CLAUSES is the list of clauses.
+
+ INDEX must be an integer or pointer variable, which is implicitly thread
+ private. It must be accepted by is_gimple_operand.
+
+ INITIAL is the initial value given to INDEX. It must be
+ accepted by is_gimple_operand.
+
+ FINAL is the final value that INDEX should take. It must
+ be accepted by is_gimple_operand.
+
+ COND is the condition code for the controlling predicate. It must
+ be one of { <, >, <=, >= }
+
+ INCR is the loop index increment. It must be tree node of type
+ tcc_constant.
+
+ PRE_BODY is a landing pad filled by the gimplifier with things from
+ INIT, COND, and INCR that are technically part of the OMP_FOR
+ structured block, but are evaluated before the loop body begins.
+
+ INITIAL, FINAL and INCR are required to be loop invariant integer
+ expressions that are evaluated without any synchronization.
+ The evaluation order, frequency of evaluation and side-effects are
+ unspecified by the standard. */
+DEFGSCODE(GIMPLE_OMP_FOR, "gimple_omp_for", NULL)
+
+/* GIMPLE_OMP_MASTER <BODY> represents #pragma omp master.
+ BODY is the sequence of statements to execute in the master section. */
+DEFGSCODE(GIMPLE_OMP_MASTER, "gimple_omp_master", NULL)
+
+/* GIMPLE_OMP_ORDERED <BODY> represents #pragma omp ordered.
+ BODY is the sequence of statements to execute in the ordered section. */
+DEFGSCODE(GIMPLE_OMP_ORDERED, "gimple_omp_ordered", NULL)
+
+/* GIMPLE_OMP_PARALLEL <BODY, CLAUSES, CHILD_FN, DATA_ARG> represents
+
+ #pragma omp parallel [CLAUSES]
+ BODY
+
+ BODY is a the sequence of statements to be executed by all threads.
+
+ CLAUSES is a TREE_LIST node with all the clauses.
+
+ CHILD_FN is set when outlining the body of the parallel region.
+ All the statements in BODY are moved into this newly created
+ function when converting OMP constructs into low-GIMPLE.
+
+ DATA_ARG is a local variable in the parent function containing data
+ to be shared with CHILD_FN. This is used to implement all the data
+ sharing clauses. */
+DEFGSCODE(GIMPLE_OMP_PARALLEL, "gimple_omp_parallel", NULL)
+
+/* GIMPLE_OMP_TASK <BODY, CLAUSES, CHILD_FN, DATA_ARG, COPY_FN,
+ ARG_SIZE, ARG_ALIGN> represents
+
+ #pragma omp task [CLAUSES]
+ BODY
+
+ BODY is a the sequence of statements to be executed by all threads.
+
+ CLAUSES is a TREE_LIST node with all the clauses.
+
+ CHILD_FN is set when outlining the body of the explicit task region.
+ All the statements in BODY are moved into this newly created
+ function when converting OMP constructs into low-GIMPLE.
+
+ DATA_ARG is a local variable in the parent function containing data
+ to be shared with CHILD_FN. This is used to implement all the data
+ sharing clauses.
+
+ COPY_FN is set when outlining the firstprivate var initialization.
+ All the needed statements are emitted into the newly created
+ function, or when only memcpy is needed, it is NULL.
+
+ ARG_SIZE and ARG_ALIGN are the size and alignment of the incoming
+ data area allocated by GOMP_task and passed to CHILD_FN. */
+DEFGSCODE(GIMPLE_OMP_TASK, "gimple_omp_task", NULL)
+
+/* OMP_RETURN marks the end of an OpenMP directive. */
+DEFGSCODE(GIMPLE_OMP_RETURN, "gimple_omp_return", NULL)
+
+/* OMP_SECTION <BODY> represents #pragma omp section.
+ BODY is the sequence of statements in the section body. */
+DEFGSCODE(GIMPLE_OMP_SECTION, "gimple_omp_section", NULL)
+
+/* OMP_SECTIONS <BODY, CLAUSES, CONTROL> represents #pragma omp sections.
+
+ BODY is the sequence of statements in the sections body.
+ CLAUSES is a TREE_LIST node holding the list of associated clauses.
+ CONTROL is a VAR_DECL used for deciding which of the sections
+ to execute. */
+DEFGSCODE(GIMPLE_OMP_SECTIONS, "gimple_omp_sections", NULL)
+
+/* GIMPLE_OMP_SECTIONS_SWITCH is a marker placed immediately after
+ OMP_SECTIONS. It represents the GIMPLE_SWITCH used to decide which
+ branch is taken. */
+DEFGSCODE(GIMPLE_OMP_SECTIONS_SWITCH, "gimple_omp_sections_switch", NULL)
+
+/* GIMPLE_OMP_SINGLE <BODY, CLAUSES> represents #pragma omp single
+ BODY is the sequence of statements inside the single section.
+ CLAUSES is a TREE_LIST node holding the associated clauses. */
+DEFGSCODE(GIMPLE_OMP_SINGLE, "gimple_omp_single", NULL)
+
+/* GIMPLE_PREDICT <PREDICT, OUTCOME> specifies a hint for branch prediction.
+
+ PREDICT is one of the predictors from predict.def.
+
+ OUTCOME is NOT_TAKEN or TAKEN. */
+DEFGSCODE(GIMPLE_PREDICT, "gimple_predict", NULL)
+
+/* This node represents a cleanup expression. It is ONLY USED INTERNALLY
+ by the gimplifier as a placeholder for cleanups, and its uses will be
+ cleaned up by the time gimplification is done.
+
+ This tuple should not exist outside of the gimplifier proper. */
+DEFGSCODE(GIMPLE_WITH_CLEANUP_EXPR, "gimple_with_cleanup_expr", NULL)
diff --git a/gcc/gimple.h b/gcc/gimple.h
new file mode 100644
index 00000000000..744461d7310
--- /dev/null
+++ b/gcc/gimple.h
@@ -0,0 +1,4539 @@
+/* Gimple IR definitions.
+
+ Copyright 2007, 2008 Free Software Foundation, Inc.
+ Contributed by Aldy Hernandez <aldyh@redhat.com>
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+#ifndef GCC_GIMPLE_H
+#define GCC_GIMPLE_H
+
+#include "pointer-set.h"
+#include "vec.h"
+#include "ggc.h"
+#include "tm.h"
+#include "hard-reg-set.h"
+#include "basic-block.h"
+#include "tree-ssa-operands.h"
+
+DEF_VEC_P(gimple);
+DEF_VEC_ALLOC_P(gimple,heap);
+DEF_VEC_ALLOC_P(gimple,gc);
+
+DEF_VEC_P(gimple_seq);
+DEF_VEC_ALLOC_P(gimple_seq,gc);
+DEF_VEC_ALLOC_P(gimple_seq,heap);
+
+enum gimple_code {
+#define DEFGSCODE(SYM, STRING, STRUCT) SYM,
+#include "gimple.def"
+#undef DEFGSCODE
+ LAST_AND_UNUSED_GIMPLE_CODE
+};
+
+extern const char *const gimple_code_name[];
+extern const unsigned char gimple_rhs_class_table[];
+
+/* Error out if a gimple tuple is addressed incorrectly. */
+#if defined ENABLE_GIMPLE_CHECKING
+extern void gimple_check_failed (const_gimple, const char *, int, \
+ const char *, enum gimple_code, \
+ enum tree_code) ATTRIBUTE_NORETURN;
+extern void gimple_range_check_failed (const_gimple, const char *, int, \
+ const char *, enum gimple_code, \
+ enum gimple_code) ATTRIBUTE_NORETURN;
+
+#define GIMPLE_CHECK(GS, CODE) \
+ do { \
+ const_gimple __gs = (GS); \
+ if (gimple_code (__gs) != (CODE)) \
+ gimple_check_failed (__gs, __FILE__, __LINE__, __FUNCTION__, \
+ (CODE), 0); \
+ } while (0)
+#else /* not ENABLE_GIMPLE_CHECKING */
+#define GIMPLE_CHECK(GS, CODE) (void)0
+#endif
+
+/* Class of GIMPLE expressions suitable for the RHS of assignments. See
+ get_gimple_rhs_class. */
+enum gimple_rhs_class
+{
+ GIMPLE_INVALID_RHS, /* The expression cannot be used on the RHS. */
+ GIMPLE_BINARY_RHS, /* The expression is a binary operation. */
+ GIMPLE_UNARY_RHS, /* The expression is a unary operation. */
+ GIMPLE_SINGLE_RHS /* The expression is a single object (an SSA
+ name, a _DECL, a _REF, etc. */
+};
+
+/* Specific flags for individual GIMPLE statements. These flags are
+ always stored in gimple_statement_base.subcode and they may only be
+ defined for statement codes that do not use sub-codes.
+
+ Values for the masks can overlap as long as the overlapping values
+ are never used in the same statement class.
+
+ The maximum mask value that can be defined is 1 << 15 (i.e., each
+ statement code can hold up to 16 bitflags).
+
+ Keep this list sorted. */
+enum gf_mask {
+ GF_ASM_INPUT = 1 << 0,
+ GF_ASM_VOLATILE = 1 << 1,
+ GF_CALL_CANNOT_INLINE = 1 << 0,
+ GF_CALL_FROM_THUNK = 1 << 1,
+ GF_CALL_RETURN_SLOT_OPT = 1 << 2,
+ GF_CALL_TAILCALL = 1 << 3,
+ GF_CALL_VA_ARG_PACK = 1 << 4,
+ GF_OMP_PARALLEL_COMBINED = 1 << 0,
+
+ /* True on an GIMPLE_OMP_RETURN statement if the return does not require
+ a thread synchronization via some sort of barrier. The exact barrier
+ that would otherwise be emitted is dependent on the OMP statement with
+ which this return is associated. */
+ GF_OMP_RETURN_NOWAIT = 1 << 0,
+
+ GF_OMP_SECTION_LAST = 1 << 0,
+ GF_PREDICT_TAKEN = 1 << 15
+};
+
+/* Masks for selecting a pass local flag (PLF) to work on. These
+ masks are used by gimple_set_plf and gimple_plf. */
+enum plf_mask {
+ GF_PLF_1 = 1 << 0,
+ GF_PLF_2 = 1 << 1
+};
+
+/* A node in a gimple_seq_d. */
+struct gimple_seq_node_d GTY((chain_next ("%h.next"), chain_prev ("%h.prev")))
+{
+ gimple stmt;
+ struct gimple_seq_node_d *prev;
+ struct gimple_seq_node_d *next;
+};
+
+/* A double-linked sequence of gimple statements. */
+struct gimple_seq_d GTY ((chain_next ("%h.next_free")))
+{
+ /* First and last statements in the sequence. */
+ gimple_seq_node first;
+ gimple_seq_node last;
+
+ /* Sequences are created/destroyed frequently. To minimize
+ allocation activity, deallocated sequences are kept in a pool of
+ available sequences. This is the pointer to the next free
+ sequence in the pool. */
+ gimple_seq next_free;
+};
+
+
+/* Return the first node in GIMPLE sequence S. */
+
+static inline gimple_seq_node
+gimple_seq_first (const_gimple_seq s)
+{
+ return s ? s->first : NULL;
+}
+
+
+/* Return the first statement in GIMPLE sequence S. */
+
+static inline gimple
+gimple_seq_first_stmt (const_gimple_seq s)
+{
+ gimple_seq_node n = gimple_seq_first (s);
+ return (n) ? n->stmt : NULL;
+}
+
+
+/* Return the last node in GIMPLE sequence S. */
+
+static inline gimple_seq_node
+gimple_seq_last (const_gimple_seq s)
+{
+ return s ? s->last : NULL;
+}
+
+
+/* Return the last statement in GIMPLE sequence S. */
+
+static inline gimple
+gimple_seq_last_stmt (const_gimple_seq s)
+{
+ gimple_seq_node n = gimple_seq_last (s);
+ return (n) ? n->stmt : NULL;
+}
+
+
+/* Set the last node in GIMPLE sequence S to LAST. */
+
+static inline void
+gimple_seq_set_last (gimple_seq s, gimple_seq_node last)
+{
+ s->last = last;
+}
+
+
+/* Set the first node in GIMPLE sequence S to FIRST. */
+
+static inline void
+gimple_seq_set_first (gimple_seq s, gimple_seq_node first)
+{
+ s->first = first;
+}
+
+
+/* Return true if GIMPLE sequence S is empty. */
+
+static inline bool
+gimple_seq_empty_p (const_gimple_seq s)
+{
+ return s == NULL || s->first == NULL;
+}
+
+
+void gimple_seq_add_stmt (gimple_seq *, gimple);
+
+/* Allocate a new sequence and initialize its first element with STMT. */
+
+static inline gimple_seq
+gimple_seq_alloc_with_stmt (gimple stmt)
+{
+ gimple_seq seq = NULL;
+ gimple_seq_add_stmt (&seq, stmt);
+ return seq;
+}
+
+
+/* Returns the sequence of statements in BB. */
+
+static inline gimple_seq
+bb_seq (const_basic_block bb)
+{
+ return (!(bb->flags & BB_RTL) && bb->il.gimple) ? bb->il.gimple->seq : NULL;
+}
+
+
+/* Sets the sequence of statements in BB to SEQ. */
+
+static inline void
+set_bb_seq (basic_block bb, gimple_seq seq)
+{
+ gcc_assert (!(bb->flags & BB_RTL));
+ bb->il.gimple->seq = seq;
+}
+
+/* Iterator object for GIMPLE statement sequences. */
+
+typedef struct
+{
+ /* Sequence node holding the current statement. */
+ gimple_seq_node ptr;
+
+ /* Sequence and basic block holding the statement. These fields
+ are necessary to handle edge cases such as when statement is
+ added to an empty basic block or when the last statement of a
+ block/sequence is removed. */
+ gimple_seq seq;
+ basic_block bb;
+} gimple_stmt_iterator;
+
+
+/* Data structure definitions for GIMPLE tuples. NOTE: word markers
+ are for 64 bit hosts. */
+
+struct gimple_statement_base GTY(())
+{
+ /* [ WORD 1 ]
+ Main identifying code for a tuple. */
+ ENUM_BITFIELD(gimple_code) code : 8;
+
+ /* Nonzero if a warning should not be emitted on this tuple. */
+ unsigned int no_warning : 1;
+
+ /* Nonzero if this tuple has been visited. Passes are responsible
+ for clearing this bit before using it. */
+ unsigned int visited : 1;
+
+ /* Nonzero if this tuple represents a non-temporal move. */
+ unsigned int nontemporal_move : 1;
+
+ /* Pass local flags. These flags are free for any pass to use as
+ they see fit. Passes should not assume that these flags contain
+ any useful value when the pass starts. Any initial state that
+ the pass requires should be set on entry to the pass. See
+ gimple_set_plf and gimple_plf for usage. */
+ unsigned int plf : 2;
+
+ /* Nonzero if this statement has been modified and needs to have its
+ operands rescanned. */
+ unsigned modified : 1;
+
+ /* Nonzero if this statement contains volatile operands. */
+ unsigned has_volatile_ops : 1;
+
+ /* Nonzero if this statement contains memory refernces. */
+ unsigned references_memory_p : 1;
+
+ /* The SUBCODE field can be used for tuple-specific flags for tuples
+ that do not require subcodes. Note that SUBCODE should be at
+ least as wide as tree codes, as several tuples store tree codes
+ in there. */
+ unsigned int subcode : 16;
+
+ /* UID of this statement. */
+ unsigned uid;
+
+ /* [ WORD 2 ]
+ Locus information for debug info. */
+ location_t location;
+
+ /* Number of operands in this tuple. */
+ unsigned num_ops;
+
+ /* [ WORD 3 ]
+ Basic block holding this statement. */
+ struct basic_block_def *bb;
+
+ /* [ WORD 4 ]
+ Lexical block holding this statement. */
+ tree block;
+};
+
+
+/* Base structure for tuples with operands. */
+
+struct gimple_statement_with_ops_base GTY(())
+{
+ /* [ WORD 1-4 ] */
+ struct gimple_statement_base gsbase;
+
+ /* [ WORD 5 ]
+ Symbols whose addresses are taken by this statement (i.e., they
+ appear inside ADDR_EXPR nodes). */
+ bitmap GTY((skip (""))) addresses_taken;
+
+ /* [ WORD 6-7 ]
+ SSA operand vectors. NOTE: It should be possible to
+ amalgamate these vectors with the operand vector OP. However,
+ the SSA operand vectors are organized differently and contain
+ more information (like immediate use chaining). */
+ struct def_optype_d GTY((skip (""))) *def_ops;
+ struct use_optype_d GTY((skip (""))) *use_ops;
+};
+
+
+/* Statements that take register operands. */
+
+struct gimple_statement_with_ops GTY(())
+{
+ /* [ WORD 1-7 ] */
+ struct gimple_statement_with_ops_base opbase;
+
+ /* [ WORD 8 ]
+ Operand vector. NOTE! This must always be the last field
+ of this structure. In particular, this means that this
+ structure cannot be embedded inside another one. */
+ tree GTY((length ("%h.opbase.gsbase.num_ops"))) op[1];
+};
+
+
+/* Base for statements that take both memory and register operands. */
+
+struct gimple_statement_with_memory_ops_base GTY(())
+{
+ /* [ WORD 1-7 ] */
+ struct gimple_statement_with_ops_base opbase;
+
+ /* [ WORD 8-9 ]
+ Vectors for virtual operands. */
+ struct voptype_d GTY((skip (""))) *vdef_ops;
+ struct voptype_d GTY((skip (""))) *vuse_ops;
+
+ /* [ WORD 9-10 ]
+ Symbols stored/loaded by this statement. */
+ bitmap GTY((skip (""))) stores;
+ bitmap GTY((skip (""))) loads;
+};
+
+
+/* Statements that take both memory and register operands. */
+
+struct gimple_statement_with_memory_ops GTY(())
+{
+ /* [ WORD 1-10 ] */
+ struct gimple_statement_with_memory_ops_base membase;
+
+ /* [ WORD 11 ]
+ Operand vector. NOTE! This must always be the last field
+ of this structure. In particular, this means that this
+ structure cannot be embedded inside another one. */
+ tree GTY((length ("%h.membase.opbase.gsbase.num_ops"))) op[1];
+};
+
+
+/* OpenMP statements (#pragma omp). */
+
+struct gimple_statement_omp GTY(())
+{
+ /* [ WORD 1-4 ] */
+ struct gimple_statement_base gsbase;
+
+ /* [ WORD 5 ] */
+ gimple_seq body;
+};
+
+
+/* GIMPLE_BIND */
+
+struct gimple_statement_bind GTY(())
+{
+ /* [ WORD 1-4 ] */
+ struct gimple_statement_base gsbase;
+
+ /* [ WORD 5 ]
+ Variables declared in this scope. */
+ tree vars;
+
+ /* [ WORD 6 ]
+ This is different than the BLOCK field in gimple_statement_base,
+ which is analogous to TREE_BLOCK (i.e., the lexical block holding
+ this statement). This field is the equivalent of BIND_EXPR_BLOCK
+ in tree land (i.e., the lexical scope defined by this bind). See
+ gimple-low.c. */
+ tree block;
+
+ /* [ WORD 7 ] */
+ gimple_seq body;
+};
+
+
+/* GIMPLE_CATCH */
+
+struct gimple_statement_catch GTY(())
+{
+ /* [ WORD 1-4 ] */
+ struct gimple_statement_base gsbase;
+
+ /* [ WORD 5 ] */
+ tree types;
+
+ /* [ WORD 6 ] */
+ gimple_seq handler;
+};
+
+
+/* GIMPLE_EH_FILTER */
+
+struct gimple_statement_eh_filter GTY(())
+{
+ /* [ WORD 1-4 ] */
+ struct gimple_statement_base gsbase;
+
+ /* Subcode: EH_FILTER_MUST_NOT_THROW. A boolean flag analogous to
+ the tree counterpart. */
+
+ /* [ WORD 5 ]
+ Filter types. */
+ tree types;
+
+ /* [ WORD 6 ]
+ Failure actions. */
+ gimple_seq failure;
+};
+
+
+/* GIMPLE_PHI */
+
+struct gimple_statement_phi GTY(())
+{
+ /* [ WORD 1-4 ] */
+ struct gimple_statement_base gsbase;
+
+ /* [ WORD 5 ] */
+ unsigned capacity;
+ unsigned nargs;
+
+ /* [ WORD 6 ] */
+ tree result;
+
+ /* [ WORD 7 ] */
+ struct phi_arg_d GTY ((length ("%h.nargs"))) args[1];
+};
+
+
+/* GIMPLE_RESX */
+
+struct gimple_statement_resx GTY(())
+{
+ /* [ WORD 1-4 ] */
+ struct gimple_statement_base gsbase;
+
+ /* [ WORD 5 ]
+ Exception region number. */
+ int region;
+};
+
+
+/* GIMPLE_TRY */
+
+struct gimple_statement_try GTY(())
+{
+ /* [ WORD 1-4 ] */
+ struct gimple_statement_base gsbase;
+
+ /* [ WORD 5 ]
+ Expression to evaluate. */
+ gimple_seq eval;
+
+ /* [ WORD 6 ]
+ Cleanup expression. */
+ gimple_seq cleanup;
+};
+
+/* Kind of GIMPLE_TRY statements. */
+enum gimple_try_flags
+{
+ /* A try/catch. */
+ GIMPLE_TRY_CATCH = 1 << 0,
+
+ /* A try/finally. */
+ GIMPLE_TRY_FINALLY = 1 << 1,
+ GIMPLE_TRY_KIND = GIMPLE_TRY_CATCH | GIMPLE_TRY_FINALLY,
+
+ /* Analogous to TRY_CATCH_IS_CLEANUP. */
+ GIMPLE_TRY_CATCH_IS_CLEANUP = 1 << 2
+};
+
+/* GIMPLE_WITH_CLEANUP_EXPR */
+
+struct gimple_statement_wce GTY(())
+{
+ /* [ WORD 1-4 ] */
+ struct gimple_statement_base gsbase;
+
+ /* Subcode: CLEANUP_EH_ONLY. True if the cleanup should only be
+ executed if an exception is thrown, not on normal exit of its
+ scope. This flag is analogous to the CLEANUP_EH_ONLY flag
+ in TARGET_EXPRs. */
+
+ /* [ WORD 5 ]
+ Cleanup expression. */
+ gimple_seq cleanup;
+};
+
+
+/* GIMPLE_ASM */
+
+struct gimple_statement_asm GTY(())
+{
+ /* [ WORD 1-10 ] */
+ struct gimple_statement_with_memory_ops_base membase;
+
+ /* [ WORD 11 ]
+ __asm__ statement. */
+ const char *string;
+
+ /* [ WORD 12 ]
+ Number of inputs, outputs and clobbers. */
+ unsigned char ni;
+ unsigned char no;
+ unsigned short nc;
+
+ /* [ WORD 13 ]
+ Operand vector. NOTE! This must always be the last field
+ of this structure. In particular, this means that this
+ structure cannot be embedded inside another one. */
+ tree GTY((length ("%h.membase.opbase.gsbase.num_ops"))) op[1];
+};
+
+/* GIMPLE_OMP_CRITICAL */
+
+struct gimple_statement_omp_critical GTY(())
+{
+ /* [ WORD 1-5 ] */
+ struct gimple_statement_omp omp;
+
+ /* [ WORD 6 ]
+ Critical section name. */
+ tree name;
+};
+
+
+struct gimple_omp_for_iter GTY(())
+{
+ /* Condition code. */
+ enum tree_code cond;
+
+ /* Index variable. */
+ tree index;
+
+ /* Initial value. */
+ tree initial;
+
+ /* Final value. */
+ tree final;
+
+ /* Increment. */
+ tree incr;
+};
+
+/* GIMPLE_OMP_FOR */
+
+struct gimple_statement_omp_for GTY(())
+{
+ /* [ WORD 1-5 ] */
+ struct gimple_statement_omp omp;
+
+ /* [ WORD 6 ] */
+ tree clauses;
+
+ /* [ WORD 7 ]
+ Number of elements in iter array. */
+ size_t collapse;
+
+ /* [ WORD 8 ] */
+ struct gimple_omp_for_iter * GTY((length ("%h.collapse"))) iter;
+
+ /* [ WORD 9 ]
+ Pre-body evaluated before the loop body begins. */
+ gimple_seq pre_body;
+};
+
+
+/* GIMPLE_OMP_PARALLEL */
+
+struct gimple_statement_omp_parallel GTY(())
+{
+ /* [ WORD 1-5 ] */
+ struct gimple_statement_omp omp;
+
+ /* [ WORD 6 ]
+ Clauses. */
+ tree clauses;
+
+ /* [ WORD 7 ]
+ Child function holding the body of the parallel region. */
+ tree child_fn;
+
+ /* [ WORD 8 ]
+ Shared data argument. */
+ tree data_arg;
+};
+
+
+/* GIMPLE_OMP_TASK */
+
+struct gimple_statement_omp_task GTY(())
+{
+ /* [ WORD 1-8 ] */
+ struct gimple_statement_omp_parallel par;
+
+ /* [ WORD 9 ]
+ Child function holding firstprivate initialization if needed. */
+ tree copy_fn;
+
+ /* [ WORD 10-11 ]
+ Size and alignment in bytes of the argument data block. */
+ tree arg_size;
+ tree arg_align;
+};
+
+
+/* GIMPLE_OMP_SECTION */
+/* Uses struct gimple_statement_omp. */
+
+
+/* GIMPLE_OMP_SECTIONS */
+
+struct gimple_statement_omp_sections GTY(())
+{
+ /* [ WORD 1-5 ] */
+ struct gimple_statement_omp omp;
+
+ /* [ WORD 6 ] */
+ tree clauses;
+
+ /* [ WORD 7 ]
+ The control variable used for deciding which of the sections to
+ execute. */
+ tree control;
+};
+
+/* GIMPLE_OMP_CONTINUE.
+
+ Note: This does not inherit from gimple_statement_omp, because we
+ do not need the body field. */
+
+struct gimple_statement_omp_continue GTY(())
+{
+ /* [ WORD 1-4 ] */
+ struct gimple_statement_base gsbase;
+
+ /* [ WORD 5 ] */
+ tree control_def;
+
+ /* [ WORD 6 ] */
+ tree control_use;
+};
+
+/* GIMPLE_OMP_SINGLE */
+
+struct gimple_statement_omp_single GTY(())
+{
+ /* [ WORD 1-5 ] */
+ struct gimple_statement_omp omp;
+
+ /* [ WORD 6 ] */
+ tree clauses;
+};
+
+
+/* GIMPLE_OMP_ATOMIC_LOAD.
+ Note: This is based on gimple_statement_base, not g_s_omp, because g_s_omp
+ contains a sequence, which we don't need here. */
+
+struct gimple_statement_omp_atomic_load GTY(())
+{
+ /* [ WORD 1-4 ] */
+ struct gimple_statement_base gsbase;
+
+ /* [ WORD 5-6 ] */
+ tree rhs, lhs;
+};
+
+/* GIMPLE_OMP_ATOMIC_STORE.
+ See note on GIMPLE_OMP_ATOMIC_LOAD. */
+
+struct gimple_statement_omp_atomic_store GTY(())
+{
+ /* [ WORD 1-4 ] */
+ struct gimple_statement_base gsbase;
+
+ /* [ WORD 5 ] */
+ tree val;
+};
+
+enum gimple_statement_structure_enum {
+#define DEFGSSTRUCT(SYM, STRING) SYM,
+#include "gsstruct.def"
+#undef DEFGSSTRUCT
+ LAST_GSS_ENUM
+};
+
+
+/* Define the overall contents of a gimple tuple. It may be any of the
+ structures declared above for various types of tuples. */
+
+union gimple_statement_d GTY ((desc ("gimple_statement_structure (&%h)")))
+{
+ struct gimple_statement_base GTY ((tag ("GSS_BASE"))) gsbase;
+ struct gimple_statement_with_ops GTY ((tag ("GSS_WITH_OPS"))) gsops;
+ struct gimple_statement_with_memory_ops GTY ((tag ("GSS_WITH_MEM_OPS"))) gsmem;
+ struct gimple_statement_omp GTY ((tag ("GSS_OMP"))) omp;
+ struct gimple_statement_bind GTY ((tag ("GSS_BIND"))) gimple_bind;
+ struct gimple_statement_catch GTY ((tag ("GSS_CATCH"))) gimple_catch;
+ struct gimple_statement_eh_filter GTY ((tag ("GSS_EH_FILTER"))) gimple_eh_filter;
+ struct gimple_statement_phi GTY ((tag ("GSS_PHI"))) gimple_phi;
+ struct gimple_statement_resx GTY ((tag ("GSS_RESX"))) gimple_resx;
+ struct gimple_statement_try GTY ((tag ("GSS_TRY"))) gimple_try;
+ struct gimple_statement_wce GTY ((tag ("GSS_WCE"))) gimple_wce;
+ struct gimple_statement_asm GTY ((tag ("GSS_ASM"))) gimple_asm;
+ struct gimple_statement_omp_critical GTY ((tag ("GSS_OMP_CRITICAL"))) gimple_omp_critical;
+ struct gimple_statement_omp_for GTY ((tag ("GSS_OMP_FOR"))) gimple_omp_for;
+ struct gimple_statement_omp_parallel GTY ((tag ("GSS_OMP_PARALLEL"))) gimple_omp_parallel;
+ struct gimple_statement_omp_task GTY ((tag ("GSS_OMP_TASK"))) gimple_omp_task;
+ struct gimple_statement_omp_sections GTY ((tag ("GSS_OMP_SECTIONS"))) gimple_omp_sections;
+ struct gimple_statement_omp_single GTY ((tag ("GSS_OMP_SINGLE"))) gimple_omp_single;
+ struct gimple_statement_omp_continue GTY ((tag ("GSS_OMP_CONTINUE"))) gimple_omp_continue;
+ struct gimple_statement_omp_atomic_load GTY ((tag ("GSS_OMP_ATOMIC_LOAD"))) gimple_omp_atomic_load;
+ struct gimple_statement_omp_atomic_store GTY ((tag ("GSS_OMP_ATOMIC_STORE"))) gimple_omp_atomic_store;
+};
+
+/* In gimple.c. */
+gimple gimple_build_return (tree);
+
+gimple gimple_build_assign_stat (tree, tree MEM_STAT_DECL);
+#define gimple_build_assign(l,r) gimple_build_assign_stat (l, r MEM_STAT_INFO)
+
+void extract_ops_from_tree (tree, enum tree_code *, tree *, tree *);
+
+gimple gimple_build_assign_with_ops_stat (enum tree_code, tree, tree,
+ tree MEM_STAT_DECL);
+#define gimple_build_assign_with_ops(c,o1,o2,o3) \
+ gimple_build_assign_with_ops_stat (c, o1, o2, o3 MEM_STAT_INFO)
+
+gimple gimple_build_call_vec (tree, VEC(tree, heap) *);
+gimple gimple_build_call (tree, unsigned, ...);
+gimple gimple_build_call_from_tree (tree);
+gimple gimplify_assign (tree, tree, gimple_seq *);
+gimple gimple_build_cond (enum tree_code, tree, tree, tree, tree);
+gimple gimple_build_label (tree label);
+gimple gimple_build_goto (tree dest);
+gimple gimple_build_nop (void);
+gimple gimple_build_bind (tree, gimple_seq, tree);
+gimple gimple_build_asm (const char *, unsigned, unsigned, unsigned, ...);
+gimple gimple_build_asm_vec (const char *, VEC(tree,gc) *, VEC(tree,gc) *,
+ VEC(tree,gc) *);
+gimple gimple_build_catch (tree, gimple_seq);
+gimple gimple_build_eh_filter (tree, gimple_seq);
+gimple gimple_build_try (gimple_seq, gimple_seq, unsigned int);
+gimple gimple_build_wce (gimple_seq);
+gimple gimple_build_resx (int);
+gimple gimple_build_switch (unsigned, tree, tree, ...);
+gimple gimple_build_switch_vec (tree, tree, VEC(tree,heap) *);
+gimple gimple_build_omp_parallel (gimple_seq, tree, tree, tree);
+gimple gimple_build_omp_task (gimple_seq, tree, tree, tree, tree, tree, tree);
+gimple gimple_build_omp_for (gimple_seq, tree, size_t, gimple_seq);
+gimple gimple_build_omp_critical (gimple_seq, tree);
+gimple gimple_build_omp_section (gimple_seq);
+gimple gimple_build_omp_continue (tree, tree);
+gimple gimple_build_omp_master (gimple_seq);
+gimple gimple_build_omp_return (bool);
+gimple gimple_build_omp_ordered (gimple_seq);
+gimple gimple_build_omp_sections (gimple_seq, tree);
+gimple gimple_build_omp_sections_switch (void);
+gimple gimple_build_omp_single (gimple_seq, tree);
+gimple gimple_build_cdt (tree, tree);
+gimple gimple_build_omp_atomic_load (tree, tree);
+gimple gimple_build_omp_atomic_store (tree);
+gimple gimple_build_predict (enum br_predictor, enum prediction);
+enum gimple_statement_structure_enum gimple_statement_structure (gimple);
+enum gimple_statement_structure_enum gss_for_assign (enum tree_code);
+void sort_case_labels (VEC(tree,heap) *);
+void gimple_set_body (tree, gimple_seq);
+gimple_seq gimple_body (tree);
+gimple_seq gimple_seq_alloc (void);
+void gimple_seq_free (gimple_seq);
+void gimple_seq_add_seq (gimple_seq *, gimple_seq);
+gimple_seq gimple_seq_copy (gimple_seq);
+int gimple_call_flags (const_gimple);
+bool gimple_assign_copy_p (gimple);
+bool gimple_assign_ssa_name_copy_p (gimple);
+bool gimple_assign_single_p (gimple);
+bool gimple_assign_unary_nop_p (gimple);
+void gimple_set_bb (gimple, struct basic_block_def *);
+tree gimple_fold (const_gimple);
+void gimple_assign_set_rhs_from_tree (gimple_stmt_iterator *, tree);
+void gimple_assign_set_rhs_with_ops (gimple_stmt_iterator *, enum tree_code,
+ tree, tree);
+tree gimple_get_lhs (const_gimple);
+void gimple_set_lhs (gimple, tree);
+gimple gimple_copy (gimple);
+bool is_gimple_operand (const_tree);
+void gimple_set_modified (gimple, bool);
+void gimple_cond_get_ops_from_tree (tree, enum tree_code *, tree *, tree *);
+gimple gimple_build_cond_from_tree (tree, tree, tree);
+void gimple_cond_set_condition_from_tree (gimple, tree);
+bool gimple_has_side_effects (const_gimple);
+bool gimple_rhs_has_side_effects (const_gimple);
+bool gimple_could_trap_p (gimple);
+bool gimple_assign_rhs_could_trap_p (gimple);
+void gimple_regimplify_operands (gimple, gimple_stmt_iterator *);
+bool empty_body_p (gimple_seq);
+unsigned get_gimple_rhs_num_ops (enum tree_code);
+
+/* Returns true iff T is a valid GIMPLE statement. */
+extern bool is_gimple_stmt (tree);
+
+/* Returns true iff TYPE is a valid type for a scalar register variable. */
+extern bool is_gimple_reg_type (tree);
+/* Returns true iff T is a scalar register variable. */
+extern bool is_gimple_reg (tree);
+/* Returns true if T is a GIMPLE temporary variable, false otherwise. */
+extern bool is_gimple_formal_tmp_var (tree);
+/* Returns true if T is a GIMPLE temporary register variable. */
+extern bool is_gimple_formal_tmp_reg (tree);
+/* Returns true iff T is any sort of variable. */
+extern bool is_gimple_variable (tree);
+/* Returns true iff T is any sort of symbol. */
+extern bool is_gimple_id (tree);
+/* Returns true iff T is a variable or an INDIRECT_REF (of a variable). */
+extern bool is_gimple_min_lval (tree);
+/* Returns true iff T is something whose address can be taken. */
+extern bool is_gimple_addressable (tree);
+/* Returns true iff T is any valid GIMPLE lvalue. */
+extern bool is_gimple_lvalue (tree);
+
+/* Returns true iff T is a GIMPLE address. */
+bool is_gimple_address (const_tree);
+/* Returns true iff T is a GIMPLE invariant address. */
+bool is_gimple_invariant_address (const_tree);
+/* Returns true iff T is a valid GIMPLE constant. */
+bool is_gimple_constant (const_tree);
+/* Returns true iff T is a GIMPLE restricted function invariant. */
+extern bool is_gimple_min_invariant (const_tree);
+/* Returns true iff T is a GIMPLE rvalue. */
+extern bool is_gimple_val (tree);
+/* Returns true iff T is a GIMPLE asm statement input. */
+extern bool is_gimple_asm_val (tree);
+/* Returns true iff T is a valid rhs for a MODIFY_EXPR where the LHS is a
+ GIMPLE temporary, a renamed user variable, or something else,
+ respectively. */
+extern bool is_gimple_formal_tmp_rhs (tree);
+extern bool is_gimple_reg_rhs (tree);
+extern bool is_gimple_mem_rhs (tree);
+
+/* Returns true iff T is a valid if-statement condition. */
+extern bool is_gimple_condexpr (tree);
+
+/* Returns true iff T is a type conversion. */
+extern bool is_gimple_cast (tree);
+/* Returns true iff T is a variable that does not need to live in memory. */
+extern bool is_gimple_non_addressable (tree t);
+
+/* Returns true iff T is a valid call address expression. */
+extern bool is_gimple_call_addr (tree);
+/* If T makes a function call, returns the CALL_EXPR operand. */
+extern tree get_call_expr_in (tree t);
+
+extern void recalculate_side_effects (tree);
+
+/* In gimplify.c */
+extern tree create_tmp_var_raw (tree, const char *);
+extern tree create_tmp_var_name (const char *);
+extern tree create_tmp_var (tree, const char *);
+extern tree get_initialized_tmp_var (tree, gimple_seq *, gimple_seq *);
+extern tree get_formal_tmp_var (tree, gimple_seq *);
+extern void declare_vars (tree, gimple, bool);
+extern void tree_annotate_all_with_location (tree *, location_t);
+extern void annotate_all_with_location (gimple_seq, location_t);
+
+/* Validation of GIMPLE expressions. Note that these predicates only check
+ the basic form of the expression, they don't recurse to make sure that
+ underlying nodes are also of the right form. */
+typedef bool (*gimple_predicate)(tree);
+
+
+/* FIXME we should deduce this from the predicate. */
+typedef enum fallback_t {
+ fb_none = 0, /* Do not generate a temporary. */
+
+ fb_rvalue = 1, /* Generate an rvalue to hold the result of a
+ gimplified expression. */
+
+ fb_lvalue = 2, /* Generate an lvalue to hold the result of a
+ gimplified expression. */
+
+ fb_mayfail = 4, /* Gimplification may fail. Error issued
+ afterwards. */
+ fb_either= fb_rvalue | fb_lvalue
+} fallback_t;
+
+enum gimplify_status {
+ GS_ERROR = -2, /* Something Bad Seen. */
+ GS_UNHANDLED = -1, /* A langhook result for "I dunno". */
+ GS_OK = 0, /* We did something, maybe more to do. */
+ GS_ALL_DONE = 1 /* The expression is fully gimplified. */
+};
+
+struct gimplify_ctx
+{
+ struct gimplify_ctx *prev_context;
+
+ VEC(gimple,heap) *bind_expr_stack;
+ tree temps;
+ gimple_seq conditional_cleanups;
+ tree exit_label;
+ tree return_temp;
+
+ VEC(tree,heap) *case_labels;
+ /* The formal temporary table. Should this be persistent? */
+ htab_t temp_htab;
+
+ int conditions;
+ bool save_stack;
+ bool into_ssa;
+ bool allow_rhs_cond_expr;
+};
+
+extern enum gimplify_status gimplify_expr (tree *, gimple_seq *, gimple_seq *,
+ bool (*) (tree), fallback_t);
+extern void gimplify_type_sizes (tree, gimple_seq *);
+extern void gimplify_one_sizepos (tree *, gimple_seq *);
+extern bool gimplify_stmt (tree *, gimple_seq *);
+extern gimple gimplify_body (tree *, tree, bool);
+extern void push_gimplify_context (struct gimplify_ctx *);
+extern void pop_gimplify_context (gimple);
+extern void gimplify_and_add (tree, gimple_seq *);
+
+/* Miscellaneous helpers. */
+extern void gimple_add_tmp_var (tree);
+extern gimple gimple_current_bind_expr (void);
+extern VEC(gimple, heap) *gimple_bind_expr_stack (void);
+extern tree voidify_wrapper_expr (tree, tree);
+extern tree build_and_jump (tree *);
+extern tree alloc_stmt_list (void);
+extern void free_stmt_list (tree);
+extern tree force_labels_r (tree *, int *, void *);
+extern enum gimplify_status gimplify_va_arg_expr (tree *, gimple_seq *,
+ gimple_seq *);
+struct gimplify_omp_ctx;
+extern void omp_firstprivatize_variable (struct gimplify_omp_ctx *, tree);
+extern tree gimple_boolify (tree);
+extern gimple_predicate rhs_predicate_for (tree);
+extern tree canonicalize_cond_expr_cond (tree);
+
+/* In omp-low.c. */
+extern void diagnose_omp_structured_block_errors (tree);
+extern tree omp_reduction_init (tree, tree);
+
+/* In tree-nested.c. */
+extern void lower_nested_functions (tree);
+extern void insert_field_into_struct (tree, tree);
+
+/* In gimplify.c. */
+extern void gimplify_function_tree (tree);
+
+/* In cfgexpand.c. */
+extern tree gimple_assign_rhs_to_tree (gimple);
+
+/* In builtins.c */
+extern bool validate_gimple_arglist (const_gimple, ...);
+
+/* In tree-ssa-operands.c */
+extern void gimple_add_to_addresses_taken (gimple, tree);
+
+/* Return the code for GIMPLE statement G. */
+
+static inline enum gimple_code
+gimple_code (const_gimple g)
+{
+ return g->gsbase.code;
+}
+
+
+/* Return true if statement G has sub-statements. This is only true for
+ High GIMPLE statements. */
+
+static inline bool
+gimple_has_substatements (gimple g)
+{
+ switch (gimple_code (g))
+ {
+ case GIMPLE_BIND:
+ case GIMPLE_CATCH:
+ case GIMPLE_EH_FILTER:
+ case GIMPLE_TRY:
+ case GIMPLE_OMP_FOR:
+ case GIMPLE_OMP_MASTER:
+ case GIMPLE_OMP_ORDERED:
+ case GIMPLE_OMP_SECTION:
+ case GIMPLE_OMP_PARALLEL:
+ case GIMPLE_OMP_TASK:
+ case GIMPLE_OMP_SECTIONS:
+ case GIMPLE_OMP_SINGLE:
+ case GIMPLE_WITH_CLEANUP_EXPR:
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+
+/* Return the basic block holding statement G. */
+
+static inline struct basic_block_def *
+gimple_bb (const_gimple g)
+{
+ return g->gsbase.bb;
+}
+
+
+/* Return the lexical scope block holding statement G. */
+
+static inline tree
+gimple_block (const_gimple g)
+{
+ return g->gsbase.block;
+}
+
+
+/* Set BLOCK to be the lexical scope block holding statement G. */
+
+static inline void
+gimple_set_block (gimple g, tree block)
+{
+ g->gsbase.block = block;
+}
+
+
+/* Return location information for statement G. */
+
+static inline location_t
+gimple_location (const_gimple g)
+{
+ return g->gsbase.location;
+}
+
+/* Return pointer to location information for statement G. */
+
+static inline const location_t *
+gimple_location_ptr (const_gimple g)
+{
+ return &g->gsbase.location;
+}
+
+
+/* Set location information for statement G. */
+
+static inline void
+gimple_set_location (gimple g, location_t location)
+{
+ g->gsbase.location = location;
+}
+
+
+/* Return true if G contains location information. */
+
+static inline bool
+gimple_has_location (const_gimple g)
+{
+ return gimple_location (g) != UNKNOWN_LOCATION;
+}
+
+
+/* Return the file name of the location of STMT. */
+
+static inline const char *
+gimple_filename (const_gimple stmt)
+{
+ return LOCATION_FILE (gimple_location (stmt));
+}
+
+
+/* Return the line number of the location of STMT. */
+
+static inline int
+gimple_lineno (const_gimple stmt)
+{
+ return LOCATION_LINE (gimple_location (stmt));
+}
+
+
+/* Determine whether SEQ is a singleton. */
+
+static inline bool
+gimple_seq_singleton_p (gimple_seq seq)
+{
+ return ((gimple_seq_first (seq) != NULL)
+ && (gimple_seq_first (seq) == gimple_seq_last (seq)));
+}
+
+/* Return true if no warnings should be emitted for statement STMT. */
+
+static inline bool
+gimple_no_warning_p (const_gimple stmt)
+{
+ return stmt->gsbase.no_warning;
+}
+
+/* Set the no_warning flag of STMT to NO_WARNING. */
+
+static inline void
+gimple_set_no_warning (gimple stmt, bool no_warning)
+{
+ stmt->gsbase.no_warning = (unsigned) no_warning;
+}
+
+/* Set the visited status on statement STMT to VISITED_P. */
+
+static inline void
+gimple_set_visited (gimple stmt, bool visited_p)
+{
+ stmt->gsbase.visited = (unsigned) visited_p;
+}
+
+
+/* Return the visited status for statement STMT. */
+
+static inline bool
+gimple_visited_p (gimple stmt)
+{
+ return stmt->gsbase.visited;
+}
+
+
+/* Set pass local flag PLF on statement STMT to VAL_P. */
+
+static inline void
+gimple_set_plf (gimple stmt, enum plf_mask plf, bool val_p)
+{
+ if (val_p)
+ stmt->gsbase.plf |= (unsigned int) plf;
+ else
+ stmt->gsbase.plf &= ~((unsigned int) plf);
+}
+
+
+/* Return the value of pass local flag PLF on statement STMT. */
+
+static inline unsigned int
+gimple_plf (gimple stmt, enum plf_mask plf)
+{
+ return stmt->gsbase.plf & ((unsigned int) plf);
+}
+
+
+/* Set the uid of statement */
+
+static inline void
+gimple_set_uid (gimple g, unsigned uid)
+{
+ g->gsbase.uid = uid;
+}
+
+
+/* Return the uid of statement */
+
+static inline unsigned
+gimple_uid (const_gimple g)
+{
+ return g->gsbase.uid;
+}
+
+
+/* Return true if GIMPLE statement G has register or memory operands. */
+
+static inline bool
+gimple_has_ops (const_gimple g)
+{
+ return gimple_code (g) >= GIMPLE_COND && gimple_code (g) <= GIMPLE_RETURN;
+}
+
+
+/* Return true if GIMPLE statement G has memory operands. */
+
+static inline bool
+gimple_has_mem_ops (const_gimple g)
+{
+ return gimple_code (g) >= GIMPLE_ASSIGN && gimple_code (g) <= GIMPLE_RETURN;
+}
+
+/* Return the set of addresses taken by statement G. */
+
+static inline bitmap
+gimple_addresses_taken (const_gimple g)
+{
+ if (gimple_has_ops (g))
+ return g->gsops.opbase.addresses_taken;
+ else
+ return NULL;
+}
+
+
+/* Return a pointer to the set of addresses taken by statement G. */
+
+static inline bitmap *
+gimple_addresses_taken_ptr (gimple g)
+{
+ if (gimple_has_ops (g))
+ return &g->gsops.opbase.addresses_taken;
+ else
+ return NULL;
+}
+
+
+/* Set B to be the set of addresses taken by statement G. The
+ previous set is freed. */
+
+static inline void
+gimple_set_addresses_taken (gimple g, bitmap b)
+{
+ gcc_assert (gimple_has_ops (g));
+ BITMAP_FREE (g->gsops.opbase.addresses_taken);
+ g->gsops.opbase.addresses_taken = b;
+}
+
+
+/* Return the set of DEF operands for statement G. */
+
+static inline struct def_optype_d *
+gimple_def_ops (const_gimple g)
+{
+ if (!gimple_has_ops (g))
+ return NULL;
+ return g->gsops.opbase.def_ops;
+}
+
+
+/* Set DEF to be the set of DEF operands for statement G. */
+
+static inline void
+gimple_set_def_ops (gimple g, struct def_optype_d *def)
+{
+ gcc_assert (gimple_has_ops (g));
+ g->gsops.opbase.def_ops = def;
+}
+
+
+/* Return the set of USE operands for statement G. */
+
+static inline struct use_optype_d *
+gimple_use_ops (const_gimple g)
+{
+ if (!gimple_has_ops (g))
+ return NULL;
+ return g->gsops.opbase.use_ops;
+}
+
+
+/* Set USE to be the set of USE operands for statement G. */
+
+static inline void
+gimple_set_use_ops (gimple g, struct use_optype_d *use)
+{
+ gcc_assert (gimple_has_ops (g));
+ g->gsops.opbase.use_ops = use;
+}
+
+
+/* Return the set of VUSE operands for statement G. */
+
+static inline struct voptype_d *
+gimple_vuse_ops (const_gimple g)
+{
+ if (!gimple_has_mem_ops (g))
+ return NULL;
+ return g->gsmem.membase.vuse_ops;
+}
+
+
+/* Set OPS to be the set of VUSE operands for statement G. */
+
+static inline void
+gimple_set_vuse_ops (gimple g, struct voptype_d *ops)
+{
+ gcc_assert (gimple_has_mem_ops (g));
+ g->gsmem.membase.vuse_ops = ops;
+}
+
+
+/* Return the set of VDEF operands for statement G. */
+
+static inline struct voptype_d *
+gimple_vdef_ops (const_gimple g)
+{
+ if (!gimple_has_mem_ops (g))
+ return NULL;
+ return g->gsmem.membase.vdef_ops;
+}
+
+
+/* Set OPS to be the set of VDEF operands for statement G. */
+
+static inline void
+gimple_set_vdef_ops (gimple g, struct voptype_d *ops)
+{
+ gcc_assert (gimple_has_mem_ops (g));
+ g->gsmem.membase.vdef_ops = ops;
+}
+
+
+/* Return the set of symbols loaded by statement G. Each element of the
+ set is the DECL_UID of the corresponding symbol. */
+
+static inline bitmap
+gimple_loaded_syms (const_gimple g)
+{
+ if (!gimple_has_mem_ops (g))
+ return NULL;
+ return g->gsmem.membase.loads;
+}
+
+
+/* Return the set of symbols stored by statement G. Each element of
+ the set is the DECL_UID of the corresponding symbol. */
+
+static inline bitmap
+gimple_stored_syms (const_gimple g)
+{
+ if (!gimple_has_mem_ops (g))
+ return NULL;
+ return g->gsmem.membase.stores;
+}
+
+
+/* Return true if statement G has operands and the modified field has
+ been set. */
+
+static inline bool
+gimple_modified_p (const_gimple g)
+{
+ return (gimple_has_ops (g)) ? (bool) g->gsbase.modified : false;
+}
+
+/* Return the type of the main expression computed by STMT. Return
+ void_type_node if the statement computes nothing. */
+
+static inline tree
+gimple_expr_type (const_gimple stmt)
+{
+ enum gimple_code code = gimple_code (stmt);
+
+ if (code == GIMPLE_ASSIGN || code == GIMPLE_CALL)
+ {
+ tree type = TREE_TYPE (gimple_get_lhs (stmt));
+ /* Integral sub-types are never the type of the expression,
+ but they still can be the type of the result as the base
+ type (in which expressions are computed) is trivially
+ convertible to one of its sub-types. So always return
+ the base type here. */
+ if (INTEGRAL_TYPE_P (type)
+ && TREE_TYPE (type))
+ type = TREE_TYPE (type);
+ return type;
+ }
+ else if (code == GIMPLE_COND)
+ return boolean_type_node;
+ else
+ return void_type_node;
+}
+
+
+/* Return the tree code for the expression computed by STMT. This is
+ only valid for GIMPLE_COND, GIMPLE_CALL and GIMPLE_ASSIGN. For
+ GIMPLE_CALL, return CALL_EXPR as the expression code for
+ consistency. This is useful when the caller needs to deal with the
+ three kinds of computation that GIMPLE supports. */
+
+static inline enum tree_code
+gimple_expr_code (const_gimple stmt)
+{
+ enum gimple_code code = gimple_code (stmt);
+ if (code == GIMPLE_ASSIGN || code == GIMPLE_COND)
+ return (enum tree_code) stmt->gsbase.subcode;
+ else if (code == GIMPLE_CALL)
+ return CALL_EXPR;
+ else
+ gcc_unreachable ();
+}
+
+
+/* Mark statement S as modified, and update it. */
+
+static inline void
+update_stmt (gimple s)
+{
+ if (gimple_has_ops (s))
+ {
+ gimple_set_modified (s, true);
+ update_stmt_operands (s);
+ }
+}
+
+/* Update statement S if it has been optimized. */
+
+static inline void
+update_stmt_if_modified (gimple s)
+{
+ if (gimple_modified_p (s))
+ update_stmt_operands (s);
+}
+
+/* Return true if statement STMT contains volatile operands. */
+
+static inline bool
+gimple_has_volatile_ops (const_gimple stmt)
+{
+ if (gimple_has_mem_ops (stmt))
+ return stmt->gsbase.has_volatile_ops;
+ else
+ return false;
+}
+
+
+/* Set the HAS_VOLATILE_OPS flag to VOLATILEP. */
+
+static inline void
+gimple_set_has_volatile_ops (gimple stmt, bool volatilep)
+{
+ if (gimple_has_mem_ops (stmt))
+ stmt->gsbase.has_volatile_ops = (unsigned) volatilep;
+}
+
+
+/* Return true if statement STMT may access memory. */
+
+static inline bool
+gimple_references_memory_p (gimple stmt)
+{
+ return gimple_has_mem_ops (stmt) && stmt->gsbase.references_memory_p;
+}
+
+
+/* Set the REFERENCES_MEMORY_P flag for STMT to MEM_P. */
+
+static inline void
+gimple_set_references_memory (gimple stmt, bool mem_p)
+{
+ if (gimple_has_mem_ops (stmt))
+ stmt->gsbase.references_memory_p = (unsigned) mem_p;
+}
+
+/* Return the subcode for OMP statement S. */
+
+static inline unsigned
+gimple_omp_subcode (const_gimple s)
+{
+ gcc_assert (gimple_code (s) >= GIMPLE_OMP_ATOMIC_LOAD
+ && gimple_code (s) <= GIMPLE_OMP_SINGLE);
+ return s->gsbase.subcode;
+}
+
+/* Set the subcode for OMP statement S to SUBCODE. */
+
+static inline void
+gimple_omp_set_subcode (gimple s, unsigned int subcode)
+{
+ /* We only have 16 bits for the subcode. Assert that we are not
+ overflowing it. */
+ gcc_assert (subcode < (1 << 16));
+ s->gsbase.subcode = subcode;
+}
+
+/* Set the nowait flag on OMP_RETURN statement S. */
+
+static inline void
+gimple_omp_return_set_nowait (gimple s)
+{
+ GIMPLE_CHECK (s, GIMPLE_OMP_RETURN);
+ s->gsbase.subcode |= GF_OMP_RETURN_NOWAIT;
+}
+
+
+/* Return true if OMP return statement G has the GF_OMP_RETURN_NOWAIT
+ flag set. */
+
+static inline bool
+gimple_omp_return_nowait_p (const_gimple g)
+{
+ GIMPLE_CHECK (g, GIMPLE_OMP_RETURN);
+ return (gimple_omp_subcode (g) & GF_OMP_RETURN_NOWAIT) != 0;
+}
+
+
+/* Return true if OMP section statement G has the GF_OMP_SECTION_LAST
+ flag set. */
+
+static inline bool
+gimple_omp_section_last_p (const_gimple g)
+{
+ GIMPLE_CHECK (g, GIMPLE_OMP_SECTION);
+ return (gimple_omp_subcode (g) & GF_OMP_SECTION_LAST) != 0;
+}
+
+
+/* Set the GF_OMP_SECTION_LAST flag on G. */
+
+static inline void
+gimple_omp_section_set_last (gimple g)
+{
+ GIMPLE_CHECK (g, GIMPLE_OMP_SECTION);
+ g->gsbase.subcode |= GF_OMP_SECTION_LAST;
+}
+
+
+/* Return true if OMP parallel statement G has the
+ GF_OMP_PARALLEL_COMBINED flag set. */
+
+static inline bool
+gimple_omp_parallel_combined_p (const_gimple g)
+{
+ GIMPLE_CHECK (g, GIMPLE_OMP_PARALLEL);
+ return (gimple_omp_subcode (g) & GF_OMP_PARALLEL_COMBINED) != 0;
+}
+
+
+/* Set the GF_OMP_PARALLEL_COMBINED field in G depending on the boolean
+ value of COMBINED_P. */
+
+static inline void
+gimple_omp_parallel_set_combined_p (gimple g, bool combined_p)
+{
+ GIMPLE_CHECK (g, GIMPLE_OMP_PARALLEL);
+ if (combined_p)
+ g->gsbase.subcode |= GF_OMP_PARALLEL_COMBINED;
+ else
+ g->gsbase.subcode &= ~GF_OMP_PARALLEL_COMBINED;
+}
+
+
+/* Return the number of operands for statement GS. */
+
+static inline unsigned
+gimple_num_ops (const_gimple gs)
+{
+ return gs->gsbase.num_ops;
+}
+
+
+/* Set the number of operands for statement GS. */
+
+static inline void
+gimple_set_num_ops (gimple gs, unsigned num_ops)
+{
+ gs->gsbase.num_ops = num_ops;
+}
+
+
+/* Return the array of operands for statement GS. */
+
+static inline tree *
+gimple_ops (gimple gs)
+{
+ /* Offset in bytes to the location of the operand vector in every
+ tuple structure. Defined in gimple.c */
+ extern size_t const gimple_ops_offset_[];
+
+ if (!gimple_has_ops (gs))
+ return NULL;
+
+ /* All the tuples have their operand vector at the very bottom
+ of the structure. */
+ return ((tree *) ((char *) gs + gimple_ops_offset_[gimple_code (gs)]));
+}
+
+
+/* Return operand I for statement GS. */
+
+static inline tree
+gimple_op (const_gimple gs, unsigned i)
+{
+ if (gimple_has_ops (gs))
+ {
+ gcc_assert (i < gimple_num_ops (gs));
+ return gimple_ops (CONST_CAST_GIMPLE (gs))[i];
+ }
+ else
+ return NULL_TREE;
+}
+
+/* Return a pointer to operand I for statement GS. */
+
+static inline tree *
+gimple_op_ptr (const_gimple gs, unsigned i)
+{
+ if (gimple_has_ops (gs))
+ {
+ gcc_assert (i < gimple_num_ops (gs));
+ return gimple_ops (CONST_CAST_GIMPLE (gs)) + i;
+ }
+ else
+ return NULL;
+}
+
+/* Set operand I of statement GS to OP. */
+
+static inline void
+gimple_set_op (gimple gs, unsigned i, tree op)
+{
+ gcc_assert (gimple_has_ops (gs) && i < gimple_num_ops (gs));
+
+ /* Note. It may be tempting to assert that OP matches
+ is_gimple_operand, but that would be wrong. Different tuples
+ accept slightly different sets of tree operands. Each caller
+ should perform its own validation. */
+ gimple_ops (gs)[i] = op;
+}
+
+/* Return true if GS is a GIMPLE_ASSIGN. */
+
+static inline bool
+is_gimple_assign (const_gimple gs)
+{
+ return gimple_code (gs) == GIMPLE_ASSIGN;
+}
+
+/* Determine if expression CODE is one of the valid expressions that can
+ be used on the RHS of GIMPLE assignments. */
+
+static inline enum gimple_rhs_class
+get_gimple_rhs_class (enum tree_code code)
+{
+ return (enum gimple_rhs_class) gimple_rhs_class_table[(int) code];
+}
+
+/* Return the LHS of assignment statement GS. */
+
+static inline tree
+gimple_assign_lhs (const_gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_ASSIGN);
+ return gimple_op (gs, 0);
+}
+
+
+/* Return a pointer to the LHS of assignment statement GS. */
+
+static inline tree *
+gimple_assign_lhs_ptr (const_gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_ASSIGN);
+ return gimple_op_ptr (gs, 0);
+}
+
+
+/* Set LHS to be the LHS operand of assignment statement GS. */
+
+static inline void
+gimple_assign_set_lhs (gimple gs, tree lhs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_ASSIGN);
+ gcc_assert (is_gimple_operand (lhs));
+ gimple_set_op (gs, 0, lhs);
+
+ if (lhs && TREE_CODE (lhs) == SSA_NAME)
+ SSA_NAME_DEF_STMT (lhs) = gs;
+}
+
+
+/* Return the first operand on the RHS of assignment statement GS. */
+
+static inline tree
+gimple_assign_rhs1 (const_gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_ASSIGN);
+ return gimple_op (gs, 1);
+}
+
+
+/* Return a pointer to the first operand on the RHS of assignment
+ statement GS. */
+
+static inline tree *
+gimple_assign_rhs1_ptr (const_gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_ASSIGN);
+ return gimple_op_ptr (gs, 1);
+}
+
+/* Set RHS to be the first operand on the RHS of assignment statement GS. */
+
+static inline void
+gimple_assign_set_rhs1 (gimple gs, tree rhs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_ASSIGN);
+
+ /* If there are 3 or more operands, the 2 operands on the RHS must be
+ GIMPLE values. */
+ if (gimple_num_ops (gs) >= 3)
+ gcc_assert (is_gimple_val (rhs));
+ else
+ gcc_assert (is_gimple_operand (rhs));
+
+ gimple_set_op (gs, 1, rhs);
+}
+
+
+/* Return the second operand on the RHS of assignment statement GS.
+ If GS does not have two operands, NULL is returned instead. */
+
+static inline tree
+gimple_assign_rhs2 (const_gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_ASSIGN);
+
+ if (gimple_num_ops (gs) >= 3)
+ return gimple_op (gs, 2);
+ else
+ return NULL_TREE;
+}
+
+
+/* Return a pointer to the second operand on the RHS of assignment
+ statement GS. */
+
+static inline tree *
+gimple_assign_rhs2_ptr (const_gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_ASSIGN);
+ return gimple_op_ptr (gs, 2);
+}
+
+
+/* Set RHS to be the second operand on the RHS of assignment statement GS. */
+
+static inline void
+gimple_assign_set_rhs2 (gimple gs, tree rhs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_ASSIGN);
+
+ /* The 2 operands on the RHS must be GIMPLE values. */
+ gcc_assert (is_gimple_val (rhs));
+
+ gimple_set_op (gs, 2, rhs);
+}
+
+/* Returns true if GS is a nontemporal move. */
+
+static inline bool
+gimple_assign_nontemporal_move_p (const_gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_ASSIGN);
+ return gs->gsbase.nontemporal_move;
+}
+
+/* Sets nontemporal move flag of GS to NONTEMPORAL. */
+
+static inline void
+gimple_assign_set_nontemporal_move (gimple gs, bool nontemporal)
+{
+ GIMPLE_CHECK (gs, GIMPLE_ASSIGN);
+ gs->gsbase.nontemporal_move = nontemporal;
+}
+
+
+/* Return the code of the expression computed on the rhs of assignment
+ statement GS. In case that the RHS is a single object, returns the
+ tree code of the object. */
+
+static inline enum tree_code
+gimple_assign_rhs_code (const_gimple gs)
+{
+ enum tree_code code;
+ GIMPLE_CHECK (gs, GIMPLE_ASSIGN);
+
+ code = gimple_expr_code (gs);
+ if (get_gimple_rhs_class (code) == GIMPLE_SINGLE_RHS)
+ code = TREE_CODE (gimple_assign_rhs1 (gs));
+
+ return code;
+}
+
+
+/* Set CODE to be the code for the expression computed on the RHS of
+ assignment S. */
+
+static inline void
+gimple_assign_set_rhs_code (gimple s, enum tree_code code)
+{
+ GIMPLE_CHECK (s, GIMPLE_ASSIGN);
+ s->gsbase.subcode = code;
+}
+
+
+/* Return true if S is a type-cast assignment. */
+
+static inline bool
+gimple_assign_cast_p (gimple s)
+{
+ if (is_gimple_assign (s))
+ {
+ enum tree_code sc = gimple_assign_rhs_code (s);
+ return sc == NOP_EXPR
+ || sc == CONVERT_EXPR
+ || sc == VIEW_CONVERT_EXPR
+ || sc == FIX_TRUNC_EXPR;
+ }
+
+ return false;
+}
+
+
+/* Return true if GS is a GIMPLE_CALL. */
+
+static inline bool
+is_gimple_call (const_gimple gs)
+{
+ return gimple_code (gs) == GIMPLE_CALL;
+}
+
+/* Return the LHS of call statement GS. */
+
+static inline tree
+gimple_call_lhs (const_gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_CALL);
+ return gimple_op (gs, 0);
+}
+
+
+/* Return a pointer to the LHS of call statement GS. */
+
+static inline tree *
+gimple_call_lhs_ptr (const_gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_CALL);
+ return gimple_op_ptr (gs, 0);
+}
+
+
+/* Set LHS to be the LHS operand of call statement GS. */
+
+static inline void
+gimple_call_set_lhs (gimple gs, tree lhs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_CALL);
+ gcc_assert (!lhs || is_gimple_operand (lhs));
+ gimple_set_op (gs, 0, lhs);
+ if (lhs && TREE_CODE (lhs) == SSA_NAME)
+ SSA_NAME_DEF_STMT (lhs) = gs;
+}
+
+
+/* Return the tree node representing the function called by call
+ statement GS. This may or may not be a FUNCTION_DECL node. */
+
+static inline tree
+gimple_call_fn (const_gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_CALL);
+ return gimple_op (gs, 1);
+}
+
+
+/* Return a pointer to the tree node representing the function called by call
+ statement GS. */
+
+static inline tree *
+gimple_call_fn_ptr (const_gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_CALL);
+ return gimple_op_ptr (gs, 1);
+}
+
+
+/* Set FN to be the function called by call statement GS. */
+
+static inline void
+gimple_call_set_fn (gimple gs, tree fn)
+{
+ GIMPLE_CHECK (gs, GIMPLE_CALL);
+ gcc_assert (is_gimple_operand (fn));
+ gimple_set_op (gs, 1, fn);
+}
+
+
+/* If a given GIMPLE_CALL's callee is a FUNCTION_DECL, return it.
+ Otherwise return NULL. This function is analogous to
+ get_callee_fndecl in tree land. */
+
+static inline tree
+gimple_call_fndecl (const_gimple gs)
+{
+ tree decl = gimple_call_fn (gs);
+ return (TREE_CODE (decl) == FUNCTION_DECL) ? decl : NULL_TREE;
+}
+
+
+/* Return the type returned by call statement GS. */
+
+static inline tree
+gimple_call_return_type (const_gimple gs)
+{
+ tree fn = gimple_call_fn (gs);
+ tree type = TREE_TYPE (fn);
+
+ /* See through pointers. */
+ if (POINTER_TYPE_P (type))
+ type = TREE_TYPE (type);
+
+ gcc_assert (TREE_CODE (type) == FUNCTION_TYPE
+ || TREE_CODE (type) == METHOD_TYPE);
+
+ /* The type returned by a FUNCTION_DECL is the type of its
+ function type. */
+ return TREE_TYPE (type);
+}
+
+
+/* Return the static chain for call statement GS. */
+
+static inline tree
+gimple_call_chain (const_gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_CALL);
+ return gimple_op (gs, 2);
+}
+
+
+/* Return a pointer to the static chain for call statement GS. */
+
+static inline tree *
+gimple_call_chain_ptr (const_gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_CALL);
+ return gimple_op_ptr (gs, 2);
+}
+
+/* Set CHAIN to be the static chain for call statement GS. */
+
+static inline void
+gimple_call_set_chain (gimple gs, tree chain)
+{
+ GIMPLE_CHECK (gs, GIMPLE_CALL);
+ gcc_assert (chain == NULL
+ || TREE_CODE (chain) == ADDR_EXPR
+ || DECL_P (chain));
+ gimple_set_op (gs, 2, chain);
+}
+
+
+/* Return the number of arguments used by call statement GS. */
+
+static inline unsigned
+gimple_call_num_args (const_gimple gs)
+{
+ unsigned num_ops;
+ GIMPLE_CHECK (gs, GIMPLE_CALL);
+ num_ops = gimple_num_ops (gs);
+ gcc_assert (num_ops >= 3);
+ return num_ops - 3;
+}
+
+
+/* Return the argument at position INDEX for call statement GS. */
+
+static inline tree
+gimple_call_arg (const_gimple gs, unsigned index)
+{
+ GIMPLE_CHECK (gs, GIMPLE_CALL);
+ return gimple_op (gs, index + 3);
+}
+
+
+/* Return a pointer to the argument at position INDEX for call
+ statement GS. */
+
+static inline tree *
+gimple_call_arg_ptr (const_gimple gs, unsigned index)
+{
+ GIMPLE_CHECK (gs, GIMPLE_CALL);
+ return gimple_op_ptr (gs, index + 3);
+}
+
+
+/* Set ARG to be the argument at position INDEX for call statement GS. */
+
+static inline void
+gimple_call_set_arg (gimple gs, unsigned index, tree arg)
+{
+ GIMPLE_CHECK (gs, GIMPLE_CALL);
+ gcc_assert (is_gimple_operand (arg));
+ gimple_set_op (gs, index + 3, arg);
+}
+
+
+/* If TAIL_P is true, mark call statement S as being a tail call
+ (i.e., a call just before the exit of a function). These calls are
+ candidate for tail call optimization. */
+
+static inline void
+gimple_call_set_tail (gimple s, bool tail_p)
+{
+ GIMPLE_CHECK (s, GIMPLE_CALL);
+ if (tail_p)
+ s->gsbase.subcode |= GF_CALL_TAILCALL;
+ else
+ s->gsbase.subcode &= ~GF_CALL_TAILCALL;
+}
+
+
+/* Return true if GIMPLE_CALL S is marked as a tail call. */
+
+static inline bool
+gimple_call_tail_p (gimple s)
+{
+ GIMPLE_CHECK (s, GIMPLE_CALL);
+ return (s->gsbase.subcode & GF_CALL_TAILCALL) != 0;
+}
+
+
+/* Set the inlinable status of GIMPLE_CALL S to INLINABLE_P. */
+
+static inline void
+gimple_call_set_cannot_inline (gimple s, bool inlinable_p)
+{
+ GIMPLE_CHECK (s, GIMPLE_CALL);
+ if (inlinable_p)
+ s->gsbase.subcode |= GF_CALL_CANNOT_INLINE;
+ else
+ s->gsbase.subcode &= ~GF_CALL_CANNOT_INLINE;
+}
+
+
+/* Return true if GIMPLE_CALL S cannot be inlined. */
+
+static inline bool
+gimple_call_cannot_inline_p (gimple s)
+{
+ GIMPLE_CHECK (s, GIMPLE_CALL);
+ return (s->gsbase.subcode & GF_CALL_CANNOT_INLINE) != 0;
+}
+
+
+/* If RETURN_SLOT_OPT_P is true mark GIMPLE_CALL S as valid for return
+ slot optimization. This transformation uses the target of the call
+ expansion as the return slot for calls that return in memory. */
+
+static inline void
+gimple_call_set_return_slot_opt (gimple s, bool return_slot_opt_p)
+{
+ GIMPLE_CHECK (s, GIMPLE_CALL);
+ if (return_slot_opt_p)
+ s->gsbase.subcode |= GF_CALL_RETURN_SLOT_OPT;
+ else
+ s->gsbase.subcode &= ~GF_CALL_RETURN_SLOT_OPT;
+}
+
+
+/* Return true if S is marked for return slot optimization. */
+
+static inline bool
+gimple_call_return_slot_opt_p (gimple s)
+{
+ GIMPLE_CHECK (s, GIMPLE_CALL);
+ return (s->gsbase.subcode & GF_CALL_RETURN_SLOT_OPT) != 0;
+}
+
+
+/* If FROM_THUNK_P is true, mark GIMPLE_CALL S as being the jump from a
+ thunk to the thunked-to function. */
+
+static inline void
+gimple_call_set_from_thunk (gimple s, bool from_thunk_p)
+{
+ GIMPLE_CHECK (s, GIMPLE_CALL);
+ if (from_thunk_p)
+ s->gsbase.subcode |= GF_CALL_FROM_THUNK;
+ else
+ s->gsbase.subcode &= ~GF_CALL_FROM_THUNK;
+}
+
+
+/* Return true if GIMPLE_CALL S is a jump from a thunk. */
+
+static inline bool
+gimple_call_from_thunk_p (gimple s)
+{
+ GIMPLE_CHECK (s, GIMPLE_CALL);
+ return (s->gsbase.subcode & GF_CALL_FROM_THUNK) != 0;
+}
+
+
+/* If PASS_ARG_PACK_P is true, GIMPLE_CALL S is a stdarg call that needs the
+ argument pack in its argument list. */
+
+static inline void
+gimple_call_set_va_arg_pack (gimple s, bool pass_arg_pack_p)
+{
+ GIMPLE_CHECK (s, GIMPLE_CALL);
+ if (pass_arg_pack_p)
+ s->gsbase.subcode |= GF_CALL_VA_ARG_PACK;
+ else
+ s->gsbase.subcode &= ~GF_CALL_VA_ARG_PACK;
+}
+
+
+/* Return true if GIMPLE_CALL S is a stdarg call that needs the
+ argument pack in its argument list. */
+
+static inline bool
+gimple_call_va_arg_pack_p (gimple s)
+{
+ GIMPLE_CHECK (s, GIMPLE_CALL);
+ return (s->gsbase.subcode & GF_CALL_VA_ARG_PACK) != 0;
+}
+
+
+/* Return true if S is a noreturn call. */
+
+static inline bool
+gimple_call_noreturn_p (gimple s)
+{
+ GIMPLE_CHECK (s, GIMPLE_CALL);
+ return (gimple_call_flags (s) & ECF_NORETURN) != 0;
+}
+
+
+/* Return true if S is a nothrow call. */
+
+static inline bool
+gimple_call_nothrow_p (gimple s)
+{
+ GIMPLE_CHECK (s, GIMPLE_CALL);
+ return (gimple_call_flags (s) & ECF_NOTHROW) != 0;
+}
+
+
+/* Copy all the GF_CALL_* flags from ORIG_CALL to DEST_CALL. */
+
+static inline void
+gimple_call_copy_flags (gimple dest_call, gimple orig_call)
+{
+ GIMPLE_CHECK (dest_call, GIMPLE_CALL);
+ GIMPLE_CHECK (orig_call, GIMPLE_CALL);
+ dest_call->gsbase.subcode = orig_call->gsbase.subcode;
+}
+
+
+/* Returns true if this is a GIMPLE_ASSIGN or a GIMPLE_CALL with a
+ non-NULL lhs. */
+
+static inline bool
+gimple_has_lhs (gimple stmt)
+{
+ return (is_gimple_assign (stmt)
+ || (is_gimple_call (stmt)
+ && gimple_call_lhs (stmt) != NULL_TREE));
+}
+
+
+/* Return the code of the predicate computed by conditional statement GS. */
+
+static inline enum tree_code
+gimple_cond_code (const_gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_COND);
+ return gs->gsbase.subcode;
+}
+
+
+/* Set CODE to be the predicate code for the conditional statement GS. */
+
+static inline void
+gimple_cond_set_code (gimple gs, enum tree_code code)
+{
+ GIMPLE_CHECK (gs, GIMPLE_COND);
+ gcc_assert (TREE_CODE_CLASS (code) == tcc_comparison);
+ gs->gsbase.subcode = code;
+}
+
+
+/* Return the LHS of the predicate computed by conditional statement GS. */
+
+static inline tree
+gimple_cond_lhs (const_gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_COND);
+ return gimple_op (gs, 0);
+}
+
+/* Return the pointer to the LHS of the predicate computed by conditional
+ statement GS. */
+
+static inline tree *
+gimple_cond_lhs_ptr (const_gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_COND);
+ return gimple_op_ptr (gs, 0);
+}
+
+/* Set LHS to be the LHS operand of the predicate computed by
+ conditional statement GS. */
+
+static inline void
+gimple_cond_set_lhs (gimple gs, tree lhs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_COND);
+ gcc_assert (is_gimple_operand (lhs));
+ gimple_set_op (gs, 0, lhs);
+}
+
+
+/* Return the RHS operand of the predicate computed by conditional GS. */
+
+static inline tree
+gimple_cond_rhs (const_gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_COND);
+ return gimple_op (gs, 1);
+}
+
+/* Return the pointer to the RHS operand of the predicate computed by
+ conditional GS. */
+
+static inline tree *
+gimple_cond_rhs_ptr (const_gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_COND);
+ return gimple_op_ptr (gs, 1);
+}
+
+
+/* Set RHS to be the RHS operand of the predicate computed by
+ conditional statement GS. */
+
+static inline void
+gimple_cond_set_rhs (gimple gs, tree rhs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_COND);
+ gcc_assert (is_gimple_operand (rhs));
+ gimple_set_op (gs, 1, rhs);
+}
+
+
+/* Return the label used by conditional statement GS when its
+ predicate evaluates to true. */
+
+static inline tree
+gimple_cond_true_label (const_gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_COND);
+ return gimple_op (gs, 2);
+}
+
+
+/* Set LABEL to be the label used by conditional statement GS when its
+ predicate evaluates to true. */
+
+static inline void
+gimple_cond_set_true_label (gimple gs, tree label)
+{
+ GIMPLE_CHECK (gs, GIMPLE_COND);
+ gcc_assert (!label || TREE_CODE (label) == LABEL_DECL);
+ gimple_set_op (gs, 2, label);
+}
+
+
+/* Set LABEL to be the label used by conditional statement GS when its
+ predicate evaluates to false. */
+
+static inline void
+gimple_cond_set_false_label (gimple gs, tree label)
+{
+ GIMPLE_CHECK (gs, GIMPLE_COND);
+ gcc_assert (!label || TREE_CODE (label) == LABEL_DECL);
+ gimple_set_op (gs, 3, label);
+}
+
+
+/* Return the label used by conditional statement GS when its
+ predicate evaluates to false. */
+
+static inline tree
+gimple_cond_false_label (const_gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_COND);
+ return gimple_op (gs, 3);
+}
+
+
+/* Set the conditional COND_STMT to be of the form 'if (1 == 0)'. */
+
+static inline void
+gimple_cond_make_false (gimple gs)
+{
+ gimple_cond_set_lhs (gs, boolean_true_node);
+ gimple_cond_set_rhs (gs, boolean_false_node);
+ gs->gsbase.subcode = EQ_EXPR;
+}
+
+
+/* Set the conditional COND_STMT to be of the form 'if (1 == 1)'. */
+
+static inline void
+gimple_cond_make_true (gimple gs)
+{
+ gimple_cond_set_lhs (gs, boolean_true_node);
+ gimple_cond_set_rhs (gs, boolean_true_node);
+ gs->gsbase.subcode = EQ_EXPR;
+}
+
+/* Check if conditional statemente GS is of the form 'if (1 == 1)',
+ 'if (0 == 0)', 'if (1 != 0)' or 'if (0 != 1)' */
+
+static inline bool
+gimple_cond_true_p (const_gimple gs)
+{
+ tree lhs = gimple_cond_lhs (gs);
+ tree rhs = gimple_cond_rhs (gs);
+ enum tree_code code = gimple_cond_code (gs);
+
+ if (lhs != boolean_true_node && lhs != boolean_false_node)
+ return false;
+
+ if (rhs != boolean_true_node && rhs != boolean_false_node)
+ return false;
+
+ if (code == NE_EXPR && lhs != rhs)
+ return true;
+
+ if (code == EQ_EXPR && lhs == rhs)
+ return true;
+
+ return false;
+}
+
+/* Check if conditional statement GS is of the form 'if (1 != 1)',
+ 'if (0 != 0)', 'if (1 == 0)' or 'if (0 == 1)' */
+
+static inline bool
+gimple_cond_false_p (const_gimple gs)
+{
+ tree lhs = gimple_cond_lhs (gs);
+ tree rhs = gimple_cond_rhs (gs);
+ enum tree_code code = gimple_cond_code (gs);
+
+ if (lhs != boolean_true_node && lhs != boolean_false_node)
+ return false;
+
+ if (rhs != boolean_true_node && rhs != boolean_false_node)
+ return false;
+
+ if (code == NE_EXPR && lhs == rhs)
+ return true;
+
+ if (code == EQ_EXPR && lhs != rhs)
+ return true;
+
+ return false;
+}
+
+/* Check if conditional statement GS is of the form 'if (var != 0)' or
+ 'if (var == 1)' */
+
+static inline bool
+gimple_cond_single_var_p (gimple gs)
+{
+ if (gimple_cond_code (gs) == NE_EXPR
+ && gimple_cond_rhs (gs) == boolean_false_node)
+ return true;
+
+ if (gimple_cond_code (gs) == EQ_EXPR
+ && gimple_cond_rhs (gs) == boolean_true_node)
+ return true;
+
+ return false;
+}
+
+/* Set the code, LHS and RHS of GIMPLE_COND STMT from CODE, LHS and RHS. */
+
+static inline void
+gimple_cond_set_condition (gimple stmt, enum tree_code code, tree lhs, tree rhs)
+{
+ gimple_cond_set_code (stmt, code);
+ gimple_cond_set_lhs (stmt, lhs);
+ gimple_cond_set_rhs (stmt, rhs);
+}
+
+/* Return the LABEL_DECL node used by GIMPLE_LABEL statement GS. */
+
+static inline tree
+gimple_label_label (const_gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_LABEL);
+ return gimple_op (gs, 0);
+}
+
+
+/* Set LABEL to be the LABEL_DECL node used by GIMPLE_LABEL statement
+ GS. */
+
+static inline void
+gimple_label_set_label (gimple gs, tree label)
+{
+ GIMPLE_CHECK (gs, GIMPLE_LABEL);
+ gcc_assert (TREE_CODE (label) == LABEL_DECL);
+ gimple_set_op (gs, 0, label);
+}
+
+
+/* Return the destination of the unconditional jump GS. */
+
+static inline tree
+gimple_goto_dest (const_gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_GOTO);
+ return gimple_op (gs, 0);
+}
+
+
+/* Set DEST to be the destination of the unconditonal jump GS. */
+
+static inline void
+gimple_goto_set_dest (gimple gs, tree dest)
+{
+ GIMPLE_CHECK (gs, GIMPLE_GOTO);
+ gcc_assert (is_gimple_operand (dest));
+ gimple_set_op (gs, 0, dest);
+}
+
+
+/* Return the variables declared in the GIMPLE_BIND statement GS. */
+
+static inline tree
+gimple_bind_vars (const_gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_BIND);
+ return gs->gimple_bind.vars;
+}
+
+
+/* Set VARS to be the set of variables declared in the GIMPLE_BIND
+ statement GS. */
+
+static inline void
+gimple_bind_set_vars (gimple gs, tree vars)
+{
+ GIMPLE_CHECK (gs, GIMPLE_BIND);
+ gs->gimple_bind.vars = vars;
+}
+
+
+/* Append VARS to the set of variables declared in the GIMPLE_BIND
+ statement GS. */
+
+static inline void
+gimple_bind_append_vars (gimple gs, tree vars)
+{
+ GIMPLE_CHECK (gs, GIMPLE_BIND);
+ gs->gimple_bind.vars = chainon (gs->gimple_bind.vars, vars);
+}
+
+
+/* Return the GIMPLE sequence contained in the GIMPLE_BIND statement GS. */
+
+static inline gimple_seq
+gimple_bind_body (gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_BIND);
+ return gs->gimple_bind.body;
+}
+
+
+/* Set SEQ to be the GIMPLE sequence contained in the GIMPLE_BIND
+ statement GS. */
+
+static inline void
+gimple_bind_set_body (gimple gs, gimple_seq seq)
+{
+ GIMPLE_CHECK (gs, GIMPLE_BIND);
+ gs->gimple_bind.body = seq;
+}
+
+
+/* Append a statement to the end of a GIMPLE_BIND's body. */
+
+static inline void
+gimple_bind_add_stmt (gimple gs, gimple stmt)
+{
+ GIMPLE_CHECK (gs, GIMPLE_BIND);
+ gimple_seq_add_stmt (&gs->gimple_bind.body, stmt);
+}
+
+
+/* Append a sequence of statements to the end of a GIMPLE_BIND's body. */
+
+static inline void
+gimple_bind_add_seq (gimple gs, gimple_seq seq)
+{
+ GIMPLE_CHECK (gs, GIMPLE_BIND);
+ gimple_seq_add_seq (&gs->gimple_bind.body, seq);
+}
+
+
+/* Return the TREE_BLOCK node associated with GIMPLE_BIND statement
+ GS. This is analogous to the BIND_EXPR_BLOCK field in trees. */
+
+static inline tree
+gimple_bind_block (const_gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_BIND);
+ return gs->gimple_bind.block;
+}
+
+
+/* Set BLOCK to be the TREE_BLOCK node associated with GIMPLE_BIND
+ statement GS. */
+
+static inline void
+gimple_bind_set_block (gimple gs, tree block)
+{
+ GIMPLE_CHECK (gs, GIMPLE_BIND);
+ gcc_assert (TREE_CODE (block) == BLOCK);
+ gs->gimple_bind.block = block;
+}
+
+
+/* Return the number of input operands for GIMPLE_ASM GS. */
+
+static inline unsigned
+gimple_asm_ninputs (const_gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_ASM);
+ return gs->gimple_asm.ni;
+}
+
+
+/* Return the number of output operands for GIMPLE_ASM GS. */
+
+static inline unsigned
+gimple_asm_noutputs (const_gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_ASM);
+ return gs->gimple_asm.no;
+}
+
+
+/* Return the number of clobber operands for GIMPLE_ASM GS. */
+
+static inline unsigned
+gimple_asm_nclobbers (const_gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_ASM);
+ return gs->gimple_asm.nc;
+}
+
+
+/* Return input operand INDEX of GIMPLE_ASM GS. */
+
+static inline tree
+gimple_asm_input_op (const_gimple gs, unsigned index)
+{
+ GIMPLE_CHECK (gs, GIMPLE_ASM);
+ gcc_assert (index <= gs->gimple_asm.ni);
+ return gimple_op (gs, index);
+}
+
+/* Return a pointer to input operand INDEX of GIMPLE_ASM GS. */
+
+static inline tree *
+gimple_asm_input_op_ptr (const_gimple gs, unsigned index)
+{
+ GIMPLE_CHECK (gs, GIMPLE_ASM);
+ gcc_assert (index <= gs->gimple_asm.ni);
+ return gimple_op_ptr (gs, index);
+}
+
+
+/* Set IN_OP to be input operand INDEX in GIMPLE_ASM GS. */
+
+static inline void
+gimple_asm_set_input_op (gimple gs, unsigned index, tree in_op)
+{
+ GIMPLE_CHECK (gs, GIMPLE_ASM);
+ gcc_assert (index <= gs->gimple_asm.ni);
+ gcc_assert (TREE_CODE (in_op) == TREE_LIST);
+ gimple_set_op (gs, index, in_op);
+}
+
+
+/* Return output operand INDEX of GIMPLE_ASM GS. */
+
+static inline tree
+gimple_asm_output_op (const_gimple gs, unsigned index)
+{
+ GIMPLE_CHECK (gs, GIMPLE_ASM);
+ gcc_assert (index <= gs->gimple_asm.no);
+ return gimple_op (gs, index + gs->gimple_asm.ni);
+}
+
+/* Return a pointer to output operand INDEX of GIMPLE_ASM GS. */
+
+static inline tree *
+gimple_asm_output_op_ptr (const_gimple gs, unsigned index)
+{
+ GIMPLE_CHECK (gs, GIMPLE_ASM);
+ gcc_assert (index <= gs->gimple_asm.no);
+ return gimple_op_ptr (gs, index + gs->gimple_asm.ni);
+}
+
+
+/* Set OUT_OP to be output operand INDEX in GIMPLE_ASM GS. */
+
+static inline void
+gimple_asm_set_output_op (gimple gs, unsigned index, tree out_op)
+{
+ GIMPLE_CHECK (gs, GIMPLE_ASM);
+ gcc_assert (index <= gs->gimple_asm.no);
+ gcc_assert (TREE_CODE (out_op) == TREE_LIST);
+ gimple_set_op (gs, index + gs->gimple_asm.ni, out_op);
+}
+
+
+/* Return clobber operand INDEX of GIMPLE_ASM GS. */
+
+static inline tree
+gimple_asm_clobber_op (const_gimple gs, unsigned index)
+{
+ GIMPLE_CHECK (gs, GIMPLE_ASM);
+ gcc_assert (index <= gs->gimple_asm.nc);
+ return gimple_op (gs, index + gs->gimple_asm.ni + gs->gimple_asm.no);
+}
+
+
+/* Set CLOBBER_OP to be clobber operand INDEX in GIMPLE_ASM GS. */
+
+static inline void
+gimple_asm_set_clobber_op (gimple gs, unsigned index, tree clobber_op)
+{
+ GIMPLE_CHECK (gs, GIMPLE_ASM);
+ gcc_assert (index <= gs->gimple_asm.nc);
+ gcc_assert (TREE_CODE (clobber_op) == TREE_LIST);
+ gimple_set_op (gs, index + gs->gimple_asm.ni + gs->gimple_asm.no, clobber_op);
+}
+
+
+/* Return the string representing the assembly instruction in
+ GIMPLE_ASM GS. */
+
+static inline const char *
+gimple_asm_string (const_gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_ASM);
+ return gs->gimple_asm.string;
+}
+
+
+/* Return true if GS is an asm statement marked volatile. */
+
+static inline bool
+gimple_asm_volatile_p (const_gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_ASM);
+ return (gs->gsbase.subcode & GF_ASM_VOLATILE) != 0;
+}
+
+
+/* If VOLATLE_P is true, mark asm statement GS as volatile. */
+
+static inline void
+gimple_asm_set_volatile (gimple gs, bool volatile_p)
+{
+ GIMPLE_CHECK (gs, GIMPLE_ASM);
+ if (volatile_p)
+ gs->gsbase.subcode |= GF_ASM_VOLATILE;
+ else
+ gs->gsbase.subcode &= ~GF_ASM_VOLATILE;
+}
+
+
+/* If INPUT_P is true, mark asm GS as an ASM_INPUT. */
+
+static inline void
+gimple_asm_set_input (gimple gs, bool input_p)
+{
+ GIMPLE_CHECK (gs, GIMPLE_ASM);
+ if (input_p)
+ gs->gsbase.subcode |= GF_ASM_INPUT;
+ else
+ gs->gsbase.subcode &= ~GF_ASM_INPUT;
+}
+
+
+/* Return true if asm GS is an ASM_INPUT. */
+
+static inline bool
+gimple_asm_input_p (const_gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_ASM);
+ return (gs->gsbase.subcode & GF_ASM_INPUT) != 0;
+}
+
+
+/* Return the types handled by GIMPLE_CATCH statement GS. */
+
+static inline tree
+gimple_catch_types (const_gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_CATCH);
+ return gs->gimple_catch.types;
+}
+
+
+/* Return a pointer to the types handled by GIMPLE_CATCH statement GS. */
+
+static inline tree *
+gimple_catch_types_ptr (gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_CATCH);
+ return &gs->gimple_catch.types;
+}
+
+
+/* Return the GIMPLE sequence representing the body of the handler of
+ GIMPLE_CATCH statement GS. */
+
+static inline gimple_seq
+gimple_catch_handler (gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_CATCH);
+ return gs->gimple_catch.handler;
+}
+
+
+/* Return a pointer to the GIMPLE sequence representing the body of
+ the handler of GIMPLE_CATCH statement GS. */
+
+static inline gimple_seq *
+gimple_catch_handler_ptr (gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_CATCH);
+ return &gs->gimple_catch.handler;
+}
+
+
+/* Set T to be the set of types handled by GIMPLE_CATCH GS. */
+
+static inline void
+gimple_catch_set_types (gimple gs, tree t)
+{
+ GIMPLE_CHECK (gs, GIMPLE_CATCH);
+ gs->gimple_catch.types = t;
+}
+
+
+/* Set HANDLER to be the body of GIMPLE_CATCH GS. */
+
+static inline void
+gimple_catch_set_handler (gimple gs, gimple_seq handler)
+{
+ GIMPLE_CHECK (gs, GIMPLE_CATCH);
+ gs->gimple_catch.handler = handler;
+}
+
+
+/* Return the types handled by GIMPLE_EH_FILTER statement GS. */
+
+static inline tree
+gimple_eh_filter_types (const_gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_EH_FILTER);
+ return gs->gimple_eh_filter.types;
+}
+
+
+/* Return a pointer to the types handled by GIMPLE_EH_FILTER statement
+ GS. */
+
+static inline tree *
+gimple_eh_filter_types_ptr (gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_EH_FILTER);
+ return &gs->gimple_eh_filter.types;
+}
+
+
+/* Return the sequence of statement to execute when GIMPLE_EH_FILTER
+ statement fails. */
+
+static inline gimple_seq
+gimple_eh_filter_failure (gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_EH_FILTER);
+ return gs->gimple_eh_filter.failure;
+}
+
+
+/* Set TYPES to be the set of types handled by GIMPLE_EH_FILTER GS. */
+
+static inline void
+gimple_eh_filter_set_types (gimple gs, tree types)
+{
+ GIMPLE_CHECK (gs, GIMPLE_EH_FILTER);
+ gs->gimple_eh_filter.types = types;
+}
+
+
+/* Set FAILURE to be the sequence of statements to execute on failure
+ for GIMPLE_EH_FILTER GS. */
+
+static inline void
+gimple_eh_filter_set_failure (gimple gs, gimple_seq failure)
+{
+ GIMPLE_CHECK (gs, GIMPLE_EH_FILTER);
+ gs->gimple_eh_filter.failure = failure;
+}
+
+/* Return the EH_FILTER_MUST_NOT_THROW flag. */
+
+static inline bool
+
+gimple_eh_filter_must_not_throw (gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_EH_FILTER);
+ return gs->gsbase.subcode != 0;
+}
+
+/* Set the EH_FILTER_MUST_NOT_THROW flag to the value MNTP. */
+
+static inline void
+gimple_eh_filter_set_must_not_throw (gimple gs, bool mntp)
+{
+ GIMPLE_CHECK (gs, GIMPLE_EH_FILTER);
+ gs->gsbase.subcode = (unsigned int) mntp;
+}
+
+
+/* GIMPLE_TRY accessors. */
+
+/* Return the kind of try block represented by GIMPLE_TRY GS. This is
+ either GIMPLE_TRY_CATCH or GIMPLE_TRY_FINALLY. */
+
+static inline enum gimple_try_flags
+gimple_try_kind (const_gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_TRY);
+ return (enum gimple_try_flags) (gs->gsbase.subcode & GIMPLE_TRY_KIND);
+}
+
+
+/* Set the kind of try block represented by GIMPLE_TRY GS. */
+
+static inline void
+gimple_try_set_kind (gimple gs, enum gimple_try_flags kind)
+{
+ GIMPLE_CHECK (gs, GIMPLE_TRY);
+ gcc_assert (kind == GIMPLE_TRY_CATCH || kind == GIMPLE_TRY_FINALLY);
+ if (gimple_try_kind (gs) != kind)
+ gs->gsbase.subcode = (unsigned int) kind;
+}
+
+
+/* Return the GIMPLE_TRY_CATCH_IS_CLEANUP flag. */
+
+static inline bool
+gimple_try_catch_is_cleanup (const_gimple gs)
+{
+ gcc_assert (gimple_try_kind (gs) == GIMPLE_TRY_CATCH);
+ return (gs->gsbase.subcode & GIMPLE_TRY_CATCH_IS_CLEANUP) != 0;
+}
+
+
+/* Return the sequence of statements used as the body for GIMPLE_TRY GS. */
+
+static inline gimple_seq
+gimple_try_eval (gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_TRY);
+ return gs->gimple_try.eval;
+}
+
+
+/* Return the sequence of statements used as the cleanup body for
+ GIMPLE_TRY GS. */
+
+static inline gimple_seq
+gimple_try_cleanup (gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_TRY);
+ return gs->gimple_try.cleanup;
+}
+
+
+/* Set the GIMPLE_TRY_CATCH_IS_CLEANUP flag. */
+
+static inline void
+gimple_try_set_catch_is_cleanup (gimple g, bool catch_is_cleanup)
+{
+ gcc_assert (gimple_try_kind (g) == GIMPLE_TRY_CATCH);
+ if (catch_is_cleanup)
+ g->gsbase.subcode |= GIMPLE_TRY_CATCH_IS_CLEANUP;
+ else
+ g->gsbase.subcode &= ~GIMPLE_TRY_CATCH_IS_CLEANUP;
+}
+
+
+/* Set EVAL to be the sequence of statements to use as the body for
+ GIMPLE_TRY GS. */
+
+static inline void
+gimple_try_set_eval (gimple gs, gimple_seq eval)
+{
+ GIMPLE_CHECK (gs, GIMPLE_TRY);
+ gs->gimple_try.eval = eval;
+}
+
+
+/* Set CLEANUP to be the sequence of statements to use as the cleanup
+ body for GIMPLE_TRY GS. */
+
+static inline void
+gimple_try_set_cleanup (gimple gs, gimple_seq cleanup)
+{
+ GIMPLE_CHECK (gs, GIMPLE_TRY);
+ gs->gimple_try.cleanup = cleanup;
+}
+
+
+/* Return the cleanup sequence for cleanup statement GS. */
+
+static inline gimple_seq
+gimple_wce_cleanup (gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_WITH_CLEANUP_EXPR);
+ return gs->gimple_wce.cleanup;
+}
+
+
+/* Set CLEANUP to be the cleanup sequence for GS. */
+
+static inline void
+gimple_wce_set_cleanup (gimple gs, gimple_seq cleanup)
+{
+ GIMPLE_CHECK (gs, GIMPLE_WITH_CLEANUP_EXPR);
+ gs->gimple_wce.cleanup = cleanup;
+}
+
+
+/* Return the CLEANUP_EH_ONLY flag for a WCE tuple. */
+
+static inline bool
+gimple_wce_cleanup_eh_only (const_gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_WITH_CLEANUP_EXPR);
+ return gs->gsbase.subcode != 0;
+}
+
+
+/* Set the CLEANUP_EH_ONLY flag for a WCE tuple. */
+
+static inline void
+gimple_wce_set_cleanup_eh_only (gimple gs, bool eh_only_p)
+{
+ GIMPLE_CHECK (gs, GIMPLE_WITH_CLEANUP_EXPR);
+ gs->gsbase.subcode = (unsigned int) eh_only_p;
+}
+
+
+/* Return the maximum number of arguments supported by GIMPLE_PHI GS. */
+
+static inline unsigned
+gimple_phi_capacity (const_gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_PHI);
+ return gs->gimple_phi.capacity;
+}
+
+
+/* Return the number of arguments in GIMPLE_PHI GS. This must always
+ be exactly the number of incoming edges for the basic block holding
+ GS. */
+
+static inline unsigned
+gimple_phi_num_args (const_gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_PHI);
+ return gs->gimple_phi.nargs;
+}
+
+
+/* Return the SSA name created by GIMPLE_PHI GS. */
+
+static inline tree
+gimple_phi_result (const_gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_PHI);
+ return gs->gimple_phi.result;
+}
+
+/* Return a pointer to the SSA name created by GIMPLE_PHI GS. */
+
+static inline tree *
+gimple_phi_result_ptr (gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_PHI);
+ return &gs->gimple_phi.result;
+}
+
+/* Set RESULT to be the SSA name created by GIMPLE_PHI GS. */
+
+static inline void
+gimple_phi_set_result (gimple gs, tree result)
+{
+ GIMPLE_CHECK (gs, GIMPLE_PHI);
+ gs->gimple_phi.result = result;
+}
+
+
+/* Return the PHI argument corresponding to incoming edge INDEX for
+ GIMPLE_PHI GS. */
+
+static inline struct phi_arg_d *
+gimple_phi_arg (gimple gs, unsigned index)
+{
+ GIMPLE_CHECK (gs, GIMPLE_PHI);
+ gcc_assert (index <= gs->gimple_phi.capacity);
+ return &(gs->gimple_phi.args[index]);
+}
+
+/* Set PHIARG to be the argument corresponding to incoming edge INDEX
+ for GIMPLE_PHI GS. */
+
+static inline void
+gimple_phi_set_arg (gimple gs, unsigned index, struct phi_arg_d * phiarg)
+{
+ GIMPLE_CHECK (gs, GIMPLE_PHI);
+ gcc_assert (index <= gs->gimple_phi.nargs);
+ memcpy (gs->gimple_phi.args + index, phiarg, sizeof (struct phi_arg_d));
+}
+
+/* Return the region number for GIMPLE_RESX GS. */
+
+static inline int
+gimple_resx_region (const_gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_RESX);
+ return gs->gimple_resx.region;
+}
+
+/* Set REGION to be the region number for GIMPLE_RESX GS. */
+
+static inline void
+gimple_resx_set_region (gimple gs, int region)
+{
+ GIMPLE_CHECK (gs, GIMPLE_RESX);
+ gs->gimple_resx.region = region;
+}
+
+
+/* Return the number of labels associated with the switch statement GS. */
+
+static inline unsigned
+gimple_switch_num_labels (const_gimple gs)
+{
+ unsigned num_ops;
+ GIMPLE_CHECK (gs, GIMPLE_SWITCH);
+ num_ops = gimple_num_ops (gs);
+ gcc_assert (num_ops > 1);
+ return num_ops - 1;
+}
+
+
+/* Set NLABELS to be the number of labels for the switch statement GS. */
+
+static inline void
+gimple_switch_set_num_labels (gimple g, unsigned nlabels)
+{
+ GIMPLE_CHECK (g, GIMPLE_SWITCH);
+ gimple_set_num_ops (g, nlabels + 1);
+}
+
+
+/* Return the index variable used by the switch statement GS. */
+
+static inline tree
+gimple_switch_index (const_gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_SWITCH);
+ return gimple_op (gs, 0);
+}
+
+
+/* Return a pointer to the index variable for the switch statement GS. */
+
+static inline tree *
+gimple_switch_index_ptr (const_gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_SWITCH);
+ return gimple_op_ptr (gs, 0);
+}
+
+
+/* Set INDEX to be the index variable for switch statement GS. */
+
+static inline void
+gimple_switch_set_index (gimple gs, tree index)
+{
+ GIMPLE_CHECK (gs, GIMPLE_SWITCH);
+ gcc_assert (SSA_VAR_P (index) || CONSTANT_CLASS_P (index));
+ gimple_set_op (gs, 0, index);
+}
+
+
+/* Return the label numbered INDEX. The default label is 0, followed by any
+ labels in a switch statement. */
+
+static inline tree
+gimple_switch_label (const_gimple gs, unsigned index)
+{
+ GIMPLE_CHECK (gs, GIMPLE_SWITCH);
+ gcc_assert (gimple_num_ops (gs) > index + 1);
+ return gimple_op (gs, index + 1);
+}
+
+/* Set the label number INDEX to LABEL. 0 is always the default label. */
+
+static inline void
+gimple_switch_set_label (gimple gs, unsigned index, tree label)
+{
+ GIMPLE_CHECK (gs, GIMPLE_SWITCH);
+ gcc_assert (gimple_num_ops (gs) > index + 1);
+ gcc_assert (label == NULL_TREE || TREE_CODE (label) == CASE_LABEL_EXPR);
+ gimple_set_op (gs, index + 1, label);
+}
+
+/* Return the default label for a switch statement. */
+
+static inline tree
+gimple_switch_default_label (const_gimple gs)
+{
+ return gimple_switch_label (gs, 0);
+}
+
+/* Set the default label for a switch statement. */
+
+static inline void
+gimple_switch_set_default_label (gimple gs, tree label)
+{
+ gimple_switch_set_label (gs, 0, label);
+}
+
+
+/* Return the body for the OMP statement GS. */
+
+static inline gimple_seq
+gimple_omp_body (gimple gs)
+{
+ return gs->omp.body;
+}
+
+/* Set BODY to be the body for the OMP statement GS. */
+
+static inline void
+gimple_omp_set_body (gimple gs, gimple_seq body)
+{
+ gs->omp.body = body;
+}
+
+
+/* Return the name associated with OMP_CRITICAL statement GS. */
+
+static inline tree
+gimple_omp_critical_name (const_gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_OMP_CRITICAL);
+ return gs->gimple_omp_critical.name;
+}
+
+
+/* Return a pointer to the name associated with OMP critical statement GS. */
+
+static inline tree *
+gimple_omp_critical_name_ptr (gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_OMP_CRITICAL);
+ return &gs->gimple_omp_critical.name;
+}
+
+
+/* Set NAME to be the name associated with OMP critical statement GS. */
+
+static inline void
+gimple_omp_critical_set_name (gimple gs, tree name)
+{
+ GIMPLE_CHECK (gs, GIMPLE_OMP_CRITICAL);
+ gs->gimple_omp_critical.name = name;
+}
+
+
+/* Return the clauses associated with OMP_FOR GS. */
+
+static inline tree
+gimple_omp_for_clauses (const_gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_OMP_FOR);
+ return gs->gimple_omp_for.clauses;
+}
+
+
+/* Return a pointer to the OMP_FOR GS. */
+
+static inline tree *
+gimple_omp_for_clauses_ptr (gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_OMP_FOR);
+ return &gs->gimple_omp_for.clauses;
+}
+
+
+/* Set CLAUSES to be the list of clauses associated with OMP_FOR GS. */
+
+static inline void
+gimple_omp_for_set_clauses (gimple gs, tree clauses)
+{
+ GIMPLE_CHECK (gs, GIMPLE_OMP_FOR);
+ gs->gimple_omp_for.clauses = clauses;
+}
+
+
+/* Get the collapse count of OMP_FOR GS. */
+
+static inline size_t
+gimple_omp_for_collapse (gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_OMP_FOR);
+ return gs->gimple_omp_for.collapse;
+}
+
+
+/* Return the index variable for OMP_FOR GS. */
+
+static inline tree
+gimple_omp_for_index (const_gimple gs, size_t i)
+{
+ GIMPLE_CHECK (gs, GIMPLE_OMP_FOR);
+ gcc_assert (i < gs->gimple_omp_for.collapse);
+ return gs->gimple_omp_for.iter[i].index;
+}
+
+
+/* Return a pointer to the index variable for OMP_FOR GS. */
+
+static inline tree *
+gimple_omp_for_index_ptr (gimple gs, size_t i)
+{
+ GIMPLE_CHECK (gs, GIMPLE_OMP_FOR);
+ gcc_assert (i < gs->gimple_omp_for.collapse);
+ return &gs->gimple_omp_for.iter[i].index;
+}
+
+
+/* Set INDEX to be the index variable for OMP_FOR GS. */
+
+static inline void
+gimple_omp_for_set_index (gimple gs, size_t i, tree index)
+{
+ GIMPLE_CHECK (gs, GIMPLE_OMP_FOR);
+ gcc_assert (i < gs->gimple_omp_for.collapse);
+ gs->gimple_omp_for.iter[i].index = index;
+}
+
+
+/* Return the initial value for OMP_FOR GS. */
+
+static inline tree
+gimple_omp_for_initial (const_gimple gs, size_t i)
+{
+ GIMPLE_CHECK (gs, GIMPLE_OMP_FOR);
+ gcc_assert (i < gs->gimple_omp_for.collapse);
+ return gs->gimple_omp_for.iter[i].initial;
+}
+
+
+/* Return a pointer to the initial value for OMP_FOR GS. */
+
+static inline tree *
+gimple_omp_for_initial_ptr (gimple gs, size_t i)
+{
+ GIMPLE_CHECK (gs, GIMPLE_OMP_FOR);
+ gcc_assert (i < gs->gimple_omp_for.collapse);
+ return &gs->gimple_omp_for.iter[i].initial;
+}
+
+
+/* Set INITIAL to be the initial value for OMP_FOR GS. */
+
+static inline void
+gimple_omp_for_set_initial (gimple gs, size_t i, tree initial)
+{
+ GIMPLE_CHECK (gs, GIMPLE_OMP_FOR);
+ gcc_assert (i < gs->gimple_omp_for.collapse);
+ gs->gimple_omp_for.iter[i].initial = initial;
+}
+
+
+/* Return the final value for OMP_FOR GS. */
+
+static inline tree
+gimple_omp_for_final (const_gimple gs, size_t i)
+{
+ GIMPLE_CHECK (gs, GIMPLE_OMP_FOR);
+ gcc_assert (i < gs->gimple_omp_for.collapse);
+ return gs->gimple_omp_for.iter[i].final;
+}
+
+
+/* Return a pointer to the final value for OMP_FOR GS. */
+
+static inline tree *
+gimple_omp_for_final_ptr (gimple gs, size_t i)
+{
+ GIMPLE_CHECK (gs, GIMPLE_OMP_FOR);
+ gcc_assert (i < gs->gimple_omp_for.collapse);
+ return &gs->gimple_omp_for.iter[i].final;
+}
+
+
+/* Set FINAL to be the final value for OMP_FOR GS. */
+
+static inline void
+gimple_omp_for_set_final (gimple gs, size_t i, tree final)
+{
+ GIMPLE_CHECK (gs, GIMPLE_OMP_FOR);
+ gcc_assert (i < gs->gimple_omp_for.collapse);
+ gs->gimple_omp_for.iter[i].final = final;
+}
+
+
+/* Return the increment value for OMP_FOR GS. */
+
+static inline tree
+gimple_omp_for_incr (const_gimple gs, size_t i)
+{
+ GIMPLE_CHECK (gs, GIMPLE_OMP_FOR);
+ gcc_assert (i < gs->gimple_omp_for.collapse);
+ return gs->gimple_omp_for.iter[i].incr;
+}
+
+
+/* Return a pointer to the increment value for OMP_FOR GS. */
+
+static inline tree *
+gimple_omp_for_incr_ptr (gimple gs, size_t i)
+{
+ GIMPLE_CHECK (gs, GIMPLE_OMP_FOR);
+ gcc_assert (i < gs->gimple_omp_for.collapse);
+ return &gs->gimple_omp_for.iter[i].incr;
+}
+
+
+/* Set INCR to be the increment value for OMP_FOR GS. */
+
+static inline void
+gimple_omp_for_set_incr (gimple gs, size_t i, tree incr)
+{
+ GIMPLE_CHECK (gs, GIMPLE_OMP_FOR);
+ gcc_assert (i < gs->gimple_omp_for.collapse);
+ gs->gimple_omp_for.iter[i].incr = incr;
+}
+
+
+/* Return the sequence of statements to execute before the OMP_FOR
+ statement GS starts. */
+
+static inline gimple_seq
+gimple_omp_for_pre_body (gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_OMP_FOR);
+ return gs->gimple_omp_for.pre_body;
+}
+
+
+/* Set PRE_BODY to be the sequence of statements to execute before the
+ OMP_FOR statement GS starts. */
+
+static inline void
+gimple_omp_for_set_pre_body (gimple gs, gimple_seq pre_body)
+{
+ GIMPLE_CHECK (gs, GIMPLE_OMP_FOR);
+ gs->gimple_omp_for.pre_body = pre_body;
+}
+
+
+/* Return the clauses associated with OMP_PARALLEL GS. */
+
+static inline tree
+gimple_omp_parallel_clauses (const_gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_OMP_PARALLEL);
+ return gs->gimple_omp_parallel.clauses;
+}
+
+
+/* Return a pointer to the clauses associated with OMP_PARALLEL GS. */
+
+static inline tree *
+gimple_omp_parallel_clauses_ptr (gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_OMP_PARALLEL);
+ return &gs->gimple_omp_parallel.clauses;
+}
+
+
+/* Set CLAUSES to be the list of clauses associated with OMP_PARALLEL
+ GS. */
+
+static inline void
+gimple_omp_parallel_set_clauses (gimple gs, tree clauses)
+{
+ GIMPLE_CHECK (gs, GIMPLE_OMP_PARALLEL);
+ gs->gimple_omp_parallel.clauses = clauses;
+}
+
+
+/* Return the child function used to hold the body of OMP_PARALLEL GS. */
+
+static inline tree
+gimple_omp_parallel_child_fn (const_gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_OMP_PARALLEL);
+ return gs->gimple_omp_parallel.child_fn;
+}
+
+/* Return a pointer to the child function used to hold the body of
+ OMP_PARALLEL GS. */
+
+static inline tree *
+gimple_omp_parallel_child_fn_ptr (gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_OMP_PARALLEL);
+ return &gs->gimple_omp_parallel.child_fn;
+}
+
+
+/* Set CHILD_FN to be the child function for OMP_PARALLEL GS. */
+
+static inline void
+gimple_omp_parallel_set_child_fn (gimple gs, tree child_fn)
+{
+ GIMPLE_CHECK (gs, GIMPLE_OMP_PARALLEL);
+ gs->gimple_omp_parallel.child_fn = child_fn;
+}
+
+
+/* Return the artificial argument used to send variables and values
+ from the parent to the children threads in OMP_PARALLEL GS. */
+
+static inline tree
+gimple_omp_parallel_data_arg (const_gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_OMP_PARALLEL);
+ return gs->gimple_omp_parallel.data_arg;
+}
+
+
+/* Return a pointer to the data argument for OMP_PARALLEL GS. */
+
+static inline tree *
+gimple_omp_parallel_data_arg_ptr (gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_OMP_PARALLEL);
+ return &gs->gimple_omp_parallel.data_arg;
+}
+
+
+/* Set DATA_ARG to be the data argument for OMP_PARALLEL GS. */
+
+static inline void
+gimple_omp_parallel_set_data_arg (gimple gs, tree data_arg)
+{
+ GIMPLE_CHECK (gs, GIMPLE_OMP_PARALLEL);
+ gs->gimple_omp_parallel.data_arg = data_arg;
+}
+
+
+/* Return the clauses associated with OMP_TASK GS. */
+
+static inline tree
+gimple_omp_task_clauses (const_gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_OMP_TASK);
+ return gs->gimple_omp_parallel.clauses;
+}
+
+
+/* Return a pointer to the clauses associated with OMP_TASK GS. */
+
+static inline tree *
+gimple_omp_task_clauses_ptr (gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_OMP_TASK);
+ return &gs->gimple_omp_parallel.clauses;
+}
+
+
+/* Set CLAUSES to be the list of clauses associated with OMP_TASK
+ GS. */
+
+static inline void
+gimple_omp_task_set_clauses (gimple gs, tree clauses)
+{
+ GIMPLE_CHECK (gs, GIMPLE_OMP_TASK);
+ gs->gimple_omp_parallel.clauses = clauses;
+}
+
+
+/* Return the child function used to hold the body of OMP_TASK GS. */
+
+static inline tree
+gimple_omp_task_child_fn (const_gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_OMP_TASK);
+ return gs->gimple_omp_parallel.child_fn;
+}
+
+/* Return a pointer to the child function used to hold the body of
+ OMP_TASK GS. */
+
+static inline tree *
+gimple_omp_task_child_fn_ptr (gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_OMP_TASK);
+ return &gs->gimple_omp_parallel.child_fn;
+}
+
+
+/* Set CHILD_FN to be the child function for OMP_TASK GS. */
+
+static inline void
+gimple_omp_task_set_child_fn (gimple gs, tree child_fn)
+{
+ GIMPLE_CHECK (gs, GIMPLE_OMP_TASK);
+ gs->gimple_omp_parallel.child_fn = child_fn;
+}
+
+
+/* Return the artificial argument used to send variables and values
+ from the parent to the children threads in OMP_TASK GS. */
+
+static inline tree
+gimple_omp_task_data_arg (const_gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_OMP_TASK);
+ return gs->gimple_omp_parallel.data_arg;
+}
+
+
+/* Return a pointer to the data argument for OMP_TASK GS. */
+
+static inline tree *
+gimple_omp_task_data_arg_ptr (gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_OMP_TASK);
+ return &gs->gimple_omp_parallel.data_arg;
+}
+
+
+/* Set DATA_ARG to be the data argument for OMP_TASK GS. */
+
+static inline void
+gimple_omp_task_set_data_arg (gimple gs, tree data_arg)
+{
+ GIMPLE_CHECK (gs, GIMPLE_OMP_TASK);
+ gs->gimple_omp_parallel.data_arg = data_arg;
+}
+
+
+/* Return the clauses associated with OMP_TASK GS. */
+
+static inline tree
+gimple_omp_taskreg_clauses (const_gimple gs)
+{
+ if (gimple_code (gs) != GIMPLE_OMP_PARALLEL)
+ GIMPLE_CHECK (gs, GIMPLE_OMP_TASK);
+ return gs->gimple_omp_parallel.clauses;
+}
+
+
+/* Return a pointer to the clauses associated with OMP_TASK GS. */
+
+static inline tree *
+gimple_omp_taskreg_clauses_ptr (gimple gs)
+{
+ if (gimple_code (gs) != GIMPLE_OMP_PARALLEL)
+ GIMPLE_CHECK (gs, GIMPLE_OMP_TASK);
+ return &gs->gimple_omp_parallel.clauses;
+}
+
+
+/* Set CLAUSES to be the list of clauses associated with OMP_TASK
+ GS. */
+
+static inline void
+gimple_omp_taskreg_set_clauses (gimple gs, tree clauses)
+{
+ if (gimple_code (gs) != GIMPLE_OMP_PARALLEL)
+ GIMPLE_CHECK (gs, GIMPLE_OMP_TASK);
+ gs->gimple_omp_parallel.clauses = clauses;
+}
+
+
+/* Return the child function used to hold the body of OMP_TASK GS. */
+
+static inline tree
+gimple_omp_taskreg_child_fn (const_gimple gs)
+{
+ if (gimple_code (gs) != GIMPLE_OMP_PARALLEL)
+ GIMPLE_CHECK (gs, GIMPLE_OMP_TASK);
+ return gs->gimple_omp_parallel.child_fn;
+}
+
+/* Return a pointer to the child function used to hold the body of
+ OMP_TASK GS. */
+
+static inline tree *
+gimple_omp_taskreg_child_fn_ptr (gimple gs)
+{
+ if (gimple_code (gs) != GIMPLE_OMP_PARALLEL)
+ GIMPLE_CHECK (gs, GIMPLE_OMP_TASK);
+ return &gs->gimple_omp_parallel.child_fn;
+}
+
+
+/* Set CHILD_FN to be the child function for OMP_TASK GS. */
+
+static inline void
+gimple_omp_taskreg_set_child_fn (gimple gs, tree child_fn)
+{
+ if (gimple_code (gs) != GIMPLE_OMP_PARALLEL)
+ GIMPLE_CHECK (gs, GIMPLE_OMP_TASK);
+ gs->gimple_omp_parallel.child_fn = child_fn;
+}
+
+
+/* Return the artificial argument used to send variables and values
+ from the parent to the children threads in OMP_TASK GS. */
+
+static inline tree
+gimple_omp_taskreg_data_arg (const_gimple gs)
+{
+ if (gimple_code (gs) != GIMPLE_OMP_PARALLEL)
+ GIMPLE_CHECK (gs, GIMPLE_OMP_TASK);
+ return gs->gimple_omp_parallel.data_arg;
+}
+
+
+/* Return a pointer to the data argument for OMP_TASK GS. */
+
+static inline tree *
+gimple_omp_taskreg_data_arg_ptr (gimple gs)
+{
+ if (gimple_code (gs) != GIMPLE_OMP_PARALLEL)
+ GIMPLE_CHECK (gs, GIMPLE_OMP_TASK);
+ return &gs->gimple_omp_parallel.data_arg;
+}
+
+
+/* Set DATA_ARG to be the data argument for OMP_TASK GS. */
+
+static inline void
+gimple_omp_taskreg_set_data_arg (gimple gs, tree data_arg)
+{
+ if (gimple_code (gs) != GIMPLE_OMP_PARALLEL)
+ GIMPLE_CHECK (gs, GIMPLE_OMP_TASK);
+ gs->gimple_omp_parallel.data_arg = data_arg;
+}
+
+
+/* Return the copy function used to hold the body of OMP_TASK GS. */
+
+static inline tree
+gimple_omp_task_copy_fn (const_gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_OMP_TASK);
+ return gs->gimple_omp_task.copy_fn;
+}
+
+/* Return a pointer to the copy function used to hold the body of
+ OMP_TASK GS. */
+
+static inline tree *
+gimple_omp_task_copy_fn_ptr (gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_OMP_TASK);
+ return &gs->gimple_omp_task.copy_fn;
+}
+
+
+/* Set CHILD_FN to be the copy function for OMP_TASK GS. */
+
+static inline void
+gimple_omp_task_set_copy_fn (gimple gs, tree copy_fn)
+{
+ GIMPLE_CHECK (gs, GIMPLE_OMP_TASK);
+ gs->gimple_omp_task.copy_fn = copy_fn;
+}
+
+
+/* Return size of the data block in bytes in OMP_TASK GS. */
+
+static inline tree
+gimple_omp_task_arg_size (const_gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_OMP_TASK);
+ return gs->gimple_omp_task.arg_size;
+}
+
+
+/* Return a pointer to the data block size for OMP_TASK GS. */
+
+static inline tree *
+gimple_omp_task_arg_size_ptr (gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_OMP_TASK);
+ return &gs->gimple_omp_task.arg_size;
+}
+
+
+/* Set ARG_SIZE to be the data block size for OMP_TASK GS. */
+
+static inline void
+gimple_omp_task_set_arg_size (gimple gs, tree arg_size)
+{
+ GIMPLE_CHECK (gs, GIMPLE_OMP_TASK);
+ gs->gimple_omp_task.arg_size = arg_size;
+}
+
+
+/* Return align of the data block in bytes in OMP_TASK GS. */
+
+static inline tree
+gimple_omp_task_arg_align (const_gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_OMP_TASK);
+ return gs->gimple_omp_task.arg_align;
+}
+
+
+/* Return a pointer to the data block align for OMP_TASK GS. */
+
+static inline tree *
+gimple_omp_task_arg_align_ptr (gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_OMP_TASK);
+ return &gs->gimple_omp_task.arg_align;
+}
+
+
+/* Set ARG_SIZE to be the data block align for OMP_TASK GS. */
+
+static inline void
+gimple_omp_task_set_arg_align (gimple gs, tree arg_align)
+{
+ GIMPLE_CHECK (gs, GIMPLE_OMP_TASK);
+ gs->gimple_omp_task.arg_align = arg_align;
+}
+
+
+/* Return the clauses associated with OMP_SINGLE GS. */
+
+static inline tree
+gimple_omp_single_clauses (const_gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_OMP_SINGLE);
+ return gs->gimple_omp_single.clauses;
+}
+
+
+/* Return a pointer to the clauses associated with OMP_SINGLE GS. */
+
+static inline tree *
+gimple_omp_single_clauses_ptr (gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_OMP_SINGLE);
+ return &gs->gimple_omp_single.clauses;
+}
+
+
+/* Set CLAUSES to be the clauses associated with OMP_SINGLE GS. */
+
+static inline void
+gimple_omp_single_set_clauses (gimple gs, tree clauses)
+{
+ GIMPLE_CHECK (gs, GIMPLE_OMP_SINGLE);
+ gs->gimple_omp_single.clauses = clauses;
+}
+
+
+/* Return the clauses associated with OMP_SECTIONS GS. */
+
+static inline tree
+gimple_omp_sections_clauses (const_gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_OMP_SECTIONS);
+ return gs->gimple_omp_sections.clauses;
+}
+
+
+/* Return a pointer to the clauses associated with OMP_SECTIONS GS. */
+
+static inline tree *
+gimple_omp_sections_clauses_ptr (gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_OMP_SECTIONS);
+ return &gs->gimple_omp_sections.clauses;
+}
+
+
+/* Set CLAUSES to be the set of clauses associated with OMP_SECTIONS
+ GS. */
+
+static inline void
+gimple_omp_sections_set_clauses (gimple gs, tree clauses)
+{
+ GIMPLE_CHECK (gs, GIMPLE_OMP_SECTIONS);
+ gs->gimple_omp_sections.clauses = clauses;
+}
+
+
+/* Return the control variable associated with the GIMPLE_OMP_SECTIONS
+ in GS. */
+
+static inline tree
+gimple_omp_sections_control (const_gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_OMP_SECTIONS);
+ return gs->gimple_omp_sections.control;
+}
+
+
+/* Return a pointer to the clauses associated with the GIMPLE_OMP_SECTIONS
+ GS. */
+
+static inline tree *
+gimple_omp_sections_control_ptr (gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_OMP_SECTIONS);
+ return &gs->gimple_omp_sections.control;
+}
+
+
+/* Set CONTROL to be the set of clauses associated with the
+ GIMPLE_OMP_SECTIONS in GS. */
+
+static inline void
+gimple_omp_sections_set_control (gimple gs, tree control)
+{
+ GIMPLE_CHECK (gs, GIMPLE_OMP_SECTIONS);
+ gs->gimple_omp_sections.control = control;
+}
+
+
+/* Set COND to be the condition code for OMP_FOR GS. */
+
+static inline void
+gimple_omp_for_set_cond (gimple gs, size_t i, enum tree_code cond)
+{
+ GIMPLE_CHECK (gs, GIMPLE_OMP_FOR);
+ gcc_assert (TREE_CODE_CLASS (cond) == tcc_comparison);
+ gcc_assert (i < gs->gimple_omp_for.collapse);
+ gs->gimple_omp_for.iter[i].cond = cond;
+}
+
+
+/* Return the condition code associated with OMP_FOR GS. */
+
+static inline enum tree_code
+gimple_omp_for_cond (const_gimple gs, size_t i)
+{
+ GIMPLE_CHECK (gs, GIMPLE_OMP_FOR);
+ gcc_assert (i < gs->gimple_omp_for.collapse);
+ return gs->gimple_omp_for.iter[i].cond;
+}
+
+
+/* Set the value being stored in an atomic store. */
+
+static inline void
+gimple_omp_atomic_store_set_val (gimple g, tree val)
+{
+ GIMPLE_CHECK (g, GIMPLE_OMP_ATOMIC_STORE);
+ g->gimple_omp_atomic_store.val = val;
+}
+
+
+/* Return the value being stored in an atomic store. */
+
+static inline tree
+gimple_omp_atomic_store_val (const_gimple g)
+{
+ GIMPLE_CHECK (g, GIMPLE_OMP_ATOMIC_STORE);
+ return g->gimple_omp_atomic_store.val;
+}
+
+
+/* Return a pointer to the value being stored in an atomic store. */
+
+static inline tree *
+gimple_omp_atomic_store_val_ptr (gimple g)
+{
+ GIMPLE_CHECK (g, GIMPLE_OMP_ATOMIC_STORE);
+ return &g->gimple_omp_atomic_store.val;
+}
+
+
+/* Set the LHS of an atomic load. */
+
+static inline void
+gimple_omp_atomic_load_set_lhs (gimple g, tree lhs)
+{
+ GIMPLE_CHECK (g, GIMPLE_OMP_ATOMIC_LOAD);
+ g->gimple_omp_atomic_load.lhs = lhs;
+}
+
+
+/* Get the LHS of an atomic load. */
+
+static inline tree
+gimple_omp_atomic_load_lhs (const_gimple g)
+{
+ GIMPLE_CHECK (g, GIMPLE_OMP_ATOMIC_LOAD);
+ return g->gimple_omp_atomic_load.lhs;
+}
+
+
+/* Return a pointer to the LHS of an atomic load. */
+
+static inline tree *
+gimple_omp_atomic_load_lhs_ptr (gimple g)
+{
+ GIMPLE_CHECK (g, GIMPLE_OMP_ATOMIC_LOAD);
+ return &g->gimple_omp_atomic_load.lhs;
+}
+
+
+/* Set the RHS of an atomic load. */
+
+static inline void
+gimple_omp_atomic_load_set_rhs (gimple g, tree rhs)
+{
+ GIMPLE_CHECK (g, GIMPLE_OMP_ATOMIC_LOAD);
+ g->gimple_omp_atomic_load.rhs = rhs;
+}
+
+
+/* Get the RHS of an atomic load. */
+
+static inline tree
+gimple_omp_atomic_load_rhs (const_gimple g)
+{
+ GIMPLE_CHECK (g, GIMPLE_OMP_ATOMIC_LOAD);
+ return g->gimple_omp_atomic_load.rhs;
+}
+
+
+/* Return a pointer to the RHS of an atomic load. */
+
+static inline tree *
+gimple_omp_atomic_load_rhs_ptr (gimple g)
+{
+ GIMPLE_CHECK (g, GIMPLE_OMP_ATOMIC_LOAD);
+ return &g->gimple_omp_atomic_load.rhs;
+}
+
+
+/* Get the definition of the control variable in a GIMPLE_OMP_CONTINUE. */
+
+static inline tree
+gimple_omp_continue_control_def (const_gimple g)
+{
+ GIMPLE_CHECK (g, GIMPLE_OMP_CONTINUE);
+ return g->gimple_omp_continue.control_def;
+}
+
+/* The same as above, but return the address. */
+
+static inline tree *
+gimple_omp_continue_control_def_ptr (gimple g)
+{
+ GIMPLE_CHECK (g, GIMPLE_OMP_CONTINUE);
+ return &g->gimple_omp_continue.control_def;
+}
+
+/* Set the definition of the control variable in a GIMPLE_OMP_CONTINUE. */
+
+static inline void
+gimple_omp_continue_set_control_def (gimple g, tree def)
+{
+ GIMPLE_CHECK (g, GIMPLE_OMP_CONTINUE);
+ g->gimple_omp_continue.control_def = def;
+}
+
+
+/* Get the use of the control variable in a GIMPLE_OMP_CONTINUE. */
+
+static inline tree
+gimple_omp_continue_control_use (const_gimple g)
+{
+ GIMPLE_CHECK (g, GIMPLE_OMP_CONTINUE);
+ return g->gimple_omp_continue.control_use;
+}
+
+
+/* The same as above, but return the address. */
+
+static inline tree *
+gimple_omp_continue_control_use_ptr (gimple g)
+{
+ GIMPLE_CHECK (g, GIMPLE_OMP_CONTINUE);
+ return &g->gimple_omp_continue.control_use;
+}
+
+
+/* Set the use of the control variable in a GIMPLE_OMP_CONTINUE. */
+
+static inline void
+gimple_omp_continue_set_control_use (gimple g, tree use)
+{
+ GIMPLE_CHECK (g, GIMPLE_OMP_CONTINUE);
+ g->gimple_omp_continue.control_use = use;
+}
+
+
+/* Return a pointer to the return value for GIMPLE_RETURN GS. */
+
+static inline tree *
+gimple_return_retval_ptr (const_gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_RETURN);
+ gcc_assert (gimple_num_ops (gs) == 1);
+ return gimple_op_ptr (gs, 0);
+}
+
+/* Return the return value for GIMPLE_RETURN GS. */
+
+static inline tree
+gimple_return_retval (const_gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_RETURN);
+ gcc_assert (gimple_num_ops (gs) == 1);
+ return gimple_op (gs, 0);
+}
+
+
+/* Set RETVAL to be the return value for GIMPLE_RETURN GS. */
+
+static inline void
+gimple_return_set_retval (gimple gs, tree retval)
+{
+ GIMPLE_CHECK (gs, GIMPLE_RETURN);
+ gcc_assert (gimple_num_ops (gs) == 1);
+ gcc_assert (retval == NULL_TREE
+ || TREE_CODE (retval) == RESULT_DECL
+ || is_gimple_val (retval));
+ gimple_set_op (gs, 0, retval);
+}
+
+
+/* Returns true when the gimple statment STMT is any of the OpenMP types. */
+
+static inline bool
+is_gimple_omp (const_gimple stmt)
+{
+ return (gimple_code (stmt) == GIMPLE_OMP_PARALLEL
+ || gimple_code (stmt) == GIMPLE_OMP_TASK
+ || gimple_code (stmt) == GIMPLE_OMP_FOR
+ || gimple_code (stmt) == GIMPLE_OMP_SECTIONS
+ || gimple_code (stmt) == GIMPLE_OMP_SECTIONS_SWITCH
+ || gimple_code (stmt) == GIMPLE_OMP_SINGLE
+ || gimple_code (stmt) == GIMPLE_OMP_SECTION
+ || gimple_code (stmt) == GIMPLE_OMP_MASTER
+ || gimple_code (stmt) == GIMPLE_OMP_ORDERED
+ || gimple_code (stmt) == GIMPLE_OMP_CRITICAL
+ || gimple_code (stmt) == GIMPLE_OMP_RETURN
+ || gimple_code (stmt) == GIMPLE_OMP_ATOMIC_LOAD
+ || gimple_code (stmt) == GIMPLE_OMP_ATOMIC_STORE
+ || gimple_code (stmt) == GIMPLE_OMP_CONTINUE);
+}
+
+
+/* Returns TRUE if statement G is a GIMPLE_NOP. */
+
+static inline bool
+gimple_nop_p (const_gimple g)
+{
+ return gimple_code (g) == GIMPLE_NOP;
+}
+
+
+/* Return the new type set by GIMPLE_CHANGE_DYNAMIC_TYPE statement GS. */
+
+static inline tree
+gimple_cdt_new_type (gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_CHANGE_DYNAMIC_TYPE);
+ return gimple_op (gs, 1);
+}
+
+/* Return a pointer to the new type set by GIMPLE_CHANGE_DYNAMIC_TYPE
+ statement GS. */
+
+static inline tree *
+gimple_cdt_new_type_ptr (gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_CHANGE_DYNAMIC_TYPE);
+ return gimple_op_ptr (gs, 1);
+}
+
+/* Set NEW_TYPE to be the type returned by GIMPLE_CHANGE_DYNAMIC_TYPE
+ statement GS. */
+
+static inline void
+gimple_cdt_set_new_type (gimple gs, tree new_type)
+{
+ GIMPLE_CHECK (gs, GIMPLE_CHANGE_DYNAMIC_TYPE);
+ gcc_assert (TREE_CODE_CLASS (TREE_CODE (new_type)) == tcc_type);
+ gimple_set_op (gs, 1, new_type);
+}
+
+
+/* Return the location affected by GIMPLE_CHANGE_DYNAMIC_TYPE statement GS. */
+
+static inline tree
+gimple_cdt_location (gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_CHANGE_DYNAMIC_TYPE);
+ return gimple_op (gs, 0);
+}
+
+
+/* Return a pointer to the location affected by GIMPLE_CHANGE_DYNAMIC_TYPE
+ statement GS. */
+
+static inline tree *
+gimple_cdt_location_ptr (gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_CHANGE_DYNAMIC_TYPE);
+ return gimple_op_ptr (gs, 0);
+}
+
+
+/* Set PTR to be the location affected by GIMPLE_CHANGE_DYNAMIC_TYPE
+ statement GS. */
+
+static inline void
+gimple_cdt_set_location (gimple gs, tree ptr)
+{
+ GIMPLE_CHECK (gs, GIMPLE_CHANGE_DYNAMIC_TYPE);
+ gimple_set_op (gs, 0, ptr);
+}
+
+
+/* Return the predictor of GIMPLE_PREDICT statement GS. */
+
+static inline enum br_predictor
+gimple_predict_predictor (gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_PREDICT);
+ return (enum br_predictor) (gs->gsbase.subcode & ~GF_PREDICT_TAKEN);
+}
+
+
+/* Set the predictor of GIMPLE_PREDICT statement GS to PREDICT. */
+
+static inline void
+gimple_predict_set_predictor (gimple gs, enum br_predictor predictor)
+{
+ GIMPLE_CHECK (gs, GIMPLE_PREDICT);
+ gs->gsbase.subcode = (gs->gsbase.subcode & GF_PREDICT_TAKEN)
+ | (unsigned) predictor;
+}
+
+
+/* Return the outcome of GIMPLE_PREDICT statement GS. */
+
+static inline enum prediction
+gimple_predict_outcome (gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_PREDICT);
+ return (gs->gsbase.subcode & GF_PREDICT_TAKEN) ? TAKEN : NOT_TAKEN;
+}
+
+
+/* Set the outcome of GIMPLE_PREDICT statement GS to OUTCOME. */
+
+static inline void
+gimple_predict_set_outcome (gimple gs, enum prediction outcome)
+{
+ GIMPLE_CHECK (gs, GIMPLE_PREDICT);
+ if (outcome == TAKEN)
+ gs->gsbase.subcode |= GF_PREDICT_TAKEN;
+ else
+ gs->gsbase.subcode &= ~GF_PREDICT_TAKEN;
+}
+
+
+/* Return a new iterator pointing to GIMPLE_SEQ's first statement. */
+
+static inline gimple_stmt_iterator
+gsi_start (gimple_seq seq)
+{
+ gimple_stmt_iterator i;
+
+ i.ptr = gimple_seq_first (seq);
+ i.seq = seq;
+ i.bb = (i.ptr && i.ptr->stmt) ? gimple_bb (i.ptr->stmt) : NULL;
+
+ return i;
+}
+
+
+/* Return a new iterator pointing to the first statement in basic block BB. */
+
+static inline gimple_stmt_iterator
+gsi_start_bb (basic_block bb)
+{
+ gimple_stmt_iterator i;
+ gimple_seq seq;
+
+ seq = bb_seq (bb);
+ i.ptr = gimple_seq_first (seq);
+ i.seq = seq;
+ i.bb = bb;
+
+ return i;
+}
+
+
+/* Return a new iterator initially pointing to GIMPLE_SEQ's last statement. */
+
+static inline gimple_stmt_iterator
+gsi_last (gimple_seq seq)
+{
+ gimple_stmt_iterator i;
+
+ i.ptr = gimple_seq_last (seq);
+ i.seq = seq;
+ i.bb = (i.ptr && i.ptr->stmt) ? gimple_bb (i.ptr->stmt) : NULL;
+
+ return i;
+}
+
+
+/* Return a new iterator pointing to the last statement in basic block BB. */
+
+static inline gimple_stmt_iterator
+gsi_last_bb (basic_block bb)
+{
+ gimple_stmt_iterator i;
+ gimple_seq seq;
+
+ seq = bb_seq (bb);
+ i.ptr = gimple_seq_last (seq);
+ i.seq = seq;
+ i.bb = bb;
+
+ return i;
+}
+
+
+/* Return true if I is at the end of its sequence. */
+
+static inline bool
+gsi_end_p (gimple_stmt_iterator i)
+{
+ return i.ptr == NULL;
+}
+
+
+/* Return true if I is one statement before the end of its sequence. */
+
+static inline bool
+gsi_one_before_end_p (gimple_stmt_iterator i)
+{
+ return i.ptr != NULL && i.ptr->next == NULL;
+}
+
+
+/* Advance the iterator to the next gimple statement. */
+
+static inline void
+gsi_next (gimple_stmt_iterator *i)
+{
+ i->ptr = i->ptr->next;
+}
+
+/* Advance the iterator to the previous gimple statement. */
+
+static inline void
+gsi_prev (gimple_stmt_iterator *i)
+{
+ i->ptr = i->ptr->prev;
+}
+
+/* Return the current stmt. */
+
+static inline gimple
+gsi_stmt (gimple_stmt_iterator i)
+{
+ return i.ptr->stmt;
+}
+
+/* Return a block statement iterator that points to the first non-label
+ statement in block BB. */
+
+static inline gimple_stmt_iterator
+gsi_after_labels (basic_block bb)
+{
+ gimple_stmt_iterator gsi = gsi_start_bb (bb);
+
+ while (!gsi_end_p (gsi) && gimple_code (gsi_stmt (gsi)) == GIMPLE_LABEL)
+ gsi_next (&gsi);
+
+ return gsi;
+}
+
+/* Return a pointer to the current stmt.
+
+ NOTE: You may want to use gsi_replace on the iterator itself,
+ as this performs additional bookkeeping that will not be done
+ if you simply assign through a pointer returned by gsi_stmt_ptr. */
+
+static inline gimple *
+gsi_stmt_ptr (gimple_stmt_iterator *i)
+{
+ return &i->ptr->stmt;
+}
+
+
+/* Return the basic block associated with this iterator. */
+
+static inline basic_block
+gsi_bb (gimple_stmt_iterator i)
+{
+ return i.bb;
+}
+
+
+/* Return the sequence associated with this iterator. */
+
+static inline gimple_seq
+gsi_seq (gimple_stmt_iterator i)
+{
+ return i.seq;
+}
+
+
+enum gsi_iterator_update
+{
+ GSI_NEW_STMT, /* Only valid when single statement is added, move
+ iterator to it. */
+ GSI_SAME_STMT, /* Leave the iterator at the same statement. */
+ GSI_CONTINUE_LINKING /* Move iterator to whatever position is suitable
+ for linking other statements in the same
+ direction. */
+};
+
+/* In gimple-iterator.c */
+gimple_stmt_iterator gsi_start_phis (basic_block);
+gimple_seq gsi_split_seq_after (gimple_stmt_iterator);
+gimple_seq gsi_split_seq_before (gimple_stmt_iterator *);
+void gsi_replace (gimple_stmt_iterator *, gimple, bool);
+void gsi_insert_before (gimple_stmt_iterator *, gimple,
+ enum gsi_iterator_update);
+void gsi_insert_before_without_update (gimple_stmt_iterator *, gimple,
+ enum gsi_iterator_update);
+void gsi_insert_seq_before (gimple_stmt_iterator *, gimple_seq,
+ enum gsi_iterator_update);
+void gsi_insert_seq_before_without_update (gimple_stmt_iterator *, gimple_seq,
+ enum gsi_iterator_update);
+void gsi_insert_after (gimple_stmt_iterator *, gimple,
+ enum gsi_iterator_update);
+void gsi_insert_after_without_update (gimple_stmt_iterator *, gimple,
+ enum gsi_iterator_update);
+void gsi_insert_seq_after (gimple_stmt_iterator *, gimple_seq,
+ enum gsi_iterator_update);
+void gsi_insert_seq_after_without_update (gimple_stmt_iterator *, gimple_seq,
+ enum gsi_iterator_update);
+void gsi_remove (gimple_stmt_iterator *, bool);
+gimple_stmt_iterator gsi_for_stmt (gimple);
+void gsi_move_after (gimple_stmt_iterator *, gimple_stmt_iterator *);
+void gsi_move_before (gimple_stmt_iterator *, gimple_stmt_iterator *);
+void gsi_move_to_bb_end (gimple_stmt_iterator *, struct basic_block_def *);
+void gsi_insert_on_edge (edge, gimple);
+void gsi_insert_seq_on_edge (edge, gimple_seq);
+basic_block gsi_insert_on_edge_immediate (edge, gimple);
+basic_block gsi_insert_seq_on_edge_immediate (edge, gimple_seq);
+void gsi_commit_one_edge_insert (edge, basic_block *);
+void gsi_commit_edge_inserts (void);
+
+
+/* Convenience routines to walk all statements of a gimple function.
+ Note that this is useful exclusively before the code is converted
+ into SSA form. Once the program is in SSA form, the standard
+ operand interface should be used to analyze/modify statements. */
+struct walk_stmt_info
+{
+ /* Points to the current statement being walked. */
+ gimple_stmt_iterator gsi;
+
+ /* Additional data that the callback functions may want to carry
+ through the recursion. */
+ void *info;
+
+ /* Pointer map used to mark visited tree nodes when calling
+ walk_tree on each operand. If set to NULL, duplicate tree nodes
+ will be visited more than once. */
+ struct pointer_set_t *pset;
+
+ /* Indicates whether the operand being examined may be replaced
+ with something that matches is_gimple_val (if true) or something
+ slightly more complicated (if false). "Something" technically
+ means the common subset of is_gimple_lvalue and is_gimple_rhs,
+ but we never try to form anything more complicated than that, so
+ we don't bother checking.
+
+ Also note that CALLBACK should update this flag while walking the
+ sub-expressions of a statement. For instance, when walking the
+ statement 'foo (&var)', the flag VAL_ONLY will initially be set
+ to true, however, when walking &var, the operand of that
+ ADDR_EXPR does not need to be a GIMPLE value. */
+ bool val_only;
+
+ /* True if we are currently walking the LHS of an assignment. */
+ bool is_lhs;
+
+ /* Optional. Set to true by the callback functions if they made any
+ changes. */
+ bool changed;
+
+ /* True if we're interested in location information. */
+ bool want_locations;
+
+ /* Operand returned by the callbacks. This is set when calling
+ walk_gimple_seq. If the walk_stmt_fn or walk_tree_fn callback
+ returns non-NULL, this field will contain the tree returned by
+ the last callback. */
+ tree callback_result;
+};
+
+/* Callback for walk_gimple_stmt. Called for every statement found
+ during traversal. The first argument points to the statement to
+ walk. The second argument is a flag that the callback sets to
+ 'true' if it the callback handled all the operands and
+ sub-statements of the statement (the default value of this flag is
+ 'false'). The third argument is an anonymous pointer to data
+ to be used by the callback. */
+typedef tree (*walk_stmt_fn) (gimple_stmt_iterator *, bool *,
+ struct walk_stmt_info *);
+
+gimple walk_gimple_seq (gimple_seq, walk_stmt_fn, walk_tree_fn,
+ struct walk_stmt_info *);
+tree walk_gimple_stmt (gimple_stmt_iterator *, walk_stmt_fn, walk_tree_fn,
+ struct walk_stmt_info *);
+tree walk_gimple_op (gimple, walk_tree_fn, struct walk_stmt_info *);
+
+#ifdef GATHER_STATISTICS
+/* Enum and arrays used for allocation stats. Keep in sync with
+ gimple.c:gimple_alloc_kind_names. */
+enum gimple_alloc_kind
+{
+ gimple_alloc_kind_assign, /* Assignments. */
+ gimple_alloc_kind_phi, /* PHI nodes. */
+ gimple_alloc_kind_cond, /* Conditionals. */
+ gimple_alloc_kind_seq, /* Sequences. */
+ gimple_alloc_kind_rest, /* Everything else. */
+ gimple_alloc_kind_all
+};
+
+extern int gimple_alloc_counts[];
+extern int gimple_alloc_sizes[];
+
+/* Return the allocation kind for a given stmt CODE. */
+static inline enum gimple_alloc_kind
+gimple_alloc_kind (enum gimple_code code)
+{
+ switch (code)
+ {
+ case GIMPLE_ASSIGN:
+ return gimple_alloc_kind_assign;
+ case GIMPLE_PHI:
+ return gimple_alloc_kind_phi;
+ case GIMPLE_COND:
+ return gimple_alloc_kind_cond;
+ default:
+ return gimple_alloc_kind_rest;
+ }
+}
+#endif /* GATHER_STATISTICS */
+
+extern void dump_gimple_statistics (void);
+
+#endif /* GCC_GIMPLE_H */
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index c3af34bf27e..0f08f3b7393 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -28,7 +28,8 @@ along with GCC; see the file COPYING3. If not see
#include "tree.h"
#include "rtl.h"
#include "varray.h"
-#include "tree-gimple.h"
+#include "gimple.h"
+#include "tree-iterator.h"
#include "tree-inline.h"
#include "diagnostic.h"
#include "langhooks.h"
@@ -49,6 +50,8 @@ along with GCC; see the file COPYING3. If not see
#include "optabs.h"
#include "pointer-set.h"
#include "splay-tree.h"
+#include "vec.h"
+#include "gimple.h"
enum gimplify_omp_var_data
@@ -67,6 +70,7 @@ enum gimplify_omp_var_data
| GOVD_LASTPRIVATE | GOVD_REDUCTION | GOVD_LOCAL)
};
+
enum omp_region_type
{
ORT_WORKSHARE = 0,
@@ -85,31 +89,10 @@ struct gimplify_omp_ctx
enum omp_region_type region_type;
};
-struct gimplify_ctx
-{
- struct gimplify_ctx *prev_context;
-
- tree current_bind_expr;
- tree temps;
- tree conditional_cleanups;
- tree exit_label;
- tree return_temp;
-
- VEC(tree,heap) *case_labels;
- /* The formal temporary table. Should this be persistent? */
- htab_t temp_htab;
-
- int conditions;
- bool save_stack;
- bool into_ssa;
- bool allow_rhs_cond_expr;
-};
-
static struct gimplify_ctx *gimplify_ctxp;
static struct gimplify_omp_ctx *gimplify_omp_ctxp;
-
/* Formal (expression) temporary table handling: Multiple occurrences of
the same scalar expression are evaluated into the same temporary. */
@@ -120,7 +103,7 @@ typedef struct gimple_temp_hash_elt
} elt_t;
/* Forward declarations. */
-static enum gimplify_status gimplify_compound_expr (tree *, tree *, bool);
+static enum gimplify_status gimplify_compound_expr (tree *, gimple_seq *, bool);
/* Mark X addressable. Unlike the langhook we expect X to be in gimple
form and we don't do any syntax checking. */
@@ -166,32 +149,73 @@ gimple_tree_eq (const void *p1, const void *p2)
return 1;
}
+/* Link gimple statement GS to the end of the sequence *SEQ_P. If
+ *SEQ_P is NULL, a new sequence is allocated. This function is
+ similar to gimple_seq_add_stmt, but does not scan the operands.
+ During gimplification, we need to manipulate statement sequences
+ before the def/use vectors have been constructed. */
+
+static void
+gimplify_seq_add_stmt (gimple_seq *seq_p, gimple gs)
+{
+ gimple_stmt_iterator si;
+
+ if (gs == NULL)
+ return;
+
+ if (*seq_p == NULL)
+ *seq_p = gimple_seq_alloc ();
+
+ si = gsi_last (*seq_p);
+
+ gsi_insert_after_without_update (&si, gs, GSI_NEW_STMT);
+}
+
+/* Append sequence SRC to the end of sequence *DST_P. If *DST_P is
+ NULL, a new sequence is allocated. This function is
+ similar to gimple_seq_add_seq, but does not scan the operands.
+ During gimplification, we need to manipulate statement sequences
+ before the def/use vectors have been constructed. */
+
+static void
+gimplify_seq_add_seq (gimple_seq *dst_p, gimple_seq src)
+{
+ gimple_stmt_iterator si;
+
+ if (src == NULL)
+ return;
+
+ if (*dst_p == NULL)
+ *dst_p = gimple_seq_alloc ();
+
+ si = gsi_last (*dst_p);
+ gsi_insert_seq_after_without_update (&si, src, GSI_NEW_STMT);
+}
+
/* Set up a context for the gimplifier. */
void
-push_gimplify_context (void)
+push_gimplify_context (struct gimplify_ctx *c)
{
- struct gimplify_ctx *c;
-
- c = (struct gimplify_ctx *) xcalloc (1, sizeof (struct gimplify_ctx));
+ memset (c, '\0', sizeof (*c));
c->prev_context = gimplify_ctxp;
- if (optimize)
- c->temp_htab = htab_create (1000, gimple_tree_hash, gimple_tree_eq, free);
-
gimplify_ctxp = c;
}
/* Tear down a context for the gimplifier. If BODY is non-null, then
put the temporaries into the outer BIND_EXPR. Otherwise, put them
- in the local_decls. */
+ in the local_decls.
+
+ BODY is not a sequence, but the first tuple in a sequence. */
void
-pop_gimplify_context (tree body)
+pop_gimplify_context (gimple body)
{
struct gimplify_ctx *c = gimplify_ctxp;
tree t;
- gcc_assert (c && !c->current_bind_expr);
+ gcc_assert (c && (c->bind_expr_stack == NULL
+ || VEC_empty (gimple, c->bind_expr_stack)));
gimplify_ctxp = c->prev_context;
for (t = c->temps; t ; t = TREE_CHAIN (t))
@@ -202,29 +226,36 @@ pop_gimplify_context (tree body)
else
record_vars (c->temps);
- if (optimize)
+ if (c->temp_htab)
htab_delete (c->temp_htab);
- free (c);
}
static void
-gimple_push_bind_expr (tree bind)
+gimple_push_bind_expr (gimple gimple_bind)
{
- TREE_CHAIN (bind) = gimplify_ctxp->current_bind_expr;
- gimplify_ctxp->current_bind_expr = bind;
+ if (gimplify_ctxp->bind_expr_stack == NULL)
+ gimplify_ctxp->bind_expr_stack = VEC_alloc (gimple, heap, 8);
+ VEC_safe_push (gimple, heap, gimplify_ctxp->bind_expr_stack, gimple_bind);
}
static void
gimple_pop_bind_expr (void)
{
- gimplify_ctxp->current_bind_expr
- = TREE_CHAIN (gimplify_ctxp->current_bind_expr);
+ VEC_pop (gimple, gimplify_ctxp->bind_expr_stack);
}
-tree
+gimple
gimple_current_bind_expr (void)
{
- return gimplify_ctxp->current_bind_expr;
+ return VEC_last (gimple, gimplify_ctxp->bind_expr_stack);
+}
+
+/* Return the stack GIMPLE_BINDs created during gimplification. */
+
+VEC(gimple, heap) *
+gimple_bind_expr_stack (void)
+{
+ return gimplify_ctxp->bind_expr_stack;
}
/* Returns true iff there is a COND_EXPR between us and the innermost
@@ -241,9 +272,9 @@ gimple_conditional_context (void)
static void
gimple_push_condition (void)
{
-#ifdef ENABLE_CHECKING
+#ifdef ENABLE_GIMPLE_CHECKING
if (gimplify_ctxp->conditions == 0)
- gcc_assert (!gimplify_ctxp->conditional_cleanups);
+ gcc_assert (gimple_seq_empty_p (gimplify_ctxp->conditional_cleanups));
#endif
++(gimplify_ctxp->conditions);
}
@@ -252,15 +283,15 @@ gimple_push_condition (void)
now, add any conditional cleanups we've seen to the prequeue. */
static void
-gimple_pop_condition (tree *pre_p)
+gimple_pop_condition (gimple_seq *pre_p)
{
int conds = --(gimplify_ctxp->conditions);
gcc_assert (conds >= 0);
if (conds == 0)
{
- append_to_statement_list (gimplify_ctxp->conditional_cleanups, pre_p);
- gimplify_ctxp->conditional_cleanups = NULL_TREE;
+ gimplify_seq_add_seq (pre_p, gimplify_ctxp->conditional_cleanups);
+ gimplify_ctxp->conditional_cleanups = NULL;
}
}
@@ -350,13 +381,34 @@ append_to_statement_list_force (tree t, tree *list_p)
append_to_statement_list_1 (t, list_p);
}
-/* Both gimplify the statement T and append it to LIST_P. */
+/* Both gimplify the statement T and append it to *SEQ_P. This function
+ behaves exactly as gimplify_stmt, but you don't have to pass T as a
+ reference. */
void
-gimplify_and_add (tree t, tree *list_p)
+gimplify_and_add (tree t, gimple_seq *seq_p)
{
- gimplify_stmt (&t);
- append_to_statement_list (t, list_p);
+ gimplify_stmt (&t, seq_p);
+}
+
+/* Gimplify statement T into sequence *SEQ_P, and return the first
+ tuple in the sequence of generated tuples for this statement.
+ Return NULL if gimplifying T produced no tuples. */
+
+static gimple
+gimplify_and_return_first (tree t, gimple_seq *seq_p)
+{
+ gimple_stmt_iterator last = gsi_last (*seq_p);
+
+ gimplify_and_add (t, seq_p);
+
+ if (!gsi_end_p (last))
+ {
+ gsi_next (&last);
+ return gsi_stmt (last);
+ }
+ else
+ return gimple_seq_first_stmt (*seq_p);
}
/* Strip off a legitimate source ending from the input string NAME of
@@ -379,20 +431,6 @@ remove_suffix (char *name, int len)
}
}
-/* Create a nameless artificial label and put it in the current function
- context. Returns the newly created label. */
-
-tree
-create_artificial_label (void)
-{
- tree lab = build_decl (LABEL_DECL, NULL_TREE, void_type_node);
-
- DECL_ARTIFICIAL (lab) = 1;
- DECL_IGNORED_P (lab) = 1;
- DECL_CONTEXT (lab) = current_function_decl;
- return lab;
-}
-
/* Subroutine for find_single_pointer_decl. */
static tree
@@ -520,31 +558,6 @@ create_tmp_var (tree type, const char *prefix)
return tmp_var;
}
-/* Given a tree, try to return a useful variable name that we can use
- to prefix a temporary that is being assigned the value of the tree.
- I.E. given <temp> = &A, return A. */
-
-const char *
-get_name (const_tree t)
-{
- const_tree stripped_decl;
-
- stripped_decl = t;
- STRIP_NOPS (stripped_decl);
- if (DECL_P (stripped_decl) && DECL_NAME (stripped_decl))
- return IDENTIFIER_POINTER (DECL_NAME (stripped_decl));
- else
- {
- switch (TREE_CODE (stripped_decl))
- {
- case ADDR_EXPR:
- return get_name (TREE_OPERAND (stripped_decl, 0));
- default:
- return NULL;
- }
- }
-}
-
/* Create a temporary with a name derived from VAL. Subroutine of
lookup_tmp_var; nobody else should call this function. */
@@ -575,6 +588,9 @@ lookup_tmp_var (tree val, bool is_formal)
void **slot;
elt.val = val;
+ if (gimplify_ctxp->temp_htab == NULL)
+ gimplify_ctxp->temp_htab
+ = htab_create (1000, gimple_tree_hash, gimple_tree_eq, free);
slot = htab_find_slot (gimplify_ctxp->temp_htab, (void *)&elt, INSERT);
if (*slot == NULL)
{
@@ -596,6 +612,62 @@ lookup_tmp_var (tree val, bool is_formal)
return ret;
}
+
+/* Return true if T is a CALL_EXPR or an expression that can be
+ assignmed to a temporary. Note that this predicate should only be
+ used during gimplification. See the rationale for this in
+ gimplify_modify_expr. */
+
+static bool
+is_gimple_formal_tmp_or_call_rhs (tree t)
+{
+ return TREE_CODE (t) == CALL_EXPR || is_gimple_formal_tmp_rhs (t);
+}
+
+/* Returns true iff T is a valid RHS for an assignment to a renamed
+ user -- or front-end generated artificial -- variable. */
+
+static bool
+is_gimple_reg_or_call_rhs (tree t)
+{
+ /* If the RHS of the MODIFY_EXPR may throw or make a nonlocal goto
+ and the LHS is a user variable, then we need to introduce a formal
+ temporary. This way the optimizers can determine that the user
+ variable is only modified if evaluation of the RHS does not throw.
+
+ Don't force a temp of a non-renamable type; the copy could be
+ arbitrarily expensive. Instead we will generate a VDEF for
+ the assignment. */
+
+ if (is_gimple_reg_type (TREE_TYPE (t))
+ && ((TREE_CODE (t) == CALL_EXPR && TREE_SIDE_EFFECTS (t))
+ || tree_could_throw_p (t)))
+ return false;
+
+ return is_gimple_formal_tmp_or_call_rhs (t);
+}
+
+/* Return true if T is a valid memory RHS or a CALL_EXPR. Note that
+ this predicate should only be used during gimplification. See the
+ rationale for this in gimplify_modify_expr. */
+
+static bool
+is_gimple_mem_or_call_rhs (tree t)
+{
+ /* If we're dealing with a renamable type, either source or dest must be
+ a renamed variable. Also force a temporary if the type doesn't need
+ to be stored in memory, since it's cheap and prevents erroneous
+ tailcalls (PR 17526). */
+ if (is_gimple_reg_type (TREE_TYPE (t))
+ || (TYPE_MODE (TREE_TYPE (t)) != BLKmode
+ && (TREE_CODE (t) != CALL_EXPR
+ || ! aggregate_value_p (t, t))))
+ return is_gimple_val (t);
+ else
+ return is_gimple_formal_tmp_or_call_rhs (t);
+}
+
+
/* Returns a formal temporary variable initialized with VAL. PRE_P is as
in gimplify_expr. Only use this function if:
@@ -609,11 +681,15 @@ lookup_tmp_var (tree val, bool is_formal)
For other cases, use get_initialized_tmp_var instead. */
static tree
-internal_get_tmp_var (tree val, tree *pre_p, tree *post_p, bool is_formal)
+internal_get_tmp_var (tree val, gimple_seq *pre_p, gimple_seq *post_p,
+ bool is_formal)
{
tree t, mod;
- gimplify_expr (&val, pre_p, post_p, is_gimple_formal_tmp_rhs, fb_rvalue);
+ /* Notice that we explicitly allow VAL to be a CALL_EXPR so that we
+ can create an INIT_EXPR and convert it into a GIMPLE_CALL below. */
+ gimplify_expr (&val, pre_p, post_p, is_gimple_formal_tmp_or_call_rhs,
+ fb_rvalue);
t = lookup_tmp_var (val, is_formal);
@@ -648,21 +724,25 @@ internal_get_tmp_var (tree val, tree *pre_p, tree *post_p, bool is_formal)
/* gimplify_modify_expr might want to reduce this further. */
gimplify_and_add (mod, pre_p);
+ ggc_free (mod);
/* If we're gimplifying into ssa, gimplify_modify_expr will have
- given our temporary an ssa name. Find and return it. */
+ given our temporary an SSA name. Find and return it. */
if (gimplify_ctxp->into_ssa)
- t = TREE_OPERAND (mod, 0);
+ {
+ gimple last = gimple_seq_last_stmt (*pre_p);
+ t = gimple_get_lhs (last);
+ }
return t;
}
/* Returns a formal temporary variable initialized with VAL. PRE_P
- points to a statement list where side-effects needed to compute VAL
- should be stored. */
+ points to a sequence where side-effects needed to compute VAL should be
+ stored. */
tree
-get_formal_tmp_var (tree val, tree *pre_p)
+get_formal_tmp_var (tree val, gimple_seq *pre_p)
{
return internal_get_tmp_var (val, pre_p, NULL, true);
}
@@ -671,7 +751,7 @@ get_formal_tmp_var (tree val, tree *pre_p)
are as in gimplify_expr. */
tree
-get_initialized_tmp_var (tree val, tree *pre_p, tree *post_p)
+get_initialized_tmp_var (tree val, gimple_seq *pre_p, gimple_seq *post_p)
{
return internal_get_tmp_var (val, pre_p, post_p, false);
}
@@ -680,27 +760,23 @@ get_initialized_tmp_var (tree val, tree *pre_p, tree *post_p)
true, generate debug info for them; otherwise don't. */
void
-declare_vars (tree vars, tree scope, bool debug_info)
+declare_vars (tree vars, gimple scope, bool debug_info)
{
tree last = vars;
if (last)
{
tree temps, block;
- /* C99 mode puts the default 'return 0;' for main outside the outer
- braces. So drill down until we find an actual scope. */
- while (TREE_CODE (scope) == COMPOUND_EXPR)
- scope = TREE_OPERAND (scope, 0);
-
- gcc_assert (TREE_CODE (scope) == BIND_EXPR);
+ gcc_assert (gimple_code (scope) == GIMPLE_BIND);
temps = nreverse (last);
- block = BIND_EXPR_BLOCK (scope);
+ block = gimple_block (scope);
+ gcc_assert (!block || TREE_CODE (block) == BLOCK);
if (!block || !debug_info)
{
- TREE_CHAIN (last) = BIND_EXPR_VARS (scope);
- BIND_EXPR_VARS (scope) = temps;
+ TREE_CHAIN (last) = gimple_bind_vars (scope);
+ gimple_bind_set_vars (scope, temps);
}
else
{
@@ -712,7 +788,8 @@ declare_vars (tree vars, tree scope, bool debug_info)
BLOCK_VARS (block) = chainon (BLOCK_VARS (block), temps);
else
{
- BIND_EXPR_VARS (scope) = chainon (BIND_EXPR_VARS (scope), temps);
+ gimple_bind_set_vars (scope,
+ chainon (gimple_bind_vars (scope), temps));
BLOCK_VARS (block) = temps;
}
}
@@ -775,13 +852,34 @@ gimple_add_tmp_var (tree tmp)
else if (cfun)
record_vars (tmp);
else
- declare_vars (tmp, DECL_SAVED_TREE (current_function_decl), false);
+ {
+ gimple_seq body_seq;
+
+ /* This case is for nested functions. We need to expose the locals
+ they create. */
+ body_seq = gimple_body (current_function_decl);
+ declare_vars (tmp, gimple_seq_first_stmt (body_seq), false);
+ }
}
-/* Determines whether to assign a locus to the statement STMT. */
+/* Determines whether to assign a location to the statement GS. */
static bool
-should_carry_locus_p (const_tree stmt)
+should_carry_location_p (gimple gs)
+{
+ /* Don't emit a line note for a label. We particularly don't want to
+ emit one for the break label, since it doesn't actually correspond
+ to the beginning of the loop/switch. */
+ if (gimple_code (gs) == GIMPLE_LABEL)
+ return false;
+
+ return true;
+}
+
+/* Same, but for a tree. */
+
+static bool
+tree_should_carry_location_p (const_tree stmt)
{
/* Don't emit a line note for a label. We particularly don't want to
emit one for the break label, since it doesn't actually correspond
@@ -796,16 +894,87 @@ should_carry_locus_p (const_tree stmt)
return true;
}
+/* Return true if a location should not be emitted for this statement
+ by annotate_one_with_location. */
+
+static inline bool
+gimple_do_not_emit_location_p (gimple g)
+{
+ return gimple_plf (g, GF_PLF_1);
+}
+
+/* Mark statement G so a location will not be emitted by
+ annotate_one_with_location. */
+
+static inline void
+gimple_set_do_not_emit_location (gimple g)
+{
+ /* The PLF flags are initialized to 0 when a new tuple is created,
+ so no need to initialize it anywhere. */
+ gimple_set_plf (g, GF_PLF_1, true);
+}
+
+/* Set the location for gimple statement GS to LOCUS. */
+
static void
-annotate_one_with_locus (tree t, location_t locus)
+annotate_one_with_location (gimple gs, location_t location)
+{
+ if (!gimple_has_location (gs)
+ && !gimple_do_not_emit_location_p (gs)
+ && should_carry_location_p (gs))
+ gimple_set_location (gs, location);
+}
+
+/* Same, but for tree T. */
+
+static void
+tree_annotate_one_with_location (tree t, location_t location)
{
if (CAN_HAVE_LOCATION_P (t)
- && ! EXPR_HAS_LOCATION (t) && should_carry_locus_p (t))
- SET_EXPR_LOCATION (t, locus);
+ && ! EXPR_HAS_LOCATION (t) && tree_should_carry_location_p (t))
+ SET_EXPR_LOCATION (t, location);
+}
+
+
+/* Set LOCATION for all the statements after iterator GSI in sequence
+ SEQ. If GSI is pointing to the end of the sequence, start with the
+ first statement in SEQ. */
+
+static void
+annotate_all_with_location_after (gimple_seq seq, gimple_stmt_iterator gsi,
+ location_t location)
+{
+ if (gsi_end_p (gsi))
+ gsi = gsi_start (seq);
+ else
+ gsi_next (&gsi);
+
+ for (; !gsi_end_p (gsi); gsi_next (&gsi))
+ annotate_one_with_location (gsi_stmt (gsi), location);
+}
+
+
+/* Set the location for all the statements in a sequence STMT_P to LOCUS. */
+
+void
+annotate_all_with_location (gimple_seq stmt_p, location_t location)
+{
+ gimple_stmt_iterator i;
+
+ if (gimple_seq_empty_p (stmt_p))
+ return;
+
+ for (i = gsi_start (stmt_p); !gsi_end_p (i); gsi_next (&i))
+ {
+ gimple gs = gsi_stmt (i);
+ annotate_one_with_location (gs, location);
+ }
}
+/* Same, but for statement or statement list in *STMT_P. */
+
void
-annotate_all_with_locus (tree *stmt_p, location_t locus)
+tree_annotate_all_with_location (tree *stmt_p, location_t location)
{
tree_stmt_iterator i;
@@ -821,10 +990,11 @@ annotate_all_with_locus (tree *stmt_p, location_t locus)
gcc_assert (TREE_CODE (t) != STATEMENT_LIST
&& TREE_CODE (t) != COMPOUND_EXPR);
- annotate_one_with_locus (t, locus);
+ tree_annotate_one_with_location (t, location);
}
}
+
/* Similar to copy_tree_r() but do not copy SAVE_EXPR or TARGET_EXPR nodes.
These nodes model computations that should only be done once. If we
were to unshare something like SAVE_EXPR(i++), the gimplification
@@ -938,15 +1108,6 @@ unvisit_body (tree *body_p, tree fndecl)
unvisit_body (&DECL_SAVED_TREE (cgn->decl), cgn->decl);
}
-/* Unshare T and all the trees reached from T via TREE_CHAIN. */
-
-static void
-unshare_all_trees (tree t)
-{
- walk_tree (&t, copy_if_shared_r, NULL, NULL);
- walk_tree (&t, unmark_visited_r, NULL, NULL);
-}
-
/* Unconditionally make an unshared copy of EXPR. This is used when using
stored expressions which span multiple functions, such as BINFO_VTABLE,
as the normal unsharing process can't tell that they're shared. */
@@ -957,25 +1118,6 @@ unshare_expr (tree expr)
walk_tree (&expr, mostly_copy_tree_r, NULL, NULL);
return expr;
}
-
-/* A terser interface for building a representation of an exception
- specification. */
-
-tree
-gimple_build_eh_filter (tree body, tree allowed, tree failure)
-{
- tree t;
-
- /* FIXME should the allowed types go in TREE_TYPE? */
- t = build2 (EH_FILTER_EXPR, void_type_node, allowed, NULL_TREE);
- append_to_statement_list (failure, &EH_FILTER_FAILURE (t));
-
- t = build2 (TRY_CATCH_EXPR, void_type_node, NULL_TREE, t);
- append_to_statement_list (body, &TREE_OPERAND (t, 0));
-
- return t;
-}
-
/* WRAPPER is a code such as BIND_EXPR or CLEANUP_POINT_EXPR which can both
contain statements and have a value. Assign its value to a temporary
@@ -1042,9 +1184,8 @@ voidify_wrapper_expr (tree wrapper, tree temp)
/* The wrapper is on the RHS of an assignment that we're pushing
down. */
gcc_assert (TREE_CODE (temp) == INIT_EXPR
- || TREE_CODE (temp) == GIMPLE_MODIFY_STMT
|| TREE_CODE (temp) == MODIFY_EXPR);
- GENERIC_TREE_OPERAND (temp, 1) = *p;
+ TREE_OPERAND (temp, 1) = *p;
*p = temp;
}
else
@@ -1063,28 +1204,28 @@ voidify_wrapper_expr (tree wrapper, tree temp)
a temporary through which they communicate. */
static void
-build_stack_save_restore (tree *save, tree *restore)
+build_stack_save_restore (gimple *save, gimple *restore)
{
- tree save_call, tmp_var;
+ tree tmp_var;
- save_call =
- build_call_expr (implicit_built_in_decls[BUILT_IN_STACK_SAVE], 0);
+ *save = gimple_build_call (implicit_built_in_decls[BUILT_IN_STACK_SAVE], 0);
tmp_var = create_tmp_var (ptr_type_node, "saved_stack");
+ gimple_call_set_lhs (*save, tmp_var);
- *save = build_gimple_modify_stmt (tmp_var, save_call);
- *restore =
- build_call_expr (implicit_built_in_decls[BUILT_IN_STACK_RESTORE],
- 1, tmp_var);
+ *restore = gimple_build_call (implicit_built_in_decls[BUILT_IN_STACK_RESTORE],
+ 1, tmp_var);
}
/* Gimplify a BIND_EXPR. Just voidify and recurse. */
static enum gimplify_status
-gimplify_bind_expr (tree *expr_p, tree *pre_p)
+gimplify_bind_expr (tree *expr_p, gimple_seq *pre_p)
{
tree bind_expr = *expr_p;
bool old_save_stack = gimplify_ctxp->save_stack;
tree t;
+ gimple gimple_bind;
+ gimple_seq body;
tree temp = voidify_wrapper_expr (bind_expr, NULL);
@@ -1116,70 +1257,90 @@ gimplify_bind_expr (tree *expr_p, tree *pre_p)
DECL_GIMPLE_REG_P (t) = 1;
}
- gimple_push_bind_expr (bind_expr);
+ gimple_bind = gimple_build_bind (BIND_EXPR_VARS (bind_expr), NULL,
+ BIND_EXPR_BLOCK (bind_expr));
+ gimple_push_bind_expr (gimple_bind);
+
gimplify_ctxp->save_stack = false;
- gimplify_to_stmt_list (&BIND_EXPR_BODY (bind_expr));
+ /* Gimplify the body into the GIMPLE_BIND tuple's body. */
+ body = NULL;
+ gimplify_stmt (&BIND_EXPR_BODY (bind_expr), &body);
+ gimple_bind_set_body (gimple_bind, body);
if (gimplify_ctxp->save_stack)
{
- tree stack_save, stack_restore;
+ gimple stack_save, stack_restore, gs;
+ gimple_seq cleanup, new_body;
/* Save stack on entry and restore it on exit. Add a try_finally
block to achieve this. Note that mudflap depends on the
format of the emitted code: see mx_register_decls(). */
build_stack_save_restore (&stack_save, &stack_restore);
- t = build2 (TRY_FINALLY_EXPR, void_type_node,
- BIND_EXPR_BODY (bind_expr), NULL_TREE);
- append_to_statement_list (stack_restore, &TREE_OPERAND (t, 1));
+ cleanup = new_body = NULL;
+ gimplify_seq_add_stmt (&cleanup, stack_restore);
+ gs = gimple_build_try (gimple_bind_body (gimple_bind), cleanup,
+ GIMPLE_TRY_FINALLY);
- BIND_EXPR_BODY (bind_expr) = NULL_TREE;
- append_to_statement_list (stack_save, &BIND_EXPR_BODY (bind_expr));
- append_to_statement_list (t, &BIND_EXPR_BODY (bind_expr));
+ gimplify_seq_add_stmt (&new_body, stack_save);
+ gimplify_seq_add_stmt (&new_body, gs);
+ gimple_bind_set_body (gimple_bind, new_body);
}
gimplify_ctxp->save_stack = old_save_stack;
gimple_pop_bind_expr ();
+ gimplify_seq_add_stmt (pre_p, gimple_bind);
+
if (temp)
{
*expr_p = temp;
- append_to_statement_list (bind_expr, pre_p);
return GS_OK;
}
- else
- return GS_ALL_DONE;
+
+ *expr_p = NULL_TREE;
+ return GS_ALL_DONE;
}
/* Gimplify a RETURN_EXPR. If the expression to be returned is not a
GIMPLE value, it is assigned to a new temporary and the statement is
re-written to return the temporary.
- PRE_P points to the list where side effects that must happen before
+ PRE_P points to the sequence where side effects that must happen before
STMT should be stored. */
static enum gimplify_status
-gimplify_return_expr (tree stmt, tree *pre_p)
+gimplify_return_expr (tree stmt, gimple_seq *pre_p)
{
+ gimple ret;
tree ret_expr = TREE_OPERAND (stmt, 0);
tree result_decl, result;
- if (!ret_expr || TREE_CODE (ret_expr) == RESULT_DECL
+ if (ret_expr == error_mark_node)
+ return GS_ERROR;
+
+ if (!ret_expr
+ || TREE_CODE (ret_expr) == RESULT_DECL
|| ret_expr == error_mark_node)
- return GS_ALL_DONE;
+ {
+ gimple ret = gimple_build_return (ret_expr);
+ gimple_set_no_warning (ret, TREE_NO_WARNING (stmt));
+ gimplify_seq_add_stmt (pre_p, ret);
+ return GS_ALL_DONE;
+ }
if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl))))
result_decl = NULL_TREE;
else
{
- result_decl = GENERIC_TREE_OPERAND (ret_expr, 0);
+ result_decl = TREE_OPERAND (ret_expr, 0);
+
+ /* See through a return by reference. */
if (TREE_CODE (result_decl) == INDIRECT_REF)
- /* See through a return by reference. */
result_decl = TREE_OPERAND (result_decl, 0);
gcc_assert ((TREE_CODE (ret_expr) == MODIFY_EXPR
- || TREE_CODE (ret_expr) == GIMPLE_MODIFY_STMT
|| TREE_CODE (ret_expr) == INIT_EXPR)
&& TREE_CODE (result_decl) == RESULT_DECL);
}
@@ -1213,34 +1374,30 @@ gimplify_return_expr (tree stmt, tree *pre_p)
gimplify_ctxp->return_temp = result;
}
- /* Smash the lhs of the GIMPLE_MODIFY_STMT to the temporary we plan to use.
+ /* Smash the lhs of the MODIFY_EXPR to the temporary we plan to use.
Then gimplify the whole thing. */
if (result != result_decl)
- GENERIC_TREE_OPERAND (ret_expr, 0) = result;
+ TREE_OPERAND (ret_expr, 0) = result;
gimplify_and_add (TREE_OPERAND (stmt, 0), pre_p);
- /* If we didn't use a temporary, then the result is just the result_decl.
- Otherwise we need a simple copy. This should already be gimple. */
- if (result == result_decl)
- ret_expr = result;
- else
- ret_expr = build_gimple_modify_stmt (result_decl, result);
- TREE_OPERAND (stmt, 0) = ret_expr;
+ ret = gimple_build_return (result);
+ gimple_set_no_warning (ret, TREE_NO_WARNING (stmt));
+ gimplify_seq_add_stmt (pre_p, ret);
return GS_ALL_DONE;
}
static void
-gimplify_vla_decl (tree decl, tree *stmt_p)
+gimplify_vla_decl (tree decl, gimple_seq *seq_p)
{
/* This is a variable-sized decl. Simplify its size and mark it
for deferred expansion. Note that mudflap depends on the format
of the emitted code: see mx_register_decls(). */
tree t, addr, ptr_type;
- gimplify_one_sizepos (&DECL_SIZE (decl), stmt_p);
- gimplify_one_sizepos (&DECL_SIZE_UNIT (decl), stmt_p);
+ gimplify_one_sizepos (&DECL_SIZE (decl), seq_p);
+ gimplify_one_sizepos (&DECL_SIZE_UNIT (decl), seq_p);
/* All occurrences of this decl in final gimplified code will be
replaced by indirection. Setting DECL_VALUE_EXPR does two
@@ -1257,20 +1414,21 @@ gimplify_vla_decl (tree decl, tree *stmt_p)
t = built_in_decls[BUILT_IN_ALLOCA];
t = build_call_expr (t, 1, DECL_SIZE_UNIT (decl));
t = fold_convert (ptr_type, t);
- t = build_gimple_modify_stmt (addr, t);
+ t = build2 (MODIFY_EXPR, TREE_TYPE (addr), addr, t);
- gimplify_and_add (t, stmt_p);
+ gimplify_and_add (t, seq_p);
/* Indicate that we need to restore the stack level when the
enclosing BIND_EXPR is exited. */
gimplify_ctxp->save_stack = true;
}
+
/* Gimplifies a DECL_EXPR node *STMT_P by making any necessary allocation
and initialization explicit. */
static enum gimplify_status
-gimplify_decl_expr (tree *stmt_p)
+gimplify_decl_expr (tree *stmt_p, gimple_seq *seq_p)
{
tree stmt = *stmt_p;
tree decl = DECL_EXPR_DECL (stmt);
@@ -1283,14 +1441,14 @@ gimplify_decl_expr (tree *stmt_p)
if ((TREE_CODE (decl) == TYPE_DECL
|| TREE_CODE (decl) == VAR_DECL)
&& !TYPE_SIZES_GIMPLIFIED (TREE_TYPE (decl)))
- gimplify_type_sizes (TREE_TYPE (decl), stmt_p);
+ gimplify_type_sizes (TREE_TYPE (decl), seq_p);
if (TREE_CODE (decl) == VAR_DECL && !DECL_EXTERNAL (decl))
{
tree init = DECL_INITIAL (decl);
if (TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
- gimplify_vla_decl (decl, stmt_p);
+ gimplify_vla_decl (decl, seq_p);
if (init && init != error_mark_node)
{
@@ -1298,7 +1456,8 @@ gimplify_decl_expr (tree *stmt_p)
{
DECL_INITIAL (decl) = NULL_TREE;
init = build2 (INIT_EXPR, void_type_node, decl, init);
- gimplify_and_add (init, stmt_p);
+ gimplify_and_add (init, seq_p);
+ ggc_free (init);
}
else
/* We must still examine initializers for static variables
@@ -1323,27 +1482,49 @@ gimplify_decl_expr (tree *stmt_p)
EXIT_EXPR, we need to append a label for it to jump to. */
static enum gimplify_status
-gimplify_loop_expr (tree *expr_p, tree *pre_p)
+gimplify_loop_expr (tree *expr_p, gimple_seq *pre_p)
{
tree saved_label = gimplify_ctxp->exit_label;
- tree start_label = build1 (LABEL_EXPR, void_type_node, NULL_TREE);
- tree jump_stmt = build_and_jump (&LABEL_EXPR_LABEL (start_label));
+ tree start_label = create_artificial_label ();
- append_to_statement_list (start_label, pre_p);
+ gimplify_seq_add_stmt (pre_p, gimple_build_label (start_label));
gimplify_ctxp->exit_label = NULL_TREE;
gimplify_and_add (LOOP_EXPR_BODY (*expr_p), pre_p);
+ gimplify_seq_add_stmt (pre_p, gimple_build_goto (start_label));
+
if (gimplify_ctxp->exit_label)
+ gimplify_seq_add_stmt (pre_p, gimple_build_label (gimplify_ctxp->exit_label));
+
+ gimplify_ctxp->exit_label = saved_label;
+
+ *expr_p = NULL;
+ return GS_ALL_DONE;
+}
+
+/* Gimplifies a statement list onto a sequence. These may be created either
+ by an enlightened front-end, or by shortcut_cond_expr. */
+
+static enum gimplify_status
+gimplify_statement_list (tree *expr_p, gimple_seq *pre_p)
+{
+ tree temp = voidify_wrapper_expr (*expr_p, NULL);
+
+ tree_stmt_iterator i = tsi_start (*expr_p);
+
+ while (!tsi_end_p (i))
{
- append_to_statement_list (jump_stmt, pre_p);
- *expr_p = build1 (LABEL_EXPR, void_type_node, gimplify_ctxp->exit_label);
+ gimplify_stmt (tsi_stmt_ptr (i), pre_p);
+ tsi_delink (&i);
}
- else
- *expr_p = jump_stmt;
- gimplify_ctxp->exit_label = saved_label;
+ if (temp)
+ {
+ *expr_p = temp;
+ return GS_OK;
+ }
return GS_ALL_DONE;
}
@@ -1358,70 +1539,63 @@ compare_case_labels (const void *p1, const void *p2)
const_tree const case1 = *(const_tree const*)p1;
const_tree const case2 = *(const_tree const*)p2;
- return tree_int_cst_compare (CASE_LOW (case1), CASE_LOW (case2));
+ /* The 'default' case label always goes first. */
+ if (!CASE_LOW (case1))
+ return -1;
+ else if (!CASE_LOW (case2))
+ return 1;
+ else
+ return tree_int_cst_compare (CASE_LOW (case1), CASE_LOW (case2));
}
+
/* Sort the case labels in LABEL_VEC in place in ascending order. */
void
-sort_case_labels (tree label_vec)
+sort_case_labels (VEC(tree,heap)* label_vec)
{
- size_t len = TREE_VEC_LENGTH (label_vec);
- tree default_case = TREE_VEC_ELT (label_vec, len - 1);
-
- if (CASE_LOW (default_case))
- {
- size_t i;
-
- /* The last label in the vector should be the default case
- but it is not. */
- for (i = 0; i < len; ++i)
- {
- tree t = TREE_VEC_ELT (label_vec, i);
- if (!CASE_LOW (t))
- {
- default_case = t;
- TREE_VEC_ELT (label_vec, i) = TREE_VEC_ELT (label_vec, len - 1);
- TREE_VEC_ELT (label_vec, len - 1) = default_case;
- break;
- }
- }
- }
-
- qsort (&TREE_VEC_ELT (label_vec, 0), len - 1, sizeof (tree),
- compare_case_labels);
+ size_t len = VEC_length (tree, label_vec);
+ qsort (VEC_address (tree, label_vec), len, sizeof (tree),
+ compare_case_labels);
}
+
/* Gimplify a SWITCH_EXPR, and collect a TREE_VEC of the labels it can
branch to. */
static enum gimplify_status
-gimplify_switch_expr (tree *expr_p, tree *pre_p)
+gimplify_switch_expr (tree *expr_p, gimple_seq *pre_p)
{
tree switch_expr = *expr_p;
+ gimple_seq switch_body_seq = NULL;
enum gimplify_status ret;
- ret = gimplify_expr (&SWITCH_COND (switch_expr), pre_p, NULL,
- is_gimple_val, fb_rvalue);
+ ret = gimplify_expr (&SWITCH_COND (switch_expr), pre_p, NULL, is_gimple_val,
+ fb_rvalue);
+ if (ret == GS_ERROR || ret == GS_UNHANDLED)
+ return ret;
if (SWITCH_BODY (switch_expr))
{
- VEC(tree,heap) *labels, *saved_labels;
- tree label_vec, default_case = NULL_TREE;
+ VEC (tree,heap) *labels;
+ VEC (tree,heap) *saved_labels;
+ tree default_case = NULL_TREE;
size_t i, len;
-
+ gimple gimple_switch;
+
/* If someone can be bothered to fill in the labels, they can
be bothered to null out the body too. */
gcc_assert (!SWITCH_LABELS (switch_expr));
+ /* save old labels, get new ones from body, then restore the old
+ labels. Save all the things from the switch body to append after. */
saved_labels = gimplify_ctxp->case_labels;
gimplify_ctxp->case_labels = VEC_alloc (tree, heap, 8);
- gimplify_to_stmt_list (&SWITCH_BODY (switch_expr));
-
+ gimplify_stmt (&SWITCH_BODY (switch_expr), &switch_body_seq);
labels = gimplify_ctxp->case_labels;
gimplify_ctxp->case_labels = saved_labels;
-
+
i = 0;
while (i < VEC_length (tree, labels))
{
@@ -1451,44 +1625,39 @@ gimplify_switch_expr (tree *expr_p, tree *pre_p)
}
len = i;
- label_vec = make_tree_vec (len + 1);
- SWITCH_LABELS (*expr_p) = label_vec;
- append_to_statement_list (switch_expr, pre_p);
-
- if (! default_case)
+ if (!default_case)
{
+ gimple new_default;
+
/* If the switch has no default label, add one, so that we jump
around the switch body. */
default_case = build3 (CASE_LABEL_EXPR, void_type_node, NULL_TREE,
- NULL_TREE, create_artificial_label ());
- append_to_statement_list (SWITCH_BODY (switch_expr), pre_p);
- *expr_p = build1 (LABEL_EXPR, void_type_node,
- CASE_LABEL (default_case));
+ NULL_TREE, create_artificial_label ());
+ new_default = gimple_build_label (CASE_LABEL (default_case));
+ gimplify_seq_add_stmt (&switch_body_seq, new_default);
}
- else
- *expr_p = SWITCH_BODY (switch_expr);
-
- for (i = 0; i < len; ++i)
- TREE_VEC_ELT (label_vec, i) = VEC_index (tree, labels, i);
- TREE_VEC_ELT (label_vec, len) = default_case;
-
- VEC_free (tree, heap, labels);
- sort_case_labels (label_vec);
+ if (!VEC_empty (tree, labels))
+ sort_case_labels (labels);
- SWITCH_BODY (switch_expr) = NULL;
+ gimple_switch = gimple_build_switch_vec (SWITCH_COND (switch_expr),
+ default_case, labels);
+ gimplify_seq_add_stmt (pre_p, gimple_switch);
+ gimplify_seq_add_seq (pre_p, switch_body_seq);
+ VEC_free(tree, heap, labels);
}
else
gcc_assert (SWITCH_LABELS (switch_expr));
- return ret;
+ return GS_ALL_DONE;
}
+
static enum gimplify_status
-gimplify_case_label_expr (tree *expr_p)
+gimplify_case_label_expr (tree *expr_p, gimple_seq *pre_p)
{
- tree expr = *expr_p;
struct gimplify_ctx *ctxp;
+ gimple gimple_label;
/* Invalid OpenMP programs can play Duff's Device type games with
#pragma omp parallel. At least in the C front end, we don't
@@ -1497,8 +1666,10 @@ gimplify_case_label_expr (tree *expr_p)
if (ctxp->case_labels)
break;
- VEC_safe_push (tree, heap, ctxp->case_labels, expr);
- *expr_p = build1 (LABEL_EXPR, void_type_node, CASE_LABEL (expr));
+ gimple_label = gimple_build_label (CASE_LABEL (*expr_p));
+ VEC_safe_push (tree, heap, ctxp->case_labels, *expr_p);
+ gimplify_seq_add_stmt (pre_p, gimple_label);
+
return GS_ALL_DONE;
}
@@ -1743,7 +1914,7 @@ gimplify_var_or_parm_decl (tree *expr_p)
/* Gimplify the COMPONENT_REF, ARRAY_REF, REALPART_EXPR or IMAGPART_EXPR
- node pointed to by EXPR_P.
+ node *EXPR_P.
compound_lval
: min_lval '[' val ']'
@@ -1758,15 +1929,15 @@ gimplify_var_or_parm_decl (tree *expr_p)
union reference must be explicit, which was not always the case when we
were splitting up array and member refs.
- PRE_P points to the list where side effects that must happen before
+ PRE_P points to the sequence where side effects that must happen before
*EXPR_P should be stored.
- POST_P points to the list where side effects that must happen after
+ POST_P points to the sequence where side effects that must happen after
*EXPR_P should be stored. */
static enum gimplify_status
-gimplify_compound_lval (tree *expr_p, tree *pre_p,
- tree *post_p, fallback_t fallback)
+gimplify_compound_lval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
+ fallback_t fallback)
{
tree *p;
VEC(tree,heap) *stack;
@@ -1821,14 +1992,15 @@ gimplify_compound_lval (tree *expr_p, tree *pre_p,
/* Gimplify the low bound and element type size and put them into
the ARRAY_REF. If these values are set, they have already been
gimplified. */
- if (!TREE_OPERAND (t, 2))
+ if (TREE_OPERAND (t, 2) == NULL_TREE)
{
tree low = unshare_expr (array_ref_low_bound (t));
if (!is_gimple_min_invariant (low))
{
- TREE_OPERAND (t, 2) = low;
- tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, post_p,
- is_gimple_formal_tmp_reg, fb_rvalue);
+ TREE_OPERAND (t, 2) = low;
+ tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p,
+ post_p, is_gimple_formal_tmp_reg,
+ fb_rvalue);
ret = MIN (ret, tret);
}
}
@@ -1845,9 +2017,10 @@ gimplify_compound_lval (tree *expr_p, tree *pre_p,
if (!is_gimple_min_invariant (elmt_size))
{
- TREE_OPERAND (t, 3) = elmt_size;
- tret = gimplify_expr (&TREE_OPERAND (t, 3), pre_p, post_p,
- is_gimple_formal_tmp_reg, fb_rvalue);
+ TREE_OPERAND (t, 3) = elmt_size;
+ tret = gimplify_expr (&TREE_OPERAND (t, 3), pre_p,
+ post_p, is_gimple_formal_tmp_reg,
+ fb_rvalue);
ret = MIN (ret, tret);
}
}
@@ -1867,9 +2040,10 @@ gimplify_compound_lval (tree *expr_p, tree *pre_p,
if (!is_gimple_min_invariant (offset))
{
- TREE_OPERAND (t, 2) = offset;
- tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, post_p,
- is_gimple_formal_tmp_reg, fb_rvalue);
+ TREE_OPERAND (t, 2) = offset;
+ tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p,
+ post_p, is_gimple_formal_tmp_reg,
+ fb_rvalue);
ret = MIN (ret, tret);
}
}
@@ -1919,15 +2093,13 @@ gimplify_compound_lval (tree *expr_p, tree *pre_p,
STRIP_USELESS_TYPE_CONVERSION (TREE_OPERAND (t, 0));
- /* The innermost expression P may have originally had TREE_SIDE_EFFECTS
- set which would have caused all the outer expressions in EXPR_P
- leading to P to also have had TREE_SIDE_EFFECTS set. */
+ /* The innermost expression P may have originally had
+ TREE_SIDE_EFFECTS set which would have caused all the outer
+ expressions in *EXPR_P leading to P to also have had
+ TREE_SIDE_EFFECTS set. */
recalculate_side_effects (t);
}
- tret = gimplify_expr (p, pre_p, post_p, is_gimple_min_lval, fallback);
- ret = MIN (ret, tret);
-
/* If the outermost expression is a COMPONENT_REF, canonicalize its type. */
if ((fallback & fb_rvalue) && TREE_CODE (*expr_p) == COMPONENT_REF)
{
@@ -1953,11 +2125,12 @@ gimplify_compound_lval (tree *expr_p, tree *pre_p,
in another expression. */
static enum gimplify_status
-gimplify_self_mod_expr (tree *expr_p, tree *pre_p, tree *post_p,
+gimplify_self_mod_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
bool want_value)
{
enum tree_code code;
- tree lhs, lvalue, rhs, t1, post = NULL, *orig_post_p = post_p;
+ tree lhs, lvalue, rhs, t1;
+ gimple_seq post = NULL, *orig_post_p = post_p;
bool postfix;
enum tree_code arith_code;
enum gimplify_status ret;
@@ -2014,22 +2187,22 @@ gimplify_self_mod_expr (tree *expr_p, tree *pre_p, tree *post_p,
}
t1 = build2 (arith_code, TREE_TYPE (*expr_p), lhs, rhs);
- t1 = build_gimple_modify_stmt (lvalue, t1);
if (postfix)
{
- gimplify_and_add (t1, orig_post_p);
- append_to_statement_list (post, orig_post_p);
+ gimplify_assign (lvalue, t1, orig_post_p);
+ gimplify_seq_add_seq (orig_post_p, post);
*expr_p = lhs;
return GS_ALL_DONE;
}
else
{
- *expr_p = t1;
+ *expr_p = build2 (MODIFY_EXPR, TREE_TYPE (lvalue), lvalue, t1);
return GS_OK;
}
}
+
/* If *EXPR_P has a variable sized type, wrap it in a WITH_SIZE_EXPR. */
static void
@@ -2056,10 +2229,12 @@ maybe_with_size_expr (tree *expr_p)
*expr_p = build2 (WITH_SIZE_EXPR, type, expr, size);
}
-/* Subroutine of gimplify_call_expr: Gimplify a single argument. */
+
+/* Helper for gimplify_call_expr. Gimplify a single argument *ARG_P
+ Store any side-effects in PRE_P. */
static enum gimplify_status
-gimplify_arg (tree *expr_p, tree *pre_p)
+gimplify_arg (tree *arg_p, gimple_seq *pre_p)
{
bool (*test) (tree);
fallback_t fb;
@@ -2069,31 +2244,33 @@ gimplify_arg (tree *expr_p, tree *pre_p)
aggregates into temporaries only to copy the temporaries to
the argument list. Make optimizers happy by pulling out to
temporaries those types that fit in registers. */
- if (is_gimple_reg_type (TREE_TYPE (*expr_p)))
+ if (is_gimple_reg_type (TREE_TYPE (*arg_p)))
test = is_gimple_val, fb = fb_rvalue;
else
test = is_gimple_lvalue, fb = fb_either;
/* If this is a variable sized type, we must remember the size. */
- maybe_with_size_expr (expr_p);
+ maybe_with_size_expr (arg_p);
/* There is a sequence point before a function call. Side effects in
the argument list must occur before the actual call. So, when
gimplifying arguments, force gimplify_expr to use an internal
post queue which is then appended to the end of PRE_P. */
- return gimplify_expr (expr_p, pre_p, NULL, test, fb);
+ return gimplify_expr (arg_p, pre_p, NULL, test, fb);
}
-/* Gimplify the CALL_EXPR node pointed to by EXPR_P. PRE_P points to the
- list where side effects that must happen before *EXPR_P should be stored.
+
+/* Gimplify the CALL_EXPR node *EXPR_P into the GIMPLE sequence PRE_P.
WANT_VALUE is true if the result of the call is desired. */
static enum gimplify_status
-gimplify_call_expr (tree *expr_p, tree *pre_p, bool want_value)
+gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
{
- tree decl, parms, p;
+ tree fndecl, parms, p;
enum gimplify_status ret;
int i, nargs;
+ gimple call;
+ bool builtin_va_start_p = FALSE;
gcc_assert (TREE_CODE (*expr_p) == CALL_EXPR);
@@ -2114,8 +2291,8 @@ gimplify_call_expr (tree *expr_p, tree *pre_p, bool want_value)
we gimplify the CALL_EXPR. At this time we do not manage to
transform all calls in the same manner as the expanders do, but
we do transform most of them. */
- decl = get_callee_fndecl (*expr_p);
- if (decl && DECL_BUILT_IN (decl))
+ fndecl = get_callee_fndecl (*expr_p);
+ if (fndecl && DECL_BUILT_IN (fndecl))
{
tree new = fold_call_expr (*expr_p, !want_value);
@@ -2128,9 +2305,10 @@ gimplify_call_expr (tree *expr_p, tree *pre_p, bool want_value)
return GS_OK;
}
- if (DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL
- && DECL_FUNCTION_CODE (decl) == BUILT_IN_VA_START)
+ if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
+ && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_VA_START)
{
+ builtin_va_start_p = TRUE;
if (call_expr_nargs (*expr_p) < 2)
{
error ("too few arguments to function %<va_start%>");
@@ -2143,9 +2321,6 @@ gimplify_call_expr (tree *expr_p, tree *pre_p, bool want_value)
*expr_p = build_empty_stmt ();
return GS_OK;
}
- /* Avoid gimplifying the second argument to va_start, which needs
- to be the plain PARM_DECL. */
- return gimplify_arg (&CALL_EXPR_ARG (*expr_p, 0), pre_p);
}
}
@@ -2158,19 +2333,20 @@ gimplify_call_expr (tree *expr_p, tree *pre_p, bool want_value)
nargs = call_expr_nargs (*expr_p);
/* Get argument types for verification. */
- decl = get_callee_fndecl (*expr_p);
+ fndecl = get_callee_fndecl (*expr_p);
parms = NULL_TREE;
- if (decl)
- parms = TYPE_ARG_TYPES (TREE_TYPE (decl));
+ if (fndecl)
+ parms = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
else if (POINTER_TYPE_P (TREE_TYPE (CALL_EXPR_FN (*expr_p))))
parms = TYPE_ARG_TYPES (TREE_TYPE (TREE_TYPE (CALL_EXPR_FN (*expr_p))));
/* Verify if the type of the argument matches that of the function
declaration. If we cannot verify this or there is a mismatch,
mark the call expression so it doesn't get inlined later. */
- if (decl && DECL_ARGUMENTS (decl))
+ if (fndecl && DECL_ARGUMENTS (fndecl))
{
- for (i = 0, p = DECL_ARGUMENTS (decl); i < nargs;
+ for (i = 0, p = DECL_ARGUMENTS (fndecl);
+ i < nargs;
i++, p = TREE_CHAIN (p))
{
/* We cannot distinguish a varargs function from the case
@@ -2235,34 +2411,42 @@ gimplify_call_expr (tree *expr_p, tree *pre_p, bool want_value)
--nargs;
*expr_p = build_call_array (TREE_TYPE (call), CALL_EXPR_FN (call),
nargs, CALL_EXPR_ARGP (call));
- /* Copy all CALL_EXPR flags, locus and block, except
+
+ /* Copy all CALL_EXPR flags, location and block, except
CALL_EXPR_VA_ARG_PACK flag. */
CALL_EXPR_STATIC_CHAIN (*expr_p) = CALL_EXPR_STATIC_CHAIN (call);
CALL_EXPR_TAILCALL (*expr_p) = CALL_EXPR_TAILCALL (call);
CALL_EXPR_RETURN_SLOT_OPT (*expr_p)
= CALL_EXPR_RETURN_SLOT_OPT (call);
CALL_FROM_THUNK_P (*expr_p) = CALL_FROM_THUNK_P (call);
- CALL_CANNOT_INLINE_P (*expr_p)
- = CALL_CANNOT_INLINE_P (call);
- TREE_NOTHROW (*expr_p) = TREE_NOTHROW (call);
+ CALL_CANNOT_INLINE_P (*expr_p) = CALL_CANNOT_INLINE_P (call);
SET_EXPR_LOCUS (*expr_p, EXPR_LOCUS (call));
TREE_BLOCK (*expr_p) = TREE_BLOCK (call);
+
/* Set CALL_EXPR_VA_ARG_PACK. */
CALL_EXPR_VA_ARG_PACK (*expr_p) = 1;
}
}
/* Finally, gimplify the function arguments. */
- for (i = (PUSH_ARGS_REVERSED ? nargs - 1 : 0);
- PUSH_ARGS_REVERSED ? i >= 0 : i < nargs;
- PUSH_ARGS_REVERSED ? i-- : i++)
+ if (nargs > 0)
{
- enum gimplify_status t;
+ for (i = (PUSH_ARGS_REVERSED ? nargs - 1 : 0);
+ PUSH_ARGS_REVERSED ? i >= 0 : i < nargs;
+ PUSH_ARGS_REVERSED ? i-- : i++)
+ {
+ enum gimplify_status t;
- t = gimplify_arg (&CALL_EXPR_ARG (*expr_p, i), pre_p);
+ /* Avoid gimplifying the second argument to va_start, which needs to
+ be the plain PARM_DECL. */
+ if ((i != 1) || !builtin_va_start_p)
+ {
+ t = gimplify_arg (&CALL_EXPR_ARG (*expr_p, i), pre_p);
- if (t == GS_ERROR)
- ret = GS_ERROR;
+ if (t == GS_ERROR)
+ ret = GS_ERROR;
+ }
+ }
}
/* Try this again in case gimplification exposed something. */
@@ -2279,6 +2463,11 @@ gimplify_call_expr (tree *expr_p, tree *pre_p, bool want_value)
return GS_OK;
}
}
+ else
+ {
+ *expr_p = NULL_TREE;
+ return GS_ERROR;
+ }
/* If the function is "const" or "pure", then clear TREE_SIDE_EFFECTS on its
decl. This allows us to eliminate redundant or useless
@@ -2291,6 +2480,24 @@ gimplify_call_expr (tree *expr_p, tree *pre_p, bool want_value)
&& !(flags & (ECF_LOOPING_CONST_OR_PURE)))
TREE_SIDE_EFFECTS (*expr_p) = 0;
}
+
+ /* If the value is not needed by the caller, emit a new GIMPLE_CALL
+ and clear *EXPR_P. Otherwise, leave *EXPR_P in its gimplified
+ form and delegate the creation of a GIMPLE_CALL to
+ gimplify_modify_expr. This is always possible because when
+ WANT_VALUE is true, the caller wants the result of this call into
+ a temporary, which means that we will emit an INIT_EXPR in
+ internal_get_tmp_var which will then be handled by
+ gimplify_modify_expr. */
+ if (!want_value)
+ {
+ /* The CALL_EXPR in *EXPR_P is already in GIMPLE form, so all we
+ have to do is replicate it as a GIMPLE_CALL tuple. */
+ call = gimple_build_call_from_tree (*expr_p);
+ gimplify_seq_add_stmt (pre_p, call);
+ *expr_p = NULL_TREE;
+ }
+
return ret;
}
@@ -2379,6 +2586,10 @@ shortcut_cond_r (tree pred, tree *true_label_p, tree *false_label_p)
return expr;
}
+/* Given a conditional expression EXPR with short-circuit boolean
+ predicates using TRUTH_ANDIF_EXPR or TRUTH_ORIF_EXPR, break the
+ predicate appart into the equivalent sequence of conditionals. */
+
static tree
shortcut_cond_expr (tree expr)
{
@@ -2405,6 +2616,7 @@ shortcut_cond_expr (tree expr)
expr = build3 (COND_EXPR, void_type_node, pred, then_, NULL_TREE);
}
}
+
if (!then_se)
{
/* If there is no 'then', turn
@@ -2573,7 +2785,7 @@ gimple_boolify (tree expr)
its operands. New statements are inserted to PRE_P. */
static enum gimplify_status
-gimplify_pure_cond_expr (tree *expr_p, tree *pre_p)
+gimplify_pure_cond_expr (tree *expr_p, gimple_seq *pre_p)
{
tree expr = *expr_p, cond;
enum gimplify_status ret, tret;
@@ -2588,8 +2800,7 @@ gimplify_pure_cond_expr (tree *expr_p, tree *pre_p)
TREE_SET_CODE (cond, TRUTH_AND_EXPR);
else if (code == TRUTH_ORIF_EXPR)
TREE_SET_CODE (cond, TRUTH_OR_EXPR);
- ret = gimplify_expr (&cond, pre_p, NULL,
- is_gimple_condexpr, fb_rvalue);
+ ret = gimplify_expr (&cond, pre_p, NULL, is_gimple_condexpr, fb_rvalue);
COND_EXPR_COND (*expr_p) = cond;
tret = gimplify_expr (&COND_EXPR_THEN (expr), pre_p, NULL,
@@ -2635,17 +2846,20 @@ generic_expr_could_trap_p (tree expr)
The second form is used when *EXPR_P is of type void.
- TARGET is the tree for T1 above.
-
PRE_P points to the list where side effects that must happen before
*EXPR_P should be stored. */
static enum gimplify_status
-gimplify_cond_expr (tree *expr_p, tree *pre_p, fallback_t fallback)
+gimplify_cond_expr (tree *expr_p, gimple_seq *pre_p, fallback_t fallback)
{
tree expr = *expr_p;
- tree tmp, tmp2, type;
+ tree tmp, type, arm1, arm2;
enum gimplify_status ret;
+ tree label_true, label_false, label_cont;
+ bool have_then_clause_p, have_else_clause_p;
+ gimple gimple_cond;
+ enum tree_code pred_code;
+ gimple_seq seq = NULL;
type = TREE_TYPE (expr);
@@ -2670,7 +2884,7 @@ gimplify_cond_expr (tree *expr_p, tree *pre_p, fallback_t fallback)
&& !generic_expr_could_trap_p (TREE_OPERAND (*expr_p, 2)))
return gimplify_pure_cond_expr (expr_p, pre_p);
- result = tmp2 = tmp = create_tmp_var (TREE_TYPE (expr), "iftmp");
+ result = tmp = create_tmp_var (TREE_TYPE (expr), "iftmp");
ret = GS_ALL_DONE;
}
else
@@ -2685,34 +2899,33 @@ gimplify_cond_expr (tree *expr_p, tree *pre_p, fallback_t fallback)
TREE_OPERAND (expr, 2) =
build_fold_addr_expr (TREE_OPERAND (expr, 2));
- tmp2 = tmp = create_tmp_var (type, "iftmp");
+ tmp = create_tmp_var (type, "iftmp");
expr = build3 (COND_EXPR, void_type_node, TREE_OPERAND (expr, 0),
TREE_OPERAND (expr, 1), TREE_OPERAND (expr, 2));
result = build_fold_indirect_ref (tmp);
- ret = GS_ALL_DONE;
}
/* Build the then clause, 't1 = a;'. But don't build an assignment
if this branch is void; in C++ it can be, if it's a throw. */
if (TREE_TYPE (TREE_OPERAND (expr, 1)) != void_type_node)
TREE_OPERAND (expr, 1)
- = build_gimple_modify_stmt (tmp, TREE_OPERAND (expr, 1));
+ = build2 (MODIFY_EXPR, TREE_TYPE (tmp), tmp, TREE_OPERAND (expr, 1));
/* Build the else clause, 't1 = b;'. */
if (TREE_TYPE (TREE_OPERAND (expr, 2)) != void_type_node)
TREE_OPERAND (expr, 2)
- = build_gimple_modify_stmt (tmp2, TREE_OPERAND (expr, 2));
+ = build2 (MODIFY_EXPR, TREE_TYPE (tmp), tmp, TREE_OPERAND (expr, 2));
TREE_TYPE (expr) = void_type_node;
recalculate_side_effects (expr);
/* Move the COND_EXPR to the prequeue. */
- gimplify_and_add (expr, pre_p);
+ gimplify_stmt (&expr, pre_p);
*expr_p = result;
- return ret;
+ return GS_ALL_DONE;
}
/* Make sure the condition has BOOLEAN_TYPE. */
@@ -2733,45 +2946,131 @@ gimplify_cond_expr (tree *expr_p, tree *pre_p, fallback_t fallback)
wrapped in a TRY_FINALLY_EXPR. To prevent that, we need to
set up a conditional context. */
gimple_push_condition ();
- gimplify_stmt (expr_p);
+ gimplify_stmt (expr_p, &seq);
gimple_pop_condition (pre_p);
+ gimple_seq_add_seq (pre_p, seq);
return GS_ALL_DONE;
}
}
/* Now do the normal gimplification. */
- ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, NULL,
- is_gimple_condexpr, fb_rvalue);
+
+ /* Gimplify condition. */
+ ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, NULL, is_gimple_condexpr,
+ fb_rvalue);
+ if (ret == GS_ERROR)
+ return GS_ERROR;
+ gcc_assert (TREE_OPERAND (expr, 0) != NULL_TREE);
gimple_push_condition ();
- gimplify_to_stmt_list (&TREE_OPERAND (expr, 1));
- gimplify_to_stmt_list (&TREE_OPERAND (expr, 2));
- recalculate_side_effects (expr);
+ have_then_clause_p = have_else_clause_p = false;
+ if (TREE_OPERAND (expr, 1) != NULL
+ && TREE_CODE (TREE_OPERAND (expr, 1)) == GOTO_EXPR
+ && TREE_CODE (GOTO_DESTINATION (TREE_OPERAND (expr, 1))) == LABEL_DECL
+ && (DECL_CONTEXT (GOTO_DESTINATION (TREE_OPERAND (expr, 1)))
+ == current_function_decl)
+ /* For -O0 avoid this optimization if the COND_EXPR and GOTO_EXPR
+ have different locations, otherwise we end up with incorrect
+ location information on the branches. */
+ && (optimize
+ || !EXPR_HAS_LOCATION (expr)
+ || !EXPR_HAS_LOCATION (TREE_OPERAND (expr, 1))
+ || EXPR_LOCATION (expr) == EXPR_LOCATION (TREE_OPERAND (expr, 1))))
+ {
+ label_true = GOTO_DESTINATION (TREE_OPERAND (expr, 1));
+ have_then_clause_p = true;
+ }
+ else
+ label_true = create_artificial_label ();
+ if (TREE_OPERAND (expr, 2) != NULL
+ && TREE_CODE (TREE_OPERAND (expr, 2)) == GOTO_EXPR
+ && TREE_CODE (GOTO_DESTINATION (TREE_OPERAND (expr, 2))) == LABEL_DECL
+ && (DECL_CONTEXT (GOTO_DESTINATION (TREE_OPERAND (expr, 2)))
+ == current_function_decl)
+ /* For -O0 avoid this optimization if the COND_EXPR and GOTO_EXPR
+ have different locations, otherwise we end up with incorrect
+ location information on the branches. */
+ && (optimize
+ || !EXPR_HAS_LOCATION (expr)
+ || !EXPR_HAS_LOCATION (TREE_OPERAND (expr, 2))
+ || EXPR_LOCATION (expr) == EXPR_LOCATION (TREE_OPERAND (expr, 2))))
+ {
+ label_false = GOTO_DESTINATION (TREE_OPERAND (expr, 2));
+ have_else_clause_p = true;
+ }
+ else
+ label_false = create_artificial_label ();
+
+ gimple_cond_get_ops_from_tree (COND_EXPR_COND (expr), &pred_code, &arm1,
+ &arm2);
+
+ gimple_cond = gimple_build_cond (pred_code, arm1, arm2, label_true,
+ label_false);
+
+ gimplify_seq_add_stmt (&seq, gimple_cond);
+ label_cont = NULL_TREE;
+ if (!have_then_clause_p)
+ {
+ /* For if (...) {} else { code; } put label_true after
+ the else block. */
+ if (TREE_OPERAND (expr, 1) == NULL_TREE
+ && !have_else_clause_p
+ && TREE_OPERAND (expr, 2) != NULL_TREE)
+ label_cont = label_true;
+ else
+ {
+ gimplify_seq_add_stmt (&seq, gimple_build_label (label_true));
+ have_then_clause_p = gimplify_stmt (&TREE_OPERAND (expr, 1), &seq);
+ /* For if (...) { code; } else {} or
+ if (...) { code; } else goto label; or
+ if (...) { code; return; } else { ... }
+ label_cont isn't needed. */
+ if (!have_else_clause_p
+ && TREE_OPERAND (expr, 2) != NULL_TREE
+ && gimple_seq_may_fallthru (seq))
+ {
+ gimple g;
+ label_cont = create_artificial_label ();
+
+ g = gimple_build_goto (label_cont);
+
+ /* GIMPLE_COND's are very low level; they have embedded
+ gotos. This particular embedded goto should not be marked
+ with the location of the original COND_EXPR, as it would
+ correspond to the COND_EXPR's condition, not the ELSE or the
+ THEN arms. To avoid marking it with the wrong location, flag
+ it as "no location". */
+ gimple_set_do_not_emit_location (g);
+
+ gimplify_seq_add_stmt (&seq, g);
+ }
+ }
+ }
+ if (!have_else_clause_p)
+ {
+ gimplify_seq_add_stmt (&seq, gimple_build_label (label_false));
+ have_else_clause_p = gimplify_stmt (&TREE_OPERAND (expr, 2), &seq);
+ }
+ if (label_cont)
+ gimplify_seq_add_stmt (&seq, gimple_build_label (label_cont));
gimple_pop_condition (pre_p);
+ gimple_seq_add_seq (pre_p, seq);
if (ret == GS_ERROR)
- ;
- else if (TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1)))
+ ; /* Do nothing. */
+ else if (have_then_clause_p || have_else_clause_p)
ret = GS_ALL_DONE;
- else if (TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 2)))
- /* Rewrite "if (a); else b" to "if (!a) b" */
+ else
{
- TREE_OPERAND (expr, 0) = invert_truthvalue (TREE_OPERAND (expr, 0));
- ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, NULL,
- is_gimple_condexpr, fb_rvalue);
-
- tmp = TREE_OPERAND (expr, 1);
- TREE_OPERAND (expr, 1) = TREE_OPERAND (expr, 2);
- TREE_OPERAND (expr, 2) = tmp;
+ /* Both arms are empty; replace the COND_EXPR with its predicate. */
+ expr = TREE_OPERAND (expr, 0);
+ gimplify_stmt (&expr, pre_p);
}
- else
- /* Both arms are empty; replace the COND_EXPR with its predicate. */
- expr = TREE_OPERAND (expr, 0);
- *expr_p = expr;
+ *expr_p = NULL;
return ret;
}
@@ -2779,27 +3078,39 @@ gimplify_cond_expr (tree *expr_p, tree *pre_p, fallback_t fallback)
a call to __builtin_memcpy. */
static enum gimplify_status
-gimplify_modify_expr_to_memcpy (tree *expr_p, tree size, bool want_value)
+gimplify_modify_expr_to_memcpy (tree *expr_p, tree size, bool want_value,
+ gimple_seq *seq_p)
{
tree t, to, to_ptr, from, from_ptr;
+ gimple gs;
- to = GENERIC_TREE_OPERAND (*expr_p, 0);
- from = GENERIC_TREE_OPERAND (*expr_p, 1);
+ to = TREE_OPERAND (*expr_p, 0);
+ from = TREE_OPERAND (*expr_p, 1);
from_ptr = build_fold_addr_expr (from);
+ gimplify_arg (&from_ptr, seq_p);
to_ptr = build_fold_addr_expr (to);
+ gimplify_arg (&to_ptr, seq_p);
+
t = implicit_built_in_decls[BUILT_IN_MEMCPY];
- t = build_call_expr (t, 3, to_ptr, from_ptr, size);
+
+ gs = gimple_build_call (t, 3, to_ptr, from_ptr, size);
if (want_value)
{
- t = build1 (NOP_EXPR, TREE_TYPE (to_ptr), t);
- t = build1 (INDIRECT_REF, TREE_TYPE (to), t);
+ /* tmp = memcpy() */
+ t = create_tmp_var (TREE_TYPE (to_ptr), NULL);
+ gimple_call_set_lhs (gs, t);
+ gimplify_seq_add_stmt (seq_p, gs);
+
+ *expr_p = build1 (INDIRECT_REF, TREE_TYPE (to), t);
+ return GS_ALL_DONE;
}
- *expr_p = t;
- return GS_OK;
+ gimplify_seq_add_stmt (seq_p, gs);
+ *expr_p = NULL;
+ return GS_ALL_DONE;
}
/* A subroutine of gimplify_modify_expr. Replace a MODIFY_EXPR with
@@ -2807,14 +3118,16 @@ gimplify_modify_expr_to_memcpy (tree *expr_p, tree size, bool want_value)
a CONSTRUCTOR with an empty element list. */
static enum gimplify_status
-gimplify_modify_expr_to_memset (tree *expr_p, tree size, bool want_value)
+gimplify_modify_expr_to_memset (tree *expr_p, tree size, bool want_value,
+ gimple_seq *seq_p)
{
tree t, from, to, to_ptr;
+ gimple gs;
/* Assert our assumptions, to abort instead of producing wrong code
silently if they are not met. Beware that the RHS CONSTRUCTOR might
not be immediately exposed. */
- from = GENERIC_TREE_OPERAND (*expr_p, 1);
+ from = TREE_OPERAND (*expr_p, 1);
if (TREE_CODE (from) == WITH_SIZE_EXPR)
from = TREE_OPERAND (from, 0);
@@ -2822,20 +3135,28 @@ gimplify_modify_expr_to_memset (tree *expr_p, tree size, bool want_value)
&& VEC_empty (constructor_elt, CONSTRUCTOR_ELTS (from)));
/* Now proceed. */
- to = GENERIC_TREE_OPERAND (*expr_p, 0);
+ to = TREE_OPERAND (*expr_p, 0);
to_ptr = build_fold_addr_expr (to);
+ gimplify_arg (&to_ptr, seq_p);
t = implicit_built_in_decls[BUILT_IN_MEMSET];
- t = build_call_expr (t, 3, to_ptr, integer_zero_node, size);
+
+ gs = gimple_build_call (t, 3, to_ptr, integer_zero_node, size);
if (want_value)
{
- t = build1 (NOP_EXPR, TREE_TYPE (to_ptr), t);
- t = build1 (INDIRECT_REF, TREE_TYPE (to), t);
+ /* tmp = memset() */
+ t = create_tmp_var (TREE_TYPE (to_ptr), NULL);
+ gimple_call_set_lhs (gs, t);
+ gimplify_seq_add_stmt (seq_p, gs);
+
+ *expr_p = build1 (INDIRECT_REF, TREE_TYPE (to), t);
+ return GS_ALL_DONE;
}
- *expr_p = t;
- return GS_OK;
+ gimplify_seq_add_stmt (seq_p, gs);
+ *expr_p = NULL;
+ return GS_ALL_DONE;
}
/* A subroutine of gimplify_init_ctor_preeval. Called via walk_tree,
@@ -2891,12 +3212,12 @@ gimplify_init_ctor_preeval_1 (tree *tp, int *walk_subtrees, void *xdata)
return NULL;
}
-/* A subroutine of gimplify_init_constructor. Pre-evaluate *EXPR_P,
+/* A subroutine of gimplify_init_constructor. Pre-evaluate EXPR,
force values that overlap with the lhs (as described by *DATA)
into temporaries. */
static void
-gimplify_init_ctor_preeval (tree *expr_p, tree *pre_p, tree *post_p,
+gimplify_init_ctor_preeval (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
struct gimplify_init_ctor_preeval_data *data)
{
enum gimplify_status one;
@@ -2923,6 +3244,7 @@ gimplify_init_ctor_preeval (tree *expr_p, tree *pre_p, tree *post_p,
for (ix = 0; VEC_iterate (constructor_elt, v, ix, ce); ix++)
gimplify_init_ctor_preeval (&ce->value, pre_p, post_p, data);
+
return;
}
@@ -2930,7 +3252,7 @@ gimplify_init_ctor_preeval (tree *expr_p, tree *pre_p, tree *post_p,
maybe_with_size_expr (expr_p);
/* Gimplify the constructor element to something appropriate for the rhs
- of a MODIFY_EXPR. Given that we know the lhs is an aggregate, we know
+ of a MODIFY_EXPR. Given that we know the LHS is an aggregate, we know
the gimplifier will consider this a store to memory. Doing this
gimplification now means that we won't have to deal with complicated
language-specific trees, nor trees like SAVE_EXPR that can induce
@@ -2981,29 +3303,27 @@ gimplify_init_ctor_preeval (tree *expr_p, tree *pre_p, tree *post_p,
already been taken care of for us, in gimplify_init_ctor_preeval(). */
static void gimplify_init_ctor_eval (tree, VEC(constructor_elt,gc) *,
- tree *, bool);
+ gimple_seq *, bool);
static void
gimplify_init_ctor_eval_range (tree object, tree lower, tree upper,
tree value, tree array_elt_type,
- tree *pre_p, bool cleared)
+ gimple_seq *pre_p, bool cleared)
{
- tree loop_entry_label, loop_exit_label;
+ tree loop_entry_label, loop_exit_label, fall_thru_label;
tree var, var_type, cref, tmp;
loop_entry_label = create_artificial_label ();
loop_exit_label = create_artificial_label ();
+ fall_thru_label = create_artificial_label ();
/* Create and initialize the index variable. */
var_type = TREE_TYPE (upper);
var = create_tmp_var (var_type, NULL);
- append_to_statement_list (build_gimple_modify_stmt (var, lower), pre_p);
+ gimplify_seq_add_stmt (pre_p, gimple_build_assign (var, lower));
/* Add the loop entry label. */
- append_to_statement_list (build1 (LABEL_EXPR,
- void_type_node,
- loop_entry_label),
- pre_p);
+ gimplify_seq_add_stmt (pre_p, gimple_build_label (loop_entry_label));
/* Build the reference. */
cref = build4 (ARRAY_REF, array_elt_type, unshare_expr (object),
@@ -3018,34 +3338,25 @@ gimplify_init_ctor_eval_range (tree object, tree lower, tree upper,
gimplify_init_ctor_eval (cref, CONSTRUCTOR_ELTS (value),
pre_p, cleared);
else
- append_to_statement_list (build_gimple_modify_stmt (cref, value), pre_p);
+ gimplify_seq_add_stmt (pre_p, gimple_build_assign (cref, value));
/* We exit the loop when the index var is equal to the upper bound. */
- gimplify_and_add (build3 (COND_EXPR, void_type_node,
- build2 (EQ_EXPR, boolean_type_node,
- var, upper),
- build1 (GOTO_EXPR,
- void_type_node,
- loop_exit_label),
- NULL_TREE),
- pre_p);
+ gimplify_seq_add_stmt (pre_p,
+ gimple_build_cond (EQ_EXPR, var, upper,
+ loop_exit_label, fall_thru_label));
+
+ gimplify_seq_add_stmt (pre_p, gimple_build_label (fall_thru_label));
/* Otherwise, increment the index var... */
tmp = build2 (PLUS_EXPR, var_type, var,
fold_convert (var_type, integer_one_node));
- append_to_statement_list (build_gimple_modify_stmt (var, tmp), pre_p);
+ gimplify_seq_add_stmt (pre_p, gimple_build_assign (var, tmp));
/* ...and jump back to the loop entry. */
- append_to_statement_list (build1 (GOTO_EXPR,
- void_type_node,
- loop_entry_label),
- pre_p);
+ gimplify_seq_add_stmt (pre_p, gimple_build_goto (loop_entry_label));
/* Add the loop exit label. */
- append_to_statement_list (build1 (LABEL_EXPR,
- void_type_node,
- loop_exit_label),
- pre_p);
+ gimplify_seq_add_stmt (pre_p, gimple_build_label (loop_exit_label));
}
/* Return true if FDECL is accessing a field that is zero sized. */
@@ -3078,7 +3389,7 @@ zero_sized_type (const_tree type)
static void
gimplify_init_ctor_eval (tree object, VEC(constructor_elt,gc) *elts,
- tree *pre_p, bool cleared)
+ gimple_seq *pre_p, bool cleared)
{
tree array_elt_type = NULL;
unsigned HOST_WIDE_INT ix;
@@ -3089,7 +3400,7 @@ gimplify_init_ctor_eval (tree object, VEC(constructor_elt,gc) *elts,
FOR_EACH_CONSTRUCTOR_ELT (elts, ix, purpose, value)
{
- tree cref, init;
+ tree cref;
/* NULL values are created above for gimplification errors. */
if (value == NULL)
@@ -3151,12 +3462,28 @@ gimplify_init_ctor_eval (tree object, VEC(constructor_elt,gc) *elts,
pre_p, cleared);
else
{
- init = build2 (INIT_EXPR, TREE_TYPE (cref), cref, value);
+ tree init = build2 (INIT_EXPR, TREE_TYPE (cref), cref, value);
gimplify_and_add (init, pre_p);
+ ggc_free (init);
}
}
}
+
+/* Returns the appropriate RHS predicate for this LHS. */
+
+gimple_predicate
+rhs_predicate_for (tree lhs)
+{
+ if (is_gimple_formal_tmp_var (lhs))
+ return is_gimple_formal_tmp_or_call_rhs;
+ else if (is_gimple_reg (lhs))
+ return is_gimple_reg_or_call_rhs;
+ else
+ return is_gimple_mem_or_call_rhs;
+}
+
+
/* A subroutine of gimplify_modify_expr. Break out elements of a
CONSTRUCTOR used as an initializer into separate MODIFY_EXPRs.
@@ -3171,12 +3498,11 @@ gimplify_init_ctor_eval (tree object, VEC(constructor_elt,gc) *elts,
If NOTIFY_TEMP_CREATION is false, just do the gimplification. */
static enum gimplify_status
-gimplify_init_constructor (tree *expr_p, tree *pre_p,
- tree *post_p, bool want_value,
- bool notify_temp_creation)
+gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
+ bool want_value, bool notify_temp_creation)
{
tree object;
- tree ctor = GENERIC_TREE_OPERAND (*expr_p, 1);
+ tree ctor = TREE_OPERAND (*expr_p, 1);
tree type = TREE_TYPE (ctor);
enum gimplify_status ret;
VEC(constructor_elt,gc) *elts;
@@ -3186,16 +3512,16 @@ gimplify_init_constructor (tree *expr_p, tree *pre_p,
if (!notify_temp_creation)
{
- ret = gimplify_expr (&GENERIC_TREE_OPERAND (*expr_p, 0), pre_p, post_p,
+ ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
is_gimple_lvalue, fb_lvalue);
if (ret == GS_ERROR)
return ret;
}
- object = GENERIC_TREE_OPERAND (*expr_p, 0);
+ object = TREE_OPERAND (*expr_p, 0);
elts = CONSTRUCTOR_ELTS (ctor);
-
ret = GS_ALL_DONE;
+
switch (TREE_CODE (type))
{
case RECORD_TYPE:
@@ -3217,7 +3543,7 @@ gimplify_init_constructor (tree *expr_p, tree *pre_p,
return GS_OK;
break;
}
-
+
/* Fetch information about the constructor to direct later processing.
We might want to make static versions of it in various cases, and
can only do so if it known to be a valid constant initializer. */
@@ -3328,7 +3654,7 @@ gimplify_init_constructor (tree *expr_p, tree *pre_p,
}
walk_tree (&DECL_INITIAL (new), force_labels_r, NULL, NULL);
- GENERIC_TREE_OPERAND (*expr_p, 1) = new;
+ TREE_OPERAND (*expr_p, 1) = new;
/* This is no longer an assignment of a CONSTRUCTOR, but
we still may have processing to do on the LHS. So
@@ -3350,7 +3676,7 @@ gimplify_init_constructor (tree *expr_p, tree *pre_p,
preeval_data.lhs_base_decl = NULL;
preeval_data.lhs_alias_set = get_alias_set (object);
- gimplify_init_ctor_preeval (&GENERIC_TREE_OPERAND (*expr_p, 1),
+ gimplify_init_ctor_preeval (&TREE_OPERAND (*expr_p, 1),
pre_p, post_p, &preeval_data);
}
@@ -3360,9 +3686,9 @@ gimplify_init_constructor (tree *expr_p, tree *pre_p,
Note that we still have to gimplify, in order to handle the
case of variable sized types. Avoid shared tree structures. */
CONSTRUCTOR_ELTS (ctor) = NULL;
+ TREE_SIDE_EFFECTS (ctor) = 0;
object = unshare_expr (object);
- gimplify_stmt (expr_p);
- append_to_statement_list (*expr_p, pre_p);
+ gimplify_stmt (expr_p, pre_p);
}
/* If we have not block cleared the object, or if there are nonzero
@@ -3406,7 +3732,9 @@ gimplify_init_constructor (tree *expr_p, tree *pre_p,
{
ctor = build2 (COMPLEX_EXPR, type, r, i);
TREE_OPERAND (*expr_p, 1) = ctor;
- ret = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p,
+ ret = gimplify_expr (&TREE_OPERAND (*expr_p, 1),
+ pre_p,
+ post_p,
rhs_predicate_for (TREE_OPERAND (*expr_p, 0)),
fb_rvalue);
}
@@ -3458,13 +3786,13 @@ gimplify_init_constructor (tree *expr_p, tree *pre_p,
for (ix = 0; VEC_iterate (constructor_elt, elts, ix, ce); ix++)
{
enum gimplify_status tret;
- tret = gimplify_expr (&ce->value, pre_p, post_p,
- is_gimple_val, fb_rvalue);
+ tret = gimplify_expr (&ce->value, pre_p, post_p, is_gimple_val,
+ fb_rvalue);
if (tret == GS_ERROR)
ret = GS_ERROR;
}
- if (!is_gimple_reg (GENERIC_TREE_OPERAND (*expr_p, 0)))
- GENERIC_TREE_OPERAND (*expr_p, 1) = get_formal_tmp_var (ctor, pre_p);
+ if (!is_gimple_reg (TREE_OPERAND (*expr_p, 0)))
+ TREE_OPERAND (*expr_p, 1) = get_formal_tmp_var (ctor, pre_p);
}
break;
@@ -3477,12 +3805,24 @@ gimplify_init_constructor (tree *expr_p, tree *pre_p,
return GS_ERROR;
else if (want_value)
{
- append_to_statement_list (*expr_p, pre_p);
*expr_p = object;
return GS_OK;
}
else
- return GS_ALL_DONE;
+ {
+ /* If we have gimplified both sides of the initializer but have
+ not emitted an assignment, do so now. */
+ if (*expr_p)
+ {
+ tree lhs = TREE_OPERAND (*expr_p, 0);
+ tree rhs = TREE_OPERAND (*expr_p, 1);
+ gimple init = gimple_build_assign (lhs, rhs);
+ gimplify_seq_add_stmt (pre_p, init);
+ *expr_p = NULL;
+ }
+
+ return GS_ALL_DONE;
+ }
}
/* Given a pointer value OP0, return a simplified version of an
@@ -3560,8 +3900,9 @@ gimple_fold_indirect_ref_rhs (tree t)
something changes. */
static enum gimplify_status
-gimplify_modify_expr_rhs (tree *expr_p, tree *from_p, tree *to_p, tree *pre_p,
- tree *post_p, bool want_value)
+gimplify_modify_expr_rhs (tree *expr_p, tree *from_p, tree *to_p,
+ gimple_seq *pre_p, gimple_seq *post_p,
+ bool want_value)
{
enum gimplify_status ret = GS_OK;
@@ -3758,8 +4099,8 @@ gimplify_modify_expr_rhs (tree *expr_p, tree *from_p, tree *to_p, tree *pre_p,
tree wrap = *from_p;
tree t;
- ret = gimplify_expr (to_p, pre_p, post_p,
- is_gimple_min_lval, fb_lvalue);
+ ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_min_lval,
+ fb_lvalue);
if (ret != GS_ERROR)
ret = GS_OK;
@@ -3784,51 +4125,6 @@ gimplify_modify_expr_rhs (tree *expr_p, tree *from_p, tree *to_p, tree *pre_p,
return ret;
}
-/* Destructively convert the TREE pointer in TP into a gimple tuple if
- appropriate. */
-
-static void
-tree_to_gimple_tuple (tree *tp)
-{
-
- switch (TREE_CODE (*tp))
- {
- case GIMPLE_MODIFY_STMT:
- return;
- case MODIFY_EXPR:
- {
- struct gimple_stmt *gs;
- tree lhs = TREE_OPERAND (*tp, 0);
- bool def_stmt_self_p = false;
-
- if (TREE_CODE (lhs) == SSA_NAME)
- {
- if (SSA_NAME_DEF_STMT (lhs) == *tp)
- def_stmt_self_p = true;
- }
-
- gs = &make_node (GIMPLE_MODIFY_STMT)->gstmt;
- gs->base = (*tp)->base;
- /* The set to base above overwrites the CODE. */
- TREE_SET_CODE ((tree) gs, GIMPLE_MODIFY_STMT);
-
- SET_EXPR_LOCUS ((tree) gs, EXPR_LOCUS (*tp));
- gs->operands[0] = TREE_OPERAND (*tp, 0);
- gs->operands[1] = TREE_OPERAND (*tp, 1);
- gs->block = TREE_BLOCK (*tp);
- *tp = (tree)gs;
-
- /* If we re-gimplify a set to an SSA_NAME, we must change the
- SSA name's DEF_STMT link. */
- if (def_stmt_self_p)
- SSA_NAME_DEF_STMT (GIMPLE_STMT_OPERAND (*tp, 0)) = *tp;
-
- return;
- }
- default:
- break;
- }
-}
/* Promote partial stores to COMPLEX variables to total stores. *EXPR_P is
a MODIFY_EXPR with a lhs of a REAL/IMAGPART_EXPR of a variable with
@@ -3843,13 +4139,14 @@ tree_to_gimple_tuple (tree *tp)
followed by a DCE pass are necessary in order to fix things up. */
static enum gimplify_status
-gimplify_modify_expr_complex_part (tree *expr_p, tree *pre_p, bool want_value)
+gimplify_modify_expr_complex_part (tree *expr_p, gimple_seq *pre_p,
+ bool want_value)
{
enum tree_code code, ocode;
tree lhs, rhs, new_rhs, other, realpart, imagpart;
- lhs = GENERIC_TREE_OPERAND (*expr_p, 0);
- rhs = GENERIC_TREE_OPERAND (*expr_p, 1);
+ lhs = TREE_OPERAND (*expr_p, 0);
+ rhs = TREE_OPERAND (*expr_p, 1);
code = TREE_CODE (lhs);
lhs = TREE_OPERAND (lhs, 0);
@@ -3865,20 +4162,13 @@ gimplify_modify_expr_complex_part (tree *expr_p, tree *pre_p, bool want_value)
else
new_rhs = build2 (COMPLEX_EXPR, TREE_TYPE (lhs), realpart, imagpart);
- GENERIC_TREE_OPERAND (*expr_p, 0) = lhs;
- GENERIC_TREE_OPERAND (*expr_p, 1) = new_rhs;
-
- if (want_value)
- {
- tree_to_gimple_tuple (expr_p);
-
- append_to_statement_list (*expr_p, pre_p);
- *expr_p = rhs;
- }
+ gimplify_seq_add_stmt (pre_p, gimple_build_assign (lhs, new_rhs));
+ *expr_p = (want_value) ? rhs : NULL_TREE;
return GS_ALL_DONE;
}
+
/* Gimplify the MODIFY_EXPR node pointed to by EXPR_P.
modify_expr
@@ -3895,14 +4185,15 @@ gimplify_modify_expr_complex_part (tree *expr_p, tree *pre_p, bool want_value)
in another expression. */
static enum gimplify_status
-gimplify_modify_expr (tree *expr_p, tree *pre_p, tree *post_p, bool want_value)
+gimplify_modify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
+ bool want_value)
{
- tree *from_p = &GENERIC_TREE_OPERAND (*expr_p, 1);
- tree *to_p = &GENERIC_TREE_OPERAND (*expr_p, 0);
+ tree *from_p = &TREE_OPERAND (*expr_p, 1);
+ tree *to_p = &TREE_OPERAND (*expr_p, 0);
enum gimplify_status ret = GS_UNHANDLED;
+ gimple assign;
gcc_assert (TREE_CODE (*expr_p) == MODIFY_EXPR
- || TREE_CODE (*expr_p) == GIMPLE_MODIFY_STMT
|| TREE_CODE (*expr_p) == INIT_EXPR);
/* Insert pointer conversions required by the middle-end that are not
@@ -3928,10 +4219,8 @@ gimplify_modify_expr (tree *expr_p, tree *pre_p, tree *post_p, bool want_value)
types properly. */
if (zero_sized_type (TREE_TYPE (*from_p)))
{
- gimplify_stmt (from_p);
- gimplify_stmt (to_p);
- append_to_statement_list (*from_p, pre_p);
- append_to_statement_list (*to_p, pre_p);
+ gimplify_stmt (from_p, pre_p);
+ gimplify_stmt (to_p, pre_p);
*expr_p = NULL_TREE;
return GS_ALL_DONE;
}
@@ -3941,15 +4230,27 @@ gimplify_modify_expr (tree *expr_p, tree *pre_p, tree *post_p, bool want_value)
before gimplifying any of the operands so that we can resolve any
PLACEHOLDER_EXPRs in the size. Also note that the RTL expander uses
the size of the expression to be copied, not of the destination, so
- that is what we must here. */
+ that is what we must do here. */
maybe_with_size_expr (from_p);
ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
if (ret == GS_ERROR)
return ret;
- ret = gimplify_expr (from_p, pre_p, post_p,
- rhs_predicate_for (*to_p), fb_rvalue);
+ /* As a special case, we have to temporarily allow for assignments
+ with a CALL_EXPR on the RHS. Since in GIMPLE a function call is
+ a toplevel statement, when gimplifying the GENERIC expression
+ MODIFY_EXPR <a, CALL_EXPR <foo>>, we cannot create the tuple
+ GIMPLE_ASSIGN <a, GIMPLE_CALL <foo>>.
+
+ Instead, we need to create the tuple GIMPLE_CALL <a, foo>. To
+ prevent gimplify_expr from trying to create a new temporary for
+ foo's LHS, we tell it that it should only gimplify until it
+ reaches the CALL_EXPR. On return from gimplify_expr, the newly
+ created GIMPLE_CALL <foo> will be the last statement in *PRE_P
+ and all we need to do here is set 'a' to be its LHS. */
+ ret = gimplify_expr (from_p, pre_p, post_p, rhs_predicate_for (*to_p),
+ fb_rvalue);
if (ret == GS_ERROR)
return ret;
@@ -3968,11 +4269,13 @@ gimplify_modify_expr (tree *expr_p, tree *pre_p, tree *post_p, bool want_value)
tree size = TREE_OPERAND (*from_p, 1);
if (TREE_CODE (from) == CONSTRUCTOR)
- return gimplify_modify_expr_to_memset (expr_p, size, want_value);
+ return gimplify_modify_expr_to_memset (expr_p, size, want_value, pre_p);
+
if (is_gimple_addressable (from))
{
*from_p = from;
- return gimplify_modify_expr_to_memcpy (expr_p, size, want_value);
+ return gimplify_modify_expr_to_memcpy (expr_p, size, want_value,
+ pre_p);
}
}
@@ -3984,35 +4287,49 @@ gimplify_modify_expr (tree *expr_p, tree *pre_p, tree *post_p, bool want_value)
&& is_gimple_reg (TREE_OPERAND (*to_p, 0)))
return gimplify_modify_expr_complex_part (expr_p, pre_p, want_value);
- if (gimplify_ctxp->into_ssa && is_gimple_reg (*to_p))
- {
- /* If we've somehow already got an SSA_NAME on the LHS, then
- we're probably modified it twice. Not good. */
- gcc_assert (TREE_CODE (*to_p) != SSA_NAME);
- *to_p = make_ssa_name (*to_p, *expr_p);
- }
-
/* Try to alleviate the effects of the gimplification creating artificial
temporaries (see for example is_gimple_reg_rhs) on the debug info. */
if (!gimplify_ctxp->into_ssa
- && DECL_P (*from_p) && DECL_IGNORED_P (*from_p)
- && DECL_P (*to_p) && !DECL_IGNORED_P (*to_p))
+ && DECL_P (*from_p)
+ && DECL_IGNORED_P (*from_p)
+ && DECL_P (*to_p)
+ && !DECL_IGNORED_P (*to_p))
{
if (!DECL_NAME (*from_p) && DECL_NAME (*to_p))
DECL_NAME (*from_p)
= create_tmp_var_name (IDENTIFIER_POINTER (DECL_NAME (*to_p)));
DECL_DEBUG_EXPR_IS_FROM (*from_p) = 1;
SET_DECL_DEBUG_EXPR (*from_p, *to_p);
+ }
+
+ if (TREE_CODE (*from_p) == CALL_EXPR)
+ {
+ /* Since the RHS is a CALL_EXPR, we need to create a GIMPLE_CALL
+ instead of a GIMPLE_ASSIGN. */
+ assign = gimple_build_call_from_tree (*from_p);
+ gimple_call_set_lhs (assign, *to_p);
}
+ else
+ assign = gimple_build_assign (*to_p, *from_p);
- if (want_value)
+ gimplify_seq_add_stmt (pre_p, assign);
+
+ if (gimplify_ctxp->into_ssa && is_gimple_reg (*to_p))
{
- tree_to_gimple_tuple (expr_p);
+ /* If we've somehow already got an SSA_NAME on the LHS, then
+ we've probably modified it twice. Not good. */
+ gcc_assert (TREE_CODE (*to_p) != SSA_NAME);
+ *to_p = make_ssa_name (*to_p, assign);
+ gimple_set_lhs (assign, *to_p);
+ }
- append_to_statement_list (*expr_p, pre_p);
- *expr_p = *to_p;
+ if (want_value)
+ {
+ *expr_p = unshare_expr (*to_p);
return GS_OK;
}
+ else
+ *expr_p = NULL;
return GS_ALL_DONE;
}
@@ -4094,12 +4411,9 @@ gimplify_boolean_expr (tree *expr_p)
expressions in the sequence will be emitted.
WANT_VALUE is true when the result of the last COMPOUND_EXPR is used. */
-/* ??? Should rearrange to share the pre-queue with all the indirect
- invocations of gimplify_expr. Would probably save on creations
- of statement_list nodes. */
static enum gimplify_status
-gimplify_compound_expr (tree *expr_p, tree *pre_p, bool want_value)
+gimplify_compound_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
{
tree t = *expr_p;
@@ -4110,8 +4424,7 @@ gimplify_compound_expr (tree *expr_p, tree *pre_p, bool want_value)
if (TREE_CODE (*sub_p) == COMPOUND_EXPR)
gimplify_compound_expr (sub_p, pre_p, false);
else
- gimplify_stmt (sub_p);
- append_to_statement_list (*sub_p, pre_p);
+ gimplify_stmt (sub_p, pre_p);
t = TREE_OPERAND (t, 1);
}
@@ -4122,58 +4435,21 @@ gimplify_compound_expr (tree *expr_p, tree *pre_p, bool want_value)
return GS_OK;
else
{
- gimplify_stmt (expr_p);
+ gimplify_stmt (expr_p, pre_p);
return GS_ALL_DONE;
}
}
-/* Gimplifies a statement list. These may be created either by an
- enlightened front-end, or by shortcut_cond_expr. */
-
-static enum gimplify_status
-gimplify_statement_list (tree *expr_p, tree *pre_p)
-{
- tree temp = voidify_wrapper_expr (*expr_p, NULL);
-
- tree_stmt_iterator i = tsi_start (*expr_p);
-
- while (!tsi_end_p (i))
- {
- tree t;
-
- gimplify_stmt (tsi_stmt_ptr (i));
- t = tsi_stmt (i);
- if (t == NULL)
- tsi_delink (&i);
- else if (TREE_CODE (t) == STATEMENT_LIST)
- {
- tsi_link_before (&i, t, TSI_SAME_STMT);
- tsi_delink (&i);
- }
- else
- tsi_next (&i);
- }
+/* Gimplify a SAVE_EXPR node. EXPR_P points to the expression to
+ gimplify. After gimplification, EXPR_P will point to a new temporary
+ that holds the original value of the SAVE_EXPR node.
- if (temp)
- {
- append_to_statement_list (*expr_p, pre_p);
- *expr_p = temp;
- return GS_OK;
- }
-
- return GS_ALL_DONE;
-}
-
-/* Gimplify a SAVE_EXPR node. EXPR_P points to the expression to
- gimplify. After gimplification, EXPR_P will point to a new temporary
- that holds the original value of the SAVE_EXPR node.
-
- PRE_P points to the list where side effects that must happen before
- *EXPR_P should be stored. */
+ PRE_P points to the list where side effects that must happen before
+ *EXPR_P should be stored. */
static enum gimplify_status
-gimplify_save_expr (tree *expr_p, tree *pre_p, tree *post_p)
+gimplify_save_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
{
enum gimplify_status ret = GS_ALL_DONE;
tree val;
@@ -4191,7 +4467,6 @@ gimplify_save_expr (tree *expr_p, tree *pre_p, tree *post_p)
{
ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
is_gimple_stmt, fb_none);
- append_to_statement_list (TREE_OPERAND (*expr_p, 0), pre_p);
val = NULL;
}
else
@@ -4220,7 +4495,7 @@ gimplify_save_expr (tree *expr_p, tree *pre_p, tree *post_p)
*EXPR_P should be stored. */
static enum gimplify_status
-gimplify_addr_expr (tree *expr_p, tree *pre_p, tree *post_p)
+gimplify_addr_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
{
tree expr = *expr_p;
tree op0 = TREE_OPERAND (expr, 0);
@@ -4303,24 +4578,39 @@ gimplify_addr_expr (tree *expr_p, tree *pre_p, tree *post_p)
value; output operands should be a gimple lvalue. */
static enum gimplify_status
-gimplify_asm_expr (tree *expr_p, tree *pre_p, tree *post_p)
+gimplify_asm_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
{
- tree expr = *expr_p;
- int noutputs = list_length (ASM_OUTPUTS (expr));
- const char **oconstraints
- = (const char **) alloca ((noutputs) * sizeof (const char *));
+ tree expr;
+ int noutputs;
+ const char **oconstraints;
int i;
tree link;
const char *constraint;
bool allows_mem, allows_reg, is_inout;
enum gimplify_status ret, tret;
+ gimple stmt;
+ VEC(tree, gc) *inputs;
+ VEC(tree, gc) *outputs;
+ VEC(tree, gc) *clobbers;
+ tree link_next;
+
+ expr = *expr_p;
+ noutputs = list_length (ASM_OUTPUTS (expr));
+ oconstraints = (const char **) alloca ((noutputs) * sizeof (const char *));
+
+ inputs = outputs = clobbers = NULL;
ret = GS_ALL_DONE;
- for (i = 0, link = ASM_OUTPUTS (expr); link; ++i, link = TREE_CHAIN (link))
+ link_next = NULL_TREE;
+ for (i = 0, link = ASM_OUTPUTS (expr); link; ++i, link = link_next)
{
- size_t constraint_len;
bool ok;
- oconstraints[i] = constraint
+ size_t constraint_len;
+
+ link_next = TREE_CHAIN (link);
+
+ oconstraints[i]
+ = constraint
= TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
constraint_len = strlen (constraint);
if (constraint_len == 0)
@@ -4346,6 +4636,9 @@ gimplify_asm_expr (tree *expr_p, tree *pre_p, tree *post_p)
ret = tret;
}
+ VEC_safe_push (tree, gc, outputs, link);
+ TREE_CHAIN (link) = NULL_TREE;
+
if (is_inout)
{
/* An input/output operand. To give the optimizers more
@@ -4439,10 +4732,11 @@ gimplify_asm_expr (tree *expr_p, tree *pre_p, tree *post_p)
}
}
- for (link = ASM_INPUTS (expr); link; ++i, link = TREE_CHAIN (link))
+ link_next = NULL_TREE;
+ for (link = ASM_INPUTS (expr); link; ++i, link = link_next)
{
- constraint
- = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
+ link_next = TREE_CHAIN (link);
+ constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
parse_input_constraint (&constraint, 0, 0, noutputs, 0,
oconstraints, &allows_mem, &allows_reg);
@@ -4478,13 +4772,27 @@ gimplify_asm_expr (tree *expr_p, tree *pre_p, tree *post_p)
if (tret == GS_ERROR)
ret = tret;
}
+
+ TREE_CHAIN (link) = NULL_TREE;
+ VEC_safe_push (tree, gc, inputs, link);
}
+
+ for (link = ASM_CLOBBERS (expr); link; ++i, link = TREE_CHAIN (link))
+ VEC_safe_push (tree, gc, clobbers, link);
+
+ stmt = gimple_build_asm_vec (TREE_STRING_POINTER (ASM_STRING (expr)),
+ inputs, outputs, clobbers);
+
+ gimple_asm_set_volatile (stmt, ASM_VOLATILE_P (expr));
+ gimple_asm_set_input (stmt, ASM_INPUT_P (expr));
+
+ gimplify_seq_add_stmt (pre_p, stmt);
return ret;
}
/* Gimplify a CLEANUP_POINT_EXPR. Currently this works by adding
- WITH_CLEANUP_EXPRs to the prequeue as we encounter cleanups while
+ GIMPLE_WITH_CLEANUP_EXPRs to the prequeue as we encounter cleanups while
gimplifying the body, and converting them to TRY_FINALLY_EXPRs when we
return to this function.
@@ -4498,10 +4806,10 @@ gimplify_asm_expr (tree *expr_p, tree *pre_p, tree *post_p)
Thing. */
static enum gimplify_status
-gimplify_cleanup_point_expr (tree *expr_p, tree *pre_p)
+gimplify_cleanup_point_expr (tree *expr_p, gimple_seq *pre_p)
{
- tree_stmt_iterator iter;
- tree body;
+ gimple_stmt_iterator iter;
+ gimple_seq body_sequence = NULL;
tree temp = voidify_wrapper_expr (*expr_p, NULL);
@@ -4509,74 +4817,79 @@ gimplify_cleanup_point_expr (tree *expr_p, tree *pre_p)
CLEANUP_POINT_EXPR and the cleanup. So save and reset the count and
any cleanups collected outside the CLEANUP_POINT_EXPR. */
int old_conds = gimplify_ctxp->conditions;
- tree old_cleanups = gimplify_ctxp->conditional_cleanups;
+ gimple_seq old_cleanups = gimplify_ctxp->conditional_cleanups;
gimplify_ctxp->conditions = 0;
- gimplify_ctxp->conditional_cleanups = NULL_TREE;
+ gimplify_ctxp->conditional_cleanups = NULL;
- body = TREE_OPERAND (*expr_p, 0);
- gimplify_to_stmt_list (&body);
+ gimplify_stmt (&TREE_OPERAND (*expr_p, 0), &body_sequence);
gimplify_ctxp->conditions = old_conds;
gimplify_ctxp->conditional_cleanups = old_cleanups;
- for (iter = tsi_start (body); !tsi_end_p (iter); )
+ for (iter = gsi_start (body_sequence); !gsi_end_p (iter); )
{
- tree *wce_p = tsi_stmt_ptr (iter);
- tree wce = *wce_p;
+ gimple wce = gsi_stmt (iter);
- if (TREE_CODE (wce) == WITH_CLEANUP_EXPR)
+ if (gimple_code (wce) == GIMPLE_WITH_CLEANUP_EXPR)
{
- if (tsi_one_before_end_p (iter))
+ if (gsi_one_before_end_p (iter))
{
- tsi_link_before (&iter, TREE_OPERAND (wce, 0), TSI_SAME_STMT);
- tsi_delink (&iter);
+ /* Note that gsi_insert_seq_before and gsi_remove do not
+ scan operands, unlike some other sequence mutators. */
+ gsi_insert_seq_before_without_update (&iter,
+ gimple_wce_cleanup (wce),
+ GSI_SAME_STMT);
+ gsi_remove (&iter, true);
break;
}
else
{
- tree sl, tfe;
- enum tree_code code;
+ gimple try;
+ gimple_seq seq;
+ enum gimple_try_flags kind;
- if (CLEANUP_EH_ONLY (wce))
- code = TRY_CATCH_EXPR;
+ if (gimple_wce_cleanup_eh_only (wce))
+ kind = GIMPLE_TRY_CATCH;
else
- code = TRY_FINALLY_EXPR;
-
- sl = tsi_split_statement_list_after (&iter);
- tfe = build2 (code, void_type_node, sl, NULL_TREE);
- append_to_statement_list (TREE_OPERAND (wce, 0),
- &TREE_OPERAND (tfe, 1));
- *wce_p = tfe;
- iter = tsi_start (sl);
+ kind = GIMPLE_TRY_FINALLY;
+ seq = gsi_split_seq_after (iter);
+
+ try = gimple_build_try (seq, gimple_wce_cleanup (wce), kind);
+ /* Do not use gsi_replace here, as it may scan operands.
+ We want to do a simple structural modification only. */
+ *gsi_stmt_ptr (&iter) = try;
+ iter = gsi_start (seq);
}
}
else
- tsi_next (&iter);
+ gsi_next (&iter);
}
+ gimplify_seq_add_seq (pre_p, body_sequence);
if (temp)
{
*expr_p = temp;
- append_to_statement_list (body, pre_p);
return GS_OK;
}
else
{
- *expr_p = body;
+ *expr_p = NULL;
return GS_ALL_DONE;
}
}
/* Insert a cleanup marker for gimplify_cleanup_point_expr. CLEANUP
- is the cleanup action required. */
+ is the cleanup action required. EH_ONLY is true if the cleanup should
+ only be executed if an exception is thrown, not on normal exit. */
static void
-gimple_push_cleanup (tree var, tree cleanup, bool eh_only, tree *pre_p)
+gimple_push_cleanup (tree var, tree cleanup, bool eh_only, gimple_seq *pre_p)
{
- tree wce;
+ gimple wce;
+ gimple_seq cleanup_stmts = NULL;
/* Errors can result in improperly nested cleanups. Which results in
- confusion when trying to resolve the WITH_CLEANUP_EXPR. */
+ confusion when trying to resolve the GIMPLE_WITH_CLEANUP_EXPR. */
if (errorcount || sorrycount)
return;
@@ -4602,15 +4915,17 @@ gimple_push_cleanup (tree var, tree cleanup, bool eh_only, tree *pre_p)
}
val
*/
-
tree flag = create_tmp_var (boolean_type_node, "cleanup");
- tree ffalse = build_gimple_modify_stmt (flag, boolean_false_node);
- tree ftrue = build_gimple_modify_stmt (flag, boolean_true_node);
+ gimple ffalse = gimple_build_assign (flag, boolean_false_node);
+ gimple ftrue = gimple_build_assign (flag, boolean_true_node);
+
cleanup = build3 (COND_EXPR, void_type_node, flag, cleanup, NULL);
- wce = build1 (WITH_CLEANUP_EXPR, void_type_node, cleanup);
- append_to_statement_list (ffalse, &gimplify_ctxp->conditional_cleanups);
- append_to_statement_list (wce, &gimplify_ctxp->conditional_cleanups);
- append_to_statement_list (ftrue, pre_p);
+ gimplify_stmt (&cleanup, &cleanup_stmts);
+ wce = gimple_build_wce (cleanup_stmts);
+
+ gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, ffalse);
+ gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, wce);
+ gimplify_seq_add_stmt (pre_p, ftrue);
/* Because of this manipulation, and the EH edges that jump
threading cannot redirect, the temporary (VAR) will appear
@@ -4619,18 +4934,17 @@ gimple_push_cleanup (tree var, tree cleanup, bool eh_only, tree *pre_p)
}
else
{
- wce = build1 (WITH_CLEANUP_EXPR, void_type_node, cleanup);
- CLEANUP_EH_ONLY (wce) = eh_only;
- append_to_statement_list (wce, pre_p);
+ gimplify_stmt (&cleanup, &cleanup_stmts);
+ wce = gimple_build_wce (cleanup_stmts);
+ gimple_wce_set_cleanup_eh_only (wce, eh_only);
+ gimplify_seq_add_stmt (pre_p, wce);
}
-
- gimplify_stmt (&TREE_OPERAND (wce, 0));
}
/* Gimplify a TARGET_EXPR which doesn't appear on the rhs of an INIT_EXPR. */
static enum gimplify_status
-gimplify_target_expr (tree *expr_p, tree *pre_p, tree *post_p)
+gimplify_target_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
{
tree targ = *expr_p;
tree temp = TARGET_EXPR_SLOT (targ);
@@ -4656,9 +4970,11 @@ gimplify_target_expr (tree *expr_p, tree *pre_p, tree *post_p)
ret = gimplify_expr (&init, pre_p, post_p, is_gimple_stmt, fb_none);
else
{
- init = build2 (INIT_EXPR, void_type_node, temp, init);
- ret = gimplify_expr (&init, pre_p, post_p, is_gimple_stmt,
- fb_none);
+ tree init_expr = build2 (INIT_EXPR, void_type_node, temp, init);
+ init = init_expr;
+ ret = gimplify_expr (&init, pre_p, post_p, is_gimple_stmt, fb_none);
+ init = NULL;
+ ggc_free (init_expr);
}
if (ret == GS_ERROR)
{
@@ -4666,15 +4982,13 @@ gimplify_target_expr (tree *expr_p, tree *pre_p, tree *post_p)
TARGET_EXPR_INITIAL (targ) = NULL_TREE;
return GS_ERROR;
}
- append_to_statement_list (init, pre_p);
+ if (init)
+ gimplify_and_add (init, pre_p);
/* If needed, push the cleanup for the temp. */
if (TARGET_EXPR_CLEANUP (targ))
- {
- gimplify_stmt (&TARGET_EXPR_CLEANUP (targ));
- gimple_push_cleanup (temp, TARGET_EXPR_CLEANUP (targ),
- CLEANUP_EH_ONLY (targ), pre_p);
- }
+ gimple_push_cleanup (temp, TARGET_EXPR_CLEANUP (targ),
+ CLEANUP_EH_ONLY (targ), pre_p);
/* Only expand this once. */
TREE_OPERAND (targ, 3) = init;
@@ -4690,29 +5004,23 @@ gimplify_target_expr (tree *expr_p, tree *pre_p, tree *post_p)
/* Gimplification of expression trees. */
-/* Gimplify an expression which appears at statement context; usually, this
- means replacing it with a suitably gimple STATEMENT_LIST. */
+/* Gimplify an expression which appears at statement context. The
+ corresponding GIMPLE statements are added to *SEQ_P. If *SEQ_P is
+ NULL, a new sequence is allocated.
-void
-gimplify_stmt (tree *stmt_p)
+ Return true if we actually added a statement to the queue. */
+
+bool
+gimplify_stmt (tree *stmt_p, gimple_seq *seq_p)
{
- gimplify_expr (stmt_p, NULL, NULL, is_gimple_stmt, fb_none);
-}
+ gimple_seq_node last;
-/* Similarly, but force the result to be a STATEMENT_LIST. */
+ if (!*seq_p)
+ *seq_p = gimple_seq_alloc ();
-void
-gimplify_to_stmt_list (tree *stmt_p)
-{
- gimplify_stmt (stmt_p);
- if (!*stmt_p)
- *stmt_p = alloc_stmt_list ();
- else if (TREE_CODE (*stmt_p) != STATEMENT_LIST)
- {
- tree t = *stmt_p;
- *stmt_p = alloc_stmt_list ();
- append_to_statement_list (t, stmt_p);
- }
+ last = gimple_seq_last (*seq_p);
+ gimplify_expr (stmt_p, seq_p, NULL, is_gimple_stmt, fb_none);
+ return last != gimple_seq_last (*seq_p);
}
@@ -5101,10 +5409,11 @@ omp_check_private (struct gimplify_omp_ctx *ctx, tree decl)
and previous omp contexts. */
static void
-gimplify_scan_omp_clauses (tree *list_p, tree *pre_p,
+gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
enum omp_region_type region_type)
{
struct gimplify_omp_ctx *ctx, *outer_ctx;
+ struct gimplify_ctx gctx;
tree c;
ctx = new_omp_context (region_type);
@@ -5112,7 +5421,6 @@ gimplify_scan_omp_clauses (tree *list_p, tree *pre_p,
while ((c = *list_p) != NULL)
{
- enum gimplify_status gs;
bool remove = false;
bool notice_outer = true;
const char *check_non_private = NULL;
@@ -5161,19 +5469,30 @@ gimplify_scan_omp_clauses (tree *list_p, tree *pre_p,
omp_add_variable (ctx, OMP_CLAUSE_REDUCTION_PLACEHOLDER (c),
GOVD_LOCAL | GOVD_SEEN);
gimplify_omp_ctxp = ctx;
- push_gimplify_context ();
- gimplify_stmt (&OMP_CLAUSE_REDUCTION_INIT (c));
- pop_gimplify_context (OMP_CLAUSE_REDUCTION_INIT (c));
- push_gimplify_context ();
- gimplify_stmt (&OMP_CLAUSE_REDUCTION_MERGE (c));
- pop_gimplify_context (OMP_CLAUSE_REDUCTION_MERGE (c));
+ push_gimplify_context (&gctx);
+
+ OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c) = gimple_seq_alloc ();
+ OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c) = gimple_seq_alloc ();
+
+ gimplify_and_add (OMP_CLAUSE_REDUCTION_INIT (c),
+ &OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c));
+ pop_gimplify_context
+ (gimple_seq_first_stmt (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c)));
+ push_gimplify_context (&gctx);
+ gimplify_and_add (OMP_CLAUSE_REDUCTION_MERGE (c),
+ &OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c));
+ pop_gimplify_context
+ (gimple_seq_first_stmt (OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c)));
+ OMP_CLAUSE_REDUCTION_INIT (c) = NULL_TREE;
+ OMP_CLAUSE_REDUCTION_MERGE (c) = NULL_TREE;
+
gimplify_omp_ctxp = outer_ctx;
}
else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
&& OMP_CLAUSE_LASTPRIVATE_STMT (c))
{
gimplify_omp_ctxp = ctx;
- push_gimplify_context ();
+ push_gimplify_context (&gctx);
if (TREE_CODE (OMP_CLAUSE_LASTPRIVATE_STMT (c)) != BIND_EXPR)
{
tree bind = build3 (BIND_EXPR, void_type_node, NULL,
@@ -5182,8 +5501,12 @@ gimplify_scan_omp_clauses (tree *list_p, tree *pre_p,
BIND_EXPR_BODY (bind) = OMP_CLAUSE_LASTPRIVATE_STMT (c);
OMP_CLAUSE_LASTPRIVATE_STMT (c) = bind;
}
- gimplify_stmt (&OMP_CLAUSE_LASTPRIVATE_STMT (c));
- pop_gimplify_context (OMP_CLAUSE_LASTPRIVATE_STMT (c));
+ gimplify_and_add (OMP_CLAUSE_LASTPRIVATE_STMT (c),
+ &OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c));
+ pop_gimplify_context
+ (gimple_seq_first_stmt (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c)));
+ OMP_CLAUSE_LASTPRIVATE_STMT (c) = NULL_TREE;
+
gimplify_omp_ctxp = outer_ctx;
}
if (notice_outer)
@@ -5218,10 +5541,9 @@ gimplify_scan_omp_clauses (tree *list_p, tree *pre_p,
case OMP_CLAUSE_SCHEDULE:
case OMP_CLAUSE_NUM_THREADS:
- gs = gimplify_expr (&OMP_CLAUSE_OPERAND (c, 0), pre_p, NULL,
- is_gimple_val, fb_rvalue);
- if (gs == GS_ERROR)
- remove = true;
+ if (gimplify_expr (&OMP_CLAUSE_OPERAND (c, 0), pre_p, NULL,
+ is_gimple_val, fb_rvalue) == GS_ERROR)
+ remove = true;
break;
case OMP_CLAUSE_NOWAIT:
@@ -5392,28 +5714,36 @@ gimplify_adjust_omp_clauses (tree *list_p)
variables. We need to do this scan now, because variable-sized
decls will be decomposed during gimplification. */
-static enum gimplify_status
-gimplify_omp_parallel (tree *expr_p, tree *pre_p)
+static void
+gimplify_omp_parallel (tree *expr_p, gimple_seq *pre_p)
{
tree expr = *expr_p;
+ gimple g;
+ gimple_seq body = NULL;
+ struct gimplify_ctx gctx;
gimplify_scan_omp_clauses (&OMP_PARALLEL_CLAUSES (expr), pre_p,
OMP_PARALLEL_COMBINED (expr)
? ORT_COMBINED_PARALLEL
: ORT_PARALLEL);
- push_gimplify_context ();
-
- gimplify_stmt (&OMP_PARALLEL_BODY (expr));
+ push_gimplify_context (&gctx);
- if (TREE_CODE (OMP_PARALLEL_BODY (expr)) == BIND_EXPR)
- pop_gimplify_context (OMP_PARALLEL_BODY (expr));
+ g = gimplify_and_return_first (OMP_PARALLEL_BODY (expr), &body);
+ if (gimple_code (g) == GIMPLE_BIND)
+ pop_gimplify_context (g);
else
- pop_gimplify_context (NULL_TREE);
+ pop_gimplify_context (NULL);
gimplify_adjust_omp_clauses (&OMP_PARALLEL_CLAUSES (expr));
- return GS_ALL_DONE;
+ g = gimple_build_omp_parallel (body,
+ OMP_PARALLEL_CLAUSES (expr),
+ NULL_TREE, NULL_TREE);
+ if (OMP_PARALLEL_COMBINED (expr))
+ gimple_omp_set_subcode (g, GF_OMP_PARALLEL_COMBINED);
+ gimplify_seq_add_stmt (pre_p, g);
+ *expr_p = NULL_TREE;
}
/* Gimplify the contents of an OMP_TASK statement. This involves
@@ -5421,35 +5751,43 @@ gimplify_omp_parallel (tree *expr_p, tree *pre_p)
variables. We need to do this scan now, because variable-sized
decls will be decomposed during gimplification. */
-static enum gimplify_status
-gimplify_omp_task (tree *expr_p, tree *pre_p)
+static void
+gimplify_omp_task (tree *expr_p, gimple_seq *pre_p)
{
tree expr = *expr_p;
+ gimple g;
+ gimple_seq body = NULL;
+ struct gimplify_ctx gctx;
gimplify_scan_omp_clauses (&OMP_TASK_CLAUSES (expr), pre_p, ORT_TASK);
- push_gimplify_context ();
+ push_gimplify_context (&gctx);
- gimplify_stmt (&OMP_TASK_BODY (expr));
-
- if (TREE_CODE (OMP_TASK_BODY (expr)) == BIND_EXPR)
- pop_gimplify_context (OMP_TASK_BODY (expr));
+ g = gimplify_and_return_first (OMP_TASK_BODY (expr), &body);
+ if (gimple_code (g) == GIMPLE_BIND)
+ pop_gimplify_context (g);
else
- pop_gimplify_context (NULL_TREE);
+ pop_gimplify_context (NULL);
gimplify_adjust_omp_clauses (&OMP_TASK_CLAUSES (expr));
- return GS_ALL_DONE;
+ g = gimple_build_omp_task (body,
+ OMP_TASK_CLAUSES (expr),
+ NULL_TREE, NULL_TREE,
+ NULL_TREE, NULL_TREE, NULL_TREE);
+ gimplify_seq_add_stmt (pre_p, g);
+ *expr_p = NULL_TREE;
}
/* Gimplify the gross structure of an OMP_FOR statement. */
static enum gimplify_status
-gimplify_omp_for (tree *expr_p, tree *pre_p)
+gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
{
- tree for_stmt, decl, var, t, bodylist;
+ tree for_stmt, decl, var, t;
enum gimplify_status ret = GS_OK;
- tree body, init_decl = NULL_TREE;
+ gimple gfor;
+ gimple_seq for_body, for_pre_body;
int i;
for_stmt = *expr_p;
@@ -5457,12 +5795,12 @@ gimplify_omp_for (tree *expr_p, tree *pre_p)
gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (for_stmt), pre_p,
ORT_WORKSHARE);
- /* If OMP_FOR is re-gimplified, ensure all variables in pre-body
- are noticed. */
- gimplify_stmt (&OMP_FOR_PRE_BODY (for_stmt));
-
- bodylist = alloc_stmt_list ();
+ /* Handle OMP_FOR_INIT. */
+ for_pre_body = NULL;
+ gimplify_and_add (OMP_FOR_PRE_BODY (for_stmt), &for_pre_body);
+ OMP_FOR_PRE_BODY (for_stmt) = NULL_TREE;
+ for_body = gimple_seq_alloc ();
gcc_assert (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
== TREE_VEC_LENGTH (OMP_FOR_COND (for_stmt)));
gcc_assert (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
@@ -5470,9 +5808,8 @@ gimplify_omp_for (tree *expr_p, tree *pre_p)
for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
{
t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
- gcc_assert (TREE_CODE (t) == MODIFY_EXPR
- || TREE_CODE (t) == GIMPLE_MODIFY_STMT);
- decl = GENERIC_TREE_OPERAND (t, 0);
+ gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
+ decl = TREE_OPERAND (t, 0);
gcc_assert (DECL_P (decl));
gcc_assert (INTEGRAL_TYPE_P (TREE_TYPE (decl))
|| POINTER_TYPE_P (TREE_TYPE (decl)));
@@ -5489,30 +5826,29 @@ gimplify_omp_for (tree *expr_p, tree *pre_p)
if (!is_gimple_reg (decl))
{
var = create_tmp_var (TREE_TYPE (decl), get_name (decl));
- GENERIC_TREE_OPERAND (t, 0) = var;
+ TREE_OPERAND (t, 0) = var;
+
+ gimplify_seq_add_stmt (&for_body, gimple_build_assign (decl, var));
- init_decl = build_gimple_modify_stmt (decl, var);
omp_add_variable (gimplify_omp_ctxp, var, GOVD_PRIVATE | GOVD_SEEN);
}
else
var = decl;
- ret |= gimplify_expr (&GENERIC_TREE_OPERAND (t, 1),
- &OMP_FOR_PRE_BODY (for_stmt),
- NULL, is_gimple_val, fb_rvalue);
-
- tree_to_gimple_tuple (&TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i));
+ ret |= gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
+ is_gimple_val, fb_rvalue);
+ if (ret == GS_ERROR)
+ return ret;
+ /* Handle OMP_FOR_COND. */
t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
gcc_assert (COMPARISON_CLASS_P (t));
- gcc_assert (GENERIC_TREE_OPERAND (t, 0) == decl);
- TREE_OPERAND (t, 0) = var;
+ gcc_assert (TREE_OPERAND (t, 0) == decl);
- ret |= gimplify_expr (&GENERIC_TREE_OPERAND (t, 1),
- &OMP_FOR_PRE_BODY (for_stmt),
- NULL, is_gimple_val, fb_rvalue);
+ ret |= gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
+ is_gimple_val, fb_rvalue);
- tree_to_gimple_tuple (&TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i));
+ /* Handle OMP_FOR_INCR. */
t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
switch (TREE_CODE (t))
{
@@ -5520,7 +5856,7 @@ gimplify_omp_for (tree *expr_p, tree *pre_p)
case POSTINCREMENT_EXPR:
t = build_int_cst (TREE_TYPE (decl), 1);
t = build2 (PLUS_EXPR, TREE_TYPE (decl), var, t);
- t = build_gimple_modify_stmt (var, t);
+ t = build2 (MODIFY_EXPR, TREE_TYPE (var), var, t);
TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i) = t;
break;
@@ -5528,15 +5864,15 @@ gimplify_omp_for (tree *expr_p, tree *pre_p)
case POSTDECREMENT_EXPR:
t = build_int_cst (TREE_TYPE (decl), -1);
t = build2 (PLUS_EXPR, TREE_TYPE (decl), var, t);
- t = build_gimple_modify_stmt (var, t);
+ t = build2 (MODIFY_EXPR, TREE_TYPE (var), var, t);
TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i) = t;
break;
- case GIMPLE_MODIFY_STMT:
- gcc_assert (GIMPLE_STMT_OPERAND (t, 0) == decl);
- GIMPLE_STMT_OPERAND (t, 0) = var;
+ case MODIFY_EXPR:
+ gcc_assert (TREE_OPERAND (t, 0) == decl);
+ TREE_OPERAND (t, 0) = var;
- t = GIMPLE_STMT_OPERAND (t, 1);
+ t = TREE_OPERAND (t, 1);
switch (TREE_CODE (t))
{
case PLUS_EXPR:
@@ -5557,64 +5893,84 @@ gimplify_omp_for (tree *expr_p, tree *pre_p)
gcc_unreachable ();
}
- ret |= gimplify_expr (&TREE_OPERAND (t, 1),
- &OMP_FOR_PRE_BODY (for_stmt),
- NULL, is_gimple_val, fb_rvalue);
+ ret |= gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
+ is_gimple_val, fb_rvalue);
break;
default:
gcc_unreachable ();
}
- if (init_decl)
- append_to_statement_list (init_decl, &bodylist);
-
if (var != decl || TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) > 1)
{
tree c;
for (c = OMP_FOR_CLAUSES (for_stmt); c ; c = OMP_CLAUSE_CHAIN (c))
- if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
- && OMP_CLAUSE_DECL (c) == decl
- && OMP_CLAUSE_LASTPRIVATE_STMT (c) == NULL)
- {
- t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
- gcc_assert (TREE_CODE (t) == GIMPLE_MODIFY_STMT);
- gcc_assert (GIMPLE_STMT_OPERAND (t, 0) == var);
- t = GIMPLE_STMT_OPERAND (t, 1);
- gcc_assert (TREE_CODE (t) == PLUS_EXPR
- || TREE_CODE (t) == MINUS_EXPR
- || TREE_CODE (t) == POINTER_PLUS_EXPR);
- gcc_assert (TREE_OPERAND (t, 0) == var);
- t = build2 (TREE_CODE (t), TREE_TYPE (decl), decl,
- TREE_OPERAND (t, 1));
- OMP_CLAUSE_LASTPRIVATE_STMT (c)
- = build_gimple_modify_stmt (decl, t);
+ if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
+ && OMP_CLAUSE_DECL (c) == decl
+ && OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c) == NULL)
+ {
+ t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
+ gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
+ gcc_assert (TREE_OPERAND (t, 0) == var);
+ t = TREE_OPERAND (t, 1);
+ gcc_assert (TREE_CODE (t) == PLUS_EXPR
+ || TREE_CODE (t) == MINUS_EXPR
+ || TREE_CODE (t) == POINTER_PLUS_EXPR);
+ gcc_assert (TREE_OPERAND (t, 0) == var);
+ t = build2 (TREE_CODE (t), TREE_TYPE (decl), decl,
+ TREE_OPERAND (t, 1));
+ gimplify_assign (decl, t,
+ &OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c));
}
}
}
- body = OMP_FOR_BODY (for_stmt);
- gimplify_to_stmt_list (&body);
- append_to_statement_list (body, &bodylist);
- OMP_FOR_BODY (for_stmt) = bodylist;
+ gimplify_and_add (OMP_FOR_BODY (for_stmt), &for_body);
+
gimplify_adjust_omp_clauses (&OMP_FOR_CLAUSES (for_stmt));
+ gfor = gimple_build_omp_for (for_body, OMP_FOR_CLAUSES (for_stmt),
+ TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)),
+ for_pre_body);
+
+ for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
+ {
+ t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
+ gimple_omp_for_set_index (gfor, i, TREE_OPERAND (t, 0));
+ gimple_omp_for_set_initial (gfor, i, TREE_OPERAND (t, 1));
+ t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
+ gimple_omp_for_set_cond (gfor, i, TREE_CODE (t));
+ gimple_omp_for_set_final (gfor, i, TREE_OPERAND (t, 1));
+ t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
+ gimple_omp_for_set_incr (gfor, i, TREE_OPERAND (t, 1));
+ }
+
+ gimplify_seq_add_stmt (pre_p, gfor);
return ret == GS_ALL_DONE ? GS_ALL_DONE : GS_ERROR;
}
/* Gimplify the gross structure of other OpenMP worksharing constructs.
In particular, OMP_SECTIONS and OMP_SINGLE. */
-static enum gimplify_status
-gimplify_omp_workshare (tree *expr_p, tree *pre_p)
+static void
+gimplify_omp_workshare (tree *expr_p, gimple_seq *pre_p)
{
- tree stmt = *expr_p;
+ tree expr = *expr_p;
+ gimple stmt;
+ gimple_seq body = NULL;
- gimplify_scan_omp_clauses (&OMP_CLAUSES (stmt), pre_p, ORT_WORKSHARE);
- gimplify_to_stmt_list (&OMP_BODY (stmt));
- gimplify_adjust_omp_clauses (&OMP_CLAUSES (stmt));
+ gimplify_scan_omp_clauses (&OMP_CLAUSES (expr), pre_p, ORT_WORKSHARE);
+ gimplify_and_add (OMP_BODY (expr), &body);
+ gimplify_adjust_omp_clauses (&OMP_CLAUSES (expr));
- return GS_ALL_DONE;
+ if (TREE_CODE (expr) == OMP_SECTIONS)
+ stmt = gimple_build_omp_sections (body, OMP_CLAUSES (expr));
+ else if (TREE_CODE (expr) == OMP_SINGLE)
+ stmt = gimple_build_omp_single (body, OMP_CLAUSES (expr));
+ else
+ gcc_unreachable ();
+
+ gimplify_seq_add_stmt (pre_p, stmt);
}
/* A subroutine of gimplify_omp_atomic. The front end is supposed to have
@@ -5664,7 +6020,8 @@ goa_lhs_expr_p (tree expr, tree addr)
a subexpression, 0 if it did not, or -1 if an error was encountered. */
static int
-goa_stabilize_expr (tree *expr_p, tree *pre_p, tree lhs_addr, tree lhs_var)
+goa_stabilize_expr (tree *expr_p, gimple_seq *pre_p, tree lhs_addr,
+ tree lhs_var)
{
tree expr = *expr_p;
int saw_lhs;
@@ -5681,11 +6038,11 @@ goa_stabilize_expr (tree *expr_p, tree *pre_p, tree lhs_addr, tree lhs_var)
switch (TREE_CODE_CLASS (TREE_CODE (expr)))
{
case tcc_binary:
- saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p,
- lhs_addr, lhs_var);
+ saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p, lhs_addr,
+ lhs_var);
case tcc_unary:
- saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
- lhs_addr, lhs_var);
+ saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p, lhs_addr,
+ lhs_var);
break;
default:
break;
@@ -5702,15 +6059,16 @@ goa_stabilize_expr (tree *expr_p, tree *pre_p, tree lhs_addr, tree lhs_var)
return saw_lhs;
}
+
/* Gimplify an OMP_ATOMIC statement. */
static enum gimplify_status
-gimplify_omp_atomic (tree *expr_p, tree *pre_p)
+gimplify_omp_atomic (tree *expr_p, gimple_seq *pre_p)
{
tree addr = TREE_OPERAND (*expr_p, 0);
tree rhs = TREE_OPERAND (*expr_p, 1);
tree type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (addr)));
- tree tmp_load, load, store;
+ tree tmp_load;
tmp_load = create_tmp_var (type, NULL);
if (goa_stabilize_expr (&rhs, pre_p, addr, tmp_load) < 0)
@@ -5720,74 +6078,170 @@ gimplify_omp_atomic (tree *expr_p, tree *pre_p)
!= GS_ALL_DONE)
return GS_ERROR;
- load = build2 (OMP_ATOMIC_LOAD, void_type_node, tmp_load, addr);
- append_to_statement_list (load, pre_p);
+ gimplify_seq_add_stmt (pre_p, gimple_build_omp_atomic_load (tmp_load, addr));
if (gimplify_expr (&rhs, pre_p, NULL, is_gimple_val, fb_rvalue)
!= GS_ALL_DONE)
return GS_ERROR;
- store = build1 (OMP_ATOMIC_STORE, void_type_node, rhs);
- *expr_p = store;
+ gimplify_seq_add_stmt (pre_p, gimple_build_omp_atomic_store (rhs));
+ *expr_p = NULL;
return GS_ALL_DONE;
-
}
-/* Gimplifies the expression tree pointed to by EXPR_P. Return 0 if
- gimplification failed.
- PRE_P points to the list where side effects that must happen before
- EXPR should be stored.
-
- POST_P points to the list where side effects that must happen after
- EXPR should be stored, or NULL if there is no suitable list. In
- that case, we copy the result to a temporary, emit the
- post-effects, and then return the temporary.
-
- GIMPLE_TEST_F points to a function that takes a tree T and
- returns nonzero if T is in the GIMPLE form requested by the
- caller. The GIMPLE predicates are in tree-gimple.c.
-
- This test is used twice. Before gimplification, the test is
- invoked to determine whether *EXPR_P is already gimple enough. If
- that fails, *EXPR_P is gimplified according to its code and
- GIMPLE_TEST_F is called again. If the test still fails, then a new
- temporary variable is created and assigned the value of the
- gimplified expression.
-
- FALLBACK tells the function what sort of a temporary we want. If the 1
- bit is set, an rvalue is OK. If the 2 bit is set, an lvalue is OK.
- If both are set, either is OK, but an lvalue is preferable.
-
- The return value is either GS_ERROR or GS_ALL_DONE, since this function
- iterates until solution. */
+/* Converts the GENERIC expression tree *EXPR_P to GIMPLE. If the
+ expression produces a value to be used as an operand inside a GIMPLE
+ statement, the value will be stored back in *EXPR_P. This value will
+ be a tree of class tcc_declaration, tcc_constant, tcc_reference or
+ an SSA_NAME. The corresponding sequence of GIMPLE statements is
+ emitted in PRE_P and POST_P.
+
+ Additionally, this process may overwrite parts of the input
+ expression during gimplification. Ideally, it should be
+ possible to do non-destructive gimplification.
+
+ EXPR_P points to the GENERIC expression to convert to GIMPLE. If
+ the expression needs to evaluate to a value to be used as
+ an operand in a GIMPLE statement, this value will be stored in
+ *EXPR_P on exit. This happens when the caller specifies one
+ of fb_lvalue or fb_rvalue fallback flags.
+
+ PRE_P will contain the sequence of GIMPLE statements corresponding
+ to the evaluation of EXPR and all the side-effects that must
+ be executed before the main expression. On exit, the last
+ statement of PRE_P is the core statement being gimplified. For
+ instance, when gimplifying 'if (++a)' the last statement in
+ PRE_P will be 'if (t.1)' where t.1 is the result of
+ pre-incrementing 'a'.
+
+ POST_P will contain the sequence of GIMPLE statements corresponding
+ to the evaluation of all the side-effects that must be executed
+ after the main expression. If this is NULL, the post
+ side-effects are stored at the end of PRE_P.
+
+ The reason why the output is split in two is to handle post
+ side-effects explicitly. In some cases, an expression may have
+ inner and outer post side-effects which need to be emitted in
+ an order different from the one given by the recursive
+ traversal. For instance, for the expression (*p--)++ the post
+ side-effects of '--' must actually occur *after* the post
+ side-effects of '++'. However, gimplification will first visit
+ the inner expression, so if a separate POST sequence was not
+ used, the resulting sequence would be:
+
+ 1 t.1 = *p
+ 2 p = p - 1
+ 3 t.2 = t.1 + 1
+ 4 *p = t.2
+
+ However, the post-decrement operation in line #2 must not be
+ evaluated until after the store to *p at line #4, so the
+ correct sequence should be:
+
+ 1 t.1 = *p
+ 2 t.2 = t.1 + 1
+ 3 *p = t.2
+ 4 p = p - 1
+
+ So, by specifying a separate post queue, it is possible
+ to emit the post side-effects in the correct order.
+ If POST_P is NULL, an internal queue will be used. Before
+ returning to the caller, the sequence POST_P is appended to
+ the main output sequence PRE_P.
+
+ GIMPLE_TEST_F points to a function that takes a tree T and
+ returns nonzero if T is in the GIMPLE form requested by the
+ caller. The GIMPLE predicates are in tree-gimple.c.
+
+ FALLBACK tells the function what sort of a temporary we want if
+ gimplification cannot produce an expression that complies with
+ GIMPLE_TEST_F.
+
+ fb_none means that no temporary should be generated
+ fb_rvalue means that an rvalue is OK to generate
+ fb_lvalue means that an lvalue is OK to generate
+ fb_either means that either is OK, but an lvalue is preferable.
+ fb_mayfail means that gimplification may fail (in which case
+ GS_ERROR will be returned)
+
+ The return value is either GS_ERROR or GS_ALL_DONE, since this
+ function iterates until EXPR is completely gimplified or an error
+ occurs. */
enum gimplify_status
-gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p,
- bool (* gimple_test_f) (tree), fallback_t fallback)
+gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
+ bool (*gimple_test_f) (tree), fallback_t fallback)
{
tree tmp;
- tree internal_pre = NULL_TREE;
- tree internal_post = NULL_TREE;
+ gimple_seq internal_pre = NULL;
+ gimple_seq internal_post = NULL;
tree save_expr;
- int is_statement = (pre_p == NULL);
+ bool is_statement;
location_t saved_location;
enum gimplify_status ret;
+ gimple_stmt_iterator pre_last_gsi, post_last_gsi;
save_expr = *expr_p;
if (save_expr == NULL_TREE)
return GS_ALL_DONE;
+ /* If we are gimplifying a top-level statement, PRE_P must be valid. */
+ is_statement = gimple_test_f == is_gimple_stmt;
+ if (is_statement)
+ gcc_assert (pre_p);
+
+ /* Consistency checks. */
+ if (gimple_test_f == is_gimple_reg)
+ gcc_assert (fallback & (fb_rvalue | fb_lvalue));
+ else if (gimple_test_f == is_gimple_val
+ || gimple_test_f == is_gimple_formal_tmp_rhs
+ || gimple_test_f == is_gimple_formal_tmp_or_call_rhs
+ || gimple_test_f == is_gimple_formal_tmp_reg
+ || gimple_test_f == is_gimple_formal_tmp_var
+ || gimple_test_f == is_gimple_call_addr
+ || gimple_test_f == is_gimple_condexpr
+ || gimple_test_f == is_gimple_mem_rhs
+ || gimple_test_f == is_gimple_mem_or_call_rhs
+ || gimple_test_f == is_gimple_reg_rhs
+ || gimple_test_f == is_gimple_reg_or_call_rhs
+ || gimple_test_f == is_gimple_asm_val)
+ gcc_assert (fallback & fb_rvalue);
+ else if (gimple_test_f == is_gimple_min_lval
+ || gimple_test_f == is_gimple_lvalue)
+ gcc_assert (fallback & fb_lvalue);
+ else if (gimple_test_f == is_gimple_addressable)
+ gcc_assert (fallback & fb_either);
+ else if (gimple_test_f == is_gimple_stmt)
+ gcc_assert (fallback == fb_none);
+ else
+ {
+ /* We should have recognized the GIMPLE_TEST_F predicate to
+ know what kind of fallback to use in case a temporary is
+ needed to hold the value or address of *EXPR_P. */
+ gcc_unreachable ();
+ }
+
/* We used to check the predicate here and return immediately if it
succeeds. This is wrong; the design is for gimplification to be
idempotent, and for the predicates to only test for valid forms, not
whether they are fully simplified. */
-
- /* Set up our internal queues if needed. */
if (pre_p == NULL)
pre_p = &internal_pre;
+
if (post_p == NULL)
post_p = &internal_post;
+ /* Remember the last statements added to PRE_P and POST_P. Every
+ new statement added by the gimplification helpers needs to be
+ annotated with location information. To centralize the
+ responsibility, we remember the last statement that had been
+ added to both queues before gimplifying *EXPR_P. If
+ gimplification produces new statements in PRE_P and POST_P, those
+ statements will be annotated with the same location information
+ as *EXPR_P. */
+ pre_last_gsi = gsi_last (*pre_p);
+ post_last_gsi = gsi_last (*post_p);
+
saved_location = input_location;
if (save_expr != error_mark_node
&& EXPR_HAS_LOCATION (*expr_p))
@@ -5806,8 +6260,7 @@ gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p,
/* Die, die, die, my darling. */
if (save_expr == error_mark_node
- || (!GIMPLE_STMT_P (save_expr)
- && TREE_TYPE (save_expr)
+ || (TREE_TYPE (save_expr)
&& TREE_TYPE (save_expr) == error_mark_node))
{
ret = GS_ERROR;
@@ -5851,6 +6304,7 @@ gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p,
case COND_EXPR:
ret = gimplify_cond_expr (expr_p, pre_p, fallback);
+
/* C99 code may assign to an array in a structure value of a
conditional expression, and this has undefined behavior
only on execution, so create a temporary if an lvalue is
@@ -5864,6 +6318,7 @@ gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p,
case CALL_EXPR:
ret = gimplify_call_expr (expr_p, pre_p, fallback != fb_none);
+
/* C99 code may assign to an array in a structure returned
from a function, and this has undefined behavior only on
execution, so create a temporary if an lvalue is
@@ -5883,23 +6338,9 @@ gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p,
break;
case MODIFY_EXPR:
- case GIMPLE_MODIFY_STMT:
case INIT_EXPR:
ret = gimplify_modify_expr (expr_p, pre_p, post_p,
fallback != fb_none);
-
- if (*expr_p)
- {
- /* The distinction between MODIFY_EXPR and INIT_EXPR is no longer
- useful. */
- if (TREE_CODE (*expr_p) == INIT_EXPR)
- TREE_SET_CODE (*expr_p, MODIFY_EXPR);
-
- /* Convert MODIFY_EXPR to GIMPLE_MODIFY_STMT. */
- if (TREE_CODE (*expr_p) == MODIFY_EXPR)
- tree_to_gimple_tuple (expr_p);
- }
-
break;
case TRUTH_ANDIF_EXPR:
@@ -5993,7 +6434,7 @@ gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p,
break;
case DECL_EXPR:
- ret = gimplify_decl_expr (expr_p);
+ ret = gimplify_decl_expr (expr_p, pre_p);
break;
case EXC_PTR_EXPR:
@@ -6023,20 +6464,27 @@ gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p,
if (TREE_CODE (GOTO_DESTINATION (*expr_p)) != LABEL_DECL)
ret = gimplify_expr (&GOTO_DESTINATION (*expr_p), pre_p,
NULL, is_gimple_val, fb_rvalue);
+ gimplify_seq_add_stmt (pre_p,
+ gimple_build_goto (GOTO_DESTINATION (*expr_p)));
break;
- /* Predictions are always gimplified. */
case PREDICT_EXPR:
- goto out;
+ gimplify_seq_add_stmt (pre_p,
+ gimple_build_predict (PREDICT_EXPR_PREDICTOR (*expr_p),
+ PREDICT_EXPR_OUTCOME (*expr_p)));
+ ret = GS_ALL_DONE;
+ break;
case LABEL_EXPR:
ret = GS_ALL_DONE;
gcc_assert (decl_function_context (LABEL_EXPR_LABEL (*expr_p))
== current_function_decl);
+ gimplify_seq_add_stmt (pre_p,
+ gimple_build_label (LABEL_EXPR_LABEL (*expr_p)));
break;
case CASE_LABEL_EXPR:
- ret = gimplify_case_label_expr (expr_p);
+ ret = gimplify_case_label_expr (expr_p, pre_p);
break;
case RETURN_EXPR:
@@ -6088,12 +6536,12 @@ gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p,
{
enum gimplify_status r0, r1, r2;
- r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
- is_gimple_lvalue, fb_either);
- r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p,
- is_gimple_val, fb_rvalue);
- r2 = gimplify_expr (&TREE_OPERAND (*expr_p, 2), pre_p, post_p,
- is_gimple_val, fb_rvalue);
+ r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
+ post_p, is_gimple_lvalue, fb_either);
+ r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
+ post_p, is_gimple_val, fb_rvalue);
+ r2 = gimplify_expr (&TREE_OPERAND (*expr_p, 2), pre_p,
+ post_p, is_gimple_val, fb_rvalue);
recalculate_side_effects (*expr_p);
ret = MIN (r0, MIN (r1, r2));
@@ -6110,10 +6558,24 @@ gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p,
case TRY_FINALLY_EXPR:
case TRY_CATCH_EXPR:
- gimplify_to_stmt_list (&TREE_OPERAND (*expr_p, 0));
- gimplify_to_stmt_list (&TREE_OPERAND (*expr_p, 1));
- ret = GS_ALL_DONE;
- break;
+ {
+ gimple_seq eval, cleanup;
+ gimple try_;
+
+ eval = cleanup = NULL;
+ gimplify_and_add (TREE_OPERAND (*expr_p, 0), &eval);
+ gimplify_and_add (TREE_OPERAND (*expr_p, 1), &cleanup);
+ try_ = gimple_build_try (eval, cleanup,
+ TREE_CODE (*expr_p) == TRY_FINALLY_EXPR
+ ? GIMPLE_TRY_FINALLY
+ : GIMPLE_TRY_CATCH);
+ if (TREE_CODE (*expr_p) == TRY_CATCH_EXPR)
+ gimple_try_set_catch_is_cleanup (try_,
+ TRY_CATCH_IS_CLEANUP (*expr_p));
+ gimplify_seq_add_stmt (pre_p, try_);
+ ret = GS_ALL_DONE;
+ break;
+ }
case CLEANUP_POINT_EXPR:
ret = gimplify_cleanup_point_expr (expr_p, pre_p);
@@ -6124,27 +6586,50 @@ gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p,
break;
case CATCH_EXPR:
- gimplify_to_stmt_list (&CATCH_BODY (*expr_p));
- ret = GS_ALL_DONE;
- break;
+ {
+ gimple c;
+ gimple_seq handler = NULL;
+ gimplify_and_add (CATCH_BODY (*expr_p), &handler);
+ c = gimple_build_catch (CATCH_TYPES (*expr_p), handler);
+ gimplify_seq_add_stmt (pre_p, c);
+ ret = GS_ALL_DONE;
+ break;
+ }
case EH_FILTER_EXPR:
- gimplify_to_stmt_list (&EH_FILTER_FAILURE (*expr_p));
- ret = GS_ALL_DONE;
- break;
+ {
+ gimple ehf;
+ gimple_seq failure = NULL;
+
+ gimplify_and_add (EH_FILTER_FAILURE (*expr_p), &failure);
+ ehf = gimple_build_eh_filter (EH_FILTER_TYPES (*expr_p), failure);
+ gimple_eh_filter_set_must_not_throw
+ (ehf, EH_FILTER_MUST_NOT_THROW (*expr_p));
+ gimplify_seq_add_stmt (pre_p, ehf);
+ ret = GS_ALL_DONE;
+ break;
+ }
case CHANGE_DYNAMIC_TYPE_EXPR:
- ret = gimplify_expr (&CHANGE_DYNAMIC_TYPE_LOCATION (*expr_p),
- pre_p, post_p, is_gimple_reg, fb_lvalue);
+ {
+ gimple cdt;
+
+ ret = gimplify_expr (&CHANGE_DYNAMIC_TYPE_LOCATION (*expr_p),
+ pre_p, post_p, is_gimple_reg, fb_lvalue);
+ cdt = gimple_build_cdt (CHANGE_DYNAMIC_TYPE_NEW_TYPE (*expr_p),
+ CHANGE_DYNAMIC_TYPE_LOCATION (*expr_p));
+ gimplify_seq_add_stmt (pre_p, cdt);
+ ret = GS_ALL_DONE;
+ }
break;
case OBJ_TYPE_REF:
{
enum gimplify_status r0, r1;
- r0 = gimplify_expr (&OBJ_TYPE_REF_OBJECT (*expr_p), pre_p, post_p,
- is_gimple_val, fb_rvalue);
- r1 = gimplify_expr (&OBJ_TYPE_REF_EXPR (*expr_p), pre_p, post_p,
- is_gimple_val, fb_rvalue);
+ r0 = gimplify_expr (&OBJ_TYPE_REF_OBJECT (*expr_p), pre_p,
+ post_p, is_gimple_val, fb_rvalue);
+ r1 = gimplify_expr (&OBJ_TYPE_REF_EXPR (*expr_p), pre_p,
+ post_p, is_gimple_val, fb_rvalue);
ret = MIN (r0, r1);
}
break;
@@ -6189,11 +6674,13 @@ gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p,
break;
case OMP_PARALLEL:
- ret = gimplify_omp_parallel (expr_p, pre_p);
+ gimplify_omp_parallel (expr_p, pre_p);
+ ret = GS_ALL_DONE;
break;
case OMP_TASK:
- ret = gimplify_omp_task (expr_p, pre_p);
+ gimplify_omp_task (expr_p, pre_p);
+ ret = GS_ALL_DONE;
break;
case OMP_FOR:
@@ -6202,35 +6689,46 @@ gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p,
case OMP_SECTIONS:
case OMP_SINGLE:
- ret = gimplify_omp_workshare (expr_p, pre_p);
+ gimplify_omp_workshare (expr_p, pre_p);
+ ret = GS_ALL_DONE;
break;
case OMP_SECTION:
case OMP_MASTER:
case OMP_ORDERED:
case OMP_CRITICAL:
- gimplify_to_stmt_list (&OMP_BODY (*expr_p));
- break;
+ {
+ gimple_seq body = NULL;
+ gimple g;
+
+ gimplify_and_add (OMP_BODY (*expr_p), &body);
+ switch (TREE_CODE (*expr_p))
+ {
+ case OMP_SECTION:
+ g = gimple_build_omp_section (body);
+ break;
+ case OMP_MASTER:
+ g = gimple_build_omp_master (body);
+ break;
+ case OMP_ORDERED:
+ g = gimple_build_omp_ordered (body);
+ break;
+ case OMP_CRITICAL:
+ g = gimple_build_omp_critical (body,
+ OMP_CRITICAL_NAME (*expr_p));
+ break;
+ default:
+ gcc_unreachable ();
+ }
+ gimplify_seq_add_stmt (pre_p, g);
+ ret = GS_ALL_DONE;
+ break;
+ }
case OMP_ATOMIC:
ret = gimplify_omp_atomic (expr_p, pre_p);
break;
- case OMP_RETURN:
- case OMP_CONTINUE:
- case OMP_ATOMIC_STORE:
- case OMP_SECTIONS_SWITCH:
- ret = GS_ALL_DONE;
- break;
-
- case OMP_ATOMIC_LOAD:
- if (gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, NULL,
- is_gimple_val, fb_rvalue) != GS_ALL_DONE)
- ret = GS_ERROR;
- else
- ret = GS_ALL_DONE;
- break;
-
case POINTER_PLUS_EXPR:
/* Convert ((type *)A)+offset into &A->field_of_type_and_offset.
The second is gimple immediate saving a need for extra statement.
@@ -6264,6 +6762,7 @@ gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p,
break;
}
/* FALLTHRU */
+
default:
switch (TREE_CODE_CLASS (TREE_CODE (*expr_p)))
{
@@ -6277,18 +6776,17 @@ gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p,
Compare scalar mode aggregates as scalar mode values. Using
memcmp for them would be very inefficient at best, and is
plain wrong if bitfields are involved. */
+ {
+ tree type = TREE_TYPE (TREE_OPERAND (*expr_p, 1));
- {
- tree type = TREE_TYPE (TREE_OPERAND (*expr_p, 1));
-
- if (!AGGREGATE_TYPE_P (type))
- goto expr_2;
- else if (TYPE_MODE (type) != BLKmode)
- ret = gimplify_scalar_mode_aggregate_compare (expr_p);
- else
- ret = gimplify_variable_sized_compare (expr_p);
+ if (!AGGREGATE_TYPE_P (type))
+ goto expr_2;
+ else if (TYPE_MODE (type) != BLKmode)
+ ret = gimplify_scalar_mode_aggregate_compare (expr_p);
+ else
+ ret = gimplify_variable_sized_compare (expr_p);
- break;
+ break;
}
/* If *EXPR_P does not need to be special-cased, handle it
@@ -6304,7 +6802,7 @@ gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p,
enum gimplify_status r0, r1;
r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
- post_p, is_gimple_val, fb_rvalue);
+ post_p, is_gimple_val, fb_rvalue);
r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
post_p, is_gimple_val, fb_rvalue);
@@ -6325,6 +6823,7 @@ gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p,
}
recalculate_side_effects (*expr_p);
+
dont_recalculate:
break;
}
@@ -6392,6 +6891,7 @@ gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p,
/* Historically, the compiler has treated a bare reference
to a non-BLKmode volatile lvalue as forcing a load. */
tree type = TYPE_MAIN_VARIANT (TREE_TYPE (*expr_p));
+
/* Normally, we do not want to create a temporary for a
TREE_ADDRESSABLE type because such a type should not be
copied by bitwise-assignment. However, we make an
@@ -6401,7 +6901,8 @@ gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p,
given a TREE_ADDRESSABLE type. */
tree tmp = create_tmp_var_raw (type, "vol");
gimple_add_tmp_var (tmp);
- *expr_p = build_gimple_modify_stmt (tmp, *expr_p);
+ gimplify_assign (tmp, *expr_p, pre_p);
+ *expr_p = NULL;
}
else
/* We can't do anything useful with a volatile reference to
@@ -6413,33 +6914,68 @@ gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p,
}
/* If we are gimplifying at the statement level, we're done. Tack
- everything together and replace the original statement with the
- gimplified form. */
+ everything together and return. */
if (fallback == fb_none || is_statement)
{
- if (internal_pre || internal_post)
+ /* Since *EXPR_P has been converted into a GIMPLE tuple, clear
+ it out for GC to reclaim it. */
+ *expr_p = NULL_TREE;
+
+ if (!gimple_seq_empty_p (internal_pre)
+ || !gimple_seq_empty_p (internal_post))
{
- append_to_statement_list (*expr_p, &internal_pre);
- append_to_statement_list (internal_post, &internal_pre);
- annotate_all_with_locus (&internal_pre, input_location);
- *expr_p = internal_pre;
+ gimplify_seq_add_seq (&internal_pre, internal_post);
+ gimplify_seq_add_seq (pre_p, internal_pre);
}
- else if (!*expr_p)
- ;
- else if (TREE_CODE (*expr_p) == STATEMENT_LIST)
- annotate_all_with_locus (expr_p, input_location);
- else
- annotate_one_with_locus (*expr_p, input_location);
+
+ /* The result of gimplifying *EXPR_P is going to be the last few
+ statements in *PRE_P and *POST_P. Add location information
+ to all the statements that were added by the gimplification
+ helpers. */
+ if (!gimple_seq_empty_p (*pre_p))
+ annotate_all_with_location_after (*pre_p, pre_last_gsi, input_location);
+
+ if (!gimple_seq_empty_p (*post_p))
+ annotate_all_with_location_after (*post_p, post_last_gsi,
+ input_location);
+
goto out;
}
- /* Otherwise we're gimplifying a subexpression, so the resulting value is
- interesting. */
+#ifdef ENABLE_GIMPLE_CHECKING
+ if (*expr_p)
+ {
+ enum tree_code code = TREE_CODE (*expr_p);
+ /* These expressions should already be in gimple IR form. */
+ gcc_assert (code != MODIFY_EXPR
+ && code != ASM_EXPR
+ && code != BIND_EXPR
+ && code != CATCH_EXPR
+ && code != COND_EXPR
+ && code != EH_FILTER_EXPR
+ && code != GOTO_EXPR
+ && code != LABEL_EXPR
+ && code != LOOP_EXPR
+ && code != RESX_EXPR
+ && code != SWITCH_EXPR
+ && code != TRY_FINALLY_EXPR
+ && code != OMP_CRITICAL
+ && code != OMP_FOR
+ && code != OMP_MASTER
+ && code != OMP_ORDERED
+ && code != OMP_PARALLEL
+ && code != OMP_SECTIONS
+ && code != OMP_SECTION
+ && code != OMP_SINGLE);
+ }
+#endif
- /* If it's sufficiently simple already, we're done. Unless we are
- handling some post-effects internally; if that's the case, we need to
- copy into a temp before adding the post-effects to the tree. */
- if (!internal_post && (*gimple_test_f) (*expr_p))
+ /* Otherwise we're gimplifying a subexpression, so the resulting
+ value is interesting. If it's a valid operand that matches
+ GIMPLE_TEST_F, we're done. Unless we are handling some
+ post-effects internally; if that's the case, we need to copy into
+ a temporary before adding the post-effects to POST_P. */
+ if (gimple_seq_empty_p (internal_post) && (*gimple_test_f) (*expr_p))
goto out;
/* Otherwise, we need to create a new temporary for the gimplified
@@ -6449,7 +6985,8 @@ gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p,
object the lvalue refers to would (probably) be modified by the
postqueue; we need to copy the value out first, which means an
rvalue. */
- if ((fallback & fb_lvalue) && !internal_post
+ if ((fallback & fb_lvalue)
+ && gimple_seq_empty_p (internal_post)
&& is_gimple_addressable (*expr_p))
{
/* An lvalue will do. Take the address of the expression, store it
@@ -6459,14 +6996,15 @@ gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p,
gimplify_expr (&tmp, pre_p, post_p, is_gimple_reg, fb_rvalue);
*expr_p = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (tmp)), tmp);
}
- else if ((fallback & fb_rvalue) && is_gimple_formal_tmp_rhs (*expr_p))
+ else if ((fallback & fb_rvalue) && is_gimple_formal_tmp_or_call_rhs (*expr_p))
{
+ /* An rvalue will do. Assign the gimplified expression into a
+ new temporary TMP and replace the original expression with
+ TMP. First, make sure that the expression has a type so that
+ it can be assigned into a temporary. */
gcc_assert (!VOID_TYPE_P (TREE_TYPE (*expr_p)));
- /* An rvalue will do. Assign the gimplified expression into a new
- temporary TMP and replace the original expression with TMP. */
-
- if (internal_post || (fallback & fb_lvalue))
+ if (!gimple_seq_empty_p (internal_post) || (fallback & fb_lvalue))
/* The postqueue might change the value of the expression between
the initialization and use of the temporary, so we can't use a
formal temp. FIXME do we care? */
@@ -6479,7 +7017,7 @@ gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p,
}
else
{
-#ifdef ENABLE_CHECKING
+#ifdef ENABLE_GIMPLE_CHECKING
if (!(fallback & fb_mayfail))
{
fprintf (stderr, "gimplification failed:\n");
@@ -6489,6 +7027,7 @@ gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p,
}
#endif
gcc_assert (fallback & fb_mayfail);
+
/* If this is an asm statement, and the user asked for the
impossible, don't die. Fail and let gimplify_asm_expr
issue an error. */
@@ -6499,10 +7038,10 @@ gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p,
/* Make sure the temporary matches our predicate. */
gcc_assert ((*gimple_test_f) (*expr_p));
- if (internal_post)
+ if (!gimple_seq_empty_p (internal_post))
{
- annotate_all_with_locus (&internal_post, input_location);
- append_to_statement_list (internal_post, pre_p);
+ annotate_all_with_location (internal_post, input_location);
+ gimplify_seq_add_seq (pre_p, internal_post);
}
out:
@@ -6514,7 +7053,7 @@ gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p,
size that we find. Add to LIST_P any statements generated. */
void
-gimplify_type_sizes (tree type, tree *list_p)
+gimplify_type_sizes (tree type, gimple_seq *list_p)
{
tree field, t;
@@ -6597,10 +7136,10 @@ gimplify_type_sizes (tree type, tree *list_p)
/* A subroutine of gimplify_type_sizes to make sure that *EXPR_P,
a size or position, has had all of its SAVE_EXPRs evaluated.
- We add any required statements to STMT_P. */
+ We add any required statements to *STMT_P. */
void
-gimplify_one_sizepos (tree *expr_p, tree *stmt_p)
+gimplify_one_sizepos (tree *expr_p, gimple_seq *stmt_p)
{
tree type, expr = *expr_p;
@@ -6631,33 +7170,36 @@ gimplify_one_sizepos (tree *expr_p, tree *stmt_p)
&& TYPE_IS_SIZETYPE (type))
{
tree tmp;
+ gimple stmt;
*expr_p = create_tmp_var (type, NULL);
tmp = build1 (NOP_EXPR, type, expr);
- tmp = build_gimple_modify_stmt (*expr_p, tmp);
+ stmt = gimplify_assign (*expr_p, tmp, stmt_p);
if (EXPR_HAS_LOCATION (expr))
- SET_EXPR_LOCUS (tmp, EXPR_LOCUS (expr));
+ gimple_set_location (stmt, *EXPR_LOCUS (expr));
else
- SET_EXPR_LOCATION (tmp, input_location);
-
- gimplify_and_add (tmp, stmt_p);
+ gimple_set_location (stmt, input_location);
}
}
-
-/* Gimplify the body of statements pointed to by BODY_P. FNDECL is the
- function decl containing BODY. */
-void
+/* Gimplify the body of statements pointed to by BODY_P and return a
+ GIMPLE_BIND containing the sequence of GIMPLE statements
+ corresponding to BODY_P. FNDECL is the function decl containing
+ *BODY_P. */
+
+gimple
gimplify_body (tree *body_p, tree fndecl, bool do_parms)
{
location_t saved_location = input_location;
- tree body, parm_stmts;
+ gimple_seq parm_stmts, seq;
+ gimple outer_bind;
+ struct gimplify_ctx gctx;
timevar_push (TV_TREE_GIMPLIFY);
gcc_assert (gimplify_ctxp == NULL);
- push_gimplify_context ();
+ push_gimplify_context (&gctx);
/* Unshare most shared trees in the body and in that of any nested functions.
It would seem we don't have to do this for nested functions because
@@ -6671,63 +7213,62 @@ gimplify_body (tree *body_p, tree fndecl, bool do_parms)
/* Resolve callee-copies. This has to be done before processing
the body so that DECL_VALUE_EXPR gets processed correctly. */
- parm_stmts = do_parms ? gimplify_parameters () : NULL;
+ parm_stmts = (do_parms) ? gimplify_parameters () : NULL;
/* Gimplify the function's body. */
- gimplify_stmt (body_p);
- body = *body_p;
-
- if (!body)
- body = alloc_stmt_list ();
- else if (TREE_CODE (body) == STATEMENT_LIST)
+ seq = NULL;
+ gimplify_stmt (body_p, &seq);
+ outer_bind = gimple_seq_first_stmt (seq);
+ if (!outer_bind)
{
- tree t = expr_only (*body_p);
- if (t)
- body = t;
+ outer_bind = gimple_build_nop ();
+ gimplify_seq_add_stmt (&seq, outer_bind);
}
- /* If there isn't an outer BIND_EXPR, add one. */
- if (TREE_CODE (body) != BIND_EXPR)
- {
- tree b = build3 (BIND_EXPR, void_type_node, NULL_TREE,
- NULL_TREE, NULL_TREE);
- TREE_SIDE_EFFECTS (b) = 1;
- append_to_statement_list_force (body, &BIND_EXPR_BODY (b));
- body = b;
- }
+ /* The body must contain exactly one statement, a GIMPLE_BIND. If this is
+ not the case, wrap everything in a GIMPLE_BIND to make it so. */
+ if (gimple_code (outer_bind) == GIMPLE_BIND
+ && gimple_seq_first (seq) == gimple_seq_last (seq))
+ ;
+ else
+ outer_bind = gimple_build_bind (NULL_TREE, seq, NULL);
+
+ *body_p = NULL_TREE;
/* If we had callee-copies statements, insert them at the beginning
of the function. */
- if (parm_stmts)
+ if (!gimple_seq_empty_p (parm_stmts))
{
- append_to_statement_list_force (BIND_EXPR_BODY (body), &parm_stmts);
- BIND_EXPR_BODY (body) = parm_stmts;
+ gimplify_seq_add_seq (&parm_stmts, gimple_bind_body (outer_bind));
+ gimple_bind_set_body (outer_bind, parm_stmts);
}
- /* Unshare again, in case gimplification was sloppy. */
- unshare_all_trees (body);
-
- *body_p = body;
-
- pop_gimplify_context (body);
+ pop_gimplify_context (outer_bind);
gcc_assert (gimplify_ctxp == NULL);
#ifdef ENABLE_TYPES_CHECKING
if (!errorcount && !sorrycount)
- verify_gimple_1 (BIND_EXPR_BODY (*body_p));
+ verify_types_in_gimple_seq (gimple_bind_body (outer_bind));
#endif
timevar_pop (TV_TREE_GIMPLIFY);
input_location = saved_location;
+
+ return outer_bind;
}
/* Entry point to the gimplification pass. FNDECL is the FUNCTION_DECL
- node for the function we want to gimplify. */
+ node for the function we want to gimplify.
+
+ Returns the sequence of GIMPLE statements corresponding to the body
+ of FNDECL. */
void
gimplify_function_tree (tree fndecl)
{
tree oldfn, parm, ret;
+ gimple_seq seq;
+ gimple bind;
oldfn = current_function_decl;
current_function_decl = fndecl;
@@ -6754,7 +7295,13 @@ gimplify_function_tree (tree fndecl)
&& !needs_to_live_in_memory (ret))
DECL_GIMPLE_REG_P (ret) = 1;
- gimplify_body (&DECL_SAVED_TREE (fndecl), fndecl, true);
+ bind = gimplify_body (&DECL_SAVED_TREE (fndecl), fndecl, true);
+
+ /* The tree body of the function is no longer needed, replace it
+ with the new GIMPLE body. */
+ seq = gimple_seq_alloc ();
+ gimple_seq_add_stmt (&seq, bind);
+ gimple_set_body (fndecl, seq);
/* If we're instrumenting function entry/exit, then prepend the call to
the entry hook and wrap the whole function in a TRY_FINALLY_EXPR to
@@ -6764,57 +7311,262 @@ gimplify_function_tree (tree fndecl)
&& !DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (fndecl)
&& !flag_instrument_functions_exclude_p (fndecl))
{
- tree tf, x, bind;
+ tree x;
+ gimple new_bind;
+ gimple tf;
+ gimple_seq cleanup = NULL, body = NULL;
- tf = build2 (TRY_FINALLY_EXPR, void_type_node, NULL, NULL);
- TREE_SIDE_EFFECTS (tf) = 1;
- x = DECL_SAVED_TREE (fndecl);
- append_to_statement_list (x, &TREE_OPERAND (tf, 0));
x = implicit_built_in_decls[BUILT_IN_PROFILE_FUNC_EXIT];
- x = build_call_expr (x, 0);
- append_to_statement_list (x, &TREE_OPERAND (tf, 1));
+ gimplify_seq_add_stmt (&cleanup, gimple_build_call (x, 0));
+ tf = gimple_build_try (seq, cleanup, GIMPLE_TRY_FINALLY);
- bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
- TREE_SIDE_EFFECTS (bind) = 1;
x = implicit_built_in_decls[BUILT_IN_PROFILE_FUNC_ENTER];
- x = build_call_expr (x, 0);
- append_to_statement_list (x, &BIND_EXPR_BODY (bind));
- append_to_statement_list (tf, &BIND_EXPR_BODY (bind));
+ gimplify_seq_add_stmt (&body, gimple_build_call (x, 0));
+ gimplify_seq_add_stmt (&body, tf);
+ new_bind = gimple_build_bind (NULL, body, gimple_block (bind));
+ /* Clear the block for BIND, since it is no longer directly inside
+ the function, but within a try block. */
+ gimple_set_block (bind, NULL);
- DECL_SAVED_TREE (fndecl) = bind;
+ /* Replace the current function body with the body
+ wrapped in the try/finally TF. */
+ seq = gimple_seq_alloc ();
+ gimple_seq_add_stmt (&seq, new_bind);
+ gimple_set_body (fndecl, seq);
}
+ DECL_SAVED_TREE (fndecl) = NULL_TREE;
+
current_function_decl = oldfn;
pop_cfun ();
}
-
+
+
+/* Some transformations like inlining may invalidate the GIMPLE form
+ for operands. This function traverses all the operands in STMT and
+ gimplifies anything that is not a valid gimple operand. Any new
+ GIMPLE statements are inserted before *GSI_P. */
+
+void
+gimple_regimplify_operands (gimple stmt, gimple_stmt_iterator *gsi_p)
+{
+ size_t i, num_ops;
+ tree orig_lhs = NULL_TREE, lhs, t;
+ gimple_seq pre = NULL;
+ gimple post_stmt = NULL;
+ struct gimplify_ctx gctx;
+
+ push_gimplify_context (&gctx);
+ gimplify_ctxp->into_ssa = gimple_in_ssa_p (cfun);
+
+ switch (gimple_code (stmt))
+ {
+ case GIMPLE_COND:
+ gimplify_expr (gimple_cond_lhs_ptr (stmt), &pre, NULL,
+ is_gimple_val, fb_rvalue);
+ gimplify_expr (gimple_cond_rhs_ptr (stmt), &pre, NULL,
+ is_gimple_val, fb_rvalue);
+ break;
+ case GIMPLE_OMP_ATOMIC_LOAD:
+ gimplify_expr (gimple_omp_atomic_load_rhs_ptr (stmt), &pre, NULL,
+ is_gimple_val, fb_rvalue);
+ break;
+ case GIMPLE_ASM:
+ {
+ size_t i, noutputs = gimple_asm_noutputs (stmt);
+ const char *constraint, **oconstraints;
+ bool allows_mem, allows_reg, is_inout;
+
+ oconstraints
+ = (const char **) alloca ((noutputs) * sizeof (const char *));
+ for (i = 0; i < noutputs; i++)
+ {
+ tree op = gimple_asm_output_op (stmt, i);
+ constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (op)));
+ oconstraints[i] = constraint;
+ parse_output_constraint (&constraint, i, 0, 0, &allows_mem,
+ &allows_reg, &is_inout);
+ gimplify_expr (&TREE_VALUE (op), &pre, NULL,
+ is_inout ? is_gimple_min_lval : is_gimple_lvalue,
+ fb_lvalue | fb_mayfail);
+ }
+ for (i = 0; i < gimple_asm_ninputs (stmt); i++)
+ {
+ tree op = gimple_asm_input_op (stmt, i);
+ constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (op)));
+ parse_input_constraint (&constraint, 0, 0, noutputs, 0,
+ oconstraints, &allows_mem, &allows_reg);
+ if (TREE_ADDRESSABLE (TREE_TYPE (TREE_VALUE (op))) && allows_mem)
+ allows_reg = 0;
+ if (!allows_reg && allows_mem)
+ gimplify_expr (&TREE_VALUE (op), &pre, NULL,
+ is_gimple_lvalue, fb_lvalue | fb_mayfail);
+ else
+ gimplify_expr (&TREE_VALUE (op), &pre, NULL,
+ is_gimple_asm_val, fb_rvalue);
+ }
+ }
+ break;
+ default:
+ /* NOTE: We start gimplifying operands from last to first to
+ make sure that side-effects on the RHS of calls, assignments
+ and ASMs are executed before the LHS. The ordering is not
+ important for other statements. */
+ num_ops = gimple_num_ops (stmt);
+ orig_lhs = gimple_get_lhs (stmt);
+ for (i = num_ops; i > 0; i--)
+ {
+ tree op = gimple_op (stmt, i - 1);
+ if (op == NULL_TREE)
+ continue;
+ if (i == 1 && (is_gimple_call (stmt) || is_gimple_assign (stmt)))
+ gimplify_expr (&op, &pre, NULL, is_gimple_lvalue, fb_lvalue);
+ else if (i == 2
+ && is_gimple_assign (stmt)
+ && num_ops == 2
+ && get_gimple_rhs_class (gimple_expr_code (stmt))
+ == GIMPLE_SINGLE_RHS)
+ gimplify_expr (&op, &pre, NULL,
+ rhs_predicate_for (gimple_assign_lhs (stmt)),
+ fb_rvalue);
+ else if (i == 2 && is_gimple_call (stmt))
+ {
+ if (TREE_CODE (op) == FUNCTION_DECL)
+ continue;
+ gimplify_expr (&op, &pre, NULL, is_gimple_call_addr, fb_rvalue);
+ }
+ else
+ gimplify_expr (&op, &pre, NULL, is_gimple_val, fb_rvalue);
+ gimple_set_op (stmt, i - 1, op);
+ }
+
+ lhs = gimple_get_lhs (stmt);
+ /* If regimplification of the LHS changed it in a way that requires
+ a simple RHS, create temporary. */
+ if (orig_lhs != lhs && !is_gimple_formal_tmp_var (lhs))
+ {
+ bool need_temp = false;
+
+ if (is_gimple_assign (stmt)
+ && num_ops == 2
+ && get_gimple_rhs_class (gimple_expr_code (stmt))
+ == GIMPLE_SINGLE_RHS)
+ gimplify_expr (gimple_assign_rhs1_ptr (stmt), &pre, NULL,
+ rhs_predicate_for (gimple_assign_lhs (stmt)),
+ fb_rvalue);
+ else if (is_gimple_reg (lhs))
+ {
+ if (is_gimple_reg_type (TREE_TYPE (lhs)))
+ {
+ if (is_gimple_call (stmt))
+ {
+ i = gimple_call_flags (stmt);
+ if ((i & ECF_LOOPING_CONST_OR_PURE)
+ || !(i & (ECF_CONST | ECF_PURE)))
+ need_temp = true;
+ }
+ if (stmt_can_throw_internal (stmt))
+ need_temp = true;
+ }
+ }
+ else
+ {
+ if (is_gimple_reg_type (TREE_TYPE (lhs)))
+ need_temp = true;
+ else if (TYPE_MODE (TREE_TYPE (lhs)) != BLKmode)
+ {
+ if (is_gimple_call (stmt))
+ {
+ tree fndecl = gimple_call_fndecl (stmt);
+
+ if (!aggregate_value_p (TREE_TYPE (lhs), fndecl)
+ && !(fndecl && DECL_RESULT (fndecl)
+ && DECL_BY_REFERENCE (DECL_RESULT (fndecl))))
+ need_temp = true;
+ }
+ else
+ need_temp = true;
+ }
+ }
+ if (need_temp)
+ {
+ tree temp = create_tmp_var (TREE_TYPE (lhs), NULL);
+
+ DECL_GIMPLE_FORMAL_TEMP_P (temp) = 1;
+ if (TREE_CODE (TREE_TYPE (lhs)) == COMPLEX_TYPE
+ || TREE_CODE (TREE_TYPE (lhs)) == VECTOR_TYPE)
+ DECL_GIMPLE_REG_P (temp) = 1;
+ if (TREE_CODE (orig_lhs) == SSA_NAME)
+ orig_lhs = SSA_NAME_VAR (orig_lhs);
+ if (TREE_CODE (orig_lhs) == VAR_DECL
+ && DECL_BASED_ON_RESTRICT_P (orig_lhs))
+ {
+ DECL_BASED_ON_RESTRICT_P (temp) = 1;
+ SET_DECL_RESTRICT_BASE (temp,
+ DECL_GET_RESTRICT_BASE (orig_lhs));
+ }
+
+ if (gimple_in_ssa_p (cfun))
+ temp = make_ssa_name (temp, NULL);
+ gimple_set_lhs (stmt, temp);
+ post_stmt = gimple_build_assign (lhs, temp);
+ if (TREE_CODE (lhs) == SSA_NAME)
+ SSA_NAME_DEF_STMT (lhs) = post_stmt;
+ }
+ }
+ break;
+ }
+
+ if (!gimple_seq_empty_p (pre))
+ {
+ if (gimple_in_ssa_p (cfun))
+ {
+ gimple_stmt_iterator i;
+
+ for (i = gsi_start (pre); !gsi_end_p (i); gsi_next (&i))
+ mark_symbols_for_renaming (gsi_stmt (i));
+ }
+ gsi_insert_seq_before (gsi_p, pre, GSI_SAME_STMT);
+ }
+ if (post_stmt)
+ gsi_insert_after (gsi_p, post_stmt, GSI_NEW_STMT);
+
+ if (gimple_referenced_vars (cfun))
+ for (t = gimplify_ctxp->temps; t ; t = TREE_CHAIN (t))
+ add_referenced_var (t);
+
+ pop_gimplify_context (NULL);
+}
+
+
/* Expands EXPR to list of gimple statements STMTS. If SIMPLE is true,
force the result to be either ssa_name or an invariant, otherwise
just force it to be a rhs expression. If VAR is not NULL, make the
base variable of the final destination be VAR if suitable. */
tree
-force_gimple_operand (tree expr, tree *stmts, bool simple, tree var)
+force_gimple_operand (tree expr, gimple_seq *stmts, bool simple, tree var)
{
tree t;
enum gimplify_status ret;
gimple_predicate gimple_test_f;
+ struct gimplify_ctx gctx;
- *stmts = NULL_TREE;
+ *stmts = NULL;
if (is_gimple_val (expr))
return expr;
gimple_test_f = simple ? is_gimple_val : is_gimple_reg_rhs;
- push_gimplify_context ();
+ push_gimplify_context (&gctx);
gimplify_ctxp->into_ssa = gimple_in_ssa_p (cfun);
gimplify_ctxp->allow_rhs_cond_expr = true;
if (var)
- expr = build_gimple_modify_stmt (var, expr);
+ expr = build2 (MODIFY_EXPR, TREE_TYPE (var), var, expr);
- if (TREE_CODE (expr) != GIMPLE_MODIFY_STMT
+ if (TREE_CODE (expr) != MODIFY_EXPR
&& TREE_TYPE (expr) == void_type_node)
{
gimplify_and_add (expr, stmts);
@@ -6822,16 +7574,13 @@ force_gimple_operand (tree expr, tree *stmts, bool simple, tree var)
}
else
{
- ret = gimplify_expr (&expr, stmts, NULL,
- gimple_test_f, fb_rvalue);
+ ret = gimplify_expr (&expr, stmts, NULL, gimple_test_f, fb_rvalue);
gcc_assert (ret != GS_ERROR);
}
if (gimple_referenced_vars (cfun))
- {
- for (t = gimplify_ctxp->temps; t ; t = TREE_CHAIN (t))
- add_referenced_var (t);
- }
+ for (t = gimplify_ctxp->temps; t ; t = TREE_CHAIN (t))
+ add_referenced_var (t);
pop_gimplify_context (NULL);
@@ -6839,33 +7588,34 @@ force_gimple_operand (tree expr, tree *stmts, bool simple, tree var)
}
/* Invokes force_gimple_operand for EXPR with parameters SIMPLE_P and VAR. If
- some statements are produced, emits them at BSI. If BEFORE is true.
- the statements are appended before BSI, otherwise they are appended after
- it. M specifies the way BSI moves after insertion (BSI_SAME_STMT or
- BSI_CONTINUE_LINKING are the usual values). */
+ some statements are produced, emits them at GSI. If BEFORE is true.
+ the statements are appended before GSI, otherwise they are appended after
+ it. M specifies the way GSI moves after insertion (GSI_SAME_STMT or
+ GSI_CONTINUE_LINKING are the usual values). */
tree
-force_gimple_operand_bsi (block_stmt_iterator *bsi, tree expr,
+force_gimple_operand_gsi (gimple_stmt_iterator *gsi, tree expr,
bool simple_p, tree var, bool before,
- enum bsi_iterator_update m)
+ enum gsi_iterator_update m)
{
- tree stmts;
+ gimple_seq stmts;
expr = force_gimple_operand (expr, &stmts, simple_p, var);
- if (stmts)
+
+ if (!gimple_seq_empty_p (stmts))
{
if (gimple_in_ssa_p (cfun))
{
- tree_stmt_iterator tsi;
+ gimple_stmt_iterator i;
- for (tsi = tsi_start (stmts); !tsi_end_p (tsi); tsi_next (&tsi))
- mark_symbols_for_renaming (tsi_stmt (tsi));
+ for (i = gsi_start (stmts); !gsi_end_p (i); gsi_next (&i))
+ mark_symbols_for_renaming (gsi_stmt (i));
}
if (before)
- bsi_insert_before (bsi, stmts, m);
+ gsi_insert_seq_before (gsi, stmts, m);
else
- bsi_insert_after (bsi, stmts, m);
+ gsi_insert_seq_after (gsi, stmts, m);
}
return expr;
diff --git a/gcc/global.c b/gcc/global.c
index 5ac45a32c92..f0643ab0111 100644
--- a/gcc/global.c
+++ b/gcc/global.c
@@ -989,7 +989,7 @@ find_reg (int num, HARD_REG_SET losers, int alt_regs_p, int accept_call_clobbere
int i, best_reg, pass;
HARD_REG_SET used, used1, used2;
- enum reg_class class = (alt_regs_p
+ enum reg_class rclass = (alt_regs_p
? reg_alternate_class (allocno[num].reg)
: reg_preferred_class (allocno[num].reg));
enum machine_mode mode = PSEUDO_REGNO_MODE (allocno[num].reg);
@@ -1006,7 +1006,7 @@ find_reg (int num, HARD_REG_SET losers, int alt_regs_p, int accept_call_clobbere
if (losers)
IOR_HARD_REG_SET (used1, losers);
- IOR_COMPL_HARD_REG_SET (used1, reg_class_contents[(int) class]);
+ IOR_COMPL_HARD_REG_SET (used1, reg_class_contents[(int) rclass]);
#ifdef EH_RETURN_DATA_REGNO
if (allocno[num].no_eh_reg)
diff --git a/gcc/graph.c b/gcc/graph.c
index e59adbc3677..643571b6af2 100644
--- a/gcc/graph.c
+++ b/gcc/graph.c
@@ -165,25 +165,25 @@ darkgrey\n shape: ellipse" : "white",
}
static void
-draw_edge (FILE *fp, int from, int to, int bb_edge, int class)
+draw_edge (FILE *fp, int from, int to, int bb_edge, int color_class)
{
const char * color;
switch (graph_dump_format)
{
case vcg:
color = "";
- if (class == 2)
+ if (color_class == 2)
color = "color: red ";
else if (bb_edge)
color = "color: blue ";
- else if (class == 3)
+ else if (color_class == 3)
color = "color: green ";
fprintf (fp,
"edge: { sourcename: \"%s.%d\" targetname: \"%s.%d\" %s",
current_function_name (), from,
current_function_name (), to, color);
- if (class)
- fprintf (fp, "class: %d ", class);
+ if (color_class)
+ fprintf (fp, "class: %d ", color_class);
fputs ("}\n", fp);
break;
case no_graph:
diff --git a/gcc/gsstruct.def b/gcc/gsstruct.def
new file mode 100644
index 00000000000..b524a37bcf4
--- /dev/null
+++ b/gcc/gsstruct.def
@@ -0,0 +1,48 @@
+/* This file contains the definitions for the gimple IR structure
+ enumeration used in GCC.
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Contributed by Aldy Hernandez <aldyh@redhat.com>
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+/* The format of this file is
+ DEFGSSTRUCT(GSS_enumeration value, printable name).
+ Each enum value should correspond with a single member of the union
+ gimple_statement_d. */
+
+DEFGSSTRUCT(GSS_BASE, "base")
+DEFGSSTRUCT(GSS_WITH_OPS, "with_ops")
+DEFGSSTRUCT(GSS_WITH_MEM_OPS, "with_mem_ops")
+DEFGSSTRUCT(GSS_OMP, "omp")
+DEFGSSTRUCT(GSS_BIND, "bind")
+DEFGSSTRUCT(GSS_CATCH, "catch")
+DEFGSSTRUCT(GSS_EH_FILTER, "eh_filter")
+DEFGSSTRUCT(GSS_PHI, "phi")
+DEFGSSTRUCT(GSS_RESX, "resx")
+DEFGSSTRUCT(GSS_TRY, "try")
+DEFGSSTRUCT(GSS_WCE, "with_cleanup_expression")
+DEFGSSTRUCT(GSS_ASM, "asm")
+DEFGSSTRUCT(GSS_OMP_CRITICAL, "omp_critical")
+DEFGSSTRUCT(GSS_OMP_FOR, "omp_for")
+DEFGSSTRUCT(GSS_OMP_PARALLEL, "omp_parallel")
+DEFGSSTRUCT(GSS_OMP_TASK, "omp_task")
+DEFGSSTRUCT(GSS_OMP_SECTIONS, "sections")
+DEFGSSTRUCT(GSS_OMP_SINGLE, "single")
+DEFGSSTRUCT(GSS_OMP_CONTINUE, "omp_continue")
+DEFGSSTRUCT(GSS_OMP_ATOMIC_LOAD, "omp_atomic_load")
+DEFGSSTRUCT(GSS_OMP_ATOMIC_STORE, "omp_atomic_store")
diff --git a/gcc/input.h b/gcc/input.h
index 5d432592315..299f56c3ce6 100644
--- a/gcc/input.h
+++ b/gcc/input.h
@@ -41,6 +41,9 @@ typedef struct GTY (())
int line;
int column;
+
+ /* In a system header?. */
+ bool sysp;
} expanded_location;
extern expanded_location expand_location (source_location);
@@ -59,5 +62,7 @@ extern location_t input_location;
#define input_line LOCATION_LINE (input_location)
#define input_filename LOCATION_FILE (input_location)
+#define in_system_header_at(LOC) ((expand_location (LOC)).sysp != 0)
+#define in_system_header (in_system_header_at (input_location))
#endif
diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c
index 9e2153141d3..af1cc0fd787 100644
--- a/gcc/ipa-cp.c
+++ b/gcc/ipa-cp.c
@@ -153,7 +153,7 @@ static void
ipcp_init_cloned_node (struct cgraph_node *orig_node,
struct cgraph_node *new_node)
{
- ipa_create_node_params (new_node);
+ ipa_check_create_node_params ();
IPA_NODE_REF (new_node)->ipcp_orig_node = orig_node;
ipa_count_formal_params (new_node);
ipa_create_param_decls_array (new_node);
@@ -183,6 +183,18 @@ ipcp_lat_is_const (struct ipcp_lattice *lat)
return false;
}
+/* Return whether LAT is a constant lattice that ipa-cp can actually insert
+ into the code (i.e. constants excluding member pointers and pointers). */
+static inline bool
+ipcp_lat_is_insertable (struct ipcp_lattice *lat)
+{
+ if ((lat->type == IPA_CONST_VALUE || lat->type == IPA_CONST_VALUE_REF)
+ && !POINTER_TYPE_P (TREE_TYPE (lat->constant)))
+ return true;
+ else
+ return false;
+}
+
/* Return true if LAT1 and LAT2 are equal. */
static inline bool
ipcp_lats_are_equal (struct ipcp_lattice *lat1, struct ipcp_lattice *lat2)
@@ -247,9 +259,7 @@ static void
ipcp_lattice_from_jfunc (struct ipa_node_params *info, struct ipcp_lattice *lat,
struct ipa_jump_func *jfunc)
{
- if (jfunc->type == IPA_UNKNOWN)
- lat->type = IPA_BOTTOM;
- else if (jfunc->type == IPA_CONST)
+ if (jfunc->type == IPA_CONST)
{
lat->type = IPA_CONST_VALUE;
lat->constant = jfunc->value.constant;
@@ -267,6 +277,8 @@ ipcp_lattice_from_jfunc (struct ipa_node_params *info, struct ipcp_lattice *lat,
lat->type = caller_lat->type;
lat->constant = caller_lat->constant;
}
+ else
+ lat->type = IPA_BOTTOM;
}
/* True when OLD and NEW values are not the same. */
@@ -293,23 +305,28 @@ ipcp_print_all_lattices (FILE * f)
fprintf (f, "\nLATTICE PRINT\n");
for (node = cgraph_nodes; node; node = node->next)
{
- struct ipa_node_params *info = IPA_NODE_REF (node);
+ struct ipa_node_params *info;
+
+ if (!node->analyzed)
+ continue;
+ info = IPA_NODE_REF (node);
fprintf (f, "Printing lattices %s:\n", cgraph_node_name (node));
count = ipa_get_param_count (info);
for (i = 0; i < count; i++)
{
struct ipcp_lattice *lat = ipcp_get_ith_lattice (info, i);
+
+ fprintf (f, " param [%d]: ", i);
if (lat->type == IPA_CONST_VALUE || lat->type == IPA_CONST_VALUE_REF)
{
- fprintf (f, " param [%d]: ", i);
fprintf (f, "type is CONST ");
print_generic_expr (f, lat->constant, 0);
fprintf (f, "\n");
}
else if (lat->type == IPA_TOP)
- fprintf (f, "param [%d]: type is TOP \n", i);
+ fprintf (f, "type is TOP\n");
else
- fprintf (f, "param [%d]: type is BOTTOM \n", i);
+ fprintf (f, "type is BOTTOM\n");
}
}
}
@@ -342,18 +359,15 @@ ipcp_initialize_node_lattices (struct cgraph_node *node)
/* Create a new assignment statement and make it the first statement in the
function. PARM1 is the lhs of the assignment and VAL is the rhs. */
static void
-constant_val_insert (tree parm1, tree val)
+constant_val_insert (tree parm1 ATTRIBUTE_UNUSED, tree val ATTRIBUTE_UNUSED)
{
- tree init_stmt = NULL;
+ gimple init_stmt = NULL;
edge e_step;
- init_stmt = build_gimple_modify_stmt (parm1, val);
-
- if (init_stmt)
- {
- e_step = single_succ_edge (ENTRY_BLOCK_PTR_FOR_FUNCTION (cfun));
- bsi_insert_on_edge_immediate (e_step, init_stmt);
- }
+ init_stmt = gimple_build_assign (parm1, val);
+ gcc_assert (init_stmt);
+ e_step = single_succ_edge (ENTRY_BLOCK_PTR_FOR_FUNCTION (cfun));
+ gsi_insert_on_edge_immediate (e_step, init_stmt);
}
/* build INTEGER_CST tree with type TREE_TYPE and value according to LAT.
@@ -413,6 +427,11 @@ ipcp_init_stage (void)
for (node = cgraph_nodes; node; node = node->next)
{
+ if (!node->analyzed)
+ continue;
+ /* Unreachable nodes should have been eliminated before ipcp. */
+ gcc_assert (node->needed || node->reachable);
+
ipa_count_formal_params (node);
ipa_create_param_decls_array (node);
ipcp_initialize_node_lattices (node);
@@ -421,9 +440,13 @@ ipcp_init_stage (void)
}
for (node = cgraph_nodes; node; node = node->next)
{
+ if (!node->analyzed)
+ continue;
/* building jump functions */
for (cs = node->callees; cs; cs = cs->next_callee)
{
+ if (!cs->callee->analyzed)
+ continue;
ipa_count_arguments (cs);
if (ipa_get_cs_argument_count (IPA_EDGE_REF (cs))
!= ipa_get_param_count (IPA_NODE_REF (cs->callee)))
@@ -480,6 +503,8 @@ ipcp_propagate_stage (void)
struct ipa_func_list *wl;
int count;
+ ipa_check_create_node_params ();
+ ipa_check_create_edge_args ();
/* Initialize worklist to contain all functions. */
wl = ipa_init_func_list ();
while (wl)
@@ -536,54 +561,6 @@ ipcp_node_not_modifiable_p (struct cgraph_node *node)
return false;
}
-/* Print ipa_jump_func data structures to F. */
-static void
-ipcp_print_all_jump_functions (FILE * f)
-{
- struct cgraph_node *node;
- int i, count;
- struct cgraph_edge *cs;
- struct ipa_jump_func *jump_func;
- enum jump_func_type type;
- tree info_type;
-
- fprintf (f, "\nCALLSITE PARAM PRINT\n");
- for (node = cgraph_nodes; node; node = node->next)
- {
- for (cs = node->callees; cs; cs = cs->next_callee)
- {
- fprintf (f, "callsite %s ", cgraph_node_name (node));
- fprintf (f, "-> %s :: \n", cgraph_node_name (cs->callee));
-
- if (ipa_is_called_with_var_arguments (IPA_NODE_REF (cs->callee)))
- continue;
-
- count = ipa_get_cs_argument_count (IPA_EDGE_REF (cs));
- for (i = 0; i < count; i++)
- {
- jump_func = ipa_get_ith_jump_func (IPA_EDGE_REF (cs), i);
- type = jump_func->type;
-
- fprintf (f, " param %d: ", i);
- if (type == IPA_UNKNOWN)
- fprintf (f, "UNKNOWN\n");
- else if (type == IPA_CONST || type == IPA_CONST_REF)
- {
- info_type = jump_func->value.constant;
- fprintf (f, "CONST : ");
- print_generic_expr (f, info_type, 0);
- fprintf (f, "\n");
- }
- else if (type == IPA_PASS_THROUGH)
- {
- fprintf (f, "PASS THROUGH : ");
- fprintf (f, "%d\n", jump_func->value.formal_id);
- }
- }
- }
- }
-}
-
/* Print count scale data structures. */
static void
ipcp_function_scale_print (FILE * f)
@@ -592,6 +569,8 @@ ipcp_function_scale_print (FILE * f)
for (node = cgraph_nodes; node; node = node->next)
{
+ if (!node->analyzed)
+ continue;
fprintf (f, "printing scale for %s: ", cgraph_node_name (node));
fprintf (f, "value is " HOST_WIDE_INT_PRINT_DEC
" \n", (HOST_WIDE_INT) ipcp_get_node_scale (node));
@@ -643,7 +622,7 @@ ipcp_print_edge_profiles (FILE * f)
for (node = cgraph_nodes; node; node = node->next)
{
fprintf (f, "function %s: \n", cgraph_node_name (node));
- if (DECL_SAVED_TREE (node->decl))
+ if (node->analyzed)
{
bb =
ENTRY_BLOCK_PTR_FOR_FUNCTION (DECL_STRUCT_FUNCTION (node->decl));
@@ -730,8 +709,8 @@ ipcp_print_all_structures (FILE * f)
ipcp_print_all_lattices (f);
ipcp_function_scale_print (f);
ipa_print_all_tree_maps (f);
- ipa_print_all_params_modified (f);
- ipcp_print_all_jump_functions (f);
+ ipa_print_all_param_flags (f);
+ ipa_print_all_jump_functions (f);
}
/* Print profile info for all functions. */
@@ -760,10 +739,8 @@ ipcp_create_replace_map (struct function *func, tree parm_tree,
tree const_val;
replace_map = XCNEW (struct ipa_replace_map);
- gcc_assert (ipcp_lat_is_const (lat));
- if (lat->type != IPA_CONST_VALUE_REF
- && is_gimple_reg (parm_tree) && gimple_default_def (func, parm_tree)
- && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (gimple_default_def (func,
+ if (is_gimple_reg (parm_tree) && gimple_default_def (func, parm_tree)
+ && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (gimple_default_def (func,
parm_tree)))
{
if (dump_file)
@@ -820,7 +797,7 @@ ipcp_update_callgraph (void)
for (node = cgraph_nodes; node; node = node->next)
{
/* want to fix only original nodes */
- if (ipcp_node_is_clone (node))
+ if (!node->analyzed || ipcp_node_is_clone (node))
continue;
for (cs = node->callees; cs; cs = cs->next_callee)
if (ipcp_node_is_clone (cs->callee))
@@ -830,9 +807,7 @@ ipcp_update_callgraph (void)
if (ipcp_need_redirect_p (cs))
{
cgraph_redirect_edge_callee (cs, orig_callee);
- TREE_OPERAND (CALL_EXPR_FN (get_call_expr_in (cs->call_stmt)),
- 0) =
- orig_callee->decl;
+ gimple_call_set_fn (cs->call_stmt, orig_callee->decl);
}
}
}
@@ -906,20 +881,24 @@ ipcp_insert_stage (void)
tree parm_tree;
struct ipa_replace_map *replace_param;
+ ipa_check_create_node_params ();
+ ipa_check_create_edge_args ();
+
for (node = cgraph_nodes; node; node = node->next)
{
- struct ipa_node_params *info = IPA_NODE_REF (node);
- /* Propagation of the constant is forbidden in
- certain conditions. */
- if (!node->analyzed || ipcp_node_not_modifiable_p (node)
- || ipa_is_called_with_var_arguments (info))
+ struct ipa_node_params *info;
+ /* Propagation of the constant is forbidden in certain conditions. */
+ if (!node->analyzed || ipcp_node_not_modifiable_p (node))
+ continue;
+ info = IPA_NODE_REF (node);
+ if (ipa_is_called_with_var_arguments (info))
continue;
const_param = 0;
count = ipa_get_param_count (info);
for (i = 0; i < count; i++)
{
struct ipcp_lattice *lat = ipcp_get_ith_lattice (info, i);
- if (ipcp_lat_is_const (lat))
+ if (ipcp_lat_is_insertable (lat))
const_param++;
}
if (const_param == 0)
@@ -928,7 +907,8 @@ ipcp_insert_stage (void)
for (i = 0; i < count; i++)
{
struct ipcp_lattice *lat = ipcp_get_ith_lattice (info, i);
- if (ipcp_lat_is_const (lat))
+ if (lat->type == IPA_CONST_VALUE
+ && !POINTER_TYPE_P (TREE_TYPE (lat->constant)))
{
parm_tree = ipa_get_ith_param (info, i);
replace_param =
@@ -959,13 +939,13 @@ ipcp_insert_stage (void)
if (const_param > 0)
{
push_cfun (DECL_STRUCT_FUNCTION (node1->decl));
- tree_register_cfg_hooks ();
+ gimple_register_cfg_hooks ();
current_function_decl = node1->decl;
for (i = 0; i < count; i++)
{
struct ipcp_lattice *lat = ipcp_get_ith_lattice (info, i);
- if (ipcp_lat_is_const (lat))
+ if (ipcp_lat_is_insertable (lat))
{
parm_tree = ipa_get_ith_param (info, i);
if (lat->type != IPA_CONST_VALUE_REF
@@ -998,8 +978,9 @@ ipcp_driver (void)
{
if (dump_file)
fprintf (dump_file, "\nIPA constant propagation start:\n");
- ipa_create_all_node_params ();
- ipa_create_all_edge_args ();
+ ipa_check_create_node_params ();
+ ipa_check_create_edge_args ();
+ ipa_register_cgraph_hooks ();
/* 1. Call the init stage to initialize
the ipa_node_params and ipa_edge_args structures. */
ipcp_init_stage ();
@@ -1025,8 +1006,7 @@ ipcp_driver (void)
ipcp_print_profile_data (dump_file);
}
/* Free all IPCP structures. */
- ipa_free_all_node_params ();
- ipa_free_all_edge_args ();
+ free_all_ipa_structures_after_ipa_cp ();
if (dump_file)
fprintf (dump_file, "\nIPA constant propagation end\n");
cgraph_remove_unreachable_nodes (true, NULL);
diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c
index 6d74c1f71b7..0ccaa6bb24f 100644
--- a/gcc/ipa-inline.c
+++ b/gcc/ipa-inline.c
@@ -60,7 +60,7 @@ along with GCC; see the file COPYING3. If not see
cgraph_decide_inlining implements heuristics taking whole callgraph
into account, while cgraph_decide_inlining_incrementally considers
- only one function at a time and is used in non-unit-at-a-time mode.
+ only one function at a time and is used by early inliner.
The inliner itself is split into several passes:
@@ -82,15 +82,13 @@ along with GCC; see the file COPYING3. If not see
to do inlining expanding code size it might result in unbounded growth of
whole unit.
- This is the main inlining pass in non-unit-at-a-time.
-
- With unit-at-a-time the pass is run during conversion into SSA form.
- Only functions already converted into SSA form are inlined, so the
- conversion must happen in topological order on the callgraph (that is
- maintained by pass manager). The functions after inlining are early
- optimized so the early inliner sees unoptimized function itself, but
- all considered callees are already optimized allowing it to unfold
- abstraction penalty on C++ effectively and cheaply.
+ The pass is run during conversion into SSA form. Only functions already
+ converted into SSA form are inlined, so the conversion must happen in
+ topological order on the callgraph (that is maintained by pass manager).
+ The functions after inlining are early optimized so the early inliner sees
+ unoptimized function itself, but all considered callees are already
+ optimized allowing it to unfold abstraction penalty on C++ effectively and
+ cheaply.
pass_ipa_early_inlining
@@ -139,6 +137,7 @@ along with GCC; see the file COPYING3. If not see
#include "ggc.h"
#include "tree-flow.h"
#include "rtl.h"
+#include "ipa-prop.h"
/* Mode incremental inliner operate on:
@@ -149,16 +148,11 @@ along with GCC; see the file COPYING3. If not see
In SIZE mode, only functions that reduce function body size after inlining
are inlined, this is used during early inlining.
- In SPEED mode, all small functions are inlined. This might result in
- unbounded growth of compilation unit and is used only in non-unit-at-a-time
- mode.
-
in ALL mode, everything is inlined. This is used during flattening. */
enum inlining_mode {
INLINE_NONE = 0,
INLINE_ALWAYS_INLINE,
INLINE_SIZE,
- INLINE_SPEED,
INLINE_ALL
};
static bool
@@ -201,20 +195,21 @@ cgraph_estimate_size_after_inlining (int times, struct cgraph_node *to,
clones or re-using node originally representing out-of-line function call.
*/
void
-cgraph_clone_inlined_nodes (struct cgraph_edge *e, bool duplicate, bool update_original)
+cgraph_clone_inlined_nodes (struct cgraph_edge *e, bool duplicate,
+ bool update_original)
{
HOST_WIDE_INT peak;
+
if (duplicate)
{
/* We may eliminate the need for out-of-line copy to be output.
In that case just go ahead and re-use it. */
if (!e->callee->callers->next_caller
&& !e->callee->needed
- && !cgraph_new_nodes
- && flag_unit_at_a_time)
+ && !cgraph_new_nodes)
{
gcc_assert (!e->callee->global.inlined_to);
- if (DECL_SAVED_TREE (e->callee->decl))
+ if (gimple_body (e->callee->decl))
overall_insns -= e->callee->global.insns, nfunctions_inlined++;
duplicate = false;
}
@@ -261,7 +256,7 @@ cgraph_mark_inline_edge (struct cgraph_edge *e, bool update_original)
gcc_assert (e->inline_failed);
e->inline_failed = NULL;
- if (!e->callee->global.inlined && flag_unit_at_a_time)
+ if (!e->callee->global.inlined)
DECL_POSSIBLY_INLINED (e->callee->decl) = true;
e->callee->global.inlined = true;
@@ -296,7 +291,7 @@ cgraph_mark_inline (struct cgraph_edge *edge)
struct cgraph_node *what = edge->callee;
struct cgraph_edge *e, *next;
- gcc_assert (!CALL_STMT_CANNOT_INLINE_P (edge->call_stmt));
+ gcc_assert (!gimple_call_cannot_inline_p (edge->call_stmt));
/* Look for all calls, mark them inline and clone recursively
all inlined functions. */
for (e = what->callers; e; e = next)
@@ -660,10 +655,12 @@ lookup_recursive_calls (struct cgraph_node *node, struct cgraph_node *where,
}
/* Decide on recursive inlining: in the case function has recursive calls,
- inline until body size reaches given argument. */
+ inline until body size reaches given argument. If any new indirect edges
+ are discovered in the process, add them to NEW_EDGES, unless it is NULL. */
static bool
-cgraph_decide_recursive_inlining (struct cgraph_node *node)
+cgraph_decide_recursive_inlining (struct cgraph_node *node,
+ VEC (cgraph_edge_p, heap) *new_edges)
{
int limit = PARAM_VALUE (PARAM_MAX_INLINE_INSNS_RECURSIVE_AUTO);
int max_depth = PARAM_VALUE (PARAM_MAX_INLINE_RECURSIVE_DEPTH_AUTO);
@@ -760,6 +757,8 @@ cgraph_decide_recursive_inlining (struct cgraph_node *node)
}
cgraph_redirect_edge_callee (curr, master_clone);
cgraph_mark_inline_edge (curr, false);
+ if (flag_indirect_inlining)
+ ipa_propagate_indirect_call_infos (curr, new_edges);
lookup_recursive_calls (node, curr->callee, heap);
n++;
}
@@ -817,6 +816,20 @@ compute_max_insns (int insns)
* (100 + PARAM_VALUE (PARAM_INLINE_UNIT_GROWTH)) / 100);
}
+/* Compute badness of all edges in NEW_EDGES and add them to the HEAP. */
+static void
+add_new_edges_to_heap (fibheap_t heap, VEC (cgraph_edge_p, heap) *new_edges)
+{
+ while (VEC_length (cgraph_edge_p, new_edges) > 0)
+ {
+ struct cgraph_edge *edge = VEC_pop (cgraph_edge_p, new_edges);
+
+ gcc_assert (!edge->aux);
+ edge->aux = fibheap_insert (heap, cgraph_edge_badness (edge), edge);
+ }
+}
+
+
/* We use greedy algorithm for inlining of small functions:
All inline candidates are put into prioritized heap based on estimated
growth of the overall number of instructions and then update the estimates.
@@ -833,6 +846,10 @@ cgraph_decide_inlining_of_small_functions (void)
fibheap_t heap = fibheap_new ();
bitmap updated_nodes = BITMAP_ALLOC (NULL);
int min_insns, max_insns;
+ VEC (cgraph_edge_p, heap) *new_indirect_edges = NULL;
+
+ if (flag_indirect_inlining)
+ new_indirect_edges = VEC_alloc (cgraph_edge_p, heap, 8);
if (dump_file)
fprintf (dump_file, "\nDeciding on smaller functions:\n");
@@ -954,20 +971,30 @@ cgraph_decide_inlining_of_small_functions (void)
}
continue;
}
+ if (!tree_can_inline_p (edge->caller->decl, edge->callee->decl))
+ {
+ gimple_call_set_cannot_inline (edge->call_stmt, true);
+ edge->inline_failed = N_("target specific option mismatch");
+ if (dump_file)
+ fprintf (dump_file, " inline_failed:%s.\n", edge->inline_failed);
+ continue;
+ }
if (cgraph_recursive_inlining_p (edge->caller, edge->callee,
&edge->inline_failed))
{
where = edge->caller;
if (where->global.inlined_to)
where = where->global.inlined_to;
- if (!cgraph_decide_recursive_inlining (where))
+ if (!cgraph_decide_recursive_inlining (where, new_indirect_edges))
continue;
+ if (flag_indirect_inlining)
+ add_new_edges_to_heap (heap, new_indirect_edges);
update_callee_keys (heap, where, updated_nodes);
}
else
{
struct cgraph_node *callee;
- if (CALL_STMT_CANNOT_INLINE_P (edge->call_stmt)
+ if (gimple_call_cannot_inline_p (edge->call_stmt)
|| !cgraph_check_inline_limits (edge->caller, edge->callee,
&edge->inline_failed, true))
{
@@ -978,6 +1005,11 @@ cgraph_decide_inlining_of_small_functions (void)
}
callee = edge->callee;
cgraph_mark_inline_edge (edge, true);
+ if (flag_indirect_inlining)
+ {
+ ipa_propagate_indirect_call_infos (edge, new_indirect_edges);
+ add_new_edges_to_heap (heap, new_indirect_edges);
+ }
update_callee_keys (heap, callee, updated_nodes);
}
where = edge->caller;
@@ -1020,6 +1052,9 @@ cgraph_decide_inlining_of_small_functions (void)
&edge->inline_failed))
edge->inline_failed = N_("--param inline-unit-growth limit reached");
}
+
+ if (new_indirect_edges)
+ VEC_free (cgraph_edge_p, heap, new_indirect_edges);
fibheap_delete (heap);
BITMAP_FREE (updated_nodes);
}
@@ -1093,12 +1128,19 @@ cgraph_decide_inlining (void)
for (e = node->callers; e; e = next)
{
next = e->next_caller;
- if (!e->inline_failed || CALL_STMT_CANNOT_INLINE_P (e->call_stmt))
+ if (!e->inline_failed || gimple_call_cannot_inline_p (e->call_stmt))
continue;
if (cgraph_recursive_inlining_p (e->caller, e->callee,
&e->inline_failed))
continue;
+ if (!tree_can_inline_p (e->caller->decl, e->callee->decl))
+ {
+ gimple_call_set_cannot_inline (e->call_stmt, true);
+ continue;
+ }
cgraph_mark_inline_edge (e, true);
+ if (flag_indirect_inlining)
+ ipa_propagate_indirect_call_infos (e, NULL);
if (dump_file)
fprintf (dump_file,
" Inlined into %s which now has %i insns.\n",
@@ -1120,6 +1162,11 @@ cgraph_decide_inlining (void)
if (!flag_really_no_inline)
cgraph_decide_inlining_of_small_functions ();
+ /* After this point, any edge discovery performed by indirect inlining is no
+ good so let's give up. */
+ if (flag_indirect_inlining)
+ free_all_ipa_structures_after_iinln ();
+
if (!flag_really_no_inline
&& flag_inline_functions_called_once)
{
@@ -1127,15 +1174,18 @@ cgraph_decide_inlining (void)
fprintf (dump_file, "\nDeciding on functions called once:\n");
/* And finally decide what functions are called once. */
-
for (i = nnodes - 1; i >= 0; i--)
{
node = order[i];
- if (node->callers && !node->callers->next_caller && !node->needed
- && node->local.inlinable && node->callers->inline_failed
- && !CALL_STMT_CANNOT_INLINE_P (node->callers->call_stmt)
- && !DECL_EXTERNAL (node->decl) && !DECL_COMDAT (node->decl))
+ if (node->callers
+ && !node->callers->next_caller
+ && !node->needed
+ && node->local.inlinable
+ && node->callers->inline_failed
+ && !gimple_call_cannot_inline_p (node->callers->call_stmt)
+ && !DECL_EXTERNAL (node->decl)
+ && !DECL_COMDAT (node->decl))
{
if (dump_file)
{
@@ -1246,13 +1296,13 @@ try_inline (struct cgraph_edge *e, enum inlining_mode mode, int depth)
if (e->inline_failed)
cgraph_mark_inline (e);
- /* In order to fully inline always_inline functions at -O0, we need to
+ /* In order to fully inline always_inline functions, we need to
recurse here, since the inlined functions might not be processed by
incremental inlining at all yet.
Also flattening needs to be done recursively. */
- if (!flag_unit_at_a_time || mode == INLINE_ALL || always_inline)
+ if (mode == INLINE_ALL || always_inline)
cgraph_decide_inlining_incrementally (e->callee, mode, depth + 1);
callee->aux = (void *)(size_t) callee_mode;
return true;
@@ -1297,7 +1347,7 @@ cgraph_decide_inlining_incrementally (struct cgraph_node *node,
if (!e->callee->local.disregard_inline_limits
&& (mode != INLINE_ALL || !e->callee->local.inlinable))
continue;
- if (CALL_STMT_CANNOT_INLINE_P (e->call_stmt))
+ if (gimple_call_cannot_inline_p (e->call_stmt))
continue;
/* When the edge is already inlined, we just need to recurse into
it in order to fully flatten the leaves. */
@@ -1322,6 +1372,17 @@ cgraph_decide_inlining_incrementally (struct cgraph_node *node,
}
continue;
}
+ if (!tree_can_inline_p (node->decl, e->callee->decl))
+ {
+ gimple_call_set_cannot_inline (e->call_stmt, true);
+ if (dump_file)
+ {
+ indent_to (dump_file, depth);
+ fprintf (dump_file,
+ "Not inlining: Target specific option mismatch.\n");
+ }
+ continue;
+ }
if (gimple_in_ssa_p (DECL_STRUCT_FUNCTION (node->decl))
!= gimple_in_ssa_p (DECL_STRUCT_FUNCTION (e->callee->decl)))
{
@@ -1332,7 +1393,7 @@ cgraph_decide_inlining_incrementally (struct cgraph_node *node,
}
continue;
}
- if (!DECL_SAVED_TREE (e->callee->decl) && !e->callee->inline_decl)
+ if (!gimple_body (e->callee->decl) && !e->callee->inline_decl)
{
if (dump_file)
{
@@ -1346,7 +1407,8 @@ cgraph_decide_inlining_incrementally (struct cgraph_node *node,
}
/* Now do the automatic inlining. */
- if (!flag_really_no_inline && mode != INLINE_ALL
+ if (!flag_really_no_inline
+ && mode != INLINE_ALL
&& mode != INLINE_ALWAYS_INLINE)
for (e = node->callees; e; e = e->next_callee)
{
@@ -1399,7 +1461,7 @@ cgraph_decide_inlining_incrementally (struct cgraph_node *node,
}
if (!cgraph_check_inline_limits (node, e->callee, &e->inline_failed,
false)
- || CALL_STMT_CANNOT_INLINE_P (e->call_stmt))
+ || gimple_call_cannot_inline_p (e->call_stmt))
{
if (dump_file)
{
@@ -1408,7 +1470,7 @@ cgraph_decide_inlining_incrementally (struct cgraph_node *node,
}
continue;
}
- if (!DECL_SAVED_TREE (e->callee->decl) && !e->callee->inline_decl)
+ if (!gimple_body (e->callee->decl) && !e->callee->inline_decl)
{
if (dump_file)
{
@@ -1418,22 +1480,24 @@ cgraph_decide_inlining_incrementally (struct cgraph_node *node,
}
continue;
}
+ if (!tree_can_inline_p (node->decl, e->callee->decl))
+ {
+ gimple_call_set_cannot_inline (e->call_stmt, true);
+ if (dump_file)
+ {
+ indent_to (dump_file, depth);
+ fprintf (dump_file,
+ "Not inlining: Target specific option mismatch.\n");
+ }
+ continue;
+ }
if (cgraph_default_inline_p (e->callee, &failed_reason))
inlined |= try_inline (e, mode, depth);
- else if (!flag_unit_at_a_time)
- e->inline_failed = failed_reason;
}
node->aux = (void *)(size_t) old_mode;
return inlined;
}
-/* When inlining shall be performed. */
-static bool
-cgraph_gate_inlining (void)
-{
- return flag_inline_trees;
-}
-
/* Because inlining might remove no-longer reachable nodes, we need to
keep the array visible to garbage collector to avoid reading collected
out nodes. */
@@ -1451,9 +1515,7 @@ cgraph_early_inlining (void)
if (sorrycount || errorcount)
return 0;
- if (cgraph_decide_inlining_incrementally (node,
- flag_unit_at_a_time || optimize_size
- ? INLINE_SIZE : INLINE_SPEED, 0))
+ if (cgraph_decide_inlining_incrementally (node, INLINE_SIZE, 0))
{
timevar_push (TV_INTEGRATION);
todo = optimize_inline_calls (current_function_decl);
@@ -1466,7 +1528,7 @@ cgraph_early_inlining (void)
static bool
cgraph_gate_early_inlining (void)
{
- return flag_inline_trees && flag_early_inlining;
+ return flag_early_inlining;
}
struct gimple_opt_pass pass_early_inline =
@@ -1492,7 +1554,7 @@ struct gimple_opt_pass pass_early_inline =
static bool
cgraph_gate_ipa_early_inlining (void)
{
- return (flag_inline_trees && flag_early_inlining
+ return (flag_early_inlining
&& (flag_branch_probabilities || flag_test_coverage
|| profile_arc_flag));
}
@@ -1529,8 +1591,8 @@ compute_inline_parameters (struct cgraph_node *node)
= inline_summary (node)->estimated_self_stack_size;
node->global.stack_frame_offset = 0;
node->local.inlinable = tree_inlinable_function_p (current_function_decl);
- inline_summary (node)->self_insns = estimate_num_insns (current_function_decl,
- &eni_inlining_weights);
+ inline_summary (node)->self_insns
+ = estimate_num_insns_fn (current_function_decl, &eni_inlining_weights);
if (node->local.inlinable && !node->local.disregard_inline_limits)
node->local.disregard_inline_limits
= DECL_DISREGARD_INLINE_LIMITS (current_function_decl);
@@ -1551,19 +1613,12 @@ compute_inline_parameters_for_current (void)
return 0;
}
-/* When inlining shall be performed. */
-static bool
-gate_inline_passes (void)
-{
- return flag_inline_trees;
-}
-
struct gimple_opt_pass pass_inline_parameters =
{
{
GIMPLE_PASS,
NULL, /* name */
- gate_inline_passes, /* gate */
+ NULL, /* gate */
compute_inline_parameters_for_current,/* execute */
NULL, /* sub */
NULL, /* next */
@@ -1577,6 +1632,31 @@ struct gimple_opt_pass pass_inline_parameters =
}
};
+/* This function performs intraprocedural analyzis in NODE that is required to
+ inline indirect calls. */
+static void
+inline_indirect_intraprocedural_analysis (struct cgraph_node *node)
+{
+ struct cgraph_edge *cs;
+
+ ipa_count_formal_params (node);
+ ipa_create_param_decls_array (node);
+ ipa_detect_param_modifications (node);
+ ipa_analyze_params_uses (node);
+
+ if (dump_file)
+ ipa_print_node_param_flags (dump_file, node);
+
+ for (cs = node->callees; cs; cs = cs->next_callee)
+ {
+ ipa_count_arguments (cs);
+ ipa_compute_jump_functions (cs);
+ }
+
+ if (dump_file)
+ ipa_print_node_jump_functions (dump_file, node);
+}
+
/* Note function body size. */
static void
inline_generate_summary (void)
@@ -1586,6 +1666,13 @@ inline_generate_summary (void)
int nnodes = cgraph_postorder (order);
int i;
+ if (flag_indirect_inlining)
+ {
+ ipa_register_cgraph_hooks ();
+ ipa_check_create_node_params ();
+ ipa_check_create_edge_args ();
+ }
+
for (i = nnodes - 1; i >= 0; i--)
{
struct cgraph_node *node = order[i];
@@ -1597,6 +1684,10 @@ inline_generate_summary (void)
push_cfun (DECL_STRUCT_FUNCTION (node->decl));
current_function_decl = node->decl;
compute_inline_parameters (node);
+
+ if (flag_indirect_inlining)
+ inline_indirect_intraprocedural_analysis (node);
+
pop_cfun ();
}
}
@@ -1621,6 +1712,7 @@ inline_transform (struct cgraph_node *node)
for (e = node->callees; e; e = e->next_callee)
if (!e->inline_failed || warn_inline)
break;
+
if (e)
{
timevar_push (TV_INTEGRATION);
@@ -1635,7 +1727,7 @@ struct ipa_opt_pass pass_ipa_inline =
{
IPA_PASS,
"inline", /* name */
- cgraph_gate_inlining, /* gate */
+ NULL, /* gate */
cgraph_decide_inlining, /* execute */
NULL, /* sub */
NULL, /* next */
@@ -1658,62 +1750,4 @@ struct ipa_opt_pass pass_ipa_inline =
};
-/* When inlining shall be performed. */
-static bool
-cgraph_gate_O0_always_inline (void)
-{
- return !flag_unit_at_a_time || !flag_inline_trees;
-}
-
-static unsigned int
-cgraph_O0_always_inline (void)
-{
- struct cgraph_node *node = cgraph_node (current_function_decl);
- unsigned int todo = 0;
- bool inlined;
-
- if (sorrycount || errorcount)
- return 0;
- inlined = cgraph_decide_inlining_incrementally (node, INLINE_SPEED, 0);
- /* We might need the body of this function so that we can expand
- it inline somewhere else. */
- if (cgraph_preserve_function_body_p (current_function_decl))
- save_inline_function_body (node);
- if (inlined || warn_inline)
- {
- timevar_push (TV_INTEGRATION);
- todo = optimize_inline_calls (current_function_decl);
- timevar_pop (TV_INTEGRATION);
- }
- /* In non-unit-at-a-time we must mark all referenced functions as needed. */
- if (!flag_unit_at_a_time)
- {
- struct cgraph_edge *e;
- for (e = node->callees; e; e = e->next_callee)
- if (e->callee->analyzed)
- cgraph_mark_needed_node (e->callee);
- }
- return todo | execute_fixup_cfg ();
-}
-
-struct gimple_opt_pass pass_O0_always_inline =
-{
- {
- GIMPLE_PASS,
- "always_inline", /* name */
- cgraph_gate_O0_always_inline, /* gate */
- cgraph_O0_always_inline, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_INLINE_HEURISTICS, /* tv_id */
- 0, /* properties_required */
- PROP_cfg, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_dump_func | TODO_verify_flow
- | TODO_verify_stmts /* todo_flags_finish */
- }
-};
-
#include "gt-ipa-inline.h"
diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c
index c5b4c9a80c8..efa195916cd 100644
--- a/gcc/ipa-prop.c
+++ b/gcc/ipa-prop.c
@@ -28,8 +28,22 @@ along with GCC; see the file COPYING3. If not see
#include "ipa-prop.h"
#include "tree-flow.h"
#include "tree-pass.h"
+#include "tree-inline.h"
#include "flags.h"
#include "timevar.h"
+#include "flags.h"
+#include "diagnostic.h"
+
+/* Vector where the parameter infos are actually stored. */
+VEC (ipa_node_params_t, heap) *ipa_node_params_vector;
+/* Vector where the parameter infos are actually stored. */
+VEC (ipa_edge_args_t, heap) *ipa_edge_args_vector;
+
+/* Holders of ipa cgraph hooks: */
+struct cgraph_edge_hook_list *edge_removal_hook_holder;
+struct cgraph_node_hook_list *node_removal_hook_holder;
+struct cgraph_2edge_hook_list *edge_duplication_hook_holder;
+struct cgraph_2node_hook_list *node_duplication_hook_holder;
/* Initialize worklist to contain all functions. */
struct ipa_func_list *
@@ -40,7 +54,13 @@ ipa_init_func_list (void)
wl = NULL;
for (node = cgraph_nodes; node; node = node->next)
- ipa_push_func_to_list (&wl, node);
+ if (node->analyzed)
+ {
+ /* Unreachable nodes should have been eliminated before ipcp and
+ inlining. */
+ gcc_assert (node->needed || node->reachable);
+ ipa_push_func_to_list (&wl, node);
+ }
return wl;
}
@@ -98,6 +118,9 @@ ipa_create_param_decls_array (struct cgraph_node *mt)
int param_num;
struct ipa_node_params *info = IPA_NODE_REF (mt);
+ if (info->param_decls)
+ return;
+
info->param_decls = XCNEWVEC (tree, ipa_get_param_count (info));
fndecl = mt->decl;
fnargs = DECL_ARGUMENTS (fndecl);
@@ -127,92 +150,81 @@ ipa_count_formal_params (struct cgraph_node *mt)
ipa_set_param_count (IPA_NODE_REF (mt), param_num);
}
-/* Check STMT to detect whether a formal is modified within MT, the appropriate
- entry is updated in the modified_flags array of ipa_node_params (associated
- with MT). */
+/* Check STMT to detect whether a formal parameter is directly modified within
+ STMT, the appropriate entry is updated in the modified flags of INFO.
+ Directly means that this function does not check for modifications through
+ pointers or escaping addresses because all TREE_ADDRESSABLE parameters are
+ considered modified anyway. */
static void
-ipa_check_stmt_modifications (struct cgraph_node *mt, tree stmt)
+ipa_check_stmt_modifications (struct ipa_node_params *info, gimple stmt)
{
- int index, j;
- tree parm_decl;
- struct ipa_node_params *info;
+ int j;
+ int index;
+ tree lhs;
- switch (TREE_CODE (stmt))
+ switch (gimple_code (stmt))
{
- case GIMPLE_MODIFY_STMT:
- if (TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 0)) == PARM_DECL)
- {
- info = IPA_NODE_REF (mt);
- parm_decl = GIMPLE_STMT_OPERAND (stmt, 0);
- index = ipa_get_param_decl_index (info, parm_decl);
- if (index >= 0)
- info->modified_flags[index] = true;
- }
+ case GIMPLE_ASSIGN:
+ lhs = gimple_assign_lhs (stmt);
+
+ while (handled_component_p (lhs))
+ lhs = TREE_OPERAND (lhs, 0);
+ if (TREE_CODE (lhs) == SSA_NAME)
+ lhs = SSA_NAME_VAR (lhs);
+ index = ipa_get_param_decl_index (info, lhs);
+ if (index >= 0)
+ info->param_flags[index].modified = true;
break;
- case ASM_EXPR:
+
+ case GIMPLE_ASM:
/* Asm code could modify any of the parameters. */
- info = IPA_NODE_REF (mt);
- for (j = 0; j < ipa_get_param_count (IPA_NODE_REF (mt)); j++)
- info->modified_flags[j] = true;
+ for (j = 0; j < ipa_get_param_count (info); j++)
+ info->param_flags[j].modified = true;
break;
+
default:
break;
}
}
-/* The modify computation driver for MT. Compute which formal arguments
- of function MT are locally modified. Formals may be modified in MT
- if their address is taken, or if
- they appear on the left hand side of an assignment. */
+/* Compute which formal parameters of function associated with NODE are locally
+ modified. Parameters may be modified in NODE if they are TREE_ADDRESSABLE,
+ if they appear on the left hand side of an assignment or if there is an
+ ASM_EXPR in the function. */
void
-ipa_detect_param_modifications (struct cgraph_node *mt)
+ipa_detect_param_modifications (struct cgraph_node *node)
{
- tree decl;
- tree body;
- int j, count;
+ tree decl = node->decl;
basic_block bb;
struct function *func;
- block_stmt_iterator bsi;
- tree stmt, parm_tree;
- struct ipa_node_params *info = IPA_NODE_REF (mt);
+ gimple_stmt_iterator gsi;
+ gimple stmt;
+ struct ipa_node_params *info = IPA_NODE_REF (node);
+ int i, count;
- if (ipa_get_param_count (info) == 0)
+ if (ipa_get_param_count (info) == 0 || info->modification_analysis_done)
return;
- count = ipa_get_param_count (info);
- info->modified_flags = XCNEWVEC (bool, count);
- decl = mt->decl;
- /* ??? Handle pending sizes case. Set all parameters
- of the function to be modified. */
+ if (!info->param_flags)
+ info->param_flags = XCNEWVEC (struct ipa_param_flags,
+ ipa_get_param_count (info));
- if (DECL_UNINLINABLE (decl))
- {
- for (j = 0; j < count; j++)
- info->modified_flags[j] = true;
-
- return;
- }
- /* Formals whose address is taken are considered modified. */
- for (j = 0; j < count; j++)
- {
- parm_tree = ipa_get_ith_param (info, j);
- if (!is_gimple_reg (parm_tree)
- && TREE_ADDRESSABLE (parm_tree))
- info->modified_flags[j] = true;
- }
- body = DECL_SAVED_TREE (decl);
- if (body != NULL)
+ func = DECL_STRUCT_FUNCTION (decl);
+ FOR_EACH_BB_FN (bb, func)
{
- func = DECL_STRUCT_FUNCTION (decl);
- FOR_EACH_BB_FN (bb, func)
- {
- for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
- {
- stmt = bsi_stmt (bsi);
- ipa_check_stmt_modifications (mt, stmt);
- }
- }
+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+ {
+ stmt = gsi_stmt (gsi);
+ ipa_check_stmt_modifications (info, stmt);
+ }
}
+
+ count = ipa_get_param_count (info);
+ for (i = 0; i < count; i++)
+ if (TREE_ADDRESSABLE (ipa_get_ith_param (info, i)))
+ info->param_flags[i].modified = true;
+
+ info->modification_analysis_done = 1;
}
/* Count number of arguments callsite CS has and store it in
@@ -220,170 +232,986 @@ ipa_detect_param_modifications (struct cgraph_node *mt)
void
ipa_count_arguments (struct cgraph_edge *cs)
{
- tree call_tree;
+ gimple stmt;
int arg_num;
- call_tree = get_call_expr_in (cs->call_stmt);
- gcc_assert (TREE_CODE (call_tree) == CALL_EXPR);
- arg_num = call_expr_nargs (call_tree);
+ stmt = cs->call_stmt;
+ gcc_assert (is_gimple_call (stmt));
+ arg_num = gimple_call_num_args (stmt);
ipa_set_cs_argument_count (IPA_EDGE_REF (cs), arg_num);
}
-/* Compute jump function for all arguments of callsite CS
- and insert the information in the jump_functions array
- in the ipa_edge_args corresponding to this callsite. */
+/* The following function prints the jump functions of all arguments on all
+ call graph edges going from NODE to file F. */
void
-ipa_compute_jump_functions (struct cgraph_edge *cs)
+ipa_print_node_jump_functions (FILE *f, struct cgraph_node *node)
{
- tree call_tree;
- tree arg, cst_decl;
- int arg_num;
- struct cgraph_node *mt;
- tree parm_decl;
- struct function *curr_cfun;
- call_expr_arg_iterator iter;
- struct ipa_edge_args *args = IPA_EDGE_REF (cs);
+ int i, count;
+ struct cgraph_edge *cs;
+ struct ipa_jump_func *jump_func;
+ enum jump_func_type type;
- if (ipa_get_cs_argument_count (args) == 0)
- return;
- args->jump_functions = XCNEWVEC (struct ipa_jump_func,
- ipa_get_cs_argument_count (args));
- call_tree = get_call_expr_in (cs->call_stmt);
- gcc_assert (TREE_CODE (call_tree) == CALL_EXPR);
- arg_num = 0;
+ fprintf (f, "JUMP FUNCTIONS OF CALLER %s:\n", cgraph_node_name (node));
+ for (cs = node->callees; cs; cs = cs->next_callee)
+ {
+ if (!ipa_edge_args_info_available_for_edge_p (cs))
+ continue;
+
+ fprintf (f, "callsite %s ", cgraph_node_name (node));
+ fprintf (f, "-> %s :: \n", cgraph_node_name (cs->callee));
+
+ count = ipa_get_cs_argument_count (IPA_EDGE_REF (cs));
+ for (i = 0; i < count; i++)
+ {
+ jump_func = ipa_get_ith_jump_func (IPA_EDGE_REF (cs), i);
+ type = jump_func->type;
+
+ fprintf (f, " param %d: ", i);
+ if (type == IPA_UNKNOWN)
+ fprintf (f, "UNKNOWN\n");
+ else if (type == IPA_CONST || type == IPA_CONST_REF)
+ {
+ tree val = jump_func->value.constant;
+ fprintf (f, "CONST: ");
+ print_generic_expr (f, val, 0);
+ fprintf (f, "\n");
+ }
+ else if (type == IPA_CONST_MEMBER_PTR)
+ {
+ fprintf (f, "CONST MEMBER PTR: ");
+ print_generic_expr (f, jump_func->value.member_cst.pfn, 0);
+ fprintf (f, ", ");
+ print_generic_expr (f, jump_func->value.member_cst.delta, 0);
+ fprintf (f, "\n");
+ }
+ else if (type == IPA_PASS_THROUGH)
+ {
+ fprintf (f, "PASS THROUGH: ");
+ fprintf (f, "%d\n", jump_func->value.formal_id);
+ }
+ }
+ }
+}
+
+/* Print ipa_jump_func data structures of all nodes in the call graph to F. */
+void
+ipa_print_all_jump_functions (FILE *f)
+{
+ struct cgraph_node *node;
- FOR_EACH_CALL_EXPR_ARG (arg, iter, call_tree)
+ fprintf (f, "\nCALLSITE PARAM PRINT\n");
+ for (node = cgraph_nodes; node; node = node->next)
{
- /* If the formal parameter was passed as argument, we store
- IPA_PASS_THROUGH and its index in the caller as the jump function
- of this argument. */
- if ((TREE_CODE (arg) == SSA_NAME
- && TREE_CODE (SSA_NAME_VAR (arg)) == PARM_DECL)
- || TREE_CODE (arg) == PARM_DECL)
+ ipa_print_node_jump_functions (f, node);
+ }
+}
+
+/* The following function determines the jump functions of scalar arguments.
+ Scalar means SSA names and constants of a number of selected types. INFO is
+ the ipa_node_params structure associated with the caller, FUNCTIONS is a
+ pointer to an array of jump function structures associated with CALL which
+ is the call statement being examined.*/
+static void
+compute_scalar_jump_functions (struct ipa_node_params *info,
+ struct ipa_jump_func *functions,
+ gimple call)
+{
+ tree arg;
+ unsigned num = 0;
+
+ for (num = 0; num < gimple_call_num_args (call); num++)
+ {
+ arg = gimple_call_arg (call, num);
+
+ if (TREE_CODE (arg) == INTEGER_CST
+ || TREE_CODE (arg) == REAL_CST
+ || TREE_CODE (arg) == FIXED_CST)
+ {
+ functions[num].type = IPA_CONST;
+ functions[num].value.constant = arg;
+ }
+ else if (TREE_CODE (arg) == ADDR_EXPR)
{
- struct ipa_node_params *info;
- int index;
-
- mt = cs->caller;
- info = IPA_NODE_REF (mt);
- parm_decl = TREE_CODE (arg) == PARM_DECL ? arg : SSA_NAME_VAR (arg);
-
- index = ipa_get_param_decl_index (info, parm_decl);
- if (TREE_CODE (arg) == SSA_NAME && IS_VALID_JUMP_FUNC_INDEX (index))
+ if (TREE_CODE (TREE_OPERAND (arg, 0)) == FUNCTION_DECL)
{
- curr_cfun = DECL_STRUCT_FUNCTION (mt->decl);
- if (!gimple_default_def (curr_cfun, parm_decl)
- || gimple_default_def (curr_cfun, parm_decl) != arg)
- info->modified_flags[index] = true;
+ functions[num].type = IPA_CONST;
+ functions[num].value.constant = TREE_OPERAND (arg, 0);
}
- if (!IS_VALID_JUMP_FUNC_INDEX (index) || info->modified_flags[index])
- args->jump_functions[arg_num].type = IPA_UNKNOWN;
- else
+ else if (TREE_CODE (TREE_OPERAND (arg, 0)) == CONST_DECL)
+ {
+ tree cst_decl = TREE_OPERAND (arg, 0);
+
+ if (TREE_CODE (DECL_INITIAL (cst_decl)) == INTEGER_CST
+ || TREE_CODE (DECL_INITIAL (cst_decl)) == REAL_CST
+ || TREE_CODE (DECL_INITIAL (cst_decl)) == FIXED_CST)
+ {
+ functions[num].type = IPA_CONST_REF;
+ functions[num].value.constant = cst_decl;
+ }
+ }
+ }
+ else if ((TREE_CODE (arg) == SSA_NAME) && SSA_NAME_IS_DEFAULT_DEF (arg))
+ {
+ int index = ipa_get_param_decl_index (info, SSA_NAME_VAR (arg));
+
+ if (index >= 0)
{
- args->jump_functions[arg_num].type = IPA_PASS_THROUGH;
- args->jump_functions[arg_num].value.formal_id = index;
+ functions[num].type = IPA_PASS_THROUGH;
+ functions[num].value.formal_id = index;
+ }
+ }
+ }
+}
+
+/* This function inspects the given TYPE and returns true iff it has the same
+ structure (the same number of fields of the same types) as a C++ member
+ pointer. If METHOD_PTR and DELTA are non-NULL, the trees representing the
+ corresponding fields are stored there. */
+static bool
+type_like_member_ptr_p (tree type, tree *method_ptr, tree *delta)
+{
+ tree fld;
+
+ if (TREE_CODE (type) != RECORD_TYPE)
+ return false;
+
+ fld = TYPE_FIELDS (type);
+ if (!fld || !POINTER_TYPE_P (TREE_TYPE (fld))
+ || TREE_CODE (TREE_TYPE (TREE_TYPE (fld))) != METHOD_TYPE)
+ return false;
+
+ if (method_ptr)
+ *method_ptr = fld;
+
+ fld = TREE_CHAIN (fld);
+ if (!fld || INTEGRAL_TYPE_P (fld))
+ return false;
+ if (delta)
+ *delta = fld;
+
+ if (TREE_CHAIN (fld))
+ return false;
+
+ return true;
+}
+
+/* This function goes through arguments of the CALL and for every one that
+ looks like a member pointer, it checks whether it can be safely declared
+ pass-through and if so, marks that to the corresponding item of jum
+ FUNCTIONS . It returns true iff there were non-pass-through member pointers
+ within the arguments. INFO describes formal parameters of the caller. */
+static bool
+compute_pass_through_member_ptrs (struct ipa_node_params *info,
+ struct ipa_jump_func *functions,
+ gimple call)
+{
+ bool undecided_members = false;
+ unsigned num;
+ tree arg;
+
+ for (num = 0; num < gimple_call_num_args (call); num++)
+ {
+ arg = gimple_call_arg (call, num);
+
+ if (type_like_member_ptr_p (TREE_TYPE (arg), NULL, NULL))
+ {
+ if (TREE_CODE (arg) == PARM_DECL)
+ {
+ int index = ipa_get_param_decl_index (info, arg);
+
+ gcc_assert (index >=0);
+ if (!ipa_is_ith_param_modified (info, index))
+ {
+ functions[num].type = IPA_PASS_THROUGH;
+ functions[num].value.formal_id = index;
+ }
+ else
+ undecided_members = true;
}
+ else
+ undecided_members = true;
}
- /* If a constant value was passed as argument,
- we store IPA_CONST and its value as the jump function
- of this argument. */
- else if (TREE_CODE (arg) == INTEGER_CST
- || TREE_CODE (arg) == REAL_CST
- || TREE_CODE (arg) == FIXED_CST)
+ }
+
+ return undecided_members;
+}
+
+/* Simple function filling in a member pointer constant jump function (with PFN
+ and DELTA as the constant value) into JFUNC. */
+static void
+fill_member_ptr_cst_jump_function (struct ipa_jump_func *jfunc,
+ tree pfn, tree delta)
+{
+ jfunc->type = IPA_CONST_MEMBER_PTR;
+ jfunc->value.member_cst.pfn = pfn;
+ jfunc->value.member_cst.delta = delta;
+}
+
+/* Traverse statements from CALL backwards, scanning whether the argument ARG
+ which is a member pointer is filled in with constant values. If it is, fill
+ the jump function JFUNC in appropriately. METHOD_FIELD and DELTA_FIELD are
+ fields of the record type of the member pointer. To give an example, we
+ look for a pattern looking like the following:
+
+ D.2515.__pfn ={v} printStuff;
+ D.2515.__delta ={v} 0;
+ i_1 = doprinting (D.2515); */
+static void
+determine_cst_member_ptr (gimple call, tree arg, tree method_field,
+ tree delta_field, struct ipa_jump_func *jfunc)
+{
+ gimple_stmt_iterator gsi;
+ tree method = NULL_TREE;
+ tree delta = NULL_TREE;
+
+ gsi = gsi_for_stmt (call);
+
+ gsi_prev (&gsi);
+ for (; !gsi_end_p (gsi); gsi_prev (&gsi))
+ {
+ gimple stmt = gsi_stmt (gsi);
+ tree lhs, rhs, fld;
+
+ if (!is_gimple_assign (stmt) || gimple_num_ops (stmt) != 2)
+ return;
+
+ lhs = gimple_assign_lhs (stmt);
+ rhs = gimple_assign_rhs1 (stmt);
+
+ if (TREE_CODE (lhs) != COMPONENT_REF
+ || TREE_OPERAND (lhs, 0) != arg)
+ continue;
+
+ fld = TREE_OPERAND (lhs, 1);
+ if (!method && fld == method_field)
{
- args->jump_functions[arg_num].type = IPA_CONST;
- args->jump_functions[arg_num].value.constant = arg;
+ if (TREE_CODE (rhs) == ADDR_EXPR
+ && TREE_CODE (TREE_OPERAND (rhs, 0)) == FUNCTION_DECL
+ && TREE_CODE (TREE_TYPE (TREE_OPERAND (rhs, 0))) == METHOD_TYPE)
+ {
+ method = TREE_OPERAND (rhs, 0);
+ if (delta)
+ {
+ fill_member_ptr_cst_jump_function (jfunc, method, delta);
+ return;
+ }
+ }
+ else
+ return;
}
- /* This is for the case of Fortran. If the address of a const_decl
- was passed as argument then we store
- IPA_CONST_REF/IPA_CONST_REF and the constant
- value as the jump function corresponding to this argument. */
- else if (TREE_CODE (arg) == ADDR_EXPR
- && TREE_CODE (TREE_OPERAND (arg, 0)) == CONST_DECL)
+
+ if (!delta && fld == delta_field)
{
- cst_decl = TREE_OPERAND (arg, 0);
- if (TREE_CODE (DECL_INITIAL (cst_decl)) == INTEGER_CST
- || TREE_CODE (DECL_INITIAL (cst_decl)) == REAL_CST
- || TREE_CODE (DECL_INITIAL (cst_decl)) == FIXED_CST)
+ if (TREE_CODE (rhs) == INTEGER_CST)
{
- args->jump_functions[arg_num].type = IPA_CONST_REF;
- args->jump_functions[arg_num].value.constant = cst_decl;
+ delta = rhs;
+ if (method)
+ {
+ fill_member_ptr_cst_jump_function (jfunc, method, delta);
+ return;
+ }
}
+ else
+ return;
}
- else
- args->jump_functions[arg_num].type = IPA_UNKNOWN;
- arg_num++;
+ }
+
+ return;
+}
+
+/* Go through the arguments of the CALL and for every member pointer within
+ tries determine whether it is a constant. If it is, create a corresponding
+ constant jump function in FUNCTIONS which is an array of jump functions
+ associated with the call. */
+static void
+compute_cst_member_ptr_arguments (struct ipa_jump_func *functions,
+ gimple call)
+{
+ unsigned num;
+ tree arg, method_field, delta_field;
+
+ for (num = 0; num < gimple_call_num_args (call); num++)
+ {
+ arg = gimple_call_arg (call, num);
+
+ if (functions[num].type == IPA_UNKNOWN
+ && type_like_member_ptr_p (TREE_TYPE (arg), &method_field,
+ &delta_field))
+ determine_cst_member_ptr (call, arg, method_field, delta_field,
+ &functions[num]);
}
}
-/* Allocate and initialize ipa_node_params structure for the given cgraph
- node. */
+/* Compute jump function for all arguments of callsite CS and insert the
+ information in the jump_functions array in the ipa_edge_args corresponding
+ to this callsite. */
void
-ipa_create_node_params (struct cgraph_node *node)
+ipa_compute_jump_functions (struct cgraph_edge *cs)
+{
+ struct ipa_node_params *info = IPA_NODE_REF (cs->caller);
+ struct ipa_edge_args *arguments = IPA_EDGE_REF (cs);
+ gimple call;
+
+ if (ipa_get_cs_argument_count (arguments) == 0 || arguments->jump_functions)
+ return;
+ arguments->jump_functions = XCNEWVEC (struct ipa_jump_func,
+ ipa_get_cs_argument_count (arguments));
+
+ call = cs->call_stmt;
+ gcc_assert (is_gimple_call (call));
+
+ /* We will deal with constants and SSA scalars first: */
+ compute_scalar_jump_functions (info, arguments->jump_functions, call);
+
+ /* Let's check whether there are any potential member pointers and if so,
+ whether we can determine their functions as pass_through. */
+ if (!compute_pass_through_member_ptrs (info, arguments->jump_functions, call))
+ return;
+
+ /* Finally, let's check whether we actually pass a new constant membeer
+ pointer here... */
+ compute_cst_member_ptr_arguments (arguments->jump_functions, call);
+}
+
+/* If RHS looks like a rhs of a statement loading pfn from a member pointer
+ formal parameter, return the parameter, otherwise return NULL. */
+static tree
+ipa_get_member_ptr_load_param (tree rhs)
+{
+ tree rec, fld;
+ tree ptr_field;
+
+ if (TREE_CODE (rhs) != COMPONENT_REF)
+ return NULL_TREE;
+
+ rec = TREE_OPERAND (rhs, 0);
+ if (TREE_CODE (rec) != PARM_DECL
+ || !type_like_member_ptr_p (TREE_TYPE (rec), &ptr_field, NULL))
+ return NULL_TREE;
+
+ fld = TREE_OPERAND (rhs, 1);
+ if (fld == ptr_field)
+ return rec;
+ else
+ return NULL_TREE;
+}
+
+/* If STMT looks like a statement loading a value from a member pointer formal
+ parameter, this function retuns that parameter. */
+static tree
+ipa_get_stmt_member_ptr_load_param (gimple stmt)
+{
+ tree rhs;
+
+ if (!is_gimple_assign (stmt) || gimple_num_ops (stmt) != 2)
+ return NULL_TREE;
+
+ rhs = gimple_assign_rhs1 (stmt);
+ return ipa_get_member_ptr_load_param (rhs);
+}
+
+/* Returns true iff T is an SSA_NAME defined by a statement. */
+static bool
+ipa_is_ssa_with_stmt_def (tree t)
+{
+ if (TREE_CODE (t) == SSA_NAME
+ && !SSA_NAME_IS_DEFAULT_DEF (t))
+ return true;
+ else
+ return false;
+}
+
+/* Creates a new note describing a call to a parameter number FORMAL_ID and
+ attaches it to the linked list of INFO. It also sets the called flag of the
+ parameter. STMT is the corresponding call statement. */
+static void
+ipa_note_param_call (struct ipa_node_params *info, int formal_id,
+ gimple stmt)
+{
+ struct ipa_param_call_note *note;
+ basic_block bb = gimple_bb (stmt);
+
+ info->param_flags[formal_id].called = 1;
+
+ note = XCNEW (struct ipa_param_call_note);
+ note->formal_id = formal_id;
+ note->stmt = stmt;
+ note->count = bb->count;
+ note->frequency = compute_call_stmt_bb_frequency (bb);
+
+ note->next = info->param_calls;
+ info->param_calls = note;
+
+ return;
+}
+
+/* Analyze the CALL and examine uses of formal parameters of the caller
+ (described by INFO). Currently it checks whether the call calls a pointer
+ that is a formal parameter and if so, the parameter is marked with the
+ called flag and a note describing the call is created. This is very simple
+ for ordinary pointers represented in SSA but not-so-nice when it comes to
+ member pointers. The ugly part of this function does nothing more than
+ tries to match the pattern of such a call. An example of such a pattern is
+ the gimple dump below, the call is on the last line:
+
+ <bb 2>:
+ f$__delta_5 = f.__delta;
+ f$__pfn_24 = f.__pfn;
+ D.2496_3 = (int) f$__pfn_24;
+ D.2497_4 = D.2496_3 & 1;
+ if (D.2497_4 != 0)
+ goto <bb 3>;
+ else
+ goto <bb 4>;
+
+ <bb 3>:
+ D.2500_7 = (unsigned int) f$__delta_5;
+ D.2501_8 = &S + D.2500_7;
+ D.2502_9 = (int (*__vtbl_ptr_type) (void) * *) D.2501_8;
+ D.2503_10 = *D.2502_9;
+ D.2504_12 = f$__pfn_24 + -1;
+ D.2505_13 = (unsigned int) D.2504_12;
+ D.2506_14 = D.2503_10 + D.2505_13;
+ D.2507_15 = *D.2506_14;
+ iftmp.11_16 = (String:: *) D.2507_15;
+
+ <bb 4>:
+ # iftmp.11_1 = PHI <iftmp.11_16(3), f$__pfn_24(2)>
+ D.2500_19 = (unsigned int) f$__delta_5;
+ D.2508_20 = &S + D.2500_19;
+ D.2493_21 = iftmp.11_1 (D.2508_20, 4);
+
+ Such patterns are results of simple calls to a member pointer:
+
+ int doprinting (int (MyString::* f)(int) const)
+ {
+ MyString S ("somestring");
+
+ return (S.*f)(4);
+ }
+*/
+
+static void
+ipa_analyze_call_uses (struct ipa_node_params *info, gimple call)
+{
+ tree target = gimple_call_fn (call);
+ gimple def;
+ tree var;
+ tree n1, n2;
+ gimple d1, d2;
+ tree rec, rec2, cond;
+ gimple branch;
+ int index;
+ basic_block bb, virt_bb, join;
+
+ if (TREE_CODE (target) != SSA_NAME)
+ return;
+
+ var = SSA_NAME_VAR (target);
+ if (SSA_NAME_IS_DEFAULT_DEF (target))
+ {
+ /* assuming TREE_CODE (var) == PARM_DECL */
+ index = ipa_get_param_decl_index (info, var);
+ if (index >= 0)
+ ipa_note_param_call (info, index, call);
+ return;
+ }
+
+ /* Now we need to try to match the complex pattern of calling a member
+ pointer. */
+
+ if (!POINTER_TYPE_P (TREE_TYPE (target))
+ || TREE_CODE (TREE_TYPE (TREE_TYPE (target))) != METHOD_TYPE)
+ return;
+
+ def = SSA_NAME_DEF_STMT (target);
+ if (gimple_code (def) != GIMPLE_PHI)
+ return;
+
+ if (gimple_phi_num_args (def) != 2)
+ return;
+
+ /* First, we need to check whether one of these is a load from a member
+ pointer that is a parameter to this function. */
+ n1 = PHI_ARG_DEF (def, 0);
+ n2 = PHI_ARG_DEF (def, 1);
+ if (!ipa_is_ssa_with_stmt_def (n1) || !ipa_is_ssa_with_stmt_def (n2))
+ return;
+ d1 = SSA_NAME_DEF_STMT (n1);
+ d2 = SSA_NAME_DEF_STMT (n2);
+
+ if ((rec = ipa_get_stmt_member_ptr_load_param (d1)))
+ {
+ if (ipa_get_stmt_member_ptr_load_param (d2))
+ return;
+
+ bb = gimple_bb (d1);
+ virt_bb = gimple_bb (d2);
+ }
+ else if ((rec = ipa_get_stmt_member_ptr_load_param (d2)))
+ {
+ bb = gimple_bb (d2);
+ virt_bb = gimple_bb (d1);
+ }
+ else
+ return;
+
+ /* Second, we need to check that the basic blocks are laid out in the way
+ corresponding to the pattern. */
+
+ join = gimple_bb (def);
+ if (!single_pred_p (virt_bb) || !single_succ_p (virt_bb)
+ || single_pred (virt_bb) != bb
+ || single_succ (virt_bb) != join)
+ return;
+
+ /* Third, let's see that the branching is done depending on the least
+ significant bit of the pfn. */
+
+ branch = last_stmt (bb);
+ if (gimple_code (branch) != GIMPLE_COND)
+ return;
+
+ if (gimple_cond_code (branch) != NE_EXPR
+ || !integer_zerop (gimple_cond_rhs (branch)))
+ return;
+
+ cond = gimple_cond_lhs (branch);
+ if (!ipa_is_ssa_with_stmt_def (cond))
+ return;
+
+ def = SSA_NAME_DEF_STMT (cond);
+ if (!is_gimple_assign (def) || gimple_num_ops (def) != 3
+ || gimple_assign_rhs_code (def) != BIT_AND_EXPR
+ || !integer_onep (gimple_assign_rhs2 (def)))
+ return;
+
+ cond = gimple_assign_rhs1 (def);
+ if (!ipa_is_ssa_with_stmt_def (cond))
+ return;
+
+ def = SSA_NAME_DEF_STMT (cond);
+
+ if (is_gimple_assign (def) && gimple_num_ops (def) == 2
+ && gimple_assign_rhs_code (def) == NOP_EXPR)
+ {
+ cond = gimple_assign_rhs1 (def);
+ if (!ipa_is_ssa_with_stmt_def (cond))
+ return;
+ def = SSA_NAME_DEF_STMT (cond);
+ }
+
+ rec2 = ipa_get_stmt_member_ptr_load_param (def);
+ if (rec != rec2)
+ return;
+
+ index = ipa_get_param_decl_index (info, rec);
+ if (index >= 0 && !ipa_is_ith_param_modified (info, index))
+ ipa_note_param_call (info, index, call);
+
+ return;
+}
+
+/* Analyze the statement STMT with respect to formal parameters (described in
+ INFO) and their uses. Currently it only checks whether formal parameters
+ are called. */
+static void
+ipa_analyze_stmt_uses (struct ipa_node_params *info, gimple stmt)
{
- node->aux = xcalloc (1, sizeof (struct ipa_node_params));
+ if (is_gimple_call (stmt))
+ ipa_analyze_call_uses (info, stmt);
}
-/* Allocate and initialize ipa_node_params structure for all
- nodes in callgraph. */
+/* Scan the function body of NODE and inspect the uses of formal parameters.
+ Store the findings in various structures of the associated ipa_node_params
+ structure, such as parameter flags, notes etc. */
void
-ipa_create_all_node_params (void)
+ipa_analyze_params_uses (struct cgraph_node *node)
{
- struct cgraph_node *node;
+ tree decl = node->decl;
+ basic_block bb;
+ struct function *func;
+ gimple_stmt_iterator gsi;
+ struct ipa_node_params *info = IPA_NODE_REF (node);
- for (node = cgraph_nodes; node; node = node->next)
- ipa_create_node_params (node);
+ if (ipa_get_param_count (info) == 0 || info->uses_analysis_done)
+ return;
+ if (!info->param_flags)
+ info->param_flags = XCNEWVEC (struct ipa_param_flags,
+ ipa_get_param_count (info));
+
+ func = DECL_STRUCT_FUNCTION (decl);
+ FOR_EACH_BB_FN (bb, func)
+ {
+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+ {
+ gimple stmt = gsi_stmt (gsi);
+ ipa_analyze_stmt_uses (info, stmt);
+ }
+ }
+
+ info->uses_analysis_done = 1;
+}
+
+/* Update the jump functions assocated with call graph edge E when the call
+ graph edge CS is being inlined, assuming that E->caller is already (possibly
+ indirectly) inlined into CS->callee and that E has not been inlined. */
+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);
+ int count = ipa_get_cs_argument_count (args);
+ int i;
+
+ for (i = 0; i < count; i++)
+ {
+ struct ipa_jump_func *src, *dst = ipa_get_ith_jump_func (args, i);
+
+ if (dst->type != IPA_PASS_THROUGH)
+ continue;
+
+ /* We must check range due to calls with variable number of arguments: */
+ if (dst->value.formal_id >= (unsigned) ipa_get_cs_argument_count (top))
+ {
+ dst->type = IPA_BOTTOM;
+ continue;
+ }
+
+ src = ipa_get_ith_jump_func (top, dst->value.formal_id);
+ *dst = *src;
+ }
+}
+
+/* Print out a debug message to file F that we have discovered that an indirect
+ call descibed by NT is in fact a call of a known constant function descibed
+ by JFUNC. NODE is the node where the call is. */
+static void
+print_edge_addition_message (FILE *f, struct ipa_param_call_note *nt,
+ struct ipa_jump_func *jfunc,
+ struct cgraph_node *node)
+{
+ fprintf (f, "ipa-prop: Discovered an indirect call to a known target (");
+ if (jfunc->type == IPA_CONST_MEMBER_PTR)
+ {
+ print_node_brief (f, "", jfunc->value.member_cst.pfn, 0);
+ print_node_brief (f, ", ", jfunc->value.member_cst.delta, 0);
+ }
+ else
+ print_node_brief(f, "", jfunc->value.constant, 0);
+
+ fprintf (f, ") in %s: ", cgraph_node_name (node));
+ print_gimple_stmt (f, nt->stmt, 2, TDF_SLIM);
+}
+
+/* Update the param called notes associated with NODE when CS is being inlined,
+ assuming NODE is (potentially indirectly) inlined into CS->callee.
+ Moreover, if the callee is discovered to be constant, create a new cgraph
+ edge for it. Newly discovered indirect edges will be added to NEW_EDGES,
+ unless it is NULL. */
+static void
+update_call_notes_after_inlining (struct cgraph_edge *cs,
+ struct cgraph_node *node,
+ VEC (cgraph_edge_p, heap) *new_edges)
+{
+ struct ipa_node_params *info = IPA_NODE_REF (node);
+ struct ipa_edge_args *top = IPA_EDGE_REF (cs);
+ struct ipa_param_call_note *nt;
+
+ for (nt = info->param_calls; nt; nt = nt->next)
+ {
+ struct ipa_jump_func *jfunc;
+
+ if (nt->processed)
+ continue;
+
+ /* We must check range due to calls with variable number of arguments: */
+ if (nt->formal_id >= (unsigned) ipa_get_cs_argument_count (top))
+ {
+ nt->processed = true;
+ continue;
+ }
+
+ jfunc = ipa_get_ith_jump_func (top, nt->formal_id);
+ if (jfunc->type == IPA_PASS_THROUGH)
+ nt->formal_id = jfunc->value.formal_id;
+ else if (jfunc->type == IPA_CONST || jfunc->type == IPA_CONST_MEMBER_PTR)
+ {
+ struct cgraph_node *callee;
+ struct cgraph_edge *new_indirect_edge;
+ tree decl;
+
+ nt->processed = true;
+ if (jfunc->type == IPA_CONST_MEMBER_PTR)
+ decl = jfunc->value.member_cst.pfn;
+ else
+ decl = jfunc->value.constant;
+
+ if (TREE_CODE (decl) != FUNCTION_DECL)
+ continue;
+ callee = cgraph_node (decl);
+ if (!callee || !callee->local.inlinable)
+ continue;
+
+ if (dump_file)
+ print_edge_addition_message (dump_file, nt, jfunc, node);
+
+ new_indirect_edge = cgraph_create_edge (node, callee, nt->stmt,
+ nt->count, nt->frequency,
+ nt->loop_nest);
+ new_indirect_edge->indirect_call = 1;
+ ipa_check_create_edge_args ();
+ if (new_edges)
+ VEC_safe_push (cgraph_edge_p, heap, new_edges, new_indirect_edge);
+ }
+ }
}
-/* Allocate and initialize ipa_edge structure. */
+/* Recursively traverse subtree of NODE (including node) made of inlined
+ cgraph_edges when CS has been inlined and invoke
+ update_call_notes_after_inlining on all nodes and
+ update_jump_functions_after_inlining on all non-inlined edges that lead out
+ of this subtree. Newly discovered indirect edges will be added to
+ NEW_EDGES, unless it is NULL. */
+static void
+propagate_info_to_inlined_callees (struct cgraph_edge *cs,
+ struct cgraph_node *node,
+ VEC (cgraph_edge_p, heap) *new_edges)
+{
+ struct cgraph_edge *e;
+
+ update_call_notes_after_inlining (cs, node, new_edges);
+
+ for (e = node->callees; e; e = e->next_callee)
+ if (!e->inline_failed)
+ propagate_info_to_inlined_callees (cs, e->callee, new_edges);
+ else
+ update_jump_functions_after_inlining (cs, e);
+}
+
+/* Update jump functions and call note functions on inlining the call site CS.
+ CS is expected to lead to a node already cloned by
+ cgraph_clone_inline_nodes. Newly discovered indirect edges will be added to
+ NEW_EDGES, unless it is NULL. */
void
-ipa_create_all_edge_args (void)
+ipa_propagate_indirect_call_infos (struct cgraph_edge *cs,
+ VEC (cgraph_edge_p, heap) *new_edges)
{
- struct cgraph_node *node;
- struct cgraph_edge *cs;
+ propagate_info_to_inlined_callees (cs, cs->callee, new_edges);
+}
- for (node = cgraph_nodes; node; node = node->next)
- for (cs = node->callees; cs; cs = cs->next_callee)
- cs->aux = xcalloc (1, sizeof (struct ipa_edge_args));
+/* Frees all dynamically allocated structures that the argument info points
+ to. */
+void
+ipa_free_edge_args_substructures (struct ipa_edge_args *args)
+{
+ if (args->jump_functions)
+ free (args->jump_functions);
+
+ memset (args, 0, sizeof (*args));
}
-/* Free ipa_edge structure. */
+/* Free all ipa_edge structures. */
void
ipa_free_all_edge_args (void)
{
- struct cgraph_node *node;
- struct cgraph_edge *cs;
+ int i;
+ struct ipa_edge_args *args;
- for (node = cgraph_nodes; node; node = node->next)
- for (cs = node->callees; cs; cs = cs->next_callee)
- if (cs->aux)
- {
- if (IPA_EDGE_REF (cs)->jump_functions)
- free (IPA_EDGE_REF (cs)->jump_functions);
- free (cs->aux);
- cs->aux = NULL;
- }
+ for (i = 0;
+ VEC_iterate (ipa_edge_args_t, ipa_edge_args_vector, i, args);
+ i++)
+ ipa_free_edge_args_substructures (args);
+
+ VEC_free (ipa_edge_args_t, heap, ipa_edge_args_vector);
+ ipa_edge_args_vector = NULL;
}
-/* Free ipa data structures of ipa_node_params and ipa_edge_args. */
+/* Frees all dynamically allocated structures that the param info points
+ to. */
+void
+ipa_free_node_params_substructures (struct ipa_node_params *info)
+{
+ if (info->ipcp_lattices)
+ free (info->ipcp_lattices);
+ if (info->param_decls)
+ free (info->param_decls);
+ if (info->param_flags)
+ free (info->param_flags);
+
+ while (info->param_calls)
+ {
+ struct ipa_param_call_note *note = info->param_calls;
+ info->param_calls = note->next;
+ free (note);
+ }
+
+ memset (info, 0, sizeof (*info));
+}
+
+/* Free all ipa_node_params structures. */
void
ipa_free_all_node_params (void)
{
- struct cgraph_node *node;
+ int i;
+ struct ipa_node_params *info;
- for (node = cgraph_nodes; node; node = node->next)
+ for (i = 0;
+ VEC_iterate (ipa_node_params_t, ipa_node_params_vector, i, info);
+ i++)
+ ipa_free_node_params_substructures (info);
+
+ VEC_free (ipa_node_params_t, heap, ipa_node_params_vector);
+ ipa_node_params_vector = NULL;
+}
+
+/* Hook that is called by cgraph.c when an edge is removed. */
+static void
+ipa_edge_removal_hook (struct cgraph_edge *cs,
+ void *data __attribute__ ((unused)))
+{
+ ipa_free_edge_args_substructures (IPA_EDGE_REF (cs));
+}
+
+/* Hook that is called by cgraph.c when a node is removed. */
+static void
+ipa_node_removal_hook (struct cgraph_node *node,
+ void *data __attribute__ ((unused)))
+{
+ ipa_free_node_params_substructures (IPA_NODE_REF (node));
+}
+
+/* Helper function to duplicate an array of size N that is at SRC and store a
+ pointer to it to DST. Nothing is done if SRC is NULL. */
+static void *
+duplicate_array (void *src, size_t n)
+{
+ void *p;
+
+ if (!src)
+ return NULL;
+
+ p = xcalloc (1, n);
+ memcpy (p, src, n);
+ return p;
+}
+
+/* Hook that is called by cgraph.c when a node is duplicated. */
+static void
+ipa_edge_duplication_hook (struct cgraph_edge *src, struct cgraph_edge *dst,
+ void *data)
+{
+ struct ipa_edge_args *old_args, *new_args;
+ int arg_count;
+
+ ipa_check_create_edge_args ();
+
+ old_args = IPA_EDGE_REF (src);
+ new_args = IPA_EDGE_REF (dst);
+
+ arg_count = ipa_get_cs_argument_count (old_args);
+ ipa_set_cs_argument_count (new_args, arg_count);
+ new_args->jump_functions = (struct ipa_jump_func *)
+ duplicate_array (old_args->jump_functions,
+ sizeof (struct ipa_jump_func) * arg_count);
+ data = data; /* Suppressing compiler warning. */
+}
+
+/* Hook that is called by cgraph.c when a node is duplicated. */
+static void
+ipa_node_duplication_hook (struct cgraph_node *src, struct cgraph_node *dst,
+ void *data)
+{
+ struct ipa_node_params *old_info, *new_info;
+ struct ipa_param_call_note *note;
+ int param_count;
+
+ ipa_check_create_node_params ();
+ old_info = IPA_NODE_REF (src);
+ new_info = IPA_NODE_REF (dst);
+ param_count = ipa_get_param_count (old_info);
+
+ ipa_set_param_count (new_info, param_count);
+ new_info->ipcp_lattices = (struct ipcp_lattice *)
+ duplicate_array (old_info->ipcp_lattices,
+ sizeof (struct ipcp_lattice) * param_count);
+ new_info->param_decls = (tree *)
+ duplicate_array (old_info->param_decls, sizeof (tree) * param_count);
+ new_info->param_flags = (struct ipa_param_flags *)
+ duplicate_array (old_info->param_flags,
+ sizeof (struct ipa_param_flags) * param_count);
+
+ new_info->ipcp_orig_node = old_info->ipcp_orig_node;
+ new_info->count_scale = old_info->count_scale;
+
+ for (note = old_info->param_calls; note; note = note->next)
{
- if (node->aux == NULL)
- continue;
- if (IPA_NODE_REF (node)->ipcp_lattices)
- free (IPA_NODE_REF (node)->ipcp_lattices);
- if (IPA_NODE_REF (node)->param_decls)
- free (IPA_NODE_REF (node)->param_decls);
- if (IPA_NODE_REF (node)->modified_flags)
- free (IPA_NODE_REF (node)->modified_flags);
- free (node->aux);
- node->aux = NULL;
+ struct ipa_param_call_note *nn;
+
+ nn = (struct ipa_param_call_note *)
+ xcalloc (1, sizeof (struct ipa_param_call_note));
+ memcpy (nn, note, sizeof (struct ipa_param_call_note));
+ nn->next = new_info->param_calls;
+ new_info->param_calls = nn;
}
+
+ data = data; /* Suppressing compiler warning. */
+}
+
+/* Register our cgraph hooks if they are not already there. */
+void
+ipa_register_cgraph_hooks (void)
+{
+ if (!edge_removal_hook_holder)
+ edge_removal_hook_holder =
+ cgraph_add_edge_removal_hook (&ipa_edge_removal_hook, NULL);
+ if (!node_removal_hook_holder)
+ node_removal_hook_holder =
+ cgraph_add_node_removal_hook (&ipa_node_removal_hook, NULL);
+ if (!edge_duplication_hook_holder)
+ edge_duplication_hook_holder =
+ cgraph_add_edge_duplication_hook (&ipa_edge_duplication_hook, NULL);
+ if (!node_duplication_hook_holder)
+ node_duplication_hook_holder =
+ cgraph_add_node_duplication_hook (&ipa_node_duplication_hook, NULL);
+}
+
+/* Unregister our cgraph hooks if they are not already there. */
+static void
+ipa_unregister_cgraph_hooks (void)
+{
+ cgraph_remove_edge_removal_hook (edge_removal_hook_holder);
+ edge_removal_hook_holder = NULL;
+ cgraph_remove_node_removal_hook (node_removal_hook_holder);
+ node_removal_hook_holder = NULL;
+ cgraph_remove_edge_duplication_hook (edge_duplication_hook_holder);
+ edge_duplication_hook_holder = NULL;
+ cgraph_remove_node_duplication_hook (node_duplication_hook_holder);
+ node_duplication_hook_holder = NULL;
+}
+
+/* Free all ipa_node_params and all ipa_edge_args structures if they are no
+ longer needed after ipa-cp. */
+void
+free_all_ipa_structures_after_ipa_cp (void)
+{
+ if (!flag_indirect_inlining)
+ {
+ ipa_free_all_edge_args ();
+ ipa_free_all_node_params ();
+ ipa_unregister_cgraph_hooks ();
+ }
+}
+
+/* Free all ipa_node_params and all ipa_edge_args structures if they are no
+ longer needed after indirect inlining. */
+void
+free_all_ipa_structures_after_iinln (void)
+{
+ ipa_free_all_edge_args ();
+ ipa_free_all_node_params ();
+ ipa_unregister_cgraph_hooks ();
}
/* Print ipa_tree_map data structures of all functions in the
@@ -398,7 +1226,11 @@ ipa_print_all_tree_maps (FILE * f)
fprintf (f, "\nPARAM TREE MAP PRINT\n");
for (node = cgraph_nodes; node; node = node->next)
{
- struct ipa_node_params *info = IPA_NODE_REF (node);
+ struct ipa_node_params *info;
+
+ if (!node->analyzed)
+ continue;
+ info = IPA_NODE_REF (node);
fprintf (f, "function %s Trees :: \n", cgraph_node_name (node));
count = ipa_get_param_count (info);
for (i = 0; i < count; i++)
@@ -412,29 +1244,37 @@ ipa_print_all_tree_maps (FILE * f)
}
}
-/* Print modified_flags data structures of all functions in the
- callgraph to F. */
+/* Print param_flags data structures of the NODE to F. */
void
-ipa_print_all_params_modified (FILE * f)
+ipa_print_node_param_flags (FILE * f, struct cgraph_node *node)
{
int i, count;
- bool temp;
- struct cgraph_node *node;
+ struct ipa_node_params *info;
- fprintf (f, "\nMODIFY PRINT\n");
- for (node = cgraph_nodes; node; node = node->next)
+ if (!node->analyzed)
+ return;
+ info = IPA_NODE_REF (node);
+ fprintf (f, "PARAM FLAGS of function %s: \n", cgraph_node_name (node));
+ count = ipa_get_param_count (info);
+ for (i = 0; i < count; i++)
{
- struct ipa_node_params *info = IPA_NODE_REF (node);
- fprintf (f, "function %s :: \n", cgraph_node_name (node));
- count = ipa_get_param_count (info);
- for (i = 0; i < count; i++)
- {
- temp = info->modified_flags[i];
- if (temp)
- fprintf (f, " param [%d] true \n", i);
- else
- fprintf (f, " param [%d] false \n", i);
- }
+ fprintf (f, " param %d flags:", i);
+ if (ipa_is_ith_param_modified (info, i))
+ fprintf (f, " modified");
+ if (ipa_is_ith_param_called (info, i))
+ fprintf (f, " called");
+ fprintf (f, "\n");
}
}
+/* Print param_flags data structures of all functions in the
+ callgraph to F. */
+void
+ipa_print_all_param_flags (FILE * f)
+{
+ struct cgraph_node *node;
+
+ fprintf (f, "\nIPA PARAM FLAGS DUMP\n");
+ for (node = cgraph_nodes; node; node = node->next)
+ ipa_print_node_param_flags (f, node);
+}
diff --git a/gcc/ipa-prop.h b/gcc/ipa-prop.h
index a81418d7f47..908a97e7797 100644
--- a/gcc/ipa-prop.h
+++ b/gcc/ipa-prop.h
@@ -21,6 +21,8 @@ along with GCC; see the file COPYING3. If not see
#define IPA_PROP_H
#include "tree.h"
+#include "vec.h"
+#include "cgraph.h"
/* The following definitions and interfaces are used by
interprocedural analyses. */
@@ -31,21 +33,23 @@ along with GCC; see the file COPYING3. If not see
Constant - a constant is passed as an actual argument.
Unknown - neither of the above.
Integer and real constants are represented as IPA_CONST and Fortran
- constants are represented as IPA_CONST_REF. */
+ constants are represented as IPA_CONST_REF. Finally, IPA_CONST_MEMBER_PTR
+ stands for C++ member pointers constants. */
enum jump_func_type
{
- IPA_UNKNOWN,
+ IPA_UNKNOWN = 0, /* newly allocated and zeroed jump functions default */
IPA_CONST,
IPA_CONST_REF,
+ IPA_CONST_MEMBER_PTR,
IPA_PASS_THROUGH
};
/* All formal parameters in the program have a lattice associated with it
computed by the interprocedural stage of IPCP.
There are three main values of the lattice:
- TOP - unknown.
- BOTTOM - non constant.
- CONSTANT_TYPE - constant value.
+ IPA_TOP - unknown,
+ IPA_BOTTOM - non constant,
+ IPA_CONST_VALUE - simple scalar constant,
Cval of formal f will have a constant value if all callsites to this
function have the same constant value passed to f.
Integer and real constants are represented as IPA_CONST and Fortran
@@ -58,14 +62,24 @@ enum ipa_lattice_type
IPA_TOP
};
-/* Represents a value of a jump function.
- value represents a constant.
- formal_id is used only in jump function context and represents
- pass-through parameter (the formal of caller is passed as argument). */
+/* Structure holding a C++ member pointer constant. Holds a pointer to the
+ method and delta offset. */
+struct ipa_member_ptr_cst
+{
+ tree pfn;
+ tree delta;
+};
+
+/* Represents a value of a jump function. formal_id is used only in jump
+ function context and represents pass-through parameter (the formal parameter
+ of the caller is passed as argument). constant represents the actual
+ constant in constant jump functions and member_cst holds constant c++ member
+ functions. */
union jump_func_value
{
unsigned int formal_id;
tree constant;
+ struct ipa_member_ptr_cst member_cst;
};
/* A jump function for a callsite represents the values passed as actual
@@ -100,18 +114,43 @@ struct ipa_replace_map
bool ref_p;
};
-/* Return the field in cgraph_node/cgraph_edge struct that points
- to ipa_node_params/ipa_edge_args struct. */
-#define IPA_NODE_REF(MT) ((struct ipa_node_params *)(MT)->aux)
-#define IPA_EDGE_REF(EDGE) ((struct ipa_edge_args *)(EDGE)->aux)
-/* This macro checks validity of index returned by
- ipa_get_param_decl_index function. */
-#define IS_VALID_JUMP_FUNC_INDEX(I) ((I) != -1)
+/* ipa_param_flags contains various flags that describe how the associated
+ parameter is treated within a function. */
+struct ipa_param_flags
+{
+ /* Whether the value parameter has been modified within the function. */
+ unsigned modified : 1;
+ /* Whether the parameter has been used as a call destination. */
+ unsigned called : 1;
+};
+
+/* Each instance of the following structure describes a statement that calls a
+ function parameter. Those referring to statements within the same function
+ are linked in a list. */
+struct ipa_param_call_note
+{
+ /* Linked list's next */
+ struct ipa_param_call_note *next;
+ /* Statement that contains the call to the parameter above. */
+ gimple stmt;
+ /* Index of the parameter that is called. */
+ unsigned int formal_id;
+ /* Expected number of executions: calculated in profile.c. */
+ gcov_type count;
+ /* Expected frequency of executions within the function. see cgraph_edge in
+ cgraph.h for more on this. */
+ int frequency;
+ /* Depth of loop nest, 1 means no loop nest. */
+ int loop_nest;
+ /* Set when we have already found the target to be a compile time constant
+ and turned this into an edge or when the note was found unusable for some
+ reason. */
+ bool processed;
+};
/* ipa_node_params stores information related to formal parameters of functions
and some other information for interprocedural passes that operate on
parameters (such as ipa-cp). */
-
struct ipa_node_params
{
/* Number of formal parameters of this function. When set to 0,
@@ -122,8 +161,10 @@ struct ipa_node_params
struct ipcp_lattice *ipcp_lattices;
/* Mapping each parameter to its PARM_DECL tree. */
tree *param_decls;
- /* Indicating which parameter is modified in its function. */
- bool *modified_flags;
+ /* Various flags describing individual parameters. */
+ struct ipa_param_flags *param_flags;
+ /* List of structures enumerating calls to a formal parameter. */
+ struct ipa_param_call_note *param_calls;
/* Only for versioned nodes this field would not be NULL,
it points to the node that IPA cp cloned from. */
struct cgraph_node *ipcp_orig_node;
@@ -137,6 +178,10 @@ struct ipa_node_params
/* Whether this function is called with variable number of actual
arguments. */
unsigned called_with_var_arguments : 1;
+ /* Whether the modification analysis has already been performed. */
+ unsigned modification_analysis_done : 1;
+ /* Whether the param uses analysis has already been performed. */
+ unsigned uses_analysis_done : 1;
};
/* ipa_node_params access functions. Please use these to access fields that
@@ -171,7 +216,16 @@ ipa_get_ith_param (struct ipa_node_params *info, int i)
static inline bool
ipa_is_ith_param_modified (struct ipa_node_params *info, int i)
{
- return info->modified_flags[i];
+ return info->param_flags[i].modified;
+}
+
+/* Returns the called flag corresponding o the ith paramterer. Note there is
+ no setter method as the goal is to set all flags when building the array in
+ ipa_detect_called_params. */
+static inline bool
+ipa_is_ith_param_called (struct ipa_node_params *info, int i)
+{
+ return info->param_flags[i].called;
}
/* Flag this node as having callers with variable number of arguments. */
@@ -229,6 +283,82 @@ ipa_get_ith_jump_func (struct ipa_edge_args *args, int i)
return &args->jump_functions[i];
}
+/* Vectors need to have typedefs of structures. */
+typedef struct ipa_node_params ipa_node_params_t;
+typedef struct ipa_edge_args ipa_edge_args_t;
+
+/* Types of vectors hodling the infos. */
+DEF_VEC_O (ipa_node_params_t);
+DEF_VEC_ALLOC_O (ipa_node_params_t, heap);
+DEF_VEC_O (ipa_edge_args_t);
+DEF_VEC_ALLOC_O (ipa_edge_args_t, heap);
+
+/* Vector where the parameter infos are actually stored. */
+extern VEC (ipa_node_params_t, heap) *ipa_node_params_vector;
+/* Vector where the parameter infos are actually stored. */
+extern VEC (ipa_edge_args_t, heap) *ipa_edge_args_vector;
+
+/* Return the associated parameter/argument info corresponding to the given
+ node/edge. */
+#define IPA_NODE_REF(NODE) (VEC_index (ipa_node_params_t, \
+ ipa_node_params_vector, (NODE)->uid))
+#define IPA_EDGE_REF(EDGE) (VEC_index (ipa_edge_args_t, \
+ ipa_edge_args_vector, (EDGE)->uid))
+/* This macro checks validity of index returned by
+ ipa_get_param_decl_index function. */
+#define IS_VALID_JUMP_FUNC_INDEX(I) ((I) != -1)
+
+/* Creating and freeing ipa_node_params and ipa_edge_args. */
+void ipa_create_all_node_params (void);
+void ipa_create_all_edge_args (void);
+void ipa_free_edge_args_substructures (struct ipa_edge_args *);
+void ipa_free_node_params_substructures (struct ipa_node_params *);
+void ipa_free_all_node_params (void);
+void ipa_free_all_edge_args (void);
+void free_all_ipa_structures_after_ipa_cp (void);
+void free_all_ipa_structures_after_iinln (void);
+void ipa_register_cgraph_hooks (void);
+
+/* This function ensures the array of node param infos is big enough to
+ accomdate a structure for all nodes and realloacates it if not. */
+static inline void
+ipa_check_create_node_params (void)
+{
+ if (!ipa_node_params_vector)
+ ipa_node_params_vector = VEC_alloc (ipa_node_params_t, heap,
+ cgraph_max_uid);
+
+ if (VEC_length (ipa_node_params_t, ipa_node_params_vector)
+ <= (unsigned) cgraph_max_uid)
+ VEC_safe_grow_cleared (ipa_node_params_t, heap,
+ ipa_node_params_vector, cgraph_max_uid + 1);
+}
+
+/* This function ensures the array of adge arguments infos is big enough to
+ accomdate a structure for all edges and realloacates it if not. */
+static inline void
+ipa_check_create_edge_args (void)
+{
+ if (!ipa_edge_args_vector)
+ ipa_edge_args_vector = VEC_alloc (ipa_edge_args_t, heap,
+ cgraph_edge_max_uid);
+
+ if (VEC_length (ipa_edge_args_t, ipa_edge_args_vector)
+ <= (unsigned) cgraph_edge_max_uid)
+ VEC_safe_grow_cleared (ipa_edge_args_t, heap, ipa_edge_args_vector,
+ cgraph_edge_max_uid + 1);
+}
+
+/* Returns true if the array of edge infos is large enough to accomodate an
+ info for EDGE. The main purpose of this function is that debug dumping
+ function can check info availability without causing reallocations. */
+static inline bool
+ipa_edge_args_info_available_for_edge_p (struct cgraph_edge *edge)
+{
+ return ((unsigned) edge->uid < VEC_length (ipa_edge_args_t,
+ ipa_edge_args_vector));
+}
+
/* A function list element. It is used to create a temporary worklist used in
the propagation stage of IPCP. (can be used for more IPA optimizations) */
struct ipa_func_list
@@ -250,16 +380,15 @@ void ipa_count_arguments (struct cgraph_edge *);
void ipa_count_formal_params (struct cgraph_node *);
void ipa_create_param_decls_array (struct cgraph_node *);
void ipa_detect_param_modifications (struct cgraph_node *);
-
-/* Creating and freeing ipa_node_params and ipa_edge_args. */
-void ipa_create_node_params (struct cgraph_node *);
-void ipa_free_all_node_params (void);
-void ipa_create_all_node_params (void);
-void ipa_create_all_edge_args (void);
-void ipa_free_all_edge_args (void);
+void ipa_analyze_params_uses (struct cgraph_node *);
+void ipa_propagate_indirect_call_infos (struct cgraph_edge *cs,
+ VEC (cgraph_edge_p, heap) *new_edges);
/* Debugging interface. */
void ipa_print_all_tree_maps (FILE *);
-void ipa_print_all_params_modified (FILE *);
+void ipa_print_node_param_flags (FILE * f, struct cgraph_node *node);
+void ipa_print_all_param_flags (FILE *);
+void ipa_print_node_jump_functions (FILE *f, struct cgraph_node *node);
+void ipa_print_all_jump_functions (FILE * f);
#endif /* IPA_PROP_H */
diff --git a/gcc/ipa-pure-const.c b/gcc/ipa-pure-const.c
index 3b2cdaee2a1..7720d304a2d 100644
--- a/gcc/ipa-pure-const.c
+++ b/gcc/ipa-pure-const.c
@@ -44,7 +44,7 @@ along with GCC; see the file COPYING3. If not see
#include "ggc.h"
#include "ipa-utils.h"
#include "c-common.h"
-#include "tree-gimple.h"
+#include "gimple.h"
#include "cgraph.h"
#include "output.h"
#include "flags.h"
@@ -276,42 +276,47 @@ check_lhs_var (funct_state local, tree t)
actual asm statement. */
static void
-get_asm_expr_operands (funct_state local, tree stmt)
+get_asm_expr_operands (funct_state local, gimple stmt)
{
- int noutputs = list_length (ASM_OUTPUTS (stmt));
+ size_t noutputs = gimple_asm_noutputs (stmt);
const char **oconstraints
= (const char **) alloca ((noutputs) * sizeof (const char *));
- int i;
- tree link;
+ size_t i;
+ tree op;
const char *constraint;
bool allows_mem, allows_reg, is_inout;
- for (i=0, link = ASM_OUTPUTS (stmt); link; ++i, link = TREE_CHAIN (link))
+ for (i = 0; i < noutputs; i++)
{
+ op = gimple_asm_output_op (stmt, i);
oconstraints[i] = constraint
- = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
+ = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (op)));
parse_output_constraint (&constraint, i, 0, 0,
&allows_mem, &allows_reg, &is_inout);
- check_lhs_var (local, TREE_VALUE (link));
+ check_lhs_var (local, TREE_VALUE (op));
}
- for (link = ASM_INPUTS (stmt); link; link = TREE_CHAIN (link))
+ for (i = 0; i < gimple_asm_ninputs (stmt); i++)
{
+ op = gimple_asm_input_op (stmt, i);
constraint
- = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
+ = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (op)));
parse_input_constraint (&constraint, 0, 0, noutputs, 0,
oconstraints, &allows_mem, &allows_reg);
- check_rhs_var (local, TREE_VALUE (link));
+ check_rhs_var (local, TREE_VALUE (op));
}
- for (link = ASM_CLOBBERS (stmt); link; link = TREE_CHAIN (link))
- if (simple_cst_equal(TREE_VALUE (link), memory_identifier_string) == 1)
- /* Abandon all hope, ye who enter here. */
- local->pure_const_state = IPA_NEITHER;
+ for (i = 0; i < gimple_asm_nclobbers (stmt); i++)
+ {
+ op = gimple_asm_clobber_op (stmt, i);
+ if (simple_cst_equal(TREE_VALUE (op), memory_identifier_string) == 1)
+ /* Abandon all hope, ye who enter here. */
+ local->pure_const_state = IPA_NEITHER;
+ }
- if (ASM_VOLATILE_P (stmt))
+ if (gimple_asm_volatile_p (stmt))
local->pure_const_state = IPA_NEITHER;
}
@@ -323,17 +328,20 @@ get_asm_expr_operands (funct_state local, tree stmt)
the entire call expression. */
static void
-check_call (funct_state local, tree call_expr)
+check_call (funct_state local, gimple call)
{
- int flags = call_expr_flags (call_expr);
- tree operand;
- call_expr_arg_iterator iter;
- tree callee_t = get_callee_fndecl (call_expr);
+ int flags = gimple_call_flags (call);
+ tree lhs, callee_t = gimple_call_fndecl (call);
struct cgraph_node* callee;
enum availability avail = AVAIL_NOT_AVAILABLE;
+ size_t i;
+
+ lhs = gimple_call_lhs (call);
+ if (lhs)
+ check_lhs_var (local, lhs);
- FOR_EACH_CALL_EXPR_ARG (operand, iter, call_expr)
- check_rhs_var (local, operand);
+ for (i = 0; i < gimple_call_num_args (call); i++)
+ check_rhs_var (local, gimple_call_arg (call, i));
/* The const and pure flags are set by a variety of places in the
compiler (including here). If someone has already set the flags
@@ -405,11 +413,10 @@ check_call (funct_state local, tree call_expr)
should be converted to use the operand scanner. */
static tree
-scan_function (tree *tp,
- int *walk_subtrees,
- void *data)
+scan_function_op (tree *tp, int *walk_subtrees, void *data)
{
- struct cgraph_node *fn = (struct cgraph_node *) data;
+ struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
+ struct cgraph_node *fn = (struct cgraph_node *) wi->info;
tree t = *tp;
funct_state local = get_function_state (fn);
@@ -417,58 +424,72 @@ scan_function (tree *tp,
{
case VAR_DECL:
if (DECL_INITIAL (t))
- walk_tree (&DECL_INITIAL (t), scan_function, fn, visited_nodes);
+ walk_tree (&DECL_INITIAL (t), scan_function_op, data, visited_nodes);
*walk_subtrees = 0;
break;
- case GIMPLE_MODIFY_STMT:
+ case ADDR_EXPR:
+ /* This case is here to find addresses on rhs of constructors in
+ decl_initial of static variables. */
+ check_rhs_var (local, t);
+ *walk_subtrees = 0;
+ break;
+
+ default:
+ break;
+ }
+ return NULL;
+}
+
+static tree
+scan_function_stmt (gimple_stmt_iterator *gsi_p,
+ bool *handled_ops_p,
+ struct walk_stmt_info *wi)
+{
+ struct cgraph_node *fn = (struct cgraph_node *) wi->info;
+ gimple stmt = gsi_stmt (*gsi_p);
+ funct_state local = get_function_state (fn);
+
+ switch (gimple_code (stmt))
+ {
+ case GIMPLE_ASSIGN:
{
/* First look on the lhs and see what variable is stored to */
- tree lhs = GIMPLE_STMT_OPERAND (t, 0);
- tree rhs = GIMPLE_STMT_OPERAND (t, 1);
+ tree lhs = gimple_assign_lhs (stmt);
+ tree rhs1 = gimple_assign_rhs1 (stmt);
+ tree rhs2 = gimple_assign_rhs2 (stmt);
+ enum tree_code code = gimple_assign_rhs_code (stmt);
+
check_lhs_var (local, lhs);
/* For the purposes of figuring out what the cast affects */
/* Next check the operands on the rhs to see if they are ok. */
- switch (TREE_CODE_CLASS (TREE_CODE (rhs)))
+ switch (TREE_CODE_CLASS (code))
{
case tcc_binary:
{
- tree op0 = TREE_OPERAND (rhs, 0);
- tree op1 = TREE_OPERAND (rhs, 1);
- check_rhs_var (local, op0);
- check_rhs_var (local, op1);
+ check_rhs_var (local, rhs1);
+ check_rhs_var (local, rhs2);
}
break;
case tcc_unary:
{
- tree op0 = TREE_OPERAND (rhs, 0);
- check_rhs_var (local, op0);
+ check_rhs_var (local, rhs1);
}
break;
case tcc_reference:
- check_rhs_var (local, rhs);
+ check_rhs_var (local, rhs1);
break;
case tcc_declaration:
- check_rhs_var (local, rhs);
+ check_rhs_var (local, rhs1);
break;
case tcc_expression:
- switch (TREE_CODE (rhs))
+ switch (code)
{
case ADDR_EXPR:
- check_rhs_var (local, rhs);
- break;
- default:
- break;
- }
- break;
- case tcc_vl_exp:
- switch (TREE_CODE (rhs))
- {
- case CALL_EXPR:
- check_call (local, rhs);
+ check_rhs_var (local, rhs1);
break;
default:
break;
@@ -477,19 +498,12 @@ scan_function (tree *tp,
default:
break;
}
- *walk_subtrees = 0;
+ *handled_ops_p = true;
}
break;
- case ADDR_EXPR:
- /* This case is here to find addresses on rhs of constructors in
- decl_initial of static variables. */
- check_rhs_var (local, t);
- *walk_subtrees = 0;
- break;
-
- case LABEL_EXPR:
- if (DECL_NONLOCAL (TREE_OPERAND (t, 0)))
+ case GIMPLE_LABEL:
+ if (DECL_NONLOCAL (gimple_label_label (stmt)))
/* Target of long jump. */
{
local->pure_const_state = IPA_NEITHER;
@@ -497,14 +511,14 @@ scan_function (tree *tp,
}
break;
- case CALL_EXPR:
- check_call (local, t);
- *walk_subtrees = 0;
+ case GIMPLE_CALL:
+ check_call (local, stmt);
+ *handled_ops_p = true;
break;
- case ASM_EXPR:
- get_asm_expr_operands (local, t);
- *walk_subtrees = 0;
+ case GIMPLE_ASM:
+ get_asm_expr_operands (local, stmt);
+ *handled_ops_p = true;
break;
default:
@@ -567,11 +581,18 @@ analyze_function (struct cgraph_node *fn)
FOR_EACH_BB_FN (this_block, this_cfun)
{
- block_stmt_iterator bsi;
- for (bsi = bsi_start (this_block); !bsi_end_p (bsi); bsi_next (&bsi))
+ gimple_stmt_iterator gsi;
+ struct walk_stmt_info wi;
+
+ memset (&wi, 0, sizeof(wi));
+ for (gsi = gsi_start_bb (this_block);
+ !gsi_end_p (gsi);
+ gsi_next (&gsi))
{
- walk_tree (bsi_stmt_ptr (bsi), scan_function,
- fn, visited_nodes);
+ wi.info = fn;
+ wi.pset = visited_nodes;
+ walk_gimple_stmt (&gsi, scan_function_stmt, scan_function_op,
+ &wi);
if (l->pure_const_state == IPA_NEITHER)
goto end;
}
@@ -771,7 +792,7 @@ static_execute (void)
static bool
gate_pure_const (void)
{
- return (flag_unit_at_a_time != 0 && flag_ipa_pure_const
+ return (flag_ipa_pure_const
/* Don't bother doing anything if the program has errors. */
&& !(errorcount || sorrycount));
}
diff --git a/gcc/ipa-reference.c b/gcc/ipa-reference.c
index 75aed2f52f6..c28c7327f2c 100644
--- a/gcc/ipa-reference.c
+++ b/gcc/ipa-reference.c
@@ -45,8 +45,7 @@ along with GCC; see the file COPYING3. If not see
Currently must be run after inlining decisions have been made since
otherwise, the local sets will not contain information that is
consistent with post inlined state. The global sets are not prone
- to this problem since they are by definition transitive.
-*/
+ to this problem since they are by definition transitive. */
#include "config.h"
#include "system.h"
@@ -62,7 +61,7 @@ along with GCC; see the file COPYING3. If not see
#include "ipa-utils.h"
#include "ipa-reference.h"
#include "c-common.h"
-#include "tree-gimple.h"
+#include "gimple.h"
#include "cgraph.h"
#include "output.h"
#include "flags.h"
@@ -388,43 +387,48 @@ check_lhs_var (ipa_reference_local_vars_info_t local, tree t)
function being analyzed and STMT is the actual asm statement. */
static void
-get_asm_expr_operands (ipa_reference_local_vars_info_t local, tree stmt)
+get_asm_stmt_operands (ipa_reference_local_vars_info_t local, gimple stmt)
{
- int noutputs = list_length (ASM_OUTPUTS (stmt));
+ size_t noutputs = gimple_asm_noutputs (stmt);
const char **oconstraints
= (const char **) alloca ((noutputs) * sizeof (const char *));
- int i;
- tree link;
+ size_t i;
+ tree op;
const char *constraint;
bool allows_mem, allows_reg, is_inout;
- for (i=0, link = ASM_OUTPUTS (stmt); link; ++i, link = TREE_CHAIN (link))
+ for (i = 0; i < noutputs; i++)
{
+ op = gimple_asm_output_op (stmt, i);
oconstraints[i] = constraint
- = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
+ = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (op)));
parse_output_constraint (&constraint, i, 0, 0,
&allows_mem, &allows_reg, &is_inout);
- check_lhs_var (local, TREE_VALUE (link));
+ check_lhs_var (local, TREE_VALUE (op));
}
- for (link = ASM_INPUTS (stmt); link; link = TREE_CHAIN (link))
+ for (i = 0; i < gimple_asm_ninputs (stmt); i++)
{
+ op = gimple_asm_input_op (stmt, i);
constraint
- = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
+ = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (op)));
parse_input_constraint (&constraint, 0, 0, noutputs, 0,
oconstraints, &allows_mem, &allows_reg);
- check_rhs_var (local, TREE_VALUE (link));
+ check_rhs_var (local, TREE_VALUE (op));
}
- for (link = ASM_CLOBBERS (stmt); link; link = TREE_CHAIN (link))
- if (simple_cst_equal(TREE_VALUE (link), memory_identifier_string) == 1)
- {
- /* Abandon all hope, ye who enter here. */
- local->calls_read_all = true;
- local->calls_write_all = true;
- }
+ for (i = 0; i < gimple_asm_nclobbers (stmt); i++)
+ {
+ op = gimple_asm_clobber_op (stmt, i);
+ if (simple_cst_equal(TREE_VALUE (op), memory_identifier_string) == 1)
+ {
+ /* Abandon all hope, ye who enter here. */
+ local->calls_read_all = true;
+ local->calls_write_all = true;
+ }
+ }
}
/* Check the parameters of a function call from CALLER to CALL_EXPR to
@@ -435,16 +439,19 @@ get_asm_expr_operands (ipa_reference_local_vars_info_t local, tree stmt)
the tree node for the entire call expression. */
static void
-check_call (ipa_reference_local_vars_info_t local, tree call_expr)
+check_call (ipa_reference_local_vars_info_t local, gimple stmt)
{
- int flags = call_expr_flags (call_expr);
+ int flags = gimple_call_flags (stmt);
tree operand;
- tree callee_t = get_callee_fndecl (call_expr);
+ tree callee_t = gimple_call_fndecl (stmt);
enum availability avail = AVAIL_NOT_AVAILABLE;
- call_expr_arg_iterator iter;
+ size_t i;
- FOR_EACH_CALL_EXPR_ARG (operand, iter, call_expr)
- check_rhs_var (local, operand);
+ if ((operand = gimple_call_lhs (stmt)) != NULL)
+ check_lhs_var (local, operand);
+
+ for (i = 0; i < gimple_call_num_args (stmt); i++)
+ check_rhs_var (local, gimple_call_arg (stmt, i));
if (callee_t)
{
@@ -473,73 +480,49 @@ check_call (ipa_reference_local_vars_info_t local, tree call_expr)
should be converted to use the operand scanner. */
static tree
-scan_for_static_refs (tree *tp,
- int *walk_subtrees,
- void *data)
+scan_stmt_for_static_refs (gimple_stmt_iterator *gsip, bool *handled_ops_p,
+ struct walk_stmt_info *data)
{
- struct cgraph_node *fn = (struct cgraph_node *) data;
- tree t = *tp;
+ struct cgraph_node *fn = (struct cgraph_node *) data->info;
+ gimple stmt = gsi_stmt (*gsip);
ipa_reference_local_vars_info_t local = NULL;
if (fn)
local = get_reference_vars_info_from_cgraph (fn)->local;
- switch (TREE_CODE (t))
+ switch (gimple_code (stmt))
{
- case VAR_DECL:
- if (DECL_INITIAL (t))
- walk_tree (&DECL_INITIAL (t), scan_for_static_refs, fn, visited_nodes);
- *walk_subtrees = 0;
- break;
-
- case GIMPLE_MODIFY_STMT:
+ case GIMPLE_ASSIGN:
{
/* First look on the lhs and see what variable is stored to */
- tree lhs = GIMPLE_STMT_OPERAND (t, 0);
- tree rhs = GIMPLE_STMT_OPERAND (t, 1);
+ tree lhs = gimple_assign_lhs (stmt);
+ tree rhs1 = gimple_assign_rhs1 (stmt);
+ tree rhs2 = gimple_assign_rhs2 (stmt);
+ enum tree_code code = gimple_assign_rhs_code (stmt);
+
check_lhs_var (local, lhs);
/* For the purposes of figuring out what the cast affects */
/* Next check the operands on the rhs to see if they are ok. */
- switch (TREE_CODE_CLASS (TREE_CODE (rhs)))
+ switch (TREE_CODE_CLASS (code))
{
case tcc_binary:
case tcc_comparison:
- {
- tree op0 = TREE_OPERAND (rhs, 0);
- tree op1 = TREE_OPERAND (rhs, 1);
- check_rhs_var (local, op0);
- check_rhs_var (local, op1);
- }
+ check_rhs_var (local, rhs1);
+ check_rhs_var (local, rhs2);
break;
- case tcc_unary:
- {
- tree op0 = TREE_OPERAND (rhs, 0);
- check_rhs_var (local, op0);
- }
- break;
+ case tcc_unary:
case tcc_reference:
- check_rhs_var (local, rhs);
- break;
case tcc_declaration:
- check_rhs_var (local, rhs);
+ check_rhs_var (local, rhs1);
break;
+
case tcc_expression:
- switch (TREE_CODE (rhs))
+ switch (code)
{
case ADDR_EXPR:
- check_rhs_var (local, rhs);
- break;
- default:
- break;
- }
- break;
- case tcc_vl_exp:
- switch (TREE_CODE (rhs))
- {
- case CALL_EXPR:
- check_call (local, rhs);
+ check_rhs_var (local, rhs1);
break;
default:
break;
@@ -548,19 +531,12 @@ scan_for_static_refs (tree *tp,
default:
break;
}
- *walk_subtrees = 0;
+ *handled_ops_p = true;
}
break;
- case ADDR_EXPR:
- /* This case is here to find addresses on rhs of constructors in
- decl_initial of static variables. */
- check_rhs_var (local, t);
- *walk_subtrees = 0;
- break;
-
- case LABEL_EXPR:
- if (DECL_NONLOCAL (TREE_OPERAND (t, 0)))
+ case GIMPLE_LABEL:
+ if (DECL_NONLOCAL (gimple_label_label (stmt)))
{
/* Target of long jump. */
local->calls_read_all = true;
@@ -568,14 +544,14 @@ scan_for_static_refs (tree *tp,
}
break;
- case CALL_EXPR:
- check_call (local, t);
- *walk_subtrees = 0;
+ case GIMPLE_CALL:
+ check_call (local, stmt);
+ *handled_ops_p = true;
break;
- case ASM_EXPR:
- get_asm_expr_operands (local, t);
- *walk_subtrees = 0;
+ case GIMPLE_ASM:
+ get_asm_stmt_operands (local, stmt);
+ *handled_ops_p = true;
break;
default:
@@ -584,6 +560,42 @@ scan_for_static_refs (tree *tp,
return NULL;
}
+/* Call-back to scan GIMPLE operands for static references. This is supposed
+ to work with scan_stmt_for_static_refs so the real call-back data is stored
+ inside a walk_stmt_info struct. Callers using the walk_tree interface must
+ also wrap the call-back data in a walk_stmt_info struct. */
+
+static tree
+scan_op_for_static_refs (tree *tp, int *walk_subtrees, void *data)
+{
+ struct walk_stmt_info *wi = (struct walk_stmt_info*) data;
+ struct cgraph_node *fn = (struct cgraph_node *) wi->info;
+ tree t = *tp;
+ ipa_reference_local_vars_info_t local = NULL;
+ if (fn)
+ local = get_reference_vars_info_from_cgraph (fn)->local;
+
+ switch (TREE_CODE (t))
+ {
+ case VAR_DECL:
+ if (DECL_INITIAL (t))
+ walk_tree (&DECL_INITIAL (t), scan_op_for_static_refs, data,
+ wi->pset);
+ *walk_subtrees = 0;
+ break;
+
+ case ADDR_EXPR:
+ /* This case is here to find addresses on rhs of constructors in
+ decl_initial of static variables. */
+ check_rhs_var (local, t);
+ *walk_subtrees = 0;
+ break;
+
+ default:
+ break;
+ }
+ return NULL;
+}
/* Lookup the tree node for the static variable that has UID. */
static tree
@@ -777,9 +789,13 @@ ipa_init (void)
static void
analyze_variable (struct varpool_node *vnode)
{
+ struct walk_stmt_info wi;
tree global = vnode->decl;
- walk_tree (&DECL_INITIAL (global), scan_for_static_refs,
- NULL, visited_nodes);
+
+ memset (&wi, 0, sizeof (wi));
+ wi.pset = visited_nodes;
+ walk_tree (&DECL_INITIAL (global), scan_op_for_static_refs,
+ &wi, wi.pset);
}
/* This is the main routine for finding the reference patterns for
@@ -793,6 +809,7 @@ analyze_function (struct cgraph_node *fn)
ipa_reference_local_vars_info_t l
= XCNEW (struct ipa_reference_local_vars_info_d);
tree decl = fn->decl;
+ struct walk_stmt_info wi;
/* Add the info to the tree's annotation. */
get_function_ann (fn->decl)->reference_vars_info = info;
@@ -810,14 +827,18 @@ analyze_function (struct cgraph_node *fn)
FOR_EACH_BB_FN (this_block, this_cfun)
{
- block_stmt_iterator bsi;
- tree phi, op;
+ gimple_stmt_iterator gsi;
+ gimple phi;
+ tree op;
use_operand_p use;
ssa_op_iter iter;
/* Find the addresses taken in phi node arguments. */
- for (phi = phi_nodes (this_block); phi; phi = PHI_CHAIN (phi))
+ for (gsi = gsi_start_phis (this_block);
+ !gsi_end_p (gsi);
+ gsi_next (&gsi))
{
+ phi = gsi_stmt (gsi);
FOR_EACH_PHI_ARG (use, phi, iter, SSA_OP_USE)
{
op = USE_FROM_PTR (use);
@@ -826,9 +847,12 @@ analyze_function (struct cgraph_node *fn)
}
}
- for (bsi = bsi_start (this_block); !bsi_end_p (bsi); bsi_next (&bsi))
- walk_tree (bsi_stmt_ptr (bsi), scan_for_static_refs,
- fn, visited_nodes);
+ memset (&wi, 0, sizeof (wi));
+ wi.info = fn;
+ wi.pset = visited_nodes;
+ for (gsi = gsi_start_bb (this_block); !gsi_end_p (gsi); gsi_next (&gsi))
+ walk_gimple_stmt (&gsi, scan_stmt_for_static_refs,
+ scan_op_for_static_refs, &wi);
}
}
@@ -844,8 +868,13 @@ analyze_function (struct cgraph_node *fn)
if (TREE_CODE (var) == VAR_DECL
&& DECL_INITIAL (var)
&& !TREE_STATIC (var))
- walk_tree (&DECL_INITIAL (var), scan_for_static_refs,
- fn, visited_nodes);
+ {
+ memset (&wi, 0, sizeof (wi));
+ wi.info = fn;
+ wi.pset = visited_nodes;
+ walk_tree (&DECL_INITIAL (var), scan_op_for_static_refs,
+ &wi, wi.pset);
+ }
}
}
}
@@ -1314,7 +1343,7 @@ static_execute (void)
static bool
gate_reference (void)
{
- return (flag_unit_at_a_time != 0 && flag_ipa_reference
+ return (flag_ipa_reference
/* Don't bother doing anything if the program has errors. */
&& !(errorcount || sorrycount));
}
@@ -1339,4 +1368,3 @@ struct simple_ipa_opt_pass pass_ipa_reference =
};
#include "gt-ipa-reference.h"
-
diff --git a/gcc/ipa-struct-reorg.c b/gcc/ipa-struct-reorg.c
index fffb454d831..d6bca8ab722 100644
--- a/gcc/ipa-struct-reorg.c
+++ b/gcc/ipa-struct-reorg.c
@@ -28,7 +28,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "ggc.h"
#include "tree.h"
#include "rtl.h"
-#include "tree-gimple.h"
+#include "gimple.h"
#include "tree-inline.h"
#include "tree-flow.h"
#include "tree-flow-inline.h"
@@ -55,6 +55,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "ipa-type-escape.h"
#include "tree-dump.h"
#include "c-common.h"
+#include "gimple.h"
/* This optimization implements structure peeling.
@@ -168,7 +169,7 @@ typedef const struct new_var_data *const_new_var;
/* This structure represents allocation site of the structure. */
typedef struct alloc_site
{
- tree stmt;
+ gimple stmt;
d_str str;
} alloc_site_t;
@@ -235,7 +236,7 @@ get_type_of_var (tree var)
/* Set of actions we do for each newly generated STMT. */
static inline void
-finalize_stmt (tree stmt)
+finalize_stmt (gimple stmt)
{
update_stmt (stmt);
mark_symbols_for_renaming (stmt);
@@ -244,9 +245,9 @@ finalize_stmt (tree stmt)
/* This function finalizes STMT and appends it to the list STMTS. */
static inline void
-finalize_stmt_and_append (tree *stmts, tree stmt)
+finalize_stmt_and_append (gimple_seq *stmts, gimple stmt)
{
- append_to_statement_list (stmt, stmts);
+ gimple_seq_add_stmt (stmts, stmt);
finalize_stmt (stmt);
}
@@ -307,25 +308,24 @@ find_field_in_struct (d_str str, tree field_decl)
static bool
is_result_of_mult (tree arg, tree *num, tree struct_size)
{
- tree size_def_stmt = SSA_NAME_DEF_STMT (arg);
+ gimple size_def_stmt = SSA_NAME_DEF_STMT (arg);
/* If the allocation statement was of the form
D.2229_10 = <alloc_func> (D.2228_9);
then size_def_stmt can be D.2228_9 = num.3_8 * 8; */
- if (size_def_stmt && TREE_CODE (size_def_stmt) == GIMPLE_MODIFY_STMT)
+ if (size_def_stmt && is_gimple_assign (size_def_stmt))
{
- tree lhs = GIMPLE_STMT_OPERAND (size_def_stmt, 0);
- tree rhs = GIMPLE_STMT_OPERAND (size_def_stmt, 1);
+ tree lhs = gimple_assign_lhs (size_def_stmt);
/* We expect temporary here. */
if (!is_gimple_reg (lhs))
return false;
- if (TREE_CODE (rhs) == MULT_EXPR)
+ if (gimple_assign_rhs_code (size_def_stmt) == MULT_EXPR)
{
- tree arg0 = TREE_OPERAND (rhs, 0);
- tree arg1 = TREE_OPERAND (rhs, 1);
+ tree arg0 = gimple_assign_rhs1 (size_def_stmt);
+ tree arg1 = gimple_assign_rhs2 (size_def_stmt);
if (operand_equal_p (arg0, struct_size, OEP_ONLY_CONST))
{
@@ -356,8 +356,9 @@ static bool
decompose_indirect_ref_acc (tree str_decl, struct field_access_site *acc)
{
tree ref_var;
- tree rhs, struct_size, op0, op1;
+ tree struct_size, op0, op1;
tree before_cast;
+ enum tree_code rhs_code;
ref_var = TREE_OPERAND (acc->ref, 0);
@@ -366,20 +367,20 @@ decompose_indirect_ref_acc (tree str_decl, struct field_access_site *acc)
acc->ref_def_stmt = SSA_NAME_DEF_STMT (ref_var);
if (!(acc->ref_def_stmt)
- || (TREE_CODE (acc->ref_def_stmt) != GIMPLE_MODIFY_STMT))
+ || (gimple_code (acc->ref_def_stmt) != GIMPLE_ASSIGN))
return false;
- rhs = GIMPLE_STMT_OPERAND (acc->ref_def_stmt, 1);
+ rhs_code = gimple_assign_rhs_code (acc->ref_def_stmt);
- if (TREE_CODE (rhs) != PLUS_EXPR
- && TREE_CODE (rhs)!= MINUS_EXPR
- && TREE_CODE (rhs) != POINTER_PLUS_EXPR)
+ if (rhs_code != PLUS_EXPR
+ && rhs_code != MINUS_EXPR
+ && rhs_code != POINTER_PLUS_EXPR)
return false;
- op0 = TREE_OPERAND (rhs, 0);
- op1 = TREE_OPERAND (rhs, 1);
+ op0 = gimple_assign_rhs1 (acc->ref_def_stmt);
+ op1 = gimple_assign_rhs2 (acc->ref_def_stmt);
- if (!is_array_access_through_pointer_and_index (TREE_CODE (rhs), op0, op1,
+ if (!is_array_access_through_pointer_and_index (rhs_code, op0, op1,
&acc->base, &acc->offset,
&acc->cast_stmt))
return false;
@@ -438,7 +439,7 @@ make_field_acc_node (void)
if it is already in hashtable of function accesses F_ACCS. */
static struct field_access_site *
-is_in_field_accs (tree stmt, htab_t f_accs)
+is_in_field_accs (gimple stmt, htab_t f_accs)
{
return (struct field_access_site *)
htab_find_with_hash (f_accs, stmt, htab_hash_pointer (stmt));
@@ -466,7 +467,7 @@ add_field_acc_to_acc_sites (struct field_access_site *acc,
accesses ACCS, this function creates it. */
static void
-add_access_to_acc_sites (tree stmt, tree var, htab_t accs)
+add_access_to_acc_sites (gimple stmt, tree var, htab_t accs)
{
struct access_site *acc;
@@ -538,23 +539,6 @@ finalize_new_vars_creation (void **slot, void *data ATTRIBUTE_UNUSED)
return 1;
}
-/* This function updates statements in STMT_LIST with BB info. */
-
-static void
-add_bb_info (basic_block bb, tree stmt_list)
-{
- if (TREE_CODE (stmt_list) == STATEMENT_LIST)
- {
- tree_stmt_iterator tsi;
- for (tsi = tsi_start (stmt_list); !tsi_end_p (tsi); tsi_next (&tsi))
- {
- tree stmt = tsi_stmt (tsi);
-
- set_bb_for_stmt (stmt, bb);
- }
- }
-}
-
/* This function looks for the variable of NEW_TYPE type, stored in VAR.
It returns it, if found, and NULL_TREE otherwise. */
@@ -610,12 +594,12 @@ find_new_var_of_type (tree orig_var, tree new_type)
res = NUM * sizeof(TYPE) and returns it.
res is filled into RES. */
-static tree
+static gimple
gen_size (tree num, tree type, tree *res)
{
tree struct_size = TYPE_SIZE_UNIT (type);
HOST_WIDE_INT struct_size_int = TREE_INT_CST_LOW (struct_size);
- tree new_stmt;
+ gimple new_stmt;
*res = create_tmp_var (TREE_TYPE (num), NULL);
@@ -625,17 +609,13 @@ gen_size (tree num, tree type, tree *res)
if (exact_log2 (struct_size_int) == -1)
{
tree size = build_int_cst (TREE_TYPE (num), struct_size_int);
- new_stmt = build_gimple_modify_stmt (*res, build2 (MULT_EXPR,
- TREE_TYPE (num),
- num, size));
+ new_stmt = gimple_build_assign_with_ops (MULT_EXPR, *res, num, size);
}
else
{
tree C = build_int_cst (TREE_TYPE (num), exact_log2 (struct_size_int));
- new_stmt = build_gimple_modify_stmt (*res, build2 (LSHIFT_EXPR,
- TREE_TYPE (num),
- num, C));
+ new_stmt = gimple_build_assign_with_ops (LSHIFT_EXPR, *res, num, C);
}
finalize_stmt (new_stmt);
@@ -646,21 +626,18 @@ gen_size (tree num, tree type, tree *res)
BEFORE_CAST to NEW_TYPE. The cast result variable is stored
into RES_P. ORIG_CAST_STMT is the original cast statement. */
-static tree
-gen_cast_stmt (tree before_cast, tree new_type, tree orig_cast_stmt,
+static gimple
+gen_cast_stmt (tree before_cast, tree new_type, gimple orig_cast_stmt,
tree *res_p)
{
- tree lhs, new_lhs, new_stmt;
- gcc_assert (TREE_CODE (orig_cast_stmt) == GIMPLE_MODIFY_STMT);
-
- lhs = GIMPLE_STMT_OPERAND (orig_cast_stmt, 0);
+ tree lhs, new_lhs;
+ gimple new_stmt;
+
+ lhs = gimple_assign_lhs (orig_cast_stmt);
new_lhs = find_new_var_of_type (lhs, new_type);
gcc_assert (new_lhs);
- new_stmt = build_gimple_modify_stmt (new_lhs,
- build1 (NOP_EXPR,
- TREE_TYPE (new_lhs),
- before_cast));
+ new_stmt = gimple_build_assign_with_ops (NOP_EXPR, new_lhs, before_cast, 0);
finalize_stmt (new_stmt);
*res_p = new_lhs;
return new_stmt;
@@ -673,12 +650,14 @@ static edge
make_edge_and_fix_phis_of_dest (basic_block bb, edge e)
{
edge new_e;
- tree phi, arg;
+ tree arg;
+ gimple_stmt_iterator si;
new_e = make_edge (bb, e->dest, e->flags);
- for (phi = phi_nodes (new_e->dest); phi; phi = PHI_CHAIN (phi))
+ for (si = gsi_start_phis (new_e->dest); !gsi_end_p (si); gsi_next (&si))
{
+ gimple phi = gsi_stmt (si);
arg = PHI_ARG_DEF_FROM_EDGE (phi, e);
add_phi_arg (phi, arg, new_e);
}
@@ -686,32 +665,46 @@ make_edge_and_fix_phis_of_dest (basic_block bb, edge e)
return new_e;
}
-/* This function inserts NEW_STMTS before STMT. */
+/* This function inserts NEW_STMT before STMT. */
static void
-insert_before_stmt (tree stmt, tree new_stmts)
+insert_before_stmt (gimple stmt, gimple new_stmt)
{
- block_stmt_iterator bsi;
+ gimple_stmt_iterator bsi;
- if (!stmt || !new_stmts)
+ if (!stmt || !new_stmt)
return;
- bsi = bsi_for_stmt (stmt);
- bsi_insert_before (&bsi, new_stmts, BSI_SAME_STMT);
+ bsi = gsi_for_stmt (stmt);
+ gsi_insert_before (&bsi, new_stmt, GSI_SAME_STMT);
}
/* Insert NEW_STMTS after STMT. */
static void
-insert_after_stmt (tree stmt, tree new_stmts)
+insert_seq_after_stmt (gimple stmt, gimple_seq new_stmts)
{
- block_stmt_iterator bsi;
+ gimple_stmt_iterator bsi;
if (!stmt || !new_stmts)
return;
- bsi = bsi_for_stmt (stmt);
- bsi_insert_after (&bsi, new_stmts, BSI_SAME_STMT);
+ bsi = gsi_for_stmt (stmt);
+ gsi_insert_seq_after (&bsi, new_stmts, GSI_SAME_STMT);
+}
+
+/* Insert NEW_STMT after STMT. */
+
+static void
+insert_after_stmt (gimple stmt, gimple new_stmt)
+{
+ gimple_stmt_iterator bsi;
+
+ if (!stmt || !new_stmt)
+ return;
+
+ bsi = gsi_for_stmt (stmt);
+ gsi_insert_after (&bsi, new_stmt, GSI_SAME_STMT);
}
/* This function returns vector of allocation sites
@@ -730,20 +723,20 @@ get_fallocs (tree fn_decl)
p_8 = (struct str_t *) D.2225_7;
which is returned by this function. */
-static tree
-get_final_alloc_stmt (tree alloc_stmt)
+static gimple
+get_final_alloc_stmt (gimple alloc_stmt)
{
- tree final_stmt;
+ gimple final_stmt;
use_operand_p use_p;
tree alloc_res;
if (!alloc_stmt)
return NULL;
- if (TREE_CODE (alloc_stmt) != GIMPLE_MODIFY_STMT)
+ if (!is_gimple_call (alloc_stmt))
return NULL;
- alloc_res = GIMPLE_STMT_OPERAND (alloc_stmt, 0);
+ alloc_res = gimple_get_lhs (alloc_stmt);
if (TREE_CODE (alloc_res) != SSA_NAME)
return NULL;
@@ -758,7 +751,7 @@ get_final_alloc_stmt (tree alloc_stmt)
sites of function FN_DECL. It returns false otherwise. */
static bool
-is_part_of_malloc (tree stmt, tree fn_decl)
+is_part_of_malloc (gimple stmt, tree fn_decl)
{
fallocs_t fallocs = get_fallocs (fn_decl);
@@ -767,8 +760,7 @@ is_part_of_malloc (tree stmt, tree fn_decl)
alloc_site_t *call;
unsigned i;
- for (i = 0;
- VEC_iterate (alloc_site_t, fallocs->allocs, i, call); i++)
+ for (i = 0; VEC_iterate (alloc_site_t, fallocs->allocs, i, call); i++)
if (call->stmt == stmt
|| get_final_alloc_stmt (call->stmt) == stmt)
return true;
@@ -780,7 +772,7 @@ is_part_of_malloc (tree stmt, tree fn_decl)
struct find_stmt_data
{
bool found;
- tree stmt;
+ gimple stmt;
};
/* This function looks for DATA->stmt among
@@ -790,9 +782,8 @@ struct find_stmt_data
static int
find_in_field_accs (void **slot, void *data)
{
- struct field_access_site *f_acc =
- *(struct field_access_site **) slot;
- tree stmt = ((struct find_stmt_data *)data)->stmt;
+ struct field_access_site *f_acc = *(struct field_access_site **) slot;
+ gimple stmt = ((struct find_stmt_data *)data)->stmt;
if (f_acc->stmt == stmt
|| f_acc->ref_def_stmt == stmt
@@ -810,7 +801,7 @@ find_in_field_accs (void **slot, void *data)
and false otherwise. */
static bool
-is_part_of_field_access (tree stmt, d_str str)
+is_part_of_field_access (gimple stmt, d_str str)
{
int i;
@@ -883,7 +874,8 @@ struct ref_pos
static tree
find_pos_in_stmt_1 (tree *tp, int *walk_subtrees, void * data)
{
- struct ref_pos * r_pos = (struct ref_pos *) data;
+ struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
+ struct ref_pos *r_pos = (struct ref_pos *) wi->info;
tree ref = r_pos->ref;
tree t = *tp;
@@ -893,23 +885,8 @@ find_pos_in_stmt_1 (tree *tp, int *walk_subtrees, void * data)
return t;
}
- switch (TREE_CODE (t))
- {
- case GIMPLE_MODIFY_STMT:
- {
- tree lhs = GIMPLE_STMT_OPERAND (t, 0);
- tree rhs = GIMPLE_STMT_OPERAND (t, 1);
- *walk_subtrees = 1;
- walk_tree (&lhs, find_pos_in_stmt_1, data, NULL);
- walk_tree (&rhs, find_pos_in_stmt_1, data, NULL);
- *walk_subtrees = 0;
- }
- break;
-
- default:
- *walk_subtrees = 1;
- }
- return NULL_TREE;
+ *walk_subtrees = 1;
+ return NULL_TREE;
}
@@ -917,13 +894,16 @@ find_pos_in_stmt_1 (tree *tp, int *walk_subtrees, void * data)
It returns it, if found, and NULL otherwise. */
static tree *
-find_pos_in_stmt (tree stmt, tree ref)
+find_pos_in_stmt (gimple stmt, tree ref)
{
struct ref_pos r_pos;
+ struct walk_stmt_info wi;
r_pos.ref = ref;
r_pos.pos = NULL;
- walk_tree (&stmt, find_pos_in_stmt_1, &r_pos, NULL);
+ memset (&wi, 0, sizeof (wi));
+ wi.info = &r_pos;
+ walk_gimple_op (stmt, find_pos_in_stmt_1, &wi);
return r_pos.pos;
}
@@ -1003,16 +983,15 @@ replace_field_acc (struct field_access_site *acc, tree new_type)
new_acc = build_comp_ref (new_ref, field_id, new_type);
VEC_free (type_wrapper_t, heap, wrapper);
- if (TREE_CODE (acc->stmt) == GIMPLE_MODIFY_STMT)
+ if (is_gimple_assign (acc->stmt))
{
- lhs = GIMPLE_STMT_OPERAND (acc->stmt, 0);
- rhs = GIMPLE_STMT_OPERAND (acc->stmt, 1);
-
-
+ lhs = gimple_assign_lhs (acc->stmt);
+ rhs = gimple_assign_rhs1 (acc->stmt);
+
if (lhs == acc->comp_ref)
- GIMPLE_STMT_OPERAND (acc->stmt, 0) = new_acc;
+ gimple_assign_set_lhs (acc->stmt, new_acc);
else if (rhs == acc->comp_ref)
- GIMPLE_STMT_OPERAND (acc->stmt, 1) = new_acc;
+ gimple_assign_set_rhs1 (acc->stmt, new_acc);
else
{
pos = find_pos_in_stmt (acc->stmt, acc->comp_ref);
@@ -1070,18 +1049,15 @@ find_structure (tree type)
like assignments: p.8_7 = p; or statements with rhs of
tree codes PLUS_EXPR and MINUS_EXPR. */
-static tree
-create_base_plus_offset (tree orig_stmt, tree new_type,
- tree offset)
+static gimple
+create_base_plus_offset (gimple orig_stmt, tree new_type, tree offset)
{
- tree lhs, rhs;
- tree new_lhs, new_rhs;
- tree new_stmt;
-
- gcc_assert (TREE_CODE (orig_stmt) == GIMPLE_MODIFY_STMT);
+ tree lhs;
+ tree new_lhs;
+ gimple new_stmt;
+ tree new_op0 = NULL_TREE, new_op1 = NULL_TREE;
- lhs = GIMPLE_STMT_OPERAND (orig_stmt, 0);
- rhs = GIMPLE_STMT_OPERAND (orig_stmt, 1);
+ lhs = gimple_assign_lhs (orig_stmt);
gcc_assert (TREE_CODE (lhs) == VAR_DECL
|| TREE_CODE (lhs) == SSA_NAME);
@@ -1090,15 +1066,14 @@ create_base_plus_offset (tree orig_stmt, tree new_type,
gcc_assert (new_lhs);
finalize_var_creation (new_lhs);
- switch (TREE_CODE (rhs))
+ switch (gimple_assign_rhs_code (orig_stmt))
{
case PLUS_EXPR:
case MINUS_EXPR:
case POINTER_PLUS_EXPR:
{
- tree op0 = TREE_OPERAND (rhs, 0);
- tree op1 = TREE_OPERAND (rhs, 1);
- tree new_op0 = NULL_TREE, new_op1 = NULL_TREE;
+ tree op0 = gimple_assign_rhs1 (orig_stmt);
+ tree op1 = gimple_assign_rhs2 (orig_stmt);
unsigned str0, str1;
unsigned length = VEC_length (structure, structures);
@@ -1116,9 +1091,6 @@ create_base_plus_offset (tree orig_stmt, tree new_type,
new_op0 = offset;
if (!new_op1)
new_op1 = offset;
-
- new_rhs = build2 (TREE_CODE (rhs), TREE_TYPE (new_op0),
- new_op0, new_op1);
}
break;
@@ -1126,8 +1098,9 @@ create_base_plus_offset (tree orig_stmt, tree new_type,
gcc_unreachable();
}
- new_stmt = build_gimple_modify_stmt (new_lhs, new_rhs);
- finalize_stmt (new_stmt);
+ new_stmt = gimple_build_assign_with_ops (gimple_assign_rhs_code (orig_stmt),
+ new_lhs, new_op0, new_op1);
+ finalize_stmt (new_stmt);
return new_stmt;
}
@@ -1140,9 +1113,10 @@ create_new_field_access (struct field_access_site *f_acc,
struct field_entry field)
{
tree new_type = field.field_mapping;
- tree new_stmt;
+ gimple new_stmt;
tree size_res;
- tree mult_stmt, cast_stmt;
+ gimple mult_stmt;
+ gimple cast_stmt;
tree cast_res = NULL;
if (f_acc->num)
@@ -1182,41 +1156,37 @@ create_new_field_access (struct field_access_site *f_acc,
variable located in the condition statement at the position POS. */
static void
-create_new_stmts_for_cond_expr_1 (tree new_var, tree cond_stmt, bool pos)
+create_new_stmts_for_cond_expr_1 (tree new_var, gimple cond_stmt, unsigned pos)
{
- tree new_cond;
- tree new_stmt;
+ gimple new_stmt;
edge true_e = NULL, false_e = NULL;
basic_block new_bb;
- tree stmt_list;
+ gimple_stmt_iterator si;
- extract_true_false_edges_from_block (bb_for_stmt (cond_stmt),
+ extract_true_false_edges_from_block (gimple_bb (cond_stmt),
&true_e, &false_e);
- new_cond = unshare_expr (COND_EXPR_COND (cond_stmt));
-
- TREE_OPERAND (new_cond, pos) = new_var;
-
- new_stmt = build3 (COND_EXPR, TREE_TYPE (cond_stmt),
- new_cond, NULL_TREE, NULL_TREE);
+ new_stmt = gimple_build_cond (gimple_cond_code (cond_stmt),
+ pos == 0 ? new_var : gimple_cond_lhs (cond_stmt),
+ pos == 1 ? new_var : gimple_cond_rhs (cond_stmt),
+ NULL_TREE,
+ NULL_TREE);
finalize_stmt (new_stmt);
/* Create new basic block after bb. */
- new_bb = create_empty_bb (bb_for_stmt (cond_stmt));
+ new_bb = create_empty_bb (gimple_bb (cond_stmt));
/* Add new condition stmt to the new_bb. */
- stmt_list = bb_stmt_list (new_bb);
- append_to_statement_list (new_stmt, &stmt_list);
- add_bb_info (new_bb, stmt_list);
+ si = gsi_start_bb (new_bb);
+ gsi_insert_after (&si, new_stmt, GSI_NEW_STMT);
-
/* Create false and true edges from new_bb. */
make_edge_and_fix_phis_of_dest (new_bb, true_e);
make_edge_and_fix_phis_of_dest (new_bb, false_e);
/* Redirect one of original edges to point to new_bb. */
- if (TREE_CODE (cond_stmt) == NE_EXPR)
+ if (gimple_cond_code (cond_stmt) == NE_EXPR)
redirect_edge_succ (true_e, new_bb);
else
redirect_edge_succ (false_e, new_bb);
@@ -1227,23 +1197,22 @@ create_new_stmts_for_cond_expr_1 (tree new_var, tree cond_stmt, bool pos)
recursively redirect edges to newly generated basic blocks. */
static void
-create_new_stmts_for_cond_expr (tree stmt)
+create_new_stmts_for_cond_expr (gimple stmt)
{
- tree cond = COND_EXPR_COND (stmt);
tree arg0, arg1, arg;
unsigned str0, str1;
bool s0, s1;
d_str str;
tree type;
- bool pos;
+ unsigned pos;
int i;
unsigned length = VEC_length (structure, structures);
- gcc_assert (TREE_CODE (cond) == EQ_EXPR
- || TREE_CODE (cond) == NE_EXPR);
+ gcc_assert (gimple_cond_code (stmt) == EQ_EXPR
+ || gimple_cond_code (stmt) == NE_EXPR);
- arg0 = TREE_OPERAND (cond, 0);
- arg1 = TREE_OPERAND (cond, 1);
+ arg0 = gimple_cond_lhs (stmt);
+ arg1 = gimple_cond_rhs (stmt);
str0 = find_structure (strip_type (get_type_of_var (arg0)));
str1 = find_structure (strip_type (get_type_of_var (arg1)));
@@ -1273,15 +1242,14 @@ create_new_stmts_for_cond_expr (tree stmt)
/* Create a new general access to replace original access ACC
for structure type NEW_TYPE. */
-static tree
+static gimple
create_general_new_stmt (struct access_site *acc, tree new_type)
{
- tree old_stmt = acc->stmt;
+ gimple old_stmt = acc->stmt;
tree var;
- tree new_stmt = unshare_expr (old_stmt);
+ gimple new_stmt = gimple_copy (old_stmt);
unsigned i;
-
for (i = 0; VEC_iterate (tree, acc->vars, i, var); i++)
{
tree *pos;
@@ -1291,32 +1259,30 @@ create_general_new_stmt (struct access_site *acc, tree new_type)
gcc_assert (new_var);
finalize_var_creation (new_var);
- if (TREE_CODE (new_stmt) == GIMPLE_MODIFY_STMT)
+ if (is_gimple_assign (new_stmt))
{
-
- lhs = GIMPLE_STMT_OPERAND (new_stmt, 0);
- rhs = GIMPLE_STMT_OPERAND (new_stmt, 1);
+ lhs = gimple_assign_lhs (new_stmt);
if (TREE_CODE (lhs) == SSA_NAME)
lhs = SSA_NAME_VAR (lhs);
- if (TREE_CODE (rhs) == SSA_NAME)
- rhs = SSA_NAME_VAR (rhs);
+ if (gimple_assign_rhs_code (new_stmt) == SSA_NAME)
+ rhs = SSA_NAME_VAR (gimple_assign_rhs1 (new_stmt));
/* It can happen that rhs is a constructor.
Then we have to replace it to be of new_type. */
- if (TREE_CODE (rhs) == CONSTRUCTOR)
+ if (gimple_assign_rhs_code (new_stmt) == CONSTRUCTOR)
{
/* Dealing only with empty constructors right now. */
gcc_assert (VEC_empty (constructor_elt,
CONSTRUCTOR_ELTS (rhs)));
rhs = build_constructor (new_type, 0);
- GIMPLE_STMT_OPERAND (new_stmt, 1) = rhs;
+ gimple_assign_set_rhs1 (new_stmt, rhs);
}
if (lhs == var)
- GIMPLE_STMT_OPERAND (new_stmt, 0) = new_var;
+ gimple_assign_set_lhs (new_stmt, new_var);
else if (rhs == var)
- GIMPLE_STMT_OPERAND (new_stmt, 1) = new_var;
+ gimple_assign_set_rhs1 (new_stmt, new_var);
else
{
pos = find_pos_in_stmt (new_stmt, var);
@@ -1343,12 +1309,12 @@ static void
create_new_stmts_for_general_acc (struct access_site *acc, d_str str)
{
tree type;
- tree stmt = acc->stmt;
+ gimple stmt = acc->stmt;
unsigned i;
for (i = 0; VEC_iterate (tree, str->new_types, i, type); i++)
{
- tree new_stmt;
+ gimple new_stmt;
new_stmt = create_general_new_stmt (acc, type);
insert_after_stmt (stmt, new_stmt);
@@ -1361,10 +1327,10 @@ create_new_stmts_for_general_acc (struct access_site *acc, d_str str)
static void
create_new_general_access (struct access_site *acc, d_str str)
{
- tree stmt = acc->stmt;
- switch (TREE_CODE (stmt))
+ gimple stmt = acc->stmt;
+ switch (gimple_code (stmt))
{
- case COND_EXPR:
+ case GIMPLE_COND:
create_new_stmts_for_cond_expr (stmt);
break;
@@ -1391,7 +1357,7 @@ create_new_acc (void **slot, void *data)
basic_block bb = ((struct create_acc_data *)data)->bb;
d_str str = ((struct create_acc_data *)data)->str;
- if (bb_for_stmt (acc->stmt) == bb)
+ if (gimple_bb (acc->stmt) == bb)
create_new_general_access (acc, str);
return 1;
}
@@ -1407,7 +1373,7 @@ create_new_field_acc (void **slot, void *data)
d_str str = ((struct create_acc_data *)data)->str;
int i = ((struct create_acc_data *)data)->field_index;
- if (bb_for_stmt (f_acc->stmt) == bb)
+ if (gimple_bb (f_acc->stmt) == bb)
create_new_field_access (f_acc, str->fields[i]);
return 1;
}
@@ -1462,11 +1428,11 @@ dump_field_acc (void **slot, void *data ATTRIBUTE_UNUSED)
fprintf(dump_file, "\n");
if (f_acc->stmt)
- print_generic_stmt (dump_file, f_acc->stmt, 0);
+ print_gimple_stmt (dump_file, f_acc->stmt, 0, 0);
if (f_acc->ref_def_stmt)
- print_generic_stmt (dump_file, f_acc->ref_def_stmt, 0);
+ print_gimple_stmt (dump_file, f_acc->ref_def_stmt, 0, 0);
if (f_acc->cast_stmt)
- print_generic_stmt (dump_file, f_acc->cast_stmt, 0);
+ print_gimple_stmt (dump_file, f_acc->cast_stmt, 0, 0);
return 1;
}
@@ -1697,22 +1663,20 @@ free_field_accesses (htab_t f_accs)
The edge origin is CONTEXT function. */
static void
-update_cgraph_with_malloc_call (tree malloc_stmt, tree context)
+update_cgraph_with_malloc_call (gimple malloc_stmt, tree context)
{
- tree call_expr;
struct cgraph_node *src, *dest;
tree malloc_fn_decl;
if (!malloc_stmt)
return;
- call_expr = get_call_expr_in (malloc_stmt);
- malloc_fn_decl = get_callee_fndecl (call_expr);
+ malloc_fn_decl = gimple_call_fndecl (malloc_stmt);
src = cgraph_node (context);
dest = cgraph_node (malloc_fn_decl);
cgraph_create_edge (src, dest, malloc_stmt,
- 0, 0, bb_for_stmt (malloc_stmt)->loop_depth);
+ 0, 0, gimple_bb (malloc_stmt)->loop_depth);
}
/* This function generates set of statements required
@@ -1720,40 +1684,39 @@ update_cgraph_with_malloc_call (tree malloc_stmt, tree context)
The statements are stored in NEW_STMTS. The statement that contain
call to malloc is returned. MALLOC_STMT is an original call to malloc. */
-static tree
-create_new_malloc (tree malloc_stmt, tree new_type, tree *new_stmts, tree num)
+static gimple
+create_new_malloc (gimple malloc_stmt, tree new_type, gimple_seq *new_stmts,
+ tree num)
{
tree new_malloc_size;
- tree call_expr, malloc_fn_decl;
- tree new_stmt, malloc_res;
- tree call_stmt, final_stmt;
+ tree malloc_fn_decl;
+ gimple new_stmt;
+ tree malloc_res;
+ gimple call_stmt, final_stmt;
tree cast_res;
gcc_assert (num && malloc_stmt && new_type);
- *new_stmts = alloc_stmt_list ();
+ *new_stmts = gimple_seq_alloc ();
/* Generate argument to malloc as multiplication of num
and size of new_type. */
new_stmt = gen_size (num, new_type, &new_malloc_size);
- append_to_statement_list (new_stmt, new_stmts);
+ gimple_seq_add_stmt (new_stmts, new_stmt);
/* Generate new call for malloc. */
malloc_res = create_tmp_var (ptr_type_node, NULL);
+ add_referenced_var (malloc_res);
- if (malloc_res)
- add_referenced_var (malloc_res);
-
- call_expr = get_call_expr_in (malloc_stmt);
- malloc_fn_decl = get_callee_fndecl (call_expr);
- call_expr = build_call_expr (malloc_fn_decl, 1, new_malloc_size);
- call_stmt = build_gimple_modify_stmt (malloc_res, call_expr);
+ malloc_fn_decl = gimple_call_fndecl (malloc_stmt);
+ call_stmt = gimple_build_call (malloc_fn_decl, 1, new_malloc_size);
+ gimple_call_set_lhs (call_stmt, malloc_res);
finalize_stmt_and_append (new_stmts, call_stmt);
/* Create new cast statement. */
final_stmt = get_final_alloc_stmt (malloc_stmt);
gcc_assert (final_stmt);
new_stmt = gen_cast_stmt (malloc_res, new_type, final_stmt, &cast_res);
- append_to_statement_list (new_stmt, new_stmts);
+ gimple_seq_add_stmt (new_stmts, new_stmt);
return call_stmt;
}
@@ -1764,11 +1727,10 @@ create_new_malloc (tree malloc_stmt, tree new_type, tree *new_stmts, tree num)
they are filled into NEW_STMTS_P. */
static tree
-gen_num_of_structs_in_malloc (tree stmt, tree str_decl, tree *new_stmts_p)
+gen_num_of_structs_in_malloc (gimple stmt, tree str_decl,
+ gimple_seq *new_stmts_p)
{
- call_expr_arg_iterator iter;
tree arg;
- tree call_expr;
tree struct_size;
HOST_WIDE_INT struct_size_int;
@@ -1776,11 +1738,10 @@ gen_num_of_structs_in_malloc (tree stmt, tree str_decl, tree *new_stmts_p)
return NULL_TREE;
/* Get malloc argument. */
- call_expr = get_call_expr_in (stmt);
- if (!call_expr)
+ if (!is_gimple_call (stmt))
return NULL_TREE;
- arg = first_call_expr_arg (call_expr, &iter);
+ arg = gimple_call_arg (stmt, 0);
if (TREE_CODE (arg) != SSA_NAME
&& !TREE_CONSTANT (arg))
@@ -1793,7 +1754,8 @@ gen_num_of_structs_in_malloc (tree stmt, tree str_decl, tree *new_stmts_p)
if (TREE_CODE (arg) == SSA_NAME)
{
- tree num, div_stmt;
+ tree num;
+ gimple div_stmt;
if (is_result_of_mult (arg, &num, struct_size))
return num;
@@ -1804,23 +1766,16 @@ gen_num_of_structs_in_malloc (tree stmt, tree str_decl, tree *new_stmts_p)
add_referenced_var (num);
if (exact_log2 (struct_size_int) == -1)
- div_stmt = build_gimple_modify_stmt (num,
- build2 (TRUNC_DIV_EXPR,
- integer_type_node,
- arg, struct_size));
+ div_stmt = gimple_build_assign_with_ops (TRUNC_DIV_EXPR, num, arg,
+ struct_size);
else
{
tree C = build_int_cst (integer_type_node,
exact_log2 (struct_size_int));
- div_stmt =
- build_gimple_modify_stmt (num, build2 (RSHIFT_EXPR,
- integer_type_node,
- arg, C));
+ div_stmt = gimple_build_assign_with_ops (RSHIFT_EXPR, num, arg, C);
}
- *new_stmts_p = alloc_stmt_list ();
- append_to_statement_list (div_stmt,
- new_stmts_p);
+ gimple_seq_add_stmt (new_stmts_p, div_stmt);
finalize_stmt (div_stmt);
return num;
}
@@ -2049,7 +2004,7 @@ field_acc_hash (const void *x)
static int
field_acc_eq (const void *x, const void *y)
{
- return ((const struct field_access_site *)x)->stmt == (const_tree)y;
+ return ((const struct field_access_site *)x)->stmt == (const_gimple)y;
}
/* This function prints an access site, defined by SLOT. */
@@ -2063,7 +2018,7 @@ dump_acc (void **slot, void *data ATTRIBUTE_UNUSED)
fprintf(dump_file, "\n");
if (acc->stmt)
- print_generic_stmt (dump_file, acc->stmt, 0);
+ print_gimple_stmt (dump_file, acc->stmt, 0, 0);
fprintf(dump_file, " : ");
for (i = 0; VEC_iterate (tree, acc->vars, i, var); i++)
@@ -2146,35 +2101,33 @@ create_new_alloc_sites (fallocs_t m_data, tree context)
alloc_site_t *call;
unsigned j;
- for (j = 0;
- VEC_iterate (alloc_site_t, m_data->allocs, j, call); j++)
+ for (j = 0; VEC_iterate (alloc_site_t, m_data->allocs, j, call); j++)
{
- tree stmt = call->stmt;
+ gimple stmt = call->stmt;
d_str str = call->str;
tree num;
- tree new_stmts = NULL_TREE;
- tree last_stmt = get_final_alloc_stmt (stmt);
+ gimple_seq new_stmts = NULL;
+ gimple last_stmt = get_final_alloc_stmt (stmt);
unsigned i;
tree type;
num = gen_num_of_structs_in_malloc (stmt, str->decl, &new_stmts);
if (new_stmts)
{
- last_stmt = tsi_stmt (tsi_last (new_stmts));
- insert_after_stmt (last_stmt, new_stmts);
+ last_stmt = gimple_seq_last_stmt (new_stmts);
+ insert_seq_after_stmt (last_stmt, new_stmts);
}
/* Generate an allocation sites for each new structure type. */
- for (i = 0;
- VEC_iterate (tree, str->new_types, i, type); i++)
+ for (i = 0; VEC_iterate (tree, str->new_types, i, type); i++)
{
- tree new_malloc_stmt = NULL_TREE;
- tree last_stmt_tmp = NULL_TREE;
+ gimple new_malloc_stmt = NULL;
+ gimple last_stmt_tmp = NULL;
- new_stmts = NULL_TREE;
+ new_stmts = NULL;
new_malloc_stmt = create_new_malloc (stmt, type, &new_stmts, num);
- last_stmt_tmp = tsi_stmt (tsi_last (new_stmts));
- insert_after_stmt (last_stmt, new_stmts);
+ last_stmt_tmp = gimple_seq_last_stmt (new_stmts);
+ insert_seq_after_stmt (last_stmt, new_stmts);
update_cgraph_with_malloc_call (new_malloc_stmt, context);
last_stmt = last_stmt_tmp;
}
@@ -2304,7 +2257,7 @@ acc_hash (const void *x)
static int
acc_eq (const void *x, const void *y)
{
- return ((const struct access_site *)x)->stmt == (const_tree)y;
+ return ((const struct access_site *)x)->stmt == (const_gimple)y;
}
/* Given a structure declaration STRUCT_DECL, and number of fields
@@ -2405,25 +2358,19 @@ remove_structure (unsigned i)
COND_STMT is a condition statement to check. */
static bool
-is_safe_cond_expr (tree cond_stmt)
+is_safe_cond_expr (gimple cond_stmt)
{
-
tree arg0, arg1;
unsigned str0, str1;
bool s0, s1;
unsigned length = VEC_length (structure, structures);
- tree cond = COND_EXPR_COND (cond_stmt);
-
- if (TREE_CODE (cond) != EQ_EXPR
- && TREE_CODE (cond) != NE_EXPR)
+ if (gimple_cond_code (cond_stmt) != EQ_EXPR
+ && gimple_cond_code (cond_stmt) != NE_EXPR)
return false;
- if (TREE_CODE_LENGTH (TREE_CODE (cond)) != 2)
- return false;
-
- arg0 = TREE_OPERAND (cond, 0);
- arg1 = TREE_OPERAND (cond, 1);
+ arg0 = gimple_cond_lhs (cond_stmt);
+ arg1 = gimple_cond_rhs (cond_stmt);
str0 = find_structure (strip_type (get_type_of_var (arg0)));
str1 = find_structure (strip_type (get_type_of_var (arg1)));
@@ -2470,7 +2417,8 @@ exclude_from_accs (void **slot, void *data)
static tree
get_stmt_accesses (tree *tp, int *walk_subtrees, void *data)
{
- tree stmt = (tree) data;
+ struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
+ gimple stmt = (gimple) wi->info;
tree t = *tp;
if (!t)
@@ -2478,17 +2426,6 @@ get_stmt_accesses (tree *tp, int *walk_subtrees, void *data)
switch (TREE_CODE (t))
{
- case GIMPLE_MODIFY_STMT:
- {
- tree lhs = GIMPLE_STMT_OPERAND (t, 0);
- tree rhs = GIMPLE_STMT_OPERAND (t, 1);
- *walk_subtrees = 1;
- walk_tree (&lhs, get_stmt_accesses, data, NULL);
- walk_tree (&rhs, get_stmt_accesses, data, NULL);
- *walk_subtrees = 0;
- }
- break;
-
case BIT_FIELD_REF:
{
tree var = TREE_OPERAND(t, 0);
@@ -2549,7 +2486,7 @@ get_stmt_accesses (tree *tp, int *walk_subtrees, void *data)
print_generic_expr (dump_file, type, 0);
fprintf (dump_file,
" has complicate access in statement ");
- print_generic_stmt (dump_file, stmt, 0);
+ print_gimple_stmt (dump_file, stmt, 0, 0);
}
remove_structure (i);
@@ -2558,7 +2495,7 @@ get_stmt_accesses (tree *tp, int *walk_subtrees, void *data)
else
{
/* Increase count of field. */
- basic_block bb = bb_for_stmt (stmt);
+ basic_block bb = gimple_bb (stmt);
field->count += bb->count;
/* Add stmt to the acc_sites of field. */
@@ -2571,18 +2508,6 @@ get_stmt_accesses (tree *tp, int *walk_subtrees, void *data)
}
break;
- case MINUS_EXPR:
- case PLUS_EXPR:
- {
- tree op0 = TREE_OPERAND (t, 0);
- tree op1 = TREE_OPERAND (t, 1);
- *walk_subtrees = 1;
- walk_tree (&op0, get_stmt_accesses, data, NULL);
- walk_tree (&op1, get_stmt_accesses, data, NULL);
- *walk_subtrees = 0;
- }
- break;
-
case COND_EXPR:
{
tree cond = COND_EXPR_COND (t);
@@ -2618,14 +2543,6 @@ get_stmt_accesses (tree *tp, int *walk_subtrees, void *data)
}
break;
- case CALL_EXPR:
- {
- /* It was checked as part of stage1 that structures
- to be transformed cannot be passed as parameters of functions. */
- *walk_subtrees = 0;
- }
- break;
-
default:
return NULL;
}
@@ -3019,7 +2936,7 @@ add_structure (tree type)
allocates the structure represented by STR. */
static void
-add_alloc_site (tree fn_decl, tree stmt, d_str str)
+add_alloc_site (tree fn_decl, gimple stmt, d_str str)
{
fallocs_t fallocs = NULL;
alloc_site_t m_call;
@@ -3049,7 +2966,7 @@ add_alloc_site (tree fn_decl, tree stmt, d_str str)
if (dump_file)
{
fprintf (dump_file, "\nAdding stmt ");
- print_generic_stmt (dump_file, stmt, 0);
+ print_gimple_stmt (dump_file, stmt, 0, 0);
fprintf (dump_file, " to list of mallocs.");
}
}
@@ -3061,11 +2978,11 @@ add_alloc_site (tree fn_decl, tree stmt, d_str str)
Otherwise I_P contains the length of the vector of structures. */
static bool
-is_alloc_of_struct (tree stmt, unsigned *i_p)
+is_alloc_of_struct (gimple stmt, unsigned *i_p)
{
tree lhs;
tree type;
- tree final_stmt;
+ gimple final_stmt;
final_stmt = get_final_alloc_stmt (stmt);
@@ -3075,10 +2992,10 @@ is_alloc_of_struct (tree stmt, unsigned *i_p)
/* final_stmt should be of the form:
T.3 = (struct_type *) T.2; */
- if (TREE_CODE (final_stmt) != GIMPLE_MODIFY_STMT)
+ if (gimple_code (final_stmt) != GIMPLE_ASSIGN)
return false;
- lhs = GIMPLE_STMT_OPERAND (final_stmt, 0);
+ lhs = gimple_assign_lhs (final_stmt);
type = get_type_of_var (lhs);
@@ -3128,13 +3045,13 @@ safe_cond_expr_check (void **slot, void *data)
{
struct access_site *acc = *(struct access_site **) slot;
- if (TREE_CODE (acc->stmt) == COND_EXPR
+ if (gimple_code (acc->stmt) == GIMPLE_COND
&& !is_safe_cond_expr (acc->stmt))
{
if (dump_file)
{
fprintf (dump_file, "\nUnsafe conditional statement ");
- print_generic_stmt (dump_file, acc->stmt, 0);
+ print_gimple_stmt (dump_file, acc->stmt, 0, 0);
}
*(bool *) data = false;
return 0;
@@ -3163,21 +3080,25 @@ exclude_alloc_and_field_accs_1 (d_str str, struct cgraph_node *node)
static void
collect_accesses_in_bb (basic_block bb)
{
- block_stmt_iterator bsi;
+ gimple_stmt_iterator bsi;
+ struct walk_stmt_info wi;
+
+ memset (&wi, 0, sizeof (wi));
- for (bsi = bsi_start (bb); ! bsi_end_p (bsi); bsi_next (&bsi))
+ for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi))
{
- tree stmt = bsi_stmt (bsi);
+ gimple stmt = gsi_stmt (bsi);
/* In asm stmt we cannot always track the arguments,
so we just give up. */
- if (TREE_CODE (stmt) == ASM_EXPR)
+ if (gimple_code (stmt) == GIMPLE_ASM)
{
free_structures ();
break;
}
- walk_tree (&stmt, get_stmt_accesses, stmt, NULL);
+ wi.info = (void *) stmt;
+ walk_gimple_op (stmt, get_stmt_accesses, &wi);
}
}
@@ -3467,7 +3388,6 @@ program_redefines_malloc_p (void)
struct cgraph_edge *c_edge;
tree fndecl;
tree fndecl2;
- tree call_expr;
for (c_node = cgraph_nodes; c_node; c_node = c_node->next)
{
@@ -3475,17 +3395,16 @@ program_redefines_malloc_p (void)
for (c_edge = c_node->callees; c_edge; c_edge = c_edge->next_callee)
{
- call_expr = get_call_expr_in (c_edge->call_stmt);
c_node2 = c_edge->callee;
fndecl2 = c_node2->decl;
- if (call_expr)
+ if (is_gimple_call (c_edge->call_stmt))
{
const char * fname = get_name (fndecl2);
- if ((call_expr_flags (call_expr) & ECF_MALLOC) &&
- (DECL_FUNCTION_CODE (fndecl2) != BUILT_IN_MALLOC) &&
- (DECL_FUNCTION_CODE (fndecl2) != BUILT_IN_CALLOC) &&
- (DECL_FUNCTION_CODE (fndecl2) != BUILT_IN_ALLOCA))
+ if ((gimple_call_flags (c_edge->call_stmt) & ECF_MALLOC)
+ && (DECL_FUNCTION_CODE (fndecl2) != BUILT_IN_MALLOC)
+ && (DECL_FUNCTION_CODE (fndecl2) != BUILT_IN_CALLOC)
+ && (DECL_FUNCTION_CODE (fndecl2) != BUILT_IN_ALLOCA))
return true;
/* Check that there is no __builtin_object_size,
@@ -3527,15 +3446,15 @@ collect_alloc_sites (void)
{
for (cs = node->callees; cs; cs = cs->next_callee)
{
- tree stmt = cs->call_stmt;
+ gimple stmt = cs->call_stmt;
if (stmt)
{
- tree call = get_call_expr_in (stmt);
tree decl;
- if (call && (decl = get_callee_fndecl (call))
- && TREE_CODE (stmt) == GIMPLE_MODIFY_STMT)
+ if (is_gimple_call (stmt)
+ && (decl = gimple_call_fndecl (stmt))
+ && gimple_call_lhs (stmt))
{
unsigned i;
@@ -3555,7 +3474,7 @@ collect_alloc_sites (void)
{
fprintf (dump_file,
"\nUnsupported allocation function ");
- print_generic_stmt (dump_file, stmt, 0);
+ print_gimple_stmt (dump_file, stmt, 0, 0);
}
remove_structure (i);
}
@@ -4035,8 +3954,9 @@ reorg_structs_drive (void)
static bool
struct_reorg_gate (void)
{
- return flag_ipa_struct_reorg && flag_whole_program
- && (optimize > 0);
+ return flag_ipa_struct_reorg
+ && flag_whole_program
+ && (optimize > 0);
}
struct simple_ipa_opt_pass pass_ipa_struct_reorg =
diff --git a/gcc/ipa-struct-reorg.h b/gcc/ipa-struct-reorg.h
index 54cdbc9982f..a92d345ec92 100644
--- a/gcc/ipa-struct-reorg.h
+++ b/gcc/ipa-struct-reorg.h
@@ -37,15 +37,15 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
struct field_access_site
{
/* Statement in which the access site occurs. */
- tree stmt; /* D.2169_25 = D.2168_24->b; */
+ gimple stmt; /* D.2169_25 = D.2168_24->b; */
tree comp_ref; /* D.2168_24->b */
tree field_decl; /* b */
tree ref; /* D.2168_24 */
tree num; /* i.6_20 */
tree offset; /* D2167_22 */
tree base; /* p.5_23 */
- tree ref_def_stmt; /* D.2168_24 = D.2167_22 + p.5_23; */
- tree cast_stmt; /* D.2167_22 = (struct str_t *) D.2166_21;
+ gimple ref_def_stmt; /* D.2168_24 = D.2167_22 + p.5_23; */
+ gimple cast_stmt; /* D.2167_22 = (struct str_t *) D.2166_21;
This statement is not always present. */
};
@@ -53,7 +53,7 @@ struct field_access_site
struct access_site
{
/* A statement in which the access site occurs. */
- tree stmt;
+ gimple stmt;
/* A list of structure variables in the access site. */
VEC (tree, heap) *vars;
};
diff --git a/gcc/ipa-type-escape.c b/gcc/ipa-type-escape.c
index 229d8b2e9a5..48d95049b4f 100644
--- a/gcc/ipa-type-escape.c
+++ b/gcc/ipa-type-escape.c
@@ -47,7 +47,7 @@ along with GCC; see the file COPYING3. If not see
#include "ipa-utils.h"
#include "ipa-type-escape.h"
#include "c-common.h"
-#include "tree-gimple.h"
+#include "gimple.h"
#include "cgraph.h"
#include "output.h"
#include "flags.h"
@@ -136,8 +136,8 @@ static bitmap_obstack ipa_obstack;
/* Static functions from this file that are used
before being defined. */
-static unsigned int look_for_casts (tree lhs ATTRIBUTE_UNUSED, tree);
-static bool is_cast_from_non_pointer (tree, tree, void *);
+static unsigned int look_for_casts (tree);
+static bool is_cast_from_non_pointer (tree, gimple, void *);
/* Get the name of TYPE or return the string "<UNNAMED>". */
static const char*
@@ -308,7 +308,7 @@ get_canon_type (tree type, bool see_thru_ptrs, bool see_thru_arrays)
while (POINTER_TYPE_P (type))
type = TYPE_MAIN_VARIANT (TREE_TYPE (type));
- result = splay_tree_lookup(type_to_canon_type, (splay_tree_key) type);
+ result = splay_tree_lookup (type_to_canon_type, (splay_tree_key) type);
if (result == NULL)
return discover_unique_type (type);
@@ -663,9 +663,7 @@ check_cast_type (tree to_type, tree from_type)
static bool
is_malloc_result (tree var)
{
- tree def_stmt;
- tree rhs;
- int flags;
+ gimple def_stmt;
if (!var)
return false;
@@ -675,20 +673,13 @@ is_malloc_result (tree var)
def_stmt = SSA_NAME_DEF_STMT (var);
- if (TREE_CODE (def_stmt) != GIMPLE_MODIFY_STMT)
+ if (!is_gimple_call (def_stmt))
return false;
- if (var != GIMPLE_STMT_OPERAND (def_stmt, 0))
+ if (var != gimple_call_lhs (def_stmt))
return false;
- rhs = get_call_expr_in (def_stmt);
-
- if (!rhs)
- return false;
-
- flags = call_expr_flags (rhs);
-
- return ((flags & ECF_MALLOC) != 0);
+ return ((gimple_call_flags (def_stmt) & ECF_MALLOC) != 0);
}
@@ -769,115 +760,98 @@ check_cast (tree to_type, tree from)
return cast;
}
-typedef struct cast
-{
- int type;
- tree stmt;
-}cast_t;
-
-/* This function is a callback for walk_tree called from
- is_cast_from_non_pointer. The data->type is set to be:
- 0 - if there is no cast
- number - the number of casts from non-pointer type
- -1 - if there is a cast that makes the type to escape
+/* Scan assignment statement S to see if there are any casts within it. */
- If data->type = number, then data->stmt will contain the
- last casting stmt met in traversing. */
-
-static tree
-is_cast_from_non_pointer_1 (tree *tp, int *walk_subtrees, void *data)
+static unsigned int
+look_for_casts_stmt (gimple s)
{
- tree def_stmt = *tp;
+ unsigned int cast = 0;
+ gcc_assert (is_gimple_assign (s));
- if (pointer_set_insert (visited_stmts, def_stmt))
+ if (gimple_assign_cast_p (s))
{
- *walk_subtrees = 0;
- return NULL;
+ tree castfromvar = gimple_assign_rhs1 (s);
+ cast |= check_cast (TREE_TYPE (gimple_assign_lhs (s)), castfromvar);
}
-
- switch (TREE_CODE (def_stmt))
+ else
{
- case GIMPLE_MODIFY_STMT:
- {
- use_operand_p use_p;
- ssa_op_iter iter;
- tree lhs = GIMPLE_STMT_OPERAND (def_stmt, 0);
- tree rhs = GIMPLE_STMT_OPERAND (def_stmt, 1);
-
- unsigned int cast = look_for_casts (lhs, rhs);
- /* Check that only one cast happened, and it's of
- non-pointer type. */
- if ((cast & CT_FROM_NON_P) == (CT_FROM_NON_P)
- && (cast & ~(CT_FROM_NON_P)) == 0)
- {
- ((cast_t *)data)->stmt = def_stmt;
- ((cast_t *)data)->type++;
-
- FOR_EACH_SSA_USE_OPERAND (use_p, def_stmt, iter, SSA_OP_ALL_USES)
- {
- walk_use_def_chains (USE_FROM_PTR (use_p), is_cast_from_non_pointer,
- data, false);
- if (((cast_t*)data)->type == -1)
- return def_stmt;
- }
- }
-
- /* Check that there is no cast, or cast is not harmful. */
- else if ((cast & CT_NO_CAST) == (CT_NO_CAST)
- || (cast & CT_DOWN) == (CT_DOWN)
- || (cast & CT_UP) == (CT_UP)
- || (cast & CT_USELESS) == (CT_USELESS)
- || (cast & CT_FROM_MALLOC) == (CT_FROM_MALLOC))
- {
- FOR_EACH_SSA_USE_OPERAND (use_p, def_stmt, iter, SSA_OP_ALL_USES)
- {
- walk_use_def_chains (USE_FROM_PTR (use_p), is_cast_from_non_pointer,
- data, false);
- if (((cast_t*)data)->type == -1)
- return def_stmt;
- }
- }
+ size_t i;
+ for (i = 0; i < gimple_num_ops (s); i++)
+ cast |= look_for_casts (gimple_op (s, i));
+ }
- /* The cast is harmful. */
- else
- {
- ((cast_t *)data)->type = -1;
- return def_stmt;
- }
+ if (!cast)
+ cast = CT_NO_CAST;
- *walk_subtrees = 0;
- }
- break;
+ return cast;
+}
- default:
- {
- *walk_subtrees = 0;
- break;
- }
- }
- return NULL;
-}
+typedef struct cast
+{
+ int type;
+ gimple stmt;
+} cast_t;
/* This function is a callback for walk_use_def_chains function called
from is_array_access_through_pointer_and_index. */
static bool
-is_cast_from_non_pointer (tree var, tree def_stmt, void *data)
+is_cast_from_non_pointer (tree var, gimple def_stmt, void *data)
{
-
if (!def_stmt || !var)
return false;
- if (TREE_CODE (def_stmt) == PHI_NODE)
+ if (gimple_code (def_stmt) == GIMPLE_PHI)
return false;
if (SSA_NAME_IS_DEFAULT_DEF (var))
return false;
- walk_tree (&def_stmt, is_cast_from_non_pointer_1, data, NULL);
+ if (is_gimple_assign (def_stmt))
+ {
+ use_operand_p use_p;
+ ssa_op_iter iter;
+ unsigned int cast = look_for_casts_stmt (def_stmt);
+
+ /* Check that only one cast happened, and it's of non-pointer
+ type. */
+ if ((cast & CT_FROM_NON_P) == (CT_FROM_NON_P)
+ && (cast & ~(CT_FROM_NON_P)) == 0)
+ {
+ ((cast_t *)data)->stmt = def_stmt;
+ ((cast_t *)data)->type++;
+
+ FOR_EACH_SSA_USE_OPERAND (use_p, def_stmt, iter, SSA_OP_ALL_USES)
+ {
+ walk_use_def_chains (USE_FROM_PTR (use_p),
+ is_cast_from_non_pointer, data, false);
+ if (((cast_t*)data)->type == -1)
+ break;
+ }
+ }
+ /* Check that there is no cast, or cast is not harmful. */
+ else if ((cast & CT_NO_CAST) == (CT_NO_CAST)
+ || (cast & CT_DOWN) == (CT_DOWN)
+ || (cast & CT_UP) == (CT_UP)
+ || (cast & CT_USELESS) == (CT_USELESS)
+ || (cast & CT_FROM_MALLOC) == (CT_FROM_MALLOC))
+ {
+ FOR_EACH_SSA_USE_OPERAND (use_p, def_stmt, iter, SSA_OP_ALL_USES)
+ {
+ walk_use_def_chains (USE_FROM_PTR (use_p),
+ is_cast_from_non_pointer, data, false);
+ if (((cast_t*)data)->type == -1)
+ break;
+ }
+ }
+ /* The cast is harmful. */
+ else
+ ((cast_t *)data)->type = -1;
+ }
+
if (((cast_t*)data)->type == -1)
return true;
@@ -930,9 +904,10 @@ is_cast_from_non_pointer (tree var, tree def_stmt, void *data)
bool
is_array_access_through_pointer_and_index (enum tree_code code, tree op0,
tree op1, tree *base, tree *offset,
- tree *offset_cast_stmt)
+ gimple *offset_cast_stmt)
{
- tree before_cast, before_cast_def_stmt;
+ tree before_cast;
+ gimple before_cast_def_stmt;
cast_t op0_cast, op1_cast;
*base = NULL;
@@ -1014,26 +989,23 @@ is_array_access_through_pointer_and_index (enum tree_code code, tree op0,
/* before_cast_def_stmt should be of the form:
D.1605_6 = i.1_5 * 16; */
- if (TREE_CODE (before_cast_def_stmt) == GIMPLE_MODIFY_STMT)
+ if (is_gimple_assign (before_cast_def_stmt))
{
- tree lhs = GIMPLE_STMT_OPERAND (before_cast_def_stmt,0);
- tree rhs = GIMPLE_STMT_OPERAND (before_cast_def_stmt,1);
-
/* We expect temporary here. */
- if (!is_gimple_reg (lhs))
+ if (!is_gimple_reg (gimple_assign_lhs (before_cast_def_stmt)))
return false;
- if (TREE_CODE (rhs) == MULT_EXPR)
+ if (gimple_assign_rhs_code (before_cast_def_stmt) == MULT_EXPR)
{
- tree arg0 = TREE_OPERAND (rhs, 0);
- tree arg1 = TREE_OPERAND (rhs, 1);
+ tree arg0 = gimple_assign_rhs1 (before_cast_def_stmt);
+ tree arg1 = gimple_assign_rhs2 (before_cast_def_stmt);
tree unit_size =
TYPE_SIZE_UNIT (TREE_TYPE (TYPE_MAIN_VARIANT (TREE_TYPE (op0))));
if (!(CONSTANT_CLASS_P (arg0)
- && simple_cst_equal (arg0,unit_size))
+ && simple_cst_equal (arg0, unit_size))
&& !(CONSTANT_CLASS_P (arg1)
- && simple_cst_equal (arg1,unit_size)))
+ && simple_cst_equal (arg1, unit_size)))
return false;
}
else
@@ -1173,7 +1145,11 @@ check_tree (tree t)
check_tree (TREE_OPERAND (t, 0));
if (SSA_VAR_P (t) || (TREE_CODE (t) == FUNCTION_DECL))
- check_operand (t);
+ {
+ check_operand (t);
+ if (DECL_P (t) && DECL_INITIAL (t))
+ check_tree (DECL_INITIAL (t));
+ }
}
/* Create an address_of edge FROM_TYPE.TO_TYPE. */
@@ -1260,15 +1236,13 @@ look_for_address_of (tree t)
}
-/* Scan tree T to see if there are any casts within it.
- LHS Is the LHS of the expression involving the cast. */
+/* Scan tree T to see if there are any casts within it. */
static unsigned int
-look_for_casts (tree lhs ATTRIBUTE_UNUSED, tree t)
+look_for_casts (tree t)
{
unsigned int cast = 0;
-
if (is_gimple_cast (t) || TREE_CODE (t) == VIEW_CONVERT_EXPR)
{
tree castfromvar = TREE_OPERAND (t, 0);
@@ -1302,7 +1276,7 @@ static void
check_rhs_var (tree t)
{
look_for_address_of (t);
- check_tree(t);
+ check_tree (t);
}
/* Check to see if T is an assignment to a static var we are
@@ -1311,7 +1285,7 @@ check_rhs_var (tree t)
static void
check_lhs_var (tree t)
{
- check_tree(t);
+ check_tree (t);
}
/* This is a scaled down version of get_asm_expr_operands from
@@ -1322,35 +1296,15 @@ check_lhs_var (tree t)
analyzed and STMT is the actual asm statement. */
static void
-get_asm_expr_operands (tree stmt)
+check_asm (gimple stmt)
{
- int noutputs = list_length (ASM_OUTPUTS (stmt));
- const char **oconstraints
- = (const char **) alloca ((noutputs) * sizeof (const char *));
- int i;
- tree link;
- const char *constraint;
- bool allows_mem, allows_reg, is_inout;
-
- for (i=0, link = ASM_OUTPUTS (stmt); link; ++i, link = TREE_CHAIN (link))
- {
- oconstraints[i] = constraint
- = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
- parse_output_constraint (&constraint, i, 0, 0,
- &allows_mem, &allows_reg, &is_inout);
-
- check_lhs_var (TREE_VALUE (link));
- }
+ size_t i;
- for (link = ASM_INPUTS (stmt); link; link = TREE_CHAIN (link))
- {
- constraint
- = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
- parse_input_constraint (&constraint, 0, 0, noutputs, 0,
- oconstraints, &allows_mem, &allows_reg);
-
- check_rhs_var (TREE_VALUE (link));
- }
+ for (i = 0; i < gimple_asm_noutputs (stmt); i++)
+ check_lhs_var (gimple_asm_output_op (stmt, i));
+
+ for (i = 0; i < gimple_asm_ninputs (stmt); i++)
+ check_rhs_var (gimple_asm_input_op (stmt, i));
/* There is no code here to check for asm memory clobbers. The
casual maintainer might think that such code would be necessary,
@@ -1360,22 +1314,22 @@ get_asm_expr_operands (tree stmt)
assumed to already escape. So, we are protected here. */
}
-/* Check the parameters of a function call to CALL_EXPR to mark the
+
+/* Check the parameters of function call to CALL to mark the
types that pass across the function boundary. Also check to see if
this is either an indirect call, a call outside the compilation
unit. */
static void
-check_call (tree call_expr)
+check_call (gimple call)
{
- tree operand;
- tree callee_t = get_callee_fndecl (call_expr);
+ tree callee_t = gimple_call_fndecl (call);
struct cgraph_node* callee;
enum availability avail = AVAIL_NOT_AVAILABLE;
- call_expr_arg_iterator iter;
+ size_t i;
- FOR_EACH_CALL_EXPR_ARG (operand, iter, call_expr)
- check_rhs_var (operand);
+ for (i = 0; i < gimple_call_num_args (call); i++)
+ check_rhs_var (gimple_call_arg (call, i));
if (callee_t)
{
@@ -1388,12 +1342,11 @@ check_call (tree call_expr)
parameters. */
if (TYPE_ARG_TYPES (TREE_TYPE (callee_t)))
{
- for (arg_type = TYPE_ARG_TYPES (TREE_TYPE (callee_t)),
- operand = first_call_expr_arg (call_expr, &iter);
+ for (arg_type = TYPE_ARG_TYPES (TREE_TYPE (callee_t)), i = 0;
arg_type && TREE_VALUE (arg_type) != void_type_node;
- arg_type = TREE_CHAIN (arg_type),
- operand = next_call_expr_arg (&iter))
+ arg_type = TREE_CHAIN (arg_type), i++)
{
+ tree operand = gimple_call_arg (call, i);
if (operand)
{
last_arg_type = TREE_VALUE(arg_type);
@@ -1411,15 +1364,14 @@ check_call (tree call_expr)
/* FIXME - According to Geoff Keating, we should never
have to do this; the front ends should always process
the arg list from the TYPE_ARG_LIST. */
- for (arg_type = DECL_ARGUMENTS (callee_t),
- operand = first_call_expr_arg (call_expr, &iter);
+ for (arg_type = DECL_ARGUMENTS (callee_t), i = 0;
arg_type;
- arg_type = TREE_CHAIN (arg_type),
- operand = next_call_expr_arg (&iter))
+ arg_type = TREE_CHAIN (arg_type), i++)
{
+ tree operand = gimple_call_arg (call, i);
if (operand)
{
- last_arg_type = TREE_TYPE(arg_type);
+ last_arg_type = TREE_TYPE (arg_type);
check_cast (last_arg_type, operand);
}
else
@@ -1433,10 +1385,9 @@ check_call (tree call_expr)
/* In the case where we have a var_args function, we need to
check the remaining parameters against the last argument. */
arg_type = last_arg_type;
- for (;
- operand != NULL_TREE;
- operand = next_call_expr_arg (&iter))
+ for ( ; i < gimple_call_num_args (call); i++)
{
+ tree operand = gimple_call_arg (call, i);
if (arg_type)
check_cast (arg_type, operand);
else
@@ -1457,16 +1408,16 @@ check_call (tree call_expr)
are any bits available for the callee (such as by declaration or
because it is builtin) and process solely on the basis of those
bits. */
-
if (avail == AVAIL_NOT_AVAILABLE || avail == AVAIL_OVERWRITABLE)
{
/* If this is a direct call to an external function, mark all of
the parameter and return types. */
- FOR_EACH_CALL_EXPR_ARG (operand, iter, call_expr)
+ for (i = 0; i < gimple_call_num_args (call); i++)
{
+ tree operand = gimple_call_arg (call, i);
tree type = get_canon_type (TREE_TYPE (operand), false, false);
mark_interesting_type (type, EXPOSED_PARAMETER);
- }
+ }
if (callee_t)
{
@@ -1494,7 +1445,8 @@ okay_pointer_operation (enum tree_code code, tree op0, tree op1)
case PLUS_EXPR:
case POINTER_PLUS_EXPR:
{
- tree base, offset, offset_cast_stmt;
+ tree base, offset;
+ gimple offset_cast_stmt;
if (POINTER_TYPE_P (op0type)
&& TREE_CODE (op0) == SSA_NAME
@@ -1528,150 +1480,124 @@ okay_pointer_operation (enum tree_code code, tree op0, tree op1)
return false;
}
-/* TP is the part of the tree currently under the microscope.
- WALK_SUBTREES is part of the walk_tree api but is unused here.
- DATA is cgraph_node of the function being walked. */
-/* FIXME: When this is converted to run over SSA form, this code
- should be converted to use the operand scanner. */
-static tree
-scan_for_refs (tree *tp, int *walk_subtrees, void *data)
+/* Helper for scan_for_refs. Check the operands of an assignment to
+ mark types that may escape. */
+
+static void
+check_assign (gimple t)
{
- struct cgraph_node *fn = (struct cgraph_node *) data;
- tree t = *tp;
+ /* First look on the lhs and see what variable is stored to */
+ check_lhs_var (gimple_assign_lhs (t));
+
+ /* For the purposes of figuring out what the cast affects */
- switch (TREE_CODE (t))
+ /* Next check the operands on the rhs to see if they are ok. */
+ switch (TREE_CODE_CLASS (gimple_assign_rhs_code (t)))
{
- case VAR_DECL:
- if (DECL_INITIAL (t))
- walk_tree (&DECL_INITIAL (t), scan_for_refs, fn, visited_nodes);
- *walk_subtrees = 0;
+ case tcc_binary:
+ {
+ tree op0 = gimple_assign_rhs1 (t);
+ tree type0 = get_canon_type (TREE_TYPE (op0), false, false);
+ tree op1 = gimple_assign_rhs2 (t);
+ tree type1 = get_canon_type (TREE_TYPE (op1), false, false);
+
+ /* If this is pointer arithmetic of any bad sort, then
+ we need to mark the types as bad. For binary
+ operations, no binary operator we currently support
+ is always "safe" in regard to what it would do to
+ pointers for purposes of determining which types
+ escape, except operations of the size of the type.
+ It is possible that min and max under the right set
+ of circumstances and if the moon is in the correct
+ place could be safe, but it is hard to see how this
+ is worth the effort. */
+ if (type0 && POINTER_TYPE_P (type0)
+ && !okay_pointer_operation (gimple_assign_rhs_code (t), op0, op1))
+ mark_interesting_type (type0, FULL_ESCAPE);
+
+ if (type1 && POINTER_TYPE_P (type1)
+ && !okay_pointer_operation (gimple_assign_rhs_code (t), op1, op0))
+ mark_interesting_type (type1, FULL_ESCAPE);
+
+ look_for_casts (op0);
+ look_for_casts (op1);
+ check_rhs_var (op0);
+ check_rhs_var (op1);
+ }
break;
- case GIMPLE_MODIFY_STMT:
+ case tcc_unary:
{
- /* First look on the lhs and see what variable is stored to */
- tree lhs = GIMPLE_STMT_OPERAND (t, 0);
- tree rhs = GIMPLE_STMT_OPERAND (t, 1);
+ tree op0 = gimple_assign_rhs1 (t);
+ tree type0 = get_canon_type (TREE_TYPE (op0), false, false);
+
+ /* For unary operations, if the operation is NEGATE or ABS on
+ a pointer, this is also considered pointer arithmetic and
+ thus, bad for business. */
+ if (type0
+ && POINTER_TYPE_P (type0)
+ && (TREE_CODE (op0) == NEGATE_EXPR
+ || TREE_CODE (op0) == ABS_EXPR))
+ mark_interesting_type (type0, FULL_ESCAPE);
+
+ check_rhs_var (op0);
+ look_for_casts (op0);
+ }
+ break;
- check_lhs_var (lhs);
- check_cast (TREE_TYPE (lhs), rhs);
+ case tcc_reference:
+ look_for_casts (gimple_assign_rhs1 (t));
+ check_rhs_var (gimple_assign_rhs1 (t));
+ break;
- /* For the purposes of figuring out what the cast affects */
+ case tcc_declaration:
+ check_rhs_var (gimple_assign_rhs1 (t));
+ break;
- /* Next check the operands on the rhs to see if they are ok. */
- switch (TREE_CODE_CLASS (TREE_CODE (rhs)))
- {
- case tcc_binary:
- {
- tree op0 = TREE_OPERAND (rhs, 0);
- tree type0 = get_canon_type (TREE_TYPE (op0), false, false);
- tree op1 = TREE_OPERAND (rhs, 1);
- tree type1 = get_canon_type (TREE_TYPE (op1), false, false);
-
- /* If this is pointer arithmetic of any bad sort, then
- we need to mark the types as bad. For binary
- operations, no binary operator we currently support
- is always "safe" in regard to what it would do to
- pointers for purposes of determining which types
- escape, except operations of the size of the type.
- It is possible that min and max under the right set
- of circumstances and if the moon is in the correct
- place could be safe, but it is hard to see how this
- is worth the effort. */
-
- if (type0 && POINTER_TYPE_P (type0)
- && !okay_pointer_operation (TREE_CODE (rhs), op0, op1))
- mark_interesting_type (type0, FULL_ESCAPE);
- if (type1 && POINTER_TYPE_P (type1)
- && !okay_pointer_operation (TREE_CODE (rhs), op1, op0))
- mark_interesting_type (type1, FULL_ESCAPE);
-
- look_for_casts (lhs, op0);
- look_for_casts (lhs, op1);
- check_rhs_var (op0);
- check_rhs_var (op1);
- }
- break;
- case tcc_unary:
- {
- tree op0 = TREE_OPERAND (rhs, 0);
- tree type0 = get_canon_type (TREE_TYPE (op0), false, false);
- /* For unary operations, if the operation is NEGATE or
- ABS on a pointer, this is also considered pointer
- arithmetic and thus, bad for business. */
- if (type0 && (TREE_CODE (op0) == NEGATE_EXPR
- || TREE_CODE (op0) == ABS_EXPR)
- && POINTER_TYPE_P (type0))
- {
- mark_interesting_type (type0, FULL_ESCAPE);
- }
- check_rhs_var (op0);
- look_for_casts (lhs, op0);
- look_for_casts (lhs, rhs);
- }
+ case tcc_expression:
+ if (gimple_assign_rhs_code (t) == ADDR_EXPR)
+ {
+ tree rhs = gimple_assign_rhs1 (t);
+ look_for_casts (TREE_OPERAND (rhs, 0));
+ check_rhs_var (rhs);
+ }
+ break;
- break;
- case tcc_reference:
- look_for_casts (lhs, rhs);
- check_rhs_var (rhs);
- break;
- case tcc_declaration:
- check_rhs_var (rhs);
- break;
- case tcc_expression:
- switch (TREE_CODE (rhs))
- {
- case ADDR_EXPR:
- look_for_casts (lhs, TREE_OPERAND (rhs, 0));
- check_rhs_var (rhs);
- break;
- default:
- break;
- }
- break;
- case tcc_vl_exp:
- switch (TREE_CODE (rhs))
- {
- case CALL_EXPR:
- /* If this is a call to malloc, squirrel away the
- result so we do mark the resulting cast as being
- bad. */
- check_call (rhs);
- break;
- default:
- break;
- }
- break;
- default:
- break;
- }
- *walk_subtrees = 0;
- }
+ default:
break;
+ }
+}
+
- case ADDR_EXPR:
- /* This case is here to find addresses on rhs of constructors in
- decl_initial of static variables. */
- check_rhs_var (t);
- *walk_subtrees = 0;
+/* Scan statement T for references to types and mark anything
+ interesting. */
+
+static void
+scan_for_refs (gimple t)
+{
+ switch (gimple_code (t))
+ {
+ case GIMPLE_ASSIGN:
+ check_assign (t);
break;
- case CALL_EXPR:
+ case GIMPLE_CALL:
+ /* If this is a call to malloc, squirrel away the result so we
+ do mark the resulting cast as being bad. */
check_call (t);
- *walk_subtrees = 0;
break;
- case ASM_EXPR:
- get_asm_expr_operands (t);
- *walk_subtrees = 0;
+ case GIMPLE_ASM:
+ check_asm (t);
break;
default:
break;
}
- return NULL;
+
+ return;
}
@@ -1721,7 +1647,7 @@ analyze_variable (struct varpool_node *vnode)
gcc_assert (TREE_CODE (global) == VAR_DECL);
if (DECL_INITIAL (global))
- walk_tree (&DECL_INITIAL (global), scan_for_refs, NULL, visited_nodes);
+ check_tree (DECL_INITIAL (global));
}
/* This is the main routine for finding the reference patterns for
@@ -1742,10 +1668,9 @@ analyze_function (struct cgraph_node *fn)
FOR_EACH_BB_FN (this_block, this_cfun)
{
- block_stmt_iterator bsi;
- for (bsi = bsi_start (this_block); !bsi_end_p (bsi); bsi_next (&bsi))
- walk_tree (bsi_stmt_ptr (bsi), scan_for_refs,
- fn, visited_nodes);
+ gimple_stmt_iterator gsi;
+ for (gsi = gsi_start_bb (this_block); !gsi_end_p (gsi); gsi_next (&gsi))
+ scan_for_refs (gsi_stmt (gsi));
}
}
@@ -1761,8 +1686,7 @@ analyze_function (struct cgraph_node *fn)
if (TREE_CODE (var) == VAR_DECL
&& DECL_INITIAL (var)
&& !TREE_STATIC (var))
- walk_tree (&DECL_INITIAL (var), scan_for_refs,
- fn, visited_nodes);
+ check_tree (DECL_INITIAL (var));
get_canon_type (TREE_TYPE (var), false, false);
}
}
@@ -2192,7 +2116,7 @@ type_escape_execute (void)
static bool
gate_type_escape_vars (void)
{
- return (flag_unit_at_a_time != 0 && flag_ipa_type_escape
+ return (flag_ipa_type_escape
/* Don't bother doing anything if the program has errors. */
&& !(errorcount || sorrycount));
}
@@ -2215,4 +2139,3 @@ struct simple_ipa_opt_pass pass_ipa_type_escape =
0 /* todo_flags_finish */
}
};
-
diff --git a/gcc/ipa-type-escape.h b/gcc/ipa-type-escape.h
index c851a2707be..13c3b725c89 100644
--- a/gcc/ipa-type-escape.h
+++ b/gcc/ipa-type-escape.h
@@ -23,11 +23,11 @@ along with GCC; see the file COPYING3. If not see
#include "tree.h"
bool ipa_type_escape_type_contained_p (tree type);
-bool ipa_type_escape_field_does_not_clobber_p (tree record_type, tree field_type);
+bool ipa_type_escape_field_does_not_clobber_p (tree, tree);
int ipa_type_escape_star_count_of_interesting_type (tree type);
int ipa_type_escape_star_count_of_interesting_or_array_type (tree type);
bool is_array_access_through_pointer_and_index (enum tree_code, tree, tree,
- tree *, tree *, tree *);
+ tree *, tree *, gimple *);
#endif /* GCC_IPA_TYPE_ESCAPE_H */
diff --git a/gcc/ipa-utils.c b/gcc/ipa-utils.c
index 2a9562935c3..729a84d8710 100644
--- a/gcc/ipa-utils.c
+++ b/gcc/ipa-utils.c
@@ -32,7 +32,7 @@ along with GCC; see the file COPYING3. If not see
#include "ipa-utils.h"
#include "ipa-reference.h"
#include "c-common.h"
-#include "tree-gimple.h"
+#include "gimple.h"
#include "cgraph.h"
#include "output.h"
#include "flags.h"
diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog
index 33ac01f7a7c..a2c3cca3e12 100644
--- a/gcc/java/ChangeLog
+++ b/gcc/java/ChangeLog
@@ -1,3 +1,81 @@
+2008-07-28 Richard Guenther <rguenther@suse.de>
+
+ Merge from gimple-tuples-branch.
+
+ 2008-07-18 Richard Guenther <rguenther@suse.de>
+
+ * expr.c: Include tree-iterator.h.
+ * Make-lang.in (expr.o): Add tree-iterator.h dependency.
+
+ 2008-07-18 Aldy Hernandez <aldyh@redhat.com>
+
+ * java-gimplify.c: Include gimple.h instead of tree-gimple.h.
+ * expr.c: Same.
+
+ 2008-07-14 Aldy Hernandez <aldyh@redhat.com>
+
+ * java-gimplify.c (java_gimplify_expr): Same.
+ (java_gimplify_modify_expr): Same.
+ * java-tree.h: Rename GENERIC_NEXT to TREE_CHAIN.
+
+ 2008-05-02 Diego Novillo <dnovillo@google.com>
+
+ * expr.c (build_java_throw_out_of_bounds_exception): Fix
+ mixed declarations and code.
+
+ 2008-05-02 Doug Kwan <dougkwan@google.com>
+
+ * expr.c (build_java_throw_out_of_bounds_exception ): Wrap call to
+ _Jv_ThrowBadArrayIndex with a COMPOUND_EXPR to return 0.
+
+ 2008-02-19 Diego Novillo <dnovillo@google.com>
+
+ http://gcc.gnu.org/ml/gcc-patches/2008-02/msg00804.html
+
+ * java-gimplify.c (java_gimplify_self_mod_expr): Change
+ gimple_seq arguments to gimple_seq *. Update all users.
+
+ 2007-11-26 Aldy Hernandez <aldyh@redhat.com>
+
+ * java-gimplify.c (java_gimplify_expr): Make pre_p and post_p
+ sequences.
+ (java_gimplify_self_mod_expr): Same.
+ * java-tree.h (java_gimplify_expr): Make pre_p and post_p
+ sequences.
+
+2008-07-24 Jan Hubicka <jh@suse.cz>
+
+ * java/decl.c: Include cgraph.h
+ (end_java_method): Remove non-unit-at-a-time code.
+ (java_mark_decl_local): Likewise; sanity check that we don't touch
+ finalized nodes.
+
+2008-07-15 Jan Hubicka <jh@suse.cz>
+
+ * lang.c (java_init_options): Enable unit-at-a-time by default.
+
+2008-07-14 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
+
+ * Make-lang.in (jvspec.o): Fix dependencies.
+
+2008-07-06 Tom Tromey <tromey@redhat.com>
+
+ * Make-lang.in (java/parse.o-warn): Remove.
+ (java/jcf-io.o-warn): Remove.
+
+2008-07-05 Tom Tromey <tromey@redhat.com>
+
+ * jcf-io.c: Don't include fnmatch.h. Don't use JCF_USE_SCANDIR.
+ (compare_path): Remove.
+ (java_or_class_file): Likewise.
+ (memoized_dirlist_entry): Likewise.
+ (memoized_dirlist_hash): Likewise.
+ (memoized_dirlist_lookup_eq): Likewise.
+ (memoized_dirlists): Likewise.
+ (caching_stat): Likewise.
+ (find_class): Use stat.
+ * jcf.h (JCF_USE_SCANDIR): Remove.
+
2008-06-30 Joshua Sumali <jsumali@redhat.com>
* Make-lang.in (JAVA_MANFILES): Add doc/aot-compile.1 and
diff --git a/gcc/java/Make-lang.in b/gcc/java/Make-lang.in
index cab40afb959..f188c7d788d 100644
--- a/gcc/java/Make-lang.in
+++ b/gcc/java/Make-lang.in
@@ -57,7 +57,7 @@ JAVA_TARGET_INDEPENDENT_BIN_TOOLS = jcf-dump
.PHONY: java
jvspec.o: $(srcdir)/java/jvspec.c $(SYSTEM_H) coretypes.h $(TM_H) \
- $(GCC_H) $(CONFIG_H)
+ $(GCC_H) $(CONFIG_H) java/jcf.h java/javaop.h
(SHLIB_LINK='$(SHLIB_LINK)'; \
$(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(DRIVER_DEFINES) \
$(INCLUDES) $(srcdir)/java/jvspec.c $(OUTPUT_OPTION))
@@ -98,12 +98,6 @@ java-warn = $(STRICT_WARN)
# String length warnings
jvspec.o-warn = -Wno-error
-# Bison-1.75 output often yields (harmless) -Wtraditional warnings
-java/parse.o-warn = -Wno-error
-
-# java/jcf-io.c contains a -Wc++compat warning.
-java/jcf-io.o-warn = -Wno-error
-
jc1$(exeext): $(JAVA_OBJS) $(BACKEND) $(LIBDEPS) attribs.o
rm -f $@
$(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ \
@@ -275,7 +269,8 @@ java/except.o: java/except.c $(CONFIG_H) $(JAVA_TREE_H) java/jcf.h $(REAL_H) \
java/expr.o: java/expr.c $(CONFIG_H) $(JAVA_TREE_H) java/jcf.h $(REAL_H) \
$(RTL_H) $(EXPR_H) java/javaop.h java/java-opcodes.h except.h \
java/java-except.h java/java-except.h java/parse.h toplev.h \
- $(SYSTEM_H) coretypes.h $(TM_H) $(GGC_H) gt-java-expr.h $(TARGET_H)
+ $(SYSTEM_H) coretypes.h $(TM_H) $(GGC_H) gt-java-expr.h $(TARGET_H) \
+ tree-iterator.h
java/jcf-depend.o: java/jcf-depend.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TM_H) java/jcf.h
java/jcf-parse.o: java/jcf-parse.c $(CONFIG_H) $(JAVA_TREE_H) $(FLAGS_H) \
@@ -304,7 +299,7 @@ java/verify-impl.o: java/verify-impl.c $(CONFIG_H) java/verify.h $(SYSTEM_H) \
java/zextract.o: java/zextract.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
java/zipfile.h
java/java-gimplify.o: java/java-gimplify.c $(CONFIG_H) $(SYSTEM_H) \
- coretypes.h $(TM_H) $(JAVA_TREE_H) $(TREE_GIMPLE_H) toplev.h
+ coretypes.h $(TM_H) $(JAVA_TREE_H) $(GIMPLE_H) toplev.h
# jcf-io.o needs $(ZLIBINC) added to cflags.
java/jcf-io.o: java/jcf-io.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
diff --git a/gcc/java/decl.c b/gcc/java/decl.c
index d249157371d..1768109414d 100644
--- a/gcc/java/decl.c
+++ b/gcc/java/decl.c
@@ -49,6 +49,7 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */
#include "version.h"
#include "tree-iterator.h"
#include "langhooks.h"
+#include "cgraph.h"
#if defined (DEBUG_JAVA_BINDING_LEVELS)
extern void indent (void);
@@ -1797,14 +1798,6 @@ end_java_method (void)
finish_method (fndecl);
- if (! flag_unit_at_a_time)
- {
- /* Nulling these fields when we no longer need them saves
- memory. */
- DECL_SAVED_TREE (fndecl) = NULL;
- DECL_STRUCT_FUNCTION (fndecl) = NULL;
- DECL_INITIAL (fndecl) = NULL_TREE;
- }
current_function_decl = NULL_TREE;
}
@@ -1854,15 +1847,12 @@ java_mark_decl_local (tree decl)
{
DECL_EXTERNAL (decl) = 0;
- /* If we've already constructed DECL_RTL, give encode_section_info
- a second chance, now that we've changed the flags. */
- /* ??? Ideally, we'd have flag_unit_at_a_time set, and not have done
- anything that would have referenced DECL_RTL so far. But at the
- moment we force flag_unit_at_a_time off due to excessive memory
- consumption when compiling large jar files. Which probably means
- that we need to re-order how we process jar files... */
- if (DECL_RTL_SET_P (decl))
- make_decl_rtl (decl);
+#ifdef ENABLE_CHECKING
+ /* Double check that we didn't pass the function to the callgraph early. */
+ if (TREE_CODE (decl) == FUNCTION_DECL)
+ gcc_assert (!cgraph_node (decl)->local.finalized);
+#endif
+ gcc_assert (!DECL_RTL_SET_P (decl));
}
/* Given appropriate target support, G++ will emit hidden aliases for native
diff --git a/gcc/java/expr.c b/gcc/java/expr.c
index c64f6d68eba..ff28bbb0b40 100644
--- a/gcc/java/expr.c
+++ b/gcc/java/expr.c
@@ -42,7 +42,8 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */
#include "toplev.h"
#include "except.h"
#include "ggc.h"
-#include "tree-gimple.h"
+#include "tree-iterator.h"
+#include "gimple.h"
#include "target.h"
static void flush_quick_stack (void);
@@ -814,10 +815,20 @@ encode_newarray_type (tree type)
static tree
build_java_throw_out_of_bounds_exception (tree index)
{
- tree node = build_call_nary (int_type_node,
+ tree node;
+
+ /* We need to build a COMPOUND_EXPR because _Jv_ThrowBadArrayIndex()
+ has void return type. We cannot just set the type of the CALL_EXPR below
+ to int_type_node because we would lose it during gimplification. */
+ gcc_assert (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (soft_badarrayindex_node))));
+ node = build_call_nary (void_type_node,
build_address_of (soft_badarrayindex_node),
1, index);
+ TREE_SIDE_EFFECTS (node) = 1;
+
+ node = build2 (COMPOUND_EXPR, int_type_node, node, integer_zero_node);
TREE_SIDE_EFFECTS (node) = 1; /* Allows expansion within ANDIF */
+
return (node);
}
diff --git a/gcc/java/java-gimplify.c b/gcc/java/java-gimplify.c
index 53582411353..790cb13c039 100644
--- a/gcc/java/java-gimplify.c
+++ b/gcc/java/java-gimplify.c
@@ -28,12 +28,13 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */
#include "tree.h"
#include "java-tree.h"
#include "tree-dump.h"
-#include "tree-gimple.h"
+#include "gimple.h"
#include "toplev.h"
static tree java_gimplify_block (tree);
static enum gimplify_status java_gimplify_modify_expr (tree *);
-static enum gimplify_status java_gimplify_self_mod_expr (tree*, tree*, tree *);
+static enum gimplify_status java_gimplify_self_mod_expr (tree *, gimple_seq *,
+ gimple_seq *);
static void dump_java_tree (enum tree_dump_index, tree);
@@ -53,8 +54,7 @@ java_genericize (tree fndecl)
/* Gimplify a Java tree. */
int
-java_gimplify_expr (tree *expr_p, tree *pre_p ATTRIBUTE_UNUSED,
- tree *post_p ATTRIBUTE_UNUSED)
+java_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
{
enum tree_code code = TREE_CODE (*expr_p);
@@ -68,9 +68,6 @@ java_gimplify_expr (tree *expr_p, tree *pre_p ATTRIBUTE_UNUSED,
*expr_p = java_replace_reference (*expr_p, /* want_lvalue */ false);
return GS_UNHANDLED;
- /* We don't handle GIMPLE_MODIFY_STMT, as MODIFY_EXPRs with java
- semantics should only be generated by the front-end, and never
- by anything after gimplification. */
case MODIFY_EXPR:
return java_gimplify_modify_expr (expr_p);
@@ -142,7 +139,7 @@ java_gimplify_modify_expr (tree *modify_expr_p)
{
tree new_lhs = java_replace_reference (lhs, /* want_lvalue */ true);
tree new_rhs = build1 (NOP_EXPR, TREE_TYPE (new_lhs), rhs);
- modify_expr = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (new_lhs),
+ modify_expr = build2 (MODIFY_EXPR, TREE_TYPE (new_lhs),
new_lhs, new_rhs);
modify_expr = build1 (NOP_EXPR, lhs_type, modify_expr);
}
@@ -160,8 +157,8 @@ java_gimplify_modify_expr (tree *modify_expr_p)
between the reading and the writing. */
static enum gimplify_status
-java_gimplify_self_mod_expr (tree *expr_p, tree *pre_p ATTRIBUTE_UNUSED,
- tree *post_p ATTRIBUTE_UNUSED)
+java_gimplify_self_mod_expr (tree *expr_p, gimple_seq *pre_p ATTRIBUTE_UNUSED,
+ gimple_seq *post_p ATTRIBUTE_UNUSED)
{
tree lhs = TREE_OPERAND (*expr_p, 0);
@@ -180,7 +177,7 @@ java_gimplify_block (tree java_block)
{
tree decls = BLOCK_VARS (java_block);
tree body = BLOCK_EXPR_BODY (java_block);
- tree outer = gimple_current_bind_expr ();
+ gimple outer = gimple_current_bind_expr ();
tree block;
/* Don't bother with empty blocks. */
@@ -199,10 +196,10 @@ java_gimplify_block (tree java_block)
routines generate info for the variables in that block. */
TREE_USED (block) = 1;
- if (outer != NULL_TREE)
+ if (outer != NULL)
{
- outer = BIND_EXPR_BLOCK (outer);
- BLOCK_SUBBLOCKS (outer) = chainon (BLOCK_SUBBLOCKS (outer), block);
+ tree b = gimple_bind_block (outer);
+ BLOCK_SUBBLOCKS (b) = chainon (BLOCK_SUBBLOCKS (b), block);
}
BLOCK_EXPR_BODY (java_block) = NULL_TREE;
diff --git a/gcc/java/java-tree.h b/gcc/java/java-tree.h
index a046a0f450a..7ae71d9e41b 100644
--- a/gcc/java/java-tree.h
+++ b/gcc/java/java-tree.h
@@ -649,7 +649,7 @@ struct lang_identifier GTY(())
/* The resulting tree type. */
union lang_tree_node
GTY((desc ("TREE_CODE (&%h.generic) == IDENTIFIER_NODE"),
- chain_next ("(union lang_tree_node *)GENERIC_NEXT (&%h.generic)")))
+ chain_next ("(union lang_tree_node *)TREE_CHAIN (&%h.generic)")))
{
union tree_node GTY ((tag ("0"),
@@ -1555,7 +1555,7 @@ enum
#undef DEBUG_JAVA_BINDING_LEVELS
extern void java_genericize (tree);
-extern int java_gimplify_expr (tree *, tree *, tree *);
+extern int java_gimplify_expr (tree *, gimple_seq *, gimple_seq *);
extern FILE *finput;
diff --git a/gcc/java/jcf-io.c b/gcc/java/jcf-io.c
index 52120971fa2..b968214e509 100644
--- a/gcc/java/jcf-io.c
+++ b/gcc/java/jcf-io.c
@@ -34,10 +34,7 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */
#include "toplev.h"
#include "java-tree.h"
#include "hashtab.h"
-#if JCF_USE_SCANDIR
#include <dirent.h>
-#include <fnmatch.h>
-#endif
#include "zlib.h"
@@ -283,145 +280,6 @@ find_classfile (char *filename, JCF *jcf, const char *dep_name)
return open_class (filename, jcf, fd, dep_name);
}
-#if JCF_USE_SCANDIR
-
-/* A comparison function (as for qsort) that compares KEY (a char *
- giving the basename of a file) with the name stored in ENTRY (a
- dirent **). */
-
-static int
-compare_path (const void *key, const void *entry)
-{
- return strcmp ((const char *) key,
- (*((const struct dirent *const*) entry))->d_name);
-}
-
-/* Returns nonzero if ENTRY names a .java or .class file. */
-
-static int
-java_or_class_file (const struct dirent *entry)
-{
- const char *base = lbasename (entry->d_name);
- return (fnmatch ("*.java", base, 0) == 0 ||
- fnmatch ("*.class", base, 0) == 0);
-}
-
-/* Information about the files present in a particular directory. */
-typedef struct memoized_dirlist_entry
-{
- /* The name of the directory. */
- const char *dir;
- /* The number of .java and .class files present, or -1 if we could
- not, for some reason, obtain the list. */
- int num_files;
- /* The .java and .class files in the directory, in alphabetical
- order. */
- struct dirent **files;
-} memoized_dirlist_entry;
-
-/* A hash function for a memoized_dirlist_entry. */
-static hashval_t
-memoized_dirlist_hash (const void *entry)
-{
- const memoized_dirlist_entry *mde = (const memoized_dirlist_entry *) entry;
- return htab_hash_string (mde->dir);
-}
-
-/* Returns true if ENTRY (a memoized_dirlist_entry *) corresponds to
- the directory given by KEY (a char *) giving the directory
- name. */
-
-static int
-memoized_dirlist_lookup_eq (const void *entry, const void *key)
-{
- return strcmp ((const char *) key,
- ((const memoized_dirlist_entry *) entry)->dir) == 0;
-}
-
-/* A hash table mapping directory names to the lists of .java and
- .class files in that directory. */
-
-static htab_t memoized_dirlists;
-
-#endif
-
-/* Like stat, but avoids actually making the stat system call if we
- know that it cannot succeed. FILENAME and BUF are as for stat. */
-
-static int
-caching_stat (char *filename, struct stat *buf)
-{
-#if JCF_USE_SCANDIR
- char *sep;
- char origsep = 0;
- char *base;
- memoized_dirlist_entry *dent;
- void **slot;
- struct memoized_dirlist_entry temp;
-
- /* If the hashtable has not already been created, create it now. */
- if (!memoized_dirlists)
- memoized_dirlists = htab_create (37,
- memoized_dirlist_hash,
- memoized_dirlist_lookup_eq,
- NULL);
-
- /* Get the name of the directory. */
- sep = strrchr (filename, DIR_SEPARATOR);
-#ifdef DIR_SEPARATOR_2
- if (! sep)
- sep = strrchr (filename, DIR_SEPARATOR_2);
-#endif
- if (sep)
- {
- origsep = *sep;
- *sep = '\0';
- base = sep + 1;
- }
- else
- base = filename;
-
- /* Obtain the entry for this directory from the hash table. This
- approach is ok since we know that the hash function only looks at
- the directory name. */
- temp.dir = filename;
- temp.num_files = 0;
- temp.files = NULL;
- slot = htab_find_slot (memoized_dirlists, &temp, INSERT);
- if (!*slot)
- {
- /* We have not already scanned this directory; scan it now. */
- dent = XNEW (memoized_dirlist_entry);
- dent->dir = xstrdup (filename);
- /* Unfortunately, scandir is not fully standardized. In
- particular, the type of the function pointer passed as the
- third argument sometimes takes a "const struct dirent *"
- parameter, and sometimes just a "struct dirent *". We cast
- to (void *) and use __extension__ so that either way it is
- quietly accepted. FIXME: scandir is not in POSIX. */
- dent->num_files = __extension__ scandir (filename, &dent->files,
- (void *) java_or_class_file,
- alphasort);
- *slot = dent;
- }
- else
- dent = *((memoized_dirlist_entry **) slot);
-
- /* Put the separator back. */
- if (sep)
- *sep = origsep;
-
- /* If the file is not in the list, there is no need to stat it; it
- does not exist. */
- if (dent->num_files != -1
- && !bsearch (base, dent->files, dent->num_files,
- sizeof (struct dirent *), compare_path))
- return -1;
-#endif
-
- return stat (filename, buf);
-}
-
/* Returns 1 if the CLASSNAME (really a char *) matches the name
stored in TABLE_ENTRY (also a char *). */
@@ -521,7 +379,7 @@ find_class (const char *classname, int classname_length, JCF *jcf)
else
continue;
}
- klass = caching_stat(buffer, &class_buf);
+ klass = stat (buffer, &class_buf);
}
}
diff --git a/gcc/java/jcf.h b/gcc/java/jcf.h
index d4de2c57d54..40bbd725d45 100644
--- a/gcc/java/jcf.h
+++ b/gcc/java/jcf.h
@@ -1,6 +1,6 @@
/* Utility macros to read Java(TM) .class files and byte codes.
Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
- 2006, 2007 Free Software Foundation, Inc.
+ 2006, 2007, 2008 Free Software Foundation, Inc.
This file is part of GCC.
@@ -45,14 +45,6 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */
#define JCF_word JCF_u4
#endif
-/* If we have both "scandir" and "alphasort", we can cache directory
- listings to reduce the time taken to search the classpath. */
-#if defined(HAVE_SCANDIR) && defined(HAVE_ALPHASORT)
-#define JCF_USE_SCANDIR 1
-#else
-#define JCF_USE_SCANDIR 0
-#endif
-
/* On case-insensitive file systems, we need to ensure that a request
to open a .java or .class file is honored only if the file to be
opened is of the exact case we are asking for. In other words, we
diff --git a/gcc/java/lang.c b/gcc/java/lang.c
index c259da4f484..dde1b76573c 100644
--- a/gcc/java/lang.c
+++ b/gcc/java/lang.c
@@ -521,10 +521,6 @@ java_init_options (unsigned int argc ATTRIBUTE_UNUSED,
/* Java requires left-to-right evaluation of subexpressions. */
flag_evaluation_order = 1;
- /* Unit at a time is disabled for Java because it is considered
- too expensive. */
- no_unit_at_a_time_default = 1;
-
jcf_path_init ();
return CL_Java;
@@ -539,8 +535,6 @@ java_post_options (const char **pfilename)
/* Use tree inlining. */
if (!flag_no_inline)
flag_no_inline = 1;
- if (flag_inline_functions)
- flag_inline_trees = 2;
/* An absolute requirement: if we're not using indirect dispatch, we
must always verify everything. */
diff --git a/gcc/lambda-code.c b/gcc/lambda-code.c
index 5ae74ffa1ce..21bc1846a73 100644
--- a/gcc/lambda-code.c
+++ b/gcc/lambda-code.c
@@ -1231,16 +1231,16 @@ gcc_loop_to_lambda_loop (struct loop *loop, int depth,
VEC(tree,heap) * outerinductionvars,
VEC(tree,heap) ** lboundvars,
VEC(tree,heap) ** uboundvars,
- VEC(int,heap) ** steps,
+ VEC(int,heap) ** steps,
struct obstack * lambda_obstack)
{
- tree phi;
- tree exit_cond;
+ gimple phi;
+ gimple exit_cond;
tree access_fn, inductionvar;
tree step;
lambda_loop lloop = NULL;
lambda_linear_expression lbound, ubound;
- tree test;
+ tree test_lhs, test_rhs;
int stepint;
int extra = 0;
tree lboundvar, uboundvar, uboundresult;
@@ -1257,9 +1257,7 @@ gcc_loop_to_lambda_loop (struct loop *loop, int depth,
return NULL;
}
- test = TREE_OPERAND (exit_cond, 0);
-
- if (SSA_NAME_DEF_STMT (inductionvar) == NULL_TREE)
+ if (SSA_NAME_DEF_STMT (inductionvar) == NULL)
{
if (dump_file && (dump_flags & TDF_DETAILS))
@@ -1270,10 +1268,10 @@ gcc_loop_to_lambda_loop (struct loop *loop, int depth,
}
phi = SSA_NAME_DEF_STMT (inductionvar);
- if (TREE_CODE (phi) != PHI_NODE)
+ if (gimple_code (phi) != GIMPLE_PHI)
{
- phi = SINGLE_SSA_TREE_OPERAND (phi, SSA_OP_USE);
- if (!phi)
+ tree op = SINGLE_SSA_TREE_OPERAND (phi, SSA_OP_USE);
+ if (!op)
{
if (dump_file && (dump_flags & TDF_DETAILS))
@@ -1283,16 +1281,14 @@ gcc_loop_to_lambda_loop (struct loop *loop, int depth,
return NULL;
}
- phi = SSA_NAME_DEF_STMT (phi);
- if (TREE_CODE (phi) != PHI_NODE)
+ phi = SSA_NAME_DEF_STMT (op);
+ if (gimple_code (phi) != GIMPLE_PHI)
{
-
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file,
"Unable to convert loop: Cannot find PHI node for induction variable\n");
return NULL;
}
-
}
/* The induction variable name/version we want to put in the array is the
@@ -1331,7 +1327,7 @@ gcc_loop_to_lambda_loop (struct loop *loop, int depth,
/* Only want phis for induction vars, which will have two
arguments. */
- if (PHI_NUM_ARGS (phi) != 2)
+ if (gimple_phi_num_args (phi) != 2)
{
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file,
@@ -1341,8 +1337,8 @@ gcc_loop_to_lambda_loop (struct loop *loop, int depth,
/* Another induction variable check. One argument's source should be
in the loop, one outside the loop. */
- if (flow_bb_inside_loop_p (loop, PHI_ARG_EDGE (phi, 0)->src)
- && flow_bb_inside_loop_p (loop, PHI_ARG_EDGE (phi, 1)->src))
+ if (flow_bb_inside_loop_p (loop, gimple_phi_arg_edge (phi, 0)->src)
+ && flow_bb_inside_loop_p (loop, gimple_phi_arg_edge (phi, 1)->src))
{
if (dump_file && (dump_flags & TDF_DETAILS))
@@ -1352,7 +1348,7 @@ gcc_loop_to_lambda_loop (struct loop *loop, int depth,
return NULL;
}
- if (flow_bb_inside_loop_p (loop, PHI_ARG_EDGE (phi, 0)->src))
+ if (flow_bb_inside_loop_p (loop, gimple_phi_arg_edge (phi, 0)->src))
{
lboundvar = PHI_ARG_DEF (phi, 1);
lbound = gcc_tree_to_linear_expression (depth, lboundvar,
@@ -1378,21 +1374,23 @@ gcc_loop_to_lambda_loop (struct loop *loop, int depth,
}
/* One part of the test may be a loop invariant tree. */
VEC_reserve (tree, heap, *invariants, 1);
- if (TREE_CODE (TREE_OPERAND (test, 1)) == SSA_NAME
- && invariant_in_loop_and_outer_loops (loop, TREE_OPERAND (test, 1)))
- VEC_quick_push (tree, *invariants, TREE_OPERAND (test, 1));
- else if (TREE_CODE (TREE_OPERAND (test, 0)) == SSA_NAME
- && invariant_in_loop_and_outer_loops (loop, TREE_OPERAND (test, 0)))
- VEC_quick_push (tree, *invariants, TREE_OPERAND (test, 0));
+ test_lhs = gimple_cond_lhs (exit_cond);
+ test_rhs = gimple_cond_rhs (exit_cond);
+
+ if (TREE_CODE (test_rhs) == SSA_NAME
+ && invariant_in_loop_and_outer_loops (loop, test_rhs))
+ VEC_quick_push (tree, *invariants, test_rhs);
+ else if (TREE_CODE (test_lhs) == SSA_NAME
+ && invariant_in_loop_and_outer_loops (loop, test_lhs))
+ VEC_quick_push (tree, *invariants, test_lhs);
/* The non-induction variable part of the test is the upper bound variable.
*/
- if (TREE_OPERAND (test, 0) == inductionvar)
- uboundvar = TREE_OPERAND (test, 1);
+ if (test_lhs == inductionvar)
+ uboundvar = test_rhs;
else
- uboundvar = TREE_OPERAND (test, 0);
+ uboundvar = test_lhs;
-
/* We only size the vectors assuming we have, at max, 2 times as many
invariants as we do loops (one for each bound).
This is just an arbitrary number, but it has to be matched against the
@@ -1401,13 +1399,13 @@ gcc_loop_to_lambda_loop (struct loop *loop, int depth,
/* We might have some leftover. */
- if (TREE_CODE (test) == LT_EXPR)
+ if (gimple_cond_code (exit_cond) == LT_EXPR)
extra = -1 * stepint;
- else if (TREE_CODE (test) == NE_EXPR)
+ else if (gimple_cond_code (exit_cond) == NE_EXPR)
extra = -1 * stepint;
- else if (TREE_CODE (test) == GT_EXPR)
+ else if (gimple_cond_code (exit_cond) == GT_EXPR)
extra = -1 * stepint;
- else if (TREE_CODE (test) == EQ_EXPR)
+ else if (gimple_cond_code (exit_cond) == EQ_EXPR)
extra = 1 * stepint;
ubound = gcc_tree_to_linear_expression (depth, uboundvar,
@@ -1439,24 +1437,23 @@ gcc_loop_to_lambda_loop (struct loop *loop, int depth,
static tree
find_induction_var_from_exit_cond (struct loop *loop)
{
- tree expr = get_loop_exit_condition (loop);
+ gimple expr = get_loop_exit_condition (loop);
tree ivarop;
- tree test;
- if (expr == NULL_TREE)
- return NULL_TREE;
- if (TREE_CODE (expr) != COND_EXPR)
+ tree test_lhs, test_rhs;
+ if (expr == NULL)
return NULL_TREE;
- test = TREE_OPERAND (expr, 0);
- if (!COMPARISON_CLASS_P (test))
+ if (gimple_code (expr) != GIMPLE_COND)
return NULL_TREE;
+ test_lhs = gimple_cond_lhs (expr);
+ test_rhs = gimple_cond_rhs (expr);
/* Find the side that is invariant in this loop. The ivar must be the other
side. */
- if (expr_invariant_in_loop_p (loop, TREE_OPERAND (test, 0)))
- ivarop = TREE_OPERAND (test, 1);
- else if (expr_invariant_in_loop_p (loop, TREE_OPERAND (test, 1)))
- ivarop = TREE_OPERAND (test, 0);
+ if (expr_invariant_in_loop_p (loop, test_lhs))
+ ivarop = test_rhs;
+ else if (expr_invariant_in_loop_p (loop, test_rhs))
+ ivarop = test_lhs;
else
return NULL_TREE;
@@ -1548,7 +1545,7 @@ gcc_loopnest_to_lambda_loopnest (struct loop *loop_nest,
static tree
lbv_to_gcc_expression (lambda_body_vector lbv,
tree type, VEC(tree,heap) *induction_vars,
- tree *stmts_to_insert)
+ gimple_seq *stmts_to_insert)
{
int k;
tree resvar;
@@ -1583,7 +1580,7 @@ lle_to_gcc_expression (lambda_linear_expression lle,
tree type,
VEC(tree,heap) *induction_vars,
VEC(tree,heap) *invariants,
- enum tree_code wrap, tree *stmts_to_insert)
+ enum tree_code wrap, gimple_seq *stmts_to_insert)
{
int k;
tree resvar;
@@ -1641,17 +1638,19 @@ lle_to_gcc_expression (lambda_linear_expression lle,
/* Remove the induction variable defined at IV_STMT. */
void
-remove_iv (tree iv_stmt)
+remove_iv (gimple iv_stmt)
{
- if (TREE_CODE (iv_stmt) == PHI_NODE)
+ gimple_stmt_iterator si = gsi_for_stmt (iv_stmt);
+
+ if (gimple_code (iv_stmt) == GIMPLE_PHI)
{
- int i;
+ unsigned i;
- for (i = 0; i < PHI_NUM_ARGS (iv_stmt); i++)
+ for (i = 0; i < gimple_phi_num_args (iv_stmt); i++)
{
- tree stmt;
+ gimple stmt;
imm_use_iterator imm_iter;
- tree arg = PHI_ARG_DEF (iv_stmt, i);
+ tree arg = gimple_phi_arg_def (iv_stmt, i);
bool used = false;
if (TREE_CODE (arg) != SSA_NAME)
@@ -1665,13 +1664,11 @@ remove_iv (tree iv_stmt)
remove_iv (SSA_NAME_DEF_STMT (arg));
}
- remove_phi_node (iv_stmt, NULL_TREE, true);
+ remove_phi_node (&si, true);
}
else
{
- block_stmt_iterator bsi = bsi_for_stmt (iv_stmt);
-
- bsi_remove (&bsi, true);
+ gsi_remove (&si, true);
release_defs (iv_stmt);
}
}
@@ -1692,18 +1689,18 @@ void
lambda_loopnest_to_gcc_loopnest (struct loop *old_loopnest,
VEC(tree,heap) *old_ivs,
VEC(tree,heap) *invariants,
- VEC(tree,heap) **remove_ivs,
+ VEC(gimple,heap) **remove_ivs,
lambda_loopnest new_loopnest,
lambda_trans_matrix transform,
struct obstack * lambda_obstack)
{
struct loop *temp;
size_t i = 0;
- int j;
+ unsigned j;
size_t depth = 0;
VEC(tree,heap) *new_ivs = NULL;
tree oldiv;
- block_stmt_iterator bsi;
+ gimple_stmt_iterator bsi;
transform = lambda_trans_matrix_inverse (transform);
@@ -1720,13 +1717,15 @@ lambda_loopnest_to_gcc_loopnest (struct loop *old_loopnest,
lambda_loop newloop;
basic_block bb;
edge exit;
- tree ivvar, ivvarinced, exitcond, stmts;
+ tree ivvar, ivvarinced;
+ gimple exitcond;
+ gimple_seq stmts;
enum tree_code testtype;
tree newupperbound, newlowerbound;
lambda_linear_expression offset;
tree type;
bool insert_after;
- tree inc_stmt;
+ gimple inc_stmt;
oldiv = VEC_index (tree, old_ivs, i);
type = TREE_TYPE (oldiv);
@@ -1749,6 +1748,7 @@ lambda_loopnest_to_gcc_loopnest (struct loop *old_loopnest,
/* Now build the new lower bounds, and insert the statements
necessary to generate it on the loop preheader. */
+ stmts = NULL;
newlowerbound = lle_to_gcc_expression (LL_LOWER_BOUND (newloop),
LL_LINEAR_OFFSET (newloop),
type,
@@ -1757,11 +1757,12 @@ lambda_loopnest_to_gcc_loopnest (struct loop *old_loopnest,
if (stmts)
{
- bsi_insert_on_edge (loop_preheader_edge (temp), stmts);
- bsi_commit_edge_inserts ();
+ gsi_insert_seq_on_edge (loop_preheader_edge (temp), stmts);
+ gsi_commit_edge_inserts ();
}
/* Build the new upper bound and insert its statements in the
basic block of the exit condition */
+ stmts = NULL;
newupperbound = lle_to_gcc_expression (LL_UPPER_BOUND (newloop),
LL_LINEAR_OFFSET (newloop),
type,
@@ -1769,10 +1770,10 @@ lambda_loopnest_to_gcc_loopnest (struct loop *old_loopnest,
invariants, MIN_EXPR, &stmts);
exit = single_exit (temp);
exitcond = get_loop_exit_condition (temp);
- bb = bb_for_stmt (exitcond);
- bsi = bsi_after_labels (bb);
+ bb = gimple_bb (exitcond);
+ bsi = gsi_after_labels (bb);
if (stmts)
- bsi_insert_before (&bsi, stmts, BSI_NEW_STMT);
+ gsi_insert_seq_before (&bsi, stmts, GSI_NEW_STMT);
/* Create the new iv. */
@@ -1786,13 +1787,14 @@ lambda_loopnest_to_gcc_loopnest (struct loop *old_loopnest,
dominate the block containing the exit condition.
So we simply create our own incremented iv to use in the new exit
test, and let redundancy elimination sort it out. */
- inc_stmt = build2 (PLUS_EXPR, type,
- ivvar, build_int_cst (type, LL_STEP (newloop)));
- inc_stmt = build_gimple_modify_stmt (SSA_NAME_VAR (ivvar), inc_stmt);
+ inc_stmt = gimple_build_assign_with_ops (PLUS_EXPR, SSA_NAME_VAR (ivvar),
+ ivvar,
+ build_int_cst (type, LL_STEP (newloop)));
+
ivvarinced = make_ssa_name (SSA_NAME_VAR (ivvar), inc_stmt);
- GIMPLE_STMT_OPERAND (inc_stmt, 0) = ivvarinced;
- bsi = bsi_for_stmt (exitcond);
- bsi_insert_before (&bsi, inc_stmt, BSI_SAME_STMT);
+ gimple_assign_set_lhs (inc_stmt, ivvarinced);
+ bsi = gsi_for_stmt (exitcond);
+ gsi_insert_before (&bsi, inc_stmt, GSI_SAME_STMT);
/* Replace the exit condition with the new upper bound
comparison. */
@@ -1806,9 +1808,7 @@ lambda_loopnest_to_gcc_loopnest (struct loop *old_loopnest,
if (exit->flags & EDGE_FALSE_VALUE)
testtype = swap_tree_comparison (testtype);
- COND_EXPR_COND (exitcond) = build2 (testtype,
- boolean_type_node,
- newupperbound, ivvarinced);
+ gimple_cond_set_condition (exitcond, testtype, newupperbound, ivvarinced);
update_stmt (exitcond);
VEC_replace (tree, new_ivs, i, ivvar);
@@ -1824,10 +1824,10 @@ lambda_loopnest_to_gcc_loopnest (struct loop *old_loopnest,
imm_use_iterator imm_iter;
use_operand_p use_p;
tree oldiv_def;
- tree oldiv_stmt = SSA_NAME_DEF_STMT (oldiv);
- tree stmt;
+ gimple oldiv_stmt = SSA_NAME_DEF_STMT (oldiv);
+ gimple stmt;
- if (TREE_CODE (oldiv_stmt) == PHI_NODE)
+ if (gimple_code (oldiv_stmt) == GIMPLE_PHI)
oldiv_def = PHI_RESULT (oldiv_stmt);
else
oldiv_def = SINGLE_SSA_TREE_OPERAND (oldiv_stmt, SSA_OP_DEF);
@@ -1835,7 +1835,8 @@ lambda_loopnest_to_gcc_loopnest (struct loop *old_loopnest,
FOR_EACH_IMM_USE_STMT (stmt, imm_iter, oldiv_def)
{
- tree newiv, stmts;
+ tree newiv;
+ gimple_seq stmts;
lambda_body_vector lbv, newlbv;
/* Compute the new expression for the induction
@@ -1847,28 +1848,29 @@ lambda_loopnest_to_gcc_loopnest (struct loop *old_loopnest,
newlbv = lambda_body_vector_compute_new (transform, lbv,
lambda_obstack);
+ stmts = NULL;
newiv = lbv_to_gcc_expression (newlbv, TREE_TYPE (oldiv),
new_ivs, &stmts);
- if (stmts && TREE_CODE (stmt) != PHI_NODE)
+ if (stmts && gimple_code (stmt) != GIMPLE_PHI)
{
- bsi = bsi_for_stmt (stmt);
- bsi_insert_before (&bsi, stmts, BSI_SAME_STMT);
+ bsi = gsi_for_stmt (stmt);
+ gsi_insert_seq_before (&bsi, stmts, GSI_SAME_STMT);
}
FOR_EACH_IMM_USE_ON_STMT (use_p, imm_iter)
propagate_value (use_p, newiv);
- if (stmts && TREE_CODE (stmt) == PHI_NODE)
- for (j = 0; j < PHI_NUM_ARGS (stmt); j++)
- if (PHI_ARG_DEF (stmt, j) == newiv)
- bsi_insert_on_edge (PHI_ARG_EDGE (stmt, j), stmts);
+ if (stmts && gimple_code (stmt) == GIMPLE_PHI)
+ for (j = 0; j < gimple_phi_num_args (stmt); j++)
+ if (gimple_phi_arg_def (stmt, j) == newiv)
+ gsi_insert_seq_on_edge (gimple_phi_arg_edge (stmt, j), stmts);
update_stmt (stmt);
}
/* Remove the now unused induction variable. */
- VEC_safe_push (tree, heap, *remove_ivs, oldiv_stmt);
+ VEC_safe_push (gimple, heap, *remove_ivs, oldiv_stmt);
}
VEC_free (tree, heap, new_ivs);
}
@@ -1877,13 +1879,13 @@ lambda_loopnest_to_gcc_loopnest (struct loop *old_loopnest,
determining if we have a perfect loop nest. */
static bool
-not_interesting_stmt (tree stmt)
+not_interesting_stmt (gimple stmt)
{
/* Note that COND_EXPR's aren't interesting because if they were exiting the
loop, we would have already failed the number of exits tests. */
- if (TREE_CODE (stmt) == LABEL_EXPR
- || TREE_CODE (stmt) == GOTO_EXPR
- || TREE_CODE (stmt) == COND_EXPR)
+ if (gimple_code (stmt) == GIMPLE_LABEL
+ || gimple_code (stmt) == GIMPLE_GOTO
+ || gimple_code (stmt) == GIMPLE_COND)
return true;
return false;
}
@@ -1891,11 +1893,11 @@ not_interesting_stmt (tree stmt)
/* Return TRUE if PHI uses DEF for it's in-the-loop edge for LOOP. */
static bool
-phi_loop_edge_uses_def (struct loop *loop, tree phi, tree def)
+phi_loop_edge_uses_def (struct loop *loop, gimple phi, tree def)
{
- int i;
- for (i = 0; i < PHI_NUM_ARGS (phi); i++)
- if (flow_bb_inside_loop_p (loop, PHI_ARG_EDGE (phi, i)->src))
+ unsigned i;
+ for (i = 0; i < gimple_phi_num_args (phi); i++)
+ if (flow_bb_inside_loop_p (loop, gimple_phi_arg_edge (phi, i)->src))
if (PHI_ARG_DEF (phi, i) == def)
return true;
return false;
@@ -1904,7 +1906,7 @@ phi_loop_edge_uses_def (struct loop *loop, tree phi, tree def)
/* Return TRUE if STMT is a use of PHI_RESULT. */
static bool
-stmt_uses_phi_result (tree stmt, tree phi_result)
+stmt_uses_phi_result (gimple stmt, tree phi_result)
{
tree use = SINGLE_SSA_TREE_OPERAND (stmt, SSA_OP_USE);
@@ -1920,9 +1922,9 @@ stmt_uses_phi_result (tree stmt, tree phi_result)
i_3 = PHI (0, i_29); */
static bool
-stmt_is_bumper_for_loop (struct loop *loop, tree stmt)
+stmt_is_bumper_for_loop (struct loop *loop, gimple stmt)
{
- tree use;
+ gimple use;
tree def;
imm_use_iterator iter;
use_operand_p use_p;
@@ -1934,7 +1936,7 @@ stmt_is_bumper_for_loop (struct loop *loop, tree stmt)
FOR_EACH_IMM_USE_FAST (use_p, iter, def)
{
use = USE_STMT (use_p);
- if (TREE_CODE (use) == PHI_NODE)
+ if (gimple_code (use) == GIMPLE_PHI)
{
if (phi_loop_edge_uses_def (loop, use, def))
if (stmt_uses_phi_result (stmt, PHI_RESULT (use)))
@@ -1976,7 +1978,7 @@ perfect_nest_p (struct loop *loop)
{
basic_block *bbs;
size_t i;
- tree exit_cond;
+ gimple exit_cond;
/* Loops at depth 0 are perfect nests. */
if (!loop->inner)
@@ -1989,13 +1991,13 @@ perfect_nest_p (struct loop *loop)
{
if (bbs[i]->loop_father == loop)
{
- block_stmt_iterator bsi;
+ gimple_stmt_iterator bsi;
- for (bsi = bsi_start (bbs[i]); !bsi_end_p (bsi); bsi_next (&bsi))
+ for (bsi = gsi_start_bb (bbs[i]); !gsi_end_p (bsi); gsi_next (&bsi))
{
- tree stmt = bsi_stmt (bsi);
+ gimple stmt = gsi_stmt (bsi);
- if (TREE_CODE (stmt) == COND_EXPR
+ if (gimple_code (stmt) == GIMPLE_COND
&& exit_cond != stmt)
goto non_perfectly_nested;
@@ -2023,10 +2025,10 @@ perfect_nest_p (struct loop *loop)
of body basic block. */
static void
-replace_uses_equiv_to_x_with_y (struct loop *loop, tree stmt, tree x,
+replace_uses_equiv_to_x_with_y (struct loop *loop, gimple stmt, tree x,
int xstep, tree y, tree yinit,
htab_t replacements,
- block_stmt_iterator *firstbsi)
+ gimple_stmt_iterator *firstbsi)
{
ssa_op_iter iter;
use_operand_p use_p;
@@ -2035,7 +2037,8 @@ replace_uses_equiv_to_x_with_y (struct loop *loop, tree stmt, tree x,
{
tree use = USE_FROM_PTR (use_p);
tree step = NULL_TREE;
- tree scev, init, val, var, setstmt;
+ tree scev, init, val, var;
+ gimple setstmt;
struct tree_map *h, in;
void **loc;
@@ -2098,12 +2101,12 @@ replace_uses_equiv_to_x_with_y (struct loop *loop, tree stmt, tree x,
which sets Y. */
var = create_tmp_var (TREE_TYPE (use), "perfecttmp");
add_referenced_var (var);
- val = force_gimple_operand_bsi (firstbsi, val, false, NULL,
- true, BSI_SAME_STMT);
- setstmt = build_gimple_modify_stmt (var, val);
+ val = force_gimple_operand_gsi (firstbsi, val, false, NULL,
+ true, GSI_SAME_STMT);
+ setstmt = gimple_build_assign (var, val);
var = make_ssa_name (var, setstmt);
- GIMPLE_STMT_OPERAND (setstmt, 0) = var;
- bsi_insert_before (firstbsi, setstmt, BSI_SAME_STMT);
+ gimple_assign_set_lhs (setstmt, var);
+ gsi_insert_before (firstbsi, setstmt, GSI_SAME_STMT);
update_stmt (setstmt);
SET_USE (use_p, var);
h = GGC_NEW (struct tree_map);
@@ -2119,12 +2122,11 @@ replace_uses_equiv_to_x_with_y (struct loop *loop, tree stmt, tree x,
/* Return true if STMT is an exit PHI for LOOP */
static bool
-exit_phi_for_loop_p (struct loop *loop, tree stmt)
+exit_phi_for_loop_p (struct loop *loop, gimple stmt)
{
-
- if (TREE_CODE (stmt) != PHI_NODE
- || PHI_NUM_ARGS (stmt) != 1
- || bb_for_stmt (stmt) != single_exit (loop)->dest)
+ if (gimple_code (stmt) != GIMPLE_PHI
+ || gimple_phi_num_args (stmt) != 1
+ || gimple_bb (stmt) != single_exit (loop)->dest)
return false;
return true;
@@ -2134,21 +2136,21 @@ exit_phi_for_loop_p (struct loop *loop, tree stmt)
copying it to the beginning of that loop and changing the uses. */
static bool
-can_put_in_inner_loop (struct loop *inner, tree stmt)
+can_put_in_inner_loop (struct loop *inner, gimple stmt)
{
imm_use_iterator imm_iter;
use_operand_p use_p;
- gcc_assert (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT);
+ gcc_assert (is_gimple_assign (stmt));
if (!ZERO_SSA_OPERANDS (stmt, SSA_OP_ALL_VIRTUALS)
- || !expr_invariant_in_loop_p (inner, GIMPLE_STMT_OPERAND (stmt, 1)))
+ || !stmt_invariant_in_loop_p (inner, stmt))
return false;
- FOR_EACH_IMM_USE_FAST (use_p, imm_iter, GIMPLE_STMT_OPERAND (stmt, 0))
+ FOR_EACH_IMM_USE_FAST (use_p, imm_iter, gimple_assign_lhs (stmt))
{
if (!exit_phi_for_loop_p (inner, USE_STMT (use_p)))
{
- basic_block immbb = bb_for_stmt (USE_STMT (use_p));
+ basic_block immbb = gimple_bb (USE_STMT (use_p));
if (!flow_bb_inside_loop_p (inner, immbb))
return false;
@@ -2158,8 +2160,9 @@ can_put_in_inner_loop (struct loop *inner, tree stmt)
}
/* Return true if STMT can be put *after* the inner loop of LOOP. */
+
static bool
-can_put_after_inner_loop (struct loop *loop, tree stmt)
+can_put_after_inner_loop (struct loop *loop, gimple stmt)
{
imm_use_iterator imm_iter;
use_operand_p use_p;
@@ -2167,11 +2170,11 @@ can_put_after_inner_loop (struct loop *loop, tree stmt)
if (!ZERO_SSA_OPERANDS (stmt, SSA_OP_ALL_VIRTUALS))
return false;
- FOR_EACH_IMM_USE_FAST (use_p, imm_iter, GIMPLE_STMT_OPERAND (stmt, 0))
+ FOR_EACH_IMM_USE_FAST (use_p, imm_iter, gimple_assign_lhs (stmt))
{
if (!exit_phi_for_loop_p (loop, USE_STMT (use_p)))
{
- basic_block immbb = bb_for_stmt (USE_STMT (use_p));
+ basic_block immbb = gimple_bb (USE_STMT (use_p));
if (!dominated_by_p (CDI_DOMINATORS,
immbb,
@@ -2211,81 +2214,77 @@ can_duplicate_iv (tree iv, struct loop *loop)
it has better cache behavior. */
static bool
-cannot_convert_modify_to_perfect_nest (tree stmt, struct loop *loop)
+cannot_convert_modify_to_perfect_nest (gimple stmt, struct loop *loop)
{
-
use_operand_p use_a, use_b;
imm_use_iterator imm_iter;
ssa_op_iter op_iter, op_iter1;
- tree op0 = GIMPLE_STMT_OPERAND (stmt, 0);
+ tree op0 = gimple_assign_lhs (stmt);
/* The statement should not define a variable used in the inner
loop. */
if (TREE_CODE (op0) == SSA_NAME
&& !can_duplicate_iv (op0, loop))
FOR_EACH_IMM_USE_FAST (use_a, imm_iter, op0)
- if (bb_for_stmt (USE_STMT (use_a))->loop_father
- == loop->inner)
+ if (gimple_bb (USE_STMT (use_a))->loop_father == loop->inner)
return true;
FOR_EACH_SSA_USE_OPERAND (use_a, stmt, op_iter, SSA_OP_USE)
{
- tree node, op = USE_FROM_PTR (use_a);
+ gimple node;
+ tree op = USE_FROM_PTR (use_a);
/* The variables should not be used in both loops. */
if (!can_duplicate_iv (op, loop))
FOR_EACH_IMM_USE_FAST (use_b, imm_iter, op)
- if (bb_for_stmt (USE_STMT (use_b))->loop_father
- == loop->inner)
+ if (gimple_bb (USE_STMT (use_b))->loop_father == loop->inner)
return true;
/* The statement should not use the value of a scalar that was
modified in the loop. */
node = SSA_NAME_DEF_STMT (op);
- if (TREE_CODE (node) == PHI_NODE)
+ if (gimple_code (node) == GIMPLE_PHI)
FOR_EACH_PHI_ARG (use_b, node, op_iter1, SSA_OP_USE)
- {
- tree arg = USE_FROM_PTR (use_b);
+ {
+ tree arg = USE_FROM_PTR (use_b);
- if (TREE_CODE (arg) == SSA_NAME)
- {
- tree arg_stmt = SSA_NAME_DEF_STMT (arg);
+ if (TREE_CODE (arg) == SSA_NAME)
+ {
+ gimple arg_stmt = SSA_NAME_DEF_STMT (arg);
- if (bb_for_stmt (arg_stmt)
- && (bb_for_stmt (arg_stmt)->loop_father
- == loop->inner))
- return true;
- }
- }
+ if (gimple_bb (arg_stmt)
+ && (gimple_bb (arg_stmt)->loop_father == loop->inner))
+ return true;
+ }
+ }
}
return false;
}
-
/* Return true when BB contains statements that can harm the transform
to a perfect loop nest. */
static bool
cannot_convert_bb_to_perfect_nest (basic_block bb, struct loop *loop)
{
- block_stmt_iterator bsi;
- tree exit_condition = get_loop_exit_condition (loop);
+ gimple_stmt_iterator bsi;
+ gimple exit_condition = get_loop_exit_condition (loop);
- for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
+ for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi))
{
- tree stmt = bsi_stmt (bsi);
+ gimple stmt = gsi_stmt (bsi);
if (stmt == exit_condition
|| not_interesting_stmt (stmt)
|| stmt_is_bumper_for_loop (loop, stmt))
continue;
- if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT)
+ if (is_gimple_assign (stmt))
{
if (cannot_convert_modify_to_perfect_nest (stmt, loop))
return true;
- if (can_duplicate_iv (GIMPLE_STMT_OPERAND (stmt, 0), loop))
+ if (can_duplicate_iv (gimple_assign_lhs (stmt), loop))
continue;
if (can_put_in_inner_loop (loop->inner, stmt)
@@ -2298,7 +2297,7 @@ cannot_convert_bb_to_perfect_nest (basic_block bb, struct loop *loop)
right now. This test ensures that the statement comes
completely *after* the inner loop. */
if (!dominated_by_p (CDI_DOMINATORS,
- bb_for_stmt (stmt),
+ gimple_bb (stmt),
loop->inner->header))
return true;
}
@@ -2306,6 +2305,7 @@ cannot_convert_bb_to_perfect_nest (basic_block bb, struct loop *loop)
return false;
}
+
/* Return TRUE if LOOP is an imperfect nest that we can convert to a
perfect one. At the moment, we only handle imperfect nests of
depth 2, where all of the statements occur after the inner loop. */
@@ -2314,8 +2314,8 @@ static bool
can_convert_to_perfect_nest (struct loop *loop)
{
basic_block *bbs;
- tree phi;
size_t i;
+ gimple_stmt_iterator si;
/* Can't handle triply nested+ loops yet. */
if (!loop->inner || loop->inner->inner)
@@ -2329,8 +2329,10 @@ can_convert_to_perfect_nest (struct loop *loop)
/* We also need to make sure the loop exit only has simple copy phis in it,
otherwise we don't know how to transform it into a perfect nest. */
- for (phi = phi_nodes (single_exit (loop)->dest); phi; phi = PHI_CHAIN (phi))
- if (PHI_NUM_ARGS (phi) != 1)
+ for (si = gsi_start_phis (single_exit (loop)->dest);
+ !gsi_end_p (si);
+ gsi_next (&si))
+ if (gimple_phi_num_args (gsi_stmt (si)) != 1)
goto fail;
free (bbs);
@@ -2385,17 +2387,17 @@ perfect_nestify (struct loop *loop,
VEC(tree,heap) *loopivs)
{
basic_block *bbs;
- tree exit_condition;
- tree cond_stmt;
+ gimple exit_condition;
+ gimple cond_stmt;
basic_block preheaderbb, headerbb, bodybb, latchbb, olddest;
int i;
- block_stmt_iterator bsi, firstbsi;
+ gimple_stmt_iterator bsi, firstbsi;
bool insert_after;
edge e;
struct loop *newloop;
- tree phi;
+ gimple phi;
tree uboundvar;
- tree stmt;
+ gimple stmt;
tree oldivvar, ivvar, ivvarinced;
VEC(tree,heap) *phis = NULL;
htab_t replacements = NULL;
@@ -2406,8 +2408,9 @@ perfect_nestify (struct loop *loop,
headerbb = create_empty_bb (EXIT_BLOCK_PTR->prev_bb);
/* Push the exit phi nodes that we are moving. */
- for (phi = phi_nodes (olddest); phi; phi = PHI_CHAIN (phi))
+ for (bsi = gsi_start_phis (olddest); !gsi_end_p (bsi); gsi_next (&bsi))
{
+ phi = gsi_stmt (bsi);
VEC_reserve (tree, heap, phis, 2);
VEC_quick_push (tree, phis, PHI_RESULT (phi));
VEC_quick_push (tree, phis, PHI_ARG_DEF (phi, 0));
@@ -2415,8 +2418,8 @@ perfect_nestify (struct loop *loop,
e = redirect_edge_and_branch (single_succ_edge (preheaderbb), headerbb);
/* Remove the exit phis from the old basic block. */
- while (phi_nodes (olddest) != NULL)
- remove_phi_node (phi_nodes (olddest), NULL, false);
+ for (bsi = gsi_start_phis (olddest); !gsi_end_p (bsi); )
+ remove_phi_node (&bsi, false);
/* and add them back to the new basic block. */
while (VEC_length (tree, phis) != 0)
@@ -2434,13 +2437,10 @@ perfect_nestify (struct loop *loop,
bodybb = create_empty_bb (EXIT_BLOCK_PTR->prev_bb);
latchbb = create_empty_bb (EXIT_BLOCK_PTR->prev_bb);
make_edge (headerbb, bodybb, EDGE_FALLTHRU);
- cond_stmt = build3 (COND_EXPR, void_type_node,
- build2 (NE_EXPR, boolean_type_node,
- integer_one_node,
- integer_zero_node),
- NULL_TREE, NULL_TREE);
- bsi = bsi_start (bodybb);
- bsi_insert_after (&bsi, cond_stmt, BSI_NEW_STMT);
+ cond_stmt = gimple_build_cond (NE_EXPR, integer_one_node, integer_zero_node,
+ NULL_TREE, NULL_TREE);
+ bsi = gsi_start_bb (bodybb);
+ gsi_insert_after (&bsi, cond_stmt, GSI_NEW_STMT);
e = make_edge (bodybb, olddest, EDGE_FALSE_VALUE);
make_edge (bodybb, latchbb, EDGE_TRUE_VALUE);
make_edge (latchbb, headerbb, EDGE_FALLTHRU);
@@ -2474,19 +2474,16 @@ perfect_nestify (struct loop *loop,
exit_condition = get_loop_exit_condition (newloop);
uboundvar = create_tmp_var (integer_type_node, "uboundvar");
add_referenced_var (uboundvar);
- stmt = build_gimple_modify_stmt (uboundvar, VEC_index (tree, ubounds, 0));
+ stmt = gimple_build_assign (uboundvar, VEC_index (tree, ubounds, 0));
uboundvar = make_ssa_name (uboundvar, stmt);
- GIMPLE_STMT_OPERAND (stmt, 0) = uboundvar;
+ gimple_assign_set_lhs (stmt, uboundvar);
if (insert_after)
- bsi_insert_after (&bsi, stmt, BSI_SAME_STMT);
+ gsi_insert_after (&bsi, stmt, GSI_SAME_STMT);
else
- bsi_insert_before (&bsi, stmt, BSI_SAME_STMT);
+ gsi_insert_before (&bsi, stmt, GSI_SAME_STMT);
update_stmt (stmt);
- COND_EXPR_COND (exit_condition) = build2 (GE_EXPR,
- boolean_type_node,
- uboundvar,
- ivvarinced);
+ gimple_cond_set_condition (exit_condition, GE_EXPR, uboundvar, ivvarinced);
update_stmt (exit_condition);
replacements = htab_create_ggc (20, tree_map_hash,
tree_map_eq, NULL);
@@ -2494,10 +2491,10 @@ perfect_nestify (struct loop *loop,
/* Now move the statements, and replace the induction variable in the moved
statements with the correct loop induction variable. */
oldivvar = VEC_index (tree, loopivs, 0);
- firstbsi = bsi_start (bodybb);
+ firstbsi = gsi_start_bb (bodybb);
for (i = loop->num_nodes - 1; i >= 0 ; i--)
{
- block_stmt_iterator tobsi = bsi_last (bodybb);
+ gimple_stmt_iterator tobsi = gsi_last_bb (bodybb);
if (bbs[i]->loop_father == loop)
{
/* If this is true, we are *before* the inner loop.
@@ -2513,22 +2510,22 @@ perfect_nestify (struct loop *loop,
if (dominated_by_p (CDI_DOMINATORS, loop->inner->header, bbs[i]))
{
- block_stmt_iterator header_bsi
- = bsi_after_labels (loop->inner->header);
+ gimple_stmt_iterator header_bsi
+ = gsi_after_labels (loop->inner->header);
- for (bsi = bsi_start (bbs[i]); !bsi_end_p (bsi);)
+ for (bsi = gsi_start_bb (bbs[i]); !gsi_end_p (bsi);)
{
- tree stmt = bsi_stmt (bsi);
+ gimple stmt = gsi_stmt (bsi);
if (stmt == exit_condition
|| not_interesting_stmt (stmt)
|| stmt_is_bumper_for_loop (loop, stmt))
{
- bsi_next (&bsi);
+ gsi_next (&bsi);
continue;
}
- bsi_move_before (&bsi, &header_bsi);
+ gsi_move_before (&bsi, &header_bsi);
}
}
else
@@ -2536,16 +2533,17 @@ perfect_nestify (struct loop *loop,
/* Note that the bsi only needs to be explicitly incremented
when we don't move something, since it is automatically
incremented when we do. */
- for (bsi = bsi_start (bbs[i]); !bsi_end_p (bsi);)
+ for (bsi = gsi_start_bb (bbs[i]); !gsi_end_p (bsi);)
{
ssa_op_iter i;
- tree n, stmt = bsi_stmt (bsi);
+ tree n;
+ gimple stmt = gsi_stmt (bsi);
if (stmt == exit_condition
|| not_interesting_stmt (stmt)
|| stmt_is_bumper_for_loop (loop, stmt))
{
- bsi_next (&bsi);
+ gsi_next (&bsi);
continue;
}
@@ -2553,7 +2551,7 @@ perfect_nestify (struct loop *loop,
(loop, stmt, oldivvar, VEC_index (int, steps, 0), ivvar,
VEC_index (tree, lbounds, 0), replacements, &firstbsi);
- bsi_move_before (&bsi, &tobsi);
+ gsi_move_before (&bsi, &tobsi);
/* If the statement has any virtual operands, they may
need to be rewired because the original loop may
@@ -2793,7 +2791,7 @@ build_access_matrix (data_reference_p data_reference,
{
struct access_matrix *am = GGC_NEW (struct access_matrix);
unsigned i, ndim = DR_NUM_DIMENSIONS (data_reference);
- struct loop *loop = bb_for_stmt (DR_STMT (data_reference))->loop_father;
+ struct loop *loop = gimple_bb (DR_STMT (data_reference))->loop_father;
struct loop *loop_nest = get_loop (loop_nest_num);
unsigned nivs = loop_depth (loop) - loop_depth (loop_nest) + 1;
unsigned lambda_nb_columns;
diff --git a/gcc/lambda-mat.c b/gcc/lambda-mat.c
index 852f812f16a..36110a72103 100644
--- a/gcc/lambda-mat.c
+++ b/gcc/lambda-mat.c
@@ -24,6 +24,7 @@ along with GCC; see the file COPYING3. If not see
#include "tm.h"
#include "ggc.h"
#include "tree.h"
+#include "tree-flow.h"
#include "lambda.h"
static void lambda_matrix_get_column (lambda_matrix, int, int,
diff --git a/gcc/lambda-trans.c b/gcc/lambda-trans.c
index c5872d5cc37..e81a71cd53e 100644
--- a/gcc/lambda-trans.c
+++ b/gcc/lambda-trans.c
@@ -25,6 +25,7 @@ along with GCC; see the file COPYING3. If not see
#include "ggc.h"
#include "tree.h"
#include "target.h"
+#include "tree-flow.h"
#include "lambda.h"
/* Allocate a new transformation matrix. */
diff --git a/gcc/lambda.h b/gcc/lambda.h
index 40e8502973c..66fbac74bd5 100644
--- a/gcc/lambda.h
+++ b/gcc/lambda.h
@@ -209,10 +209,10 @@ lambda_loopnest gcc_loopnest_to_lambda_loopnest (struct loop *,
struct obstack *);
void lambda_loopnest_to_gcc_loopnest (struct loop *,
VEC(tree,heap) *, VEC(tree,heap) *,
- VEC(tree,heap) **,
+ VEC(gimple,heap) **,
lambda_loopnest, lambda_trans_matrix,
struct obstack *);
-void remove_iv (tree);
+void remove_iv (gimple);
static inline void lambda_vector_negate (lambda_vector, lambda_vector, int);
static inline void lambda_vector_mult_const (lambda_vector, lambda_vector, int, int);
diff --git a/gcc/langhooks-def.h b/gcc/langhooks-def.h
index dd4916caff6..4cab70b6149 100644
--- a/gcc/langhooks-def.h
+++ b/gcc/langhooks-def.h
@@ -73,7 +73,7 @@ extern tree lhd_callgraph_analyze_expr (tree *, int *);
/* Declarations for tree gimplification hooks. */
-extern int lhd_gimplify_expr (tree *, tree *, tree *);
+extern int lhd_gimplify_expr (tree *, gimple_seq *, gimple_seq *);
extern enum omp_clause_default_kind lhd_omp_predetermined_sharing (tree);
extern tree lhd_omp_assignment (tree, tree, tree);
struct gimplify_omp_ctx;
diff --git a/gcc/langhooks.c b/gcc/langhooks.c
index 3943f02b794..2285ac17f54 100644
--- a/gcc/langhooks.c
+++ b/gcc/langhooks.c
@@ -27,7 +27,7 @@ along with GCC; see the file COPYING3. If not see
#include "toplev.h"
#include "tree.h"
#include "tree-inline.h"
-#include "tree-gimple.h"
+#include "gimple.h"
#include "rtl.h"
#include "insn-config.h"
#include "integrate.h"
@@ -303,8 +303,9 @@ lhd_expr_size (const_tree exp)
/* lang_hooks.gimplify_expr re-writes *EXPR_P into GIMPLE form. */
int
-lhd_gimplify_expr (tree *expr_p ATTRIBUTE_UNUSED, tree *pre_p ATTRIBUTE_UNUSED,
- tree *post_p ATTRIBUTE_UNUSED)
+lhd_gimplify_expr (tree *expr_p ATTRIBUTE_UNUSED,
+ gimple_seq *pre_p ATTRIBUTE_UNUSED,
+ gimple_seq *post_p ATTRIBUTE_UNUSED)
{
return GS_UNHANDLED;
}
@@ -394,7 +395,9 @@ lhd_print_error_function (diagnostic_context *context, const char *file,
if (abstract_origin)
{
ao = BLOCK_ABSTRACT_ORIGIN (abstract_origin);
- while (TREE_CODE (ao) == BLOCK && BLOCK_ABSTRACT_ORIGIN (ao))
+ while (TREE_CODE (ao) == BLOCK
+ && BLOCK_ABSTRACT_ORIGIN (ao)
+ && BLOCK_ABSTRACT_ORIGIN (ao) != ao)
ao = BLOCK_ABSTRACT_ORIGIN (ao);
gcc_assert (TREE_CODE (ao) == FUNCTION_DECL);
fndecl = ao;
@@ -424,7 +427,9 @@ lhd_print_error_function (diagnostic_context *context, const char *file,
{
ao = BLOCK_ABSTRACT_ORIGIN (block);
- while (TREE_CODE (ao) == BLOCK && BLOCK_ABSTRACT_ORIGIN (ao))
+ while (TREE_CODE (ao) == BLOCK
+ && BLOCK_ABSTRACT_ORIGIN (ao)
+ && BLOCK_ABSTRACT_ORIGIN (ao) != ao)
ao = BLOCK_ABSTRACT_ORIGIN (ao);
if (TREE_CODE (ao) == FUNCTION_DECL)
@@ -523,7 +528,7 @@ lhd_omp_predetermined_sharing (tree decl ATTRIBUTE_UNUSED)
tree
lhd_omp_assignment (tree clause ATTRIBUTE_UNUSED, tree dst, tree src)
{
- return build_gimple_modify_stmt (dst, src);
+ return build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
}
/* Register language specific type size variables as potentially OpenMP
diff --git a/gcc/langhooks.h b/gcc/langhooks.h
index 1f64cf18d52..6a23a313f35 100644
--- a/gcc/langhooks.h
+++ b/gcc/langhooks.h
@@ -401,7 +401,7 @@ struct lang_hooks
/* Perform language-specific gimplification on the argument. Returns an
enum gimplify_status, though we can't see that type here. */
- int (*gimplify_expr) (tree *, tree *, tree *);
+ int (*gimplify_expr) (tree *, gimple_seq *, gimple_seq *);
/* Fold an OBJ_TYPE_REF expression to the address of a function.
KNOWN_TYPE carries the true type of the OBJ_TYPE_REF_OBJECT. */
diff --git a/gcc/lcm.c b/gcc/lcm.c
index 6471bb08ebf..c5c2cfc5621 100644
--- a/gcc/lcm.c
+++ b/gcc/lcm.c
@@ -350,13 +350,13 @@ compute_laterin (struct edge_list *edge_list, sbitmap *earliest,
static void
compute_insert_delete (struct edge_list *edge_list, sbitmap *antloc,
sbitmap *later, sbitmap *laterin, sbitmap *insert,
- sbitmap *delete)
+ sbitmap *del)
{
int x;
basic_block bb;
FOR_EACH_BB (bb)
- sbitmap_difference (delete[bb->index], antloc[bb->index],
+ sbitmap_difference (del[bb->index], antloc[bb->index],
laterin[bb->index]);
for (x = 0; x < NUM_EDGES (edge_list); x++)
@@ -377,7 +377,7 @@ compute_insert_delete (struct edge_list *edge_list, sbitmap *antloc,
struct edge_list *
pre_edge_lcm (int n_exprs, sbitmap *transp,
sbitmap *avloc, sbitmap *antloc, sbitmap *kill,
- sbitmap **insert, sbitmap **delete)
+ sbitmap **insert, sbitmap **del)
{
sbitmap *antin, *antout, *earliest;
sbitmap *avin, *avout;
@@ -450,8 +450,8 @@ pre_edge_lcm (int n_exprs, sbitmap *transp,
sbitmap_vector_free (earliest);
*insert = sbitmap_vector_alloc (num_edges, n_exprs);
- *delete = sbitmap_vector_alloc (last_basic_block, n_exprs);
- compute_insert_delete (edge_list, antloc, later, laterin, *insert, *delete);
+ *del = sbitmap_vector_alloc (last_basic_block, n_exprs);
+ compute_insert_delete (edge_list, antloc, later, laterin, *insert, *del);
sbitmap_vector_free (laterin);
sbitmap_vector_free (later);
@@ -460,7 +460,7 @@ pre_edge_lcm (int n_exprs, sbitmap *transp,
if (dump_file)
{
dump_sbitmap_vector (dump_file, "pre_insert_map", "", *insert, num_edges);
- dump_sbitmap_vector (dump_file, "pre_delete_map", "", *delete,
+ dump_sbitmap_vector (dump_file, "pre_delete_map", "", *del,
last_basic_block);
}
#endif
@@ -684,13 +684,13 @@ compute_nearerout (struct edge_list *edge_list, sbitmap *farthest,
static void
compute_rev_insert_delete (struct edge_list *edge_list, sbitmap *st_avloc,
sbitmap *nearer, sbitmap *nearerout,
- sbitmap *insert, sbitmap *delete)
+ sbitmap *insert, sbitmap *del)
{
int x;
basic_block bb;
FOR_EACH_BB (bb)
- sbitmap_difference (delete[bb->index], st_avloc[bb->index],
+ sbitmap_difference (del[bb->index], st_avloc[bb->index],
nearerout[bb->index]);
for (x = 0; x < NUM_EDGES (edge_list); x++)
@@ -711,7 +711,7 @@ compute_rev_insert_delete (struct edge_list *edge_list, sbitmap *st_avloc,
struct edge_list *
pre_edge_rev_lcm (int n_exprs, sbitmap *transp,
sbitmap *st_avloc, sbitmap *st_antloc, sbitmap *kill,
- sbitmap **insert, sbitmap **delete)
+ sbitmap **insert, sbitmap **del)
{
sbitmap *st_antin, *st_antout;
sbitmap *st_avout, *st_avin, *farthest;
@@ -790,9 +790,9 @@ pre_edge_rev_lcm (int n_exprs, sbitmap *transp,
sbitmap_vector_free (farthest);
*insert = sbitmap_vector_alloc (num_edges, n_exprs);
- *delete = sbitmap_vector_alloc (last_basic_block, n_exprs);
+ *del = sbitmap_vector_alloc (last_basic_block, n_exprs);
compute_rev_insert_delete (edge_list, st_avloc, nearer, nearerout,
- *insert, *delete);
+ *insert, *del);
sbitmap_vector_free (nearerout);
sbitmap_vector_free (nearer);
@@ -801,7 +801,7 @@ pre_edge_rev_lcm (int n_exprs, sbitmap *transp,
if (dump_file)
{
dump_sbitmap_vector (dump_file, "pre_insert_map", "", *insert, num_edges);
- dump_sbitmap_vector (dump_file, "pre_delete_map", "", *delete,
+ dump_sbitmap_vector (dump_file, "pre_delete_map", "", *del,
last_basic_block);
}
#endif
diff --git a/gcc/local-alloc.c b/gcc/local-alloc.c
index 13a5a8ab920..e7bbcdaa169 100644
--- a/gcc/local-alloc.c
+++ b/gcc/local-alloc.c
@@ -1988,11 +1988,11 @@ combine_regs (rtx usedreg, rtx setreg, int may_save_copy, int insn_number,
True if REG's reg class either contains or is contained in CLASS. */
static int
-reg_meets_class_p (int reg, enum reg_class class)
+reg_meets_class_p (int reg, enum reg_class rclass)
{
- enum reg_class rclass = reg_preferred_class (reg);
- return (reg_class_subset_p (rclass, class)
- || reg_class_subset_p (class, rclass));
+ enum reg_class rclass2 = reg_preferred_class (reg);
+ return (reg_class_subset_p (rclass2, rclass)
+ || reg_class_subset_p (rclass, rclass2));
}
/* Update the class of QTYNO assuming that REG is being tied to it. */
@@ -2143,7 +2143,7 @@ wipe_dead_reg (rtx reg, int output_p)
register is available. If not, return -1. */
static int
-find_free_reg (enum reg_class class, enum machine_mode mode, int qtyno,
+find_free_reg (enum reg_class rclass, enum machine_mode mode, int qtyno,
int accept_call_clobbered, int just_try_suggested,
int born_index, int dead_index)
{
@@ -2175,7 +2175,7 @@ find_free_reg (enum reg_class class, enum machine_mode mode, int qtyno,
for (ins = born_index; ins < dead_index; ins++)
IOR_HARD_REG_SET (used, regs_live_at[ins]);
- IOR_COMPL_HARD_REG_SET (used, reg_class_contents[(int) class]);
+ IOR_COMPL_HARD_REG_SET (used, reg_class_contents[(int) rclass]);
/* Don't use the frame pointer reg in local-alloc even if
we may omit the frame pointer, because if we do that and then we
@@ -2260,7 +2260,7 @@ find_free_reg (enum reg_class class, enum machine_mode mode, int qtyno,
{
/* Don't try the copy-suggested regs again. */
qty_phys_num_copy_sugg[qtyno] = 0;
- return find_free_reg (class, mode, qtyno, accept_call_clobbered, 1,
+ return find_free_reg (rclass, mode, qtyno, accept_call_clobbered, 1,
born_index, dead_index);
}
@@ -2278,7 +2278,7 @@ find_free_reg (enum reg_class class, enum machine_mode mode, int qtyno,
optimize_size ? qty[qtyno].n_calls_crossed
: qty[qtyno].freq_calls_crossed))
{
- i = find_free_reg (class, mode, qtyno, 1, 0, born_index, dead_index);
+ i = find_free_reg (rclass, mode, qtyno, 1, 0, born_index, dead_index);
if (i >= 0)
caller_save_needed = 1;
return i;
diff --git a/gcc/lower-subreg.c b/gcc/lower-subreg.c
index 57205b51e61..fd3b7fe971f 100644
--- a/gcc/lower-subreg.c
+++ b/gcc/lower-subreg.c
@@ -577,7 +577,7 @@ resolve_reg_notes (rtx insn)
pnote = &REG_NOTES (insn);
while (*pnote != NULL_RTX)
{
- bool delete = false;
+ bool del = false;
note = *pnote;
switch (REG_NOTE_KIND (note))
@@ -585,14 +585,14 @@ resolve_reg_notes (rtx insn)
case REG_DEAD:
case REG_UNUSED:
if (resolve_reg_p (XEXP (note, 0)))
- delete = true;
+ del = true;
break;
default:
break;
}
- if (delete)
+ if (del)
*pnote = XEXP (note, 1);
else
pnote = &XEXP (note, 1);
diff --git a/gcc/matrix-reorg.c b/gcc/matrix-reorg.c
index 33bb0b4e8f4..9ebbcde5608 100644
--- a/gcc/matrix-reorg.c
+++ b/gcc/matrix-reorg.c
@@ -107,9 +107,7 @@ along with GCC; see the file COPYING3. If not see
Both optimizations are described in the paper "Matrix flattening and
transposing in GCC" which was presented in GCC summit 2006.
- http://www.gccsummit.org/2006/2006-GCC-Summit-Proceedings.pdf
-
- */
+ http://www.gccsummit.org/2006/2006-GCC-Summit-Proceedings.pdf. */
#include "config.h"
#include "system.h"
@@ -145,8 +143,9 @@ along with GCC; see the file COPYING3. If not see
#include "tree-chrec.h"
#include "tree-scalar-evolution.h"
-/*
- We need to collect a lot of data from the original malloc,
+ /* FIXME tuples. */
+#if 0
+/* We need to collect a lot of data from the original malloc,
particularly as the gimplifier has converted:
orig_var = (struct_type *) malloc (x * sizeof (struct_type *));
@@ -430,7 +429,7 @@ may_flatten_matrices_1 (tree stmt)
switch (TREE_CODE (stmt))
{
case GIMPLE_MODIFY_STMT:
- t = GIMPLE_STMT_OPERAND (stmt, 1);
+ t = TREE_OPERAND (stmt, 1);
while (CONVERT_EXPR_P (t))
{
if (TREE_TYPE (t) && POINTER_TYPE_P (TREE_TYPE (t)))
@@ -775,7 +774,7 @@ analyze_matrix_allocation_site (struct matrix_info *mi, tree stmt,
{
if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT)
{
- tree rhs = GIMPLE_STMT_OPERAND (stmt, 1);
+ tree rhs = TREE_OPERAND (stmt, 1);
rhs = get_inner_of_cast_expr (rhs);
if (TREE_CODE (rhs) == SSA_NAME)
@@ -910,7 +909,7 @@ analyze_transpose (void **slot, void *data ATTRIBUTE_UNUSED)
for (i = 0; VEC_iterate (access_site_info_p, mi->access_l, i, acc_info);
i++)
{
- if (TREE_CODE (GIMPLE_STMT_OPERAND (acc_info->stmt, 1)) == POINTER_PLUS_EXPR
+ if (TREE_CODE (TREE_OPERAND (acc_info->stmt, 1)) == POINTER_PLUS_EXPR
&& acc_info->level < min_escape_l)
{
loop = loop_containing_stmt (acc_info->stmt);
@@ -930,7 +929,7 @@ analyze_transpose (void **slot, void *data ATTRIBUTE_UNUSED)
{
acc_info->iterated_by_inner_most_loop_p = 1;
mi->dim_hot_level[acc_info->level] +=
- bb_for_stmt (acc_info->stmt)->count;
+ gimple_bb (acc_info->stmt)->count;
}
}
@@ -952,7 +951,7 @@ get_index_from_offset (tree offset, tree def_stmt)
if (TREE_CODE (def_stmt) == PHI_NODE)
return NULL;
- expr = get_inner_of_cast_expr (GIMPLE_STMT_OPERAND (def_stmt, 1));
+ expr = get_inner_of_cast_expr (TREE_OPERAND (def_stmt, 1));
if (TREE_CODE (expr) == SSA_NAME)
return get_index_from_offset (offset, SSA_NAME_DEF_STMT (expr));
else if (TREE_CODE (expr) == MULT_EXPR)
@@ -980,9 +979,9 @@ update_type_size (struct matrix_info *mi, tree stmt, tree ssa_var,
/* Update type according to the type of the INDIRECT_REF expr. */
if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT
- && TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 0)) == INDIRECT_REF)
+ && TREE_CODE (TREE_OPERAND (stmt, 0)) == INDIRECT_REF)
{
- lhs = GIMPLE_STMT_OPERAND (stmt, 0);
+ lhs = TREE_OPERAND (stmt, 0);
gcc_assert (POINTER_TYPE_P
(TREE_TYPE (SSA_NAME_VAR (TREE_OPERAND (lhs, 0)))));
type_size =
@@ -1139,8 +1138,8 @@ analyze_accesses_for_modify_stmt (struct matrix_info *mi, tree ssa_var,
bool record_accesses)
{
- tree lhs = GIMPLE_STMT_OPERAND (use_stmt, 0);
- tree rhs = GIMPLE_STMT_OPERAND (use_stmt, 1);
+ tree lhs = TREE_OPERAND (use_stmt, 0);
+ tree rhs = TREE_OPERAND (use_stmt, 1);
struct ssa_acc_in_tree lhs_acc, rhs_acc;
memset (&lhs_acc, 0, sizeof (lhs_acc));
@@ -1376,7 +1375,7 @@ check_var_notmodified_p (tree * tp, int *walk_subtrees, void *data)
stmt = bsi_stmt (bsi);
if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT)
continue;
- if (GIMPLE_STMT_OPERAND (stmt, 0) == t)
+ if (TREE_OPERAND (stmt, 0) == t)
return stmt;
}
}
@@ -1425,7 +1424,7 @@ can_calculate_expr_before_stmt (tree expr, sbitmap visited)
return fold_build2 (TREE_CODE (expr), TREE_TYPE (expr), op1, op2);
return NULL_TREE;
case GIMPLE_MODIFY_STMT:
- return can_calculate_expr_before_stmt (GIMPLE_STMT_OPERAND (expr, 1),
+ return can_calculate_expr_before_stmt (TREE_OPERAND (expr, 1),
visited);
case PHI_NODE:
{
@@ -1588,9 +1587,9 @@ find_sites_in_func (bool record)
{
stmt = bsi_stmt (bsi);
if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT
- && TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 0)) == VAR_DECL)
+ && TREE_CODE (TREE_OPERAND (stmt, 0)) == VAR_DECL)
{
- tmpmi.decl = GIMPLE_STMT_OPERAND (stmt, 0);
+ tmpmi.decl = TREE_OPERAND (stmt, 0);
if ((mi = (struct matrix_info *) htab_find (matrices_to_reorg,
&tmpmi)))
{
@@ -1599,16 +1598,16 @@ find_sites_in_func (bool record)
}
}
if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT
- && TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 0)) == SSA_NAME
- && TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 1)) == VAR_DECL)
+ && TREE_CODE (TREE_OPERAND (stmt, 0)) == SSA_NAME
+ && TREE_CODE (TREE_OPERAND (stmt, 1)) == VAR_DECL)
{
- tmpmi.decl = GIMPLE_STMT_OPERAND (stmt, 1);
+ tmpmi.decl = TREE_OPERAND (stmt, 1);
if ((mi = (struct matrix_info *) htab_find (matrices_to_reorg,
&tmpmi)))
{
sbitmap_zero (visited_stmts_1);
analyze_matrix_accesses (mi,
- GIMPLE_STMT_OPERAND (stmt, 0), 0,
+ TREE_OPERAND (stmt, 0), 0,
false, visited_stmts_1, record);
}
}
@@ -1642,8 +1641,8 @@ record_all_accesses_in_func (void)
if (!ssa_var
|| TREE_CODE (SSA_NAME_DEF_STMT (ssa_var)) != GIMPLE_MODIFY_STMT)
continue;
- rhs = GIMPLE_STMT_OPERAND (SSA_NAME_DEF_STMT (ssa_var), 1);
- lhs = GIMPLE_STMT_OPERAND (SSA_NAME_DEF_STMT (ssa_var), 0);
+ rhs = TREE_OPERAND (SSA_NAME_DEF_STMT (ssa_var), 1);
+ lhs = TREE_OPERAND (SSA_NAME_DEF_STMT (ssa_var), 0);
if (TREE_CODE (rhs) != VAR_DECL && TREE_CODE (lhs) != VAR_DECL)
continue;
@@ -1741,7 +1740,7 @@ transform_access_sites (void **slot, void *data ATTRIBUTE_UNUSED)
}
if (acc_info->is_alloc)
{
- if (acc_info->level >= 0 && bb_for_stmt (acc_info->stmt))
+ if (acc_info->level >= 0 && gimple_bb (acc_info->stmt))
{
ssa_op_iter iter;
tree def;
@@ -1751,7 +1750,7 @@ transform_access_sites (void **slot, void *data ATTRIBUTE_UNUSED)
mark_sym_for_renaming (SSA_NAME_VAR (def));
bsi = bsi_for_stmt (stmt);
gcc_assert (TREE_CODE (acc_info->stmt) == GIMPLE_MODIFY_STMT);
- if (TREE_CODE (GIMPLE_STMT_OPERAND (acc_info->stmt, 0)) ==
+ if (TREE_CODE (TREE_OPERAND (acc_info->stmt, 0)) ==
SSA_NAME && acc_info->level < min_escape_l - 1)
{
imm_use_iterator imm_iter;
@@ -1759,7 +1758,7 @@ transform_access_sites (void **slot, void *data ATTRIBUTE_UNUSED)
tree use_stmt;
FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter,
- GIMPLE_STMT_OPERAND (acc_info->stmt,
+ TREE_OPERAND (acc_info->stmt,
0))
FOR_EACH_IMM_USE_ON_STMT (use_p, imm_iter)
{
@@ -1768,22 +1767,22 @@ transform_access_sites (void **slot, void *data ATTRIBUTE_UNUSED)
/* Emit convert statement to convert to type of use. */
conv =
fold_build1 (CONVERT_EXPR,
- TREE_TYPE (GIMPLE_STMT_OPERAND
+ TREE_TYPE (TREE_OPERAND
(acc_info->stmt, 0)),
- TREE_OPERAND (GIMPLE_STMT_OPERAND
+ TREE_OPERAND (TREE_OPERAND
(acc_info->stmt, 1), 0));
tmp =
create_tmp_var (TREE_TYPE
- (GIMPLE_STMT_OPERAND
+ (TREE_OPERAND
(acc_info->stmt, 0)), "new");
add_referenced_var (tmp);
stmts =
fold_build2 (GIMPLE_MODIFY_STMT,
- TREE_TYPE (GIMPLE_STMT_OPERAND
+ TREE_TYPE (TREE_OPERAND
(acc_info->stmt, 0)), tmp,
conv);
tmp = make_ssa_name (tmp, stmts);
- GIMPLE_STMT_OPERAND (stmts, 0) = tmp;
+ TREE_OPERAND (stmts, 0) = tmp;
bsi = bsi_for_stmt (acc_info->stmt);
bsi_insert_after (&bsi, stmts, BSI_SAME_STMT);
SET_USE (use_p, tmp);
@@ -1795,7 +1794,7 @@ transform_access_sites (void **slot, void *data ATTRIBUTE_UNUSED)
free (acc_info);
continue;
}
- orig = GIMPLE_STMT_OPERAND (acc_info->stmt, 1);
+ orig = TREE_OPERAND (acc_info->stmt, 1);
type = TREE_TYPE (orig);
if (TREE_CODE (orig) == INDIRECT_REF
&& acc_info->level < min_escape_l - 1)
@@ -1804,8 +1803,8 @@ transform_access_sites (void **slot, void *data ATTRIBUTE_UNUSED)
from "pointer to type" to "type". */
orig =
build1 (NOP_EXPR, TREE_TYPE (orig),
- GIMPLE_STMT_OPERAND (orig, 0));
- GIMPLE_STMT_OPERAND (acc_info->stmt, 1) = orig;
+ TREE_OPERAND (orig, 0));
+ TREE_OPERAND (acc_info->stmt, 1) = orig;
}
else if (TREE_CODE (orig) == POINTER_PLUS_EXPR
&& acc_info->level < (min_escape_l))
@@ -2095,7 +2094,7 @@ transform_allocation_sites (void **slot, void *data ATTRIBUTE_UNUSED)
true, BSI_SAME_STMT);
/* GLOBAL_HOLDING_THE_SIZE = DIM_SIZE. */
tmp = fold_build2 (GIMPLE_MODIFY_STMT, type, dim_var, dim_size);
- GIMPLE_STMT_OPERAND (tmp, 0) = dim_var;
+ TREE_OPERAND (tmp, 0) = dim_var;
mark_symbols_for_renaming (tmp);
bsi_insert_before (&bsi, tmp, BSI_SAME_STMT);
@@ -2104,7 +2103,7 @@ transform_allocation_sites (void **slot, void *data ATTRIBUTE_UNUSED)
update_ssa (TODO_update_ssa);
/* Replace the malloc size argument in the malloc of level 0 to be
the size of all the dimensions. */
- malloc_stmt = GIMPLE_STMT_OPERAND (call_stmt_0, 1);
+ malloc_stmt = TREE_OPERAND (call_stmt_0, 1);
c_node = cgraph_node (mi->allocation_function_decl);
old_size_0 = CALL_EXPR_ARG (malloc_stmt, 0);
tmp = force_gimple_operand_bsi (&bsi, mi->dimension_size[0], true,
@@ -2128,7 +2127,7 @@ transform_allocation_sites (void **slot, void *data ATTRIBUTE_UNUSED)
tree call;
tree call_stmt = mi->malloc_for_level[i];
- call = GIMPLE_STMT_OPERAND (call_stmt, 1);
+ call = TREE_OPERAND (call_stmt, 1);
gcc_assert (TREE_CODE (call) == CALL_EXPR);
e = cgraph_edge (c_node, call_stmt);
gcc_assert (e);
@@ -2138,7 +2137,7 @@ transform_allocation_sites (void **slot, void *data ATTRIBUTE_UNUSED)
bsi_remove (&bsi, true);
/* remove the type cast stmt. */
FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter,
- GIMPLE_STMT_OPERAND (call_stmt, 0))
+ TREE_OPERAND (call_stmt, 0))
{
use_stmt1 = use_stmt;
bsi = bsi_for_stmt (use_stmt);
@@ -2146,7 +2145,7 @@ transform_allocation_sites (void **slot, void *data ATTRIBUTE_UNUSED)
}
/* Remove the assignment of the allocated area. */
FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter,
- GIMPLE_STMT_OPERAND (use_stmt1, 0))
+ TREE_OPERAND (use_stmt1, 0))
{
bsi = bsi_for_stmt (use_stmt);
bsi_remove (&bsi, true);
@@ -2204,12 +2203,13 @@ dump_matrix_reorg_analysis (void **slot, void *data ATTRIBUTE_UNUSED)
return 1;
}
-
+#endif
/* Perform matrix flattening. */
static unsigned int
matrix_reorg (void)
{
+#if 0 /* FIXME tuples */
struct cgraph_node *node;
if (profile_info)
@@ -2233,7 +2233,7 @@ matrix_reorg (void)
current_function_decl = node->decl;
push_cfun (DECL_STRUCT_FUNCTION (node->decl));
bitmap_obstack_initialize (NULL);
- tree_register_cfg_hooks ();
+ gimple_register_cfg_hooks ();
if (!gimple_in_ssa_p (cfun))
{
@@ -2301,7 +2301,7 @@ matrix_reorg (void)
current_function_decl = node->decl;
push_cfun (DECL_STRUCT_FUNCTION (node->decl));
bitmap_obstack_initialize (NULL);
- tree_register_cfg_hooks ();
+ gimple_register_cfg_hooks ();
record_all_accesses_in_func ();
htab_traverse (matrices_to_reorg, transform_access_sites, NULL);
free_dominance_info (CDI_DOMINATORS);
@@ -2316,6 +2316,9 @@ matrix_reorg (void)
set_cfun (NULL);
matrices_to_reorg = NULL;
return 0;
+#else
+ gcc_unreachable ();
+#endif
}
@@ -2323,7 +2326,12 @@ matrix_reorg (void)
static bool
gate_matrix_reorg (void)
{
+ /* FIXME tuples */
+#if 0
return flag_ipa_matrix_reorg && flag_whole_program;
+#else
+ return false;
+#endif
}
struct simple_ipa_opt_pass pass_ipa_matrix_reorg =
@@ -2344,3 +2352,4 @@ struct simple_ipa_opt_pass pass_ipa_matrix_reorg =
TODO_dump_cgraph | TODO_dump_func /* todo_flags_finish */
}
};
+
diff --git a/gcc/mode-switching.c b/gcc/mode-switching.c
index 23269b815dd..e6fd61d4fda 100644
--- a/gcc/mode-switching.c
+++ b/gcc/mode-switching.c
@@ -585,7 +585,7 @@ optimize_mode_switching (void)
for (i = 0; i < max_num_modes; i++)
{
int current_mode[N_ENTITIES];
- sbitmap *delete;
+ sbitmap *del;
sbitmap *insert;
/* Set the anticipatable and computing arrays. */
@@ -612,7 +612,7 @@ optimize_mode_switching (void)
FOR_EACH_BB (bb)
sbitmap_not (kill[bb->index], transp[bb->index]);
edge_list = pre_edge_lcm (n_entities, transp, comp, antic,
- kill, &insert, &delete);
+ kill, &insert, &del);
for (j = n_entities - 1; j >= 0; j--)
{
@@ -663,7 +663,7 @@ optimize_mode_switching (void)
}
FOR_EACH_BB_REVERSE (bb)
- if (TEST_BIT (delete[bb->index], j))
+ if (TEST_BIT (del[bb->index], j))
{
make_preds_opaque (bb, j);
/* Cancel the 'deleted' mode set. */
@@ -671,7 +671,7 @@ optimize_mode_switching (void)
}
}
- sbitmap_vector_free (delete);
+ sbitmap_vector_free (del);
sbitmap_vector_free (insert);
clear_aux_for_edges ();
free_edge_list (edge_list);
diff --git a/gcc/objc/ChangeLog b/gcc/objc/ChangeLog
index f5869b3bca9..8fa3d3d4df1 100644
--- a/gcc/objc/ChangeLog
+++ b/gcc/objc/ChangeLog
@@ -1,3 +1,48 @@
+2008-07-28 Richard Guenther <rguenther@suse.de>
+
+ Merge from gimple-tuples-branch.
+
+ 2008-07-18 Aldy Hernandez <aldyh@redhat.com>
+
+ * Make-lang.in (objc-lang.o): Depend on GIMPLE_H.
+ (objc-act.o): Rename TREE_GIMPLE_H to GIMPLE_H.
+ * objc-act.h: Include gimple.h instead of tree-gimple.h.
+ * ipa-reference.c: Same.
+
+ 2007-11-10 Aldy Hernandez <aldyh@redhat.com>
+
+ * objc-act.c (objc_gimplify_expr): Change pre and post to sequences.
+ * objc-act.h (objc_gimplify_expr): Change prototype accordingly.
+
+2008-07-21 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
+
+ * objc-act.c: Fix comment typos.
+
+2008-07-18 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * objc-act.c (objc_start_class_interface,
+ objc_start_category_interface, objc_start_class_implementation,
+ objc_start_category_implementation, objc_build_struct,
+ generate_static_references, build_private_template,
+ lookup_category, objc_add_method, add_category,
+ add_instance_variable, objc_is_public, conforms_to_protocol,
+ start_class, continue_class, finish_class): Avoid C++ keywords.
+
+2008-07-14 Jason Merrill <jason@redhat.com>
+
+ PR objc++/36723
+ * objc-act.c (objc_build_constructor): Update C++ tweak.
+
+2007-07-14 Rafael Avila de Espindola <espindola@google.com>
+
+ * objc-act.c (synth_module_prologue): Use TREE_NO_WARNING instead
+ of DECL_IN_SYSTEM_HEADER.
+
+2008-07-11 Ian Lance Taylor <iant@google.com>
+
+ * objc-act.c (objc_is_reserved_word): Always check for RID_CLASS,
+ etc., not just when OBJCPLUS is defined.
+
2008-06-19 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* objc-act.c (setup_string_decl, objc_build_string_object,
diff --git a/gcc/objc/Make-lang.in b/gcc/objc/Make-lang.in
index 93a0042a860..c5de9d83c73 100644
--- a/gcc/objc/Make-lang.in
+++ b/gcc/objc/Make-lang.in
@@ -72,14 +72,14 @@ objc/objc-lang.o : objc/objc-lang.c \
$(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
$(C_TREE_H) $(DIAGNOSTIC_H) \
$(GGC_H) langhooks.h $(LANGHOOKS_DEF_H) $(C_COMMON_H) gtype-objc.h \
- c-objc-common.h objc/objc-act.h $(TREE_GIMPLE_H)
+ c-objc-common.h objc/objc-act.h $(GIMPLE_H)
objc/objc-act.o : objc/objc-act.c \
$(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) $(RTL_H) $(TM_P_H) \
$(EXPR_H) $(TARGET_H) $(C_TREE_H) $(DIAGNOSTIC_H) toplev.h $(FLAGS_H) \
objc/objc-act.h input.h $(FUNCTION_H) output.h debug.h langhooks.h \
$(LANGHOOKS_DEF_H) $(HASHTAB_H) $(C_PRAGMA_H) gt-objc-objc-act.h \
- $(TREE_GIMPLE_H)
+ $(GIMPLE_H)
objc.srcextra:
diff --git a/gcc/objc/objc-act.c b/gcc/objc/objc-act.c
index 4aef9a02017..5941fb69389 100644
--- a/gcc/objc/objc-act.c
+++ b/gcc/objc/objc-act.c
@@ -617,19 +617,19 @@ lookup_protocol_in_reflist (tree rproto_list, tree lproto)
}
void
-objc_start_class_interface (tree class, tree super_class, tree protos)
+objc_start_class_interface (tree klass, tree super_class, tree protos)
{
objc_interface_context
= objc_ivar_context
- = start_class (CLASS_INTERFACE_TYPE, class, super_class, protos);
+ = start_class (CLASS_INTERFACE_TYPE, klass, super_class, protos);
objc_public_flag = 0;
}
void
-objc_start_category_interface (tree class, tree categ, tree protos)
+objc_start_category_interface (tree klass, tree categ, tree protos)
{
objc_interface_context
- = start_class (CATEGORY_INTERFACE_TYPE, class, categ, protos);
+ = start_class (CATEGORY_INTERFACE_TYPE, klass, categ, protos);
objc_ivar_chain
= continue_class (objc_interface_context);
}
@@ -656,19 +656,19 @@ objc_finish_interface (void)
}
void
-objc_start_class_implementation (tree class, tree super_class)
+objc_start_class_implementation (tree klass, tree super_class)
{
objc_implementation_context
= objc_ivar_context
- = start_class (CLASS_IMPLEMENTATION_TYPE, class, super_class, NULL_TREE);
+ = start_class (CLASS_IMPLEMENTATION_TYPE, klass, super_class, NULL_TREE);
objc_public_flag = 0;
}
void
-objc_start_category_implementation (tree class, tree categ)
+objc_start_category_implementation (tree klass, tree categ)
{
objc_implementation_context
- = start_class (CATEGORY_IMPLEMENTATION_TYPE, class, categ, NULL_TREE);
+ = start_class (CATEGORY_IMPLEMENTATION_TYPE, klass, categ, NULL_TREE);
objc_ivar_chain
= continue_class (objc_implementation_context);
}
@@ -760,12 +760,9 @@ objc_is_reserved_word (tree ident)
unsigned char code = C_RID_CODE (ident);
return (OBJC_IS_AT_KEYWORD (code)
-#ifdef OBJCPLUS
|| code == RID_CLASS || code == RID_PUBLIC
|| code == RID_PROTECTED || code == RID_PRIVATE
- || code == RID_TRY || code == RID_THROW || code == RID_CATCH
-#endif
- );
+ || code == RID_TRY || code == RID_THROW || code == RID_CATCH);
}
/* Return true if TYPE is 'id'. */
@@ -782,13 +779,13 @@ objc_is_class_id (tree type)
return OBJC_TYPE_NAME (type) == objc_class_id;
}
-/* Construct a C struct with same name as CLASS, a base struct with tag
+/* Construct a C struct with same name as KLASS, a base struct with tag
SUPER_NAME (if any), and FIELDS indicated. */
static tree
-objc_build_struct (tree class, tree fields, tree super_name)
+objc_build_struct (tree klass, tree fields, tree super_name)
{
- tree name = CLASS_NAME (class);
+ tree name = CLASS_NAME (klass);
tree s = start_struct (RECORD_TYPE, name);
tree super = (super_name ? xref_tag (RECORD_TYPE, super_name) : NULL_TREE);
tree t, objc_info = NULL_TREE;
@@ -804,7 +801,7 @@ objc_build_struct (tree class, tree fields, tree super_name)
&& TREE_CODE (TREE_CHAIN (field)) == FIELD_DECL)
field = TREE_CHAIN (field);
- /* For ObjC ABI purposes, the "packed" size of a base class is the
+ /* For ObjC ABI purposes, the "packed" size of a base class is
the sum of the offset and the size (in bits) of the last field
in the class. */
DECL_SIZE (base)
@@ -848,7 +845,7 @@ objc_build_struct (tree class, tree fields, tree super_name)
/* Point the struct at its related Objective-C class. */
INIT_TYPE_OBJC_INFO (s);
- TYPE_OBJC_INTERFACE (s) = class;
+ TYPE_OBJC_INTERFACE (s) = klass;
s = finish_struct (s, fields, NULL_TREE);
@@ -857,14 +854,14 @@ objc_build_struct (tree class, tree fields, tree super_name)
{
TYPE_OBJC_INFO (t) = TREE_VALUE (objc_info);
/* Replace the IDENTIFIER_NODE with an actual @interface. */
- TYPE_OBJC_INTERFACE (t) = class;
+ TYPE_OBJC_INTERFACE (t) = klass;
}
/* Use TYPE_BINFO structures to point at the super class, if any. */
objc_xref_basetypes (s, super);
/* Mark this struct as a class template. */
- CLASS_STATIC_TEMPLATE (class) = s;
+ CLASS_STATIC_TEMPLATE (klass) = s;
return s;
}
@@ -1528,7 +1525,7 @@ synth_module_prologue (void)
const struct gcc_debug_hooks *const save_hooks = debug_hooks;
/* Suppress outputting debug symbols, because
- dbxout_init hasn'r been called yet. */
+ dbxout_init hasn't been called yet. */
write_symbols = NO_DEBUG;
debug_hooks = &do_nothing_debug_hooks;
@@ -1555,11 +1552,11 @@ synth_module_prologue (void)
type = lang_hooks.decls.pushdecl (build_decl (TYPE_DECL,
objc_object_name,
objc_object_type));
- DECL_IN_SYSTEM_HEADER (type) = 1;
+ TREE_NO_WARNING (type) = 1;
type = lang_hooks.decls.pushdecl (build_decl (TYPE_DECL,
objc_class_name,
objc_class_type));
- DECL_IN_SYSTEM_HEADER (type) = 1;
+ TREE_NO_WARNING (type) = 1;
/* Forward-declare '@interface Protocol'. */
@@ -2031,8 +2028,7 @@ objc_build_constructor (tree type, tree elts)
/* Adjust for impedance mismatch. We should figure out how to build
CONSTRUCTORs that consistently please both the C and C++ gods. */
if (!TREE_PURPOSE (elts))
- TREE_TYPE (constructor) = NULL_TREE;
- TREE_HAS_CONSTRUCTOR (constructor) = 1;
+ TREE_TYPE (constructor) = init_list_type_node;
#endif
return constructor;
@@ -2422,7 +2418,7 @@ static void
generate_static_references (void)
{
tree decls = NULL_TREE, expr = NULL_TREE;
- tree class_name, class, decl, initlist;
+ tree class_name, klass, decl, initlist;
tree cl_chain, in_chain, type
= build_array_type (build_pointer_type (void_type_node), NULL_TREE);
int num_inst, num_class;
@@ -2441,8 +2437,8 @@ generate_static_references (void)
decl = start_var_decl (type, buf);
/* Output {class_name, ...}. */
- class = TREE_VALUE (cl_chain);
- class_name = get_objc_string_decl (OBJC_TYPE_NAME (class), class_names);
+ klass = TREE_VALUE (cl_chain);
+ class_name = get_objc_string_decl (OBJC_TYPE_NAME (klass), class_names);
initlist = build_tree_list (NULL_TREE,
build_unary_op (ADDR_EXPR, class_name, 1));
@@ -4106,13 +4102,13 @@ build_objc_exception_stuff (void)
}; */
static void
-build_private_template (tree class)
+build_private_template (tree klass)
{
- if (!CLASS_STATIC_TEMPLATE (class))
+ if (!CLASS_STATIC_TEMPLATE (klass))
{
- tree record = objc_build_struct (class,
- get_class_ivars (class, false),
- CLASS_SUPER_NAME (class));
+ tree record = objc_build_struct (klass,
+ get_class_ivars (klass, false),
+ CLASS_SUPER_NAME (klass));
/* Set the TREE_USED bit for this struct, so that stab generator
can emit stabs for this struct type. */
@@ -5650,9 +5646,9 @@ build_shared_structure_initializer (tree type, tree isa, tree super,
/* Retrieve category interface CAT_NAME (if any) associated with CLASS. */
static inline tree
-lookup_category (tree class, tree cat_name)
+lookup_category (tree klass, tree cat_name)
{
- tree category = CLASS_CATEGORY_LIST (class);
+ tree category = CLASS_CATEGORY_LIST (klass);
while (category && CLASS_SUPER_NAME (category) != cat_name)
category = CLASS_CATEGORY_LIST (category);
@@ -6915,24 +6911,24 @@ add_method_to_hash_list (hash *hash_list, tree method)
}
static tree
-objc_add_method (tree class, tree method, int is_class)
+objc_add_method (tree klass, tree method, int is_class)
{
tree mth;
if (!(mth = lookup_method (is_class
- ? CLASS_CLS_METHODS (class)
- : CLASS_NST_METHODS (class), method)))
+ ? CLASS_CLS_METHODS (klass)
+ : CLASS_NST_METHODS (klass), method)))
{
/* put method on list in reverse order */
if (is_class)
{
- TREE_CHAIN (method) = CLASS_CLS_METHODS (class);
- CLASS_CLS_METHODS (class) = method;
+ TREE_CHAIN (method) = CLASS_CLS_METHODS (klass);
+ CLASS_CLS_METHODS (klass) = method;
}
else
{
- TREE_CHAIN (method) = CLASS_NST_METHODS (class);
- CLASS_NST_METHODS (class) = method;
+ TREE_CHAIN (method) = CLASS_NST_METHODS (klass);
+ CLASS_NST_METHODS (klass) = method;
}
}
else
@@ -6942,8 +6938,8 @@ objc_add_method (tree class, tree method, int is_class)
and/or return types. We do not do this for @implementations, because
C/C++ will do it for us (i.e., there will be duplicate function
definition errors). */
- if ((TREE_CODE (class) == CLASS_INTERFACE_TYPE
- || TREE_CODE (class) == CATEGORY_INTERFACE_TYPE)
+ if ((TREE_CODE (klass) == CLASS_INTERFACE_TYPE
+ || TREE_CODE (klass) == CATEGORY_INTERFACE_TYPE)
&& !comp_proto_with_proto (method, mth, 1))
error ("duplicate declaration of method %<%c%s%>",
is_class ? '+' : '-',
@@ -6961,12 +6957,12 @@ objc_add_method (tree class, tree method, int is_class)
instance methods listed in @protocol declarations to
the class hash table, on the assumption that @protocols
may be adopted by root classes or categories. */
- if (TREE_CODE (class) == CATEGORY_INTERFACE_TYPE
- || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
- class = lookup_interface (CLASS_NAME (class));
+ if (TREE_CODE (klass) == CATEGORY_INTERFACE_TYPE
+ || TREE_CODE (klass) == CATEGORY_IMPLEMENTATION_TYPE)
+ klass = lookup_interface (CLASS_NAME (klass));
- if (TREE_CODE (class) == PROTOCOL_INTERFACE_TYPE
- || !CLASS_SUPER_NAME (class))
+ if (TREE_CODE (klass) == PROTOCOL_INTERFACE_TYPE
+ || !CLASS_SUPER_NAME (klass))
add_method_to_hash_list (cls_method_hash_list, method);
}
@@ -6999,31 +6995,31 @@ add_class (tree class_name, tree name)
}
static void
-add_category (tree class, tree category)
+add_category (tree klass, tree category)
{
/* Put categories on list in reverse order. */
- tree cat = lookup_category (class, CLASS_SUPER_NAME (category));
+ tree cat = lookup_category (klass, CLASS_SUPER_NAME (category));
if (cat)
{
warning (0, "duplicate interface declaration for category %<%s(%s)%>",
- IDENTIFIER_POINTER (CLASS_NAME (class)),
+ IDENTIFIER_POINTER (CLASS_NAME (klass)),
IDENTIFIER_POINTER (CLASS_SUPER_NAME (category)));
}
else
{
- CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (class);
- CLASS_CATEGORY_LIST (class) = category;
+ CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (klass);
+ CLASS_CATEGORY_LIST (klass) = category;
}
}
/* Called after parsing each instance variable declaration. Necessary to
preserve typedefs and implement public/private...
- PUBLIC is 1 for public, 0 for protected, and 2 for private. */
+ VISIBILITY is 1 for public, 0 for protected, and 2 for private. */
static tree
-add_instance_variable (tree class, int public, tree field_decl)
+add_instance_variable (tree klass, int visibility, tree field_decl)
{
tree field_type = TREE_TYPE (field_decl);
const char *ivar_name = DECL_NAME (field_decl)
@@ -7036,7 +7032,7 @@ add_instance_variable (tree class, int public, tree field_decl)
error ("illegal reference type specified for instance variable %qs",
ivar_name);
/* Return class as is without adding this ivar. */
- return class;
+ return klass;
}
#endif
@@ -7046,7 +7042,7 @@ add_instance_variable (tree class, int public, tree field_decl)
{
error ("instance variable %qs has unknown size", ivar_name);
/* Return class as is without adding this ivar. */
- return class;
+ return klass;
}
#ifdef OBJCPLUS
@@ -7092,7 +7088,7 @@ add_instance_variable (tree class, int public, tree field_decl)
"for instance variable %qs",
type_name, ivar_name);
/* Return class as is without adding this ivar. */
- return class;
+ return klass;
}
/* User-defined constructors and destructors are not known to Obj-C
@@ -7113,7 +7109,7 @@ add_instance_variable (tree class, int public, tree field_decl)
#endif
/* Overload the public attribute, it is not used for FIELD_DECLs. */
- switch (public)
+ switch (visibility)
{
case 0:
TREE_PUBLIC (field_decl) = 0;
@@ -7135,9 +7131,9 @@ add_instance_variable (tree class, int public, tree field_decl)
}
- CLASS_RAW_IVARS (class) = chainon (CLASS_RAW_IVARS (class), field_decl);
+ CLASS_RAW_IVARS (klass) = chainon (CLASS_RAW_IVARS (klass), field_decl);
- return class;
+ return klass;
}
static tree
@@ -7180,16 +7176,16 @@ objc_is_public (tree expr, tree identifier)
{
if (TYPE_HAS_OBJC_INFO (basetype) && TYPE_OBJC_INTERFACE (basetype))
{
- tree class = lookup_interface (OBJC_TYPE_NAME (basetype));
+ tree klass = lookup_interface (OBJC_TYPE_NAME (basetype));
- if (!class)
+ if (!klass)
{
error ("cannot find interface declaration for %qs",
IDENTIFIER_POINTER (OBJC_TYPE_NAME (basetype)));
return 0;
}
- if ((decl = is_ivar (get_class_ivars (class, true), identifier)))
+ if ((decl = is_ivar (get_class_ivars (klass, true), identifier)))
{
if (TREE_PUBLIC (decl))
return 1;
@@ -7210,13 +7206,13 @@ objc_is_public (tree expr, tree identifier)
if (basetype == curtype
|| DERIVED_FROM_P (basetype, curtype))
{
- int private = is_private (decl);
+ int priv = is_private (decl);
- if (private)
+ if (priv)
error ("instance variable %qs is declared private",
IDENTIFIER_POINTER (DECL_NAME (decl)));
- return !private;
+ return !priv;
}
}
@@ -7276,21 +7272,21 @@ check_methods (tree chain, tree list, int mtype)
return first;
}
-/* Check if CLASS, or its superclasses, explicitly conforms to PROTOCOL. */
+/* Check if KLASS, or its superclasses, explicitly conforms to PROTOCOL. */
static int
-conforms_to_protocol (tree class, tree protocol)
+conforms_to_protocol (tree klass, tree protocol)
{
if (TREE_CODE (protocol) == PROTOCOL_INTERFACE_TYPE)
{
- tree p = CLASS_PROTOCOL_LIST (class);
+ tree p = CLASS_PROTOCOL_LIST (klass);
while (p && TREE_VALUE (p) != protocol)
p = TREE_CHAIN (p);
if (!p)
{
- tree super = (CLASS_SUPER_NAME (class)
- ? lookup_interface (CLASS_SUPER_NAME (class))
+ tree super = (CLASS_SUPER_NAME (klass)
+ ? lookup_interface (CLASS_SUPER_NAME (klass))
: NULL_TREE);
int tmp = super ? conforms_to_protocol (super, protocol) : 0;
if (!tmp)
@@ -7444,7 +7440,7 @@ static tree
start_class (enum tree_code code, tree class_name, tree super_name,
tree protocol_list)
{
- tree class, decl;
+ tree klass, decl;
#ifdef OBJCPLUS
if (current_namespace != global_namespace) {
@@ -7460,8 +7456,8 @@ start_class (enum tree_code code, tree class_name, tree super_name,
objc_implementation_context = NULL_TREE;
}
- class = make_node (code);
- TYPE_LANG_SLOT_1 (class) = make_tree_vec (CLASS_LANG_SLOT_ELTS);
+ klass = make_node (code);
+ TYPE_LANG_SLOT_1 (klass) = make_tree_vec (CLASS_LANG_SLOT_ELTS);
/* Check for existence of the super class, if one was specified. Note
that we must have seen an @interface, not just a @class. If we
@@ -7482,9 +7478,9 @@ start_class (enum tree_code code, tree class_name, tree super_name,
super_name = super;
}
- CLASS_NAME (class) = class_name;
- CLASS_SUPER_NAME (class) = super_name;
- CLASS_CLS_METHODS (class) = NULL_TREE;
+ CLASS_NAME (klass) = class_name;
+ CLASS_SUPER_NAME (klass) = super_name;
+ CLASS_CLS_METHODS (klass) = NULL_TREE;
if (! objc_is_class_name (class_name)
&& (decl = lookup_name (class_name)))
@@ -7514,7 +7510,7 @@ start_class (enum tree_code code, tree class_name, tree super_name,
/* Reset for multiple classes per file. */
method_slot = 0;
- objc_implementation_context = class;
+ objc_implementation_context = klass;
/* Lookup the interface for this implementation. */
@@ -7557,10 +7553,10 @@ start_class (enum tree_code code, tree class_name, tree super_name,
#endif
IDENTIFIER_POINTER (class_name));
else
- add_class (class, class_name);
+ add_class (klass, class_name);
if (protocol_list)
- CLASS_PROTOCOL_LIST (class)
+ CLASS_PROTOCOL_LIST (klass)
= lookup_and_install_protocols (protocol_list);
}
@@ -7579,10 +7575,10 @@ start_class (enum tree_code code, tree class_name, tree super_name,
exit (FATAL_EXIT_CODE);
}
else
- add_category (class_category_is_assoc_with, class);
+ add_category (class_category_is_assoc_with, klass);
if (protocol_list)
- CLASS_PROTOCOL_LIST (class)
+ CLASS_PROTOCOL_LIST (klass)
= lookup_and_install_protocols (protocol_list);
}
@@ -7591,7 +7587,7 @@ start_class (enum tree_code code, tree class_name, tree super_name,
/* Reset for multiple classes per file. */
method_slot = 0;
- objc_implementation_context = class;
+ objc_implementation_context = klass;
/* For a category, class_name is really the name of the class that
the following set of methods will be associated with. We must
@@ -7604,21 +7600,21 @@ start_class (enum tree_code code, tree class_name, tree super_name,
exit (FATAL_EXIT_CODE);
}
}
- return class;
+ return klass;
}
static tree
-continue_class (tree class)
+continue_class (tree klass)
{
- if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
- || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
+ if (TREE_CODE (klass) == CLASS_IMPLEMENTATION_TYPE
+ || TREE_CODE (klass) == CATEGORY_IMPLEMENTATION_TYPE)
{
struct imp_entry *imp_entry;
/* Check consistency of the instance variables. */
- if (CLASS_RAW_IVARS (class))
- check_ivars (implementation_template, class);
+ if (CLASS_RAW_IVARS (klass))
+ check_ivars (implementation_template, klass);
/* code generation */
@@ -7633,7 +7629,7 @@ continue_class (tree class)
imp_entry = (struct imp_entry *) ggc_alloc (sizeof (struct imp_entry));
imp_entry->next = imp_list;
- imp_entry->imp_context = class;
+ imp_entry->imp_context = klass;
imp_entry->imp_template = implementation_template;
synth_forward_declarations ();
@@ -7643,7 +7639,7 @@ continue_class (tree class)
/* Append to front and increment count. */
imp_list = imp_entry;
- if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
+ if (TREE_CODE (klass) == CLASS_IMPLEMENTATION_TYPE)
imp_count++;
else
cat_count++;
@@ -7655,13 +7651,13 @@ continue_class (tree class)
return get_class_ivars (implementation_template, true);
}
- else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
+ else if (TREE_CODE (klass) == CLASS_INTERFACE_TYPE)
{
#ifdef OBJCPLUS
push_lang_context (lang_name_c);
#endif /* OBJCPLUS */
- build_private_template (class);
+ build_private_template (klass);
#ifdef OBJCPLUS
pop_lang_context ();
@@ -7677,9 +7673,9 @@ continue_class (tree class)
/* This is called once we see the "@end" in an interface/implementation. */
static void
-finish_class (tree class)
+finish_class (tree klass)
{
- if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
+ if (TREE_CODE (klass) == CLASS_IMPLEMENTATION_TYPE)
{
/* All code generation is done in finish_objc. */
@@ -7698,9 +7694,9 @@ finish_class (tree class)
}
}
- else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
+ else if (TREE_CODE (klass) == CATEGORY_IMPLEMENTATION_TYPE)
{
- tree category = lookup_category (implementation_template, CLASS_SUPER_NAME (class));
+ tree category = lookup_category (implementation_template, CLASS_SUPER_NAME (klass));
if (category)
{
@@ -9480,7 +9476,7 @@ objc_rewrite_function_call (tree function, tree params)
of its cousins). */
enum gimplify_status
-objc_gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p)
+objc_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
{
enum gimplify_status r0, r1;
if (TREE_CODE (*expr_p) == OBJ_TYPE_REF
diff --git a/gcc/objc/objc-act.h b/gcc/objc/objc-act.h
index e4b8a93bf39..741401d8356 100644
--- a/gcc/objc/objc-act.h
+++ b/gcc/objc/objc-act.h
@@ -23,7 +23,7 @@ along with GCC; see the file COPYING3. If not see
#define GCC_OBJC_ACT_H
/* For enum gimplify_status */
-#include "tree-gimple.h"
+#include "gimple.h"
/*** Language hooks ***/
@@ -32,7 +32,7 @@ const char *objc_printable_name (tree, int);
tree objc_get_callee_fndecl (const_tree);
void objc_finish_file (void);
tree objc_fold_obj_type_ref (tree, tree);
-enum gimplify_status objc_gimplify_expr (tree *, tree *, tree *);
+enum gimplify_status objc_gimplify_expr (tree *, gimple_seq *, gimple_seq *);
/* NB: The remaining public functions are prototyped in c-common.h, for the
benefit of stub-objc.c and objc-act.c. */
diff --git a/gcc/objcp/Make-lang.in b/gcc/objcp/Make-lang.in
index 695df4d2f61..fb7cffee234 100644
--- a/gcc/objcp/Make-lang.in
+++ b/gcc/objcp/Make-lang.in
@@ -72,12 +72,12 @@ cc1objplus$(exeext): $(OBJCXX_OBJS) cc1objplus-checksum.o $(BACKEND) $(LIBDEPS)
objcp/objcp-lang.o : objcp/objcp-lang.c \
$(CXX_TREE_H) $(TM_H) toplev.h debug.h langhooks.h objc/objc-act.h \
$(LANGHOOKS_DEF_H) $(C_COMMON_H) gtype-objcp.h \
- $(DIAGNOSTIC_H) cp/cp-objcp-common.h $(TREE_GIMPLE_H)
+ $(DIAGNOSTIC_H) cp/cp-objcp-common.h $(GIMPLE_H)
objcp/objcp-decl.o : objcp/objcp-decl.c \
$(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) $(C_TREE_H) \
toplev.h $(GGC_H) $(C_PRAGMA_H) input.h $(FLAGS_H) output.h \
- objc/objc-act.h objcp/objcp-decl.h $(TREE_GIMPLE_H) $(EXPR_H) $(TARGET_H)
+ objc/objc-act.h objcp/objcp-decl.h $(GIMPLE_H) $(EXPR_H) $(TARGET_H)
# The following must be an explicit rule; please keep in sync with the implicit
# one in Makefile.in.
@@ -86,7 +86,7 @@ objcp/objcp-act.o : objc/objc-act.c \
$(EXPR_H) $(TARGET_H) $(CXX_TREE_H) $(DIAGNOSTIC_H) toplev.h $(FLAGS_H) \
objc/objc-act.h input.h $(FUNCTION_H) output.h debug.h langhooks.h \
objcp/objcp-decl.h $(LANGHOOKS_DEF_H) $(HASHTAB_H) gt-objc-objc-act.h \
- $(TREE_GIMPLE_H)
+ $(GIMPLE_H)
$(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION)
po-generated:
diff --git a/gcc/omp-low.c b/gcc/omp-low.c
index e5680077bd0..cda05a449ca 100644
--- a/gcc/omp-low.c
+++ b/gcc/omp-low.c
@@ -27,7 +27,8 @@ along with GCC; see the file COPYING3. If not see
#include "tm.h"
#include "tree.h"
#include "rtl.h"
-#include "tree-gimple.h"
+#include "gimple.h"
+#include "tree-iterator.h"
#include "tree-inline.h"
#include "langhooks.h"
#include "diagnostic.h"
@@ -44,6 +45,7 @@ along with GCC; see the file COPYING3. If not see
#include "optabs.h"
#include "cfgloop.h"
+
/* Lowering of OpenMP parallel and workshare constructs proceeds in two
phases. The first phase scans the function looking for OMP statements
and then for variables that must be replaced to satisfy data sharing
@@ -68,7 +70,7 @@ typedef struct omp_context
/* The tree of contexts corresponding to the encountered constructs. */
struct omp_context *outer;
- tree stmt;
+ gimple stmt;
/* Map variables to fields in a structure that allows communication
between sending and receiving threads. */
@@ -114,7 +116,8 @@ struct omp_for_data_loop
struct omp_for_data
{
struct omp_for_data_loop loop;
- tree chunk_size, for_stmt;
+ tree chunk_size;
+ gimple for_stmt;
tree pre, iter_type;
int collapse;
bool have_nowait, have_ordered;
@@ -128,8 +131,33 @@ static int taskreg_nesting_level;
struct omp_region *root_omp_region;
static bitmap task_shared_vars;
-static void scan_omp (tree *, omp_context *);
-static void lower_omp (tree *, omp_context *);
+static void scan_omp (gimple_seq, omp_context *);
+static tree scan_omp_1_op (tree *, int *, void *);
+
+#define WALK_SUBSTMTS \
+ case GIMPLE_BIND: \
+ case GIMPLE_TRY: \
+ case GIMPLE_CATCH: \
+ case GIMPLE_EH_FILTER: \
+ /* The sub-statements for these should be walked. */ \
+ *handled_ops_p = false; \
+ break;
+
+/* Convenience function for calling scan_omp_1_op on tree operands. */
+
+static inline tree
+scan_omp_op (tree *tp, omp_context *ctx)
+{
+ struct walk_stmt_info wi;
+
+ memset (&wi, 0, sizeof (wi));
+ wi.info = ctx;
+ wi.want_locations = true;
+
+ return walk_tree (tp, scan_omp_1_op, &wi, NULL);
+}
+
+static void lower_omp (gimple_seq, omp_context *);
static tree lookup_decl_in_outer_ctx (tree, omp_context *);
static tree maybe_lookup_decl_in_outer_ctx (tree, omp_context *);
@@ -150,7 +178,7 @@ find_omp_clause (tree clauses, enum tree_code kind)
static inline bool
is_parallel_ctx (omp_context *ctx)
{
- return TREE_CODE (ctx->stmt) == OMP_PARALLEL;
+ return gimple_code (ctx->stmt) == GIMPLE_OMP_PARALLEL;
}
@@ -159,7 +187,7 @@ is_parallel_ctx (omp_context *ctx)
static inline bool
is_task_ctx (omp_context *ctx)
{
- return TREE_CODE (ctx->stmt) == OMP_TASK;
+ return gimple_code (ctx->stmt) == GIMPLE_OMP_TASK;
}
@@ -168,8 +196,8 @@ is_task_ctx (omp_context *ctx)
static inline bool
is_taskreg_ctx (omp_context *ctx)
{
- return TREE_CODE (ctx->stmt) == OMP_PARALLEL
- || TREE_CODE (ctx->stmt) == OMP_TASK;
+ return gimple_code (ctx->stmt) == GIMPLE_OMP_PARALLEL
+ || gimple_code (ctx->stmt) == GIMPLE_OMP_TASK;
}
@@ -186,7 +214,7 @@ is_combined_parallel (struct omp_region *region)
them into *FD. */
static void
-extract_omp_for_data (tree for_stmt, struct omp_for_data *fd,
+extract_omp_for_data (gimple for_stmt, struct omp_for_data *fd,
struct omp_for_data_loop *loops)
{
tree t, var, *collapse_iter, *collapse_count;
@@ -197,7 +225,7 @@ extract_omp_for_data (tree for_stmt, struct omp_for_data *fd,
fd->for_stmt = for_stmt;
fd->pre = NULL;
- fd->collapse = TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt));
+ fd->collapse = gimple_omp_for_collapse (for_stmt);
if (fd->collapse > 1)
fd->loops = loops;
else
@@ -209,7 +237,7 @@ extract_omp_for_data (tree for_stmt, struct omp_for_data *fd,
collapse_iter = NULL;
collapse_count = NULL;
- for (t = OMP_FOR_CLAUSES (for_stmt); t ; t = OMP_CLAUSE_CHAIN (t))
+ for (t = gimple_omp_for_clauses (for_stmt); t ; t = OMP_CLAUSE_CHAIN (t))
switch (OMP_CLAUSE_CODE (t))
{
case OMP_CLAUSE_NOWAIT:
@@ -264,19 +292,16 @@ extract_omp_for_data (tree for_stmt, struct omp_for_data *fd,
else
loop = &dummy_loop;
- t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
- gcc_assert (TREE_CODE (t) == GIMPLE_MODIFY_STMT);
- loop->v = GIMPLE_STMT_OPERAND (t, 0);
+
+ loop->v = gimple_omp_for_index (for_stmt, i);
gcc_assert (SSA_VAR_P (loop->v));
gcc_assert (TREE_CODE (TREE_TYPE (loop->v)) == INTEGER_TYPE
|| TREE_CODE (TREE_TYPE (loop->v)) == POINTER_TYPE);
var = TREE_CODE (loop->v) == SSA_NAME ? SSA_NAME_VAR (loop->v) : loop->v;
- loop->n1 = GIMPLE_STMT_OPERAND (t, 1);
+ loop->n1 = gimple_omp_for_initial (for_stmt, i);
- t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
- loop->cond_code = TREE_CODE (t);
- gcc_assert (TREE_OPERAND (t, 0) == var);
- loop->n2 = TREE_OPERAND (t, 1);
+ loop->cond_code = gimple_omp_for_cond (for_stmt, i);
+ loop->n2 = gimple_omp_for_final (for_stmt, i);
switch (loop->cond_code)
{
case LT_EXPR:
@@ -304,10 +329,7 @@ extract_omp_for_data (tree for_stmt, struct omp_for_data *fd,
gcc_unreachable ();
}
- t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
- gcc_assert (TREE_CODE (t) == GIMPLE_MODIFY_STMT);
- gcc_assert (GIMPLE_STMT_OPERAND (t, 0) == var);
- t = GIMPLE_STMT_OPERAND (t, 1);
+ t = gimple_omp_for_incr (for_stmt, i);
gcc_assert (TREE_OPERAND (t, 0) == var);
switch (TREE_CODE (t))
{
@@ -449,9 +471,9 @@ extract_omp_for_data (tree for_stmt, struct omp_for_data *fd,
When expanding a combined parallel+workshare region, the call to
the child function may need additional arguments in the case of
- OMP_FOR regions. In some cases, these arguments are computed out
- of variables passed in from the parent to the child via 'struct
- .omp_data_s'. For instance:
+ GIMPLE_OMP_FOR regions. In some cases, these arguments are
+ computed out of variables passed in from the parent to the child
+ via 'struct .omp_data_s'. For instance:
#pragma omp parallel for schedule (guided, i * 4)
for (j ...)
@@ -475,7 +497,7 @@ extract_omp_for_data (tree for_stmt, struct omp_for_data *fd,
To see whether the code in WS_ENTRY_BB blocks the combined
parallel+workshare call, we collect all the variables used in the
- OMP_FOR header check whether they appear on the LHS of any
+ GIMPLE_OMP_FOR header check whether they appear on the LHS of any
statement in WS_ENTRY_BB. If so, then we cannot emit the combined
call.
@@ -488,15 +510,15 @@ static bool
workshare_safe_to_combine_p (basic_block par_entry_bb, basic_block ws_entry_bb)
{
struct omp_for_data fd;
- tree par_stmt, ws_stmt;
+ gimple par_stmt, ws_stmt;
par_stmt = last_stmt (par_entry_bb);
ws_stmt = last_stmt (ws_entry_bb);
- if (TREE_CODE (ws_stmt) == OMP_SECTIONS)
+ if (gimple_code (ws_stmt) == GIMPLE_OMP_SECTIONS)
return true;
- gcc_assert (TREE_CODE (ws_stmt) == OMP_FOR);
+ gcc_assert (gimple_code (ws_stmt) == GIMPLE_OMP_FOR);
extract_omp_for_data (ws_stmt, &fd, NULL);
@@ -525,11 +547,11 @@ workshare_safe_to_combine_p (basic_block par_entry_bb, basic_block ws_entry_bb)
expanded. */
static tree
-get_ws_args_for (tree ws_stmt)
+get_ws_args_for (gimple ws_stmt)
{
tree t;
- if (TREE_CODE (ws_stmt) == OMP_FOR)
+ if (gimple_code (ws_stmt) == GIMPLE_OMP_FOR)
{
struct omp_for_data fd;
tree ws_args;
@@ -554,12 +576,12 @@ get_ws_args_for (tree ws_stmt)
return ws_args;
}
- else if (TREE_CODE (ws_stmt) == OMP_SECTIONS)
+ else if (gimple_code (ws_stmt) == GIMPLE_OMP_SECTIONS)
{
/* Number of sections is equal to the number of edges from the
- OMP_SECTIONS_SWITCH statement, except for the one to the exit
- of the sections region. */
- basic_block bb = single_succ (bb_for_stmt (ws_stmt));
+ GIMPLE_OMP_SECTIONS_SWITCH statement, except for the one to
+ the exit of the sections region. */
+ basic_block bb = single_succ (gimple_bb (ws_stmt));
t = build_int_cst (unsigned_type_node, EDGE_COUNT (bb->succs) - 1);
t = tree_cons (NULL, t, NULL);
return t;
@@ -583,9 +605,9 @@ determine_parallel_type (struct omp_region *region)
return;
/* We only support parallel+for and parallel+sections. */
- if (region->type != OMP_PARALLEL
- || (region->inner->type != OMP_FOR
- && region->inner->type != OMP_SECTIONS))
+ if (region->type != GIMPLE_OMP_PARALLEL
+ || (region->inner->type != GIMPLE_OMP_FOR
+ && region->inner->type != GIMPLE_OMP_SECTIONS))
return;
/* Check for perfect nesting PAR_ENTRY_BB -> WS_ENTRY_BB and
@@ -598,13 +620,13 @@ determine_parallel_type (struct omp_region *region)
if (single_succ (par_entry_bb) == ws_entry_bb
&& single_succ (ws_exit_bb) == par_exit_bb
&& workshare_safe_to_combine_p (par_entry_bb, ws_entry_bb)
- && (OMP_PARALLEL_COMBINED (last_stmt (par_entry_bb))
+ && (gimple_omp_parallel_combined_p (last_stmt (par_entry_bb))
|| (last_and_only_stmt (ws_entry_bb)
&& last_and_only_stmt (par_exit_bb))))
{
- tree ws_stmt = last_stmt (ws_entry_bb);
+ gimple ws_stmt = last_stmt (ws_entry_bb);
- if (region->inner->type == OMP_FOR)
+ if (region->inner->type == GIMPLE_OMP_FOR)
{
/* If this is a combined parallel loop, we need to determine
whether or not to use the combined library calls. There
@@ -615,7 +637,7 @@ determine_parallel_type (struct omp_region *region)
parallel loop call would still need extra synchronization
to implement ordered semantics, so there would not be any
gain in using the combined call. */
- tree clauses = OMP_FOR_CLAUSES (ws_stmt);
+ tree clauses = gimple_omp_for_clauses (ws_stmt);
tree c = find_omp_clause (clauses, OMP_CLAUSE_SCHEDULE);
if (c == NULL
|| OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_STATIC
@@ -745,7 +767,7 @@ use_pointer_for_field (tree decl, omp_context *shared_ctx)
{
tree c;
- for (c = OMP_TASKREG_CLAUSES (up->stmt);
+ for (c = gimple_omp_taskreg_clauses (up->stmt);
c; c = OMP_CLAUSE_CHAIN (c))
if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
&& OMP_CLAUSE_DECL (c) == decl)
@@ -990,7 +1012,7 @@ fixup_remapped_decl (tree decl, omp_context *ctx, bool private_debug)
&& DECL_HAS_VALUE_EXPR_P (decl))
{
tree ve = DECL_VALUE_EXPR (decl);
- walk_tree (&ve, copy_body_r, &ctx->cb, NULL);
+ walk_tree (&ve, copy_tree_body_r, &ctx->cb, NULL);
SET_DECL_VALUE_EXPR (new_decl, ve);
DECL_HAS_VALUE_EXPR_P (new_decl) = 1;
}
@@ -1058,19 +1080,19 @@ void
dump_omp_region (FILE *file, struct omp_region *region, int indent)
{
fprintf (file, "%*sbb %d: %s\n", indent, "", region->entry->index,
- tree_code_name[region->type]);
+ gimple_code_name[region->type]);
if (region->inner)
dump_omp_region (file, region->inner, indent + 4);
if (region->cont)
{
- fprintf (file, "%*sbb %d: OMP_CONTINUE\n", indent, "",
+ fprintf (file, "%*sbb %d: GIMPLE_OMP_CONTINUE\n", indent, "",
region->cont->index);
}
if (region->exit)
- fprintf (file, "%*sbb %d: OMP_RETURN\n", indent, "",
+ fprintf (file, "%*sbb %d: GIMPLE_OMP_RETURN\n", indent, "",
region->exit->index);
else
fprintf (file, "%*s[no exit marker]\n", indent, "");
@@ -1095,7 +1117,8 @@ debug_all_omp_regions (void)
/* Create a new parallel region starting at STMT inside region PARENT. */
struct omp_region *
-new_omp_region (basic_block bb, enum tree_code type, struct omp_region *parent)
+new_omp_region (basic_block bb, enum gimple_code type,
+ struct omp_region *parent)
{
struct omp_region *region = XCNEW (struct omp_region);
@@ -1155,7 +1178,7 @@ free_omp_regions (void)
/* Create a new context, with OUTER_CTX being the surrounding context. */
static omp_context *
-new_omp_context (tree stmt, omp_context *outer_ctx)
+new_omp_context (gimple stmt, omp_context *outer_ctx)
{
omp_context *ctx = XCNEW (omp_context);
@@ -1188,17 +1211,19 @@ new_omp_context (tree stmt, omp_context *outer_ctx)
return ctx;
}
-static void maybe_catch_exception (tree *stmt_p);
+static gimple_seq maybe_catch_exception (gimple_seq);
/* Finalize task copyfn. */
static void
-finalize_task_copyfn (tree task_stmt)
+finalize_task_copyfn (gimple task_stmt)
{
struct function *child_cfun;
tree child_fn, old_fn;
+ gimple_seq seq, new_seq;
+ gimple bind;
- child_fn = OMP_TASK_COPYFN (task_stmt);
+ child_fn = gimple_omp_task_copy_fn (task_stmt);
if (child_fn == NULL_TREE)
return;
@@ -1211,8 +1236,17 @@ finalize_task_copyfn (tree task_stmt)
old_fn = current_function_decl;
push_cfun (child_cfun);
current_function_decl = child_fn;
- gimplify_body (&DECL_SAVED_TREE (child_fn), child_fn, false);
- maybe_catch_exception (&BIND_EXPR_BODY (DECL_SAVED_TREE (child_fn)));
+ bind = gimplify_body (&DECL_SAVED_TREE (child_fn), child_fn, false);
+ seq = gimple_seq_alloc ();
+ gimple_seq_add_stmt (&seq, bind);
+ new_seq = maybe_catch_exception (seq);
+ if (new_seq != seq)
+ {
+ bind = gimple_build_bind (NULL, new_seq, NULL);
+ seq = gimple_seq_alloc ();
+ gimple_seq_add_stmt (&seq, bind);
+ }
+ gimple_set_body (child_fn, seq);
pop_cfun ();
current_function_decl = old_fn;
@@ -1285,9 +1319,11 @@ fixup_child_record_type (omp_context *ctx)
DECL_CONTEXT (new_f) = type;
TREE_TYPE (new_f) = remap_type (TREE_TYPE (f), &ctx->cb);
TREE_CHAIN (new_f) = new_fields;
- walk_tree (&DECL_SIZE (new_f), copy_body_r, &ctx->cb, NULL);
- walk_tree (&DECL_SIZE_UNIT (new_f), copy_body_r, &ctx->cb, NULL);
- walk_tree (&DECL_FIELD_OFFSET (new_f), copy_body_r, &ctx->cb, NULL);
+ walk_tree (&DECL_SIZE (new_f), copy_tree_body_r, &ctx->cb, NULL);
+ walk_tree (&DECL_SIZE_UNIT (new_f), copy_tree_body_r,
+ &ctx->cb, NULL);
+ walk_tree (&DECL_FIELD_OFFSET (new_f), copy_tree_body_r,
+ &ctx->cb, NULL);
new_fields = new_f;
/* Arrange to be able to look up the receiver field
@@ -1386,7 +1422,7 @@ scan_sharing_clauses (tree clauses, omp_context *ctx)
case OMP_CLAUSE_COPYPRIVATE:
if (ctx->outer)
- scan_omp (&OMP_CLAUSE_DECL (c), ctx->outer);
+ scan_omp_op (&OMP_CLAUSE_DECL (c), ctx->outer);
/* FALLTHRU */
case OMP_CLAUSE_COPYIN:
@@ -1403,7 +1439,7 @@ scan_sharing_clauses (tree clauses, omp_context *ctx)
case OMP_CLAUSE_NUM_THREADS:
case OMP_CLAUSE_SCHEDULE:
if (ctx->outer)
- scan_omp (&OMP_CLAUSE_OPERAND (c, 0), ctx->outer);
+ scan_omp_op (&OMP_CLAUSE_OPERAND (c, 0), ctx->outer);
break;
case OMP_CLAUSE_NOWAIT:
@@ -1424,7 +1460,7 @@ scan_sharing_clauses (tree clauses, omp_context *ctx)
case OMP_CLAUSE_LASTPRIVATE:
/* Let the corresponding firstprivate clause create
the variable. */
- if (OMP_CLAUSE_LASTPRIVATE_STMT (c))
+ if (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c))
scan_array_reductions = true;
if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
break;
@@ -1472,12 +1508,12 @@ scan_sharing_clauses (tree clauses, omp_context *ctx)
if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
&& OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
{
- scan_omp (&OMP_CLAUSE_REDUCTION_INIT (c), ctx);
- scan_omp (&OMP_CLAUSE_REDUCTION_MERGE (c), ctx);
+ scan_omp (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c), ctx);
+ scan_omp (OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c), ctx);
}
else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
- && OMP_CLAUSE_LASTPRIVATE_STMT (c))
- scan_omp (&OMP_CLAUSE_LASTPRIVATE_STMT (c), ctx);
+ && OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c))
+ scan_omp (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c), ctx);
}
/* Create a new name for omp child function. Returns an identifier. */
@@ -1526,7 +1562,7 @@ create_omp_child_function (omp_context *ctx, bool task_copy)
if (!task_copy)
ctx->cb.dst_fn = decl;
else
- OMP_TASK_COPYFN (ctx->stmt) = decl;
+ gimple_omp_task_set_copy_fn (ctx->stmt, decl);
TREE_STATIC (decl) = 1;
TREE_USED (decl) = 1;
@@ -1567,8 +1603,8 @@ create_omp_child_function (omp_context *ctx, bool task_copy)
allocate_struct_function clobbers CFUN, so we need to restore
it afterward. */
push_struct_function (decl);
- DECL_SOURCE_LOCATION (decl) = EXPR_LOCATION (ctx->stmt);
- cfun->function_end_locus = EXPR_LOCATION (ctx->stmt);
+ DECL_SOURCE_LOCATION (decl) = gimple_location (ctx->stmt);
+ cfun->function_end_locus = gimple_location (ctx->stmt);
pop_cfun ();
}
@@ -1576,22 +1612,24 @@ create_omp_child_function (omp_context *ctx, bool task_copy)
/* Scan an OpenMP parallel directive. */
static void
-scan_omp_parallel (tree *stmt_p, omp_context *outer_ctx)
+scan_omp_parallel (gimple_stmt_iterator *gsi, omp_context *outer_ctx)
{
omp_context *ctx;
tree name;
+ gimple stmt = gsi_stmt (*gsi);
/* Ignore parallel directives with empty bodies, unless there
are copyin clauses. */
if (optimize > 0
- && empty_body_p (OMP_PARALLEL_BODY (*stmt_p))
- && find_omp_clause (OMP_CLAUSES (*stmt_p), OMP_CLAUSE_COPYIN) == NULL)
+ && empty_body_p (gimple_omp_body (stmt))
+ && find_omp_clause (gimple_omp_parallel_clauses (stmt),
+ OMP_CLAUSE_COPYIN) == NULL)
{
- *stmt_p = build_empty_stmt ();
+ gsi_replace (gsi, gimple_build_nop (), false);
return;
}
- ctx = new_omp_context (*stmt_p, outer_ctx);
+ ctx = new_omp_context (stmt, outer_ctx);
if (taskreg_nesting_level > 1)
ctx->is_nested = true;
ctx->field_map = splay_tree_new (splay_tree_compare_pointers, 0, 0);
@@ -1601,10 +1639,10 @@ scan_omp_parallel (tree *stmt_p, omp_context *outer_ctx)
name = build_decl (TYPE_DECL, name, ctx->record_type);
TYPE_NAME (ctx->record_type) = name;
create_omp_child_function (ctx, false);
- OMP_PARALLEL_FN (*stmt_p) = ctx->cb.dst_fn;
+ gimple_omp_parallel_set_child_fn (stmt, ctx->cb.dst_fn);
- scan_sharing_clauses (OMP_PARALLEL_CLAUSES (*stmt_p), ctx);
- scan_omp (&OMP_PARALLEL_BODY (*stmt_p), ctx);
+ scan_sharing_clauses (gimple_omp_parallel_clauses (stmt), ctx);
+ scan_omp (gimple_omp_body (stmt), ctx);
if (TYPE_FIELDS (ctx->record_type) == NULL)
ctx->record_type = ctx->receiver_decl = NULL;
@@ -1618,20 +1656,21 @@ scan_omp_parallel (tree *stmt_p, omp_context *outer_ctx)
/* Scan an OpenMP task directive. */
static void
-scan_omp_task (tree *stmt_p, omp_context *outer_ctx)
+scan_omp_task (gimple_stmt_iterator *gsi, omp_context *outer_ctx)
{
omp_context *ctx;
- tree name;
+ tree name, t;
+ gimple stmt = gsi_stmt (*gsi);
/* Ignore task directives with empty bodies. */
if (optimize > 0
- && empty_body_p (OMP_TASK_BODY (*stmt_p)))
+ && empty_body_p (gimple_omp_body (stmt)))
{
- *stmt_p = build_empty_stmt ();
+ gsi_replace (gsi, gimple_build_nop (), false);
return;
}
- ctx = new_omp_context (*stmt_p, outer_ctx);
+ ctx = new_omp_context (stmt, outer_ctx);
if (taskreg_nesting_level > 1)
ctx->is_nested = true;
ctx->field_map = splay_tree_new (splay_tree_compare_pointers, 0, 0);
@@ -1641,9 +1680,9 @@ scan_omp_task (tree *stmt_p, omp_context *outer_ctx)
name = build_decl (TYPE_DECL, name, ctx->record_type);
TYPE_NAME (ctx->record_type) = name;
create_omp_child_function (ctx, false);
- OMP_TASK_FN (*stmt_p) = ctx->cb.dst_fn;
+ gimple_omp_task_set_child_fn (stmt, ctx->cb.dst_fn);
- scan_sharing_clauses (OMP_TASK_CLAUSES (*stmt_p), ctx);
+ scan_sharing_clauses (gimple_omp_task_clauses (stmt), ctx);
if (ctx->srecord_type)
{
@@ -1653,15 +1692,15 @@ scan_omp_task (tree *stmt_p, omp_context *outer_ctx)
create_omp_child_function (ctx, true);
}
- scan_omp (&OMP_TASK_BODY (*stmt_p), ctx);
+ scan_omp (gimple_omp_body (stmt), ctx);
if (TYPE_FIELDS (ctx->record_type) == NULL)
{
ctx->record_type = ctx->receiver_decl = NULL;
- OMP_TASK_ARG_SIZE (*stmt_p)
- = build_int_cst (long_integer_type_node, 0);
- OMP_TASK_ARG_ALIGN (*stmt_p)
- = build_int_cst (long_integer_type_node, 1);
+ t = build_int_cst (long_integer_type_node, 0);
+ gimple_omp_task_set_arg_size (stmt, t);
+ t = build_int_cst (long_integer_type_node, 1);
+ gimple_omp_task_set_arg_align (stmt, t);
}
else
{
@@ -1684,12 +1723,12 @@ scan_omp_task (tree *stmt_p, omp_context *outer_ctx)
fixup_child_record_type (ctx);
if (ctx->srecord_type)
layout_type (ctx->srecord_type);
- OMP_TASK_ARG_SIZE (*stmt_p)
- = fold_convert (long_integer_type_node,
+ t = fold_convert (long_integer_type_node,
TYPE_SIZE_UNIT (ctx->record_type));
- OMP_TASK_ARG_ALIGN (*stmt_p)
- = build_int_cst (long_integer_type_node,
+ gimple_omp_task_set_arg_size (stmt, t);
+ t = build_int_cst (long_integer_type_node,
TYPE_ALIGN_UNIT (ctx->record_type));
+ gimple_omp_task_set_arg_align (stmt, t);
}
}
@@ -1697,47 +1736,43 @@ scan_omp_task (tree *stmt_p, omp_context *outer_ctx)
/* Scan an OpenMP loop directive. */
static void
-scan_omp_for (tree *stmt_p, omp_context *outer_ctx)
+scan_omp_for (gimple stmt, omp_context *outer_ctx)
{
omp_context *ctx;
- tree stmt;
- int i;
+ size_t i;
- stmt = *stmt_p;
ctx = new_omp_context (stmt, outer_ctx);
- scan_sharing_clauses (OMP_FOR_CLAUSES (stmt), ctx);
+ scan_sharing_clauses (gimple_omp_for_clauses (stmt), ctx);
- scan_omp (&OMP_FOR_PRE_BODY (stmt), ctx);
- for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (stmt)); i++)
+ scan_omp (gimple_omp_for_pre_body (stmt), ctx);
+ for (i = 0; i < gimple_omp_for_collapse (stmt); i++)
{
- scan_omp (&TREE_VEC_ELT (OMP_FOR_INIT (stmt), i), ctx);
- scan_omp (&TREE_VEC_ELT (OMP_FOR_COND (stmt), i), ctx);
- scan_omp (&TREE_VEC_ELT (OMP_FOR_INCR (stmt), i), ctx);
+ scan_omp_op (gimple_omp_for_index_ptr (stmt, i), ctx);
+ scan_omp_op (gimple_omp_for_initial_ptr (stmt, i), ctx);
+ scan_omp_op (gimple_omp_for_final_ptr (stmt, i), ctx);
+ scan_omp_op (gimple_omp_for_incr_ptr (stmt, i), ctx);
}
- scan_omp (&OMP_FOR_BODY (stmt), ctx);
+ scan_omp (gimple_omp_body (stmt), ctx);
}
/* Scan an OpenMP sections directive. */
static void
-scan_omp_sections (tree *stmt_p, omp_context *outer_ctx)
+scan_omp_sections (gimple stmt, omp_context *outer_ctx)
{
- tree stmt;
omp_context *ctx;
- stmt = *stmt_p;
ctx = new_omp_context (stmt, outer_ctx);
- scan_sharing_clauses (OMP_SECTIONS_CLAUSES (stmt), ctx);
- scan_omp (&OMP_SECTIONS_BODY (stmt), ctx);
+ scan_sharing_clauses (gimple_omp_sections_clauses (stmt), ctx);
+ scan_omp (gimple_omp_body (stmt), ctx);
}
/* Scan an OpenMP single directive. */
static void
-scan_omp_single (tree *stmt_p, omp_context *outer_ctx)
+scan_omp_single (gimple stmt, omp_context *outer_ctx)
{
- tree stmt = *stmt_p;
omp_context *ctx;
tree name;
@@ -1748,8 +1783,8 @@ scan_omp_single (tree *stmt_p, omp_context *outer_ctx)
name = build_decl (TYPE_DECL, name, ctx->record_type);
TYPE_NAME (ctx->record_type) = name;
- scan_sharing_clauses (OMP_SINGLE_CLAUSES (stmt), ctx);
- scan_omp (&OMP_SINGLE_BODY (stmt), ctx);
+ scan_sharing_clauses (gimple_omp_single_clauses (stmt), ctx);
+ scan_omp (gimple_omp_body (stmt), ctx);
if (TYPE_FIELDS (ctx->record_type) == NULL)
ctx->record_type = NULL;
@@ -1760,24 +1795,24 @@ scan_omp_single (tree *stmt_p, omp_context *outer_ctx)
/* Check OpenMP nesting restrictions. */
static void
-check_omp_nesting_restrictions (tree t, omp_context *ctx)
+check_omp_nesting_restrictions (gimple stmt, omp_context *ctx)
{
- switch (TREE_CODE (t))
+ switch (gimple_code (stmt))
{
- case OMP_FOR:
- case OMP_SECTIONS:
- case OMP_SINGLE:
- case CALL_EXPR:
+ case GIMPLE_OMP_FOR:
+ case GIMPLE_OMP_SECTIONS:
+ case GIMPLE_OMP_SINGLE:
+ case GIMPLE_CALL:
for (; ctx != NULL; ctx = ctx->outer)
- switch (TREE_CODE (ctx->stmt))
+ switch (gimple_code (ctx->stmt))
{
- case OMP_FOR:
- case OMP_SECTIONS:
- case OMP_SINGLE:
- case OMP_ORDERED:
- case OMP_MASTER:
- case OMP_TASK:
- if (TREE_CODE (t) == CALL_EXPR)
+ case GIMPLE_OMP_FOR:
+ case GIMPLE_OMP_SECTIONS:
+ case GIMPLE_OMP_SINGLE:
+ case GIMPLE_OMP_ORDERED:
+ case GIMPLE_OMP_MASTER:
+ case GIMPLE_OMP_TASK:
+ if (is_gimple_call (stmt))
{
warning (0, "barrier region may not be closely nested inside "
"of work-sharing, critical, ordered, master or "
@@ -1788,54 +1823,55 @@ check_omp_nesting_restrictions (tree t, omp_context *ctx)
"of work-sharing, critical, ordered, master or explicit "
"task region");
return;
- case OMP_PARALLEL:
+ case GIMPLE_OMP_PARALLEL:
return;
default:
break;
}
break;
- case OMP_MASTER:
+ case GIMPLE_OMP_MASTER:
for (; ctx != NULL; ctx = ctx->outer)
- switch (TREE_CODE (ctx->stmt))
+ switch (gimple_code (ctx->stmt))
{
- case OMP_FOR:
- case OMP_SECTIONS:
- case OMP_SINGLE:
- case OMP_TASK:
+ case GIMPLE_OMP_FOR:
+ case GIMPLE_OMP_SECTIONS:
+ case GIMPLE_OMP_SINGLE:
+ case GIMPLE_OMP_TASK:
warning (0, "master region may not be closely nested inside "
"of work-sharing or explicit task region");
return;
- case OMP_PARALLEL:
+ case GIMPLE_OMP_PARALLEL:
return;
default:
break;
}
break;
- case OMP_ORDERED:
+ case GIMPLE_OMP_ORDERED:
for (; ctx != NULL; ctx = ctx->outer)
- switch (TREE_CODE (ctx->stmt))
+ switch (gimple_code (ctx->stmt))
{
- case OMP_CRITICAL:
- case OMP_TASK:
+ case GIMPLE_OMP_CRITICAL:
+ case GIMPLE_OMP_TASK:
warning (0, "ordered region may not be closely nested inside "
"of critical or explicit task region");
return;
- case OMP_FOR:
- if (find_omp_clause (OMP_CLAUSES (ctx->stmt),
+ case GIMPLE_OMP_FOR:
+ if (find_omp_clause (gimple_omp_for_clauses (ctx->stmt),
OMP_CLAUSE_ORDERED) == NULL)
warning (0, "ordered region must be closely nested inside "
"a loop region with an ordered clause");
return;
- case OMP_PARALLEL:
+ case GIMPLE_OMP_PARALLEL:
return;
default:
break;
}
break;
- case OMP_CRITICAL:
+ case GIMPLE_OMP_CRITICAL:
for (; ctx != NULL; ctx = ctx->outer)
- if (TREE_CODE (ctx->stmt) == OMP_CRITICAL
- && OMP_CRITICAL_NAME (t) == OMP_CRITICAL_NAME (ctx->stmt))
+ if (gimple_code (ctx->stmt) == GIMPLE_OMP_CRITICAL
+ && (gimple_omp_critical_name (stmt)
+ == gimple_omp_critical_name (ctx->stmt)))
{
warning (0, "critical region may not be nested inside a critical "
"region with the same name");
@@ -1848,90 +1884,117 @@ check_omp_nesting_restrictions (tree t, omp_context *ctx)
}
-/* Callback for walk_stmts used to scan for OpenMP directives at TP. */
+/* Helper function scan_omp.
+
+ Callback for walk_tree or operators in walk_gimple_stmt used to
+ scan for OpenMP directives in TP. */
static tree
-scan_omp_1 (tree *tp, int *walk_subtrees, void *data)
+scan_omp_1_op (tree *tp, int *walk_subtrees, void *data)
{
struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
omp_context *ctx = (omp_context *) wi->info;
tree t = *tp;
- if (EXPR_HAS_LOCATION (t))
- input_location = EXPR_LOCATION (t);
+ switch (TREE_CODE (t))
+ {
+ case VAR_DECL:
+ case PARM_DECL:
+ case LABEL_DECL:
+ case RESULT_DECL:
+ if (ctx)
+ *tp = remap_decl (t, &ctx->cb);
+ break;
+
+ default:
+ if (ctx && TYPE_P (t))
+ *tp = remap_type (t, &ctx->cb);
+ else if (!DECL_P (t))
+ *walk_subtrees = 1;
+ break;
+ }
+
+ return NULL_TREE;
+}
+
+
+/* Helper function for scan_omp.
+
+ Callback for walk_gimple_stmt used to scan for OpenMP directives in
+ the current statement in GSI. */
+
+static tree
+scan_omp_1_stmt (gimple_stmt_iterator *gsi, bool *handled_ops_p,
+ struct walk_stmt_info *wi)
+{
+ gimple stmt = gsi_stmt (*gsi);
+ omp_context *ctx = (omp_context *) wi->info;
+
+ if (gimple_has_location (stmt))
+ input_location = gimple_location (stmt);
/* Check the OpenMP nesting restrictions. */
if (ctx != NULL)
{
- if (OMP_DIRECTIVE_P (t))
- check_omp_nesting_restrictions (t, ctx);
- else if (TREE_CODE (t) == CALL_EXPR)
+ if (is_gimple_omp (stmt))
+ check_omp_nesting_restrictions (stmt, ctx);
+ else if (is_gimple_call (stmt))
{
- tree fndecl = get_callee_fndecl (t);
+ tree fndecl = gimple_call_fndecl (stmt);
if (fndecl && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
&& DECL_FUNCTION_CODE (fndecl) == BUILT_IN_GOMP_BARRIER)
- check_omp_nesting_restrictions (t, ctx);
+ check_omp_nesting_restrictions (stmt, ctx);
}
}
- *walk_subtrees = 0;
- switch (TREE_CODE (t))
+ *handled_ops_p = true;
+
+ switch (gimple_code (stmt))
{
- case OMP_PARALLEL:
+ case GIMPLE_OMP_PARALLEL:
taskreg_nesting_level++;
- scan_omp_parallel (tp, ctx);
+ scan_omp_parallel (gsi, ctx);
taskreg_nesting_level--;
break;
- case OMP_TASK:
+ case GIMPLE_OMP_TASK:
taskreg_nesting_level++;
- scan_omp_task (tp, ctx);
+ scan_omp_task (gsi, ctx);
taskreg_nesting_level--;
break;
- case OMP_FOR:
- scan_omp_for (tp, ctx);
+ case GIMPLE_OMP_FOR:
+ scan_omp_for (stmt, ctx);
break;
- case OMP_SECTIONS:
- scan_omp_sections (tp, ctx);
+ case GIMPLE_OMP_SECTIONS:
+ scan_omp_sections (stmt, ctx);
break;
- case OMP_SINGLE:
- scan_omp_single (tp, ctx);
+ case GIMPLE_OMP_SINGLE:
+ scan_omp_single (stmt, ctx);
break;
- case OMP_SECTION:
- case OMP_MASTER:
- case OMP_ORDERED:
- case OMP_CRITICAL:
- ctx = new_omp_context (*tp, ctx);
- scan_omp (&OMP_BODY (*tp), ctx);
+ case GIMPLE_OMP_SECTION:
+ case GIMPLE_OMP_MASTER:
+ case GIMPLE_OMP_ORDERED:
+ case GIMPLE_OMP_CRITICAL:
+ ctx = new_omp_context (stmt, ctx);
+ scan_omp (gimple_omp_body (stmt), ctx);
break;
- case BIND_EXPR:
+ case GIMPLE_BIND:
{
tree var;
- *walk_subtrees = 1;
- for (var = BIND_EXPR_VARS (t); var ; var = TREE_CHAIN (var))
- insert_decl_map (&ctx->cb, var, var);
+ *handled_ops_p = false;
+ if (ctx)
+ for (var = gimple_bind_vars (stmt); var ; var = TREE_CHAIN (var))
+ insert_decl_map (&ctx->cb, var, var);
}
break;
-
- case VAR_DECL:
- case PARM_DECL:
- case LABEL_DECL:
- case RESULT_DECL:
- if (ctx)
- *tp = remap_decl (t, &ctx->cb);
- break;
-
default:
- if (ctx && TYPE_P (t))
- *tp = remap_type (t, &ctx->cb);
- else if (!DECL_P (t))
- *walk_subtrees = 1;
+ *handled_ops_p = false;
break;
}
@@ -1939,24 +2002,22 @@ scan_omp_1 (tree *tp, int *walk_subtrees, void *data)
}
-/* Scan all the statements starting at STMT_P. CTX contains context
- information about the OpenMP directives and clauses found during
- the scan. */
+/* Scan all the statements starting at the current statement. CTX
+ contains context information about the OpenMP directives and
+ clauses found during the scan. */
static void
-scan_omp (tree *stmt_p, omp_context *ctx)
+scan_omp (gimple_seq body, omp_context *ctx)
{
location_t saved_location;
struct walk_stmt_info wi;
memset (&wi, 0, sizeof (wi));
- wi.callback = scan_omp_1;
wi.info = ctx;
- wi.want_bind_expr = (ctx != NULL);
wi.want_locations = true;
saved_location = input_location;
- walk_stmts (&wi, stmt_p);
+ walk_gimple_seq (body, scan_omp_1_stmt, scan_omp_1_op, &wi);
input_location = saved_location;
}
@@ -1973,7 +2034,7 @@ build_omp_barrier (void)
/* If a context was created for STMT when it was scanned, return it. */
static omp_context *
-maybe_lookup_ctx (tree stmt)
+maybe_lookup_ctx (gimple stmt)
{
splay_tree_node n;
n = splay_tree_lookup (all_contexts, (splay_tree_key) stmt);
@@ -2133,17 +2194,17 @@ omp_reduction_init (tree clause, tree type)
to destructors go in DLIST. */
static void
-lower_rec_input_clauses (tree clauses, tree *ilist, tree *dlist,
+lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
omp_context *ctx)
{
- tree_stmt_iterator diter;
+ gimple_stmt_iterator diter;
tree c, dtor, copyin_seq, x, ptr;
bool copyin_by_ref = false;
bool lastprivate_firstprivate = false;
int pass;
- *dlist = alloc_stmt_list ();
- diter = tsi_start (*dlist);
+ *dlist = gimple_seq_alloc ();
+ diter = gsi_start (*dlist);
copyin_seq = NULL;
/* Do all the fixed sized types in the first pass, and the variable sized
@@ -2205,15 +2266,26 @@ lower_rec_input_clauses (tree clauses, tree *ilist, tree *dlist,
if (c_kind != OMP_CLAUSE_FIRSTPRIVATE || !is_task_ctx (ctx))
{
+ gimple stmt;
+ tree tmp;
+
ptr = DECL_VALUE_EXPR (new_var);
gcc_assert (TREE_CODE (ptr) == INDIRECT_REF);
ptr = TREE_OPERAND (ptr, 0);
gcc_assert (DECL_P (ptr));
x = TYPE_SIZE_UNIT (TREE_TYPE (new_var));
- x = build_call_expr (built_in_decls[BUILT_IN_ALLOCA], 1, x);
- x = fold_convert (TREE_TYPE (ptr), x);
- x = build_gimple_modify_stmt (ptr, x);
- gimplify_and_add (x, ilist);
+
+ /* void *tmp = __builtin_alloca */
+ stmt
+ = gimple_build_call (built_in_decls[BUILT_IN_ALLOCA], 1, x);
+ tmp = create_tmp_var_raw (ptr_type_node, NULL);
+ gimple_add_tmp_var (tmp);
+ gimple_call_set_lhs (stmt, tmp);
+
+ gimple_seq_add_stmt (ilist, stmt);
+
+ x = fold_convert (TREE_TYPE (ptr), tmp);
+ gimplify_assign (ptr, x, ilist);
}
}
else if (is_reference (var))
@@ -2252,8 +2324,7 @@ lower_rec_input_clauses (tree clauses, tree *ilist, tree *dlist,
x = fold_convert (TREE_TYPE (new_var), x);
}
- x = build_gimple_modify_stmt (new_var, x);
- gimplify_and_add (x, ilist);
+ gimplify_assign (new_var, x, ilist);
new_var = build_fold_indirect_ref (new_var);
}
@@ -2315,9 +2386,11 @@ lower_rec_input_clauses (tree clauses, tree *ilist, tree *dlist,
x = lang_hooks.decls.omp_clause_dtor (c, new_var);
if (x)
{
+ gimple_seq tseq = NULL;
+
dtor = x;
- gimplify_stmt (&dtor);
- tsi_link_before (&diter, dtor, TSI_SAME_STMT);
+ gimplify_stmt (&dtor, &tseq);
+ gsi_insert_seq_before (&diter, tseq, GSI_SAME_STMT);
}
break;
@@ -2360,16 +2433,17 @@ lower_rec_input_clauses (tree clauses, tree *ilist, tree *dlist,
x = build_fold_addr_expr (x);
SET_DECL_VALUE_EXPR (placeholder, x);
DECL_HAS_VALUE_EXPR_P (placeholder) = 1;
- gimplify_and_add (OMP_CLAUSE_REDUCTION_INIT (c), ilist);
- OMP_CLAUSE_REDUCTION_INIT (c) = NULL;
+ lower_omp (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c), ctx);
+ gimple_seq_add_seq (ilist,
+ OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c));
+ OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c) = NULL;
DECL_HAS_VALUE_EXPR_P (placeholder) = 0;
}
else
{
x = omp_reduction_init (c, TREE_TYPE (new_var));
gcc_assert (TREE_CODE (TREE_TYPE (new_var)) != ARRAY_TYPE);
- x = build_gimple_modify_stmt (new_var, x);
- gimplify_and_add (x, ilist);
+ gimplify_assign (new_var, x, ilist);
}
break;
@@ -2406,10 +2480,10 @@ lower_rec_input_clauses (tree clauses, tree *ilist, tree *dlist,
always true. */
static void
-lower_lastprivate_clauses (tree clauses, tree predicate, tree *stmt_list,
- omp_context *ctx)
+lower_lastprivate_clauses (tree clauses, tree predicate, gimple_seq *stmt_list,
+ omp_context *ctx)
{
- tree sub_list, x, c;
+ tree x, c, label = NULL;
bool par_clauses = false;
/* Early exit if there are no lastprivate clauses. */
@@ -2426,14 +2500,29 @@ lower_lastprivate_clauses (tree clauses, tree predicate, tree *stmt_list,
if (ctx == NULL || !is_parallel_ctx (ctx))
return;
- clauses = find_omp_clause (OMP_PARALLEL_CLAUSES (ctx->stmt),
+ clauses = find_omp_clause (gimple_omp_parallel_clauses (ctx->stmt),
OMP_CLAUSE_LASTPRIVATE);
if (clauses == NULL)
return;
par_clauses = true;
}
- sub_list = alloc_stmt_list ();
+ if (predicate)
+ {
+ gimple stmt;
+ tree label_true, arm1, arm2;
+
+ label = create_artificial_label ();
+ label_true = create_artificial_label ();
+ arm1 = TREE_OPERAND (predicate, 0);
+ arm2 = TREE_OPERAND (predicate, 1);
+ gimplify_expr (&arm1, stmt_list, NULL, is_gimple_val, fb_rvalue);
+ gimplify_expr (&arm2, stmt_list, NULL, is_gimple_val, fb_rvalue);
+ stmt = gimple_build_cond (TREE_CODE (predicate), arm1, arm2,
+ label_true, label);
+ gimple_seq_add_stmt (stmt_list, stmt);
+ gimple_seq_add_stmt (stmt_list, gimple_build_label (label_true));
+ }
for (c = clauses; c ;)
{
@@ -2444,15 +2533,19 @@ lower_lastprivate_clauses (tree clauses, tree predicate, tree *stmt_list,
var = OMP_CLAUSE_DECL (c);
new_var = lookup_decl (var, ctx);
- if (OMP_CLAUSE_LASTPRIVATE_STMT (c))
- gimplify_and_add (OMP_CLAUSE_LASTPRIVATE_STMT (c), &sub_list);
- OMP_CLAUSE_LASTPRIVATE_STMT (c) = NULL;
+ if (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c))
+ {
+ lower_omp (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c), ctx);
+ gimple_seq_add_seq (stmt_list,
+ OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c));
+ }
+ OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c) = NULL;
x = build_outer_var_ref (var, ctx);
if (is_reference (var))
new_var = build_fold_indirect_ref (new_var);
x = lang_hooks.decls.omp_clause_assign_op (c, x, new_var);
- append_to_statement_list (x, &sub_list);
+ gimplify_and_add (x, stmt_list);
}
c = OMP_CLAUSE_CHAIN (c);
if (c == NULL && !par_clauses)
@@ -2467,27 +2560,25 @@ lower_lastprivate_clauses (tree clauses, tree predicate, tree *stmt_list,
if (ctx == NULL || !is_parallel_ctx (ctx))
break;
- c = find_omp_clause (OMP_PARALLEL_CLAUSES (ctx->stmt),
+ c = find_omp_clause (gimple_omp_parallel_clauses (ctx->stmt),
OMP_CLAUSE_LASTPRIVATE);
par_clauses = true;
}
}
- if (predicate)
- x = build3 (COND_EXPR, void_type_node, predicate, sub_list, NULL);
- else
- x = sub_list;
-
- gimplify_and_add (x, stmt_list);
+ if (label)
+ gimple_seq_add_stmt (stmt_list, gimple_build_label (label));
}
/* Generate code to implement the REDUCTION clauses. */
static void
-lower_reduction_clauses (tree clauses, tree *stmt_list, omp_context *ctx)
+lower_reduction_clauses (tree clauses, gimple_seq *stmt_seqp, omp_context *ctx)
{
- tree sub_list = NULL, x, c;
+ gimple_seq sub_seq = NULL;
+ gimple stmt;
+ tree x, c;
int count = 0;
/* First see if there is exactly one reduction clause. Use OMP_ATOMIC
@@ -2535,7 +2626,7 @@ lower_reduction_clauses (tree clauses, tree *stmt_list, omp_context *ctx)
ref = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (addr)), addr);
x = fold_build2 (code, TREE_TYPE (ref), ref, new_var);
x = build2 (OMP_ATOMIC, void_type_node, addr, x);
- gimplify_and_add (x, stmt_list);
+ gimplify_and_add (x, stmt_seqp);
return;
}
@@ -2547,33 +2638,33 @@ lower_reduction_clauses (tree clauses, tree *stmt_list, omp_context *ctx)
ref = build_fold_addr_expr (ref);
SET_DECL_VALUE_EXPR (placeholder, ref);
DECL_HAS_VALUE_EXPR_P (placeholder) = 1;
- gimplify_and_add (OMP_CLAUSE_REDUCTION_MERGE (c), &sub_list);
- OMP_CLAUSE_REDUCTION_MERGE (c) = NULL;
+ lower_omp (OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c), ctx);
+ gimple_seq_add_seq (&sub_seq, OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c));
+ OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c) = NULL;
OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) = NULL;
}
else
{
x = build2 (code, TREE_TYPE (ref), ref, new_var);
ref = build_outer_var_ref (var, ctx);
- x = build_gimple_modify_stmt (ref, x);
- append_to_statement_list (x, &sub_list);
+ gimplify_assign (ref, x, &sub_seq);
}
}
- x = build_call_expr (built_in_decls[BUILT_IN_GOMP_ATOMIC_START], 0);
- gimplify_and_add (x, stmt_list);
+ stmt = gimple_build_call (built_in_decls[BUILT_IN_GOMP_ATOMIC_START], 0);
+ gimple_seq_add_stmt (stmt_seqp, stmt);
- gimplify_and_add (sub_list, stmt_list);
+ gimple_seq_add_seq (stmt_seqp, sub_seq);
- x = build_call_expr (built_in_decls[BUILT_IN_GOMP_ATOMIC_END], 0);
- gimplify_and_add (x, stmt_list);
+ stmt = gimple_build_call (built_in_decls[BUILT_IN_GOMP_ATOMIC_END], 0);
+ gimple_seq_add_stmt (stmt_seqp, stmt);
}
/* Generate code to implement the COPYPRIVATE clauses. */
static void
-lower_copyprivate_clauses (tree clauses, tree *slist, tree *rlist,
+lower_copyprivate_clauses (tree clauses, gimple_seq *slist, gimple_seq *rlist,
omp_context *ctx)
{
tree c;
@@ -2592,8 +2683,7 @@ lower_copyprivate_clauses (tree clauses, tree *slist, tree *rlist,
ref = build_sender_ref (var, ctx);
x = lookup_decl_in_outer_ctx (var, ctx);
x = by_ref ? build_fold_addr_expr (x) : x;
- x = build_gimple_modify_stmt (ref, x);
- gimplify_and_add (x, slist);
+ gimplify_assign (ref, x, slist);
ref = build_receiver_ref (var, by_ref, ctx);
if (is_reference (var))
@@ -2611,7 +2701,8 @@ lower_copyprivate_clauses (tree clauses, tree *slist, tree *rlist,
and REDUCTION from the sender (aka parent) side. */
static void
-lower_send_clauses (tree clauses, tree *ilist, tree *olist, omp_context *ctx)
+lower_send_clauses (tree clauses, gimple_seq *ilist, gimple_seq *olist,
+ omp_context *ctx)
{
tree c;
@@ -2681,8 +2772,7 @@ lower_send_clauses (tree clauses, tree *ilist, tree *olist, omp_context *ctx)
{
ref = build_sender_ref (val, ctx);
x = by_ref ? build_fold_addr_expr (var) : var;
- x = build_gimple_modify_stmt (ref, x);
- gimplify_and_add (x, ilist);
+ gimplify_assign (ref, x, ilist);
if (is_task_ctx (ctx))
DECL_ABSTRACT_ORIGIN (TREE_OPERAND (ref, 1)) = NULL;
}
@@ -2690,18 +2780,17 @@ lower_send_clauses (tree clauses, tree *ilist, tree *olist, omp_context *ctx)
if (do_out)
{
ref = build_sender_ref (val, ctx);
- x = build_gimple_modify_stmt (var, ref);
- gimplify_and_add (x, olist);
+ gimplify_assign (var, ref, olist);
}
}
}
-/* Generate code to implement SHARED from the sender (aka parent) side.
- This is trickier, since OMP_PARALLEL_CLAUSES doesn't list things that
- got automatically shared. */
+/* Generate code to implement SHARED from the sender (aka parent)
+ side. This is trickier, since GIMPLE_OMP_PARALLEL_CLAUSES doesn't
+ list things that got automatically shared. */
static void
-lower_send_shared_vars (tree *ilist, tree *olist, omp_context *ctx)
+lower_send_shared_vars (gimple_seq *ilist, gimple_seq *olist, omp_context *ctx)
{
tree var, ovar, nvar, f, x, record_type;
@@ -2725,25 +2814,37 @@ lower_send_shared_vars (tree *ilist, tree *olist, omp_context *ctx)
{
x = build_sender_ref (ovar, ctx);
var = build_fold_addr_expr (var);
- x = build_gimple_modify_stmt (x, var);
- gimplify_and_add (x, ilist);
+ gimplify_assign (x, var, ilist);
}
else
{
x = build_sender_ref (ovar, ctx);
- x = build_gimple_modify_stmt (x, var);
- gimplify_and_add (x, ilist);
+ gimplify_assign (x, var, ilist);
if (!TREE_READONLY (var))
{
x = build_sender_ref (ovar, ctx);
- x = build_gimple_modify_stmt (var, x);
- gimplify_and_add (x, olist);
+ gimplify_assign (var, x, olist);
}
}
}
}
+
+/* A convenience function to build an empty GIMPLE_COND with just the
+ condition. */
+
+static gimple
+gimple_build_cond_empty (tree cond)
+{
+ enum tree_code pred_code;
+ tree lhs, rhs;
+
+ gimple_cond_get_ops_from_tree (cond, &pred_code, &lhs, &rhs);
+ return gimple_build_cond (pred_code, lhs, rhs, NULL_TREE, NULL_TREE);
+}
+
+
/* Build the function calls to GOMP_parallel_start etc to actually
generate the parallel operation. REGION is the parallel region
being expanded. BB is the block where to insert the code. WS_ARGS
@@ -2753,13 +2854,14 @@ lower_send_shared_vars (tree *ilist, tree *olist, omp_context *ctx)
static void
expand_parallel_call (struct omp_region *region, basic_block bb,
- tree entry_stmt, tree ws_args)
+ gimple entry_stmt, tree ws_args)
{
tree t, t1, t2, val, cond, c, clauses;
- block_stmt_iterator si;
+ gimple_stmt_iterator gsi;
+ gimple stmt;
int start_ix;
- clauses = OMP_PARALLEL_CLAUSES (entry_stmt);
+ clauses = gimple_omp_parallel_clauses (entry_stmt);
/* Determine what flavor of GOMP_parallel_start we will be
emitting. */
@@ -2768,14 +2870,14 @@ expand_parallel_call (struct omp_region *region, basic_block bb,
{
switch (region->inner->type)
{
- case OMP_FOR:
+ case GIMPLE_OMP_FOR:
gcc_assert (region->inner->sched_kind != OMP_CLAUSE_SCHEDULE_AUTO);
start_ix = BUILT_IN_GOMP_PARALLEL_LOOP_STATIC_START
+ (region->inner->sched_kind
== OMP_CLAUSE_SCHEDULE_RUNTIME
? 3 : region->inner->sched_kind);
break;
- case OMP_SECTIONS:
+ case GIMPLE_OMP_SECTIONS:
start_ix = BUILT_IN_GOMP_PARALLEL_SECTIONS_START;
break;
default:
@@ -2803,7 +2905,7 @@ expand_parallel_call (struct omp_region *region, basic_block bb,
(cond != 0) or (cond ? val : 1u). */
if (cond)
{
- block_stmt_iterator si;
+ gimple_stmt_iterator gsi;
cond = gimple_boolify (cond);
@@ -2814,14 +2916,14 @@ expand_parallel_call (struct omp_region *region, basic_block bb,
{
basic_block cond_bb, then_bb, else_bb;
edge e, e_then, e_else;
- tree t, tmp_then, tmp_else, tmp_join, tmp_var;
+ tree tmp_then, tmp_else, tmp_join, tmp_var;
tmp_var = create_tmp_var (TREE_TYPE (val), NULL);
if (gimple_in_ssa_p (cfun))
{
- tmp_then = make_ssa_name (tmp_var, NULL_TREE);
- tmp_else = make_ssa_name (tmp_var, NULL_TREE);
- tmp_join = make_ssa_name (tmp_var, NULL_TREE);
+ tmp_then = make_ssa_name (tmp_var, NULL);
+ tmp_else = make_ssa_name (tmp_var, NULL);
+ tmp_join = make_ssa_name (tmp_var, NULL);
}
else
{
@@ -2840,24 +2942,18 @@ expand_parallel_call (struct omp_region *region, basic_block bb,
set_immediate_dominator (CDI_DOMINATORS, then_bb, cond_bb);
set_immediate_dominator (CDI_DOMINATORS, else_bb, cond_bb);
- t = build3 (COND_EXPR, void_type_node,
- cond, NULL_TREE, NULL_TREE);
-
- si = bsi_start (cond_bb);
- bsi_insert_after (&si, t, BSI_CONTINUE_LINKING);
+ stmt = gimple_build_cond_empty (cond);
+ gsi = gsi_start_bb (cond_bb);
+ gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
- si = bsi_start (then_bb);
- t = build_gimple_modify_stmt (tmp_then, val);
- if (gimple_in_ssa_p (cfun))
- SSA_NAME_DEF_STMT (tmp_then) = t;
- bsi_insert_after (&si, t, BSI_CONTINUE_LINKING);
+ gsi = gsi_start_bb (then_bb);
+ stmt = gimple_build_assign (tmp_then, val);
+ gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
- si = bsi_start (else_bb);
- t = build_gimple_modify_stmt (tmp_else,
- build_int_cst (unsigned_type_node, 1));
- if (gimple_in_ssa_p (cfun))
- SSA_NAME_DEF_STMT (tmp_else) = t;
- bsi_insert_after (&si, t, BSI_CONTINUE_LINKING);
+ gsi = gsi_start_bb (else_bb);
+ stmt = gimple_build_assign
+ (tmp_else, build_int_cst (unsigned_type_node, 1));
+ gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
make_edge (cond_bb, then_bb, EDGE_TRUE_VALUE);
make_edge (cond_bb, else_bb, EDGE_FALSE_VALUE);
@@ -2866,7 +2962,7 @@ expand_parallel_call (struct omp_region *region, basic_block bb,
if (gimple_in_ssa_p (cfun))
{
- tree phi = create_phi_node (tmp_join, bb);
+ gimple phi = create_phi_node (tmp_join, bb);
SSA_NAME_DEF_STMT (tmp_join) = phi;
add_phi_arg (phi, tmp_then, e_then);
add_phi_arg (phi, tmp_else, e_else);
@@ -2875,18 +2971,18 @@ expand_parallel_call (struct omp_region *region, basic_block bb,
val = tmp_join;
}
- si = bsi_start (bb);
- val = force_gimple_operand_bsi (&si, val, true, NULL_TREE,
- false, BSI_CONTINUE_LINKING);
+ gsi = gsi_start_bb (bb);
+ val = force_gimple_operand_gsi (&gsi, val, true, NULL_TREE,
+ false, GSI_CONTINUE_LINKING);
}
- si = bsi_last (bb);
- t = OMP_PARALLEL_DATA_ARG (entry_stmt);
+ gsi = gsi_last_bb (bb);
+ t = gimple_omp_parallel_data_arg (entry_stmt);
if (t == NULL)
t1 = null_pointer_node;
else
t1 = build_fold_addr_expr (t);
- t2 = build_fold_addr_expr (OMP_PARALLEL_FN (entry_stmt));
+ t2 = build_fold_addr_expr (gimple_omp_parallel_child_fn (entry_stmt));
if (ws_args)
{
@@ -2898,21 +2994,21 @@ expand_parallel_call (struct omp_region *region, basic_block bb,
else
t = build_call_expr (built_in_decls[start_ix], 3, t2, t1, val);
- force_gimple_operand_bsi (&si, t, true, NULL_TREE,
- false, BSI_CONTINUE_LINKING);
+ force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
+ false, GSI_CONTINUE_LINKING);
- t = OMP_PARALLEL_DATA_ARG (entry_stmt);
+ t = gimple_omp_parallel_data_arg (entry_stmt);
if (t == NULL)
t = null_pointer_node;
else
t = build_fold_addr_expr (t);
- t = build_call_expr (OMP_PARALLEL_FN (entry_stmt), 1, t);
- force_gimple_operand_bsi (&si, t, true, NULL_TREE,
- false, BSI_CONTINUE_LINKING);
+ t = build_call_expr (gimple_omp_parallel_child_fn (entry_stmt), 1, t);
+ force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
+ false, GSI_CONTINUE_LINKING);
t = build_call_expr (built_in_decls[BUILT_IN_GOMP_PARALLEL_END], 0);
- force_gimple_operand_bsi (&si, t, true, NULL_TREE,
- false, BSI_CONTINUE_LINKING);
+ force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
+ false, GSI_CONTINUE_LINKING);
}
@@ -2920,12 +3016,12 @@ expand_parallel_call (struct omp_region *region, basic_block bb,
generate the task operation. BB is the block where to insert the code. */
static void
-expand_task_call (basic_block bb, tree entry_stmt)
+expand_task_call (basic_block bb, gimple entry_stmt)
{
tree t, t1, t2, t3, flags, cond, c, clauses;
- block_stmt_iterator si;
+ gimple_stmt_iterator gsi;
- clauses = OMP_TASK_CLAUSES (entry_stmt);
+ clauses = gimple_omp_task_clauses (entry_stmt);
c = find_omp_clause (clauses, OMP_CLAUSE_IF);
if (c)
@@ -2936,53 +3032,52 @@ expand_task_call (basic_block bb, tree entry_stmt)
c = find_omp_clause (clauses, OMP_CLAUSE_UNTIED);
flags = build_int_cst (unsigned_type_node, (c ? 1 : 0));
- si = bsi_last (bb);
- t = OMP_TASK_DATA_ARG (entry_stmt);
+ gsi = gsi_last_bb (bb);
+ t = gimple_omp_task_data_arg (entry_stmt);
if (t == NULL)
t2 = null_pointer_node;
else
t2 = build_fold_addr_expr (t);
- t1 = build_fold_addr_expr (OMP_TASK_FN (entry_stmt));
- t = OMP_TASK_COPYFN (entry_stmt);
+ t1 = build_fold_addr_expr (gimple_omp_task_child_fn (entry_stmt));
+ t = gimple_omp_task_copy_fn (entry_stmt);
if (t == NULL)
t3 = null_pointer_node;
else
t3 = build_fold_addr_expr (t);
t = build_call_expr (built_in_decls[BUILT_IN_GOMP_TASK], 7, t1, t2, t3,
- OMP_TASK_ARG_SIZE (entry_stmt),
- OMP_TASK_ARG_ALIGN (entry_stmt), cond, flags);
+ gimple_omp_task_arg_size (entry_stmt),
+ gimple_omp_task_arg_align (entry_stmt), cond, flags);
- force_gimple_operand_bsi (&si, t, true, NULL_TREE,
- false, BSI_CONTINUE_LINKING);
+ force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
+ false, GSI_CONTINUE_LINKING);
}
-/* If exceptions are enabled, wrap *STMT_P in a MUST_NOT_THROW catch
- handler. This prevents programs from violating the structured
- block semantics with throws. */
+/* If exceptions are enabled, wrap the statements in BODY in a MUST_NOT_THROW
+ catch handler and return it. This prevents programs from violating the
+ structured block semantics with throws. */
-static void
-maybe_catch_exception (tree *stmt_p)
+static gimple_seq
+maybe_catch_exception (gimple_seq body)
{
- tree f, t;
+ gimple f, t;
if (!flag_exceptions)
- return;
+ return body;
if (lang_protect_cleanup_actions)
t = lang_protect_cleanup_actions ();
else
- t = build_call_expr (built_in_decls[BUILT_IN_TRAP], 0);
- f = build2 (EH_FILTER_EXPR, void_type_node, NULL, NULL);
- EH_FILTER_MUST_NOT_THROW (f) = 1;
- gimplify_and_add (t, &EH_FILTER_FAILURE (f));
-
- t = build2 (TRY_CATCH_EXPR, void_type_node, *stmt_p, NULL);
- append_to_statement_list (f, &TREE_OPERAND (t, 1));
+ t = gimple_build_call (built_in_decls[BUILT_IN_TRAP], 0);
+
+ f = gimple_build_eh_filter (NULL, gimple_seq_alloc_with_stmt (t));
+ gimple_eh_filter_set_must_not_throw (f, true);
- *stmt_p = NULL;
- append_to_statement_list (t, stmt_p);
+ t = gimple_build_try (body, gimple_seq_alloc_with_stmt (f),
+ GIMPLE_TRY_CATCH);
+
+ return gimple_seq_alloc_with_stmt (t);
}
/* Chain all the DECLs in LIST by their TREE_CHAIN fields. */
@@ -3006,19 +3101,19 @@ list2chain (tree list)
/* Remove barriers in REGION->EXIT's block. Note that this is only
- valid for OMP_PARALLEL regions. Since the end of a parallel region
- is an implicit barrier, any workshare inside the OMP_PARALLEL that
- left a barrier at the end of the OMP_PARALLEL region can now be
+ valid for GIMPLE_OMP_PARALLEL regions. Since the end of a parallel region
+ is an implicit barrier, any workshare inside the GIMPLE_OMP_PARALLEL that
+ left a barrier at the end of the GIMPLE_OMP_PARALLEL region can now be
removed. */
static void
remove_exit_barrier (struct omp_region *region)
{
- block_stmt_iterator si;
+ gimple_stmt_iterator gsi;
basic_block exit_bb;
edge_iterator ei;
edge e;
- tree t;
+ gimple stmt;
exit_bb = region->exit;
@@ -3027,32 +3122,32 @@ remove_exit_barrier (struct omp_region *region)
if (! exit_bb)
return;
- /* The last insn in the block will be the parallel's OMP_RETURN. The
- workshare's OMP_RETURN will be in a preceding block. The kinds of
+ /* The last insn in the block will be the parallel's GIMPLE_OMP_RETURN. The
+ workshare's GIMPLE_OMP_RETURN will be in a preceding block. The kinds of
statements that can appear in between are extremely limited -- no
memory operations at all. Here, we allow nothing at all, so the
- only thing we allow to precede this OMP_RETURN is a label. */
- si = bsi_last (exit_bb);
- gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_RETURN);
- bsi_prev (&si);
- if (!bsi_end_p (si) && TREE_CODE (bsi_stmt (si)) != LABEL_EXPR)
+ only thing we allow to precede this GIMPLE_OMP_RETURN is a label. */
+ gsi = gsi_last_bb (exit_bb);
+ gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_RETURN);
+ gsi_prev (&gsi);
+ if (!gsi_end_p (gsi) && gimple_code (gsi_stmt (gsi)) != GIMPLE_LABEL)
return;
FOR_EACH_EDGE (e, ei, exit_bb->preds)
{
- si = bsi_last (e->src);
- if (bsi_end_p (si))
+ gsi = gsi_last_bb (e->src);
+ if (gsi_end_p (gsi))
continue;
- t = bsi_stmt (si);
- if (TREE_CODE (t) == OMP_RETURN)
- OMP_RETURN_NOWAIT (t) = 1;
+ stmt = gsi_stmt (gsi);
+ if (gimple_code (stmt) == GIMPLE_OMP_RETURN)
+ gimple_omp_return_set_nowait (stmt);
}
}
static void
remove_exit_barriers (struct omp_region *region)
{
- if (region->type == OMP_PARALLEL)
+ if (region->type == GIMPLE_OMP_PARALLEL)
remove_exit_barrier (region);
if (region->inner)
@@ -3076,27 +3171,26 @@ remove_exit_barriers (struct omp_region *region)
scheduling point. */
static void
-optimize_omp_library_calls (tree entry_stmt)
+optimize_omp_library_calls (gimple entry_stmt)
{
basic_block bb;
- block_stmt_iterator bsi;
+ gimple_stmt_iterator gsi;
tree thr_num_id
= DECL_ASSEMBLER_NAME (built_in_decls [BUILT_IN_OMP_GET_THREAD_NUM]);
tree num_thr_id
= DECL_ASSEMBLER_NAME (built_in_decls [BUILT_IN_OMP_GET_NUM_THREADS]);
- bool untied_task = (TREE_CODE (entry_stmt) == OMP_TASK
- && find_omp_clause (OMP_TASK_CLAUSES (entry_stmt),
+ bool untied_task = (gimple_code (entry_stmt) == GIMPLE_OMP_TASK
+ && find_omp_clause (gimple_omp_task_clauses (entry_stmt),
OMP_CLAUSE_UNTIED) != NULL);
FOR_EACH_BB (bb)
- for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
- tree stmt = bsi_stmt (bsi);
- tree call = get_call_expr_in (stmt);
+ gimple call = gsi_stmt (gsi);
tree decl;
- if (call
- && (decl = get_callee_fndecl (call))
+ if (is_gimple_call (call)
+ && (decl = gimple_call_fndecl (call))
&& DECL_EXTERNAL (decl)
&& TREE_PUBLIC (decl)
&& DECL_INITIAL (decl) == NULL)
@@ -3117,7 +3211,7 @@ optimize_omp_library_calls (tree entry_stmt)
continue;
if (DECL_ASSEMBLER_NAME (decl) != DECL_ASSEMBLER_NAME (built_in)
- || call_expr_nargs (call) != 0)
+ || gimple_call_num_args (call) != 0)
continue;
if (flag_exceptions && !TREE_NOTHROW (decl))
@@ -3128,7 +3222,7 @@ optimize_omp_library_calls (tree entry_stmt)
!= TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (built_in))))
continue;
- CALL_EXPR_FN (call) = build_fold_addr_expr (built_in);
+ gimple_call_set_fn (call, build_fold_addr_expr (built_in));
}
}
}
@@ -3141,12 +3235,12 @@ expand_omp_taskreg (struct omp_region *region)
basic_block entry_bb, exit_bb, new_bb;
struct function *child_cfun;
tree child_fn, block, t, ws_args, *tp;
- block_stmt_iterator si;
- tree entry_stmt;
+ gimple_stmt_iterator gsi;
+ gimple entry_stmt, stmt;
edge e;
entry_stmt = last_stmt (region->entry);
- child_fn = OMP_TASKREG_FN (entry_stmt);
+ child_fn = gimple_omp_taskreg_child_fn (entry_stmt);
child_cfun = DECL_STRUCT_FUNCTION (child_fn);
/* If this function has been already instrumented, make sure
the child function isn't instrumented again. */
@@ -3166,14 +3260,14 @@ expand_omp_taskreg (struct omp_region *region)
the region, in which case all we need to do is make the
sub-graph unreachable and emit the parallel call. */
edge entry_succ_e, exit_succ_e;
- block_stmt_iterator si;
+ gimple_stmt_iterator gsi;
entry_succ_e = single_succ_edge (entry_bb);
- si = bsi_last (entry_bb);
- gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_PARALLEL
- || TREE_CODE (bsi_stmt (si)) == OMP_TASK);
- bsi_remove (&si, true);
+ gsi = gsi_last_bb (entry_bb);
+ gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_PARALLEL
+ || gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_TASK);
+ gsi_remove (&gsi, true);
new_bb = entry_bb;
if (exit_bb)
@@ -3198,41 +3292,52 @@ expand_omp_taskreg (struct omp_region *region)
a function call that has been inlined, the original PARM_DECL
.OMP_DATA_I may have been converted into a different local
variable. In which case, we need to keep the assignment. */
- if (OMP_TASKREG_DATA_ARG (entry_stmt))
+ if (gimple_omp_taskreg_data_arg (entry_stmt))
{
basic_block entry_succ_bb = single_succ (entry_bb);
- block_stmt_iterator si;
- tree parcopy_stmt = NULL_TREE, arg, narg;
+ gimple_stmt_iterator gsi;
+ tree arg, narg;
+ gimple parcopy_stmt = NULL;
- for (si = bsi_start (entry_succ_bb); ; bsi_next (&si))
+ for (gsi = gsi_start_bb (entry_succ_bb); ; gsi_next (&gsi))
{
- tree stmt, arg;
+ gimple stmt;
- gcc_assert (!bsi_end_p (si));
- stmt = bsi_stmt (si);
- if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT)
+ gcc_assert (!gsi_end_p (gsi));
+ stmt = gsi_stmt (gsi);
+ if (gimple_code (stmt) != GIMPLE_ASSIGN)
continue;
- arg = GIMPLE_STMT_OPERAND (stmt, 1);
- STRIP_NOPS (arg);
- if (TREE_CODE (arg) == ADDR_EXPR
- && TREE_OPERAND (arg, 0)
- == OMP_TASKREG_DATA_ARG (entry_stmt))
+ if (gimple_num_ops (stmt) == 2)
{
- parcopy_stmt = stmt;
- break;
+ tree arg = gimple_assign_rhs1 (stmt);
+
+ /* We're ignore the subcode because we're
+ effectively doing a STRIP_NOPS. */
+
+ if (TREE_CODE (arg) == ADDR_EXPR
+ && TREE_OPERAND (arg, 0)
+ == gimple_omp_taskreg_data_arg (entry_stmt))
+ {
+ parcopy_stmt = stmt;
+ break;
+ }
}
}
- gcc_assert (parcopy_stmt != NULL_TREE);
+ gcc_assert (parcopy_stmt != NULL);
arg = DECL_ARGUMENTS (child_fn);
if (!gimple_in_ssa_p (cfun))
{
- if (GIMPLE_STMT_OPERAND (parcopy_stmt, 0) == arg)
- bsi_remove (&si, true);
+ if (gimple_assign_lhs (parcopy_stmt) == arg)
+ gsi_remove (&gsi, true);
else
- GIMPLE_STMT_OPERAND (parcopy_stmt, 1) = arg;
+ {
+ /* ?? Is setting the subcode really necessary ?? */
+ gimple_omp_set_subcode (parcopy_stmt, TREE_CODE (arg));
+ gimple_assign_set_rhs1 (parcopy_stmt, arg);
+ }
}
else
{
@@ -3240,9 +3345,11 @@ expand_omp_taskreg (struct omp_region *region)
definition of the argument. That should not be defined now,
since the argument is not used uninitialized. */
gcc_assert (gimple_default_def (cfun, arg) == NULL);
- narg = make_ssa_name (arg, build_empty_stmt ());
+ narg = make_ssa_name (arg, gimple_build_nop ());
set_default_def (arg, narg);
- GIMPLE_STMT_OPERAND (parcopy_stmt, 1) = narg;
+ /* ?? Is setting the subcode really necessary ?? */
+ gimple_omp_set_subcode (parcopy_stmt, TREE_CODE (narg));
+ gimple_assign_set_rhs1 (parcopy_stmt, narg);
update_stmt (parcopy_stmt);
}
}
@@ -3250,33 +3357,34 @@ expand_omp_taskreg (struct omp_region *region)
/* Declare local variables needed in CHILD_CFUN. */
block = DECL_INITIAL (child_fn);
BLOCK_VARS (block) = list2chain (child_cfun->local_decls);
- DECL_SAVED_TREE (child_fn) = bb_stmt_list (single_succ (entry_bb));
+ DECL_SAVED_TREE (child_fn) = NULL;
+ gimple_set_body (child_fn, bb_seq (single_succ (entry_bb)));
TREE_USED (block) = 1;
/* Reset DECL_CONTEXT on function arguments. */
for (t = DECL_ARGUMENTS (child_fn); t; t = TREE_CHAIN (t))
DECL_CONTEXT (t) = child_fn;
- /* Split ENTRY_BB at OMP_PARALLEL or OMP_TASK, so that it can be
- moved to the child function. */
- si = bsi_last (entry_bb);
- t = bsi_stmt (si);
- gcc_assert (t && (TREE_CODE (t) == OMP_PARALLEL
- || TREE_CODE (t) == OMP_TASK));
- bsi_remove (&si, true);
- e = split_block (entry_bb, t);
+ /* Split ENTRY_BB at GIMPLE_OMP_PARALLEL or GIMPLE_OMP_TASK,
+ so that it can be moved to the child function. */
+ gsi = gsi_last_bb (entry_bb);
+ stmt = gsi_stmt (gsi);
+ gcc_assert (stmt && (gimple_code (stmt) == GIMPLE_OMP_PARALLEL
+ || gimple_code (stmt) == GIMPLE_OMP_TASK));
+ gsi_remove (&gsi, true);
+ e = split_block (entry_bb, stmt);
entry_bb = e->dest;
single_succ_edge (entry_bb)->flags = EDGE_FALLTHRU;
- /* Convert OMP_RETURN into a RETURN_EXPR. */
+ /* Convert GIMPLE_OMP_RETURN into a RETURN_EXPR. */
if (exit_bb)
{
- si = bsi_last (exit_bb);
- gcc_assert (!bsi_end_p (si)
- && TREE_CODE (bsi_stmt (si)) == OMP_RETURN);
- t = build1 (RETURN_EXPR, void_type_node, NULL);
- bsi_insert_after (&si, t, BSI_SAME_STMT);
- bsi_remove (&si, true);
+ gsi = gsi_last_bb (exit_bb);
+ gcc_assert (!gsi_end_p (gsi)
+ && gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_RETURN);
+ stmt = gimple_build_return (NULL);
+ gsi_insert_after (&gsi, stmt, GSI_SAME_STMT);
+ gsi_remove (&gsi, true);
}
/* Move the parallel region into CHILD_CFUN. */
@@ -3291,7 +3399,7 @@ expand_omp_taskreg (struct omp_region *region)
block = NULL_TREE;
}
else
- block = TREE_BLOCK (entry_stmt);
+ block = gimple_block (entry_stmt);
new_bb = move_sese_region_to_fn (child_cfun, entry_bb, exit_bb, block);
if (exit_bb)
@@ -3328,7 +3436,7 @@ expand_omp_taskreg (struct omp_region *region)
current_function_decl = child_fn;
FOR_EACH_BB (bb)
- changed |= tree_purge_dead_eh_edges (bb);
+ changed |= gimple_purge_dead_eh_edges (bb);
if (changed)
cleanup_tree_cfg ();
current_function_decl = save_current;
@@ -3337,7 +3445,7 @@ expand_omp_taskreg (struct omp_region *region)
}
/* Emit a library call to launch the children threads. */
- if (TREE_CODE (entry_stmt) == OMP_PARALLEL)
+ if (gimple_code (entry_stmt) == GIMPLE_OMP_PARALLEL)
expand_parallel_call (region, new_bb, entry_stmt, ws_args);
else
expand_task_call (new_bb, entry_stmt);
@@ -3431,11 +3539,12 @@ expand_omp_for_generic (struct omp_region *region,
enum built_in_function start_fn,
enum built_in_function next_fn)
{
- tree type, istart0, iend0, iend, phi;
+ tree type, istart0, iend0, iend;
tree t, vmain, vback, bias = NULL_TREE;
basic_block entry_bb, cont_bb, exit_bb, l0_bb, l1_bb, collapse_bb;
basic_block l2_bb = NULL, l3_bb = NULL;
- block_stmt_iterator si;
+ gimple_stmt_iterator gsi;
+ gimple stmt;
bool in_combined_parallel = is_combined_parallel (region);
bool broken_loop = region->cont == NULL;
edge e, ne;
@@ -3499,9 +3608,9 @@ expand_omp_for_generic (struct omp_region *region,
l3_bb = BRANCH_EDGE (entry_bb)->dest;
exit_bb = region->exit;
- si = bsi_last (entry_bb);
+ gsi = gsi_last_bb (entry_bb);
- gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_FOR);
+ gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_FOR);
if (fd->collapse > 1)
{
/* collapsed loops need work for expansion in SSA form. */
@@ -3536,21 +3645,23 @@ expand_omp_for_generic (struct omp_region *region,
else
{
counts[i] = create_tmp_var (type, ".count");
- t = build_gimple_modify_stmt (counts[i], t);
- force_gimple_operand_bsi (&si, t, true, NULL_TREE,
- true, BSI_SAME_STMT);
+ t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
+ true, GSI_SAME_STMT);
+ stmt = gimple_build_assign (counts[i], t);
+ gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
}
if (SSA_VAR_P (fd->loop.n2))
{
if (i == 0)
- t = build_gimple_modify_stmt (fd->loop.n2, counts[0]);
+ t = counts[0];
else
{
t = fold_build2 (MULT_EXPR, type, fd->loop.n2, counts[i]);
- t = build_gimple_modify_stmt (fd->loop.n2, t);
+ t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
+ true, GSI_SAME_STMT);
}
- force_gimple_operand_bsi (&si, t, true, NULL_TREE,
- true, BSI_SAME_STMT);
+ stmt = gimple_build_assign (fd->loop.n2, t);
+ gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
}
}
}
@@ -3615,41 +3726,38 @@ expand_omp_for_generic (struct omp_region *region,
if (TREE_TYPE (t) != boolean_type_node)
t = fold_build2 (NE_EXPR, boolean_type_node,
t, build_int_cst (TREE_TYPE (t), 0));
- t = force_gimple_operand_bsi (&si, t, true, NULL_TREE,
- true, BSI_SAME_STMT);
- t = build3 (COND_EXPR, void_type_node, t, NULL_TREE, NULL_TREE);
- bsi_insert_after (&si, t, BSI_SAME_STMT);
+ t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
+ true, GSI_SAME_STMT);
+ gsi_insert_after (&gsi, gimple_build_cond_empty (t), GSI_SAME_STMT);
- /* Remove the OMP_FOR statement. */
- bsi_remove (&si, true);
+ /* Remove the GIMPLE_OMP_FOR statement. */
+ gsi_remove (&gsi, true);
/* Iteration setup for sequential loop goes in L0_BB. */
- si = bsi_start (l0_bb);
+ gsi = gsi_start_bb (l0_bb);
if (bias)
t = fold_convert (type, fold_build2 (MINUS_EXPR, fd->iter_type,
istart0, bias));
else
t = fold_convert (type, istart0);
- t = force_gimple_operand_bsi (&si, t, false, NULL_TREE,
- false, BSI_CONTINUE_LINKING);
- t = build_gimple_modify_stmt (fd->loop.v, t);
- bsi_insert_after (&si, t, BSI_CONTINUE_LINKING);
- if (gimple_in_ssa_p (cfun))
- SSA_NAME_DEF_STMT (fd->loop.v) = t;
+ t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
+ false, GSI_CONTINUE_LINKING);
+ stmt = gimple_build_assign (fd->loop.v, t);
+ gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
if (bias)
t = fold_convert (type, fold_build2 (MINUS_EXPR, fd->iter_type,
iend0, bias));
else
t = fold_convert (type, iend0);
- iend = force_gimple_operand_bsi (&si, t, true, NULL_TREE,
- false, BSI_CONTINUE_LINKING);
+ iend = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
+ false, GSI_CONTINUE_LINKING);
if (fd->collapse > 1)
{
tree tem = create_tmp_var (type, ".tem");
- t = build_gimple_modify_stmt (tem, fd->loop.v);
- bsi_insert_after (&si, t, BSI_CONTINUE_LINKING);
+ stmt = gimple_build_assign (tem, fd->loop.v);
+ gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
for (i = fd->collapse - 1; i >= 0; i--)
{
tree vtype = TREE_TYPE (fd->loops[i].v), itype;
@@ -3664,15 +3772,17 @@ expand_omp_for_generic (struct omp_region *region,
fd->loops[i].n1, fold_convert (sizetype, t));
else
t = fold_build2 (PLUS_EXPR, itype, fd->loops[i].n1, t);
- t = build_gimple_modify_stmt (fd->loops[i].v, t);
- force_gimple_operand_bsi (&si, t, true, NULL_TREE,
- false, BSI_CONTINUE_LINKING);
+ t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
+ false, GSI_CONTINUE_LINKING);
+ stmt = gimple_build_assign (fd->loops[i].v, t);
+ gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
if (i != 0)
{
t = fold_build2 (TRUNC_DIV_EXPR, type, tem, counts[i]);
- t = build_gimple_modify_stmt (tem, t);
- force_gimple_operand_bsi (&si, t, true, NULL_TREE,
- false, BSI_CONTINUE_LINKING);
+ t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
+ false, GSI_CONTINUE_LINKING);
+ stmt = gimple_build_assign (tem, t);
+ gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
}
}
}
@@ -3681,30 +3791,28 @@ expand_omp_for_generic (struct omp_region *region,
{
/* Code to control the increment and predicate for the sequential
loop goes in the CONT_BB. */
- si = bsi_last (cont_bb);
- t = bsi_stmt (si);
- gcc_assert (TREE_CODE (t) == OMP_CONTINUE);
- vmain = TREE_OPERAND (t, 1);
- vback = TREE_OPERAND (t, 0);
+ gsi = gsi_last_bb (cont_bb);
+ stmt = gsi_stmt (gsi);
+ gcc_assert (gimple_code (stmt) == GIMPLE_OMP_CONTINUE);
+ vmain = gimple_omp_continue_control_use (stmt);
+ vback = gimple_omp_continue_control_def (stmt);
if (POINTER_TYPE_P (type))
t = fold_build2 (POINTER_PLUS_EXPR, type, vmain,
fold_convert (sizetype, fd->loop.step));
else
t = fold_build2 (PLUS_EXPR, type, vmain, fd->loop.step);
- t = force_gimple_operand_bsi (&si, t, false, NULL_TREE,
- true, BSI_SAME_STMT);
- t = build_gimple_modify_stmt (vback, t);
- bsi_insert_before (&si, t, BSI_SAME_STMT);
- if (gimple_in_ssa_p (cfun))
- SSA_NAME_DEF_STMT (vback) = t;
-
+ t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
+ true, GSI_SAME_STMT);
+ stmt = gimple_build_assign (vback, t);
+ gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
+
t = build2 (fd->loop.cond_code, boolean_type_node, vback, iend);
- t = build3 (COND_EXPR, void_type_node, t, NULL_TREE, NULL_TREE);
- bsi_insert_before (&si, t, BSI_SAME_STMT);
+ stmt = gimple_build_cond_empty (t);
+ gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
- /* Remove OMP_CONTINUE. */
- bsi_remove (&si, true);
+ /* Remove GIMPLE_OMP_CONTINUE. */
+ gsi_remove (&gsi, true);
if (fd->collapse > 1)
{
@@ -3716,17 +3824,18 @@ expand_omp_for_generic (struct omp_region *region,
tree vtype = TREE_TYPE (fd->loops[i].v);
bb = create_empty_bb (last_bb);
- si = bsi_start (bb);
+ gsi = gsi_start_bb (bb);
if (i < fd->collapse - 1)
{
e = make_edge (last_bb, bb, EDGE_FALSE_VALUE);
e->probability = REG_BR_PROB_BASE / 8;
- t = build_gimple_modify_stmt (fd->loops[i + 1].v,
- fd->loops[i + 1].n1);
- force_gimple_operand_bsi (&si, t, true, NULL_TREE,
- false, BSI_CONTINUE_LINKING);
+ t = fd->loops[i + 1].n1;
+ t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
+ false, GSI_CONTINUE_LINKING);
+ stmt = gimple_build_assign (fd->loops[i + 1].v, t);
+ gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
}
else
collapse_bb = bb;
@@ -3740,19 +3849,20 @@ expand_omp_for_generic (struct omp_region *region,
else
t = fold_build2 (PLUS_EXPR, vtype, fd->loops[i].v,
fd->loops[i].step);
- t = build_gimple_modify_stmt (fd->loops[i].v, t);
- force_gimple_operand_bsi (&si, t, true, NULL_TREE,
- false, BSI_CONTINUE_LINKING);
+ t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
+ false, GSI_CONTINUE_LINKING);
+ stmt = gimple_build_assign (fd->loops[i].v, t);
+ gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
if (i > 0)
{
+ t = fd->loops[i].n2;
+ t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
+ false, GSI_CONTINUE_LINKING);
t = fold_build2 (fd->loops[i].cond_code, boolean_type_node,
- fd->loops[i].v, fd->loops[i].n2);
- t = force_gimple_operand_bsi (&si, t, false, NULL_TREE,
- false, BSI_CONTINUE_LINKING);
- t = build3 (COND_EXPR, void_type_node, t,
- NULL_TREE, NULL_TREE);
- bsi_insert_after (&si, t, BSI_CONTINUE_LINKING);
+ fd->loops[i].v, t);
+ stmt = gimple_build_cond_empty (t);
+ gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
e = make_edge (bb, l1_bb, EDGE_TRUE_VALUE);
e->probability = REG_BR_PROB_BASE * 7 / 8;
}
@@ -3763,29 +3873,29 @@ expand_omp_for_generic (struct omp_region *region,
}
/* Emit code to get the next parallel iteration in L2_BB. */
- si = bsi_start (l2_bb);
+ gsi = gsi_start_bb (l2_bb);
t = build_call_expr (built_in_decls[next_fn], 2,
build_fold_addr_expr (istart0),
build_fold_addr_expr (iend0));
+ t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
+ false, GSI_CONTINUE_LINKING);
if (TREE_TYPE (t) != boolean_type_node)
t = fold_build2 (NE_EXPR, boolean_type_node,
t, build_int_cst (TREE_TYPE (t), 0));
- t = force_gimple_operand_bsi (&si, t, true, NULL_TREE,
- false, BSI_CONTINUE_LINKING);
- t = build3 (COND_EXPR, void_type_node, t, NULL_TREE, NULL_TREE);
- bsi_insert_after (&si, t, BSI_CONTINUE_LINKING);
+ stmt = gimple_build_cond_empty (t);
+ gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
}
/* Add the loop cleanup function. */
- si = bsi_last (exit_bb);
- if (OMP_RETURN_NOWAIT (bsi_stmt (si)))
+ gsi = gsi_last_bb (exit_bb);
+ if (gimple_omp_return_nowait_p (gsi_stmt (gsi)))
t = built_in_decls[BUILT_IN_GOMP_LOOP_END_NOWAIT];
else
t = built_in_decls[BUILT_IN_GOMP_LOOP_END];
- t = build_call_expr (t, 0);
- bsi_insert_after (&si, t, BSI_SAME_STMT);
- bsi_remove (&si, true);
+ stmt = gimple_build_call (t, 0);
+ gsi_insert_after (&gsi, stmt, GSI_SAME_STMT);
+ gsi_remove (&gsi, true);
/* Connect the new blocks. */
find_edge (entry_bb, l0_bb)->flags = EDGE_TRUE_VALUE;
@@ -3793,12 +3903,18 @@ expand_omp_for_generic (struct omp_region *region,
if (!broken_loop)
{
+ gimple_seq phis;
+
e = find_edge (cont_bb, l3_bb);
ne = make_edge (l2_bb, l3_bb, EDGE_FALSE_VALUE);
- for (phi = phi_nodes (l3_bb); phi; phi = PHI_CHAIN (phi))
- SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (phi, ne),
- PHI_ARG_DEF_FROM_EDGE (phi, e));
+ phis = phi_nodes (l3_bb);
+ for (gsi = gsi_start (phis); !gsi_end_p (gsi); gsi_next (&gsi))
+ {
+ gimple phi = gsi_stmt (gsi);
+ SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (phi, ne),
+ PHI_ARG_DEF_FROM_EDGE (phi, e));
+ }
remove_edge (e);
make_edge (cont_bb, l2_bb, EDGE_FALSE_VALUE);
@@ -3868,7 +3984,8 @@ expand_omp_for_static_nochunk (struct omp_region *region,
tree type, itype, vmain, vback;
basic_block entry_bb, exit_bb, seq_start_bb, body_bb, cont_bb;
basic_block fin_bb;
- block_stmt_iterator si;
+ gimple_stmt_iterator gsi;
+ gimple stmt;
itype = type = TREE_TYPE (fd->loop.v);
if (POINTER_TYPE_P (type))
@@ -3886,28 +4003,28 @@ expand_omp_for_static_nochunk (struct omp_region *region,
exit_bb = region->exit;
/* Iteration space partitioning goes in ENTRY_BB. */
- si = bsi_last (entry_bb);
- gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_FOR);
+ gsi = gsi_last_bb (entry_bb);
+ gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_FOR);
t = build_call_expr (built_in_decls[BUILT_IN_OMP_GET_NUM_THREADS], 0);
t = fold_convert (itype, t);
- nthreads = force_gimple_operand_bsi (&si, t, true, NULL_TREE,
- true, BSI_SAME_STMT);
+ nthreads = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
+ true, GSI_SAME_STMT);
t = build_call_expr (built_in_decls[BUILT_IN_OMP_GET_THREAD_NUM], 0);
t = fold_convert (itype, t);
- threadid = force_gimple_operand_bsi (&si, t, true, NULL_TREE,
- true, BSI_SAME_STMT);
+ threadid = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
+ true, GSI_SAME_STMT);
fd->loop.n1
- = force_gimple_operand_bsi (&si, fold_convert (type, fd->loop.n1),
- true, NULL_TREE, true, BSI_SAME_STMT);
+ = force_gimple_operand_gsi (&gsi, fold_convert (type, fd->loop.n1),
+ true, NULL_TREE, true, GSI_SAME_STMT);
fd->loop.n2
- = force_gimple_operand_bsi (&si, fold_convert (itype, fd->loop.n2),
- true, NULL_TREE, true, BSI_SAME_STMT);
+ = force_gimple_operand_gsi (&gsi, fold_convert (itype, fd->loop.n2),
+ true, NULL_TREE, true, GSI_SAME_STMT);
fd->loop.step
- = force_gimple_operand_bsi (&si, fold_convert (itype, fd->loop.step),
- true, NULL_TREE, true, BSI_SAME_STMT);
+ = force_gimple_operand_gsi (&gsi, fold_convert (itype, fd->loop.step),
+ true, NULL_TREE, true, GSI_SAME_STMT);
t = build_int_cst (itype, (fd->loop.cond_code == LT_EXPR ? -1 : 1));
t = fold_build2 (PLUS_EXPR, itype, fd->loop.step, t);
@@ -3920,32 +4037,31 @@ expand_omp_for_static_nochunk (struct omp_region *region,
else
t = fold_build2 (TRUNC_DIV_EXPR, itype, t, fd->loop.step);
t = fold_convert (itype, t);
- n = force_gimple_operand_bsi (&si, t, true, NULL_TREE, true, BSI_SAME_STMT);
+ n = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE, true, GSI_SAME_STMT);
t = fold_build2 (TRUNC_DIV_EXPR, itype, n, nthreads);
- q = force_gimple_operand_bsi (&si, t, true, NULL_TREE, true, BSI_SAME_STMT);
+ q = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE, true, GSI_SAME_STMT);
t = fold_build2 (MULT_EXPR, itype, q, nthreads);
t = fold_build2 (NE_EXPR, itype, t, n);
t = fold_build2 (PLUS_EXPR, itype, q, t);
- q = force_gimple_operand_bsi (&si, t, true, NULL_TREE, true, BSI_SAME_STMT);
+ q = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE, true, GSI_SAME_STMT);
t = build2 (MULT_EXPR, itype, q, threadid);
- s0 = force_gimple_operand_bsi (&si, t, true, NULL_TREE, true, BSI_SAME_STMT);
+ s0 = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE, true, GSI_SAME_STMT);
t = fold_build2 (PLUS_EXPR, itype, s0, q);
t = fold_build2 (MIN_EXPR, itype, t, n);
- e0 = force_gimple_operand_bsi (&si, t, true, NULL_TREE, true, BSI_SAME_STMT);
+ e0 = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE, true, GSI_SAME_STMT);
t = build2 (GE_EXPR, boolean_type_node, s0, e0);
- t = build3 (COND_EXPR, void_type_node, t, NULL_TREE, NULL_TREE);
- bsi_insert_before (&si, t, BSI_SAME_STMT);
+ gsi_insert_before (&gsi, gimple_build_cond_empty (t), GSI_SAME_STMT);
- /* Remove the OMP_FOR statement. */
- bsi_remove (&si, true);
+ /* Remove the GIMPLE_OMP_FOR statement. */
+ gsi_remove (&gsi, true);
/* Setup code for sequential iteration goes in SEQ_START_BB. */
- si = bsi_start (seq_start_bb);
+ gsi = gsi_start_bb (seq_start_bb);
t = fold_convert (itype, s0);
t = fold_build2 (MULT_EXPR, itype, t, fd->loop.step);
@@ -3954,13 +4070,11 @@ expand_omp_for_static_nochunk (struct omp_region *region,
fold_convert (sizetype, t));
else
t = fold_build2 (PLUS_EXPR, type, t, fd->loop.n1);
- t = force_gimple_operand_bsi (&si, t, false, NULL_TREE,
- false, BSI_CONTINUE_LINKING);
- t = build_gimple_modify_stmt (fd->loop.v, t);
- bsi_insert_after (&si, t, BSI_CONTINUE_LINKING);
- if (gimple_in_ssa_p (cfun))
- SSA_NAME_DEF_STMT (fd->loop.v) = t;
-
+ t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
+ false, GSI_CONTINUE_LINKING);
+ stmt = gimple_build_assign (fd->loop.v, t);
+ gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
+
t = fold_convert (itype, e0);
t = fold_build2 (MULT_EXPR, itype, t, fd->loop.step);
if (POINTER_TYPE_P (type))
@@ -3968,41 +4082,39 @@ expand_omp_for_static_nochunk (struct omp_region *region,
fold_convert (sizetype, t));
else
t = fold_build2 (PLUS_EXPR, type, t, fd->loop.n1);
- e = force_gimple_operand_bsi (&si, t, true, NULL_TREE,
- false, BSI_CONTINUE_LINKING);
+ e = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
+ false, GSI_CONTINUE_LINKING);
- /* The code controlling the sequential loop replaces the OMP_CONTINUE. */
- si = bsi_last (cont_bb);
- t = bsi_stmt (si);
- gcc_assert (TREE_CODE (t) == OMP_CONTINUE);
- vmain = TREE_OPERAND (t, 1);
- vback = TREE_OPERAND (t, 0);
+ /* The code controlling the sequential loop replaces the
+ GIMPLE_OMP_CONTINUE. */
+ gsi = gsi_last_bb (cont_bb);
+ stmt = gsi_stmt (gsi);
+ gcc_assert (gimple_code (stmt) == GIMPLE_OMP_CONTINUE);
+ vmain = gimple_omp_continue_control_use (stmt);
+ vback = gimple_omp_continue_control_def (stmt);
if (POINTER_TYPE_P (type))
t = fold_build2 (POINTER_PLUS_EXPR, type, vmain,
fold_convert (sizetype, fd->loop.step));
else
t = fold_build2 (PLUS_EXPR, type, vmain, fd->loop.step);
- t = force_gimple_operand_bsi (&si, t, false, NULL_TREE,
- true, BSI_SAME_STMT);
- t = build_gimple_modify_stmt (vback, t);
- bsi_insert_before (&si, t, BSI_SAME_STMT);
- if (gimple_in_ssa_p (cfun))
- SSA_NAME_DEF_STMT (vback) = t;
+ t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
+ true, GSI_SAME_STMT);
+ stmt = gimple_build_assign (vback, t);
+ gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
t = build2 (fd->loop.cond_code, boolean_type_node, vback, e);
- t = build3 (COND_EXPR, void_type_node, t, NULL_TREE, NULL_TREE);
- bsi_insert_before (&si, t, BSI_SAME_STMT);
+ gsi_insert_before (&gsi, gimple_build_cond_empty (t), GSI_SAME_STMT);
- /* Remove the OMP_CONTINUE statement. */
- bsi_remove (&si, true);
+ /* Remove the GIMPLE_OMP_CONTINUE statement. */
+ gsi_remove (&gsi, true);
- /* Replace the OMP_RETURN with a barrier, or nothing. */
- si = bsi_last (exit_bb);
- if (!OMP_RETURN_NOWAIT (bsi_stmt (si)))
- force_gimple_operand_bsi (&si, build_omp_barrier (), false, NULL_TREE,
- false, BSI_SAME_STMT);
- bsi_remove (&si, true);
+ /* Replace the GIMPLE_OMP_RETURN with a barrier, or nothing. */
+ gsi = gsi_last_bb (exit_bb);
+ if (!gimple_omp_return_nowait_p (gsi_stmt (gsi)))
+ force_gimple_operand_gsi (&gsi, build_omp_barrier (), false, NULL_TREE,
+ false, GSI_SAME_STMT);
+ gsi_remove (&gsi, true);
/* Connect all the blocks. */
find_edge (entry_bb, seq_start_bb)->flags = EDGE_FALSE_VALUE;
@@ -4057,16 +4169,16 @@ expand_omp_for_static_nochunk (struct omp_region *region,
*/
static void
-expand_omp_for_static_chunk (struct omp_region *region,
- struct omp_for_data *fd)
+expand_omp_for_static_chunk (struct omp_region *region, struct omp_for_data *fd)
{
- tree n, s0, e0, e, t, phi, nphi, args;
+ tree n, s0, e0, e, t;
tree trip_var, trip_init, trip_main, trip_back, nthreads, threadid;
- tree type, itype, cont, v_main, v_back, v_extra;
+ tree type, itype, v_main, v_back, v_extra;
basic_block entry_bb, exit_bb, body_bb, seq_start_bb, iter_part_bb;
basic_block trip_update_bb, cont_bb, fin_bb;
- block_stmt_iterator si;
- edge se, re, ene;
+ gimple_stmt_iterator si;
+ gimple stmt;
+ edge se;
itype = type = TREE_TYPE (fd->loop.v);
if (POINTER_TYPE_P (type))
@@ -4089,31 +4201,31 @@ expand_omp_for_static_chunk (struct omp_region *region,
exit_bb = region->exit;
/* Trip and adjustment setup goes in ENTRY_BB. */
- si = bsi_last (entry_bb);
- gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_FOR);
+ si = gsi_last_bb (entry_bb);
+ gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_FOR);
t = build_call_expr (built_in_decls[BUILT_IN_OMP_GET_NUM_THREADS], 0);
t = fold_convert (itype, t);
- nthreads = force_gimple_operand_bsi (&si, t, true, NULL_TREE,
- true, BSI_SAME_STMT);
+ nthreads = force_gimple_operand_gsi (&si, t, true, NULL_TREE,
+ true, GSI_SAME_STMT);
t = build_call_expr (built_in_decls[BUILT_IN_OMP_GET_THREAD_NUM], 0);
t = fold_convert (itype, t);
- threadid = force_gimple_operand_bsi (&si, t, true, NULL_TREE,
- true, BSI_SAME_STMT);
+ threadid = force_gimple_operand_gsi (&si, t, true, NULL_TREE,
+ true, GSI_SAME_STMT);
fd->loop.n1
- = force_gimple_operand_bsi (&si, fold_convert (type, fd->loop.n1),
- true, NULL_TREE, true, BSI_SAME_STMT);
+ = force_gimple_operand_gsi (&si, fold_convert (type, fd->loop.n1),
+ true, NULL_TREE, true, GSI_SAME_STMT);
fd->loop.n2
- = force_gimple_operand_bsi (&si, fold_convert (itype, fd->loop.n2),
- true, NULL_TREE, true, BSI_SAME_STMT);
+ = force_gimple_operand_gsi (&si, fold_convert (itype, fd->loop.n2),
+ true, NULL_TREE, true, GSI_SAME_STMT);
fd->loop.step
- = force_gimple_operand_bsi (&si, fold_convert (itype, fd->loop.step),
- true, NULL_TREE, true, BSI_SAME_STMT);
+ = force_gimple_operand_gsi (&si, fold_convert (itype, fd->loop.step),
+ true, NULL_TREE, true, GSI_SAME_STMT);
fd->chunk_size
- = force_gimple_operand_bsi (&si, fold_convert (itype, fd->chunk_size),
- true, NULL_TREE, true, BSI_SAME_STMT);
+ = force_gimple_operand_gsi (&si, fold_convert (itype, fd->chunk_size),
+ true, NULL_TREE, true, GSI_SAME_STMT);
t = build_int_cst (itype, (fd->loop.cond_code == LT_EXPR ? -1 : 1));
t = fold_build2 (PLUS_EXPR, itype, fd->loop.step, t);
@@ -4126,16 +4238,16 @@ expand_omp_for_static_chunk (struct omp_region *region,
else
t = fold_build2 (TRUNC_DIV_EXPR, itype, t, fd->loop.step);
t = fold_convert (itype, t);
- n = force_gimple_operand_bsi (&si, t, true, NULL_TREE,
- true, BSI_SAME_STMT);
+ n = force_gimple_operand_gsi (&si, t, true, NULL_TREE,
+ true, GSI_SAME_STMT);
trip_var = create_tmp_var (itype, ".trip");
if (gimple_in_ssa_p (cfun))
{
add_referenced_var (trip_var);
- trip_init = make_ssa_name (trip_var, NULL_TREE);
- trip_main = make_ssa_name (trip_var, NULL_TREE);
- trip_back = make_ssa_name (trip_var, NULL_TREE);
+ trip_init = make_ssa_name (trip_var, NULL);
+ trip_main = make_ssa_name (trip_var, NULL);
+ trip_back = make_ssa_name (trip_var, NULL);
}
else
{
@@ -4144,10 +4256,8 @@ expand_omp_for_static_chunk (struct omp_region *region,
trip_back = trip_var;
}
- t = build_gimple_modify_stmt (trip_init, build_int_cst (itype, 0));
- bsi_insert_before (&si, t, BSI_SAME_STMT);
- if (gimple_in_ssa_p (cfun))
- SSA_NAME_DEF_STMT (trip_init) = t;
+ stmt = gimple_build_assign (trip_init, build_int_cst (itype, 0));
+ gsi_insert_before (&si, stmt, GSI_SAME_STMT);
t = fold_build2 (MULT_EXPR, itype, threadid, fd->chunk_size);
t = fold_build2 (MULT_EXPR, itype, t, fd->loop.step);
@@ -4156,32 +4266,31 @@ expand_omp_for_static_chunk (struct omp_region *region,
fold_convert (sizetype, t));
else
t = fold_build2 (PLUS_EXPR, type, t, fd->loop.n1);
- v_extra = force_gimple_operand_bsi (&si, t, true, NULL_TREE,
- true, BSI_SAME_STMT);
+ v_extra = force_gimple_operand_gsi (&si, t, true, NULL_TREE,
+ true, GSI_SAME_STMT);
- /* Remove the OMP_FOR. */
- bsi_remove (&si, true);
+ /* Remove the GIMPLE_OMP_FOR. */
+ gsi_remove (&si, true);
/* Iteration space partitioning goes in ITER_PART_BB. */
- si = bsi_last (iter_part_bb);
+ si = gsi_last_bb (iter_part_bb);
t = fold_build2 (MULT_EXPR, itype, trip_main, nthreads);
t = fold_build2 (PLUS_EXPR, itype, t, threadid);
t = fold_build2 (MULT_EXPR, itype, t, fd->chunk_size);
- s0 = force_gimple_operand_bsi (&si, t, true, NULL_TREE,
- false, BSI_CONTINUE_LINKING);
+ s0 = force_gimple_operand_gsi (&si, t, true, NULL_TREE,
+ false, GSI_CONTINUE_LINKING);
t = fold_build2 (PLUS_EXPR, itype, s0, fd->chunk_size);
t = fold_build2 (MIN_EXPR, itype, t, n);
- e0 = force_gimple_operand_bsi (&si, t, true, NULL_TREE,
- false, BSI_CONTINUE_LINKING);
+ e0 = force_gimple_operand_gsi (&si, t, true, NULL_TREE,
+ false, GSI_CONTINUE_LINKING);
t = build2 (LT_EXPR, boolean_type_node, s0, n);
- t = build3 (COND_EXPR, void_type_node, t, NULL_TREE, NULL_TREE);
- bsi_insert_after (&si, t, BSI_CONTINUE_LINKING);
+ gsi_insert_after (&si, gimple_build_cond_empty (t), GSI_CONTINUE_LINKING);
/* Setup code for sequential iteration goes in SEQ_START_BB. */
- si = bsi_start (seq_start_bb);
+ si = gsi_start_bb (seq_start_bb);
t = fold_convert (itype, s0);
t = fold_build2 (MULT_EXPR, itype, t, fd->loop.step);
@@ -4190,12 +4299,10 @@ expand_omp_for_static_chunk (struct omp_region *region,
fold_convert (sizetype, t));
else
t = fold_build2 (PLUS_EXPR, type, t, fd->loop.n1);
- t = force_gimple_operand_bsi (&si, t, false, NULL_TREE,
- false, BSI_CONTINUE_LINKING);
- t = build_gimple_modify_stmt (fd->loop.v, t);
- bsi_insert_after (&si, t, BSI_CONTINUE_LINKING);
- if (gimple_in_ssa_p (cfun))
- SSA_NAME_DEF_STMT (fd->loop.v) = t;
+ t = force_gimple_operand_gsi (&si, t, false, NULL_TREE,
+ false, GSI_CONTINUE_LINKING);
+ stmt = gimple_build_assign (fd->loop.v, t);
+ gsi_insert_after (&si, stmt, GSI_CONTINUE_LINKING);
t = fold_convert (itype, e0);
t = fold_build2 (MULT_EXPR, itype, t, fd->loop.step);
@@ -4204,50 +4311,45 @@ expand_omp_for_static_chunk (struct omp_region *region,
fold_convert (sizetype, t));
else
t = fold_build2 (PLUS_EXPR, type, t, fd->loop.n1);
- e = force_gimple_operand_bsi (&si, t, true, NULL_TREE,
- false, BSI_CONTINUE_LINKING);
+ e = force_gimple_operand_gsi (&si, t, true, NULL_TREE,
+ false, GSI_CONTINUE_LINKING);
/* The code controlling the sequential loop goes in CONT_BB,
- replacing the OMP_CONTINUE. */
- si = bsi_last (cont_bb);
- cont = bsi_stmt (si);
- gcc_assert (TREE_CODE (cont) == OMP_CONTINUE);
- v_main = TREE_OPERAND (cont, 1);
- v_back = TREE_OPERAND (cont, 0);
+ replacing the GIMPLE_OMP_CONTINUE. */
+ si = gsi_last_bb (cont_bb);
+ stmt = gsi_stmt (si);
+ gcc_assert (gimple_code (stmt) == GIMPLE_OMP_CONTINUE);
+ v_main = gimple_omp_continue_control_use (stmt);
+ v_back = gimple_omp_continue_control_def (stmt);
if (POINTER_TYPE_P (type))
t = fold_build2 (POINTER_PLUS_EXPR, type, v_main,
fold_convert (sizetype, fd->loop.step));
else
- t = build2 (PLUS_EXPR, type, v_main, fd->loop.step);
- t = build_gimple_modify_stmt (v_back, t);
- bsi_insert_before (&si, t, BSI_SAME_STMT);
- if (gimple_in_ssa_p (cfun))
- SSA_NAME_DEF_STMT (v_back) = t;
+ t = fold_build2 (PLUS_EXPR, type, v_main, fd->loop.step);
+ stmt = gimple_build_assign (v_back, t);
+ gsi_insert_before (&si, stmt, GSI_SAME_STMT);
t = build2 (fd->loop.cond_code, boolean_type_node, v_back, e);
- t = build3 (COND_EXPR, void_type_node, t, NULL_TREE, NULL_TREE);
- bsi_insert_before (&si, t, BSI_SAME_STMT);
+ gsi_insert_before (&si, gimple_build_cond_empty (t), GSI_SAME_STMT);
- /* Remove OMP_CONTINUE. */
- bsi_remove (&si, true);
+ /* Remove GIMPLE_OMP_CONTINUE. */
+ gsi_remove (&si, true);
/* Trip update code goes into TRIP_UPDATE_BB. */
- si = bsi_start (trip_update_bb);
+ si = gsi_start_bb (trip_update_bb);
t = build_int_cst (itype, 1);
t = build2 (PLUS_EXPR, itype, trip_main, t);
- t = build_gimple_modify_stmt (trip_back, t);
- bsi_insert_after (&si, t, BSI_CONTINUE_LINKING);
- if (gimple_in_ssa_p (cfun))
- SSA_NAME_DEF_STMT (trip_back) = t;
+ stmt = gimple_build_assign (trip_back, t);
+ gsi_insert_after (&si, stmt, GSI_CONTINUE_LINKING);
- /* Replace the OMP_RETURN with a barrier, or nothing. */
- si = bsi_last (exit_bb);
- if (!OMP_RETURN_NOWAIT (bsi_stmt (si)))
- force_gimple_operand_bsi (&si, build_omp_barrier (), false, NULL_TREE,
- false, BSI_SAME_STMT);
- bsi_remove (&si, true);
+ /* Replace the GIMPLE_OMP_RETURN with a barrier, or nothing. */
+ si = gsi_last_bb (exit_bb);
+ if (!gimple_omp_return_nowait_p (gsi_stmt (si)))
+ force_gimple_operand_gsi (&si, build_omp_barrier (), false, NULL_TREE,
+ false, GSI_SAME_STMT);
+ gsi_remove (&si, true);
/* Connect the new blocks. */
find_edge (iter_part_bb, seq_start_bb)->flags = EDGE_TRUE_VALUE;
@@ -4260,21 +4362,30 @@ expand_omp_for_static_chunk (struct omp_region *region,
if (gimple_in_ssa_p (cfun))
{
+ gimple_stmt_iterator psi;
+ gimple phi;
+ edge re, ene;
+ edge_var_map_vector head;
+ edge_var_map *vm;
+ size_t i;
+
/* When we redirect the edge from trip_update_bb to iter_part_bb, we
remove arguments of the phi nodes in fin_bb. We need to create
appropriate phi nodes in iter_part_bb instead. */
se = single_pred_edge (fin_bb);
re = single_succ_edge (trip_update_bb);
+ head = redirect_edge_var_map_vector (re);
ene = single_succ_edge (entry_bb);
- args = PENDING_STMT (re);
- PENDING_STMT (re) = NULL_TREE;
- for (phi = phi_nodes (fin_bb);
- phi && args;
- phi = PHI_CHAIN (phi), args = TREE_CHAIN (args))
+ psi = gsi_start_phis (fin_bb);
+ for (i = 0; !gsi_end_p (psi) && VEC_iterate (edge_var_map, head, i, vm);
+ gsi_next (&psi), ++i)
{
- t = PHI_RESULT (phi);
- gcc_assert (t == TREE_PURPOSE (args));
+ gimple nphi;
+
+ phi = gsi_stmt (psi);
+ t = gimple_phi_result (phi);
+ gcc_assert (t == redirect_edge_var_map_result (vm));
nphi = create_phi_node (t, iter_part_bb);
SSA_NAME_DEF_STMT (t) = nphi;
@@ -4284,11 +4395,17 @@ expand_omp_for_static_chunk (struct omp_region *region,
if (t == fd->loop.v)
t = v_extra;
add_phi_arg (nphi, t, ene);
- add_phi_arg (nphi, TREE_VALUE (args), re);
+ add_phi_arg (nphi, redirect_edge_var_map_def (vm), re);
+ }
+ gcc_assert (!gsi_end_p (psi) && i == VEC_length (edge_var_map, head));
+ redirect_edge_var_map_clear (re);
+ while (1)
+ {
+ psi = gsi_start_phis (fin_bb);
+ if (gsi_end_p (psi))
+ break;
+ remove_phi_node (&psi, false);
}
- gcc_assert (!phi && !args);
- while ((phi = phi_nodes (fin_bb)) != NULL_TREE)
- remove_phi_node (phi, NULL_TREE, false);
/* Make phi node for trip. */
phi = create_phi_node (trip_main, iter_part_bb);
@@ -4319,9 +4436,8 @@ expand_omp_for (struct omp_region *region)
loops
= (struct omp_for_data_loop *)
- alloca (TREE_VEC_LENGTH (OMP_FOR_INIT (last_stmt (region->entry)))
+ alloca (gimple_omp_for_collapse (last_stmt (region->entry))
* sizeof (struct omp_for_data_loop));
-
extract_omp_for_data (last_stmt (region->entry), &fd, loops);
region->sched_kind = fd.sched_kind;
@@ -4351,7 +4467,7 @@ expand_omp_for (struct omp_region *region)
gcc_assert (fd.sched_kind != OMP_CLAUSE_SCHEDULE_AUTO);
fn_index = (fd.sched_kind == OMP_CLAUSE_SCHEDULE_RUNTIME)
- ? 3 : fd.sched_kind;
+ ? 3 : fd.sched_kind;
fn_index += fd.have_ordered * 4;
start_ix = BUILT_IN_GOMP_LOOP_STATIC_START + fn_index;
next_ix = BUILT_IN_GOMP_LOOP_STATIC_NEXT + fn_index;
@@ -4399,13 +4515,16 @@ expand_omp_for (struct omp_region *region)
static void
expand_omp_sections (struct omp_region *region)
{
- tree label_vec, l1, l2, t, u, sections_stmt, vin, vmain, vnext, cont;
- unsigned i, casei, len;
+ tree t, u, vin = NULL, vmain, vnext, l1, l2;
+ VEC (tree,heap) *label_vec;
+ unsigned len;
basic_block entry_bb, l0_bb, l1_bb, l2_bb, default_bb;
- block_stmt_iterator si;
+ gimple_stmt_iterator si, switch_si;
+ gimple sections_stmt, stmt, cont;
edge_iterator ei;
edge e;
struct omp_region *inner;
+ unsigned i, casei;
bool exit_reachable = region->cont != NULL;
gcc_assert (exit_reachable == (region->exit != NULL));
@@ -4416,50 +4535,55 @@ expand_omp_sections (struct omp_region *region)
if (exit_reachable)
{
if (single_pred (l2_bb) == l0_bb)
- l2 = tree_block_label (l2_bb);
+ l2 = gimple_block_label (l2_bb);
else
{
/* This can happen if there are reductions. */
len = EDGE_COUNT (l0_bb->succs);
gcc_assert (len > 0);
e = EDGE_SUCC (l0_bb, len - 1);
- si = bsi_last (e->dest);
+ si = gsi_last_bb (e->dest);
l2 = NULL_TREE;
- if (bsi_end_p (si) || TREE_CODE (bsi_stmt (si)) != OMP_SECTION)
- l2 = tree_block_label (e->dest);
+ if (gsi_end_p (si)
+ || gimple_code (gsi_stmt (si)) != GIMPLE_OMP_SECTION)
+ l2 = gimple_block_label (e->dest);
else
FOR_EACH_EDGE (e, ei, l0_bb->succs)
{
- si = bsi_last (e->dest);
- if (bsi_end_p (si) || TREE_CODE (bsi_stmt (si)) != OMP_SECTION)
+ si = gsi_last_bb (e->dest);
+ if (gsi_end_p (si)
+ || gimple_code (gsi_stmt (si)) != GIMPLE_OMP_SECTION)
{
- l2 = tree_block_label (e->dest);
+ l2 = gimple_block_label (e->dest);
break;
}
}
}
default_bb = create_empty_bb (l1_bb->prev_bb);
- l1 = tree_block_label (l1_bb);
+ l1 = gimple_block_label (l1_bb);
}
else
{
default_bb = create_empty_bb (l0_bb);
l1 = NULL_TREE;
- l2 = tree_block_label (default_bb);
+ l2 = gimple_block_label (default_bb);
}
/* We will build a switch() with enough cases for all the
- OMP_SECTION regions, a '0' case to handle the end of more work
+ GIMPLE_OMP_SECTION regions, a '0' case to handle the end of more work
and a default case to abort if something goes wrong. */
len = EDGE_COUNT (l0_bb->succs);
- label_vec = make_tree_vec (len + 1);
+
+ /* Use VEC_quick_push on label_vec throughout, since we know the size
+ in advance. */
+ label_vec = VEC_alloc (tree, heap, len);
/* The call to GOMP_sections_start goes in ENTRY_BB, replacing the
- OMP_SECTIONS statement. */
- si = bsi_last (entry_bb);
- sections_stmt = bsi_stmt (si);
- gcc_assert (TREE_CODE (sections_stmt) == OMP_SECTIONS);
- vin = OMP_SECTIONS_CONTROL (sections_stmt);
+ GIMPLE_OMP_SECTIONS statement. */
+ si = gsi_last_bb (entry_bb);
+ sections_stmt = gsi_stmt (si);
+ gcc_assert (gimple_code (sections_stmt) == GIMPLE_OMP_SECTIONS);
+ vin = gimple_omp_sections_control (sections_stmt);
if (!is_combined_parallel (region))
{
/* If we are not inside a combined parallel+sections region,
@@ -4467,29 +4591,28 @@ expand_omp_sections (struct omp_region *region)
t = build_int_cst (unsigned_type_node,
exit_reachable ? len - 1 : len);
u = built_in_decls[BUILT_IN_GOMP_SECTIONS_START];
- t = build_call_expr (u, 1, t);
+ stmt = gimple_build_call (u, 1, t);
}
else
{
/* Otherwise, call GOMP_sections_next. */
u = built_in_decls[BUILT_IN_GOMP_SECTIONS_NEXT];
- t = build_call_expr (u, 0);
+ stmt = gimple_build_call (u, 0);
}
- t = build_gimple_modify_stmt (vin, t);
- bsi_insert_after (&si, t, BSI_SAME_STMT);
- if (gimple_in_ssa_p (cfun))
- SSA_NAME_DEF_STMT (vin) = t;
- bsi_remove (&si, true);
-
- /* The switch() statement replacing OMP_SECTIONS_SWITCH goes in L0_BB. */
- si = bsi_last (l0_bb);
- gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_SECTIONS_SWITCH);
+ gimple_call_set_lhs (stmt, vin);
+ gsi_insert_after (&si, stmt, GSI_SAME_STMT);
+ gsi_remove (&si, true);
+
+ /* The switch() statement replacing GIMPLE_OMP_SECTIONS_SWITCH goes in
+ L0_BB. */
+ switch_si = gsi_last_bb (l0_bb);
+ gcc_assert (gimple_code (gsi_stmt (switch_si)) == GIMPLE_OMP_SECTIONS_SWITCH);
if (exit_reachable)
{
cont = last_stmt (l1_bb);
- gcc_assert (TREE_CODE (cont) == OMP_CONTINUE);
- vmain = TREE_OPERAND (cont, 1);
- vnext = TREE_OPERAND (cont, 0);
+ gcc_assert (gimple_code (cont) == GIMPLE_OMP_CONTINUE);
+ vmain = gimple_omp_continue_control_use (cont);
+ vnext = gimple_omp_continue_control_def (cont);
}
else
{
@@ -4497,20 +4620,16 @@ expand_omp_sections (struct omp_region *region)
vnext = NULL_TREE;
}
- t = build3 (SWITCH_EXPR, void_type_node, vmain, NULL, label_vec);
- bsi_insert_after (&si, t, BSI_SAME_STMT);
- bsi_remove (&si, true);
-
i = 0;
if (exit_reachable)
{
t = build3 (CASE_LABEL_EXPR, void_type_node,
build_int_cst (unsigned_type_node, 0), NULL, l2);
- TREE_VEC_ELT (label_vec, 0) = t;
+ VEC_quick_push (tree, label_vec, t);
i++;
}
- /* Convert each OMP_SECTION into a CASE_LABEL_EXPR. */
+ /* Convert each GIMPLE_OMP_SECTION into a CASE_LABEL_EXPR. */
for (inner = region->inner, casei = 1;
inner;
inner = inner->next, i++, casei++)
@@ -4518,7 +4637,7 @@ expand_omp_sections (struct omp_region *region)
basic_block s_entry_bb, s_exit_bb;
/* Skip optional reduction region. */
- if (inner->type == OMP_ATOMIC_LOAD)
+ if (inner->type == GIMPLE_OMP_ATOMIC_LOAD)
{
--i;
--casei;
@@ -4528,61 +4647,63 @@ expand_omp_sections (struct omp_region *region)
s_entry_bb = inner->entry;
s_exit_bb = inner->exit;
- t = tree_block_label (s_entry_bb);
+ t = gimple_block_label (s_entry_bb);
u = build_int_cst (unsigned_type_node, casei);
u = build3 (CASE_LABEL_EXPR, void_type_node, u, NULL, t);
- TREE_VEC_ELT (label_vec, i) = u;
+ VEC_quick_push (tree, label_vec, u);
- si = bsi_last (s_entry_bb);
- gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_SECTION);
- gcc_assert (i < len || OMP_SECTION_LAST (bsi_stmt (si)));
- bsi_remove (&si, true);
+ si = gsi_last_bb (s_entry_bb);
+ gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_SECTION);
+ gcc_assert (i < len || gimple_omp_section_last_p (gsi_stmt (si)));
+ gsi_remove (&si, true);
single_succ_edge (s_entry_bb)->flags = EDGE_FALLTHRU;
if (s_exit_bb == NULL)
continue;
- si = bsi_last (s_exit_bb);
- gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_RETURN);
- bsi_remove (&si, true);
+ si = gsi_last_bb (s_exit_bb);
+ gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_RETURN);
+ gsi_remove (&si, true);
single_succ_edge (s_exit_bb)->flags = EDGE_FALLTHRU;
}
/* Error handling code goes in DEFAULT_BB. */
- t = tree_block_label (default_bb);
+ t = gimple_block_label (default_bb);
u = build3 (CASE_LABEL_EXPR, void_type_node, NULL, NULL, t);
- TREE_VEC_ELT (label_vec, len) = u;
make_edge (l0_bb, default_bb, 0);
- si = bsi_start (default_bb);
- t = build_call_expr (built_in_decls[BUILT_IN_TRAP], 0);
- bsi_insert_after (&si, t, BSI_CONTINUE_LINKING);
+ stmt = gimple_build_switch_vec (vmain, u, label_vec);
+ gsi_insert_after (&switch_si, stmt, GSI_SAME_STMT);
+ gsi_remove (&switch_si, true);
+ VEC_free (tree, heap, label_vec);
+
+ si = gsi_start_bb (default_bb);
+ stmt = gimple_build_call (built_in_decls[BUILT_IN_TRAP], 0);
+ gsi_insert_after (&si, stmt, GSI_CONTINUE_LINKING);
if (exit_reachable)
{
/* Code to get the next section goes in L1_BB. */
- si = bsi_last (l1_bb);
- gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_CONTINUE);
+ si = gsi_last_bb (l1_bb);
+ gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_CONTINUE);
- t = build_call_expr (built_in_decls[BUILT_IN_GOMP_SECTIONS_NEXT], 0);
- t = build_gimple_modify_stmt (vnext, t);
- bsi_insert_after (&si, t, BSI_SAME_STMT);
- if (gimple_in_ssa_p (cfun))
- SSA_NAME_DEF_STMT (vnext) = t;
- bsi_remove (&si, true);
+ stmt = gimple_build_call (built_in_decls[BUILT_IN_GOMP_SECTIONS_NEXT], 0);
+ gimple_call_set_lhs (stmt, vnext);
+ gsi_insert_after (&si, stmt, GSI_SAME_STMT);
+ gsi_remove (&si, true);
single_succ_edge (l1_bb)->flags = EDGE_FALLTHRU;
- /* Cleanup function replaces OMP_RETURN in EXIT_BB. */
- si = bsi_last (l2_bb);
- if (OMP_RETURN_NOWAIT (bsi_stmt (si)))
+ /* Cleanup function replaces GIMPLE_OMP_RETURN in EXIT_BB. */
+ si = gsi_last_bb (l2_bb);
+ if (gimple_omp_return_nowait_p (gsi_stmt (si)))
t = built_in_decls[BUILT_IN_GOMP_SECTIONS_END_NOWAIT];
else
t = built_in_decls[BUILT_IN_GOMP_SECTIONS_END];
- t = build_call_expr (t, 0);
- bsi_insert_after (&si, t, BSI_SAME_STMT);
- bsi_remove (&si, true);
+ stmt = gimple_build_call (t, 0);
+ gsi_insert_after (&si, stmt, GSI_SAME_STMT);
+ gsi_remove (&si, true);
}
set_immediate_dominator (CDI_DOMINATORS, default_bb, l0_bb);
@@ -4596,28 +4717,28 @@ static void
expand_omp_single (struct omp_region *region)
{
basic_block entry_bb, exit_bb;
- block_stmt_iterator si;
+ gimple_stmt_iterator si;
bool need_barrier = false;
entry_bb = region->entry;
exit_bb = region->exit;
- si = bsi_last (entry_bb);
+ si = gsi_last_bb (entry_bb);
/* The terminal barrier at the end of a GOMP_single_copy sequence cannot
be removed. We need to ensure that the thread that entered the single
does not exit before the data is copied out by the other threads. */
- if (find_omp_clause (OMP_SINGLE_CLAUSES (bsi_stmt (si)),
+ if (find_omp_clause (gimple_omp_single_clauses (gsi_stmt (si)),
OMP_CLAUSE_COPYPRIVATE))
need_barrier = true;
- gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_SINGLE);
- bsi_remove (&si, true);
+ gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_SINGLE);
+ gsi_remove (&si, true);
single_succ_edge (entry_bb)->flags = EDGE_FALLTHRU;
- si = bsi_last (exit_bb);
- if (!OMP_RETURN_NOWAIT (bsi_stmt (si)) || need_barrier)
- force_gimple_operand_bsi (&si, build_omp_barrier (), false, NULL_TREE,
- false, BSI_SAME_STMT);
- bsi_remove (&si, true);
+ si = gsi_last_bb (exit_bb);
+ if (!gimple_omp_return_nowait_p (gsi_stmt (si)) || need_barrier)
+ force_gimple_operand_gsi (&si, build_omp_barrier (), false, NULL_TREE,
+ false, GSI_SAME_STMT);
+ gsi_remove (&si, true);
single_succ_edge (exit_bb)->flags = EDGE_FALLTHRU;
}
@@ -4630,24 +4751,24 @@ static void
expand_omp_synch (struct omp_region *region)
{
basic_block entry_bb, exit_bb;
- block_stmt_iterator si;
+ gimple_stmt_iterator si;
entry_bb = region->entry;
exit_bb = region->exit;
- si = bsi_last (entry_bb);
- gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_SINGLE
- || TREE_CODE (bsi_stmt (si)) == OMP_MASTER
- || TREE_CODE (bsi_stmt (si)) == OMP_ORDERED
- || TREE_CODE (bsi_stmt (si)) == OMP_CRITICAL);
- bsi_remove (&si, true);
+ si = gsi_last_bb (entry_bb);
+ gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_SINGLE
+ || gimple_code (gsi_stmt (si)) == GIMPLE_OMP_MASTER
+ || gimple_code (gsi_stmt (si)) == GIMPLE_OMP_ORDERED
+ || gimple_code (gsi_stmt (si)) == GIMPLE_OMP_CRITICAL);
+ gsi_remove (&si, true);
single_succ_edge (entry_bb)->flags = EDGE_FALLTHRU;
if (exit_bb)
{
- si = bsi_last (exit_bb);
- gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_RETURN);
- bsi_remove (&si, true);
+ si = gsi_last_bb (exit_bb);
+ gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_RETURN);
+ gsi_remove (&si, true);
single_succ_edge (exit_bb)->flags = EDGE_FALLTHRU;
}
}
@@ -4667,38 +4788,36 @@ expand_omp_atomic_fetch_op (basic_block load_bb,
enum insn_code *optab;
tree rhs;
basic_block store_bb = single_succ (load_bb);
- block_stmt_iterator bsi;
- tree stmt;
+ gimple_stmt_iterator gsi;
+ gimple stmt;
/* We expect to find the following sequences:
load_bb:
- OMP_ATOMIC_LOAD (tmp, mem)
+ GIMPLE_OMP_ATOMIC_LOAD (tmp, mem)
store_bb:
val = tmp OP something; (or: something OP tmp)
- OMP_STORE (val)
+ GIMPLE_OMP_STORE (val)
???FIXME: Allow a more flexible sequence.
Perhaps use data flow to pick the statements.
*/
- bsi = bsi_after_labels (store_bb);
- stmt = bsi_stmt (bsi);
- if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT)
+ gsi = gsi_after_labels (store_bb);
+ stmt = gsi_stmt (gsi);
+ if (!is_gimple_assign (stmt))
return false;
- bsi_next (&bsi);
- if (TREE_CODE (bsi_stmt (bsi)) != OMP_ATOMIC_STORE)
+ gsi_next (&gsi);
+ if (gimple_code (gsi_stmt (gsi)) != GIMPLE_OMP_ATOMIC_STORE)
return false;
- if (!operand_equal_p (GIMPLE_STMT_OPERAND (stmt, 0), stored_val, 0))
+ if (!operand_equal_p (gimple_assign_lhs (stmt), stored_val, 0))
return false;
- rhs = GIMPLE_STMT_OPERAND (stmt, 1);
-
/* Check for one of the supported fetch-op operations. */
- switch (TREE_CODE (rhs))
+ switch (gimple_assign_rhs_code (stmt))
{
case PLUS_EXPR:
case POINTER_PLUS_EXPR:
@@ -4725,11 +4844,11 @@ expand_omp_atomic_fetch_op (basic_block load_bb,
return false;
}
/* Make sure the expression is of the proper form. */
- if (operand_equal_p (TREE_OPERAND (rhs, 0), loaded_val, 0))
- rhs = TREE_OPERAND (rhs, 1);
- else if (commutative_tree_code (TREE_CODE (rhs))
- && operand_equal_p (TREE_OPERAND (rhs, 1), loaded_val, 0))
- rhs = TREE_OPERAND (rhs, 0);
+ if (operand_equal_p (gimple_assign_rhs1 (stmt), loaded_val, 0))
+ rhs = gimple_assign_rhs2 (stmt);
+ else if (commutative_tree_code (gimple_assign_rhs_code (stmt))
+ && operand_equal_p (gimple_assign_rhs2 (stmt), loaded_val, 0))
+ rhs = gimple_assign_rhs1 (stmt);
else
return false;
@@ -4739,17 +4858,18 @@ expand_omp_atomic_fetch_op (basic_block load_bb,
if (optab[TYPE_MODE (itype)] == CODE_FOR_nothing)
return false;
- bsi = bsi_last (load_bb);
- gcc_assert (TREE_CODE (bsi_stmt (bsi)) == OMP_ATOMIC_LOAD);
+ gsi = gsi_last_bb (load_bb);
+ gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_ATOMIC_LOAD);
call = build_call_expr (decl, 2, addr, fold_convert (itype, rhs));
- force_gimple_operand_bsi (&bsi, call, true, NULL_TREE, true, BSI_SAME_STMT);
- bsi_remove (&bsi, true);
+ call = fold_convert (void_type_node, call);
+ force_gimple_operand_gsi (&gsi, call, true, NULL_TREE, true, GSI_SAME_STMT);
+ gsi_remove (&gsi, true);
- bsi = bsi_last (store_bb);
- gcc_assert (TREE_CODE (bsi_stmt (bsi)) == OMP_ATOMIC_STORE);
- bsi_remove (&bsi, true);
- bsi = bsi_last (store_bb);
- bsi_remove (&bsi, true);
+ gsi = gsi_last_bb (store_bb);
+ gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_ATOMIC_STORE);
+ gsi_remove (&gsi, true);
+ gsi = gsi_last_bb (store_bb);
+ gsi_remove (&gsi, true);
if (gimple_in_ssa_p (cfun))
update_ssa (TODO_update_ssa_no_phi);
@@ -4776,9 +4896,9 @@ expand_omp_atomic_pipeline (basic_block load_bb, basic_block store_bb,
{
tree loadedi, storedi, initial, new_storedi, old_vali;
tree type, itype, cmpxchg, iaddr;
- block_stmt_iterator bsi;
+ gimple_stmt_iterator si;
basic_block loop_header = single_succ (load_bb);
- tree phi, x;
+ gimple phi, stmt;
edge e;
cmpxchg = built_in_decls[BUILT_IN_VAL_COMPARE_AND_SWAP_N + index + 1];
@@ -4788,19 +4908,24 @@ expand_omp_atomic_pipeline (basic_block load_bb, basic_block store_bb,
if (sync_compare_and_swap[TYPE_MODE (itype)] == CODE_FOR_nothing)
return false;
- /* Load the initial value, replacing the OMP_ATOMIC_LOAD. */
- bsi = bsi_last (load_bb);
- gcc_assert (TREE_CODE (bsi_stmt (bsi)) == OMP_ATOMIC_LOAD);
+ /* Load the initial value, replacing the GIMPLE_OMP_ATOMIC_LOAD. */
+ si = gsi_last_bb (load_bb);
+ gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_ATOMIC_LOAD);
+
/* For floating-point values, we'll need to view-convert them to integers
so that we can perform the atomic compare and swap. Simplify the
following code by always setting up the "i"ntegral variables. */
if (!INTEGRAL_TYPE_P (type) && !POINTER_TYPE_P (type))
{
+ tree iaddr_val;
+
iaddr = create_tmp_var (build_pointer_type (itype), NULL);
- x = build_gimple_modify_stmt (iaddr,
- fold_convert (TREE_TYPE (iaddr), addr));
- force_gimple_operand_bsi (&bsi, x, true, NULL_TREE,
- true, BSI_SAME_STMT);
+ iaddr_val
+ = force_gimple_operand_gsi (&si,
+ fold_convert (TREE_TYPE (iaddr), addr),
+ false, NULL_TREE, true, GSI_SAME_STMT);
+ stmt = gimple_build_assign (iaddr, iaddr_val);
+ gsi_insert_before (&si, stmt, GSI_SAME_STMT);
DECL_NO_TBAA_P (iaddr) = 1;
DECL_POINTER_ALIAS_SET (iaddr) = 0;
loadedi = create_tmp_var (itype, NULL);
@@ -4816,63 +4941,65 @@ expand_omp_atomic_pipeline (basic_block load_bb, basic_block store_bb,
iaddr = addr;
loadedi = loaded_val;
}
- initial = force_gimple_operand_bsi (&bsi, build_fold_indirect_ref (iaddr),
- true, NULL_TREE, true, BSI_SAME_STMT);
+
+ initial = force_gimple_operand_gsi (&si, build_fold_indirect_ref (iaddr),
+ true, NULL_TREE, true, GSI_SAME_STMT);
/* Move the value to the LOADEDI temporary. */
if (gimple_in_ssa_p (cfun))
{
- gcc_assert (phi_nodes (loop_header) == NULL_TREE);
+ gcc_assert (gimple_seq_empty_p (phi_nodes (loop_header)));
phi = create_phi_node (loadedi, loop_header);
SSA_NAME_DEF_STMT (loadedi) = phi;
SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (phi, single_succ_edge (load_bb)),
initial);
}
else
- bsi_insert_before (&bsi,
- build_gimple_modify_stmt (loadedi, initial),
- BSI_SAME_STMT);
+ gsi_insert_before (&si,
+ gimple_build_assign (loadedi, initial),
+ GSI_SAME_STMT);
if (loadedi != loaded_val)
{
- block_stmt_iterator bsi2;
+ gimple_stmt_iterator gsi2;
+ tree x;
x = build1 (VIEW_CONVERT_EXPR, type, loadedi);
- bsi2 = bsi_start (loop_header);
+ gsi2 = gsi_start_bb (loop_header);
if (gimple_in_ssa_p (cfun))
{
- x = force_gimple_operand_bsi (&bsi2, x, true, NULL_TREE,
- true, BSI_SAME_STMT);
- x = build_gimple_modify_stmt (loaded_val, x);
- bsi_insert_before (&bsi2, x, BSI_SAME_STMT);
- SSA_NAME_DEF_STMT (loaded_val) = x;
+ gimple stmt;
+ x = force_gimple_operand_gsi (&gsi2, x, true, NULL_TREE,
+ true, GSI_SAME_STMT);
+ stmt = gimple_build_assign (loaded_val, x);
+ gsi_insert_before (&gsi2, stmt, GSI_SAME_STMT);
}
else
{
- x = build_gimple_modify_stmt (loaded_val, x);
- force_gimple_operand_bsi (&bsi2, x, true, NULL_TREE,
- true, BSI_SAME_STMT);
+ x = build2 (MODIFY_EXPR, TREE_TYPE (loaded_val), loaded_val, x);
+ force_gimple_operand_gsi (&gsi2, x, true, NULL_TREE,
+ true, GSI_SAME_STMT);
}
}
- bsi_remove (&bsi, true);
+ gsi_remove (&si, true);
- bsi = bsi_last (store_bb);
- gcc_assert (TREE_CODE (bsi_stmt (bsi)) == OMP_ATOMIC_STORE);
+ si = gsi_last_bb (store_bb);
+ gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_ATOMIC_STORE);
if (iaddr == addr)
storedi = stored_val;
else
storedi =
- force_gimple_operand_bsi (&bsi,
+ force_gimple_operand_gsi (&si,
build1 (VIEW_CONVERT_EXPR, itype,
stored_val), true, NULL_TREE, true,
- BSI_SAME_STMT);
+ GSI_SAME_STMT);
/* Build the compare&swap statement. */
new_storedi = build_call_expr (cmpxchg, 3, iaddr, loadedi, storedi);
- new_storedi = force_gimple_operand_bsi (&bsi,
+ new_storedi = force_gimple_operand_gsi (&si,
fold_convert (itype, new_storedi),
true, NULL_TREE,
- true, BSI_SAME_STMT);
+ true, GSI_SAME_STMT);
if (gimple_in_ssa_p (cfun))
old_vali = loadedi;
@@ -4881,21 +5008,20 @@ expand_omp_atomic_pipeline (basic_block load_bb, basic_block store_bb,
old_vali = create_tmp_var (itype, NULL);
if (gimple_in_ssa_p (cfun))
add_referenced_var (old_vali);
- x = build_gimple_modify_stmt (old_vali, loadedi);
- force_gimple_operand_bsi (&bsi, x, true, NULL_TREE,
- true, BSI_SAME_STMT);
+ stmt = gimple_build_assign (old_vali, loadedi);
+ gsi_insert_before (&si, stmt, GSI_SAME_STMT);
- x = build_gimple_modify_stmt (loadedi, new_storedi);
- force_gimple_operand_bsi (&bsi, x, true, NULL_TREE,
- true, BSI_SAME_STMT);
+ stmt = gimple_build_assign (loadedi, new_storedi);
+ gsi_insert_before (&si, stmt, GSI_SAME_STMT);
}
/* Note that we always perform the comparison as an integer, even for
floating point. This allows the atomic operation to properly
succeed even with NaNs and -0.0. */
- x = build2 (NE_EXPR, boolean_type_node, new_storedi, old_vali);
- x = build3 (COND_EXPR, void_type_node, x, NULL_TREE, NULL_TREE);
- bsi_insert_before (&bsi, x, BSI_SAME_STMT);
+ stmt = gimple_build_cond_empty
+ (build2 (NE_EXPR, boolean_type_node,
+ new_storedi, old_vali));
+ gsi_insert_before (&si, stmt, GSI_SAME_STMT);
/* Update cfg. */
e = single_succ_edge (store_bb);
@@ -4908,12 +5034,12 @@ expand_omp_atomic_pipeline (basic_block load_bb, basic_block store_bb,
if we are not in SSA). */
if (gimple_in_ssa_p (cfun))
{
- phi = phi_nodes (loop_header);
+ phi = gimple_seq_first_stmt (phi_nodes (loop_header));
SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (phi, e), new_storedi);
}
- /* Remove OMP_ATOMIC_STORE. */
- bsi_remove (&bsi, true);
+ /* Remove GIMPLE_OMP_ATOMIC_STORE. */
+ gsi_remove (&si, true);
if (gimple_in_ssa_p (cfun))
update_ssa (TODO_update_ssa_no_phi);
@@ -4932,15 +5058,16 @@ expand_omp_atomic_pipeline (basic_block load_bb, basic_block store_bb,
responses received from omp@openmp.org, appears to be within spec.
Which makes sense, since that's how several other compilers handle
this situation as well.
- LOADED_VAL and ADDR are the operands of OMP_ATOMIC_LOAD we're expanding.
- STORED_VAL is the operand of the matching OMP_ATOMIC_STORE.
+ LOADED_VAL and ADDR are the operands of GIMPLE_OMP_ATOMIC_LOAD we're
+ expanding. STORED_VAL is the operand of the matching
+ GIMPLE_OMP_ATOMIC_STORE.
We replace
- OMP_ATOMIC_LOAD (loaded_val, addr) with
+ GIMPLE_OMP_ATOMIC_LOAD (loaded_val, addr) with
loaded_val = *addr;
and replace
- OMP_ATOMIC_ATORE (stored_val) with
+ GIMPLE_OMP_ATOMIC_ATORE (stored_val) with
*addr = stored_val;
*/
@@ -4948,40 +5075,39 @@ static bool
expand_omp_atomic_mutex (basic_block load_bb, basic_block store_bb,
tree addr, tree loaded_val, tree stored_val)
{
- block_stmt_iterator bsi;
+ gimple_stmt_iterator si;
+ gimple stmt;
tree t;
- bsi = bsi_last (load_bb);
- gcc_assert (TREE_CODE (bsi_stmt (bsi)) == OMP_ATOMIC_LOAD);
+ si = gsi_last_bb (load_bb);
+ gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_ATOMIC_LOAD);
t = built_in_decls[BUILT_IN_GOMP_ATOMIC_START];
t = build_function_call_expr (t, 0);
- force_gimple_operand_bsi (&bsi, t, true, NULL_TREE, true, BSI_SAME_STMT);
+ force_gimple_operand_gsi (&si, t, true, NULL_TREE, true, GSI_SAME_STMT);
- t = build_gimple_modify_stmt (loaded_val, build_fold_indirect_ref (addr));
- if (gimple_in_ssa_p (cfun))
- SSA_NAME_DEF_STMT (loaded_val) = t;
- bsi_insert_before (&bsi, t, BSI_SAME_STMT);
- bsi_remove (&bsi, true);
+ stmt = gimple_build_assign (loaded_val, build_fold_indirect_ref (addr));
+ gsi_insert_before (&si, stmt, GSI_SAME_STMT);
+ gsi_remove (&si, true);
- bsi = bsi_last (store_bb);
- gcc_assert (TREE_CODE (bsi_stmt (bsi)) == OMP_ATOMIC_STORE);
+ si = gsi_last_bb (store_bb);
+ gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_ATOMIC_STORE);
- t = build_gimple_modify_stmt (build_fold_indirect_ref (unshare_expr (addr)),
+ stmt = gimple_build_assign (build_fold_indirect_ref (unshare_expr (addr)),
stored_val);
- bsi_insert_before (&bsi, t, BSI_SAME_STMT);
+ gsi_insert_before (&si, stmt, GSI_SAME_STMT);
t = built_in_decls[BUILT_IN_GOMP_ATOMIC_END];
t = build_function_call_expr (t, 0);
- force_gimple_operand_bsi (&bsi, t, true, NULL_TREE, true, BSI_SAME_STMT);
- bsi_remove (&bsi, true);
+ force_gimple_operand_gsi (&si, t, true, NULL_TREE, true, GSI_SAME_STMT);
+ gsi_remove (&si, true);
if (gimple_in_ssa_p (cfun))
update_ssa (TODO_update_ssa_no_phi);
return true;
}
-/* Expand an OMP_ATOMIC statement. We try to expand
+/* Expand an GIMPLE_OMP_ATOMIC statement. We try to expand
using expand_omp_atomic_fetch_op. If it failed, we try to
call expand_omp_atomic_pipeline, and if it fails too, the
ultimate fallback is wrapping the operation in a mutex
@@ -4992,10 +5118,10 @@ static void
expand_omp_atomic (struct omp_region *region)
{
basic_block load_bb = region->entry, store_bb = region->exit;
- tree load = last_stmt (load_bb), store = last_stmt (store_bb);
- tree loaded_val = TREE_OPERAND (load, 0);
- tree addr = TREE_OPERAND (load, 1);
- tree stored_val = TREE_OPERAND (store, 0);
+ gimple load = last_stmt (load_bb), store = last_stmt (store_bb);
+ tree loaded_val = gimple_omp_atomic_load_lhs (load);
+ tree addr = gimple_omp_atomic_load_rhs (load);
+ tree stored_val = gimple_omp_atomic_store_val (store);
tree type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (addr)));
HOST_WIDE_INT index;
@@ -5034,7 +5160,7 @@ expand_omp_atomic (struct omp_region *region)
/* Expand the parallel region tree rooted at REGION. Expansion
proceeds in depth-first order. Innermost regions are expanded
first. This way, parallel regions that require a new function to
- be created (e.g., OMP_PARALLEL) can be expanded without having any
+ be created (e.g., GIMPLE_OMP_PARALLEL) can be expanded without having any
internal dependencies in their body. */
static void
@@ -5046,50 +5172,47 @@ expand_omp (struct omp_region *region)
/* First, determine whether this is a combined parallel+workshare
region. */
- if (region->type == OMP_PARALLEL)
+ if (region->type == GIMPLE_OMP_PARALLEL)
determine_parallel_type (region);
if (region->inner)
expand_omp (region->inner);
saved_location = input_location;
- if (EXPR_HAS_LOCATION (last_stmt (region->entry)))
- input_location = EXPR_LOCATION (last_stmt (region->entry));
+ if (gimple_has_location (last_stmt (region->entry)))
+ input_location = gimple_location (last_stmt (region->entry));
switch (region->type)
{
- case OMP_PARALLEL:
+ case GIMPLE_OMP_PARALLEL:
+ case GIMPLE_OMP_TASK:
expand_omp_taskreg (region);
break;
- case OMP_TASK:
- expand_omp_taskreg (region);
- break;
-
- case OMP_FOR:
+ case GIMPLE_OMP_FOR:
expand_omp_for (region);
break;
- case OMP_SECTIONS:
+ case GIMPLE_OMP_SECTIONS:
expand_omp_sections (region);
break;
- case OMP_SECTION:
+ case GIMPLE_OMP_SECTION:
/* Individual omp sections are handled together with their
- parent OMP_SECTIONS region. */
+ parent GIMPLE_OMP_SECTIONS region. */
break;
- case OMP_SINGLE:
+ case GIMPLE_OMP_SINGLE:
expand_omp_single (region);
break;
- case OMP_MASTER:
- case OMP_ORDERED:
- case OMP_CRITICAL:
+ case GIMPLE_OMP_MASTER:
+ case GIMPLE_OMP_ORDERED:
+ case GIMPLE_OMP_CRITICAL:
expand_omp_synch (region);
break;
- case OMP_ATOMIC_LOAD:
+ case GIMPLE_OMP_ATOMIC_LOAD:
expand_omp_atomic (region);
break;
@@ -5112,19 +5235,19 @@ static void
build_omp_regions_1 (basic_block bb, struct omp_region *parent,
bool single_tree)
{
- block_stmt_iterator si;
- tree stmt;
+ gimple_stmt_iterator gsi;
+ gimple stmt;
basic_block son;
- si = bsi_last (bb);
- if (!bsi_end_p (si) && OMP_DIRECTIVE_P (bsi_stmt (si)))
+ gsi = gsi_last_bb (bb);
+ if (!gsi_end_p (gsi) && is_gimple_omp (gsi_stmt (gsi)))
{
struct omp_region *region;
- enum tree_code code;
+ enum gimple_code code;
- stmt = bsi_stmt (si);
- code = TREE_CODE (stmt);
- if (code == OMP_RETURN)
+ stmt = gsi_stmt (gsi);
+ code = gimple_code (stmt);
+ if (code == GIMPLE_OMP_RETURN)
{
/* STMT is the return point out of region PARENT. Mark it
as the exit point and make PARENT the immediately
@@ -5134,26 +5257,28 @@ build_omp_regions_1 (basic_block bb, struct omp_region *parent,
region->exit = bb;
parent = parent->outer;
}
- else if (code == OMP_ATOMIC_STORE)
+ else if (code == GIMPLE_OMP_ATOMIC_STORE)
{
- /* OMP_ATOMIC_STORE is analogous to OMP_RETURN, but matches with
- OMP_ATOMIC_LOAD. */
+ /* GIMPLE_OMP_ATOMIC_STORE is analoguous to
+ GIMPLE_OMP_RETURN, but matches with
+ GIMPLE_OMP_ATOMIC_LOAD. */
gcc_assert (parent);
- gcc_assert (parent->type == OMP_ATOMIC_LOAD);
+ gcc_assert (parent->type == GIMPLE_OMP_ATOMIC_LOAD);
region = parent;
region->exit = bb;
parent = parent->outer;
}
- else if (code == OMP_CONTINUE)
+ else if (code == GIMPLE_OMP_CONTINUE)
{
gcc_assert (parent);
parent->cont = bb;
}
- else if (code == OMP_SECTIONS_SWITCH)
+ else if (code == GIMPLE_OMP_SECTIONS_SWITCH)
{
- /* OMP_SECTIONS_SWITCH is part of OMP_SECTIONS, and we do nothing for
- it. */ ;
+ /* GIMPLE_OMP_SECTIONS_SWITCH is part of
+ GIMPLE_OMP_SECTIONS, and we do nothing for it. */
+ ;
}
else
{
@@ -5214,7 +5339,6 @@ build_omp_regions (void)
build_omp_regions_1 (ENTRY_BLOCK_PTR, NULL, false);
}
-
/* Main entry point for expanding OMP-GIMPLE into runtime calls. */
static unsigned int
@@ -5272,106 +5396,106 @@ struct gimple_opt_pass pass_expand_omp =
/* Routines to lower OpenMP directives into OMP-GIMPLE. */
-/* Lower the OpenMP sections directive in *STMT_P. */
+/* Lower the OpenMP sections directive in the current statement in GSI_P.
+ CTX is the enclosing OMP context for the current statement. */
static void
-lower_omp_sections (tree *stmt_p, omp_context *ctx)
+lower_omp_sections (gimple_stmt_iterator *gsi_p, omp_context *ctx)
{
- tree new_stmt, stmt, body, bind, block, ilist, olist, new_body, control;
- tree t, dlist;
- tree_stmt_iterator tsi;
+ tree block, control;
+ gimple_stmt_iterator tgsi;
unsigned i, len;
+ gimple stmt, new_stmt, bind, t;
+ gimple_seq ilist, dlist, olist, new_body, body;
+ struct gimplify_ctx gctx;
- stmt = *stmt_p;
+ stmt = gsi_stmt (*gsi_p);
- push_gimplify_context ();
+ push_gimplify_context (&gctx);
dlist = NULL;
ilist = NULL;
- lower_rec_input_clauses (OMP_SECTIONS_CLAUSES (stmt), &ilist, &dlist, ctx);
+ lower_rec_input_clauses (gimple_omp_sections_clauses (stmt),
+ &ilist, &dlist, ctx);
- tsi = tsi_start (OMP_SECTIONS_BODY (stmt));
- for (len = 0; !tsi_end_p (tsi); len++, tsi_next (&tsi))
+ tgsi = gsi_start (gimple_omp_body (stmt));
+ for (len = 0; !gsi_end_p (tgsi); len++, gsi_next (&tgsi))
continue;
- tsi = tsi_start (OMP_SECTIONS_BODY (stmt));
- body = alloc_stmt_list ();
- for (i = 0; i < len; i++, tsi_next (&tsi))
+ tgsi = gsi_start (gimple_omp_body (stmt));
+ body = NULL;
+ for (i = 0; i < len; i++, gsi_next (&tgsi))
{
omp_context *sctx;
- tree sec_start, sec_end;
+ gimple sec_start;
- sec_start = tsi_stmt (tsi);
+ sec_start = gsi_stmt (tgsi);
sctx = maybe_lookup_ctx (sec_start);
gcc_assert (sctx);
- append_to_statement_list (sec_start, &body);
+ gimple_seq_add_stmt (&body, sec_start);
- lower_omp (&OMP_SECTION_BODY (sec_start), sctx);
- append_to_statement_list (OMP_SECTION_BODY (sec_start), &body);
- OMP_SECTION_BODY (sec_start) = NULL;
+ lower_omp (gimple_omp_body (sec_start), sctx);
+ gimple_seq_add_seq (&body, gimple_omp_body (sec_start));
+ gimple_omp_set_body (sec_start, NULL);
if (i == len - 1)
{
- tree l = alloc_stmt_list ();
- lower_lastprivate_clauses (OMP_SECTIONS_CLAUSES (stmt), NULL,
+ gimple_seq l = NULL;
+ lower_lastprivate_clauses (gimple_omp_sections_clauses (stmt), NULL,
&l, ctx);
- append_to_statement_list (l, &body);
- OMP_SECTION_LAST (sec_start) = 1;
+ gimple_seq_add_seq (&body, l);
+ gimple_omp_section_set_last (sec_start);
}
- sec_end = make_node (OMP_RETURN);
- append_to_statement_list (sec_end, &body);
+ gimple_seq_add_stmt (&body, gimple_build_omp_return (false));
}
block = make_node (BLOCK);
- bind = build3 (BIND_EXPR, void_type_node, NULL, body, block);
+ bind = gimple_build_bind (NULL, body, block);
- olist = NULL_TREE;
- lower_reduction_clauses (OMP_SECTIONS_CLAUSES (stmt), &olist, ctx);
+ olist = NULL;
+ lower_reduction_clauses (gimple_omp_sections_clauses (stmt), &olist, ctx);
block = make_node (BLOCK);
- new_stmt = build3 (BIND_EXPR, void_type_node, NULL, NULL, block);
- TREE_SIDE_EFFECTS (new_stmt) = 1;
+ new_stmt = gimple_build_bind (NULL, NULL, block);
pop_gimplify_context (new_stmt);
-
- BIND_EXPR_VARS (new_stmt)
- = chainon (BIND_EXPR_VARS (new_stmt), ctx->block_vars);
- BLOCK_VARS (block) = BIND_EXPR_VARS (new_stmt);
+ gimple_bind_append_vars (new_stmt, ctx->block_vars);
+ BLOCK_VARS (block) = gimple_bind_vars (bind);
if (BLOCK_VARS (block))
TREE_USED (block) = 1;
- new_body = alloc_stmt_list ();
- append_to_statement_list (ilist, &new_body);
- append_to_statement_list (stmt, &new_body);
- append_to_statement_list (make_node (OMP_SECTIONS_SWITCH), &new_body);
- append_to_statement_list (bind, &new_body);
+ new_body = NULL;
+ gimple_seq_add_seq (&new_body, ilist);
+ gimple_seq_add_stmt (&new_body, stmt);
+ gimple_seq_add_stmt (&new_body, gimple_build_omp_sections_switch ());
+ gimple_seq_add_stmt (&new_body, bind);
control = create_tmp_var (unsigned_type_node, ".section");
- t = build2 (OMP_CONTINUE, void_type_node, control, control);
- OMP_SECTIONS_CONTROL (stmt) = control;
- append_to_statement_list (t, &new_body);
+ t = gimple_build_omp_continue (control, control);
+ gimple_omp_sections_set_control (stmt, control);
+ gimple_seq_add_stmt (&new_body, t);
- append_to_statement_list (olist, &new_body);
- append_to_statement_list (dlist, &new_body);
+ gimple_seq_add_seq (&new_body, olist);
+ gimple_seq_add_seq (&new_body, dlist);
- maybe_catch_exception (&new_body);
+ new_body = maybe_catch_exception (new_body);
- t = make_node (OMP_RETURN);
- OMP_RETURN_NOWAIT (t) = !!find_omp_clause (OMP_SECTIONS_CLAUSES (stmt),
- OMP_CLAUSE_NOWAIT);
- append_to_statement_list (t, &new_body);
+ t = gimple_build_omp_return
+ (!!find_omp_clause (gimple_omp_sections_clauses (stmt),
+ OMP_CLAUSE_NOWAIT));
+ gimple_seq_add_stmt (&new_body, t);
- BIND_EXPR_BODY (new_stmt) = new_body;
- OMP_SECTIONS_BODY (stmt) = NULL;
+ gimple_bind_set_body (new_stmt, new_body);
+ gimple_omp_set_body (stmt, NULL);
- *stmt_p = new_stmt;
+ gsi_replace (gsi_p, new_stmt, true);
}
/* A subroutine of lower_omp_single. Expand the simple form of
- an OMP_SINGLE, without a copyprivate clause:
+ a GIMPLE_OMP_SINGLE, without a copyprivate clause:
if (GOMP_single_start ())
BODY;
@@ -5382,22 +5506,31 @@ lower_omp_sections (tree *stmt_p, omp_context *ctx)
to a synchronization analysis pass. */
static void
-lower_omp_single_simple (tree single_stmt, tree *pre_p)
+lower_omp_single_simple (gimple single_stmt, gimple_seq *pre_p)
{
- tree t;
-
- t = build_call_expr (built_in_decls[BUILT_IN_GOMP_SINGLE_START], 0);
- if (TREE_TYPE (t) != boolean_type_node)
- t = fold_build2 (NE_EXPR, boolean_type_node,
- t, build_int_cst (TREE_TYPE (t), 0));
- t = build3 (COND_EXPR, void_type_node, t,
- OMP_SINGLE_BODY (single_stmt), NULL);
- gimplify_and_add (t, pre_p);
+ tree tlabel = create_artificial_label ();
+ tree flabel = create_artificial_label ();
+ gimple call, cond;
+ tree lhs, decl;
+
+ decl = built_in_decls[BUILT_IN_GOMP_SINGLE_START];
+ lhs = create_tmp_var (TREE_TYPE (TREE_TYPE (decl)), NULL);
+ call = gimple_build_call (decl, 0);
+ gimple_call_set_lhs (call, lhs);
+ gimple_seq_add_stmt (pre_p, call);
+
+ cond = gimple_build_cond (EQ_EXPR, lhs,
+ fold_convert (TREE_TYPE (lhs), boolean_true_node),
+ tlabel, flabel);
+ gimple_seq_add_stmt (pre_p, cond);
+ gimple_seq_add_stmt (pre_p, gimple_build_label (tlabel));
+ gimple_seq_add_seq (pre_p, gimple_omp_body (single_stmt));
+ gimple_seq_add_stmt (pre_p, gimple_build_label (flabel));
}
/* A subroutine of lower_omp_single. Expand the simple form of
- an OMP_SINGLE, with a copyprivate clause:
+ a GIMPLE_OMP_SINGLE, with a copyprivate clause:
#pragma omp single copyprivate (a, b, c)
@@ -5426,9 +5559,10 @@ lower_omp_single_simple (tree single_stmt, tree *pre_p)
to a synchronization analysis pass. */
static void
-lower_omp_single_copy (tree single_stmt, tree *pre_p, omp_context *ctx)
+lower_omp_single_copy (gimple single_stmt, gimple_seq *pre_p, omp_context *ctx)
{
- tree ptr_type, t, l0, l1, l2, copyin_seq;
+ tree ptr_type, t, l0, l1, l2;
+ gimple_seq copyin_seq;
ctx->sender_decl = create_tmp_var (ctx->record_type, ".omp_copy_o");
@@ -5441,8 +5575,7 @@ lower_omp_single_copy (tree single_stmt, tree *pre_p, omp_context *ctx)
t = build_call_expr (built_in_decls[BUILT_IN_GOMP_SINGLE_COPY_START], 0);
t = fold_convert (ptr_type, t);
- t = build_gimple_modify_stmt (ctx->receiver_decl, t);
- gimplify_and_add (t, pre_p);
+ gimplify_assign (ctx->receiver_decl, t, pre_p);
t = build2 (EQ_EXPR, boolean_type_node, ctx->receiver_decl,
build_int_cst (ptr_type, 0));
@@ -5450,13 +5583,12 @@ lower_omp_single_copy (tree single_stmt, tree *pre_p, omp_context *ctx)
build_and_jump (&l0), build_and_jump (&l1));
gimplify_and_add (t, pre_p);
- t = build1 (LABEL_EXPR, void_type_node, l0);
- gimplify_and_add (t, pre_p);
+ gimple_seq_add_stmt (pre_p, gimple_build_label (l0));
- append_to_statement_list (OMP_SINGLE_BODY (single_stmt), pre_p);
+ gimple_seq_add_seq (pre_p, gimple_omp_body (single_stmt));
copyin_seq = NULL;
- lower_copyprivate_clauses (OMP_SINGLE_CLAUSES (single_stmt), pre_p,
+ lower_copyprivate_clauses (gimple_omp_single_clauses (single_stmt), pre_p,
&copyin_seq, ctx);
t = build_fold_addr_expr (ctx->sender_decl);
@@ -5466,55 +5598,57 @@ lower_omp_single_copy (tree single_stmt, tree *pre_p, omp_context *ctx)
t = build_and_jump (&l2);
gimplify_and_add (t, pre_p);
- t = build1 (LABEL_EXPR, void_type_node, l1);
- gimplify_and_add (t, pre_p);
+ gimple_seq_add_stmt (pre_p, gimple_build_label (l1));
- append_to_statement_list (copyin_seq, pre_p);
+ gimple_seq_add_seq (pre_p, copyin_seq);
- t = build1 (LABEL_EXPR, void_type_node, l2);
- gimplify_and_add (t, pre_p);
+ gimple_seq_add_stmt (pre_p, gimple_build_label (l2));
}
/* Expand code for an OpenMP single directive. */
static void
-lower_omp_single (tree *stmt_p, omp_context *ctx)
+lower_omp_single (gimple_stmt_iterator *gsi_p, omp_context *ctx)
{
- tree t, bind, block, single_stmt = *stmt_p, dlist;
+ tree block;
+ gimple t, bind, single_stmt = gsi_stmt (*gsi_p);
+ gimple_seq bind_body, dlist;
+ struct gimplify_ctx gctx;
- push_gimplify_context ();
+ push_gimplify_context (&gctx);
- block = make_node (BLOCK);
- *stmt_p = bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, block);
- TREE_SIDE_EFFECTS (bind) = 1;
+ bind_body = NULL;
+ lower_rec_input_clauses (gimple_omp_single_clauses (single_stmt),
+ &bind_body, &dlist, ctx);
+ lower_omp (gimple_omp_body (single_stmt), ctx);
- lower_rec_input_clauses (OMP_SINGLE_CLAUSES (single_stmt),
- &BIND_EXPR_BODY (bind), &dlist, ctx);
- lower_omp (&OMP_SINGLE_BODY (single_stmt), ctx);
-
- append_to_statement_list (single_stmt, &BIND_EXPR_BODY (bind));
+ gimple_seq_add_stmt (&bind_body, single_stmt);
if (ctx->record_type)
- lower_omp_single_copy (single_stmt, &BIND_EXPR_BODY (bind), ctx);
+ lower_omp_single_copy (single_stmt, &bind_body, ctx);
else
- lower_omp_single_simple (single_stmt, &BIND_EXPR_BODY (bind));
+ lower_omp_single_simple (single_stmt, &bind_body);
- OMP_SINGLE_BODY (single_stmt) = NULL;
+ gimple_omp_set_body (single_stmt, NULL);
- append_to_statement_list (dlist, &BIND_EXPR_BODY (bind));
+ gimple_seq_add_seq (&bind_body, dlist);
- maybe_catch_exception (&BIND_EXPR_BODY (bind));
+ bind_body = maybe_catch_exception (bind_body);
- t = make_node (OMP_RETURN);
- OMP_RETURN_NOWAIT (t) = !!find_omp_clause (OMP_SINGLE_CLAUSES (single_stmt),
- OMP_CLAUSE_NOWAIT);
- append_to_statement_list (t, &BIND_EXPR_BODY (bind));
+ t = gimple_build_omp_return
+ (!!find_omp_clause (gimple_omp_single_clauses (single_stmt),
+ OMP_CLAUSE_NOWAIT));
+ gimple_seq_add_stmt (&bind_body, t);
+
+ block = make_node (BLOCK);
+ bind = gimple_build_bind (NULL, bind_body, block);
pop_gimplify_context (bind);
- BIND_EXPR_VARS (bind) = chainon (BIND_EXPR_VARS (bind), ctx->block_vars);
- BLOCK_VARS (block) = BIND_EXPR_VARS (bind);
+ gimple_bind_append_vars (bind, ctx->block_vars);
+ BLOCK_VARS (block) = ctx->block_vars;
+ gsi_replace (gsi_p, bind, true);
if (BLOCK_VARS (block))
TREE_USED (block) = 1;
}
@@ -5523,80 +5657,80 @@ lower_omp_single (tree *stmt_p, omp_context *ctx)
/* Expand code for an OpenMP master directive. */
static void
-lower_omp_master (tree *stmt_p, omp_context *ctx)
+lower_omp_master (gimple_stmt_iterator *gsi_p, omp_context *ctx)
{
- tree bind, block, stmt = *stmt_p, lab = NULL, x;
+ tree block, lab = NULL, x;
+ gimple stmt = gsi_stmt (*gsi_p), bind;
+ gimple_seq tseq;
+ struct gimplify_ctx gctx;
- push_gimplify_context ();
+ push_gimplify_context (&gctx);
block = make_node (BLOCK);
- *stmt_p = bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, block);
- TREE_SIDE_EFFECTS (bind) = 1;
-
- append_to_statement_list (stmt, &BIND_EXPR_BODY (bind));
+ bind = gimple_build_bind (NULL, gimple_seq_alloc_with_stmt (stmt),
+ block);
x = build_call_expr (built_in_decls[BUILT_IN_OMP_GET_THREAD_NUM], 0);
x = build2 (EQ_EXPR, boolean_type_node, x, integer_zero_node);
x = build3 (COND_EXPR, void_type_node, x, NULL, build_and_jump (&lab));
- gimplify_and_add (x, &BIND_EXPR_BODY (bind));
+ tseq = NULL;
+ gimplify_and_add (x, &tseq);
+ gimple_bind_add_seq (bind, tseq);
- lower_omp (&OMP_MASTER_BODY (stmt), ctx);
- maybe_catch_exception (&OMP_MASTER_BODY (stmt));
- append_to_statement_list (OMP_MASTER_BODY (stmt), &BIND_EXPR_BODY (bind));
- OMP_MASTER_BODY (stmt) = NULL;
+ lower_omp (gimple_omp_body (stmt), ctx);
+ gimple_omp_set_body (stmt, maybe_catch_exception (gimple_omp_body (stmt)));
+ gimple_bind_add_seq (bind, gimple_omp_body (stmt));
+ gimple_omp_set_body (stmt, NULL);
- x = build1 (LABEL_EXPR, void_type_node, lab);
- gimplify_and_add (x, &BIND_EXPR_BODY (bind));
+ gimple_bind_add_stmt (bind, gimple_build_label (lab));
- x = make_node (OMP_RETURN);
- OMP_RETURN_NOWAIT (x) = 1;
- append_to_statement_list (x, &BIND_EXPR_BODY (bind));
+ gimple_bind_add_stmt (bind, gimple_build_omp_return (true));
pop_gimplify_context (bind);
- BIND_EXPR_VARS (bind) = chainon (BIND_EXPR_VARS (bind), ctx->block_vars);
- BLOCK_VARS (block) = BIND_EXPR_VARS (bind);
+ gimple_bind_append_vars (bind, ctx->block_vars);
+ BLOCK_VARS (block) = ctx->block_vars;
+ gsi_replace (gsi_p, bind, true);
}
/* Expand code for an OpenMP ordered directive. */
static void
-lower_omp_ordered (tree *stmt_p, omp_context *ctx)
+lower_omp_ordered (gimple_stmt_iterator *gsi_p, omp_context *ctx)
{
- tree bind, block, stmt = *stmt_p, x;
+ tree block;
+ gimple stmt = gsi_stmt (*gsi_p), bind, x;
+ struct gimplify_ctx gctx;
- push_gimplify_context ();
+ push_gimplify_context (&gctx);
block = make_node (BLOCK);
- *stmt_p = bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, block);
- TREE_SIDE_EFFECTS (bind) = 1;
-
- append_to_statement_list (stmt, &BIND_EXPR_BODY (bind));
+ bind = gimple_build_bind (NULL, gimple_seq_alloc_with_stmt (stmt),
+ block);
- x = build_call_expr (built_in_decls[BUILT_IN_GOMP_ORDERED_START], 0);
- gimplify_and_add (x, &BIND_EXPR_BODY (bind));
+ x = gimple_build_call (built_in_decls[BUILT_IN_GOMP_ORDERED_START], 0);
+ gimple_bind_add_stmt (bind, x);
- lower_omp (&OMP_ORDERED_BODY (stmt), ctx);
- maybe_catch_exception (&OMP_ORDERED_BODY (stmt));
- append_to_statement_list (OMP_ORDERED_BODY (stmt), &BIND_EXPR_BODY (bind));
- OMP_ORDERED_BODY (stmt) = NULL;
+ lower_omp (gimple_omp_body (stmt), ctx);
+ gimple_omp_set_body (stmt, maybe_catch_exception (gimple_omp_body (stmt)));
+ gimple_bind_add_seq (bind, gimple_omp_body (stmt));
+ gimple_omp_set_body (stmt, NULL);
- x = build_call_expr (built_in_decls[BUILT_IN_GOMP_ORDERED_END], 0);
- gimplify_and_add (x, &BIND_EXPR_BODY (bind));
+ x = gimple_build_call (built_in_decls[BUILT_IN_GOMP_ORDERED_END], 0);
+ gimple_bind_add_stmt (bind, x);
- x = make_node (OMP_RETURN);
- OMP_RETURN_NOWAIT (x) = 1;
- append_to_statement_list (x, &BIND_EXPR_BODY (bind));
+ gimple_bind_add_stmt (bind, gimple_build_omp_return (true));
pop_gimplify_context (bind);
- BIND_EXPR_VARS (bind) = chainon (BIND_EXPR_VARS (bind), ctx->block_vars);
- BLOCK_VARS (block) = BIND_EXPR_VARS (bind);
+ gimple_bind_append_vars (bind, ctx->block_vars);
+ BLOCK_VARS (block) = gimple_bind_vars (bind);
+ gsi_replace (gsi_p, bind, true);
}
-/* Gimplify an OMP_CRITICAL statement. This is a relatively simple
+/* Gimplify a GIMPLE_OMP_CRITICAL statement. This is a relatively simple
substitution of a couple of function calls. But in the NAMED case,
requires that languages coordinate a symbol name. It is therefore
best put here in common code. */
@@ -5605,12 +5739,15 @@ static GTY((param1_is (tree), param2_is (tree)))
splay_tree critical_name_mutexes;
static void
-lower_omp_critical (tree *stmt_p, omp_context *ctx)
+lower_omp_critical (gimple_stmt_iterator *gsi_p, omp_context *ctx)
{
- tree bind, block, stmt = *stmt_p;
- tree t, lock, unlock, name;
+ tree block;
+ tree name, lock, unlock;
+ gimple stmt = gsi_stmt (*gsi_p), bind;
+ gimple_seq tbody;
+ struct gimplify_ctx gctx;
- name = OMP_CRITICAL_NAME (stmt);
+ name = gimple_omp_critical_name (stmt);
if (name)
{
tree decl;
@@ -5658,30 +5795,30 @@ lower_omp_critical (tree *stmt_p, omp_context *ctx)
unlock = build_call_expr (unlock, 0);
}
- push_gimplify_context ();
+ push_gimplify_context (&gctx);
block = make_node (BLOCK);
- *stmt_p = bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, block);
- TREE_SIDE_EFFECTS (bind) = 1;
-
- append_to_statement_list (stmt, &BIND_EXPR_BODY (bind));
+ bind = gimple_build_bind (NULL, gimple_seq_alloc_with_stmt (stmt), block);
- gimplify_and_add (lock, &BIND_EXPR_BODY (bind));
+ tbody = gimple_bind_body (bind);
+ gimplify_and_add (lock, &tbody);
+ gimple_bind_set_body (bind, tbody);
- lower_omp (&OMP_CRITICAL_BODY (stmt), ctx);
- maybe_catch_exception (&OMP_CRITICAL_BODY (stmt));
- append_to_statement_list (OMP_CRITICAL_BODY (stmt), &BIND_EXPR_BODY (bind));
- OMP_CRITICAL_BODY (stmt) = NULL;
+ lower_omp (gimple_omp_body (stmt), ctx);
+ gimple_omp_set_body (stmt, maybe_catch_exception (gimple_omp_body (stmt)));
+ gimple_bind_add_seq (bind, gimple_omp_body (stmt));
+ gimple_omp_set_body (stmt, NULL);
- gimplify_and_add (unlock, &BIND_EXPR_BODY (bind));
+ tbody = gimple_bind_body (bind);
+ gimplify_and_add (unlock, &tbody);
+ gimple_bind_set_body (bind, tbody);
- t = make_node (OMP_RETURN);
- OMP_RETURN_NOWAIT (t) = 1;
- append_to_statement_list (t, &BIND_EXPR_BODY (bind));
+ gimple_bind_add_stmt (bind, gimple_build_omp_return (true));
pop_gimplify_context (bind);
- BIND_EXPR_VARS (bind) = chainon (BIND_EXPR_VARS (bind), ctx->block_vars);
- BLOCK_VARS (block) = BIND_EXPR_VARS (bind);
+ gimple_bind_append_vars (bind, ctx->block_vars);
+ BLOCK_VARS (block) = gimple_bind_vars (bind);
+ gsi_replace (gsi_p, bind, true);
}
@@ -5692,11 +5829,12 @@ lower_omp_critical (tree *stmt_p, omp_context *ctx)
*BODY_P. */
static void
-lower_omp_for_lastprivate (struct omp_for_data *fd, tree *body_p,
- tree *dlist, struct omp_context *ctx)
+lower_omp_for_lastprivate (struct omp_for_data *fd, gimple_seq *body_p,
+ gimple_seq *dlist, struct omp_context *ctx)
{
- tree clauses, cond, stmts, vinit, t;
+ tree clauses, cond, vinit;
enum tree_code cond_code;
+ gimple_seq stmts;
cond_code = fd->loop.cond_code;
cond_code = cond_code == LT_EXPR ? GE_EXPR : LE_EXPR;
@@ -5712,12 +5850,12 @@ lower_omp_for_lastprivate (struct omp_for_data *fd, tree *body_p,
cond = build2 (cond_code, boolean_type_node, fd->loop.v, fd->loop.n2);
- clauses = OMP_FOR_CLAUSES (fd->for_stmt);
+ clauses = gimple_omp_for_clauses (fd->for_stmt);
stmts = NULL;
lower_lastprivate_clauses (clauses, cond, &stmts, ctx);
- if (stmts != NULL)
+ if (!gimple_seq_empty_p (stmts))
{
- append_to_statement_list (*dlist, &stmts);
+ gimple_seq_add_seq (&stmts, *dlist);
*dlist = stmts;
/* Optimize: v = 0; is usually cheaper than v = some_other_constant. */
@@ -5729,8 +5867,7 @@ lower_omp_for_lastprivate (struct omp_for_data *fd, tree *body_p,
/* Initialize the iterator variable, so that threads that don't execute
any iterations don't execute the lastprivate clauses by accident. */
- t = build_gimple_modify_stmt (fd->loop.v, vinit);
- gimplify_and_add (t, body_p);
+ gimplify_assign (fd->loop.v, vinit, body_p);
}
}
@@ -5738,36 +5875,39 @@ lower_omp_for_lastprivate (struct omp_for_data *fd, tree *body_p,
/* Lower code for an OpenMP loop directive. */
static void
-lower_omp_for (tree *stmt_p, omp_context *ctx)
+lower_omp_for (gimple_stmt_iterator *gsi_p, omp_context *ctx)
{
- tree t, stmt, ilist, dlist, new_stmt, block, *body_p, *rhs_p;
+ tree *rhs_p, block;
struct omp_for_data fd;
- int i;
-
- stmt = *stmt_p;
+ gimple stmt = gsi_stmt (*gsi_p), new_stmt;
+ gimple_seq omp_for_body, body, dlist, ilist;
+ size_t i;
+ struct gimplify_ctx gctx;
- push_gimplify_context ();
+ push_gimplify_context (&gctx);
- lower_omp (&OMP_FOR_PRE_BODY (stmt), ctx);
- lower_omp (&OMP_FOR_BODY (stmt), ctx);
+ lower_omp (gimple_omp_for_pre_body (stmt), ctx);
+ lower_omp (gimple_omp_body (stmt), ctx);
block = make_node (BLOCK);
- new_stmt = build3 (BIND_EXPR, void_type_node, NULL, NULL, block);
- TREE_SIDE_EFFECTS (new_stmt) = 1;
- body_p = &BIND_EXPR_BODY (new_stmt);
+ new_stmt = gimple_build_bind (NULL, NULL, block);
/* Move declaration of temporaries in the loop body before we make
it go away. */
- if (TREE_CODE (OMP_FOR_BODY (stmt)) == BIND_EXPR)
- BIND_EXPR_VARS (new_stmt)
- = chainon (BIND_EXPR_VARS (new_stmt),
- BIND_EXPR_VARS (OMP_FOR_BODY (stmt)));
+ omp_for_body = gimple_omp_body (stmt);
+ if (!gimple_seq_empty_p (omp_for_body)
+ && gimple_code (gimple_seq_first_stmt (omp_for_body)) == GIMPLE_BIND)
+ {
+ tree vars = gimple_bind_vars (gimple_seq_first_stmt (omp_for_body));
+ gimple_bind_append_vars (new_stmt, vars);
+ }
- /* The pre-body and input clauses go before the lowered OMP_FOR. */
+ /* The pre-body and input clauses go before the lowered GIMPLE_OMP_FOR. */
ilist = NULL;
dlist = NULL;
- lower_rec_input_clauses (OMP_FOR_CLAUSES (stmt), body_p, &dlist, ctx);
- append_to_statement_list (OMP_FOR_PRE_BODY (stmt), body_p);
+ body = NULL;
+ lower_rec_input_clauses (gimple_omp_for_clauses (stmt), &body, &dlist, ctx);
+ gimple_seq_add_seq (&body, gimple_omp_for_pre_body (stmt));
/* Lower the header expressions. At this point, we can assume that
the header is of the form:
@@ -5776,71 +5916,72 @@ lower_omp_for (tree *stmt_p, omp_context *ctx)
We just need to make sure that VAL1, VAL2 and VAL3 are lowered
using the .omp_data_s mapping, if needed. */
- for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (stmt)); i++)
+ for (i = 0; i < gimple_omp_for_collapse (stmt); i++)
{
- rhs_p = &GIMPLE_STMT_OPERAND (TREE_VEC_ELT (OMP_FOR_INIT (stmt), i), 1);
+ rhs_p = gimple_omp_for_initial_ptr (stmt, i);
if (!is_gimple_min_invariant (*rhs_p))
- *rhs_p = get_formal_tmp_var (*rhs_p, body_p);
+ *rhs_p = get_formal_tmp_var (*rhs_p, &body);
- rhs_p = &TREE_OPERAND (TREE_VEC_ELT (OMP_FOR_COND (stmt), i), 1);
+ rhs_p = gimple_omp_for_final_ptr (stmt, i);
if (!is_gimple_min_invariant (*rhs_p))
- *rhs_p = get_formal_tmp_var (*rhs_p, body_p);
+ *rhs_p = get_formal_tmp_var (*rhs_p, &body);
- rhs_p = &TREE_OPERAND (GIMPLE_STMT_OPERAND
- (TREE_VEC_ELT (OMP_FOR_INCR (stmt), i), 1), 1);
+ rhs_p = &TREE_OPERAND (gimple_omp_for_incr (stmt, i), 1);
if (!is_gimple_min_invariant (*rhs_p))
- *rhs_p = get_formal_tmp_var (*rhs_p, body_p);
+ *rhs_p = get_formal_tmp_var (*rhs_p, &body);
}
/* Once lowered, extract the bounds and clauses. */
extract_omp_for_data (stmt, &fd, NULL);
- lower_omp_for_lastprivate (&fd, body_p, &dlist, ctx);
+ lower_omp_for_lastprivate (&fd, &body, &dlist, ctx);
- append_to_statement_list (stmt, body_p);
+ gimple_seq_add_stmt (&body, stmt);
+ gimple_seq_add_seq (&body, gimple_omp_body (stmt));
- append_to_statement_list (OMP_FOR_BODY (stmt), body_p);
-
- t = build2 (OMP_CONTINUE, void_type_node, fd.loop.v, fd.loop.v);
- append_to_statement_list (t, body_p);
+ gimple_seq_add_stmt (&body, gimple_build_omp_continue (fd.loop.v,
+ fd.loop.v));
/* After the loop, add exit clauses. */
- lower_reduction_clauses (OMP_FOR_CLAUSES (stmt), body_p, ctx);
- append_to_statement_list (dlist, body_p);
+ lower_reduction_clauses (gimple_omp_for_clauses (stmt), &body, ctx);
+ gimple_seq_add_seq (&body, dlist);
- maybe_catch_exception (body_p);
+ body = maybe_catch_exception (body);
/* Region exit marker goes at the end of the loop body. */
- t = make_node (OMP_RETURN);
- OMP_RETURN_NOWAIT (t) = fd.have_nowait;
- append_to_statement_list (t, body_p);
+ gimple_seq_add_stmt (&body, gimple_build_omp_return (fd.have_nowait));
pop_gimplify_context (new_stmt);
- BIND_EXPR_VARS (new_stmt)
- = chainon (BIND_EXPR_VARS (new_stmt), ctx->block_vars);
- BLOCK_VARS (block) = BIND_EXPR_VARS (new_stmt);
+
+ gimple_bind_append_vars (new_stmt, ctx->block_vars);
+ BLOCK_VARS (block) = gimple_bind_vars (new_stmt);
if (BLOCK_VARS (block))
TREE_USED (block) = 1;
- OMP_FOR_BODY (stmt) = NULL_TREE;
- OMP_FOR_PRE_BODY (stmt) = NULL_TREE;
- *stmt_p = new_stmt;
+ gimple_bind_set_body (new_stmt, body);
+ gimple_omp_set_body (stmt, NULL);
+ gimple_omp_for_set_pre_body (stmt, NULL);
+ gsi_replace (gsi_p, new_stmt, true);
}
-/* Callback for walk_stmts. Check if *TP only contains OMP_FOR
- or OMP_PARALLEL. */
+/* Callback for walk_stmts. Check if the current statement only contains
+ GIMPLE_OMP_FOR or GIMPLE_OMP_PARALLEL. */
static tree
-check_combined_parallel (tree *tp, int *walk_subtrees, void *data)
+check_combined_parallel (gimple_stmt_iterator *gsi_p,
+ bool *handled_ops_p,
+ struct walk_stmt_info *wi)
{
- struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
int *info = (int *) wi->info;
+ gimple stmt = gsi_stmt (*gsi_p);
- *walk_subtrees = 0;
- switch (TREE_CODE (*tp))
+ *handled_ops_p = true;
+ switch (gimple_code (stmt))
{
- case OMP_FOR:
- case OMP_SECTIONS:
+ WALK_SUBSTMTS;
+
+ case GIMPLE_OMP_FOR:
+ case GIMPLE_OMP_SECTIONS:
*info = *info == 0 ? 1 : -1;
break;
default:
@@ -5887,9 +6028,10 @@ task_copyfn_remap_type (struct omp_taskcopy_context *tcctx, tree orig_type)
DECL_CONTEXT (new_f) = type;
TREE_TYPE (new_f) = remap_type (TREE_TYPE (f), &tcctx->cb);
TREE_CHAIN (new_f) = new_fields;
- walk_tree (&DECL_SIZE (new_f), copy_body_r, &tcctx->cb, NULL);
- walk_tree (&DECL_SIZE_UNIT (new_f), copy_body_r, &tcctx->cb, NULL);
- walk_tree (&DECL_FIELD_OFFSET (new_f), copy_body_r, &tcctx->cb, NULL);
+ walk_tree (&DECL_SIZE (new_f), copy_tree_body_r, &tcctx->cb, NULL);
+ walk_tree (&DECL_SIZE_UNIT (new_f), copy_tree_body_r, &tcctx->cb, NULL);
+ walk_tree (&DECL_FIELD_OFFSET (new_f), copy_tree_body_r,
+ &tcctx->cb, NULL);
new_fields = new_f;
*pointer_map_insert (tcctx->cb.decl_map, f) = new_f;
}
@@ -5901,7 +6043,7 @@ task_copyfn_remap_type (struct omp_taskcopy_context *tcctx, tree orig_type)
/* Create task copyfn. */
static void
-create_task_copyfn (tree task_stmt, omp_context *ctx)
+create_task_copyfn (gimple task_stmt, omp_context *ctx)
{
struct function *child_cfun;
tree child_fn, t, c, src, dst, f, sf, arg, sarg, decl;
@@ -5909,8 +6051,9 @@ create_task_copyfn (tree task_stmt, omp_context *ctx)
bool record_needs_remap = false, srecord_needs_remap = false;
splay_tree_node n;
struct omp_taskcopy_context tcctx;
+ struct gimplify_ctx gctx;
- child_fn = OMP_TASK_COPYFN (task_stmt);
+ child_fn = gimple_omp_task_copy_fn (task_stmt);
child_cfun = DECL_STRUCT_FUNCTION (child_fn);
gcc_assert (child_cfun->cfg == NULL);
child_cfun->dont_save_pending_sizes_p = 1;
@@ -5921,14 +6064,14 @@ create_task_copyfn (tree task_stmt, omp_context *ctx)
DECL_CONTEXT (t) = child_fn;
/* Populate the function. */
- push_gimplify_context ();
+ push_gimplify_context (&gctx);
current_function_decl = child_fn;
bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
TREE_SIDE_EFFECTS (bind) = 1;
list = NULL;
DECL_SAVED_TREE (child_fn) = bind;
- DECL_SOURCE_LOCATION (child_fn) = EXPR_LOCATION (task_stmt);
+ DECL_SOURCE_LOCATION (child_fn) = gimple_location (task_stmt);
/* Remap src and dst argument types if needed. */
record_type = ctx->record_type;
@@ -5978,7 +6121,7 @@ create_task_copyfn (tree task_stmt, omp_context *ctx)
/* First pass: initialize temporaries used in record_type and srecord_type
sizes and field offsets. */
if (tcctx.cb.decl_map)
- for (c = OMP_TASK_CLAUSES (task_stmt); c; c = OMP_CLAUSE_CHAIN (c))
+ for (c = gimple_omp_task_clauses (task_stmt); c; c = OMP_CLAUSE_CHAIN (c))
if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE)
{
tree *p;
@@ -5992,13 +6135,13 @@ create_task_copyfn (tree task_stmt, omp_context *ctx)
sf = *(tree *) pointer_map_contains (tcctx.cb.decl_map, sf);
src = build_fold_indirect_ref (sarg);
src = build3 (COMPONENT_REF, TREE_TYPE (sf), src, sf, NULL);
- t = build_gimple_modify_stmt (*p, src);
+ t = build2 (MODIFY_EXPR, TREE_TYPE (*p), *p, src);
append_to_statement_list (t, &list);
}
/* Second pass: copy shared var pointers and copy construct non-VLA
firstprivate vars. */
- for (c = OMP_TASK_CLAUSES (task_stmt); c; c = OMP_CLAUSE_CHAIN (c))
+ for (c = gimple_omp_task_clauses (task_stmt); c; c = OMP_CLAUSE_CHAIN (c))
switch (OMP_CLAUSE_CODE (c))
{
case OMP_CLAUSE_SHARED:
@@ -6017,7 +6160,7 @@ create_task_copyfn (tree task_stmt, omp_context *ctx)
src = build3 (COMPONENT_REF, TREE_TYPE (sf), src, sf, NULL);
dst = build_fold_indirect_ref (arg);
dst = build3 (COMPONENT_REF, TREE_TYPE (f), dst, f, NULL);
- t = build_gimple_modify_stmt (dst, src);
+ t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
append_to_statement_list (t, &list);
break;
case OMP_CLAUSE_FIRSTPRIVATE:
@@ -6071,7 +6214,7 @@ create_task_copyfn (tree task_stmt, omp_context *ctx)
src = decl;
dst = build_fold_indirect_ref (arg);
dst = build3 (COMPONENT_REF, TREE_TYPE (f), dst, f, NULL);
- t = build_gimple_modify_stmt (dst, src);
+ t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
append_to_statement_list (t, &list);
break;
default:
@@ -6080,7 +6223,7 @@ create_task_copyfn (tree task_stmt, omp_context *ctx)
/* Last pass: handle VLA firstprivates. */
if (tcctx.cb.decl_map)
- for (c = OMP_TASK_CLAUSES (task_stmt); c; c = OMP_CLAUSE_CHAIN (c))
+ for (c = gimple_omp_task_clauses (task_stmt); c; c = OMP_CLAUSE_CHAIN (c))
if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE)
{
tree ind, ptr, df;
@@ -6114,7 +6257,8 @@ create_task_copyfn (tree task_stmt, omp_context *ctx)
df = *(tree *) pointer_map_contains (tcctx.cb.decl_map, df);
ptr = build_fold_indirect_ref (arg);
ptr = build3 (COMPONENT_REF, TREE_TYPE (df), ptr, df, NULL);
- t = build_gimple_modify_stmt (ptr, build_fold_addr_expr (dst));
+ t = build2 (MODIFY_EXPR, TREE_TYPE (ptr), ptr,
+ build_fold_addr_expr (dst));
append_to_statement_list (t, &list);
}
@@ -6129,124 +6273,123 @@ create_task_copyfn (tree task_stmt, omp_context *ctx)
current_function_decl = ctx->cb.src_fn;
}
-/* Lower the OpenMP parallel or task directive in *STMT_P. CTX holds context
- information for the directive. */
+/* Lower the OpenMP parallel or task directive in the current statement
+ in GSI_P. CTX holds context information for the directive. */
static void
-lower_omp_taskreg (tree *stmt_p, omp_context *ctx)
+lower_omp_taskreg (gimple_stmt_iterator *gsi_p, omp_context *ctx)
{
- tree clauses, par_bind, par_body, new_body, bind;
- tree olist, ilist, par_olist, par_ilist;
- tree stmt, child_fn, t;
-
- stmt = *stmt_p;
-
- clauses = OMP_TASKREG_CLAUSES (stmt);
- par_bind = OMP_TASKREG_BODY (stmt);
- par_body = BIND_EXPR_BODY (par_bind);
+ tree clauses;
+ tree child_fn, t;
+ gimple stmt = gsi_stmt (*gsi_p);
+ gimple par_bind, bind;
+ gimple_seq par_body, olist, ilist, par_olist, par_ilist, new_body;
+ struct gimplify_ctx gctx;
+
+ clauses = gimple_omp_taskreg_clauses (stmt);
+ par_bind = gimple_seq_first_stmt (gimple_omp_body (stmt));
+ par_body = gimple_bind_body (par_bind);
child_fn = ctx->cb.dst_fn;
- if (TREE_CODE (stmt) == OMP_PARALLEL && !OMP_PARALLEL_COMBINED (stmt))
+ if (gimple_code (stmt) == GIMPLE_OMP_PARALLEL
+ && !gimple_omp_parallel_combined_p (stmt))
{
struct walk_stmt_info wi;
int ws_num = 0;
memset (&wi, 0, sizeof (wi));
- wi.callback = check_combined_parallel;
wi.info = &ws_num;
wi.val_only = true;
- walk_stmts (&wi, &par_bind);
+ walk_gimple_seq (par_body, check_combined_parallel, NULL, &wi);
if (ws_num == 1)
- OMP_PARALLEL_COMBINED (stmt) = 1;
+ gimple_omp_parallel_set_combined_p (stmt, true);
}
if (ctx->srecord_type)
create_task_copyfn (stmt, ctx);
- push_gimplify_context ();
+ push_gimplify_context (&gctx);
- par_olist = NULL_TREE;
- par_ilist = NULL_TREE;
+ par_olist = NULL;
+ par_ilist = NULL;
lower_rec_input_clauses (clauses, &par_ilist, &par_olist, ctx);
- lower_omp (&par_body, ctx);
- if (TREE_CODE (stmt) == OMP_PARALLEL)
+ lower_omp (par_body, ctx);
+ if (gimple_code (stmt) == GIMPLE_OMP_PARALLEL)
lower_reduction_clauses (clauses, &par_olist, ctx);
/* Declare all the variables created by mapping and the variables
declared in the scope of the parallel body. */
record_vars_into (ctx->block_vars, child_fn);
- record_vars_into (BIND_EXPR_VARS (par_bind), child_fn);
+ record_vars_into (gimple_bind_vars (par_bind), child_fn);
if (ctx->record_type)
{
ctx->sender_decl
= create_tmp_var (ctx->srecord_type ? ctx->srecord_type
: ctx->record_type, ".omp_data_o");
- OMP_TASKREG_DATA_ARG (stmt) = ctx->sender_decl;
+ gimple_omp_taskreg_set_data_arg (stmt, ctx->sender_decl);
}
- olist = NULL_TREE;
- ilist = NULL_TREE;
+ olist = NULL;
+ ilist = NULL;
lower_send_clauses (clauses, &ilist, &olist, ctx);
lower_send_shared_vars (&ilist, &olist, ctx);
/* Once all the expansions are done, sequence all the different
- fragments inside OMP_TASKREG_BODY. */
- bind = build3 (BIND_EXPR, void_type_node, NULL, NULL,
- BIND_EXPR_BLOCK (par_bind));
- TREE_SIDE_EFFECTS (bind) = 1;
+ fragments inside gimple_omp_body. */
- new_body = alloc_stmt_list ();
+ new_body = NULL;
if (ctx->record_type)
{
t = build_fold_addr_expr (ctx->sender_decl);
/* fixup_child_record_type might have changed receiver_decl's type. */
t = fold_convert (TREE_TYPE (ctx->receiver_decl), t);
- t = build_gimple_modify_stmt (ctx->receiver_decl, t);
- append_to_statement_list (t, &new_body);
+ gimple_seq_add_stmt (&new_body,
+ gimple_build_assign (ctx->receiver_decl, t));
}
- append_to_statement_list (par_ilist, &new_body);
- append_to_statement_list (par_body, &new_body);
- append_to_statement_list (par_olist, &new_body);
- maybe_catch_exception (&new_body);
- t = make_node (OMP_RETURN);
- append_to_statement_list (t, &new_body);
- OMP_TASKREG_BODY (stmt) = new_body;
+ gimple_seq_add_seq (&new_body, par_ilist);
+ gimple_seq_add_seq (&new_body, par_body);
+ gimple_seq_add_seq (&new_body, par_olist);
+ new_body = maybe_catch_exception (new_body);
+ gimple_seq_add_stmt (&new_body, gimple_build_omp_return (false));
+ gimple_omp_set_body (stmt, new_body);
- append_to_statement_list (stmt, &BIND_EXPR_BODY (bind));
+ bind = gimple_build_bind (NULL, NULL, gimple_bind_block (par_bind));
+ gimple_bind_add_stmt (bind, stmt);
if (ilist || olist)
{
- append_to_statement_list (bind, &ilist);
- append_to_statement_list (olist, &ilist);
- bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
- TREE_SIDE_EFFECTS (bind) = 1;
- append_to_statement_list (ilist, &BIND_EXPR_BODY (bind));
+ gimple_seq_add_stmt (&ilist, bind);
+ gimple_seq_add_seq (&ilist, olist);
+ bind = gimple_build_bind (NULL, ilist, NULL);
}
- *stmt_p = bind;
+ gsi_replace (gsi_p, bind, true);
- pop_gimplify_context (NULL_TREE);
+ pop_gimplify_context (NULL);
}
/* Callback for lower_omp_1. Return non-NULL if *tp needs to be
- regimplified. */
+ regimplified. If DATA is non-NULL, lower_omp_1 is outside
+ of OpenMP context, but with task_shared_vars set. */
static tree
-lower_omp_2 (tree *tp, int *walk_subtrees, void *data)
+lower_omp_regimplify_p (tree *tp, int *walk_subtrees,
+ void *data)
{
tree t = *tp;
- omp_context *ctx = (omp_context *) data;
/* Any variable with DECL_VALUE_EXPR needs to be regimplified. */
- if (TREE_CODE (t) == VAR_DECL
- && ((ctx && DECL_HAS_VALUE_EXPR_P (t))
- || (task_shared_vars
- && bitmap_bit_p (task_shared_vars, DECL_UID (t)))))
+ if (TREE_CODE (t) == VAR_DECL && data == NULL && DECL_HAS_VALUE_EXPR_P (t))
+ return t;
+
+ if (task_shared_vars
+ && DECL_P (t)
+ && bitmap_bit_p (task_shared_vars, DECL_UID (t)))
return t;
/* If a global variable has been privatized, TREE_CONSTANT on
ADDR_EXPR might be wrong. */
- if (ctx && TREE_CODE (t) == ADDR_EXPR)
+ if (data == NULL && TREE_CODE (t) == ADDR_EXPR)
recompute_tree_invariant_for_addr_expr (t);
*walk_subtrees = !TYPE_P (t) && !DECL_P (t);
@@ -6254,158 +6397,106 @@ lower_omp_2 (tree *tp, int *walk_subtrees, void *data)
}
static void
-lower_omp_1 (tree *tp, omp_context *ctx, tree_stmt_iterator *tsi)
+lower_omp_1 (gimple_stmt_iterator *gsi_p, omp_context *ctx)
{
- tree t = *tp;
+ gimple stmt = gsi_stmt (*gsi_p);
+ struct walk_stmt_info wi;
- if (!t)
- return;
+ if (gimple_has_location (stmt))
+ input_location = gimple_location (stmt);
- if (EXPR_HAS_LOCATION (t))
- input_location = EXPR_LOCATION (t);
+ if (task_shared_vars)
+ memset (&wi, '\0', sizeof (wi));
/* If we have issued syntax errors, avoid doing any heavy lifting.
Just replace the OpenMP directives with a NOP to avoid
confusing RTL expansion. */
- if (errorcount && OMP_DIRECTIVE_P (t))
+ if (errorcount && is_gimple_omp (stmt))
{
- *tp = build_empty_stmt ();
+ gsi_replace (gsi_p, gimple_build_nop (), true);
return;
}
- switch (TREE_CODE (t))
+ switch (gimple_code (stmt))
{
- case STATEMENT_LIST:
- {
- tree_stmt_iterator i;
- for (i = tsi_start (t); !tsi_end_p (i); tsi_next (&i))
- lower_omp_1 (tsi_stmt_ptr (i), ctx, &i);
- }
- break;
-
- case COND_EXPR:
- lower_omp_1 (&COND_EXPR_THEN (t), ctx, NULL);
- lower_omp_1 (&COND_EXPR_ELSE (t), ctx, NULL);
+ case GIMPLE_COND:
if ((ctx || task_shared_vars)
- && walk_tree (&COND_EXPR_COND (t), lower_omp_2, ctx, NULL))
- {
- tree pre = NULL;
- gimplify_expr (&COND_EXPR_COND (t), &pre, NULL,
- is_gimple_condexpr, fb_rvalue);
- if (pre)
- {
- if (tsi)
- tsi_link_before (tsi, pre, TSI_SAME_STMT);
- else
- {
- append_to_statement_list (t, &pre);
- *tp = pre;
- }
- }
- }
+ && (walk_tree (gimple_cond_lhs_ptr (stmt), lower_omp_regimplify_p,
+ ctx ? NULL : &wi, NULL)
+ || walk_tree (gimple_cond_rhs_ptr (stmt), lower_omp_regimplify_p,
+ ctx ? NULL : &wi, NULL)))
+ gimple_regimplify_operands (stmt, gsi_p);
break;
- case CATCH_EXPR:
- lower_omp_1 (&CATCH_BODY (t), ctx, NULL);
+ case GIMPLE_CATCH:
+ lower_omp (gimple_catch_handler (stmt), ctx);
break;
- case EH_FILTER_EXPR:
- lower_omp_1 (&EH_FILTER_FAILURE (t), ctx, NULL);
+ case GIMPLE_EH_FILTER:
+ lower_omp (gimple_eh_filter_failure (stmt), ctx);
break;
- case TRY_CATCH_EXPR:
- case TRY_FINALLY_EXPR:
- lower_omp_1 (&TREE_OPERAND (t, 0), ctx, NULL);
- lower_omp_1 (&TREE_OPERAND (t, 1), ctx, NULL);
+ case GIMPLE_TRY:
+ lower_omp (gimple_try_eval (stmt), ctx);
+ lower_omp (gimple_try_cleanup (stmt), ctx);
break;
- case BIND_EXPR:
- lower_omp_1 (&BIND_EXPR_BODY (t), ctx, NULL);
+ case GIMPLE_BIND:
+ lower_omp (gimple_bind_body (stmt), ctx);
break;
- case RETURN_EXPR:
- lower_omp_1 (&TREE_OPERAND (t, 0), ctx, NULL);
+ case GIMPLE_OMP_PARALLEL:
+ case GIMPLE_OMP_TASK:
+ ctx = maybe_lookup_ctx (stmt);
+ lower_omp_taskreg (gsi_p, ctx);
break;
-
- case OMP_PARALLEL:
- case OMP_TASK:
- ctx = maybe_lookup_ctx (t);
- lower_omp_taskreg (tp, ctx);
- break;
- case OMP_FOR:
- ctx = maybe_lookup_ctx (t);
+ case GIMPLE_OMP_FOR:
+ ctx = maybe_lookup_ctx (stmt);
gcc_assert (ctx);
- lower_omp_for (tp, ctx);
+ lower_omp_for (gsi_p, ctx);
break;
- case OMP_SECTIONS:
- ctx = maybe_lookup_ctx (t);
+ case GIMPLE_OMP_SECTIONS:
+ ctx = maybe_lookup_ctx (stmt);
gcc_assert (ctx);
- lower_omp_sections (tp, ctx);
+ lower_omp_sections (gsi_p, ctx);
break;
- case OMP_SINGLE:
- ctx = maybe_lookup_ctx (t);
+ case GIMPLE_OMP_SINGLE:
+ ctx = maybe_lookup_ctx (stmt);
gcc_assert (ctx);
- lower_omp_single (tp, ctx);
+ lower_omp_single (gsi_p, ctx);
break;
- case OMP_MASTER:
- ctx = maybe_lookup_ctx (t);
+ case GIMPLE_OMP_MASTER:
+ ctx = maybe_lookup_ctx (stmt);
gcc_assert (ctx);
- lower_omp_master (tp, ctx);
+ lower_omp_master (gsi_p, ctx);
break;
- case OMP_ORDERED:
- ctx = maybe_lookup_ctx (t);
+ case GIMPLE_OMP_ORDERED:
+ ctx = maybe_lookup_ctx (stmt);
gcc_assert (ctx);
- lower_omp_ordered (tp, ctx);
+ lower_omp_ordered (gsi_p, ctx);
break;
- case OMP_CRITICAL:
- ctx = maybe_lookup_ctx (t);
+ case GIMPLE_OMP_CRITICAL:
+ ctx = maybe_lookup_ctx (stmt);
gcc_assert (ctx);
- lower_omp_critical (tp, ctx);
+ lower_omp_critical (gsi_p, ctx);
+ break;
+ case GIMPLE_OMP_ATOMIC_LOAD:
+ if ((ctx || task_shared_vars)
+ && walk_tree (gimple_omp_atomic_load_rhs_ptr (stmt),
+ lower_omp_regimplify_p, ctx ? NULL : &wi, NULL))
+ gimple_regimplify_operands (stmt, gsi_p);
break;
-
default:
if ((ctx || task_shared_vars)
- && walk_tree (tp, lower_omp_2, ctx, NULL))
- {
- /* The gimplifier doesn't gimplify CALL_EXPR_STATIC_CHAIN.
- Handle that here. */
- tree call = get_call_expr_in (t);
- if (call
- && CALL_EXPR_STATIC_CHAIN (call)
- && walk_tree (&CALL_EXPR_STATIC_CHAIN (call), lower_omp_2,
- ctx, NULL))
- {
- tree pre = NULL;
- gimplify_expr (&CALL_EXPR_STATIC_CHAIN (call), &pre, NULL,
- is_gimple_val, fb_rvalue);
- if (pre)
- {
- if (tsi)
- tsi_link_before (tsi, pre, TSI_SAME_STMT);
- else
- {
- append_to_statement_list (t, &pre);
- lower_omp_1 (&pre, ctx, NULL);
- *tp = pre;
- return;
- }
- }
- }
-
- if (tsi == NULL)
- gimplify_stmt (tp);
- else
- {
- tree pre = NULL;
- gimplify_expr (tp, &pre, NULL, is_gimple_stmt, fb_none);
- if (pre)
- tsi_link_before (tsi, pre, TSI_SAME_STMT);
- }
- }
+ && walk_gimple_op (stmt, lower_omp_regimplify_p,
+ ctx ? NULL : &wi))
+ gimple_regimplify_operands (stmt, gsi_p);
break;
}
}
static void
-lower_omp (tree *stmt_p, omp_context *ctx)
+lower_omp (gimple_seq body, omp_context *ctx)
{
location_t saved_location = input_location;
- lower_omp_1 (stmt_p, ctx, NULL);
+ gimple_stmt_iterator gsi = gsi_start (body);
+ for (gsi = gsi_start (body); !gsi_end_p (gsi); gsi_next (&gsi))
+ lower_omp_1 (&gsi, ctx);
input_location = saved_location;
}
@@ -6414,17 +6505,22 @@ lower_omp (tree *stmt_p, omp_context *ctx)
static unsigned int
execute_lower_omp (void)
{
+ gimple_seq body;
+
all_contexts = splay_tree_new (splay_tree_compare_pointers, 0,
delete_omp_context);
- scan_omp (&DECL_SAVED_TREE (current_function_decl), NULL);
+ body = gimple_body (current_function_decl);
+ scan_omp (body, NULL);
gcc_assert (taskreg_nesting_level == 0);
if (all_contexts->root)
{
+ struct gimplify_ctx gctx;
+
if (task_shared_vars)
- push_gimplify_context ();
- lower_omp (&DECL_SAVED_TREE (current_function_decl), NULL);
+ push_gimplify_context (&gctx);
+ lower_omp (body, NULL);
if (task_shared_vars)
pop_gimplify_context (NULL);
}
@@ -6473,13 +6569,25 @@ static splay_tree all_labels;
true if an error is detected. */
static bool
-diagnose_sb_0 (tree *stmt_p, tree branch_ctx, tree label_ctx)
+diagnose_sb_0 (gimple_stmt_iterator *gsi_p,
+ gimple branch_ctx, gimple label_ctx)
{
- bool exit_p = true;
-
- if ((label_ctx ? TREE_VALUE (label_ctx) : NULL) == branch_ctx)
+ if (label_ctx == branch_ctx)
return false;
+
+ /*
+ Previously we kept track of the label's entire context in diagnose_sb_[12]
+ so we could traverse it and issue a correct "exit" or "enter" error
+ message upon a structured block violation.
+
+ We built the context by building a list with tree_cons'ing, but there is
+ no easy counterpart in gimple tuples. It seems like far too much work
+ for issuing exit/enter error messages. If someone really misses the
+ distinct error message... patches welcome.
+ */
+
+#if 0
/* Try to avoid confusing the user by producing and error message
with correct "exit" or "enter" verbiage. We prefer "exit"
unless we can show that LABEL_CTX is nested within BRANCH_CTX. */
@@ -6502,63 +6610,64 @@ diagnose_sb_0 (tree *stmt_p, tree branch_ctx, tree label_ctx)
error ("invalid exit from OpenMP structured block");
else
error ("invalid entry to OpenMP structured block");
+#endif
+
+ /* If it's obvious we have an invalid entry, be specific about the error. */
+ if (branch_ctx == NULL)
+ error ("invalid entry to OpenMP structured block");
+ else
+ /* Otherwise, be vague and lazy, but efficient. */
+ error ("invalid branch to/from an OpenMP structured block");
- *stmt_p = build_empty_stmt ();
+ gsi_replace (gsi_p, gimple_build_nop (), false);
return true;
}
/* Pass 1: Create a minimal tree of OpenMP structured blocks, and record
- where in the tree each label is found. */
+ where each label is found. */
static tree
-diagnose_sb_1 (tree *tp, int *walk_subtrees, void *data)
+diagnose_sb_1 (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
+ struct walk_stmt_info *wi)
{
- struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
- tree context = (tree) wi->info;
- tree inner_context;
- tree t = *tp;
- int i;
+ gimple context = (gimple) wi->info;
+ gimple inner_context;
+ gimple stmt = gsi_stmt (*gsi_p);
- *walk_subtrees = 0;
- switch (TREE_CODE (t))
+ *handled_ops_p = true;
+
+ switch (gimple_code (stmt))
{
- case OMP_PARALLEL:
- case OMP_TASK:
- case OMP_SECTIONS:
- case OMP_SINGLE:
- walk_tree (&OMP_CLAUSES (t), diagnose_sb_1, wi, NULL);
- /* FALLTHRU */
- case OMP_SECTION:
- case OMP_MASTER:
- case OMP_ORDERED:
- case OMP_CRITICAL:
- /* The minimal context here is just a tree of statements. */
- inner_context = tree_cons (NULL, t, context);
+ WALK_SUBSTMTS;
+
+ case GIMPLE_OMP_PARALLEL:
+ case GIMPLE_OMP_TASK:
+ case GIMPLE_OMP_SECTIONS:
+ case GIMPLE_OMP_SINGLE:
+ case GIMPLE_OMP_SECTION:
+ case GIMPLE_OMP_MASTER:
+ case GIMPLE_OMP_ORDERED:
+ case GIMPLE_OMP_CRITICAL:
+ /* The minimal context here is just the current OMP construct. */
+ inner_context = stmt;
wi->info = inner_context;
- walk_stmts (wi, &OMP_BODY (t));
+ walk_gimple_seq (gimple_omp_body (stmt), diagnose_sb_1, NULL, wi);
wi->info = context;
break;
- case OMP_FOR:
- walk_tree (&OMP_FOR_CLAUSES (t), diagnose_sb_1, wi, NULL);
- inner_context = tree_cons (NULL, t, context);
+ case GIMPLE_OMP_FOR:
+ inner_context = stmt;
wi->info = inner_context;
- for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (t)); i++)
- {
- walk_tree (&TREE_VEC_ELT (OMP_FOR_INIT (t), i), diagnose_sb_1,
- wi, NULL);
- walk_tree (&TREE_VEC_ELT (OMP_FOR_COND (t), i), diagnose_sb_1,
- wi, NULL);
- walk_tree (&TREE_VEC_ELT (OMP_FOR_INCR (t), i), diagnose_sb_1,
- wi, NULL);
- }
- walk_stmts (wi, &OMP_FOR_PRE_BODY (t));
- walk_stmts (wi, &OMP_FOR_BODY (t));
+ /* gimple_omp_for_{index,initial,final} are all DECLs; no need to
+ walk them. */
+ walk_gimple_seq (gimple_omp_for_pre_body (stmt),
+ diagnose_sb_1, NULL, wi);
+ walk_gimple_seq (gimple_omp_body (stmt), diagnose_sb_1, NULL, wi);
wi->info = context;
break;
- case LABEL_EXPR:
- splay_tree_insert (all_labels, (splay_tree_key) LABEL_EXPR_LABEL (t),
+ case GIMPLE_LABEL:
+ splay_tree_insert (all_labels, (splay_tree_key) gimple_label_label (stmt),
(splay_tree_value) context);
break;
@@ -6573,76 +6682,68 @@ diagnose_sb_1 (tree *tp, int *walk_subtrees, void *data)
the destination label's context. */
static tree
-diagnose_sb_2 (tree *tp, int *walk_subtrees, void *data)
+diagnose_sb_2 (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
+ struct walk_stmt_info *wi)
{
- struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
- tree context = (tree) wi->info;
+ gimple context = (gimple) wi->info;
splay_tree_node n;
- tree t = *tp;
- int i;
+ gimple stmt = gsi_stmt (*gsi_p);
- *walk_subtrees = 0;
- switch (TREE_CODE (t))
+ *handled_ops_p = true;
+
+ switch (gimple_code (stmt))
{
- case OMP_PARALLEL:
- case OMP_TASK:
- case OMP_SECTIONS:
- case OMP_SINGLE:
- walk_tree (&OMP_CLAUSES (t), diagnose_sb_2, wi, NULL);
- /* FALLTHRU */
- case OMP_SECTION:
- case OMP_MASTER:
- case OMP_ORDERED:
- case OMP_CRITICAL:
- wi->info = t;
- walk_stmts (wi, &OMP_BODY (t));
+ WALK_SUBSTMTS;
+
+ case GIMPLE_OMP_PARALLEL:
+ case GIMPLE_OMP_TASK:
+ case GIMPLE_OMP_SECTIONS:
+ case GIMPLE_OMP_SINGLE:
+ case GIMPLE_OMP_SECTION:
+ case GIMPLE_OMP_MASTER:
+ case GIMPLE_OMP_ORDERED:
+ case GIMPLE_OMP_CRITICAL:
+ wi->info = stmt;
+ walk_gimple_seq (gimple_omp_body (stmt), diagnose_sb_2, NULL, wi);
wi->info = context;
break;
- case OMP_FOR:
- walk_tree (&OMP_FOR_CLAUSES (t), diagnose_sb_2, wi, NULL);
- wi->info = t;
- for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (t)); i++)
- {
- walk_tree (&TREE_VEC_ELT (OMP_FOR_INIT (t), i), diagnose_sb_2,
- wi, NULL);
- walk_tree (&TREE_VEC_ELT (OMP_FOR_COND (t), i), diagnose_sb_2,
- wi, NULL);
- walk_tree (&TREE_VEC_ELT (OMP_FOR_INCR (t), i), diagnose_sb_2,
- wi, NULL);
- }
- walk_stmts (wi, &OMP_FOR_PRE_BODY (t));
- walk_stmts (wi, &OMP_FOR_BODY (t));
+ case GIMPLE_OMP_FOR:
+ wi->info = stmt;
+ /* gimple_omp_for_{index,initial,final} are all DECLs; no need to
+ walk them. */
+ walk_gimple_seq (gimple_omp_for_pre_body (stmt),
+ diagnose_sb_2, NULL, wi);
+ walk_gimple_seq (gimple_omp_body (stmt), diagnose_sb_2, NULL, wi);
wi->info = context;
break;
- case GOTO_EXPR:
+ case GIMPLE_GOTO:
{
- tree lab = GOTO_DESTINATION (t);
+ tree lab = gimple_goto_dest (stmt);
if (TREE_CODE (lab) != LABEL_DECL)
break;
n = splay_tree_lookup (all_labels, (splay_tree_key) lab);
- diagnose_sb_0 (tp, context, n ? (tree) n->value : NULL_TREE);
+ diagnose_sb_0 (gsi_p, context, n ? (gimple) n->value : NULL);
}
break;
- case SWITCH_EXPR:
+ case GIMPLE_SWITCH:
{
- tree vec = SWITCH_LABELS (t);
- int i, len = TREE_VEC_LENGTH (vec);
- for (i = 0; i < len; ++i)
+ unsigned int i;
+ for (i = 0; i < gimple_switch_num_labels (stmt); ++i)
{
- tree lab = CASE_LABEL (TREE_VEC_ELT (vec, i));
+ tree lab = CASE_LABEL (gimple_switch_label (stmt, i));
n = splay_tree_lookup (all_labels, (splay_tree_key) lab);
- if (diagnose_sb_0 (tp, context, (tree) n->value))
+ if (n && diagnose_sb_0 (gsi_p, context, (gimple) n->value))
break;
}
}
break;
- case RETURN_EXPR:
- diagnose_sb_0 (tp, context, NULL_TREE);
+ case GIMPLE_RETURN:
+ diagnose_sb_0 (gsi_p, context, NULL);
break;
default:
@@ -6657,24 +6758,25 @@ diagnose_omp_structured_block_errors (tree fndecl)
{
tree save_current = current_function_decl;
struct walk_stmt_info wi;
+ struct function *old_cfun = cfun;
+ gimple_seq body = gimple_body (fndecl);
current_function_decl = fndecl;
+ set_cfun (DECL_STRUCT_FUNCTION (fndecl));
all_labels = splay_tree_new (splay_tree_compare_pointers, 0, 0);
memset (&wi, 0, sizeof (wi));
- wi.callback = diagnose_sb_1;
- walk_stmts (&wi, &DECL_SAVED_TREE (fndecl));
+ walk_gimple_seq (body, diagnose_sb_1, NULL, &wi);
memset (&wi, 0, sizeof (wi));
- wi.callback = diagnose_sb_2;
wi.want_locations = true;
- wi.want_return_expr = true;
- walk_stmts (&wi, &DECL_SAVED_TREE (fndecl));
+ walk_gimple_seq (body, diagnose_sb_2, NULL, &wi);
splay_tree_delete (all_labels);
all_labels = NULL;
+ set_cfun (old_cfun);
current_function_decl = save_current;
}
diff --git a/gcc/opt-functions.awk b/gcc/opt-functions.awk
index 213e9497dcf..a14b8c203d5 100644
--- a/gcc/opt-functions.awk
+++ b/gcc/opt-functions.awk
@@ -128,6 +128,23 @@ function var_type(flags)
return "const char *"
}
+# Return the type of variable that should be associated with the given flags
+# for use within a structure. Simple variables are changed to unsigned char
+# type instead of int to save space.
+function var_type_struct(flags)
+{
+ if (flag_set_p("UInteger", flags))
+ return "int "
+ else if (!flag_set_p("Joined.*", flags)) {
+ if (flag_set_p(".*Mask.*", flags))
+ return "int "
+ else
+ return "unsigned char "
+ }
+ else
+ return "const char *"
+}
+
# Given that an option has flags FLAGS, return an initializer for the
# "var_cond" and "var_value" fields of its cl_options[] entry.
function var_set(flags)
diff --git a/gcc/optabs.c b/gcc/optabs.c
index 6e8c6cf3d21..ee5bec11a41 100644
--- a/gcc/optabs.c
+++ b/gcc/optabs.c
@@ -1571,14 +1571,14 @@ expand_binop (enum machine_mode mode, optab binoptab, rtx op0, rtx op1,
enum optab_methods next_methods
= (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN
? OPTAB_WIDEN : methods);
- enum mode_class class;
+ enum mode_class mclass;
enum machine_mode wider_mode;
rtx libfunc;
rtx temp;
rtx entry_last = get_last_insn ();
rtx last;
- class = GET_MODE_CLASS (mode);
+ mclass = GET_MODE_CLASS (mode);
/* If subtracting an integer constant, convert this into an addition of
the negated constant. */
@@ -1609,7 +1609,7 @@ expand_binop (enum machine_mode mode, optab binoptab, rtx op0, rtx op1,
&& optab_handler (rotr_optab, mode)->insn_code != CODE_FOR_nothing)
|| (binoptab == rotr_optab
&& optab_handler (rotl_optab, mode)->insn_code != CODE_FOR_nothing))
- && class == MODE_INT)
+ && mclass == MODE_INT)
{
optab otheroptab = (binoptab == rotl_optab ? rotr_optab : rotl_optab);
rtx newop1;
@@ -1658,7 +1658,7 @@ expand_binop (enum machine_mode mode, optab binoptab, rtx op0, rtx op1,
can open-code the operation. Check for a widening multiply at the
wider mode as well. */
- if (CLASS_HAS_WIDER_MODES_P (class)
+ if (CLASS_HAS_WIDER_MODES_P (mclass)
&& methods != OPTAB_DIRECT && methods != OPTAB_LIB)
for (wider_mode = GET_MODE_WIDER_MODE (mode);
wider_mode != VOIDmode;
@@ -1683,7 +1683,7 @@ expand_binop (enum machine_mode mode, optab binoptab, rtx op0, rtx op1,
|| binoptab == xor_optab
|| binoptab == add_optab || binoptab == sub_optab
|| binoptab == smul_optab || binoptab == ashl_optab)
- && class == MODE_INT)
+ && mclass == MODE_INT)
{
no_extend = 1;
xop0 = avoid_expensive_constant (mode, binoptab,
@@ -1703,7 +1703,7 @@ expand_binop (enum machine_mode mode, optab binoptab, rtx op0, rtx op1,
unsignedp, OPTAB_DIRECT);
if (temp)
{
- if (class != MODE_INT
+ if (mclass != MODE_INT
|| !TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode),
GET_MODE_BITSIZE (wider_mode)))
{
@@ -1734,7 +1734,7 @@ expand_binop (enum machine_mode mode, optab binoptab, rtx op0, rtx op1,
/* These can be done a word at a time. */
if ((binoptab == and_optab || binoptab == ior_optab || binoptab == xor_optab)
- && class == MODE_INT
+ && mclass == MODE_INT
&& GET_MODE_SIZE (mode) > UNITS_PER_WORD
&& optab_handler (binoptab, word_mode)->insn_code != CODE_FOR_nothing)
{
@@ -1785,7 +1785,7 @@ expand_binop (enum machine_mode mode, optab binoptab, rtx op0, rtx op1,
/* Synthesize double word shifts from single word shifts. */
if ((binoptab == lshr_optab || binoptab == ashl_optab
|| binoptab == ashr_optab)
- && class == MODE_INT
+ && mclass == MODE_INT
&& (GET_CODE (op1) == CONST_INT || !optimize_size)
&& GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
&& optab_handler (binoptab, word_mode)->insn_code != CODE_FOR_nothing
@@ -1855,7 +1855,7 @@ expand_binop (enum machine_mode mode, optab binoptab, rtx op0, rtx op1,
/* Synthesize double word rotates from single word shifts. */
if ((binoptab == rotl_optab || binoptab == rotr_optab)
- && class == MODE_INT
+ && mclass == MODE_INT
&& GET_CODE (op1) == CONST_INT
&& GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
&& optab_handler (ashl_optab, word_mode)->insn_code != CODE_FOR_nothing
@@ -1968,7 +1968,7 @@ expand_binop (enum machine_mode mode, optab binoptab, rtx op0, rtx op1,
/* These can be done a word at a time by propagating carries. */
if ((binoptab == add_optab || binoptab == sub_optab)
- && class == MODE_INT
+ && mclass == MODE_INT
&& GET_MODE_SIZE (mode) >= 2 * UNITS_PER_WORD
&& optab_handler (binoptab, word_mode)->insn_code != CODE_FOR_nothing)
{
@@ -2094,7 +2094,7 @@ expand_binop (enum machine_mode mode, optab binoptab, rtx op0, rtx op1,
try using a signed widening multiply. */
if (binoptab == smul_optab
- && class == MODE_INT
+ && mclass == MODE_INT
&& GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
&& optab_handler (smul_optab, word_mode)->insn_code != CODE_FOR_nothing
&& optab_handler (add_optab, word_mode)->insn_code != CODE_FOR_nothing)
@@ -2197,7 +2197,7 @@ expand_binop (enum machine_mode mode, optab binoptab, rtx op0, rtx op1,
/* Look for a wider mode of the same class for which it appears we can do
the operation. */
- if (CLASS_HAS_WIDER_MODES_P (class))
+ if (CLASS_HAS_WIDER_MODES_P (mclass))
{
for (wider_mode = GET_MODE_WIDER_MODE (mode);
wider_mode != VOIDmode;
@@ -2219,7 +2219,7 @@ expand_binop (enum machine_mode mode, optab binoptab, rtx op0, rtx op1,
|| binoptab == xor_optab
|| binoptab == add_optab || binoptab == sub_optab
|| binoptab == smul_optab || binoptab == ashl_optab)
- && class == MODE_INT)
+ && mclass == MODE_INT)
no_extend = 1;
xop0 = widen_operand (xop0, wider_mode, mode,
@@ -2233,7 +2233,7 @@ expand_binop (enum machine_mode mode, optab binoptab, rtx op0, rtx op1,
unsignedp, methods);
if (temp)
{
- if (class != MODE_INT
+ if (mclass != MODE_INT
|| !TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode),
GET_MODE_BITSIZE (wider_mode)))
{
@@ -2327,12 +2327,12 @@ expand_twoval_unop (optab unoptab, rtx op0, rtx targ0, rtx targ1,
int unsignedp)
{
enum machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
- enum mode_class class;
+ enum mode_class mclass;
enum machine_mode wider_mode;
rtx entry_last = get_last_insn ();
rtx last;
- class = GET_MODE_CLASS (mode);
+ mclass = GET_MODE_CLASS (mode);
if (!targ0)
targ0 = gen_reg_rtx (mode);
@@ -2374,7 +2374,7 @@ expand_twoval_unop (optab unoptab, rtx op0, rtx targ0, rtx targ1,
/* It can't be done in this mode. Can we do it in a wider mode? */
- if (CLASS_HAS_WIDER_MODES_P (class))
+ if (CLASS_HAS_WIDER_MODES_P (mclass))
{
for (wider_mode = GET_MODE_WIDER_MODE (mode);
wider_mode != VOIDmode;
@@ -2420,12 +2420,12 @@ expand_twoval_binop (optab binoptab, rtx op0, rtx op1, rtx targ0, rtx targ1,
int unsignedp)
{
enum machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
- enum mode_class class;
+ enum mode_class mclass;
enum machine_mode wider_mode;
rtx entry_last = get_last_insn ();
rtx last;
- class = GET_MODE_CLASS (mode);
+ mclass = GET_MODE_CLASS (mode);
if (!targ0)
targ0 = gen_reg_rtx (mode);
@@ -2491,7 +2491,7 @@ expand_twoval_binop (optab binoptab, rtx op0, rtx op1, rtx targ0, rtx targ1,
/* It can't be done in this mode. Can we do it in a wider mode? */
- if (CLASS_HAS_WIDER_MODES_P (class))
+ if (CLASS_HAS_WIDER_MODES_P (mclass))
{
for (wider_mode = GET_MODE_WIDER_MODE (mode);
wider_mode != VOIDmode;
@@ -2591,8 +2591,8 @@ expand_simple_unop (enum machine_mode mode, enum rtx_code code, rtx op0,
static rtx
widen_clz (enum machine_mode mode, rtx op0, rtx target)
{
- enum mode_class class = GET_MODE_CLASS (mode);
- if (CLASS_HAS_WIDER_MODES_P (class))
+ enum mode_class mclass = GET_MODE_CLASS (mode);
+ if (CLASS_HAS_WIDER_MODES_P (mclass))
{
enum machine_mode wider_mode;
for (wider_mode = GET_MODE_WIDER_MODE (mode);
@@ -2702,11 +2702,11 @@ expand_doubleword_clz (enum machine_mode mode, rtx op0, rtx target)
static rtx
widen_bswap (enum machine_mode mode, rtx op0, rtx target)
{
- enum mode_class class = GET_MODE_CLASS (mode);
+ enum mode_class mclass = GET_MODE_CLASS (mode);
enum machine_mode wider_mode;
rtx x, last;
- if (!CLASS_HAS_WIDER_MODES_P (class))
+ if (!CLASS_HAS_WIDER_MODES_P (mclass))
return NULL_RTX;
for (wider_mode = GET_MODE_WIDER_MODE (mode);
@@ -2767,8 +2767,8 @@ expand_doubleword_bswap (enum machine_mode mode, rtx op, rtx target)
static rtx
expand_parity (enum machine_mode mode, rtx op0, rtx target)
{
- enum mode_class class = GET_MODE_CLASS (mode);
- if (CLASS_HAS_WIDER_MODES_P (class))
+ enum mode_class mclass = GET_MODE_CLASS (mode);
+ if (CLASS_HAS_WIDER_MODES_P (mclass))
{
enum machine_mode wider_mode;
for (wider_mode = mode; wider_mode != VOIDmode;
@@ -3116,7 +3116,7 @@ rtx
expand_unop (enum machine_mode mode, optab unoptab, rtx op0, rtx target,
int unsignedp)
{
- enum mode_class class = GET_MODE_CLASS (mode);
+ enum mode_class mclass = GET_MODE_CLASS (mode);
enum machine_mode wider_mode;
rtx temp;
rtx libfunc;
@@ -3163,7 +3163,7 @@ expand_unop (enum machine_mode mode, optab unoptab, rtx op0, rtx target,
goto try_libcall;
}
- if (CLASS_HAS_WIDER_MODES_P (class))
+ if (CLASS_HAS_WIDER_MODES_P (mclass))
for (wider_mode = GET_MODE_WIDER_MODE (mode);
wider_mode != VOIDmode;
wider_mode = GET_MODE_WIDER_MODE (wider_mode))
@@ -3180,14 +3180,14 @@ expand_unop (enum machine_mode mode, optab unoptab, rtx op0, rtx target,
xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
(unoptab == neg_optab
|| unoptab == one_cmpl_optab)
- && class == MODE_INT);
+ && mclass == MODE_INT);
temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
unsignedp);
if (temp)
{
- if (class != MODE_INT
+ if (mclass != MODE_INT
|| !TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode),
GET_MODE_BITSIZE (wider_mode)))
{
@@ -3206,7 +3206,7 @@ expand_unop (enum machine_mode mode, optab unoptab, rtx op0, rtx target,
/* These can be done a word at a time. */
if (unoptab == one_cmpl_optab
- && class == MODE_INT
+ && mclass == MODE_INT
&& GET_MODE_SIZE (mode) > UNITS_PER_WORD
&& optab_handler (unoptab, word_mode)->insn_code != CODE_FOR_nothing)
{
@@ -3323,7 +3323,7 @@ expand_unop (enum machine_mode mode, optab unoptab, rtx op0, rtx target,
/* It can't be done in this mode. Can we do it in a wider mode? */
- if (CLASS_HAS_WIDER_MODES_P (class))
+ if (CLASS_HAS_WIDER_MODES_P (mclass))
{
for (wider_mode = GET_MODE_WIDER_MODE (mode);
wider_mode != VOIDmode;
@@ -3343,7 +3343,7 @@ expand_unop (enum machine_mode mode, optab unoptab, rtx op0, rtx target,
xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
(unoptab == neg_optab
|| unoptab == one_cmpl_optab)
- && class == MODE_INT);
+ && mclass == MODE_INT);
temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
unsignedp);
@@ -3358,7 +3358,7 @@ expand_unop (enum machine_mode mode, optab unoptab, rtx op0, rtx target,
if (temp)
{
- if (class != MODE_INT)
+ if (mclass != MODE_INT)
{
if (target == 0)
target = gen_reg_rtx (mode);
@@ -4191,7 +4191,7 @@ emit_cmp_and_jump_insn_1 (rtx x, rtx y, enum machine_mode mode,
enum rtx_code comparison, int unsignedp, rtx label)
{
rtx test = gen_rtx_fmt_ee (comparison, mode, x, y);
- enum mode_class class = GET_MODE_CLASS (mode);
+ enum mode_class mclass = GET_MODE_CLASS (mode);
enum machine_mode wider_mode = mode;
/* Try combined insns first. */
@@ -4238,7 +4238,7 @@ emit_cmp_and_jump_insn_1 (rtx x, rtx y, enum machine_mode mode,
return;
}
- if (!CLASS_HAS_WIDER_MODES_P (class))
+ if (!CLASS_HAS_WIDER_MODES_P (mclass))
break;
wider_mode = GET_MODE_WIDER_MODE (wider_mode);
diff --git a/gcc/optc-gen.awk b/gcc/optc-gen.awk
index 79fe800018b..d53ba69aa76 100644
--- a/gcc/optc-gen.awk
+++ b/gcc/optc-gen.awk
@@ -28,6 +28,7 @@
BEGIN {
n_opts = 0
n_langs = 0
+ n_target_save = 0
quote = "\042"
comma = ","
FS=SUBSEP
@@ -41,6 +42,11 @@ BEGIN {
langs[n_langs] = $2
n_langs++;
}
+ else if ($1 == "TargetSave") {
+ # Make sure the declarations are put in source order
+ target_save_decl[n_target_save] = $2
+ n_target_save++
+ }
else {
name = opt_args("Mask", $1)
if (name == "") {
@@ -64,10 +70,17 @@ print "#include " quote "intl.h" quote
print ""
print "#ifdef GCC_DRIVER"
print "int target_flags;"
+print "#else"
+print "#include " quote "flags.h" quote
+print "#include " quote "target.h" quote
print "#endif /* GCC_DRIVER */"
print ""
+have_save = 0;
for (i = 0; i < n_opts; i++) {
+ if (flag_set_p("Save", flags[i]))
+ have_save = 1;
+
name = var_name(flags[i]);
if (name == "")
continue;
@@ -210,4 +223,310 @@ for (i = 0; i < n_opts; i++) {
}
print "};"
+
+print "";
+print "#if !defined(GCC_DRIVER) && !defined(IN_LIBGCC2) && !defined(IN_TARGET_LIBS)"
+print "";
+print "/* Save optimization variables into a structure. */"
+print "void";
+print "cl_optimization_save (struct cl_optimization *ptr)";
+print "{";
+
+n_opt_char = 2;
+n_opt_short = 0;
+n_opt_int = 0;
+n_opt_other = 0;
+var_opt_char[0] = "optimize";
+var_opt_char[1] = "optimize_size";
+var_opt_range["optimize"] = "0, 255";
+var_opt_range["optimize_size"] = "0, 255";
+
+# Sort by size to mimic how the structure is laid out to be friendlier to the
+# cache.
+
+for (i = 0; i < n_opts; i++) {
+ if (flag_set_p("Optimization", flags[i])) {
+ name = var_name(flags[i])
+ if(name == "")
+ continue;
+
+ if(name in var_opt_seen)
+ continue;
+
+ var_opt_seen[name]++;
+ otype = var_type_struct(flags[i]);
+ if (otype ~ "^((un)?signed +)?int *$")
+ var_opt_int[n_opt_int++] = name;
+
+ else if (otype ~ "^((un)?signed +)?short *$")
+ var_opt_short[n_opt_short++] = name;
+
+ else if (otype ~ "^((un)?signed +)?char *$") {
+ var_opt_char[n_opt_char++] = name;
+ if (otype ~ "^unsigned +char *$")
+ var_opt_range[name] = "0, 255"
+ else if (otype ~ "^signed +char *$")
+ var_opt_range[name] = "-128, 127"
+ }
+ else
+ var_opt_other[n_opt_other++] = name;
+ }
+}
+
+for (i = 0; i < n_opt_char; i++) {
+ name = var_opt_char[i];
+ if (var_opt_range[name] != "")
+ print " gcc_assert (IN_RANGE (" name ", " var_opt_range[name] "));";
+}
+
+print "";
+for (i = 0; i < n_opt_other; i++) {
+ print " ptr->" var_opt_other[i] " = " var_opt_other[i] ";";
+}
+
+for (i = 0; i < n_opt_int; i++) {
+ print " ptr->" var_opt_int[i] " = " var_opt_int[i] ";";
+}
+
+for (i = 0; i < n_opt_short; i++) {
+ print " ptr->" var_opt_short[i] " = " var_opt_short[i] ";";
+}
+
+for (i = 0; i < n_opt_char; i++) {
+ print " ptr->" var_opt_char[i] " = " var_opt_char[i] ";";
+}
+
+print "}";
+
+print "";
+print "/* Restore optimization options from a structure. */";
+print "void";
+print "cl_optimization_restore (struct cl_optimization *ptr)";
+print "{";
+
+for (i = 0; i < n_opt_other; i++) {
+ print " " var_opt_other[i] " = ptr->" var_opt_other[i] ";";
+}
+
+for (i = 0; i < n_opt_int; i++) {
+ print " " var_opt_int[i] " = ptr->" var_opt_int[i] ";";
+}
+
+for (i = 0; i < n_opt_short; i++) {
+ print " " var_opt_short[i] " = ptr->" var_opt_short[i] ";";
+}
+
+for (i = 0; i < n_opt_char; i++) {
+ print " " var_opt_char[i] " = ptr->" var_opt_char[i] ";";
+}
+
+print "}";
+
+print "";
+print "/* Print optimization options from a structure. */";
+print "void";
+print "cl_optimization_print (FILE *file,";
+print " int indent_to,";
+print " struct cl_optimization *ptr)";
+print "{";
+
+print " fputs (\"\\n\", file);";
+for (i = 0; i < n_opt_other; i++) {
+ print " if (ptr->" var_opt_other[i] ")";
+ print " fprintf (file, \"%*s%s (0x%lx)\\n\",";
+ print " indent_to, \"\",";
+ print " \"" var_opt_other[i] "\",";
+ print " (unsigned long)ptr->" var_opt_other[i] ");";
+ print "";
+}
+
+for (i = 0; i < n_opt_int; i++) {
+ print " if (ptr->" var_opt_int[i] ")";
+ print " fprintf (file, \"%*s%s (0x%x)\\n\",";
+ print " indent_to, \"\",";
+ print " \"" var_opt_int[i] "\",";
+ print " ptr->" var_opt_int[i] ");";
+ print "";
+}
+
+for (i = 0; i < n_opt_short; i++) {
+ print " if (ptr->" var_opt_short[i] ")";
+ print " fprintf (file, \"%*s%s (0x%x)\\n\",";
+ print " indent_to, \"\",";
+ print " \"" var_opt_short[i] "\",";
+ print " ptr->" var_opt_short[i] ");";
+ print "";
+}
+
+for (i = 0; i < n_opt_char; i++) {
+ print " if (ptr->" var_opt_char[i] ")";
+ print " fprintf (file, \"%*s%s (0x%x)\\n\",";
+ print " indent_to, \"\",";
+ print " \"" var_opt_char[i] "\",";
+ print " ptr->" var_opt_char[i] ");";
+ print "";
+}
+
+print "}";
+
+print "";
+print "/* Save selected option variables into a structure. */"
+print "void";
+print "cl_target_option_save (struct cl_target_option *ptr)";
+print "{";
+
+n_target_char = 0;
+n_target_short = 0;
+n_target_int = 0;
+n_target_other = 0;
+
+if (have_save) {
+ for (i = 0; i < n_opts; i++) {
+ if (flag_set_p("Save", flags[i])) {
+ name = var_name(flags[i])
+ if(name == "")
+ name = "target_flags";
+
+ if(name in var_save_seen)
+ continue;
+
+ var_save_seen[name]++;
+ otype = var_type_struct(flags[i])
+ if (otype ~ "^((un)?signed +)?int *$")
+ var_target_int[n_target_int++] = name;
+
+ else if (otype ~ "^((un)?signed +)?short *$")
+ var_target_short[n_target_short++] = name;
+
+ else if (otype ~ "^((un)?signed +)?char *$") {
+ var_target_char[n_target_char++] = name;
+ if (otype ~ "^unsigned +char *$")
+ var_target_range[name] = "0, 255"
+ else if (otype ~ "^signed +char *$")
+ var_target_range[name] = "-128, 127"
+ }
+ else
+ var_target_other[n_target_other++] = name;
+ }
+ }
+} else {
+ var_target_int[n_target_int++] = "target_flags";
+}
+
+have_assert = 0;
+for (i = 0; i < n_target_char; i++) {
+ name = var_target_char[i];
+ if (var_target_range[name] != "") {
+ have_assert = 1;
+ print " gcc_assert (IN_RANGE (" name ", " var_target_range[name] "));";
+ }
+}
+
+if (have_assert)
+ print "";
+
+print " if (targetm.target_option.save)";
+print " targetm.target_option.save (ptr);";
+print "";
+
+for (i = 0; i < n_target_other; i++) {
+ print " ptr->" var_target_other[i] " = " var_target_other[i] ";";
+}
+
+for (i = 0; i < n_target_int; i++) {
+ print " ptr->" var_target_int[i] " = " var_target_int[i] ";";
+}
+
+for (i = 0; i < n_target_short; i++) {
+ print " ptr->" var_target_short[i] " = " var_target_short[i] ";";
+}
+
+for (i = 0; i < n_target_char; i++) {
+ print " ptr->" var_target_char[i] " = " var_target_char[i] ";";
+}
+
+print "}";
+
+print "";
+print "/* Restore selected current options from a structure. */";
+print "void";
+print "cl_target_option_restore (struct cl_target_option *ptr)";
+print "{";
+
+for (i = 0; i < n_target_other; i++) {
+ print " " var_target_other[i] " = ptr->" var_target_other[i] ";";
+}
+
+for (i = 0; i < n_target_int; i++) {
+ print " " var_target_int[i] " = ptr->" var_target_int[i] ";";
+}
+
+for (i = 0; i < n_target_short; i++) {
+ print " " var_target_short[i] " = ptr->" var_target_short[i] ";";
+}
+
+for (i = 0; i < n_target_char; i++) {
+ print " " var_target_char[i] " = ptr->" var_target_char[i] ";";
+}
+
+# This must occur after the normal variables in case the code depends on those
+# variables.
+print "";
+print " if (targetm.target_option.restore)";
+print " targetm.target_option.restore (ptr);";
+
+print "}";
+
+print "";
+print "/* Print optimization options from a structure. */";
+print "void";
+print "cl_target_option_print (FILE *file,";
+print " int indent,";
+print " struct cl_target_option *ptr)";
+print "{";
+
+print " fputs (\"\\n\", file);";
+for (i = 0; i < n_target_other; i++) {
+ print " if (ptr->" var_target_other[i] ")";
+ print " fprintf (file, \"%*s%s (0x%lx)\\n\",";
+ print " indent, \"\",";
+ print " \"" var_target_other[i] "\",";
+ print " (unsigned long)ptr->" var_target_other[i] ");";
+ print "";
+}
+
+for (i = 0; i < n_target_int; i++) {
+ print " if (ptr->" var_target_int[i] ")";
+ print " fprintf (file, \"%*s%s (0x%x)\\n\",";
+ print " indent, \"\",";
+ print " \"" var_target_int[i] "\",";
+ print " ptr->" var_target_int[i] ");";
+ print "";
+}
+
+for (i = 0; i < n_target_short; i++) {
+ print " if (ptr->" var_target_short[i] ")";
+ print " fprintf (file, \"%*s%s (0x%x)\\n\",";
+ print " indent, \"\",";
+ print " \"" var_target_short[i] "\",";
+ print " ptr->" var_target_short[i] ");";
+ print "";
+}
+
+for (i = 0; i < n_target_char; i++) {
+ print " if (ptr->" var_target_char[i] ")";
+ print " fprintf (file, \"%*s%s (0x%x)\\n\",";
+ print " indent, \"\",";
+ print " \"" var_target_char[i] "\",";
+ print " ptr->" var_target_char[i] ");";
+ print "";
+}
+
+print "";
+print " if (targetm.target_option.print)";
+print " targetm.target_option.print (file, indent, ptr);";
+
+print "}";
+print "#endif";
+
}
diff --git a/gcc/opth-gen.awk b/gcc/opth-gen.awk
index 9aa18a12ad9..a67e5b77a8b 100644
--- a/gcc/opth-gen.awk
+++ b/gcc/opth-gen.awk
@@ -26,6 +26,7 @@
BEGIN {
n_opts = 0
n_langs = 0
+ n_target_save = 0
n_extra_masks = 0
quote = "\042"
comma = ","
@@ -38,6 +39,11 @@ BEGIN {
langs[n_langs] = $2
n_langs++;
}
+ else if ($1 == "TargetSave") {
+ # Make sure the declarations are put in source order
+ target_save_decl[n_target_save] = $2
+ n_target_save++
+ }
else {
name = opt_args("Mask", $1)
if (name == "") {
@@ -64,15 +70,180 @@ print "extern int target_flags;"
print "extern int target_flags_explicit;"
print ""
+have_save = 0;
+
for (i = 0; i < n_opts; i++) {
+ if (flag_set_p("Save", flags[i]))
+ have_save = 1;
+
name = var_name(flags[i]);
if (name == "")
continue;
+ if (name in var_seen)
+ continue;
+
+ var_seen[name] = 1;
print "extern " var_type(flags[i]) name ";"
}
print ""
+# All of the optimization switches gathered together so they can be saved and restored.
+# This will allow attribute((cold)) to turn on space optimization.
+
+# Change the type of normal switches from int to unsigned char to save space.
+# Also, order the structure so that pointer fields occur first, then int
+# fields, and then char fields to provide the best packing.
+
+print "#if !defined(GCC_DRIVER) && !defined(IN_LIBGCC2) && !defined(IN_TARGET_LIBS)"
+print ""
+print "/* Structure to save/restore optimization and target specific options. */";
+print "struct cl_optimization GTY(())";
+print "{";
+
+n_opt_char = 2;
+n_opt_short = 0;
+n_opt_int = 0;
+n_opt_other = 0;
+var_opt_char[0] = "unsigned char optimize";
+var_opt_char[1] = "unsigned char optimize_size";
+
+for (i = 0; i < n_opts; i++) {
+ if (flag_set_p("Optimization", flags[i])) {
+ name = var_name(flags[i])
+ if(name == "")
+ continue;
+
+ if(name in var_opt_seen)
+ continue;
+
+ var_opt_seen[name]++;
+ otype = var_type_struct(flags[i]);
+ if (otype ~ "^((un)?signed +)?int *$")
+ var_opt_int[n_opt_int++] = otype name;
+
+ else if (otype ~ "^((un)?signed +)?short *$")
+ var_opt_short[n_opt_short++] = otype name;
+
+ else if (otype ~ "^((un)?signed +)?char *$")
+ var_opt_char[n_opt_char++] = otype name;
+
+ else
+ var_opt_other[n_opt_other++] = otype name;
+ }
+}
+
+for (i = 0; i < n_opt_other; i++) {
+ print " " var_opt_other[i] ";";
+}
+
+for (i = 0; i < n_opt_int; i++) {
+ print " " var_opt_int[i] ";";
+}
+
+for (i = 0; i < n_opt_short; i++) {
+ print " " var_opt_short[i] ";";
+}
+
+for (i = 0; i < n_opt_char; i++) {
+ print " " var_opt_char[i] ";";
+}
+
+print "};";
+print "";
+
+# Target and optimization save/restore/print functions.
+print "/* Structure to save/restore selected target specific options. */";
+print "struct cl_target_option GTY(())";
+print "{";
+
+n_target_char = 0;
+n_target_short = 0;
+n_target_int = 0;
+n_target_other = 0;
+
+for (i = 0; i < n_target_save; i++) {
+ if (target_save_decl[i] ~ "^((un)?signed +)?int +[_a-zA-Z0-9]+$")
+ var_target_int[n_target_int++] = target_save_decl[i];
+
+ else if (target_save_decl[i] ~ "^((un)?signed +)?short +[_a-zA-Z0-9]+$")
+ var_target_short[n_target_short++] = target_save_decl[i];
+
+ else if (target_save_decl[i] ~ "^((un)?signed +)?char +[_a-zA-Z0-9]+$")
+ var_target_char[n_target_char++] = target_save_decl[i];
+
+ else
+ var_target_other[n_target_other++] = target_save_decl[i];
+}
+
+if (have_save) {
+ for (i = 0; i < n_opts; i++) {
+ if (flag_set_p("Save", flags[i])) {
+ name = var_name(flags[i])
+ if(name == "")
+ name = "target_flags";
+
+ if(name in var_save_seen)
+ continue;
+
+ var_save_seen[name]++;
+ otype = var_type_struct(flags[i])
+ if (otype ~ "^((un)?signed +)?int *$")
+ var_target_int[n_target_int++] = otype name;
+
+ else if (otype ~ "^((un)?signed +)?short *$")
+ var_target_short[n_target_short++] = otype name;
+
+ else if (otype ~ "^((un)?signed +)?char *$")
+ var_target_char[n_target_char++] = otype name;
+
+ else
+ var_target_other[n_target_other++] = otype name;
+ }
+ }
+} else {
+ var_target_int[n_target_int++] = "int target_flags";
+}
+
+for (i = 0; i < n_target_other; i++) {
+ print " " var_target_other[i] ";";
+}
+
+for (i = 0; i < n_target_int; i++) {
+ print " " var_target_int[i] ";";
+}
+
+for (i = 0; i < n_target_short; i++) {
+ print " " var_target_short[i] ";";
+}
+
+for (i = 0; i < n_target_char; i++) {
+ print " " var_target_char[i] ";";
+}
+
+print "};";
+print "";
+print "";
+print "/* Save optimization variables into a structure. */"
+print "extern void cl_optimization_save (struct cl_optimization *);";
+print "";
+print "/* Restore optimization variables from a structure. */";
+print "extern void cl_optimization_restore (struct cl_optimization *);";
+print "";
+print "/* Print optimization variables from a structure. */";
+print "extern void cl_optimization_print (FILE *, int, struct cl_optimization *);";
+print "";
+print "/* Save selected option variables into a structure. */"
+print "extern void cl_target_option_save (struct cl_target_option *);";
+print "";
+print "/* Restore selected option variables from a structure. */"
+print "extern void cl_target_option_restore (struct cl_target_option *);";
+print "";
+print "/* Print target option variables from a structure. */";
+print "extern void cl_target_option_print (FILE *, int, struct cl_target_option *);";
+print "#endif";
+print "";
+
for (i = 0; i < n_opts; i++) {
name = opt_args("Mask", flags[i])
vname = var_name(flags[i])
diff --git a/gcc/opts.c b/gcc/opts.c
index a0dfcbded88..5800eb6a0a2 100644
--- a/gcc/opts.c
+++ b/gcc/opts.c
@@ -333,11 +333,6 @@ bool use_gnu_debug_info_extensions;
/* The default visibility for all symbols (unless overridden) */
enum symbol_visibility default_visibility = VISIBILITY_DEFAULT;
-/* Disable unit-at-a-time for frontends that might be still broken in this
- respect. */
-
-bool no_unit_at_a_time_default;
-
/* Global visibility options. */
struct visibility_flags visibility_options;
@@ -371,6 +366,12 @@ DEF_VEC_ALLOC_P(const_char_p,heap);
static VEC(const_char_p,heap) *ignored_options;
+/* Function calls disallowed under -Wdisallowed-function-list=... */
+static VEC(char_p,heap) *warning_disallowed_functions;
+
+/* If -Wdisallowed-function-list=... */
+bool warn_disallowed_functions = false;
+
/* Input file names. */
const char **in_fnames;
unsigned num_in_fnames;
@@ -451,14 +452,17 @@ complain_wrong_lang (const char *text, const struct cl_option *option,
/* Buffer the unknown option described by the string OPT. Currently,
we only complain about unknown -Wno-* options if they may have
- prevented a diagnostic. Otherwise, we just ignore them. */
+ prevented a diagnostic. Otherwise, we just ignore them.
+ Note that if we do complain, it is only as a warning, not an error;
+ passing the compiler an unrecognised -Wno-* option should never
+ change whether the compilation succeeds or fails. */
-static void postpone_unknown_option_error(const char *opt)
+static void postpone_unknown_option_warning(const char *opt)
{
VEC_safe_push (const_char_p, heap, ignored_options, opt);
}
-/* Produce an error for each option previously buffered. */
+/* Produce a warning for each option previously buffered. */
void print_ignored_options (void)
{
@@ -470,7 +474,7 @@ void print_ignored_options (void)
{
const char *opt;
opt = VEC_pop (const_char_p, ignored_options);
- error ("unrecognized command line option \"%s\"", opt);
+ warning (0, "unrecognized command line option \"%s\"", opt);
}
input_location = saved_loc;
@@ -507,9 +511,9 @@ handle_option (const char **argv, unsigned int lang_mask)
opt_index = find_opt (opt + 1, lang_mask | CL_COMMON | CL_TARGET);
if (opt_index == cl_options_count && opt[1] == 'W')
{
- /* We don't generate errors for unknown -Wno-* options
+ /* We don't generate warnings for unknown -Wno-* options
unless we issue diagnostics. */
- postpone_unknown_option_error (argv[0]);
+ postpone_unknown_option_warning (argv[0]);
result = 1;
goto done;
}
@@ -655,12 +659,10 @@ add_input_filename (const char *filename)
in_fnames[num_in_fnames - 1] = filename;
}
-/* Add functions or file names to a vector of names to exclude from
- instrumentation. */
+/* Add comma-separated strings to a char_p vector. */
static void
-add_instrument_functions_exclude_list (VEC(char_p,heap) **pvec,
- const char* arg)
+add_comma_separated_to_vector (VEC(char_p,heap) **pvec, const char* arg)
{
char *tmp;
char *r;
@@ -736,6 +738,31 @@ flag_instrument_functions_exclude_p (tree fndecl)
return false;
}
+
+/* Return whether this function call is disallowed. */
+void
+warn_if_disallowed_function_p (const_tree exp)
+{
+ if (TREE_CODE(exp) == CALL_EXPR
+ && VEC_length (char_p, warning_disallowed_functions) > 0)
+ {
+ int i;
+ char *s;
+ const char *fnname =
+ IDENTIFIER_POINTER (DECL_NAME (get_callee_fndecl (exp)));
+ for (i = 0; VEC_iterate (char_p, warning_disallowed_functions, i, s);
+ ++i)
+ {
+ if (strcmp (fnname, s) == 0)
+ {
+ warning (OPT_Wdisallowed_function_list_,
+ "disallowed call to %qs", fnname);
+ break;
+ }
+ }
+ }
+}
+
/* Decode and handle the vector of command line options. LANG_MASK
contains has a single bit set representing the current
language. */
@@ -777,12 +804,36 @@ handle_options (unsigned int argc, const char **argv, unsigned int lang_mask)
void
decode_options (unsigned int argc, const char **argv)
{
- unsigned int i, lang_mask;
+ static bool first_time_p = true;
+ static int initial_max_aliased_vops;
+ static int initial_avg_aliased_vops;
+ static int initial_min_crossjump_insns;
+ static int initial_max_fields_for_field_sensitive;
+ static unsigned int initial_lang_mask;
- /* Perform language-specific options initialization. */
- lang_mask = lang_hooks.init_options (argc, argv);
+ unsigned int i, lang_mask;
+ int opt1;
+ int opt2;
+ int opt3;
+ int opt1_max;
- lang_hooks.initialize_diagnostics (global_dc);
+ if (first_time_p)
+ {
+ /* Perform language-specific options initialization. */
+ initial_lang_mask = lang_mask = lang_hooks.init_options (argc, argv);
+
+ lang_hooks.initialize_diagnostics (global_dc);
+
+ /* Save initial values of parameters we reset. */
+ initial_max_aliased_vops = MAX_ALIASED_VOPS;
+ initial_avg_aliased_vops = AVG_ALIASED_VOPS;
+ initial_min_crossjump_insns
+ = compiler_params[PARAM_MIN_CROSSJUMP_INSNS].value;
+ initial_max_fields_for_field_sensitive
+ = compiler_params[PARAM_MAX_FIELDS_FOR_FIELD_SENSITIVE].value;
+ }
+ else
+ lang_mask = initial_lang_mask;
/* Scan to see what optimization level has been specified. That will
determine the default value of many flags. */
@@ -816,148 +867,197 @@ decode_options (unsigned int argc, const char **argv)
}
}
}
+
+ if (!flag_unit_at_a_time)
+ {
+ flag_section_anchors = 0;
+ flag_toplevel_reorder = 0;
+ }
+ if (!flag_toplevel_reorder)
+ {
+ if (flag_section_anchors == 1)
+ error ("Section anchors must be disabled when toplevel reorder is disabled.");
+ flag_section_anchors = 0;
+ }
+ /* Originally we just set the variables if a particular optimization level,
+ but with the advent of being able to change the optimization level for a
+ function, we need to reset optimizations. */
if (!optimize)
{
flag_merge_constants = 0;
- }
- if (!no_unit_at_a_time_default)
- {
- flag_unit_at_a_time = 1;
- if (!optimize)
+ /* We disable toplevel reordering at -O0 to disable transformations that
+ might be surprising to end users and to get -fno-toplevel-reorder
+ tested, but we keep section anchors. */
+ if (flag_toplevel_reorder == 2)
flag_toplevel_reorder = 0;
}
+ else
+ flag_merge_constants = 1;
- if (optimize >= 1)
- {
- flag_defer_pop = 1;
+ /* -O1 optimizations. */
+ opt1 = (optimize >= 1);
+ flag_defer_pop = opt1;
#ifdef DELAY_SLOTS
- flag_delayed_branch = 1;
+ flag_delayed_branch = opt1;
#endif
#ifdef CAN_DEBUG_WITHOUT_FP
- flag_omit_frame_pointer = 1;
+ flag_omit_frame_pointer = opt1;
#endif
- flag_guess_branch_prob = 1;
- flag_cprop_registers = 1;
- flag_if_conversion = 1;
- flag_if_conversion2 = 1;
- flag_ipa_pure_const = 1;
- flag_ipa_reference = 1;
- flag_split_wide_types = 1;
- flag_tree_ccp = 1;
- flag_tree_dce = 1;
- flag_tree_dom = 1;
- flag_tree_dse = 1;
- flag_tree_ter = 1;
- flag_tree_sra = 1;
- flag_tree_copyrename = 1;
- flag_tree_fre = 1;
- flag_tree_copy_prop = 1;
- flag_tree_sink = 1;
-
- if (!optimize_size)
- {
- /* Loop header copying usually increases size of the code. This used
- not to be true, since quite often it is possible to verify that
- the condition is satisfied in the first iteration and therefore
- to eliminate it. Jump threading handles these cases now. */
- flag_tree_ch = 1;
- }
- }
-
- if (optimize >= 2)
- {
- flag_inline_small_functions = 1;
- flag_thread_jumps = 1;
- flag_crossjumping = 1;
- flag_optimize_sibling_calls = 1;
- flag_forward_propagate = 1;
- flag_cse_follow_jumps = 1;
- flag_gcse = 1;
- flag_expensive_optimizations = 1;
- flag_rerun_cse_after_loop = 1;
- flag_caller_saves = 1;
- flag_peephole2 = 1;
+ flag_guess_branch_prob = opt1;
+ flag_cprop_registers = opt1;
+ flag_if_conversion = opt1;
+ flag_if_conversion2 = opt1;
+ flag_ipa_pure_const = opt1;
+ flag_ipa_reference = opt1;
+ flag_split_wide_types = opt1;
+ flag_tree_ccp = opt1;
+ flag_tree_dce = opt1;
+ flag_tree_dom = opt1;
+ flag_tree_dse = opt1;
+ flag_tree_ter = opt1;
+ flag_tree_sra = opt1;
+ flag_tree_copyrename = opt1;
+ flag_tree_fre = opt1;
+ flag_tree_copy_prop = opt1;
+ flag_tree_sink = opt1;
+ flag_tree_ch = opt1;
+
+ /* -O2 optimizations. */
+ opt2 = (optimize >= 2);
+ flag_inline_small_functions = opt2;
+ flag_indirect_inlining = opt2;
+ flag_thread_jumps = opt2;
+ flag_crossjumping = opt2;
+ flag_optimize_sibling_calls = opt2;
+ flag_forward_propagate = opt2;
+ flag_cse_follow_jumps = opt2;
+ flag_gcse = opt2;
+ flag_expensive_optimizations = opt2;
+ flag_rerun_cse_after_loop = opt2;
+ flag_caller_saves = opt2;
+ flag_peephole2 = opt2;
#ifdef INSN_SCHEDULING
- flag_schedule_insns = 1;
- flag_schedule_insns_after_reload = 1;
+ flag_schedule_insns = opt2;
+ flag_schedule_insns_after_reload = opt2;
#endif
- flag_regmove = 1;
- flag_strict_aliasing = 1;
- flag_strict_overflow = 1;
- flag_delete_null_pointer_checks = 1;
- flag_reorder_blocks = 1;
- flag_reorder_functions = 1;
- flag_tree_store_ccp = 1;
- flag_tree_vrp = 1;
+ flag_regmove = opt2;
+ flag_strict_aliasing = opt2;
+ flag_strict_overflow = opt2;
+ flag_delete_null_pointer_checks = opt2;
+ flag_reorder_blocks = opt2;
+ flag_reorder_functions = opt2;
+ flag_tree_store_ccp = opt2;
+ flag_tree_vrp = opt2;
+ flag_tree_builtin_call_dce = opt2;
+ flag_tree_pre = opt2;
flag_tree_switch_conversion = 1;
- if (!optimize_size)
- {
- /* Conditional DCE generates bigger code. */
- flag_tree_builtin_call_dce = 1;
- /* PRE tends to generate bigger code. */
- flag_tree_pre = 1;
- }
-
/* Allow more virtual operators to increase alias precision. */
- set_param_value ("max-aliased-vops", 500);
- }
- if (optimize >= 3)
- {
- flag_predictive_commoning = 1;
- flag_inline_functions = 1;
- flag_unswitch_loops = 1;
- flag_gcse_after_reload = 1;
- flag_tree_vectorize = 1;
+ set_param_value ("max-aliased-vops",
+ (opt2) ? 500 : initial_max_aliased_vops);
- /* Allow even more virtual operators. */
- set_param_value ("max-aliased-vops", 1000);
- set_param_value ("avg-aliased-vops", 3);
- }
+ /* Track fields in field-sensitive alias analysis. */
+ set_param_value ("max-fields-for-field-sensitive",
+ (opt2) ? 100 : initial_max_fields_for_field_sensitive);
+
+ /* -O3 optimizations. */
+ opt3 = (optimize >= 3);
+ flag_predictive_commoning = opt3;
+ flag_inline_functions = opt3;
+ flag_unswitch_loops = opt3;
+ flag_gcse_after_reload = opt3;
+ flag_tree_vectorize = opt3;
+
+ /* Allow even more virtual operators. Max-aliased-vops was set above for
+ -O2, so don't reset it unless we are at -O3. */
+ if (opt3)
+ set_param_value ("max-aliased-vops", 1000);
+
+ set_param_value ("avg-aliased-vops", (opt3) ? 3 : initial_avg_aliased_vops);
+
+ /* Just -O1/-O0 optimizations. */
+ opt1_max = (optimize <= 1);
+ align_loops = opt1_max;
+ align_jumps = opt1_max;
+ align_labels = opt1_max;
+ align_functions = opt1_max;
- if (optimize < 2 || optimize_size)
+ if (optimize_size)
{
+ /* Loop header copying usually increases size of the code. This used not to
+ be true, since quite often it is possible to verify that the condition is
+ satisfied in the first iteration and therefore to eliminate it. Jump
+ threading handles these cases now. */
+ flag_tree_ch = 0;
+
+ /* Conditional DCE generates bigger code. */
+ flag_tree_builtin_call_dce = 0;
+
+ /* PRE tends to generate bigger code. */
+ flag_tree_pre = 0;
+
+ /* These options are set with -O3, so reset for -Os */
+ flag_predictive_commoning = 0;
+ flag_inline_functions = 0;
+ flag_unswitch_loops = 0;
+ flag_gcse_after_reload = 0;
+ flag_tree_vectorize = 0;
+
+ /* Don't reorder blocks when optimizing for size because extra jump insns may
+ be created; also barrier may create extra padding.
+
+ More correctly we should have a block reordering mode that tried to
+ minimize the combined size of all the jumps. This would more or less
+ automatically remove extra jumps, but would also try to use more short
+ jumps instead of long jumps. */
+ flag_reorder_blocks = 0;
+ flag_reorder_blocks_and_partition = 0;
+
+ /* Inlining of functions reducing size is a good idea regardless of them
+ being declared inline. */
+ flag_inline_functions = 1;
+
+ /* Don't align code. */
align_loops = 1;
align_jumps = 1;
align_labels = 1;
align_functions = 1;
- /* Don't reorder blocks when optimizing for size because extra
- jump insns may be created; also barrier may create extra padding.
-
- More correctly we should have a block reordering mode that tried
- to minimize the combined size of all the jumps. This would more
- or less automatically remove extra jumps, but would also try to
- use more short jumps instead of long jumps. */
- flag_reorder_blocks = 0;
- flag_reorder_blocks_and_partition = 0;
- }
+ /* Unroll/prefetch switches that may be set on the command line, and tend to
+ generate bigger code. */
+ flag_unroll_loops = 0;
+ flag_unroll_all_loops = 0;
+ flag_prefetch_loop_arrays = 0;
- if (optimize_size)
- {
- /* Inlining of functions reducing size is a good idea regardless
- of them being declared inline. */
- flag_inline_functions = 1;
+ /* Basic optimization options. */
+ optimize_size = 1;
+ if (optimize > 2)
+ optimize = 2;
/* We want to crossjump as much as possible. */
set_param_value ("min-crossjump-insns", 1);
}
+ else
+ set_param_value ("min-crossjump-insns", initial_min_crossjump_insns);
- /* Initialize whether `char' is signed. */
- flag_signed_char = DEFAULT_SIGNED_CHAR;
- /* Set this to a special "uninitialized" value. The actual default is set
- after target options have been processed. */
- flag_short_enums = 2;
-
- /* Initialize target_flags before OPTIMIZATION_OPTIONS so the latter can
- modify it. */
- target_flags = targetm.default_target_flags;
-
- /* Some targets have ABI-specified unwind tables. */
- flag_unwind_tables = targetm.unwind_tables_default;
+ if (first_time_p)
+ {
+ /* Initialize whether `char' is signed. */
+ flag_signed_char = DEFAULT_SIGNED_CHAR;
+ /* Set this to a special "uninitialized" value. The actual default is
+ set after target options have been processed. */
+ flag_short_enums = 2;
+
+ /* Initialize target_flags before OPTIMIZATION_OPTIONS so the latter can
+ modify it. */
+ target_flags = targetm.default_target_flags;
+
+ /* Some targets have ABI-specified unwind tables. */
+ flag_unwind_tables = targetm.unwind_tables_default;
+ }
#ifdef OPTIMIZATION_OPTIONS
/* Allow default optimizations to be specified on a per-machine basis. */
@@ -966,15 +1066,18 @@ decode_options (unsigned int argc, const char **argv)
handle_options (argc, argv, lang_mask);
- if (flag_pie)
- flag_pic = flag_pie;
- if (flag_pic && !flag_pie)
- flag_shlib = 1;
+ if (first_time_p)
+ {
+ if (flag_pie)
+ flag_pic = flag_pie;
+ if (flag_pic && !flag_pie)
+ flag_shlib = 1;
- if (flag_no_inline == 2)
- flag_no_inline = 0;
- else
- flag_really_no_inline = flag_no_inline;
+ if (flag_no_inline == 2)
+ flag_no_inline = 0;
+ else
+ flag_really_no_inline = flag_no_inline;
+ }
/* Set flag_no_inline before the post_options () hook. The C front
ends use it to determine tree inlining defaults. FIXME: such
@@ -999,16 +1102,6 @@ decode_options (unsigned int argc, const char **argv)
if (flag_really_no_inline == 2)
flag_really_no_inline = flag_no_inline;
- /* Inlining of functions called just once will only work if we can look
- at the complete translation unit. */
- if (flag_inline_functions_called_once && !flag_unit_at_a_time)
- {
- flag_inline_functions_called_once = 0;
- warning (OPT_Wdisabled_optimization,
- "-funit-at-a-time is required for inlining of functions "
- "that are only called once");
- }
-
/* The optimization to partition hot and cold basic blocks into separate
sections of the .o and executable files does not work (currently)
with exception handling. This is because there is no support for
@@ -1055,6 +1148,14 @@ decode_options (unsigned int argc, const char **argv)
flag_ira = 0;
}
#endif
+
+ /* Save the current optimization options if this is the first call. */
+ if (first_time_p)
+ {
+ optimization_default_node = build_optimization_node ();
+ optimization_current_node = optimization_default_node;
+ first_time_p = false;
+ }
}
#define LEFT_COLUMN 27
@@ -1546,6 +1647,12 @@ common_handle_option (size_t scode, const char *arg, int value,
set_Wextra (value);
break;
+ case OPT_Wdisallowed_function_list_:
+ warn_disallowed_functions = true;
+ add_comma_separated_to_vector
+ (&warning_disallowed_functions, arg);
+ break;
+
case OPT_Werror_:
enable_warning_as_error (arg, value, lang_mask);
break;
@@ -1696,12 +1803,12 @@ common_handle_option (size_t scode, const char *arg, int value,
break;
case OPT_finstrument_functions_exclude_function_list_:
- add_instrument_functions_exclude_list
+ add_comma_separated_to_vector
(&flag_instrument_functions_exclude_functions, arg);
break;
case OPT_finstrument_functions_exclude_file_list_:
- add_instrument_functions_exclude_list
+ add_comma_separated_to_vector
(&flag_instrument_functions_exclude_files, arg);
break;
@@ -2056,6 +2163,18 @@ fast_math_flags_set_p (void)
&& !flag_errno_math);
}
+/* Return true iff flags are set as if -ffast-math but using the flags stored
+ in the struct cl_optimization structure. */
+bool
+fast_math_flags_struct_set_p (struct cl_optimization *opt)
+{
+ return (!opt->flag_trapping_math
+ && opt->flag_unsafe_math_optimizations
+ && opt->flag_finite_math_only
+ && !opt->flag_signed_zeros
+ && !opt->flag_errno_math);
+}
+
/* Handle a debug output -g switch. EXTENDED is true or false to support
extended output (2 is special and means "-ggdb" was given). */
static void
diff --git a/gcc/opts.h b/gcc/opts.h
index 2f543407de0..62ad89aa5a5 100644
--- a/gcc/opts.h
+++ b/gcc/opts.h
@@ -64,7 +64,6 @@ extern const struct cl_option cl_options[];
extern const unsigned int cl_options_count;
extern const char *const lang_names[];
extern const unsigned int cl_lang_count;
-extern bool no_unit_at_a_time_default;
#define CL_PARAMS (1 << 18) /* Fake entry. Used to display --param info with --help. */
#define CL_WARNING (1 << 19) /* Enables an (optional) warning message. */
diff --git a/gcc/passes.c b/gcc/passes.c
index 751bf537f2b..a77b82d540f 100644
--- a/gcc/passes.c
+++ b/gcc/passes.c
@@ -180,7 +180,7 @@ rest_of_decl_compilation (tree decl,
/* Don't output anything when a tentative file-scope definition
is seen. But at end of compilation, do output code for them.
- We do output all variables when unit-at-a-time is active and rely on
+ We do output all variables and rely on
callgraph code to defer them except for forward declarations
(see gcc.c-torture/compile/920624-1.c) */
if ((at_end
@@ -523,9 +523,7 @@ init_optimization_passes (void)
NEXT_PASS (pass_inline_parameters);
*p = NULL;
- /* Interprocedural optimization passes.
- All these passes are ignored in -fno-unit-at-a-time
- except for subpasses of early_local_passes. */
+ /* Interprocedural optimization passes. */
p = &all_ipa_passes;
NEXT_PASS (pass_ipa_function_and_variable_visibility);
NEXT_PASS (pass_ipa_early_inline);
@@ -542,12 +540,13 @@ init_optimization_passes (void)
NEXT_PASS (pass_cleanup_cfg);
NEXT_PASS (pass_init_datastructures);
NEXT_PASS (pass_expand_omp);
+
+ NEXT_PASS (pass_referenced_vars);
+ NEXT_PASS (pass_reset_cc_flags);
+ NEXT_PASS (pass_build_ssa);
NEXT_PASS (pass_all_early_optimizations);
{
struct opt_pass **p = &pass_all_early_optimizations.pass.sub;
- NEXT_PASS (pass_referenced_vars);
- NEXT_PASS (pass_reset_cc_flags);
- NEXT_PASS (pass_build_ssa);
NEXT_PASS (pass_early_warn_uninitialized);
NEXT_PASS (pass_rebuild_cgraph_edges);
NEXT_PASS (pass_early_inline);
@@ -574,8 +573,8 @@ init_optimization_passes (void)
NEXT_PASS (pass_tail_recursion);
NEXT_PASS (pass_convert_switch);
NEXT_PASS (pass_profile);
- NEXT_PASS (pass_release_ssa_names);
}
+ NEXT_PASS (pass_release_ssa_names);
NEXT_PASS (pass_rebuild_cgraph_edges);
}
NEXT_PASS (pass_ipa_increase_alignment);
@@ -592,7 +591,6 @@ init_optimization_passes (void)
/* These passes are run after IPA passes on every function that is being
output to the assembler file. */
p = &all_passes;
- NEXT_PASS (pass_O0_always_inline);
NEXT_PASS (pass_all_optimizations);
{
struct opt_pass **p = &pass_all_optimizations.pass.sub;
@@ -601,7 +599,6 @@ init_optimization_passes (void)
NEXT_PASS (pass_build_alias);
NEXT_PASS (pass_return_slot);
NEXT_PASS (pass_rename_ssa_copies);
-
/* Initial scalar cleanups. */
NEXT_PASS (pass_complete_unrolli);
NEXT_PASS (pass_ccp);
@@ -630,14 +627,12 @@ init_optimization_passes (void)
NEXT_PASS (pass_sra);
NEXT_PASS (pass_rename_ssa_copies);
NEXT_PASS (pass_dominator);
-
/* The only const/copy propagation opportunities left after
DOM should be due to degenerate PHI nodes. So rather than
run the full propagators, run a specialized pass which
only examines PHIs to discover const/copy propagation
opportunities. */
NEXT_PASS (pass_phi_only_cprop);
-
NEXT_PASS (pass_reassoc);
NEXT_PASS (pass_dce);
NEXT_PASS (pass_dse);
@@ -685,14 +680,12 @@ init_optimization_passes (void)
NEXT_PASS (pass_reassoc);
NEXT_PASS (pass_vrp);
NEXT_PASS (pass_dominator);
-
/* The only const/copy propagation opportunities left after
DOM should be due to degenerate PHI nodes. So rather than
run the full propagators, run a specialized pass which
only examines PHIs to discover const/copy propagation
opportunities. */
NEXT_PASS (pass_phi_only_cprop);
-
NEXT_PASS (pass_cd_dce);
NEXT_PASS (pass_tracer);
@@ -712,14 +705,16 @@ init_optimization_passes (void)
NEXT_PASS (pass_tail_calls);
NEXT_PASS (pass_rename_ssa_copies);
NEXT_PASS (pass_uncprop);
- NEXT_PASS (pass_del_ssa);
- NEXT_PASS (pass_nrv);
- NEXT_PASS (pass_mark_used_blocks);
- NEXT_PASS (pass_cleanup_cfg_post_optimizing);
}
+ NEXT_PASS (pass_del_ssa);
+ NEXT_PASS (pass_nrv);
+ NEXT_PASS (pass_mark_used_blocks);
+ NEXT_PASS (pass_cleanup_cfg_post_optimizing);
+
NEXT_PASS (pass_warn_function_noreturn);
NEXT_PASS (pass_free_datastructures);
NEXT_PASS (pass_mudflap_2);
+
NEXT_PASS (pass_free_cfg_annotations);
NEXT_PASS (pass_expand);
NEXT_PASS (pass_rest_of_compilation);
@@ -960,12 +955,10 @@ execute_function_todo (void *data)
if (flags & TODO_remove_unused_locals)
remove_unused_locals ();
- if ((flags & TODO_dump_func)
- && dump_file && current_function_decl)
+ if ((flags & TODO_dump_func) && dump_file && current_function_decl)
{
if (cfun->curr_properties & PROP_trees)
- dump_function_to_file (current_function_decl,
- dump_file, dump_flags);
+ dump_function_to_file (current_function_decl, dump_file, dump_flags);
else
{
if (dump_flags & TDF_SLIM)
@@ -976,7 +969,7 @@ execute_function_todo (void *data)
else
print_rtl (dump_file, get_insns ());
- if (cfun->curr_properties & PROP_cfg
+ if ((cfun->curr_properties & PROP_cfg)
&& graph_dump_format != no_graph
&& (dump_flags & TDF_GRAPH))
print_rtl_graph_with_bb (dump_file_name, get_insns ());
@@ -1045,8 +1038,7 @@ execute_todo (unsigned int flags)
cgraph_remove_unreachable_nodes (true, dump_file);
}
- if ((flags & TODO_dump_cgraph)
- && dump_file && !current_function_decl)
+ if ((flags & TODO_dump_cgraph) && dump_file && !current_function_decl)
{
gcc_assert (!cfun);
dump_cgraph (dump_file);
@@ -1056,9 +1048,7 @@ execute_todo (unsigned int flags)
}
if (flags & TODO_ggc_collect)
- {
- ggc_collect ();
- }
+ ggc_collect ();
/* Now that the dumping has been done, we can get rid of the optional
df problems. */
@@ -1227,8 +1217,6 @@ execute_one_ipa_transform_pass (struct cgraph_node *node,
pass_fini_dump_file (pass);
current_pass = NULL;
- /* Reset in_gimple_form to not break non-unit-at-a-time mode. */
- in_gimple_form = false;
}
static bool
@@ -1260,6 +1248,7 @@ execute_one_pass (struct opt_pass *pass)
}
current_pass = pass;
+
/* See if we're supposed to run this pass. */
if (pass->gate && !pass->gate ())
return false;
@@ -1328,8 +1317,6 @@ execute_one_pass (struct opt_pass *pass)
|| pass->type != RTL_PASS);
current_pass = NULL;
- /* Reset in_gimple_form to not break non-unit-at-a-time mode. */
- in_gimple_form = false;
return true;
}
diff --git a/gcc/postreload.c b/gcc/postreload.c
index 8966c20b887..7659bab435a 100644
--- a/gcc/postreload.c
+++ b/gcc/postreload.c
@@ -518,7 +518,7 @@ reload_cse_simplify_operands (rtx insn, rtx testreg)
for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
{
- int class = (int) NO_REGS;
+ int rclass = (int) NO_REGS;
if (! TEST_HARD_REG_BIT (equiv_regs[i], regno))
continue;
@@ -552,13 +552,13 @@ reload_cse_simplify_operands (rtx insn, rtx testreg)
break;
case 'g': case 'r':
- class = reg_class_subunion[(int) class][(int) GENERAL_REGS];
+ rclass = reg_class_subunion[(int) rclass][(int) GENERAL_REGS];
break;
default:
- class
+ rclass
= (reg_class_subunion
- [(int) class]
+ [(int) rclass]
[(int) REG_CLASS_FROM_CONSTRAINT ((unsigned char) c, p)]);
break;
@@ -568,7 +568,7 @@ reload_cse_simplify_operands (rtx insn, rtx testreg)
alternative yet and the operand being replaced is not
a cheap CONST_INT. */
if (op_alt_regno[i][j] == -1
- && reg_fits_class_p (testreg, class, 0, mode)
+ && reg_fits_class_p (testreg, rclass, 0, mode)
&& (GET_CODE (recog_data.operand[i]) != CONST_INT
|| (rtx_cost (recog_data.operand[i], SET)
> rtx_cost (testreg, SET))))
@@ -577,7 +577,7 @@ reload_cse_simplify_operands (rtx insn, rtx testreg)
op_alt_regno[i][j] = regno;
}
j++;
- class = (int) NO_REGS;
+ rclass = (int) NO_REGS;
break;
}
p += CONSTRAINT_LEN (c, p);
diff --git a/gcc/predict.c b/gcc/predict.c
index f85786e1a1d..6a887be8e56 100644
--- a/gcc/predict.c
+++ b/gcc/predict.c
@@ -203,7 +203,7 @@ static struct pointer_map_t *bb_predictions;
PREDICTOR. */
bool
-tree_predicted_by_p (const_basic_block bb, enum br_predictor predictor)
+gimple_predicted_by_p (const_basic_block bb, enum br_predictor predictor)
{
struct edge_prediction *i;
void **preds = pointer_map_contains (bb_predictions, bb);
@@ -305,7 +305,7 @@ rtl_predict_edge (edge e, enum br_predictor predictor, int probability)
/* Predict edge E with the given PROBABILITY. */
void
-tree_predict_edge (edge e, enum br_predictor predictor, int probability)
+gimple_predict_edge (edge e, enum br_predictor predictor, int probability)
{
gcc_assert (profile_status != PROFILE_GUESSED);
if ((e->src != ENTRY_BLOCK_PTR && EDGE_COUNT (e->src->succs) > 1)
@@ -947,36 +947,38 @@ guess_outgoing_edge_probabilities (basic_block bb)
combine_predictions_for_insn (BB_END (bb), bb);
}
-/* Return constant EXPR will likely have at execution time, NULL if unknown.
- The function is used by builtin_expect branch predictor so the evidence
- must come from this construct and additional possible constant folding.
-
- We may want to implement more involved value guess (such as value range
- propagation based prediction), but such tricks shall go to new
- implementation. */
+static tree expr_expected_value (tree, bitmap);
+
+/* Helper function for expr_expected_value. */
static tree
-expr_expected_value (tree expr, bitmap visited)
+expr_expected_value_1 (tree type, tree op0, enum tree_code code, tree op1, bitmap visited)
{
- if (TREE_CONSTANT (expr))
- return expr;
- else if (TREE_CODE (expr) == SSA_NAME)
+ gimple def;
+
+ if (get_gimple_rhs_class (code) == GIMPLE_SINGLE_RHS)
{
- tree def = SSA_NAME_DEF_STMT (expr);
+ if (TREE_CONSTANT (op0))
+ return op0;
+
+ if (code != SSA_NAME)
+ return NULL_TREE;
+
+ def = SSA_NAME_DEF_STMT (op0);
/* If we were already here, break the infinite cycle. */
- if (bitmap_bit_p (visited, SSA_NAME_VERSION (expr)))
+ if (bitmap_bit_p (visited, SSA_NAME_VERSION (op0)))
return NULL;
- bitmap_set_bit (visited, SSA_NAME_VERSION (expr));
+ bitmap_set_bit (visited, SSA_NAME_VERSION (op0));
- if (TREE_CODE (def) == PHI_NODE)
+ if (gimple_code (def) == GIMPLE_PHI)
{
/* All the arguments of the PHI node must have the same constant
length. */
- int i;
+ int i, n = gimple_phi_num_args (def);
tree val = NULL, new_val;
- for (i = 0; i < PHI_NUM_ARGS (def); i++)
+ for (i = 0; i < n; i++)
{
tree arg = PHI_ARG_DEF (def, i);
@@ -999,81 +1001,121 @@ expr_expected_value (tree expr, bitmap visited)
}
return val;
}
- if (TREE_CODE (def) != GIMPLE_MODIFY_STMT
- || GIMPLE_STMT_OPERAND (def, 0) != expr)
- return NULL;
- return expr_expected_value (GIMPLE_STMT_OPERAND (def, 1), visited);
- }
- else if (TREE_CODE (expr) == CALL_EXPR)
- {
- tree decl = get_callee_fndecl (expr);
- if (!decl)
- return NULL;
- if (DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL
- && DECL_FUNCTION_CODE (decl) == BUILT_IN_EXPECT)
+ if (is_gimple_assign (def))
{
- tree val;
+ if (gimple_assign_lhs (def) != op0)
+ return NULL;
- if (call_expr_nargs (expr) != 2)
+ return expr_expected_value_1 (TREE_TYPE (gimple_assign_lhs (def)),
+ gimple_assign_rhs1 (def),
+ gimple_assign_rhs_code (def),
+ gimple_assign_rhs2 (def),
+ visited);
+ }
+
+ if (is_gimple_call (def))
+ {
+ tree decl = gimple_call_fndecl (def);
+ if (!decl)
return NULL;
- val = CALL_EXPR_ARG (expr, 0);
- if (TREE_CONSTANT (val))
- return val;
- return CALL_EXPR_ARG (expr, 1);
+ if (DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL
+ && DECL_FUNCTION_CODE (decl) == BUILT_IN_EXPECT)
+ {
+ tree val;
+
+ if (gimple_call_num_args (def) != 2)
+ return NULL;
+ val = gimple_call_arg (def, 0);
+ if (TREE_CONSTANT (val))
+ return val;
+ return gimple_call_arg (def, 1);
+ }
}
+
+ return NULL;
}
- if (BINARY_CLASS_P (expr) || COMPARISON_CLASS_P (expr))
+
+ if (get_gimple_rhs_class (code) == GIMPLE_BINARY_RHS)
{
- tree op0, op1, res;
- op0 = expr_expected_value (TREE_OPERAND (expr, 0), visited);
+ tree res;
+ op0 = expr_expected_value (op0, visited);
if (!op0)
return NULL;
- op1 = expr_expected_value (TREE_OPERAND (expr, 1), visited);
+ op1 = expr_expected_value (op1, visited);
if (!op1)
return NULL;
- res = fold_build2 (TREE_CODE (expr), TREE_TYPE (expr), op0, op1);
+ res = fold_build2 (code, type, op0, op1);
if (TREE_CONSTANT (res))
return res;
return NULL;
}
- if (UNARY_CLASS_P (expr))
+ if (get_gimple_rhs_class (code) == GIMPLE_UNARY_RHS)
{
- tree op0, res;
- op0 = expr_expected_value (TREE_OPERAND (expr, 0), visited);
+ tree res;
+ op0 = expr_expected_value (op0, visited);
if (!op0)
return NULL;
- res = fold_build1 (TREE_CODE (expr), TREE_TYPE (expr), op0);
+ res = fold_build1 (code, type, op0);
if (TREE_CONSTANT (res))
return res;
return NULL;
}
return NULL;
}
+
+/* Return constant EXPR will likely have at execution time, NULL if unknown.
+ The function is used by builtin_expect branch predictor so the evidence
+ must come from this construct and additional possible constant folding.
+
+ We may want to implement more involved value guess (such as value range
+ propagation based prediction), but such tricks shall go to new
+ implementation. */
+
+static tree
+expr_expected_value (tree expr, bitmap visited)
+{
+ enum tree_code code;
+ tree op0, op1;
+
+ if (TREE_CONSTANT (expr))
+ return expr;
+
+ extract_ops_from_tree (expr, &code, &op0, &op1);
+ return expr_expected_value_1 (TREE_TYPE (expr),
+ op0, code, op1, visited);
+}
+
/* Get rid of all builtin_expect calls we no longer need. */
static void
strip_builtin_expect (void)
{
basic_block bb;
+ gimple ass_stmt;
+ tree var;
+
FOR_EACH_BB (bb)
{
- block_stmt_iterator bi;
- for (bi = bsi_start (bb); !bsi_end_p (bi); bsi_next (&bi))
+ gimple_stmt_iterator bi;
+ for (bi = gsi_start_bb (bb); !gsi_end_p (bi); gsi_next (&bi))
{
- tree stmt = bsi_stmt (bi);
+ gimple stmt = gsi_stmt (bi);
tree fndecl;
- tree call;
- if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT
- && (call = GIMPLE_STMT_OPERAND (stmt, 1))
- && TREE_CODE (call) == CALL_EXPR
- && (fndecl = get_callee_fndecl (call))
+ if (gimple_code (stmt) != GIMPLE_CALL)
+ continue;
+
+ fndecl = gimple_call_fndecl (stmt);
+
+ if (fndecl
&& DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
&& DECL_FUNCTION_CODE (fndecl) == BUILT_IN_EXPECT
- && call_expr_nargs (call) == 2)
+ && gimple_call_num_args (stmt) == 2)
{
- GIMPLE_STMT_OPERAND (stmt, 1) = CALL_EXPR_ARG (call, 0);
- update_stmt (stmt);
+ var = gimple_call_lhs (stmt);
+ ass_stmt = gimple_build_assign (var, gimple_call_arg (stmt, 0));
+
+ gsi_replace (&bi, ass_stmt, true);
}
}
}
@@ -1083,27 +1125,26 @@ strip_builtin_expect (void)
static void
tree_predict_by_opcode (basic_block bb)
{
- tree stmt = last_stmt (bb);
+ gimple stmt = last_stmt (bb);
edge then_edge;
- tree cond;
- tree op0;
+ tree op0, op1;
tree type;
tree val;
+ enum tree_code cmp;
bitmap visited;
edge_iterator ei;
- if (!stmt || TREE_CODE (stmt) != COND_EXPR)
+ if (!stmt || gimple_code (stmt) != GIMPLE_COND)
return;
FOR_EACH_EDGE (then_edge, ei, bb->succs)
if (then_edge->flags & EDGE_TRUE_VALUE)
break;
- cond = TREE_OPERAND (stmt, 0);
- if (!COMPARISON_CLASS_P (cond))
- return;
- op0 = TREE_OPERAND (cond, 0);
+ op0 = gimple_cond_lhs (stmt);
+ op1 = gimple_cond_rhs (stmt);
+ cmp = gimple_cond_code (stmt);
type = TREE_TYPE (op0);
visited = BITMAP_ALLOC (NULL);
- val = expr_expected_value (cond, visited);
+ val = expr_expected_value_1 (boolean_type_node, op0, cmp, op1, visited);
BITMAP_FREE (visited);
if (val)
{
@@ -1118,9 +1159,9 @@ tree_predict_by_opcode (basic_block bb)
Similarly, a comparison ptr1 == ptr2 is predicted as false. */
if (POINTER_TYPE_P (type))
{
- if (TREE_CODE (cond) == EQ_EXPR)
+ if (cmp == EQ_EXPR)
predict_edge_def (then_edge, PRED_TREE_POINTER, NOT_TAKEN);
- else if (TREE_CODE (cond) == NE_EXPR)
+ else if (cmp == NE_EXPR)
predict_edge_def (then_edge, PRED_TREE_POINTER, TAKEN);
}
else
@@ -1129,7 +1170,7 @@ tree_predict_by_opcode (basic_block bb)
EQ tests are usually false and NE tests are usually true. Also,
most quantities are positive, so we can make the appropriate guesses
about signed comparisons against zero. */
- switch (TREE_CODE (cond))
+ switch (cmp)
{
case EQ_EXPR:
case UNEQ_EXPR:
@@ -1140,8 +1181,7 @@ tree_predict_by_opcode (basic_block bb)
;
/* Comparisons with 0 are often used for booleans and there is
nothing useful to predict about them. */
- else if (integer_zerop (op0)
- || integer_zerop (TREE_OPERAND (cond, 1)))
+ else if (integer_zerop (op0) || integer_zerop (op1))
;
else
predict_edge_def (then_edge, PRED_TREE_OPCODE_NONEQUAL, NOT_TAKEN);
@@ -1157,7 +1197,7 @@ tree_predict_by_opcode (basic_block bb)
/* Comparisons with 0 are often used for booleans and there is
nothing useful to predict about them. */
else if (integer_zerop (op0)
- || integer_zerop (TREE_OPERAND (cond, 1)))
+ || integer_zerop (op1))
;
else
predict_edge_def (then_edge, PRED_TREE_OPCODE_NONEQUAL, TAKEN);
@@ -1173,23 +1213,23 @@ tree_predict_by_opcode (basic_block bb)
case LE_EXPR:
case LT_EXPR:
- if (integer_zerop (TREE_OPERAND (cond, 1))
- || integer_onep (TREE_OPERAND (cond, 1))
- || integer_all_onesp (TREE_OPERAND (cond, 1))
- || real_zerop (TREE_OPERAND (cond, 1))
- || real_onep (TREE_OPERAND (cond, 1))
- || real_minus_onep (TREE_OPERAND (cond, 1)))
+ if (integer_zerop (op1)
+ || integer_onep (op1)
+ || integer_all_onesp (op1)
+ || real_zerop (op1)
+ || real_onep (op1)
+ || real_minus_onep (op1))
predict_edge_def (then_edge, PRED_TREE_OPCODE_POSITIVE, NOT_TAKEN);
break;
case GE_EXPR:
case GT_EXPR:
- if (integer_zerop (TREE_OPERAND (cond, 1))
- || integer_onep (TREE_OPERAND (cond, 1))
- || integer_all_onesp (TREE_OPERAND (cond, 1))
- || real_zerop (TREE_OPERAND (cond, 1))
- || real_onep (TREE_OPERAND (cond, 1))
- || real_minus_onep (TREE_OPERAND (cond, 1)))
+ if (integer_zerop (op1)
+ || integer_onep (op1)
+ || integer_all_onesp (op1)
+ || real_zerop (op1)
+ || real_onep (op1)
+ || real_minus_onep (op1))
predict_edge_def (then_edge, PRED_TREE_OPCODE_POSITIVE, TAKEN);
break;
@@ -1199,6 +1239,7 @@ tree_predict_by_opcode (basic_block bb)
}
/* Try to guess whether the value of return means error code. */
+
static enum br_predictor
return_prediction (tree val, enum prediction *prediction)
{
@@ -1243,10 +1284,10 @@ return_prediction (tree val, enum prediction *prediction)
static void
apply_return_prediction (void)
{
- tree return_stmt = NULL;
+ gimple return_stmt = NULL;
tree return_val;
edge e;
- tree phi;
+ gimple phi;
int phi_num_args, i;
enum br_predictor pred;
enum prediction direction;
@@ -1256,26 +1297,20 @@ apply_return_prediction (void)
{
return_stmt = last_stmt (e->src);
if (return_stmt
- && TREE_CODE (return_stmt) == RETURN_EXPR)
+ && gimple_code (return_stmt) == GIMPLE_RETURN)
break;
}
if (!e)
return;
- return_val = TREE_OPERAND (return_stmt, 0);
+ return_val = gimple_return_retval (return_stmt);
if (!return_val)
return;
- if (TREE_CODE (return_val) == GIMPLE_MODIFY_STMT)
- return_val = GIMPLE_STMT_OPERAND (return_val, 1);
if (TREE_CODE (return_val) != SSA_NAME
|| !SSA_NAME_DEF_STMT (return_val)
- || TREE_CODE (SSA_NAME_DEF_STMT (return_val)) != PHI_NODE)
- return;
- for (phi = SSA_NAME_DEF_STMT (return_val); phi; phi = PHI_CHAIN (phi))
- if (PHI_RESULT (phi) == return_val)
- break;
- if (!phi)
+ || gimple_code (SSA_NAME_DEF_STMT (return_val)) != GIMPLE_PHI)
return;
- phi_num_args = PHI_NUM_ARGS (phi);
+ phi = SSA_NAME_DEF_STMT (return_val);
+ phi_num_args = gimple_phi_num_args (phi);
pred = return_prediction (PHI_ARG_DEF (phi, 0), &direction);
/* Avoid the degenerate case where all return values form the function
@@ -1289,7 +1324,7 @@ apply_return_prediction (void)
{
pred = return_prediction (PHI_ARG_DEF (phi, i), &direction);
if (pred != PRED_NO_PREDICTION)
- predict_paths_leading_to (PHI_ARG_EDGE (phi, i)->src, pred,
+ predict_paths_leading_to (gimple_phi_arg_edge (phi, i)->src, pred,
direction);
}
}
@@ -1307,46 +1342,34 @@ tree_bb_level_predictions (void)
FOR_EACH_BB (bb)
{
- block_stmt_iterator bsi = bsi_last (bb);
+ gimple_stmt_iterator gsi;
- for (bsi = bsi_start (bb); !bsi_end_p (bsi);)
+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi);)
{
- tree stmt = bsi_stmt (bsi);
+ gimple stmt = gsi_stmt (gsi);
tree decl;
- bool next = false;
- switch (TREE_CODE (stmt))
+ if (is_gimple_call (stmt))
{
- case GIMPLE_MODIFY_STMT:
- if (TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 1)) == CALL_EXPR)
- {
- stmt = GIMPLE_STMT_OPERAND (stmt, 1);
- goto call_expr;
- }
- break;
- case CALL_EXPR:
-call_expr:;
- if (call_expr_flags (stmt) & ECF_NORETURN)
- predict_paths_leading_to (bb, PRED_NORETURN,
- NOT_TAKEN);
- decl = get_callee_fndecl (stmt);
- if (decl
- && lookup_attribute ("cold",
- DECL_ATTRIBUTES (decl)))
- predict_paths_leading_to (bb, PRED_COLD_FUNCTION,
- NOT_TAKEN);
- break;
- case PREDICT_EXPR:
- predict_paths_leading_to (bb, PREDICT_EXPR_PREDICTOR (stmt),
- PREDICT_EXPR_OUTCOME (stmt));
- bsi_remove (&bsi, true);
- next = true;
- break;
- default:
- break;
+ if (gimple_call_flags (stmt) & ECF_NORETURN)
+ predict_paths_leading_to (bb, PRED_NORETURN,
+ NOT_TAKEN);
+ decl = gimple_call_fndecl (stmt);
+ if (decl
+ && lookup_attribute ("cold",
+ DECL_ATTRIBUTES (decl)))
+ predict_paths_leading_to (bb, PRED_COLD_FUNCTION,
+ NOT_TAKEN);
}
- if (!next)
- bsi_next (&bsi);
+ else if (gimple_code (stmt) == GIMPLE_PREDICT)
+ {
+ predict_paths_leading_to (bb, gimple_predict_predictor (stmt),
+ gimple_predict_outcome (stmt));
+ gsi_remove (&gsi, true);
+ continue;
+ }
+
+ gsi_next (&gsi);
}
}
}
@@ -1416,7 +1439,7 @@ tree_estimate_probability (void)
&& e->dest != EXIT_BLOCK_PTR
&& single_succ_p (e->dest)
&& single_succ_edge (e->dest)->dest == EXIT_BLOCK_PTR
- && TREE_CODE (last_stmt (e->dest)) == RETURN_EXPR)
+ && gimple_code (last_stmt (e->dest)) == GIMPLE_RETURN)
{
edge e1;
edge_iterator ei1;
@@ -1442,23 +1465,20 @@ tree_estimate_probability (void)
&& dominated_by_p (CDI_DOMINATORS, e->dest, e->src)
&& !dominated_by_p (CDI_POST_DOMINATORS, e->src, e->dest))
{
- block_stmt_iterator bi;
+ gimple_stmt_iterator bi;
/* The call heuristic claims that a guarded function call
is improbable. This is because such calls are often used
to signal exceptional situations such as printing error
messages. */
- for (bi = bsi_start (e->dest); !bsi_end_p (bi);
- bsi_next (&bi))
+ for (bi = gsi_start_bb (e->dest); !gsi_end_p (bi);
+ gsi_next (&bi))
{
- tree stmt = bsi_stmt (bi);
- if ((TREE_CODE (stmt) == CALL_EXPR
- || (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT
- && TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 1))
- == CALL_EXPR))
+ gimple stmt = gsi_stmt (bi);
+ if (is_gimple_call (stmt)
/* Constant and pure calls are hardly used to signalize
something exceptional. */
- && TREE_SIDE_EFFECTS (stmt))
+ && gimple_has_side_effects (stmt))
{
predict_edge_def (e, PRED_CALL, NOT_TAKEN);
break;
@@ -1483,7 +1503,7 @@ tree_estimate_probability (void)
remove_fake_exit_edges ();
loop_optimizer_finalize ();
if (dump_file && (dump_flags & TDF_DETAILS))
- dump_tree_cfg (dump_file, dump_flags);
+ gimple_dump_cfg (dump_file, dump_flags);
if (profile_status == PROFILE_ABSENT)
profile_status = PROFILE_GUESSED;
return 0;
diff --git a/gcc/print-tree.c b/gcc/print-tree.c
index 3b34f89d41c..a310ec436e2 100644
--- a/gcc/print-tree.c
+++ b/gcc/print-tree.c
@@ -29,6 +29,7 @@ along with GCC; see the file COPYING3. If not see
#include "ggc.h"
#include "langhooks.h"
#include "tree-iterator.h"
+#include "diagnostic.h"
#include "tree-flow.h"
/* Define the hash table of nodes already seen.
@@ -281,7 +282,7 @@ print_node (FILE *file, const char *prefix, tree node, int indent)
if (indent <= 4)
print_node_brief (file, "type", TREE_TYPE (node), indent + 4);
}
- else if (!GIMPLE_TUPLE_P (node))
+ else
{
print_node (file, "type", TREE_TYPE (node), indent + 4);
if (TREE_TYPE (node))
@@ -369,8 +370,14 @@ print_node (FILE *file, const char *prefix, tree node, int indent)
if (TREE_CODE (node) == TYPE_DECL && TYPE_DECL_SUPPRESS_DEBUG (node))
fputs (" suppress-debug", file);
- if (TREE_CODE (node) == FUNCTION_DECL && DECL_INLINE (node))
- fputs (DECL_DECLARED_INLINE_P (node) ? " inline" : " autoinline", file);
+ if (TREE_CODE (node) == FUNCTION_DECL
+ && DECL_FUNCTION_SPECIFIC_TARGET (node))
+ fputs (" function-specific-target", file);
+ if (TREE_CODE (node) == FUNCTION_DECL
+ && DECL_FUNCTION_SPECIFIC_OPTIMIZATION (node))
+ fputs (" function-specific-opt", file);
+ if (TREE_CODE (node) == FUNCTION_DECL && DECL_DECLARED_INLINE_P (node))
+ fputs (" autoinline", file);
if (TREE_CODE (node) == FUNCTION_DECL && DECL_BUILT_IN (node))
fputs (" built-in", file);
if (TREE_CODE (node) == FUNCTION_DECL && DECL_NO_STATIC_CHAIN (node))
@@ -706,18 +713,6 @@ print_node (FILE *file, const char *prefix, tree node, int indent)
print_node (file, "chain", TREE_CHAIN (node), indent + 4);
break;
- case tcc_gimple_stmt:
- len = TREE_CODE_LENGTH (TREE_CODE (node));
-
- for (i = 0; i < len; i++)
- {
- char temp[10];
-
- sprintf (temp, "arg %d", i);
- print_node (file, temp, GIMPLE_STMT_OPERAND (node, i), indent + 4);
- }
- break;
-
case tcc_constant:
case tcc_exceptional:
switch (TREE_CODE (node))
@@ -890,8 +885,8 @@ print_node (FILE *file, const char *prefix, tree node, int indent)
case SSA_NAME:
print_node_brief (file, "var", SSA_NAME_VAR (node), indent + 4);
- print_node_brief (file, "def_stmt",
- SSA_NAME_DEF_STMT (node), indent + 4);
+ fprintf (file, "def_stmt ");
+ print_gimple_stmt (file, SSA_NAME_DEF_STMT (node), indent + 4, 0);
indent_to (file, indent + 4);
fprintf (file, "version %u", SSA_NAME_VERSION (node));
@@ -911,12 +906,6 @@ print_node (FILE *file, const char *prefix, tree node, int indent)
}
break;
- case PHI_NODE:
- print_node (file, "result", PHI_RESULT (node), indent + 4);
- for (i = 0; i < PHI_NUM_ARGS (node); i++)
- print_node (file, "arg", PHI_ARG_DEF (node, i), indent + 4);
- break;
-
case OMP_CLAUSE:
{
int i;
@@ -931,6 +920,14 @@ print_node (FILE *file, const char *prefix, tree node, int indent)
}
break;
+ case OPTIMIZATION_NODE:
+ cl_optimization_print (file, indent + 4, TREE_OPTIMIZATION (node));
+ break;
+
+ case TARGET_OPTION_NODE:
+ cl_target_option_print (file, indent + 4, TREE_TARGET_OPTION (node));
+ break;
+
default:
if (EXCEPTIONAL_CLASS_P (node))
lang_hooks.print_xnode (file, node, indent);
diff --git a/gcc/profile.c b/gcc/profile.c
index 78568228e1f..b6cddc2295f 100644
--- a/gcc/profile.c
+++ b/gcc/profile.c
@@ -95,6 +95,7 @@ struct bb_info {
#define EDGE_INFO(e) ((struct edge_info *) (e)->aux)
#define BB_INFO(b) ((struct bb_info *) (b)->aux)
+
/* Counter summary from the last set of coverage counts read. */
const struct gcov_ctr_summary *profile_info;
@@ -671,7 +672,7 @@ compute_value_histograms (histogram_values values)
for (i = 0; i < VEC_length (histogram_value, values); i++)
{
histogram_value hist = VEC_index (histogram_value, values, i);
- tree stmt = hist->hvalue.stmt;
+ gimple stmt = hist->hvalue.stmt;
t = (int) hist->type;
@@ -793,16 +794,16 @@ branch_prob (void)
FOR_EACH_EDGE (e, ei, bb->succs)
{
- block_stmt_iterator bsi;
- tree last = NULL;
+ gimple_stmt_iterator gsi;
+ gimple last = NULL;
/* It may happen that there are compiler generated statements
without a locus at all. Go through the basic block from the
last to the first statement looking for a locus. */
- for (bsi = bsi_last (bb); !bsi_end_p (bsi); bsi_prev (&bsi))
+ for (gsi = gsi_last_bb (bb); !gsi_end_p (gsi); gsi_prev (&gsi))
{
- last = bsi_stmt (bsi);
- if (EXPR_LOCUS (last))
+ last = gsi_stmt (gsi);
+ if (gimple_has_location (last))
break;
}
@@ -811,13 +812,14 @@ branch_prob (void)
Don't do that when the locuses match, so
if (blah) goto something;
is not computed twice. */
- if (last && EXPR_LOCUS (last)
- && e->goto_locus
+ if (last
+ && gimple_has_location (last)
+ && e->goto_locus != UNKNOWN_LOCATION
&& !single_succ_p (bb)
&& (LOCATION_FILE (e->goto_locus)
- != LOCATION_FILE (EXPR_LOCATION (last))
+ != LOCATION_FILE (gimple_location (last))
|| (LOCATION_LINE (e->goto_locus)
- != LOCATION_LINE (EXPR_LOCATION (last)))))
+ != LOCATION_LINE (gimple_location (last)))))
{
basic_block new = split_edge (e);
single_succ_edge (new)->goto_locus = e->goto_locus;
@@ -982,7 +984,7 @@ branch_prob (void)
FOR_EACH_BB (bb)
{
- block_stmt_iterator bsi;
+ gimple_stmt_iterator gsi;
offset = 0;
@@ -994,26 +996,18 @@ branch_prob (void)
&offset, bb);
}
- for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
- tree stmt = bsi_stmt (bsi);
- if (EXPR_HAS_LOCATION (stmt))
- output_location (EXPR_FILENAME (stmt), EXPR_LINENO (stmt),
- &offset, bb);
- /* Take into account modify statements nested in return
- produced by C++ NRV transformation. */
- if (TREE_CODE (stmt) == RETURN_EXPR
- && TREE_OPERAND (stmt, 0)
- && TREE_CODE (TREE_OPERAND (stmt, 0)) == MODIFY_EXPR
- && EXPR_HAS_LOCATION (TREE_OPERAND (stmt, 0)))
- output_location (EXPR_FILENAME (TREE_OPERAND (stmt, 0)),
- EXPR_LINENO (TREE_OPERAND (stmt, 0)),
+ gimple stmt = gsi_stmt (gsi);
+ if (gimple_has_location (stmt))
+ output_location (gimple_filename (stmt), gimple_lineno (stmt),
&offset, bb);
}
/* Notice GOTO expressions we eliminated while constructing the
CFG. */
- if (single_succ_p (bb) && single_succ_edge (bb)->goto_locus)
+ if (single_succ_p (bb)
+ && single_succ_edge (bb)->goto_locus != UNKNOWN_LOCATION)
{
location_t curr_location = single_succ_edge (bb)->goto_locus;
/* ??? The FILE/LINE API is inconsistent for these cases. */
@@ -1063,7 +1057,7 @@ branch_prob (void)
instrument_values (values);
/* Commit changes done by instrumentation. */
- bsi_commit_edge_inserts ();
+ gsi_commit_edge_inserts ();
}
free_aux_for_edges ();
@@ -1251,4 +1245,3 @@ tree_register_profile_hooks (void)
gcc_assert (current_ir_type () == IR_GIMPLE);
profile_hooks = &tree_profile_hooks;
}
-
diff --git a/gcc/ra.h b/gcc/ra.h
index bd419522394..4fe80c8555b 100644
--- a/gcc/ra.h
+++ b/gcc/ra.h
@@ -144,10 +144,10 @@ add_neighbor (int alloc_no, int neighbor)
if (adjlist == NULL || adjlist->index == ADJACENCY_VEC_LENGTH)
{
- adjacency_t *new = (adjacency_t *) pool_alloc (adjacency_pool);
- new->index = 0;
- new->next = adjlist;
- adjlist = new;
+ adjacency_t *new_adj = (adjacency_t *) pool_alloc (adjacency_pool);
+ new_adj->index = 0;
+ new_adj->next = adjlist;
+ adjlist = new_adj;
adjacency[alloc_no] = adjlist;
}
diff --git a/gcc/recog.c b/gcc/recog.c
index 5b30172d21c..a10c6369185 100644
--- a/gcc/recog.c
+++ b/gcc/recog.c
@@ -40,6 +40,7 @@ along with GCC; see the file COPYING3. If not see
#include "basic-block.h"
#include "output.h"
#include "reload.h"
+#include "target.h"
#include "timevar.h"
#include "tree-pass.h"
#include "df.h"
@@ -182,7 +183,7 @@ static int changes_allocated;
static int num_changes = 0;
/* Validate a proposed change to OBJECT. LOC is the location in the rtl
- at which NEW will be placed. If OBJECT is zero, no validation is done,
+ at which NEW_RTX will be placed. If OBJECT is zero, no validation is done,
the change is simply made.
Two types of objects are supported: If OBJECT is a MEM, memory_address_p
@@ -200,16 +201,16 @@ static int num_changes = 0;
Otherwise, perform the change and return 1. */
static bool
-validate_change_1 (rtx object, rtx *loc, rtx new, bool in_group, bool unshare)
+validate_change_1 (rtx object, rtx *loc, rtx new_rtx, bool in_group, bool unshare)
{
rtx old = *loc;
- if (old == new || rtx_equal_p (old, new))
+ if (old == new_rtx || rtx_equal_p (old, new_rtx))
return 1;
gcc_assert (in_group != 0 || num_changes == 0);
- *loc = new;
+ *loc = new_rtx;
/* Save the information describing this change. */
if (num_changes >= changes_allocated)
@@ -252,18 +253,18 @@ validate_change_1 (rtx object, rtx *loc, rtx new, bool in_group, bool unshare)
UNSHARE to false. */
bool
-validate_change (rtx object, rtx *loc, rtx new, bool in_group)
+validate_change (rtx object, rtx *loc, rtx new_rtx, bool in_group)
{
- return validate_change_1 (object, loc, new, in_group, false);
+ return validate_change_1 (object, loc, new_rtx, in_group, false);
}
/* Wrapper for validate_change_1 without the UNSHARE argument defaulting
UNSHARE to true. */
bool
-validate_unshare_change (rtx object, rtx *loc, rtx new, bool in_group)
+validate_unshare_change (rtx object, rtx *loc, rtx new_rtx, bool in_group)
{
- return validate_change_1 (object, loc, new, in_group, true);
+ return validate_change_1 (object, loc, new_rtx, in_group, true);
}
@@ -524,7 +525,7 @@ validate_replace_rtx_1 (rtx *loc, rtx from, rtx to, rtx object)
enum rtx_code code;
enum machine_mode op0_mode = VOIDmode;
int prev_changes = num_changes;
- rtx new;
+ rtx new_rtx;
if (!x)
return;
@@ -632,25 +633,25 @@ validate_replace_rtx_1 (rtx *loc, rtx from, rtx to, rtx object)
case SIGN_EXTEND:
if (GET_MODE (XEXP (x, 0)) == VOIDmode)
{
- new = simplify_gen_unary (code, GET_MODE (x), XEXP (x, 0),
+ new_rtx = simplify_gen_unary (code, GET_MODE (x), XEXP (x, 0),
op0_mode);
/* If any of the above failed, substitute in something that
we know won't be recognized. */
- if (!new)
- new = gen_rtx_CLOBBER (GET_MODE (x), const0_rtx);
- validate_change (object, loc, new, 1);
+ if (!new_rtx)
+ new_rtx = gen_rtx_CLOBBER (GET_MODE (x), const0_rtx);
+ validate_change (object, loc, new_rtx, 1);
}
break;
case SUBREG:
/* All subregs possible to simplify should be simplified. */
- new = simplify_subreg (GET_MODE (x), SUBREG_REG (x), op0_mode,
+ new_rtx = simplify_subreg (GET_MODE (x), SUBREG_REG (x), op0_mode,
SUBREG_BYTE (x));
/* Subregs of VOIDmode operands are incorrect. */
- if (!new && GET_MODE (SUBREG_REG (x)) == VOIDmode)
- new = gen_rtx_CLOBBER (GET_MODE (x), const0_rtx);
- if (new)
- validate_change (object, loc, new, 1);
+ if (!new_rtx && GET_MODE (SUBREG_REG (x)) == VOIDmode)
+ new_rtx = gen_rtx_CLOBBER (GET_MODE (x), const0_rtx);
+ if (new_rtx)
+ validate_change (object, loc, new_rtx, 1);
break;
case ZERO_EXTRACT:
case SIGN_EXTRACT:
@@ -1685,16 +1686,14 @@ asm_operand_ok (rtx op, const char *constraint)
result = 1;
}
#ifdef EXTRA_CONSTRAINT_STR
+ else if (EXTRA_MEMORY_CONSTRAINT (c, constraint))
+ /* Every memory operand can be reloaded to fit. */
+ result = result || memory_operand (op, VOIDmode);
+ else if (EXTRA_ADDRESS_CONSTRAINT (c, constraint))
+ /* Every address operand can be reloaded to fit. */
+ result = result || address_operand (op, VOIDmode);
else if (EXTRA_CONSTRAINT_STR (op, c, constraint))
result = 1;
- else if (EXTRA_MEMORY_CONSTRAINT (c, constraint)
- /* Every memory operand can be reloaded to fit. */
- && memory_operand (op, VOIDmode))
- result = 1;
- else if (EXTRA_ADDRESS_CONSTRAINT (c, constraint)
- /* Every address operand can be reloaded to fit. */
- && address_operand (op, VOIDmode))
- result = 1;
#endif
break;
}
@@ -2199,7 +2198,7 @@ preprocess_constraints (void)
struct funny_match
{
- int this, other;
+ int this_op, other;
};
int
@@ -2349,7 +2348,7 @@ constrain_operands (int strict)
output op is the one that will be printed. */
if (val == 2 && strict > 0)
{
- funny_match[funny_match_index].this = opno;
+ funny_match[funny_match_index].this_op = opno;
funny_match[funny_match_index++].other = match;
}
}
@@ -2582,7 +2581,7 @@ constrain_operands (int strict)
while (--funny_match_index >= 0)
{
recog_data.operand[funny_match[funny_match_index].other]
- = recog_data.operand[funny_match[funny_match_index].this];
+ = recog_data.operand[funny_match[funny_match_index].this_op];
}
return 1;
@@ -2900,6 +2899,9 @@ peep2_find_free_register (int from, int to, const char *class_str,
/* Don't allocate fixed registers. */
if (fixed_regs[regno])
continue;
+ /* Don't allocate global registers. */
+ if (global_regs[regno])
+ continue;
/* Make sure the register is of the right class. */
if (! TEST_HARD_REG_BIT (reg_class_contents[cl], regno))
continue;
@@ -2909,6 +2911,9 @@ peep2_find_free_register (int from, int to, const char *class_str,
/* And that we don't create an extra save/restore. */
if (! call_used_regs[regno] && ! df_regs_ever_live_p (regno))
continue;
+ if (! targetm.hard_regno_scratch_ok (regno))
+ continue;
+
/* And we don't clobber traceback for noreturn functions. */
if ((regno == FRAME_POINTER_REGNUM || regno == HARD_FRAME_POINTER_REGNUM)
&& (! reload_completed || frame_pointer_needed))
@@ -2983,7 +2988,7 @@ peephole2_optimize (void)
prev = PREV_INSN (insn);
if (INSN_P (insn))
{
- rtx try, before_try, x;
+ rtx attempt, before_try, x;
int match_len;
rtx note;
bool was_call = false;
@@ -3004,13 +3009,13 @@ peephole2_optimize (void)
substitution would lose the
REG_FRAME_RELATED_EXPR that is attached. */
peep2_current_count = 0;
- try = NULL;
+ attempt = NULL;
}
else
/* Match the peephole. */
- try = peephole2_insns (PATTERN (insn), insn, &match_len);
+ attempt = peephole2_insns (PATTERN (insn), insn, &match_len);
- if (try != NULL)
+ if (attempt != NULL)
{
/* If we are splitting a CALL_INSN, look for the CALL_INSN
in SEQ and copy our CALL_INSN_FUNCTION_USAGE and other
@@ -3028,7 +3033,7 @@ peephole2_optimize (void)
continue;
was_call = true;
- new_insn = try;
+ new_insn = attempt;
while (new_insn != NULL_RTX)
{
if (CALL_P (new_insn))
@@ -3076,8 +3081,9 @@ peephole2_optimize (void)
REG_EH_REGION, NULL_RTX);
/* Replace the old sequence with the new. */
- try = emit_insn_after_setloc (try, peep2_insn_data[i].insn,
- INSN_LOCATOR (peep2_insn_data[i].insn));
+ attempt = emit_insn_after_setloc (attempt,
+ peep2_insn_data[i].insn,
+ INSN_LOCATOR (peep2_insn_data[i].insn));
before_try = PREV_INSN (insn);
delete_insn_chain (insn, peep2_insn_data[i].insn, false);
@@ -3091,7 +3097,7 @@ peephole2_optimize (void)
if (eh_edge->flags & (EDGE_EH | EDGE_ABNORMAL_CALL))
break;
- for (x = try ; x != before_try ; x = PREV_INSN (x))
+ for (x = attempt ; x != before_try ; x = PREV_INSN (x))
if (CALL_P (x)
|| (flag_non_call_exceptions
&& may_trap_p (PATTERN (x))
@@ -3141,7 +3147,7 @@ peephole2_optimize (void)
bitmap_copy (live, peep2_insn_data[i].live_before);
/* Update life information for the new sequence. */
- x = try;
+ x = attempt;
do
{
if (INSN_P (x))
@@ -3165,7 +3171,7 @@ peephole2_optimize (void)
/* If we generated a jump instruction, it won't have
JUMP_LABEL set. Recompute after we're done. */
- for (x = try; x != before_try; x = PREV_INSN (x))
+ for (x = attempt; x != before_try; x = PREV_INSN (x))
if (JUMP_P (x))
{
do_rebuild_jump_labels = true;
diff --git a/gcc/reg-stack.c b/gcc/reg-stack.c
index 4b5e422e207..eb31bc835cf 100644
--- a/gcc/reg-stack.c
+++ b/gcc/reg-stack.c
@@ -713,18 +713,18 @@ replace_reg (rtx *reg, int regno)
static void
remove_regno_note (rtx insn, enum reg_note note, unsigned int regno)
{
- rtx *note_link, this;
+ rtx *note_link, this_rtx;
note_link = &REG_NOTES (insn);
- for (this = *note_link; this; this = XEXP (this, 1))
- if (REG_NOTE_KIND (this) == note
- && REG_P (XEXP (this, 0)) && REGNO (XEXP (this, 0)) == regno)
+ for (this_rtx = *note_link; this_rtx; this_rtx = XEXP (this_rtx, 1))
+ if (REG_NOTE_KIND (this_rtx) == note
+ && REG_P (XEXP (this_rtx, 0)) && REGNO (XEXP (this_rtx, 0)) == regno)
{
- *note_link = XEXP (this, 1);
+ *note_link = XEXP (this_rtx, 1);
return;
}
else
- note_link = &XEXP (this, 1);
+ note_link = &XEXP (this_rtx, 1);
gcc_unreachable ();
}
@@ -2355,7 +2355,7 @@ subst_stack_regs (rtx insn, stack regstack)
is no longer needed once this has executed. */
static void
-change_stack (rtx insn, stack old, stack new, enum emit_where where)
+change_stack (rtx insn, stack old, stack new_stack, enum emit_where where)
{
int reg;
int update_end = 0;
@@ -2368,9 +2368,9 @@ change_stack (rtx insn, stack old, stack new, enum emit_where where)
&& starting_stack_p
&& where == EMIT_BEFORE)
{
- BLOCK_INFO (current_block)->stack_in = *new;
+ BLOCK_INFO (current_block)->stack_in = *new_stack;
starting_stack_p = false;
- *old = *new;
+ *old = *new_stack;
return;
}
@@ -2386,7 +2386,7 @@ change_stack (rtx insn, stack old, stack new, enum emit_where where)
/* Initialize partially dead variables. */
for (i = FIRST_STACK_REG; i < LAST_STACK_REG + 1; i++)
- if (TEST_HARD_REG_BIT (new->reg_set, i)
+ if (TEST_HARD_REG_BIT (new_stack->reg_set, i)
&& !TEST_HARD_REG_BIT (old->reg_set, i))
{
old->reg[++old->top] = i;
@@ -2400,28 +2400,28 @@ change_stack (rtx insn, stack old, stack new, enum emit_where where)
/* If the destination block's stack already has a specified layout
and contains two or more registers, use a more intelligent algorithm
to pop registers that minimizes the number number of fxchs below. */
- if (new->top > 0)
+ if (new_stack->top > 0)
{
bool slots[REG_STACK_SIZE];
int pops[REG_STACK_SIZE];
int next, dest, topsrc;
/* First pass to determine the free slots. */
- for (reg = 0; reg <= new->top; reg++)
- slots[reg] = TEST_HARD_REG_BIT (new->reg_set, old->reg[reg]);
+ for (reg = 0; reg <= new_stack->top; reg++)
+ slots[reg] = TEST_HARD_REG_BIT (new_stack->reg_set, old->reg[reg]);
/* Second pass to allocate preferred slots. */
topsrc = -1;
- for (reg = old->top; reg > new->top; reg--)
- if (TEST_HARD_REG_BIT (new->reg_set, old->reg[reg]))
+ for (reg = old->top; reg > new_stack->top; reg--)
+ if (TEST_HARD_REG_BIT (new_stack->reg_set, old->reg[reg]))
{
dest = -1;
- for (next = 0; next <= new->top; next++)
- if (!slots[next] && new->reg[next] == old->reg[reg])
+ for (next = 0; next <= new_stack->top; next++)
+ if (!slots[next] && new_stack->reg[next] == old->reg[reg])
{
/* If this is a preference for the new top of stack, record
the fact by remembering it's old->reg in topsrc. */
- if (next == new->top)
+ if (next == new_stack->top)
topsrc = reg;
slots[next] = true;
dest = next;
@@ -2438,18 +2438,18 @@ change_stack (rtx insn, stack old, stack new, enum emit_where where)
slot is still unallocated, in which case we should place the
top of stack there. */
if (topsrc != -1)
- for (reg = 0; reg < new->top; reg++)
+ for (reg = 0; reg < new_stack->top; reg++)
if (!slots[reg])
{
pops[topsrc] = reg;
- slots[new->top] = false;
+ slots[new_stack->top] = false;
slots[reg] = true;
break;
}
/* Third pass allocates remaining slots and emits pop insns. */
- next = new->top;
- for (reg = old->top; reg > new->top; reg--)
+ next = new_stack->top;
+ for (reg = old->top; reg > new_stack->top; reg--)
{
dest = pops[reg];
if (dest == -1)
@@ -2472,14 +2472,14 @@ change_stack (rtx insn, stack old, stack new, enum emit_where where)
live = 0;
for (reg = 0; reg <= old->top; reg++)
- if (TEST_HARD_REG_BIT (new->reg_set, old->reg[reg]))
+ if (TEST_HARD_REG_BIT (new_stack->reg_set, old->reg[reg]))
live++;
next = live;
while (old->top >= live)
- if (TEST_HARD_REG_BIT (new->reg_set, old->reg[old->top]))
+ if (TEST_HARD_REG_BIT (new_stack->reg_set, old->reg[old->top]))
{
- while (TEST_HARD_REG_BIT (new->reg_set, old->reg[next]))
+ while (TEST_HARD_REG_BIT (new_stack->reg_set, old->reg[next]))
next--;
emit_pop_insn (insn, old, FP_MODE_REG (old->reg[next], DFmode),
EMIT_BEFORE);
@@ -2489,13 +2489,13 @@ change_stack (rtx insn, stack old, stack new, enum emit_where where)
EMIT_BEFORE);
}
- if (new->top == -2)
+ if (new_stack->top == -2)
{
/* If the new block has never been processed, then it can inherit
the old stack order. */
- new->top = old->top;
- memcpy (new->reg, old->reg, sizeof (new->reg));
+ new_stack->top = old->top;
+ memcpy (new_stack->reg, old->reg, sizeof (new_stack->reg));
}
else
{
@@ -2505,10 +2505,10 @@ change_stack (rtx insn, stack old, stack new, enum emit_where where)
/* By now, the only difference should be the order of the stack,
not their depth or liveliness. */
- gcc_assert (hard_reg_set_equal_p (old->reg_set, new->reg_set));
- gcc_assert (old->top == new->top);
+ gcc_assert (hard_reg_set_equal_p (old->reg_set, new_stack->reg_set));
+ gcc_assert (old->top == new_stack->top);
- /* If the stack is not empty (new->top != -1), loop here emitting
+ /* If the stack is not empty (new_stack->top != -1), loop here emitting
swaps until the stack is correct.
The worst case number of swaps emitted is N + 2, where N is the
@@ -2517,16 +2517,16 @@ change_stack (rtx insn, stack old, stack new, enum emit_where where)
other regs. But since we never swap any other reg away from
its correct slot, this algorithm will converge. */
- if (new->top != -1)
+ if (new_stack->top != -1)
do
{
/* Swap the reg at top of stack into the position it is
supposed to be in, until the correct top of stack appears. */
- while (old->reg[old->top] != new->reg[new->top])
+ while (old->reg[old->top] != new_stack->reg[new_stack->top])
{
- for (reg = new->top; reg >= 0; reg--)
- if (new->reg[reg] == old->reg[old->top])
+ for (reg = new_stack->top; reg >= 0; reg--)
+ if (new_stack->reg[reg] == old->reg[old->top])
break;
gcc_assert (reg != -1);
@@ -2539,8 +2539,8 @@ change_stack (rtx insn, stack old, stack new, enum emit_where where)
incorrect reg to the top of stack, and let the while loop
above fix it. */
- for (reg = new->top; reg >= 0; reg--)
- if (new->reg[reg] != old->reg[reg])
+ for (reg = new_stack->top; reg >= 0; reg--)
+ if (new_stack->reg[reg] != old->reg[reg])
{
emit_swap_insn (insn, old,
FP_MODE_REG (old->reg[reg], DFmode));
@@ -2551,7 +2551,7 @@ change_stack (rtx insn, stack old, stack new, enum emit_where where)
/* At this point there must be no differences. */
for (reg = old->top; reg >= 0; reg--)
- gcc_assert (old->reg[reg] == new->reg[reg]);
+ gcc_assert (old->reg[reg] == new_stack->reg[reg]);
}
if (update_end)
diff --git a/gcc/regclass.c b/gcc/regclass.c
index 95425541850..b12d4168506 100644
--- a/gcc/regclass.c
+++ b/gcc/regclass.c
@@ -736,7 +736,7 @@ init_fake_stack_mems (void)
Only needed if secondary reloads are required for memory moves. */
int
-memory_move_secondary_cost (enum machine_mode mode, enum reg_class class, int in)
+memory_move_secondary_cost (enum machine_mode mode, enum reg_class rclass, int in)
{
enum reg_class altclass;
int partial_cost = 0;
@@ -745,17 +745,17 @@ memory_move_secondary_cost (enum machine_mode mode, enum reg_class class, int in
rtx mem ATTRIBUTE_UNUSED = top_of_stack[(int) mode];
- altclass = secondary_reload_class (in ? 1 : 0, class, mode, mem);
+ altclass = secondary_reload_class (in ? 1 : 0, rclass, mode, mem);
if (altclass == NO_REGS)
return 0;
if (in)
- partial_cost = REGISTER_MOVE_COST (mode, altclass, class);
+ partial_cost = REGISTER_MOVE_COST (mode, altclass, rclass);
else
- partial_cost = REGISTER_MOVE_COST (mode, class, altclass);
+ partial_cost = REGISTER_MOVE_COST (mode, rclass, altclass);
- if (class == altclass)
+ if (rclass == altclass)
/* This isn't simply a copy-to-temporary situation. Can't guess
what it is, so MEMORY_MOVE_COST really ought not to be calling
here in that case.
@@ -1086,23 +1086,23 @@ dump_regclass (FILE *dump)
int i;
for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
{
- int /* enum reg_class */ class;
+ int /* enum reg_class */ rclass;
if (REG_N_REFS (i))
{
fprintf (dump, " Register %i costs:", i);
- for (class = 0; class < (int) N_REG_CLASSES; class++)
- if (contains_reg_of_mode [(enum reg_class) class][PSEUDO_REGNO_MODE (i)]
+ for (rclass = 0; rclass < (int) N_REG_CLASSES; rclass++)
+ if (contains_reg_of_mode [(enum reg_class) rclass][PSEUDO_REGNO_MODE (i)]
#ifdef FORBIDDEN_INC_DEC_CLASSES
&& (!in_inc_dec[i]
- || !forbidden_inc_dec_class[(enum reg_class) class])
+ || !forbidden_inc_dec_class[(enum reg_class) rclass])
#endif
#ifdef CANNOT_CHANGE_MODE_CLASS
- && ! invalid_mode_change_p (i, (enum reg_class) class,
+ && ! invalid_mode_change_p (i, (enum reg_class) rclass,
PSEUDO_REGNO_MODE (i))
#endif
)
- fprintf (dump, " %s:%i", reg_class_names[class],
- costs[i].cost[(enum reg_class) class]);
+ fprintf (dump, " %s:%i", reg_class_names[rclass],
+ costs[i].cost[(enum reg_class) rclass]);
fprintf (dump, " MEM:%i\n", costs[i].mem_cost);
}
}
@@ -1381,7 +1381,7 @@ regclass (rtx f, int nregs)
enum reg_class best = ALL_REGS, alt = NO_REGS;
/* This is an enum reg_class, but we call it an int
to save lots of casts. */
- int class;
+ int rclass;
struct costs *p = &costs[i];
if (regno_reg_rtx[i] == NULL)
@@ -1392,27 +1392,27 @@ regclass (rtx f, int nregs)
if (optimize && !REG_N_REFS (i) && !REG_N_SETS (i))
continue;
- for (class = (int) ALL_REGS - 1; class > 0; class--)
+ for (rclass = (int) ALL_REGS - 1; rclass > 0; rclass--)
{
/* Ignore classes that are too small for this operand or
invalid for an operand that was auto-incremented. */
- if (!contains_reg_of_mode [class][PSEUDO_REGNO_MODE (i)]
+ if (!contains_reg_of_mode [rclass][PSEUDO_REGNO_MODE (i)]
#ifdef FORBIDDEN_INC_DEC_CLASSES
- || (in_inc_dec[i] && forbidden_inc_dec_class[class])
+ || (in_inc_dec[i] && forbidden_inc_dec_class[rclass])
#endif
#ifdef CANNOT_CHANGE_MODE_CLASS
- || invalid_mode_change_p (i, (enum reg_class) class,
+ || invalid_mode_change_p (i, (enum reg_class) rclass,
PSEUDO_REGNO_MODE (i))
#endif
)
;
- else if (p->cost[class] < best_cost)
+ else if (p->cost[rclass] < best_cost)
{
- best_cost = p->cost[class];
- best = (enum reg_class) class;
+ best_cost = p->cost[rclass];
+ best = (enum reg_class) rclass;
}
- else if (p->cost[class] == best_cost)
- best = reg_class_subunion[(int) best][class];
+ else if (p->cost[rclass] == best_cost)
+ best = reg_class_subunion[(int) best][rclass];
}
/* If no register class is better than memory, use memory. */
@@ -1427,19 +1427,19 @@ regclass (rtx f, int nregs)
will be doing it again later. */
if ((pass == 1 || dump_file) || ! flag_expensive_optimizations)
- for (class = 0; class < N_REG_CLASSES; class++)
- if (p->cost[class] < p->mem_cost
- && (reg_class_size[(int) reg_class_subunion[(int) alt][class]]
+ for (rclass = 0; rclass < N_REG_CLASSES; rclass++)
+ if (p->cost[rclass] < p->mem_cost
+ && (reg_class_size[(int) reg_class_subunion[(int) alt][rclass]]
> reg_class_size[(int) alt])
#ifdef FORBIDDEN_INC_DEC_CLASSES
- && ! (in_inc_dec[i] && forbidden_inc_dec_class[class])
+ && ! (in_inc_dec[i] && forbidden_inc_dec_class[rclass])
#endif
#ifdef CANNOT_CHANGE_MODE_CLASS
- && ! invalid_mode_change_p (i, (enum reg_class) class,
+ && ! invalid_mode_change_p (i, (enum reg_class) rclass,
PSEUDO_REGNO_MODE (i))
#endif
)
- alt = reg_class_subunion[(int) alt][class];
+ alt = reg_class_subunion[(int) alt][rclass];
/* If we don't add any classes, nothing to try. */
if (alt == best)
@@ -1516,7 +1516,7 @@ record_reg_classes (int n_alts, int n_ops, rtx *ops,
int alt_cost = 0;
enum reg_class classes[MAX_RECOG_OPERANDS];
int allows_mem[MAX_RECOG_OPERANDS];
- int class;
+ int rclass;
for (i = 0; i < n_ops; i++)
{
@@ -1616,17 +1616,17 @@ record_reg_classes (int n_alts, int n_ops, rtx *ops,
switch (recog_data.operand_type[i])
{
case OP_INOUT:
- for (class = 0; class < N_REG_CLASSES; class++)
- pp->cost[class] = (intable[class][op_class]
- + outtable[op_class][class]);
+ for (rclass = 0; rclass < N_REG_CLASSES; rclass++)
+ pp->cost[rclass] = (intable[rclass][op_class]
+ + outtable[op_class][rclass]);
break;
case OP_IN:
- for (class = 0; class < N_REG_CLASSES; class++)
- pp->cost[class] = intable[class][op_class];
+ for (rclass = 0; rclass < N_REG_CLASSES; rclass++)
+ pp->cost[rclass] = intable[rclass][op_class];
break;
case OP_OUT:
- for (class = 0; class < N_REG_CLASSES; class++)
- pp->cost[class] = outtable[op_class][class];
+ for (rclass = 0; rclass < N_REG_CLASSES; rclass++)
+ pp->cost[rclass] = outtable[op_class][rclass];
break;
}
@@ -1860,17 +1860,17 @@ record_reg_classes (int n_alts, int n_ops, rtx *ops,
switch (recog_data.operand_type[i])
{
case OP_INOUT:
- for (class = 0; class < N_REG_CLASSES; class++)
- pp->cost[class] = (intable[class][op_class]
- + outtable[op_class][class]);
+ for (rclass = 0; rclass < N_REG_CLASSES; rclass++)
+ pp->cost[rclass] = (intable[rclass][op_class]
+ + outtable[op_class][rclass]);
break;
case OP_IN:
- for (class = 0; class < N_REG_CLASSES; class++)
- pp->cost[class] = intable[class][op_class];
+ for (rclass = 0; rclass < N_REG_CLASSES; rclass++)
+ pp->cost[rclass] = intable[rclass][op_class];
break;
case OP_OUT:
- for (class = 0; class < N_REG_CLASSES; class++)
- pp->cost[class] = outtable[op_class][class];
+ for (rclass = 0; rclass < N_REG_CLASSES; rclass++)
+ pp->cost[rclass] = outtable[op_class][rclass];
break;
}
@@ -1948,9 +1948,9 @@ record_reg_classes (int n_alts, int n_ops, rtx *ops,
pp->mem_cost = MIN (pp->mem_cost,
(qq->mem_cost + alt_cost) * scale);
- for (class = 0; class < N_REG_CLASSES; class++)
- pp->cost[class] = MIN (pp->cost[class],
- (qq->cost[class] + alt_cost) * scale);
+ for (rclass = 0; rclass < N_REG_CLASSES; rclass++)
+ pp->cost[rclass] = MIN (pp->cost[rclass],
+ (qq->cost[rclass] + alt_cost) * scale);
}
}
@@ -1977,7 +1977,7 @@ record_reg_classes (int n_alts, int n_ops, rtx *ops,
{
unsigned int regno = REGNO (ops[!i]);
enum machine_mode mode = GET_MODE (ops[!i]);
- int class;
+ int rclass;
if (regno >= FIRST_PSEUDO_REGISTER && reg_pref != 0
&& reg_pref[regno].prefclass != NO_REGS)
@@ -1990,15 +1990,15 @@ record_reg_classes (int n_alts, int n_ops, rtx *ops,
op_costs[i].cost[(unsigned char) pref] = -1;
}
else if (regno < FIRST_PSEUDO_REGISTER)
- for (class = 0; class < N_REG_CLASSES; class++)
- if (TEST_HARD_REG_BIT (reg_class_contents[class], regno)
- && reg_class_size[class] == (unsigned) CLASS_MAX_NREGS (class, mode))
+ for (rclass = 0; rclass < N_REG_CLASSES; rclass++)
+ if (TEST_HARD_REG_BIT (reg_class_contents[rclass], regno)
+ && reg_class_size[rclass] == (unsigned) CLASS_MAX_NREGS (rclass, mode))
{
- if (reg_class_size[class] == 1)
- op_costs[i].cost[class] = -1;
- else if (in_hard_reg_set_p (reg_class_contents[class],
+ if (reg_class_size[rclass] == 1)
+ op_costs[i].cost[rclass] = -1;
+ else if (in_hard_reg_set_p (reg_class_contents[rclass],
mode, regno))
- op_costs[i].cost[class] = -1;
+ op_costs[i].cost[rclass] = -1;
}
}
}
@@ -2009,7 +2009,7 @@ record_reg_classes (int n_alts, int n_ops, rtx *ops,
X must not be a pseudo. */
static int
-copy_cost (rtx x, enum machine_mode mode, enum reg_class class, int to_p,
+copy_cost (rtx x, enum machine_mode mode, enum reg_class rclass, int to_p,
secondary_reload_info *prev_sri)
{
enum reg_class secondary_class = NO_REGS;
@@ -2022,7 +2022,7 @@ copy_cost (rtx x, enum machine_mode mode, enum reg_class class, int to_p,
return 0;
/* Get the class we will actually use for a reload. */
- class = PREFERRED_RELOAD_CLASS (x, class);
+ rclass = PREFERRED_RELOAD_CLASS (x, rclass);
/* If we need a secondary reload for an intermediate, the
cost is that to load the input into the intermediate register, then
@@ -2030,13 +2030,13 @@ copy_cost (rtx x, enum machine_mode mode, enum reg_class class, int to_p,
sri.prev_sri = prev_sri;
sri.extra_cost = 0;
- secondary_class = targetm.secondary_reload (to_p, x, class, mode, &sri);
+ secondary_class = targetm.secondary_reload (to_p, x, rclass, mode, &sri);
if (!move_cost[mode])
init_move_cost (mode);
if (secondary_class != NO_REGS)
- return (move_cost[mode][(int) secondary_class][(int) class]
+ return (move_cost[mode][(int) secondary_class][(int) rclass]
+ sri.extra_cost
+ copy_cost (x, mode, secondary_class, to_p, &sri));
@@ -2044,12 +2044,12 @@ copy_cost (rtx x, enum machine_mode mode, enum reg_class class, int to_p,
cost to move between the register classes, and use 2 for everything
else (constants). */
- if (MEM_P (x) || class == NO_REGS)
- return sri.extra_cost + MEMORY_MOVE_COST (mode, class, to_p);
+ if (MEM_P (x) || rclass == NO_REGS)
+ return sri.extra_cost + MEMORY_MOVE_COST (mode, rclass, to_p);
else if (REG_P (x))
return (sri.extra_cost
- + move_cost[mode][(int) REGNO_REG_CLASS (REGNO (x))][(int) class]);
+ + move_cost[mode][(int) REGNO_REG_CLASS (REGNO (x))][(int) rclass]);
else
/* If this is a constant, we may eventually want to call rtx_cost here. */
@@ -2075,12 +2075,12 @@ record_address_regs (enum machine_mode mode, rtx x, int context,
int scale)
{
enum rtx_code code = GET_CODE (x);
- enum reg_class class;
+ enum reg_class rclass;
if (context == 1)
- class = INDEX_REG_CLASS;
+ rclass = INDEX_REG_CLASS;
else
- class = base_reg_class (mode, outer_code, index_code);
+ rclass = base_reg_class (mode, outer_code, index_code);
switch (code)
{
@@ -2233,12 +2233,12 @@ record_address_regs (enum machine_mode mode, rtx x, int context,
struct costs *pp = &costs[REGNO (x)];
int i;
- pp->mem_cost += (MEMORY_MOVE_COST (Pmode, class, 1) * scale) / 2;
+ pp->mem_cost += (MEMORY_MOVE_COST (Pmode, rclass, 1) * scale) / 2;
if (!move_cost[Pmode])
init_move_cost (Pmode);
for (i = 0; i < N_REG_CLASSES; i++)
- pp->cost[i] += (may_move_in_cost[Pmode][i][(int) class] * scale) / 2;
+ pp->cost[i] += (may_move_in_cost[Pmode][i][(int) rclass] * scale) / 2;
}
break;
@@ -2667,7 +2667,7 @@ cannot_change_mode_set_regs (HARD_REG_SET *used, enum machine_mode from,
bool
invalid_mode_change_p (unsigned int regno,
- enum reg_class class ATTRIBUTE_UNUSED,
+ enum reg_class rclass ATTRIBUTE_UNUSED,
enum machine_mode from)
{
struct subregs_of_mode_node dummy, *node;
@@ -2684,7 +2684,7 @@ invalid_mode_change_p (unsigned int regno,
mask = 1 << (regno & 7);
for (to = VOIDmode; to < NUM_MACHINE_MODES; to++)
if (node->modes[to] & mask)
- if (CANNOT_CHANGE_MODE_CLASS (from, to, class))
+ if (CANNOT_CHANGE_MODE_CLASS (from, to, rclass))
return true;
return false;
diff --git a/gcc/regrename.c b/gcc/regrename.c
index 8e48ad58a94..0ed810e6393 100644
--- a/gcc/regrename.c
+++ b/gcc/regrename.c
@@ -222,13 +222,13 @@ regrename_optimize (void)
{
int new_reg, best_new_reg;
int n_uses;
- struct du_chain *this = all_chains;
+ struct du_chain *this_du = all_chains;
struct du_chain *tmp, *last;
HARD_REG_SET this_unavailable;
- int reg = REGNO (*this->loc);
+ int reg = REGNO (*this_du->loc);
int i;
- all_chains = this->next_chain;
+ all_chains = this_du->next_chain;
best_new_reg = reg;
@@ -256,7 +256,7 @@ regrename_optimize (void)
count number of uses, and narrow the set of registers we can
use for renaming. */
n_uses = 0;
- for (last = this; last->next_use; last = last->next_use)
+ for (last = this_du; last->next_use; last = last->next_use)
{
n_uses++;
IOR_COMPL_HARD_REG_SET (this_unavailable,
@@ -268,16 +268,16 @@ regrename_optimize (void)
IOR_COMPL_HARD_REG_SET (this_unavailable,
reg_class_contents[last->cl]);
- if (this->need_caller_save_reg)
+ if (this_du->need_caller_save_reg)
IOR_HARD_REG_SET (this_unavailable, call_used_reg_set);
- merge_overlapping_regs (bb, &this_unavailable, this);
+ merge_overlapping_regs (bb, &this_unavailable, this_du);
/* Now potential_regs is a reasonable approximation, let's
have a closer look at each register still in there. */
for (new_reg = 0; new_reg < FIRST_PSEUDO_REGISTER; new_reg++)
{
- int nregs = hard_regno_nregs[new_reg][GET_MODE (*this->loc)];
+ int nregs = hard_regno_nregs[new_reg][GET_MODE (*this_du->loc)];
for (i = nregs - 1; i >= 0; --i)
if (TEST_HARD_REG_BIT (this_unavailable, new_reg + i)
@@ -302,7 +302,7 @@ regrename_optimize (void)
/* See whether it accepts all modes that occur in
definition and uses. */
- for (tmp = this; tmp; tmp = tmp->next_use)
+ for (tmp = this_du; tmp; tmp = tmp->next_use)
if (! HARD_REGNO_MODE_OK (new_reg, GET_MODE (*tmp->loc))
|| (tmp->need_caller_save_reg
&& ! (HARD_REGNO_CALL_PART_CLOBBERED
@@ -333,7 +333,7 @@ regrename_optimize (void)
continue;
}
- do_replace (this, best_new_reg);
+ do_replace (this_du, best_new_reg);
tick[best_new_reg] = ++this_tick;
df_set_regs_ever_live (best_new_reg, true);
@@ -385,15 +385,15 @@ scan_rtx_reg (rtx insn, rtx *loc, enum reg_class cl,
{
if (type == OP_OUT)
{
- struct du_chain *this = XOBNEW (&rename_obstack, struct du_chain);
- this->next_use = 0;
- this->next_chain = open_chains;
- this->loc = loc;
- this->insn = insn;
- this->cl = cl;
- this->need_caller_save_reg = 0;
- this->earlyclobber = earlyclobber;
- open_chains = this;
+ struct du_chain *this_du = XOBNEW (&rename_obstack, struct du_chain);
+ this_du->next_use = 0;
+ this_du->next_chain = open_chains;
+ this_du->loc = loc;
+ this_du->insn = insn;
+ this_du->cl = cl;
+ this_du->need_caller_save_reg = 0;
+ this_du->earlyclobber = earlyclobber;
+ open_chains = this_du;
}
return;
}
@@ -403,7 +403,7 @@ scan_rtx_reg (rtx insn, rtx *loc, enum reg_class cl,
for (p = &open_chains; *p;)
{
- struct du_chain *this = *p;
+ struct du_chain *this_du = *p;
/* Check if the chain has been terminated if it has then skip to
the next chain.
@@ -412,18 +412,18 @@ scan_rtx_reg (rtx insn, rtx *loc, enum reg_class cl,
the chain in Step 3, but are trying to hide in-out operands
from terminate_write in Step 5. */
- if (*this->loc == cc0_rtx)
- p = &this->next_chain;
+ if (*this_du->loc == cc0_rtx)
+ p = &this_du->next_chain;
else
{
- int regno = REGNO (*this->loc);
- int nregs = hard_regno_nregs[regno][GET_MODE (*this->loc)];
+ int regno = REGNO (*this_du->loc);
+ int nregs = hard_regno_nregs[regno][GET_MODE (*this_du->loc)];
int exact_match = (regno == this_regno && nregs == this_nregs);
if (regno + nregs <= this_regno
|| this_regno + this_nregs <= regno)
{
- p = &this->next_chain;
+ p = &this_du->next_chain;
continue;
}
@@ -437,23 +437,23 @@ scan_rtx_reg (rtx insn, rtx *loc, enum reg_class cl,
be replaced with, terminate the chain. */
if (cl != NO_REGS)
{
- this = XOBNEW (&rename_obstack, struct du_chain);
- this->next_use = 0;
- this->next_chain = (*p)->next_chain;
- this->loc = loc;
- this->insn = insn;
- this->cl = cl;
- this->need_caller_save_reg = 0;
+ this_du = XOBNEW (&rename_obstack, struct du_chain);
+ this_du->next_use = 0;
+ this_du->next_chain = (*p)->next_chain;
+ this_du->loc = loc;
+ this_du->insn = insn;
+ this_du->cl = cl;
+ this_du->need_caller_save_reg = 0;
while (*p)
p = &(*p)->next_use;
- *p = this;
+ *p = this_du;
return;
}
}
if (action != terminate_overlapping_read || ! exact_match)
{
- struct du_chain *next = this->next_chain;
+ struct du_chain *next = this_du->next_chain;
/* Whether the terminated chain can be used for renaming
depends on the action and this being an exact match.
@@ -462,12 +462,12 @@ scan_rtx_reg (rtx insn, rtx *loc, enum reg_class cl,
if ((action == terminate_dead || action == terminate_write)
&& exact_match)
{
- this->next_chain = closed_chains;
- closed_chains = this;
+ this_du->next_chain = closed_chains;
+ closed_chains = this_du;
if (dump_file)
fprintf (dump_file,
"Closing chain %s at insn %d (%s)\n",
- reg_names[REGNO (*this->loc)], INSN_UID (insn),
+ reg_names[REGNO (*this_du->loc)], INSN_UID (insn),
scan_actions_name[(int) action]);
}
else
@@ -475,13 +475,13 @@ scan_rtx_reg (rtx insn, rtx *loc, enum reg_class cl,
if (dump_file)
fprintf (dump_file,
"Discarding chain %s at insn %d (%s)\n",
- reg_names[REGNO (*this->loc)], INSN_UID (insn),
+ reg_names[REGNO (*this_du->loc)], INSN_UID (insn),
scan_actions_name[(int) action]);
}
*p = next;
}
else
- p = &this->next_chain;
+ p = &this_du->next_chain;
}
}
}
@@ -976,15 +976,15 @@ dump_def_use_chain (struct du_chain *chains)
{
while (chains)
{
- struct du_chain *this = chains;
- int r = REGNO (*this->loc);
- int nregs = hard_regno_nregs[r][GET_MODE (*this->loc)];
+ struct du_chain *this_du = chains;
+ int r = REGNO (*this_du->loc);
+ int nregs = hard_regno_nregs[r][GET_MODE (*this_du->loc)];
fprintf (dump_file, "Register %s (%d):", reg_names[r], nregs);
- while (this)
+ while (this_du)
{
- fprintf (dump_file, " %d [%s]", INSN_UID (this->insn),
- reg_class_names[this->cl]);
- this = this->next_use;
+ fprintf (dump_file, " %d [%s]", INSN_UID (this_du->insn),
+ reg_class_names[this_du->cl]);
+ this_du = this_du->next_use;
}
fprintf (dump_file, "\n");
chains = chains->next_chain;
@@ -1365,17 +1365,17 @@ find_oldest_value_reg (enum reg_class cl, rtx reg, struct value_data *vd)
for (i = vd->e[regno].oldest_regno; i != regno; i = vd->e[i].next_regno)
{
enum machine_mode oldmode = vd->e[i].mode;
- rtx new;
+ rtx new_rtx;
if (!in_hard_reg_set_p (reg_class_contents[cl], mode, i))
return NULL_RTX;
- new = maybe_mode_change (oldmode, vd->e[regno].mode, mode, i, regno);
- if (new)
+ new_rtx = maybe_mode_change (oldmode, vd->e[regno].mode, mode, i, regno);
+ if (new_rtx)
{
- ORIGINAL_REGNO (new) = ORIGINAL_REGNO (reg);
- REG_ATTRS (new) = REG_ATTRS (reg);
- return new;
+ ORIGINAL_REGNO (new_rtx) = ORIGINAL_REGNO (reg);
+ REG_ATTRS (new_rtx) = REG_ATTRS (reg);
+ return new_rtx;
}
}
@@ -1389,14 +1389,14 @@ static bool
replace_oldest_value_reg (rtx *loc, enum reg_class cl, rtx insn,
struct value_data *vd)
{
- rtx new = find_oldest_value_reg (cl, *loc, vd);
- if (new)
+ rtx new_rtx = find_oldest_value_reg (cl, *loc, vd);
+ if (new_rtx)
{
if (dump_file)
fprintf (dump_file, "insn %u: replaced reg %u with %u\n",
- INSN_UID (insn), REGNO (*loc), REGNO (new));
+ INSN_UID (insn), REGNO (*loc), REGNO (new_rtx));
- validate_change (insn, loc, new, 1);
+ validate_change (insn, loc, new_rtx, 1);
return true;
}
return false;
@@ -1634,7 +1634,7 @@ copyprop_hardreg_forward_1 (basic_block bb, struct value_data *vd)
unsigned int regno = REGNO (src);
enum machine_mode mode = GET_MODE (src);
unsigned int i;
- rtx new;
+ rtx new_rtx;
/* If we are accessing SRC in some mode other that what we
set it in, make sure that the replacement is valid. */
@@ -1649,13 +1649,13 @@ copyprop_hardreg_forward_1 (basic_block bb, struct value_data *vd)
register in the same class. */
if (REG_P (SET_DEST (set)))
{
- new = find_oldest_value_reg (REGNO_REG_CLASS (regno), src, vd);
- if (new && validate_change (insn, &SET_SRC (set), new, 0))
+ new_rtx = find_oldest_value_reg (REGNO_REG_CLASS (regno), src, vd);
+ if (new_rtx && validate_change (insn, &SET_SRC (set), new_rtx, 0))
{
if (dump_file)
fprintf (dump_file,
"insn %u: replaced reg %u with %u\n",
- INSN_UID (insn), regno, REGNO (new));
+ INSN_UID (insn), regno, REGNO (new_rtx));
changed = true;
goto did_replacement;
}
@@ -1665,18 +1665,18 @@ copyprop_hardreg_forward_1 (basic_block bb, struct value_data *vd)
for (i = vd->e[regno].oldest_regno; i != regno;
i = vd->e[i].next_regno)
{
- new = maybe_mode_change (vd->e[i].mode, vd->e[regno].mode,
+ new_rtx = maybe_mode_change (vd->e[i].mode, vd->e[regno].mode,
mode, i, regno);
- if (new != NULL_RTX)
+ if (new_rtx != NULL_RTX)
{
- if (validate_change (insn, &SET_SRC (set), new, 0))
+ if (validate_change (insn, &SET_SRC (set), new_rtx, 0))
{
- ORIGINAL_REGNO (new) = ORIGINAL_REGNO (src);
- REG_ATTRS (new) = REG_ATTRS (src);
+ ORIGINAL_REGNO (new_rtx) = ORIGINAL_REGNO (src);
+ REG_ATTRS (new_rtx) = REG_ATTRS (src);
if (dump_file)
fprintf (dump_file,
"insn %u: replaced reg %u with %u\n",
- INSN_UID (insn), regno, REGNO (new));
+ INSN_UID (insn), regno, REGNO (new_rtx));
changed = true;
goto did_replacement;
}
@@ -1729,13 +1729,13 @@ copyprop_hardreg_forward_1 (basic_block bb, struct value_data *vd)
if (replaced[i])
{
int j;
- rtx new;
+ rtx new_rtx;
- new = *recog_data.operand_loc[i];
- recog_data.operand[i] = new;
+ new_rtx = *recog_data.operand_loc[i];
+ recog_data.operand[i] = new_rtx;
for (j = 0; j < recog_data.n_dups; j++)
if (recog_data.dup_num[j] == i)
- validate_unshare_change (insn, recog_data.dup_loc[j], new, 1);
+ validate_unshare_change (insn, recog_data.dup_loc[j], new_rtx, 1);
any_replacements = true;
}
diff --git a/gcc/reload.c b/gcc/reload.c
index 0a7a209e239..8bbadc38f8d 100644
--- a/gcc/reload.c
+++ b/gcc/reload.c
@@ -319,7 +319,7 @@ push_secondary_reload (int in_p, rtx x, int opnum, int optional,
enum machine_mode reload_mode, enum reload_type type,
enum insn_code *picode, secondary_reload_info *prev_sri)
{
- enum reg_class class = NO_REGS;
+ enum reg_class rclass = NO_REGS;
enum reg_class scratch_class;
enum machine_mode mode = reload_mode;
enum insn_code icode = CODE_FOR_nothing;
@@ -362,15 +362,15 @@ push_secondary_reload (int in_p, rtx x, int opnum, int optional,
sri.icode = CODE_FOR_nothing;
sri.prev_sri = prev_sri;
- class = targetm.secondary_reload (in_p, x, reload_class, reload_mode, &sri);
+ rclass = targetm.secondary_reload (in_p, x, reload_class, reload_mode, &sri);
icode = sri.icode;
/* If we don't need any secondary registers, done. */
- if (class == NO_REGS && icode == CODE_FOR_nothing)
+ if (rclass == NO_REGS && icode == CODE_FOR_nothing)
return -1;
- if (class != NO_REGS)
- t_reload = push_secondary_reload (in_p, x, opnum, optional, class,
+ if (rclass != NO_REGS)
+ t_reload = push_secondary_reload (in_p, x, opnum, optional, rclass,
reload_mode, type, &t_icode, &sri);
/* If we will be using an insn, the secondary reload is for a
@@ -392,7 +392,7 @@ push_secondary_reload (int in_p, rtx x, int opnum, int optional,
an icode to reload from an intermediate tertiary reload register.
We should probably have a new field in struct reload to tag a
chain of scratch operand reloads onto. */
- gcc_assert (class == NO_REGS);
+ gcc_assert (rclass == NO_REGS);
scratch_constraint = insn_data[(int) icode].operand[2].constraint;
gcc_assert (*scratch_constraint == '=');
@@ -404,7 +404,7 @@ push_secondary_reload (int in_p, rtx x, int opnum, int optional,
: REG_CLASS_FROM_CONSTRAINT ((unsigned char) letter,
scratch_constraint));
- class = scratch_class;
+ rclass = scratch_class;
mode = insn_data[(int) icode].operand[2].mode;
}
@@ -422,21 +422,21 @@ push_secondary_reload (int in_p, rtx x, int opnum, int optional,
Allow this when a reload_in/out pattern is being used. I.e. assume
that the generated code handles this case. */
- gcc_assert (!in_p || class != reload_class || icode != CODE_FOR_nothing
+ gcc_assert (!in_p || rclass != reload_class || icode != CODE_FOR_nothing
|| t_icode != CODE_FOR_nothing);
/* See if we can reuse an existing secondary reload. */
for (s_reload = 0; s_reload < n_reloads; s_reload++)
if (rld[s_reload].secondary_p
- && (reg_class_subset_p (class, rld[s_reload].class)
- || reg_class_subset_p (rld[s_reload].class, class))
+ && (reg_class_subset_p (rclass, rld[s_reload].rclass)
+ || reg_class_subset_p (rld[s_reload].rclass, rclass))
&& ((in_p && rld[s_reload].inmode == mode)
|| (! in_p && rld[s_reload].outmode == mode))
&& ((in_p && rld[s_reload].secondary_in_reload == t_reload)
|| (! in_p && rld[s_reload].secondary_out_reload == t_reload))
&& ((in_p && rld[s_reload].secondary_in_icode == t_icode)
|| (! in_p && rld[s_reload].secondary_out_icode == t_icode))
- && (SMALL_REGISTER_CLASS_P (class) || SMALL_REGISTER_CLASSES)
+ && (SMALL_REGISTER_CLASS_P (rclass) || SMALL_REGISTER_CLASSES)
&& MERGABLE_RELOADS (secondary_type, rld[s_reload].when_needed,
opnum, rld[s_reload].opnum))
{
@@ -445,8 +445,8 @@ push_secondary_reload (int in_p, rtx x, int opnum, int optional,
if (! in_p)
rld[s_reload].outmode = mode;
- if (reg_class_subset_p (class, rld[s_reload].class))
- rld[s_reload].class = class;
+ if (reg_class_subset_p (rclass, rld[s_reload].rclass))
+ rld[s_reload].rclass = rclass;
rld[s_reload].opnum = MIN (rld[s_reload].opnum, opnum);
rld[s_reload].optional &= optional;
@@ -467,7 +467,7 @@ push_secondary_reload (int in_p, rtx x, int opnum, int optional,
way reloads are output. */
if (in_p && icode == CODE_FOR_nothing
- && SECONDARY_MEMORY_NEEDED (class, reload_class, mode))
+ && SECONDARY_MEMORY_NEEDED (rclass, reload_class, mode))
{
get_secondary_mem (x, reload_mode, opnum, type);
@@ -479,7 +479,7 @@ push_secondary_reload (int in_p, rtx x, int opnum, int optional,
/* We need to make a new secondary reload for this register class. */
rld[s_reload].in = rld[s_reload].out = 0;
- rld[s_reload].class = class;
+ rld[s_reload].rclass = rclass;
rld[s_reload].inmode = in_p ? mode : VOIDmode;
rld[s_reload].outmode = ! in_p ? mode : VOIDmode;
@@ -503,7 +503,7 @@ push_secondary_reload (int in_p, rtx x, int opnum, int optional,
#ifdef SECONDARY_MEMORY_NEEDED
if (! in_p && icode == CODE_FOR_nothing
- && SECONDARY_MEMORY_NEEDED (reload_class, class, mode))
+ && SECONDARY_MEMORY_NEEDED (reload_class, rclass, mode))
get_secondary_mem (x, mode, opnum, type);
#endif
}
@@ -516,7 +516,7 @@ push_secondary_reload (int in_p, rtx x, int opnum, int optional,
register and a scratch register is needed, we return the class of the
intermediate register. */
enum reg_class
-secondary_reload_class (bool in_p, enum reg_class class,
+secondary_reload_class (bool in_p, enum reg_class rclass,
enum machine_mode mode, rtx x)
{
enum insn_code icode;
@@ -524,13 +524,13 @@ secondary_reload_class (bool in_p, enum reg_class class,
sri.icode = CODE_FOR_nothing;
sri.prev_sri = NULL;
- class = targetm.secondary_reload (in_p, x, class, mode, &sri);
+ rclass = targetm.secondary_reload (in_p, x, rclass, mode, &sri);
icode = sri.icode;
/* If there are no secondary reloads at all, we return NO_REGS.
If an intermediate register is needed, we return its class. */
- if (icode == CODE_FOR_nothing || class != NO_REGS)
- return class;
+ if (icode == CODE_FOR_nothing || rclass != NO_REGS)
+ return rclass;
/* No intermediate register is needed, but we have a special reload
pattern, which we assume for now needs a scratch register. */
@@ -547,7 +547,7 @@ scratch_reload_class (enum insn_code icode)
{
const char *scratch_constraint;
char scratch_letter;
- enum reg_class class;
+ enum reg_class rclass;
gcc_assert (insn_data[(int) icode].n_operands == 3);
scratch_constraint = insn_data[(int) icode].operand[2].constraint;
@@ -558,10 +558,10 @@ scratch_reload_class (enum insn_code icode)
scratch_letter = *scratch_constraint;
if (scratch_letter == 'r')
return GENERAL_REGS;
- class = REG_CLASS_FROM_CONSTRAINT ((unsigned char) scratch_letter,
+ rclass = REG_CLASS_FROM_CONSTRAINT ((unsigned char) scratch_letter,
scratch_constraint);
- gcc_assert (class != NO_REGS);
- return class;
+ gcc_assert (rclass != NO_REGS);
+ return rclass;
}
#ifdef SECONDARY_MEMORY_NEEDED
@@ -660,24 +660,24 @@ find_valid_class (enum machine_mode outer ATTRIBUTE_UNUSED,
unsigned int dest_regno ATTRIBUTE_UNUSED)
{
int best_cost = -1;
- int class;
+ int rclass;
int regno;
enum reg_class best_class = NO_REGS;
enum reg_class dest_class ATTRIBUTE_UNUSED = REGNO_REG_CLASS (dest_regno);
unsigned int best_size = 0;
int cost;
- for (class = 1; class < N_REG_CLASSES; class++)
+ for (rclass = 1; rclass < N_REG_CLASSES; rclass++)
{
int bad = 0;
int good = 0;
for (regno = 0; regno < FIRST_PSEUDO_REGISTER - n && ! bad; regno++)
- if (TEST_HARD_REG_BIT (reg_class_contents[class], regno))
+ if (TEST_HARD_REG_BIT (reg_class_contents[rclass], regno))
{
if (HARD_REGNO_MODE_OK (regno, inner))
{
good = 1;
- if (! TEST_HARD_REG_BIT (reg_class_contents[class], regno + n)
+ if (! TEST_HARD_REG_BIT (reg_class_contents[rclass], regno + n)
|| ! HARD_REGNO_MODE_OK (regno + n, outer))
bad = 1;
}
@@ -685,15 +685,15 @@ find_valid_class (enum machine_mode outer ATTRIBUTE_UNUSED,
if (bad || !good)
continue;
- cost = REGISTER_MOVE_COST (outer, class, dest_class);
+ cost = REGISTER_MOVE_COST (outer, rclass, dest_class);
- if ((reg_class_size[class] > best_size
+ if ((reg_class_size[rclass] > best_size
&& (best_cost < 0 || best_cost >= cost))
|| best_cost > cost)
{
- best_class = class;
- best_size = reg_class_size[class];
- best_cost = REGISTER_MOVE_COST (outer, class, dest_class);
+ best_class = rclass;
+ best_size = reg_class_size[rclass];
+ best_cost = REGISTER_MOVE_COST (outer, rclass, dest_class);
}
}
@@ -704,14 +704,14 @@ find_valid_class (enum machine_mode outer ATTRIBUTE_UNUSED,
/* Return the number of a previously made reload that can be combined with
a new one, or n_reloads if none of the existing reloads can be used.
- OUT, CLASS, TYPE and OPNUM are the same arguments as passed to
+ OUT, RCLASS, TYPE and OPNUM are the same arguments as passed to
push_reload, they determine the kind of the new reload that we try to
combine. P_IN points to the corresponding value of IN, which can be
modified by this function.
DONT_SHARE is nonzero if we can't share any input-only reload for IN. */
static int
-find_reusable_reload (rtx *p_in, rtx out, enum reg_class class,
+find_reusable_reload (rtx *p_in, rtx out, enum reg_class rclass,
enum reload_type type, int opnum, int dont_share)
{
rtx in = *p_in;
@@ -732,18 +732,18 @@ find_reusable_reload (rtx *p_in, rtx out, enum reg_class class,
than we otherwise would. */
for (i = 0; i < n_reloads; i++)
- if ((reg_class_subset_p (class, rld[i].class)
- || reg_class_subset_p (rld[i].class, class))
+ if ((reg_class_subset_p (rclass, rld[i].rclass)
+ || reg_class_subset_p (rld[i].rclass, rclass))
/* If the existing reload has a register, it must fit our class. */
&& (rld[i].reg_rtx == 0
- || TEST_HARD_REG_BIT (reg_class_contents[(int) class],
+ || TEST_HARD_REG_BIT (reg_class_contents[(int) rclass],
true_regnum (rld[i].reg_rtx)))
&& ((in != 0 && MATCHES (rld[i].in, in) && ! dont_share
&& (out == 0 || rld[i].out == 0 || MATCHES (rld[i].out, out)))
|| (out != 0 && MATCHES (rld[i].out, out)
&& (in == 0 || rld[i].in == 0 || MATCHES (rld[i].in, in))))
&& (rld[i].out == 0 || ! earlyclobber_operand_p (rld[i].out))
- && (SMALL_REGISTER_CLASS_P (class) || SMALL_REGISTER_CLASSES)
+ && (SMALL_REGISTER_CLASS_P (rclass) || SMALL_REGISTER_CLASSES)
&& MERGABLE_RELOADS (type, rld[i].when_needed, opnum, rld[i].opnum))
return i;
@@ -753,12 +753,12 @@ find_reusable_reload (rtx *p_in, rtx out, enum reg_class class,
the preincrementation as happening before any ref in this insn
to that register. */
for (i = 0; i < n_reloads; i++)
- if ((reg_class_subset_p (class, rld[i].class)
- || reg_class_subset_p (rld[i].class, class))
+ if ((reg_class_subset_p (rclass, rld[i].rclass)
+ || reg_class_subset_p (rld[i].rclass, rclass))
/* If the existing reload has a register, it must fit our
class. */
&& (rld[i].reg_rtx == 0
- || TEST_HARD_REG_BIT (reg_class_contents[(int) class],
+ || TEST_HARD_REG_BIT (reg_class_contents[(int) rclass],
true_regnum (rld[i].reg_rtx)))
&& out == 0 && rld[i].out == 0 && rld[i].in != 0
&& ((REG_P (in)
@@ -768,7 +768,7 @@ find_reusable_reload (rtx *p_in, rtx out, enum reg_class class,
&& GET_RTX_CLASS (GET_CODE (in)) == RTX_AUTOINC
&& MATCHES (XEXP (in, 0), rld[i].in)))
&& (rld[i].out == 0 || ! earlyclobber_operand_p (rld[i].out))
- && (SMALL_REGISTER_CLASS_P (class) || SMALL_REGISTER_CLASSES)
+ && (SMALL_REGISTER_CLASS_P (rclass) || SMALL_REGISTER_CLASSES)
&& MERGABLE_RELOADS (type, rld[i].when_needed,
opnum, rld[i].opnum))
{
@@ -878,7 +878,7 @@ can_reload_into (rtx in, int regno, enum machine_mode mode)
If IN and OUT are both nonzero, it means the same register must be used
to reload both IN and OUT.
- CLASS is a register class required for the reloaded data.
+ RCLASS is a register class required for the reloaded data.
INMODE is the machine mode that the instruction requires
for the reg that replaces IN and OUTMODE is likewise for OUT.
@@ -904,7 +904,7 @@ can_reload_into (rtx in, int regno, enum machine_mode mode)
int
push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
- enum reg_class class, enum machine_mode inmode,
+ enum reg_class rclass, enum machine_mode inmode,
enum machine_mode outmode, int strict_low, int optional,
int opnum, enum reload_type type)
{
@@ -1003,7 +1003,7 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
if (in != 0 && GET_CODE (in) == SUBREG
&& (subreg_lowpart_p (in) || strict_low)
#ifdef CANNOT_CHANGE_MODE_CLASS
- && !CANNOT_CHANGE_MODE_CLASS (GET_MODE (SUBREG_REG (in)), inmode, class)
+ && !CANNOT_CHANGE_MODE_CLASS (GET_MODE (SUBREG_REG (in)), inmode, rclass)
#endif
&& (CONSTANT_P (SUBREG_REG (in))
|| GET_CODE (SUBREG_REG (in)) == PLUS
@@ -1043,8 +1043,8 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
!= (int) hard_regno_nregs[REGNO (SUBREG_REG (in))]
[GET_MODE (SUBREG_REG (in))]))
|| ! HARD_REGNO_MODE_OK (subreg_regno (in), inmode)))
- || (secondary_reload_class (1, class, inmode, in) != NO_REGS
- && (secondary_reload_class (1, class, GET_MODE (SUBREG_REG (in)),
+ || (secondary_reload_class (1, rclass, inmode, in) != NO_REGS
+ && (secondary_reload_class (1, rclass, GET_MODE (SUBREG_REG (in)),
SUBREG_REG (in))
== NO_REGS))
#ifdef CANNOT_CHANGE_MODE_CLASS
@@ -1079,7 +1079,7 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
if (in != 0 && reload_inner_reg_of_subreg (in, inmode, 0))
{
- enum reg_class in_class = class;
+ enum reg_class in_class = rclass;
if (REG_P (SUBREG_REG (in)))
in_class
@@ -1109,7 +1109,7 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
if (out != 0 && GET_CODE (out) == SUBREG
&& (subreg_lowpart_p (out) || strict_low)
#ifdef CANNOT_CHANGE_MODE_CLASS
- && !CANNOT_CHANGE_MODE_CLASS (GET_MODE (SUBREG_REG (out)), outmode, class)
+ && !CANNOT_CHANGE_MODE_CLASS (GET_MODE (SUBREG_REG (out)), outmode, rclass)
#endif
&& (CONSTANT_P (SUBREG_REG (out))
|| strict_low
@@ -1136,8 +1136,8 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
!= (int) hard_regno_nregs[REGNO (SUBREG_REG (out))]
[GET_MODE (SUBREG_REG (out))]))
|| ! HARD_REGNO_MODE_OK (subreg_regno (out), outmode)))
- || (secondary_reload_class (0, class, outmode, out) != NO_REGS
- && (secondary_reload_class (0, class, GET_MODE (SUBREG_REG (out)),
+ || (secondary_reload_class (0, rclass, outmode, out) != NO_REGS
+ && (secondary_reload_class (0, rclass, GET_MODE (SUBREG_REG (out)),
SUBREG_REG (out))
== NO_REGS))
#ifdef CANNOT_CHANGE_MODE_CLASS
@@ -1211,10 +1211,10 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
/* Narrow down the class of register wanted if that is
desirable on this machine for efficiency. */
{
- enum reg_class preferred_class = class;
+ enum reg_class preferred_class = rclass;
if (in != 0)
- preferred_class = PREFERRED_RELOAD_CLASS (in, class);
+ preferred_class = PREFERRED_RELOAD_CLASS (in, rclass);
/* Output reloads may need analogous treatment, different in detail. */
#ifdef PREFERRED_OUTPUT_RELOAD_CLASS
@@ -1225,7 +1225,7 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
/* Discard what the target said if we cannot do it. */
if (preferred_class != NO_REGS
|| (optional && type == RELOAD_FOR_OUTPUT))
- class = preferred_class;
+ rclass = preferred_class;
}
/* Make sure we use a class that can handle the actual pseudo
@@ -1234,14 +1234,14 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
can handle SImode, QImode needs a smaller class. */
#ifdef LIMIT_RELOAD_CLASS
if (in_subreg_loc)
- class = LIMIT_RELOAD_CLASS (inmode, class);
+ rclass = LIMIT_RELOAD_CLASS (inmode, rclass);
else if (in != 0 && GET_CODE (in) == SUBREG)
- class = LIMIT_RELOAD_CLASS (GET_MODE (SUBREG_REG (in)), class);
+ rclass = LIMIT_RELOAD_CLASS (GET_MODE (SUBREG_REG (in)), rclass);
if (out_subreg_loc)
- class = LIMIT_RELOAD_CLASS (outmode, class);
+ rclass = LIMIT_RELOAD_CLASS (outmode, rclass);
if (out != 0 && GET_CODE (out) == SUBREG)
- class = LIMIT_RELOAD_CLASS (GET_MODE (SUBREG_REG (out)), class);
+ rclass = LIMIT_RELOAD_CLASS (GET_MODE (SUBREG_REG (out)), rclass);
#endif
/* Verify that this class is at least possible for the mode that
@@ -1265,7 +1265,7 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
}
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
if (HARD_REGNO_MODE_OK (i, mode)
- && in_hard_reg_set_p (reg_class_contents[(int) class], mode, i))
+ && in_hard_reg_set_p (reg_class_contents[(int) rclass], mode, i))
break;
if (i == FIRST_PSEUDO_REGISTER)
{
@@ -1290,10 +1290,10 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
/* Optional output reloads are always OK even if we have no register class,
since the function of these reloads is only to have spill_reg_store etc.
set, so that the storing insn can be deleted later. */
- gcc_assert (class != NO_REGS
+ gcc_assert (rclass != NO_REGS
|| (optional != 0 && type == RELOAD_FOR_OUTPUT));
- i = find_reusable_reload (&in, out, class, type, opnum, dont_share);
+ i = find_reusable_reload (&in, out, rclass, type, opnum, dont_share);
if (i == n_reloads)
{
@@ -1303,11 +1303,11 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
if (in != 0)
secondary_in_reload
- = push_secondary_reload (1, in, opnum, optional, class, inmode, type,
+ = push_secondary_reload (1, in, opnum, optional, rclass, inmode, type,
&secondary_in_icode, NULL);
if (out != 0 && GET_CODE (out) != SCRATCH)
secondary_out_reload
- = push_secondary_reload (0, out, opnum, optional, class, outmode,
+ = push_secondary_reload (0, out, opnum, optional, rclass, outmode,
type, &secondary_out_icode, NULL);
/* We found no existing reload suitable for re-use.
@@ -1320,14 +1320,14 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
|| (GET_CODE (in) == SUBREG && REG_P (SUBREG_REG (in))))
&& reg_or_subregno (in) < FIRST_PSEUDO_REGISTER
&& SECONDARY_MEMORY_NEEDED (REGNO_REG_CLASS (reg_or_subregno (in)),
- class, inmode))
+ rclass, inmode))
get_secondary_mem (in, inmode, opnum, type);
#endif
i = n_reloads;
rld[i].in = in;
rld[i].out = out;
- rld[i].class = class;
+ rld[i].rclass = rclass;
rld[i].inmode = inmode;
rld[i].outmode = outmode;
rld[i].reg_rtx = 0;
@@ -1351,7 +1351,7 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
&& (REG_P (out)
|| (GET_CODE (out) == SUBREG && REG_P (SUBREG_REG (out))))
&& reg_or_subregno (out) < FIRST_PSEUDO_REGISTER
- && SECONDARY_MEMORY_NEEDED (class,
+ && SECONDARY_MEMORY_NEEDED (rclass,
REGNO_REG_CLASS (reg_or_subregno (out)),
outmode))
get_secondary_mem (out, outmode, opnum, type);
@@ -1411,8 +1411,8 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
rld[i].out = out;
rld[i].out_reg = outloc ? *outloc : 0;
}
- if (reg_class_subset_p (class, rld[i].class))
- rld[i].class = class;
+ if (reg_class_subset_p (rclass, rld[i].rclass))
+ rld[i].rclass = rclass;
rld[i].optional &= optional;
if (MERGE_TO_OTHER (type, rld[i].when_needed,
opnum, rld[i].opnum))
@@ -1484,7 +1484,7 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
{
rld[i].reg_rtx = find_dummy_reload (in, out, inloc, outloc,
inmode, outmode,
- rld[i].class, i,
+ rld[i].rclass, i,
earlyclobber_operand_p (out));
/* If the outgoing register already contains the same value
@@ -1563,7 +1563,7 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
for (offs = 0; offs < nregs; offs++)
if (fixed_regs[regno + offs]
- || ! TEST_HARD_REG_BIT (reg_class_contents[(int) class],
+ || ! TEST_HARD_REG_BIT (reg_class_contents[(int) rclass],
regno + offs))
break;
@@ -1732,8 +1732,8 @@ combine_reloads (void)
&& rld[i].when_needed != RELOAD_FOR_OUTPUT_ADDRESS
&& rld[i].when_needed != RELOAD_FOR_OUTADDR_ADDRESS
&& rld[i].when_needed != RELOAD_OTHER
- && (CLASS_MAX_NREGS (rld[i].class, rld[i].inmode)
- == CLASS_MAX_NREGS (rld[output_reload].class,
+ && (CLASS_MAX_NREGS (rld[i].rclass, rld[i].inmode)
+ == CLASS_MAX_NREGS (rld[output_reload].rclass,
rld[output_reload].outmode))
&& rld[i].inc == 0
&& rld[i].reg_rtx == 0
@@ -1746,11 +1746,11 @@ combine_reloads (void)
secondary_memlocs_elim[(int) rld[output_reload].outmode][rld[output_reload].opnum]))
#endif
&& (SMALL_REGISTER_CLASSES
- ? (rld[i].class == rld[output_reload].class)
- : (reg_class_subset_p (rld[i].class,
- rld[output_reload].class)
- || reg_class_subset_p (rld[output_reload].class,
- rld[i].class)))
+ ? (rld[i].rclass == rld[output_reload].rclass)
+ : (reg_class_subset_p (rld[i].rclass,
+ rld[output_reload].rclass)
+ || reg_class_subset_p (rld[output_reload].rclass,
+ rld[i].rclass)))
&& (MATCHES (rld[i].in, rld[output_reload].out)
/* Args reversed because the first arg seems to be
the one that we imagine being modified
@@ -1768,7 +1768,7 @@ combine_reloads (void)
rld[output_reload].out))))
&& ! reload_inner_reg_of_subreg (rld[i].in, rld[i].inmode,
rld[i].when_needed != RELOAD_FOR_INPUT)
- && (reg_class_size[(int) rld[i].class]
+ && (reg_class_size[(int) rld[i].rclass]
|| SMALL_REGISTER_CLASSES)
/* We will allow making things slightly worse by combining an
input and an output, but no worse than that. */
@@ -1801,9 +1801,9 @@ combine_reloads (void)
= secondary_memlocs_elim[(int) rld[output_reload].outmode][rld[output_reload].opnum];
#endif
/* If required, minimize the register class. */
- if (reg_class_subset_p (rld[output_reload].class,
- rld[i].class))
- rld[i].class = rld[output_reload].class;
+ if (reg_class_subset_p (rld[output_reload].rclass,
+ rld[i].rclass))
+ rld[i].rclass = rld[output_reload].rclass;
/* Transfer all replacements from the old reload to the combined. */
for (j = 0; j < n_replacements; j++)
@@ -1837,7 +1837,7 @@ combine_reloads (void)
rld[output_reload].out)
&& (regno = REGNO (XEXP (note, 0))) < FIRST_PSEUDO_REGISTER
&& HARD_REGNO_MODE_OK (regno, rld[output_reload].outmode)
- && TEST_HARD_REG_BIT (reg_class_contents[(int) rld[output_reload].class],
+ && TEST_HARD_REG_BIT (reg_class_contents[(int) rld[output_reload].rclass],
regno)
&& (hard_regno_nregs[regno][rld[output_reload].outmode]
<= hard_regno_nregs[regno][GET_MODE (XEXP (note, 0))])
@@ -1845,10 +1845,10 @@ combine_reloads (void)
won't want this register. */
&& ((secondary_out = rld[output_reload].secondary_out_reload) == -1
|| (!(TEST_HARD_REG_BIT
- (reg_class_contents[(int) rld[secondary_out].class], regno))
+ (reg_class_contents[(int) rld[secondary_out].rclass], regno))
&& ((secondary_out = rld[secondary_out].secondary_out_reload) == -1
|| !(TEST_HARD_REG_BIT
- (reg_class_contents[(int) rld[secondary_out].class],
+ (reg_class_contents[(int) rld[secondary_out].rclass],
regno)))))
&& !fixed_regs[regno]
/* Check that a former pseudo is valid; see find_dummy_reload. */
@@ -1869,7 +1869,7 @@ combine_reloads (void)
If so, return the register rtx that proves acceptable.
INLOC and OUTLOC are locations where IN and OUT appear in the insn.
- CLASS is the register class required for the reload.
+ RCLASS is the register class required for the reload.
If FOR_REAL is >= 0, it is the number of the reload,
and in some cases when it can be discovered that OUT doesn't need
@@ -1886,7 +1886,7 @@ combine_reloads (void)
static rtx
find_dummy_reload (rtx real_in, rtx real_out, rtx *inloc, rtx *outloc,
enum machine_mode inmode, enum machine_mode outmode,
- enum reg_class class, int for_real, int earlyclobber)
+ enum reg_class rclass, int for_real, int earlyclobber)
{
rtx in = real_in;
rtx out = real_out;
@@ -1929,9 +1929,9 @@ find_dummy_reload (rtx real_in, rtx real_out, rtx *inloc, rtx *outloc,
/* Narrow down the reg class, the same way push_reload will;
otherwise we might find a dummy now, but push_reload won't. */
{
- enum reg_class preferred_class = PREFERRED_RELOAD_CLASS (in, class);
+ enum reg_class preferred_class = PREFERRED_RELOAD_CLASS (in, rclass);
if (preferred_class != NO_REGS)
- class = preferred_class;
+ rclass = preferred_class;
}
/* See if OUT will do. */
@@ -1962,7 +1962,7 @@ find_dummy_reload (rtx real_in, rtx real_out, rtx *inloc, rtx *outloc,
unsigned int i;
for (i = 0; i < nwords; i++)
- if (! TEST_HARD_REG_BIT (reg_class_contents[(int) class],
+ if (! TEST_HARD_REG_BIT (reg_class_contents[(int) rclass],
regno + i))
break;
@@ -2032,7 +2032,7 @@ find_dummy_reload (rtx real_in, rtx real_out, rtx *inloc, rtx *outloc,
unsigned int i;
for (i = 0; i < nwords; i++)
- if (! TEST_HARD_REG_BIT (reg_class_contents[(int) class],
+ if (! TEST_HARD_REG_BIT (reg_class_contents[(int) rclass],
regno + i))
break;
@@ -4188,7 +4188,7 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
&& rld[i].out == 0)
{
rld[i].reg_rtx
- = find_equiv_reg (rld[i].in, insn, rld[i].class, -1,
+ = find_equiv_reg (rld[i].in, insn, rld[i].rclass, -1,
static_reload_reg_p, 0, rld[i].inmode);
/* Prevent generation of insn to load the value
because the one we found already has the value. */
@@ -4457,7 +4457,7 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
if (i != j && rld[j].in != 0 && rld[j].out == 0
&& rld[j].when_needed == rld[i].when_needed
&& MATCHES (rld[i].in, rld[j].in)
- && rld[i].class == rld[j].class
+ && rld[i].rclass == rld[j].rclass
&& !rld[i].nocombine && !rld[j].nocombine
&& rld[i].reg_rtx == rld[j].reg_rtx)
{
@@ -4486,7 +4486,7 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
> GET_MODE_SIZE (rld[i].inmode)))
? rld[i].outmode : rld[i].inmode;
- rld[i].nregs = CLASS_MAX_NREGS (rld[i].class, rld[i].mode);
+ rld[i].nregs = CLASS_MAX_NREGS (rld[i].rclass, rld[i].mode);
}
/* Special case a simple move with an input reload and a
@@ -4503,14 +4503,14 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
unsigned int regno = REGNO (dest);
if (regno < FIRST_PSEUDO_REGISTER
- && TEST_HARD_REG_BIT (reg_class_contents[rld[i].class], regno)
+ && TEST_HARD_REG_BIT (reg_class_contents[rld[i].rclass], regno)
&& HARD_REGNO_MODE_OK (regno, rld[i].mode))
{
int nr = hard_regno_nregs[regno][rld[i].mode];
int ok = 1, nri;
for (nri = 1; nri < nr; nri ++)
- if (! TEST_HARD_REG_BIT (reg_class_contents[rld[i].class], regno + nri))
+ if (! TEST_HARD_REG_BIT (reg_class_contents[rld[i].rclass], regno + nri))
ok = 0;
if (ok)
@@ -5920,14 +5920,14 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context,
is larger than the class size, then reload the whole SUBREG. */
else
{
- enum reg_class class = context_reg_class;
- if ((unsigned) CLASS_MAX_NREGS (class, GET_MODE (SUBREG_REG (x)))
- > reg_class_size[class])
+ enum reg_class rclass = context_reg_class;
+ if ((unsigned) CLASS_MAX_NREGS (rclass, GET_MODE (SUBREG_REG (x)))
+ > reg_class_size[rclass])
{
x = find_reloads_subreg_address (x, 0, opnum,
ADDR_TYPE (type),
ind_levels, insn);
- push_reload (x, NULL_RTX, loc, (rtx*) 0, class,
+ push_reload (x, NULL_RTX, loc, (rtx*) 0, rclass,
GET_MODE (x), VOIDmode, 0, 0, opnum, type);
return 1;
}
@@ -5958,7 +5958,7 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context,
}
/* X, which is found at *LOC, is a part of an address that needs to be
- reloaded into a register of class CLASS. If X is a constant, or if
+ reloaded into a register of class RCLASS. If X is a constant, or if
X is a PLUS that contains a constant, check that the constant is a
legitimate operand and that we are supposed to be able to load
it into the register.
@@ -5973,13 +5973,13 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context,
supports. */
static void
-find_reloads_address_part (rtx x, rtx *loc, enum reg_class class,
+find_reloads_address_part (rtx x, rtx *loc, enum reg_class rclass,
enum machine_mode mode, int opnum,
enum reload_type type, int ind_levels)
{
if (CONSTANT_P (x)
&& (! LEGITIMATE_CONSTANT_P (x)
- || PREFERRED_RELOAD_CLASS (x, class) == NO_REGS))
+ || PREFERRED_RELOAD_CLASS (x, rclass) == NO_REGS))
{
x = force_const_mem (mode, x);
find_reloads_address (mode, &x, XEXP (x, 0), &XEXP (x, 0),
@@ -5989,7 +5989,7 @@ find_reloads_address_part (rtx x, rtx *loc, enum reg_class class,
else if (GET_CODE (x) == PLUS
&& CONSTANT_P (XEXP (x, 1))
&& (! LEGITIMATE_CONSTANT_P (XEXP (x, 1))
- || PREFERRED_RELOAD_CLASS (XEXP (x, 1), class) == NO_REGS))
+ || PREFERRED_RELOAD_CLASS (XEXP (x, 1), rclass) == NO_REGS))
{
rtx tem;
@@ -5999,7 +5999,7 @@ find_reloads_address_part (rtx x, rtx *loc, enum reg_class class,
opnum, type, ind_levels, 0);
}
- push_reload (x, NULL_RTX, loc, (rtx*) 0, class,
+ push_reload (x, NULL_RTX, loc, (rtx*) 0, rclass,
mode, VOIDmode, 0, 0, opnum, type);
}
@@ -6053,7 +6053,6 @@ find_reloads_subreg_address (rtx x, int force_replace, int opnum,
unsigned inner_size = GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)));
int offset;
rtx orig = tem;
- enum machine_mode orig_mode = GET_MODE (orig);
int reloaded;
/* For big-endian paradoxical subregs, SUBREG_BYTE does not
@@ -6099,15 +6098,16 @@ find_reloads_subreg_address (rtx x, int force_replace, int opnum,
/* For some processors an address may be valid in the
original mode but not in a smaller mode. For
example, ARM accepts a scaled index register in
- SImode but not in HImode. find_reloads_address
+ SImode but not in HImode. Similarly, the address may
+ have been valid before the subreg offset was added,
+ but not afterwards. find_reloads_address
assumes that we pass it a valid address, and doesn't
force a reload. This will probably be fine if
find_reloads_address finds some reloads. But if it
doesn't find any, then we may have just converted a
valid address into an invalid one. Check for that
here. */
- if (reloaded != 1
- && strict_memory_address_p (orig_mode, XEXP (tem, 0))
+ if (reloaded == 0
&& !strict_memory_address_p (GET_MODE (tem),
XEXP (tem, 0)))
push_reload (XEXP (tem, 0), NULL_RTX, &XEXP (tem, 0), (rtx*) 0,
@@ -6604,7 +6604,7 @@ refers_to_mem_for_reload_p (rtx x)
/* Check the insns before INSN to see if there is a suitable register
containing the same value as GOAL.
- If OTHER is -1, look for a register in class CLASS.
+ If OTHER is -1, look for a register in class RCLASS.
Otherwise, just see if register number OTHER shares GOAL's value.
Return an rtx for the register found, or zero if none is found.
@@ -6630,7 +6630,7 @@ refers_to_mem_for_reload_p (rtx x)
as if it were a constant except that sp is required to be unchanging. */
rtx
-find_equiv_reg (rtx goal, rtx insn, enum reg_class class, int other,
+find_equiv_reg (rtx goal, rtx insn, enum reg_class rclass, int other,
short *reload_reg_p, int goalreg, enum machine_mode mode)
{
rtx p = insn;
@@ -6776,7 +6776,7 @@ find_equiv_reg (rtx goal, rtx insn, enum reg_class class, int other,
}
else if ((unsigned) valueno >= FIRST_PSEUDO_REGISTER)
continue;
- else if (!in_hard_reg_set_p (reg_class_contents[(int) class],
+ else if (!in_hard_reg_set_p (reg_class_contents[(int) rclass],
mode, valueno))
continue;
value = valtry;
@@ -7266,7 +7266,7 @@ debug_reload_to_stream (FILE *f)
fprintf (f, "\n\t");
}
- fprintf (f, "%s, ", reg_class_names[(int) rld[r].class]);
+ fprintf (f, "%s, ", reg_class_names[(int) rld[r].rclass]);
fprintf (f, "%s (opnum = %d)",
reload_when_needed_name[(int) rld[r].when_needed],
diff --git a/gcc/reload.h b/gcc/reload.h
index 88e27080d3e..6c3e0e18d20 100644
--- a/gcc/reload.h
+++ b/gcc/reload.h
@@ -83,7 +83,7 @@ struct reload
rtx out;
/* The class of registers to reload into. */
- enum reg_class class;
+ enum reg_class rclass;
/* The mode this operand should have when reloaded, on input. */
enum machine_mode inmode;
diff --git a/gcc/reload1.c b/gcc/reload1.c
index eec21890aa8..a1711be6a26 100644
--- a/gcc/reload1.c
+++ b/gcc/reload1.c
@@ -1684,8 +1684,8 @@ reload_reg_class_lower (const void *r1p, const void *r2p)
return t;
/* Count all solitary classes before non-solitary ones. */
- t = ((reg_class_size[(int) rld[r2].class] == 1)
- - (reg_class_size[(int) rld[r1].class] == 1));
+ t = ((reg_class_size[(int) rld[r2].rclass] == 1)
+ - (reg_class_size[(int) rld[r1].rclass] == 1));
if (t != 0)
return t;
@@ -1695,7 +1695,7 @@ reload_reg_class_lower (const void *r1p, const void *r2p)
return t;
/* Consider reloads in order of increasing reg-class number. */
- t = (int) rld[r1].class - (int) rld[r2].class;
+ t = (int) rld[r1].rclass - (int) rld[r2].rclass;
if (t != 0)
return t;
@@ -1846,7 +1846,7 @@ find_reg (struct insn_chain *chain, int order)
COPY_HARD_REG_SET (not_usable, bad_spill_regs);
IOR_HARD_REG_SET (not_usable, bad_spill_regs_global);
- IOR_COMPL_HARD_REG_SET (not_usable, reg_class_contents[rl->class]);
+ IOR_COMPL_HARD_REG_SET (not_usable, reg_class_contents[rl->rclass]);
CLEAR_HARD_REG_SET (used_by_other_reload);
for (k = 0; k < order; k++)
@@ -2045,7 +2045,7 @@ find_reload_regs (struct insn_chain *chain)
{
if (dump_file)
fprintf (dump_file, "reload failure for reload %d\n", r);
- spill_failure (chain->insn, rld[r].class);
+ spill_failure (chain->insn, rld[r].rclass);
failure = 1;
return;
}
@@ -2152,16 +2152,16 @@ delete_caller_save_insns (void)
INSN should be one of the insns which needed this particular spill reg. */
static void
-spill_failure (rtx insn, enum reg_class class)
+spill_failure (rtx insn, enum reg_class rclass)
{
if (asm_noperands (PATTERN (insn)) >= 0)
error_for_asm (insn, "can't find a register in class %qs while "
"reloading %<asm%>",
- reg_class_names[class]);
+ reg_class_names[rclass]);
else
{
error ("unable to find a register to spill in class %qs",
- reg_class_names[class]);
+ reg_class_names[rclass]);
if (dump_file)
{
@@ -2587,7 +2587,7 @@ eliminate_regs_1 (rtx x, enum machine_mode mem_mode, rtx insn,
enum rtx_code code = GET_CODE (x);
struct elim_table *ep;
int regno;
- rtx new;
+ rtx new_rtx;
int i, j;
const char *fmt;
int copied = 0;
@@ -2716,15 +2716,15 @@ eliminate_regs_1 (rtx x, enum machine_mode mem_mode, rtx insn,
&& reg_equiv_constant[REGNO (new0)] != 0)
new0 = reg_equiv_constant[REGNO (new0)];
- new = form_sum (new0, new1);
+ new_rtx = form_sum (new0, new1);
/* As above, if we are not inside a MEM we do not want to
turn a PLUS into something else. We might try to do so here
for an addition of 0 if we aren't optimizing. */
- if (! mem_mode && GET_CODE (new) != PLUS)
- return gen_rtx_PLUS (GET_MODE (x), new, const0_rtx);
+ if (! mem_mode && GET_CODE (new_rtx) != PLUS)
+ return gen_rtx_PLUS (GET_MODE (x), new_rtx, const0_rtx);
else
- return new;
+ return new_rtx;
}
}
return x;
@@ -2781,8 +2781,8 @@ eliminate_regs_1 (rtx x, enum machine_mode mem_mode, rtx insn,
/* If we have something in XEXP (x, 0), the usual case, eliminate it. */
if (XEXP (x, 0))
{
- new = eliminate_regs_1 (XEXP (x, 0), mem_mode, insn, true);
- if (new != XEXP (x, 0))
+ new_rtx = eliminate_regs_1 (XEXP (x, 0), mem_mode, insn, true);
+ if (new_rtx != XEXP (x, 0))
{
/* If this is a REG_DEAD note, it is not valid anymore.
Using the eliminated version could result in creating a
@@ -2792,7 +2792,7 @@ eliminate_regs_1 (rtx x, enum machine_mode mem_mode, rtx insn,
? eliminate_regs_1 (XEXP (x, 1), mem_mode, insn, true)
: NULL_RTX);
- x = gen_rtx_EXPR_LIST (REG_NOTE_KIND (x), new, XEXP (x, 1));
+ x = gen_rtx_EXPR_LIST (REG_NOTE_KIND (x), new_rtx, XEXP (x, 1));
}
}
@@ -2804,10 +2804,10 @@ eliminate_regs_1 (rtx x, enum machine_mode mem_mode, rtx insn,
strictly needed, but it simplifies the code. */
if (XEXP (x, 1))
{
- new = eliminate_regs_1 (XEXP (x, 1), mem_mode, insn, true);
- if (new != XEXP (x, 1))
+ new_rtx = eliminate_regs_1 (XEXP (x, 1), mem_mode, insn, true);
+ if (new_rtx != XEXP (x, 1))
return
- gen_rtx_fmt_ee (GET_CODE (x), GET_MODE (x), XEXP (x, 0), new);
+ gen_rtx_fmt_ee (GET_CODE (x), GET_MODE (x), XEXP (x, 0), new_rtx);
}
return x;
@@ -2829,13 +2829,13 @@ eliminate_regs_1 (rtx x, enum machine_mode mem_mode, rtx insn,
if (GET_CODE (XEXP (x, 1)) == PLUS
&& XEXP (XEXP (x, 1), 0) == XEXP (x, 0))
{
- rtx new = eliminate_regs_1 (XEXP (XEXP (x, 1), 1), mem_mode,
+ rtx new_rtx = eliminate_regs_1 (XEXP (XEXP (x, 1), 1), mem_mode,
insn, true);
- if (new != XEXP (XEXP (x, 1), 1))
+ if (new_rtx != XEXP (XEXP (x, 1), 1))
return gen_rtx_fmt_ee (code, GET_MODE (x), XEXP (x, 0),
gen_rtx_PLUS (GET_MODE (x),
- XEXP (x, 0), new));
+ XEXP (x, 0), new_rtx));
}
return x;
@@ -2853,9 +2853,9 @@ eliminate_regs_1 (rtx x, enum machine_mode mem_mode, rtx insn,
case POPCOUNT:
case PARITY:
case BSWAP:
- new = eliminate_regs_1 (XEXP (x, 0), mem_mode, insn, false);
- if (new != XEXP (x, 0))
- return gen_rtx_fmt_e (code, GET_MODE (x), new);
+ new_rtx = eliminate_regs_1 (XEXP (x, 0), mem_mode, insn, false);
+ if (new_rtx != XEXP (x, 0))
+ return gen_rtx_fmt_e (code, GET_MODE (x), new_rtx);
return x;
case SUBREG:
@@ -2871,17 +2871,17 @@ eliminate_regs_1 (rtx x, enum machine_mode mem_mode, rtx insn,
&& reg_equiv_memory_loc != 0
&& reg_equiv_memory_loc[REGNO (SUBREG_REG (x))] != 0)
{
- new = SUBREG_REG (x);
+ new_rtx = SUBREG_REG (x);
}
else
- new = eliminate_regs_1 (SUBREG_REG (x), mem_mode, insn, false);
+ new_rtx = eliminate_regs_1 (SUBREG_REG (x), mem_mode, insn, false);
- if (new != SUBREG_REG (x))
+ if (new_rtx != SUBREG_REG (x))
{
int x_size = GET_MODE_SIZE (GET_MODE (x));
- int new_size = GET_MODE_SIZE (GET_MODE (new));
+ int new_size = GET_MODE_SIZE (GET_MODE (new_rtx));
- if (MEM_P (new)
+ if (MEM_P (new_rtx)
&& ((x_size < new_size
#ifdef WORD_REGISTER_OPERATIONS
/* On these machines, combine can create rtl of the form
@@ -2897,9 +2897,9 @@ eliminate_regs_1 (rtx x, enum machine_mode mem_mode, rtx insn,
)
|| x_size == new_size)
)
- return adjust_address_nv (new, GET_MODE (x), SUBREG_BYTE (x));
+ return adjust_address_nv (new_rtx, GET_MODE (x), SUBREG_BYTE (x));
else
- return gen_rtx_SUBREG (GET_MODE (x), new, SUBREG_BYTE (x));
+ return gen_rtx_SUBREG (GET_MODE (x), new_rtx, SUBREG_BYTE (x));
}
return x;
@@ -2915,9 +2915,9 @@ eliminate_regs_1 (rtx x, enum machine_mode mem_mode, rtx insn,
case USE:
/* Handle insn_list USE that a call to a pure function may generate. */
- new = eliminate_regs_1 (XEXP (x, 0), 0, insn, false);
- if (new != XEXP (x, 0))
- return gen_rtx_USE (GET_MODE (x), new);
+ new_rtx = eliminate_regs_1 (XEXP (x, 0), 0, insn, false);
+ if (new_rtx != XEXP (x, 0))
+ return gen_rtx_USE (GET_MODE (x), new_rtx);
return x;
case CLOBBER:
@@ -2936,21 +2936,21 @@ eliminate_regs_1 (rtx x, enum machine_mode mem_mode, rtx insn,
{
if (*fmt == 'e')
{
- new = eliminate_regs_1 (XEXP (x, i), mem_mode, insn, false);
- if (new != XEXP (x, i) && ! copied)
+ new_rtx = eliminate_regs_1 (XEXP (x, i), mem_mode, insn, false);
+ if (new_rtx != XEXP (x, i) && ! copied)
{
x = shallow_copy_rtx (x);
copied = 1;
}
- XEXP (x, i) = new;
+ XEXP (x, i) = new_rtx;
}
else if (*fmt == 'E')
{
int copied_vec = 0;
for (j = 0; j < XVECLEN (x, i); j++)
{
- new = eliminate_regs_1 (XVECEXP (x, i, j), mem_mode, insn, false);
- if (new != XVECEXP (x, i, j) && ! copied_vec)
+ new_rtx = eliminate_regs_1 (XVECEXP (x, i, j), mem_mode, insn, false);
+ if (new_rtx != XVECEXP (x, i, j) && ! copied_vec)
{
rtvec new_v = gen_rtvec_v (XVECLEN (x, i),
XVEC (x, i)->elem);
@@ -2962,7 +2962,7 @@ eliminate_regs_1 (rtx x, enum machine_mode mem_mode, rtx insn,
XVEC (x, i) = new_v;
copied_vec = 1;
}
- XVECEXP (x, i, j) = new;
+ XVECEXP (x, i, j) = new_rtx;
}
}
}
@@ -5824,7 +5824,7 @@ allocate_reload_reg (struct insn_chain *chain ATTRIBUTE_UNUSED, int r,
for (count = 0; count < n_spills; count++)
{
- int class = (int) rld[r].class;
+ int rclass = (int) rld[r].rclass;
int regnum;
i++;
@@ -5841,7 +5841,7 @@ allocate_reload_reg (struct insn_chain *chain ATTRIBUTE_UNUSED, int r,
&& free_for_value_p (regnum, rld[r].mode, rld[r].opnum,
rld[r].when_needed, rld[r].in,
rld[r].out, r, 1)))
- && TEST_HARD_REG_BIT (reg_class_contents[class], regnum)
+ && TEST_HARD_REG_BIT (reg_class_contents[rclass], regnum)
&& HARD_REGNO_MODE_OK (regnum, rld[r].mode)
/* Look first for regs to share, then for unshared. But
don't share regs used for inherited reloads; they are
@@ -5871,7 +5871,7 @@ allocate_reload_reg (struct insn_chain *chain ATTRIBUTE_UNUSED, int r,
while (nr > 1)
{
int regno = regnum + nr - 1;
- if (!(TEST_HARD_REG_BIT (reg_class_contents[class], regno)
+ if (!(TEST_HARD_REG_BIT (reg_class_contents[rclass], regno)
&& spill_reg_order[regno] >= 0
&& reload_reg_free_p (regno, rld[r].opnum,
rld[r].when_needed)))
@@ -5997,7 +5997,7 @@ choose_reload_regs (struct insn_chain *chain)
{
max_group_size = MAX (rld[j].nregs, max_group_size);
group_class
- = reg_class_superunion[(int) rld[j].class][(int) group_class];
+ = reg_class_superunion[(int) rld[j].rclass][(int) group_class];
}
save_reload_reg_rtx[j] = rld[j].reg_rtx;
@@ -6143,7 +6143,7 @@ choose_reload_regs (struct insn_chain *chain)
#endif
)
{
- enum reg_class class = rld[r].class, last_class;
+ enum reg_class rclass = rld[r].rclass, last_class;
rtx last_reg = reg_last_reload_reg[regno];
enum machine_mode need_mode;
@@ -6164,18 +6164,18 @@ choose_reload_regs (struct insn_chain *chain)
&& reg_reloaded_contents[i] == regno
&& TEST_HARD_REG_BIT (reg_reloaded_valid, i)
&& HARD_REGNO_MODE_OK (i, rld[r].mode)
- && (TEST_HARD_REG_BIT (reg_class_contents[(int) class], i)
+ && (TEST_HARD_REG_BIT (reg_class_contents[(int) rclass], i)
/* Even if we can't use this register as a reload
register, we might use it for reload_override_in,
if copying it to the desired class is cheap
enough. */
- || ((REGISTER_MOVE_COST (mode, last_class, class)
- < MEMORY_MOVE_COST (mode, class, 1))
- && (secondary_reload_class (1, class, mode,
+ || ((REGISTER_MOVE_COST (mode, last_class, rclass)
+ < MEMORY_MOVE_COST (mode, rclass, 1))
+ && (secondary_reload_class (1, rclass, mode,
last_reg)
== NO_REGS)
#ifdef SECONDARY_MEMORY_NEEDED
- && ! SECONDARY_MEMORY_NEEDED (last_class, class,
+ && ! SECONDARY_MEMORY_NEEDED (last_class, rclass,
mode)
#endif
))
@@ -6207,7 +6207,7 @@ choose_reload_regs (struct insn_chain *chain)
bad_for_class = 0;
for (k = 0; k < nr; k++)
- bad_for_class |= ! TEST_HARD_REG_BIT (reg_class_contents[(int) rld[r].class],
+ bad_for_class |= ! TEST_HARD_REG_BIT (reg_class_contents[(int) rld[r].rclass],
i+k);
/* We found a register that contains the
@@ -6289,7 +6289,7 @@ choose_reload_regs (struct insn_chain *chain)
|| REG_P (rld[r].in)
|| MEM_P (rld[r].in))
&& (rld[r].nregs == max_group_size
- || ! reg_classes_intersect_p (rld[r].class, group_class)))
+ || ! reg_classes_intersect_p (rld[r].rclass, group_class)))
search_equiv = rld[r].in;
/* If this is an output reload from a simple move insn, look
if an equivalence for the input is available. */
@@ -6306,7 +6306,7 @@ choose_reload_regs (struct insn_chain *chain)
if (search_equiv)
{
rtx equiv
- = find_equiv_reg (search_equiv, insn, rld[r].class,
+ = find_equiv_reg (search_equiv, insn, rld[r].rclass,
-1, NULL, 0, rld[r].mode);
int regno = 0;
@@ -6347,7 +6347,7 @@ choose_reload_regs (struct insn_chain *chain)
{
regs_used |= TEST_HARD_REG_BIT (reload_reg_used_at_all,
i);
- bad_for_class |= ! TEST_HARD_REG_BIT (reg_class_contents[(int) rld[r].class],
+ bad_for_class |= ! TEST_HARD_REG_BIT (reg_class_contents[(int) rld[r].rclass],
i);
}
@@ -6485,9 +6485,9 @@ choose_reload_regs (struct insn_chain *chain)
|| rld[s].optional)
continue;
- if ((rld[s].class != rld[r].class
- && reg_classes_intersect_p (rld[r].class,
- rld[s].class))
+ if ((rld[s].rclass != rld[r].rclass
+ && reg_classes_intersect_p (rld[r].rclass,
+ rld[s].rclass))
|| rld[s].nregs < rld[r].nregs)
break;
}
@@ -7171,7 +7171,7 @@ emit_input_reload_insns (struct insn_chain *chain, struct reload *rl,
sri.icode = CODE_FOR_nothing;
sri.prev_sri = NULL;
- new_class = targetm.secondary_reload (1, real_oldequiv, rl->class,
+ new_class = targetm.secondary_reload (1, real_oldequiv, rl->rclass,
mode, &sri);
if (new_class == NO_REGS && sri.icode == CODE_FOR_nothing)
@@ -7361,7 +7361,7 @@ emit_output_reload_insns (struct insn_chain *chain, struct reload *rl,
&& reg_equiv_mem[REGNO (old)] != 0)
real_old = reg_equiv_mem[REGNO (old)];
- if (secondary_reload_class (0, rl->class, mode, real_old) != NO_REGS)
+ if (secondary_reload_class (0, rl->rclass, mode, real_old) != NO_REGS)
{
rtx second_reloadreg = reloadreg;
reloadreg = rld[secondary_reload].reg_rtx;
diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c
index d569ff04b2b..fb4a5df7dc8 100644
--- a/gcc/rtlanal.c
+++ b/gcc/rtlanal.c
@@ -2470,32 +2470,32 @@ replace_rtx (rtx x, rtx from, rtx to)
if (GET_CODE (x) == SUBREG)
{
- rtx new = replace_rtx (SUBREG_REG (x), from, to);
+ rtx new_rtx = replace_rtx (SUBREG_REG (x), from, to);
- if (GET_CODE (new) == CONST_INT)
+ if (GET_CODE (new_rtx) == CONST_INT)
{
- x = simplify_subreg (GET_MODE (x), new,
+ x = simplify_subreg (GET_MODE (x), new_rtx,
GET_MODE (SUBREG_REG (x)),
SUBREG_BYTE (x));
gcc_assert (x);
}
else
- SUBREG_REG (x) = new;
+ SUBREG_REG (x) = new_rtx;
return x;
}
else if (GET_CODE (x) == ZERO_EXTEND)
{
- rtx new = replace_rtx (XEXP (x, 0), from, to);
+ rtx new_rtx = replace_rtx (XEXP (x, 0), from, to);
- if (GET_CODE (new) == CONST_INT)
+ if (GET_CODE (new_rtx) == CONST_INT)
{
x = simplify_unary_operation (ZERO_EXTEND, GET_MODE (x),
- new, GET_MODE (XEXP (x, 0)));
+ new_rtx, GET_MODE (XEXP (x, 0)));
gcc_assert (x);
}
else
- XEXP (x, 0) = new;
+ XEXP (x, 0) = new_rtx;
return x;
}
@@ -3692,12 +3692,12 @@ nonzero_bits1 (const_rtx x, enum machine_mode mode, const_rtx known_x,
{
unsigned HOST_WIDE_INT nonzero_for_hook = nonzero;
- rtx new = rtl_hooks.reg_nonzero_bits (x, mode, known_x,
+ rtx new_rtx = rtl_hooks.reg_nonzero_bits (x, mode, known_x,
known_mode, known_ret,
&nonzero_for_hook);
- if (new)
- nonzero_for_hook &= cached_nonzero_bits (new, mode, known_x,
+ if (new_rtx)
+ nonzero_for_hook &= cached_nonzero_bits (new_rtx, mode, known_x,
known_mode, known_ret);
return nonzero_for_hook;
@@ -4177,12 +4177,12 @@ num_sign_bit_copies1 (const_rtx x, enum machine_mode mode, const_rtx known_x,
{
unsigned int copies_for_hook = 1, copies = 1;
- rtx new = rtl_hooks.reg_num_sign_bit_copies (x, mode, known_x,
+ rtx new_rtx = rtl_hooks.reg_num_sign_bit_copies (x, mode, known_x,
known_mode, known_ret,
&copies_for_hook);
- if (new)
- copies = cached_num_sign_bit_copies (new, mode, known_x,
+ if (new_rtx)
+ copies = cached_num_sign_bit_copies (new_rtx, mode, known_x,
known_mode, known_ret);
if (copies > 1 || copies_for_hook > 1)
diff --git a/gcc/rtlhooks.c b/gcc/rtlhooks.c
index 432b286c1d8..25fbc094830 100644
--- a/gcc/rtlhooks.c
+++ b/gcc/rtlhooks.c
@@ -141,7 +141,7 @@ gen_lowpart_if_possible (enum machine_mode mode, rtx x)
{
/* This is the only other case we handle. */
int offset = 0;
- rtx new;
+ rtx new_rtx;
if (WORDS_BIG_ENDIAN)
offset = (MAX (GET_MODE_SIZE (GET_MODE (x)), UNITS_PER_WORD)
@@ -152,11 +152,11 @@ gen_lowpart_if_possible (enum machine_mode mode, rtx x)
offset -= (MIN (UNITS_PER_WORD, GET_MODE_SIZE (mode))
- MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (x))));
- new = adjust_address_nv (x, mode, offset);
- if (! memory_address_p (mode, XEXP (new, 0)))
+ new_rtx = adjust_address_nv (x, mode, offset);
+ if (! memory_address_p (mode, XEXP (new_rtx, 0)))
return 0;
- return new;
+ return new_rtx;
}
else if (mode != GET_MODE (x) && GET_MODE (x) != VOIDmode
&& validate_subreg (mode, GET_MODE (x), x,
diff --git a/gcc/sched-ebb.c b/gcc/sched-ebb.c
index 58a89346cf0..25b97c395d1 100644
--- a/gcc/sched-ebb.c
+++ b/gcc/sched-ebb.c
@@ -357,7 +357,7 @@ static void
add_deps_for_risky_insns (rtx head, rtx tail)
{
rtx insn, prev;
- int class;
+ int classification;
rtx last_jump = NULL_RTX;
rtx next_tail = NEXT_INSN (tail);
basic_block last_block = NULL, bb;
@@ -372,9 +372,9 @@ add_deps_for_risky_insns (rtx head, rtx tail)
}
else if (INSN_P (insn) && last_jump != NULL_RTX)
{
- class = haifa_classify_insn (insn);
+ classification = haifa_classify_insn (insn);
prev = last_jump;
- switch (class)
+ switch (classification)
{
case PFREE_CANDIDATE:
if (flag_schedule_speculative_load)
diff --git a/gcc/sched-rgn.c b/gcc/sched-rgn.c
index abb2c8d6f6c..28f528302ff 100644
--- a/gcc/sched-rgn.c
+++ b/gcc/sched-rgn.c
@@ -2388,10 +2388,10 @@ static struct deps *bb_deps;
static rtx
concat_INSN_LIST (rtx copy, rtx old)
{
- rtx new = old;
+ rtx new_rtx = old;
for (; copy ; copy = XEXP (copy, 1))
- new = alloc_INSN_LIST (XEXP (copy, 0), new);
- return new;
+ new_rtx = alloc_INSN_LIST (XEXP (copy, 0), new_rtx);
+ return new_rtx;
}
static void
diff --git a/gcc/stmt.c b/gcc/stmt.c
index af02f3402ce..664c91049b4 100644
--- a/gcc/stmt.c
+++ b/gcc/stmt.c
@@ -1356,9 +1356,6 @@ expand_expr_stmt (tree exp)
tree type;
value = expand_expr (exp, const0_rtx, VOIDmode, EXPAND_NORMAL);
- if (GIMPLE_TUPLE_P (exp))
- type = void_type_node;
- else
type = TREE_TYPE (exp);
/* If all we do is reference a volatile value in memory,
@@ -1412,7 +1409,6 @@ warn_if_unused_value (const_tree exp, location_t locus)
case PREDECREMENT_EXPR:
case POSTDECREMENT_EXPR:
case MODIFY_EXPR:
- case GIMPLE_MODIFY_STMT:
case INIT_EXPR:
case TARGET_EXPR:
case CALL_EXPR:
@@ -1581,10 +1577,10 @@ expand_return (tree retval)
expand_null_return ();
return;
}
- else if ((TREE_CODE (retval) == GIMPLE_MODIFY_STMT
+ else if ((TREE_CODE (retval) == MODIFY_EXPR
|| TREE_CODE (retval) == INIT_EXPR)
- && TREE_CODE (GENERIC_TREE_OPERAND (retval, 0)) == RESULT_DECL)
- retval_rhs = GENERIC_TREE_OPERAND (retval, 1);
+ && TREE_CODE (TREE_OPERAND (retval, 0)) == RESULT_DECL)
+ retval_rhs = TREE_OPERAND (retval, 1);
else
retval_rhs = retval;
@@ -1603,7 +1599,7 @@ expand_return (tree retval)
(and in expand_call). */
else if (retval_rhs != 0
- && TYPE_MODE (GENERIC_TREE_TYPE (retval_rhs)) == BLKmode
+ && TYPE_MODE (TREE_TYPE (retval_rhs)) == BLKmode
&& REG_P (result_rtl))
{
int i;
diff --git a/gcc/stor-layout.c b/gcc/stor-layout.c
index 2b48ea60370..17654611e1a 100644
--- a/gcc/stor-layout.c
+++ b/gcc/stor-layout.c
@@ -163,12 +163,12 @@ variable_size (tree size)
#endif
/* Return the machine mode to use for a nonscalar of SIZE bits. The
- mode must be in class CLASS, and have exactly that many value bits;
+ mode must be in class MCLASS, and have exactly that many value bits;
it may have padding as well. If LIMIT is nonzero, modes of wider
than MAX_FIXED_MODE_SIZE will not be used. */
enum machine_mode
-mode_for_size (unsigned int size, enum mode_class class, int limit)
+mode_for_size (unsigned int size, enum mode_class mclass, int limit)
{
enum machine_mode mode;
@@ -176,7 +176,7 @@ mode_for_size (unsigned int size, enum mode_class class, int limit)
return BLKmode;
/* Get the first mode which has this size, in the specified class. */
- for (mode = GET_CLASS_NARROWEST_MODE (class); mode != VOIDmode;
+ for (mode = GET_CLASS_NARROWEST_MODE (mclass); mode != VOIDmode;
mode = GET_MODE_WIDER_MODE (mode))
if (GET_MODE_PRECISION (mode) == size)
return mode;
@@ -187,7 +187,7 @@ mode_for_size (unsigned int size, enum mode_class class, int limit)
/* Similar, except passed a tree node. */
enum machine_mode
-mode_for_size_tree (const_tree size, enum mode_class class, int limit)
+mode_for_size_tree (const_tree size, enum mode_class mclass, int limit)
{
unsigned HOST_WIDE_INT uhwi;
unsigned int ui;
@@ -198,20 +198,20 @@ mode_for_size_tree (const_tree size, enum mode_class class, int limit)
ui = uhwi;
if (uhwi != ui)
return BLKmode;
- return mode_for_size (ui, class, limit);
+ return mode_for_size (ui, mclass, limit);
}
/* Similar, but never return BLKmode; return the narrowest mode that
contains at least the requested number of value bits. */
enum machine_mode
-smallest_mode_for_size (unsigned int size, enum mode_class class)
+smallest_mode_for_size (unsigned int size, enum mode_class mclass)
{
enum machine_mode mode;
/* Get the first mode which has at least this size, in the
specified class. */
- for (mode = GET_CLASS_NARROWEST_MODE (class); mode != VOIDmode;
+ for (mode = GET_CLASS_NARROWEST_MODE (mclass); mode != VOIDmode;
mode = GET_MODE_WIDER_MODE (mode))
if (GET_MODE_PRECISION (mode) >= size)
return mode;
diff --git a/gcc/system.h b/gcc/system.h
index be70b026ff4..80bfe619c3d 100644
--- a/gcc/system.h
+++ b/gcc/system.h
@@ -786,8 +786,9 @@ extern void fancy_abort (const char *, int, const char *) ATTRIBUTE_NORETURN;
change after the fact). Beyond these uses, most other cases of
using this macro should be viewed with extreme caution. */
-#if defined(__GNUC__) && GCC_VERSION != 4000
-/* GCC 4.0.x has a bug where it may ICE on this expression. */
+#if defined(__GNUC__) && GCC_VERSION > 4000
+/* GCC 4.0.x has a bug where it may ICE on this expression,
+ so does GCC 3.4.x (PR17436). */
#define CONST_CAST2(TOTYPE,FROMTYPE,X) ((__extension__(union {FROMTYPE _q; TOTYPE _nq;})(X))._nq)
#else
#define CONST_CAST2(TOTYPE,FROMTYPE,X) ((TOTYPE)(FROMTYPE)(X))
@@ -796,6 +797,7 @@ extern void fancy_abort (const char *, int, const char *) ATTRIBUTE_NORETURN;
#define CONST_CAST_TREE(X) CONST_CAST(union tree_node *, (X))
#define CONST_CAST_RTX(X) CONST_CAST(struct rtx_def *, (X))
#define CONST_CAST_BB(X) CONST_CAST(struct basic_block_def *, (X))
+#define CONST_CAST_GIMPLE(X) CONST_CAST(union gimple_statement_d *, (X))
/* Activate certain diagnostics as warnings (not errors via the
-Werror flag). */
diff --git a/gcc/target-def.h b/gcc/target-def.h
index 2692e94aabc..bf8c7e79eac 100644
--- a/gcc/target-def.h
+++ b/gcc/target-def.h
@@ -520,6 +520,8 @@
#define TARGET_MACHINE_DEPENDENT_REORG 0
#define TARGET_BUILD_BUILTIN_VA_LIST std_build_builtin_va_list
+#define TARGET_FN_ABI_VA_LIST std_fn_abi_va_list
+#define TARGET_CANONICAL_VA_LIST_TYPE std_canonical_va_list_type
#define TARGET_EXPAND_BUILTIN_VA_START 0
#define TARGET_GET_PCH_VALIDITY default_get_pch_validity
@@ -617,6 +619,10 @@
#define TARGET_INSTANTIATE_DECLS hook_void_void
#endif
+#ifndef TARGET_HARD_REGNO_SCRATCH_OK
+#define TARGET_HARD_REGNO_SCRATCH_OK default_hard_regno_scratch_ok
+#endif
+
/* C specific. */
#ifndef TARGET_C_MODE_FOR_SUFFIX
#define TARGET_C_MODE_FOR_SUFFIX default_mode_for_suffix
@@ -752,6 +758,51 @@
TARGET_EMUTLS_DEBUG_FORM_TLS_ADDRESS \
}
+/* Function specific option attribute support. */
+#ifndef TARGET_OPTION_VALID_ATTRIBUTE_P
+#define TARGET_OPTION_VALID_ATTRIBUTE_P NULL
+#endif
+
+#ifndef TARGET_OPTION_SAVE
+#define TARGET_OPTION_SAVE NULL
+#endif
+
+#ifndef TARGET_OPTION_RESTORE
+#define TARGET_OPTION_RESTORE NULL
+#endif
+
+#ifndef TARGET_OPTION_PRINT
+#define TARGET_OPTION_PRINT NULL
+#endif
+
+#ifndef TARGET_OPTION_PRAGMA_PARSE
+#define TARGET_OPTION_PRAGMA_PARSE NULL
+#endif
+
+#ifndef TARGET_OPTION_CAN_INLINE_P
+#define TARGET_OPTION_CAN_INLINE_P default_target_option_can_inline_p
+#endif
+
+#ifndef TARGET_OPTION_COLD_ATTRIBUTE_SETS_OPTIMIZATION
+#define TARGET_OPTION_COLD_ATTRIBUTE_SETS_OPTIMIZATION false
+#endif
+
+#ifndef TARGET_OPTION_HOT_ATTRIBUTE_SETS_OPTIMIZATION
+#define TARGET_OPTION_HOT_ATTRIBUTE_SETS_OPTIMIZATION false
+#endif
+
+#define TARGET_OPTION_HOOKS \
+ { \
+ TARGET_OPTION_VALID_ATTRIBUTE_P, \
+ TARGET_OPTION_SAVE, \
+ TARGET_OPTION_RESTORE, \
+ TARGET_OPTION_PRINT, \
+ TARGET_OPTION_PRAGMA_PARSE, \
+ TARGET_OPTION_CAN_INLINE_P, \
+ TARGET_OPTION_COLD_ATTRIBUTE_SETS_OPTIMIZATION, \
+ TARGET_OPTION_HOT_ATTRIBUTE_SETS_OPTIMIZATION, \
+ }
+
/* The whole shebang. */
#define TARGET_INITIALIZER \
{ \
@@ -820,6 +871,8 @@
TARGET_CC_MODES_COMPATIBLE, \
TARGET_MACHINE_DEPENDENT_REORG, \
TARGET_BUILD_BUILTIN_VA_LIST, \
+ TARGET_FN_ABI_VA_LIST, \
+ TARGET_CANONICAL_VA_LIST_TYPE, \
TARGET_EXPAND_BUILTIN_VA_START, \
TARGET_GIMPLIFY_VA_ARG_EXPR, \
TARGET_GET_PCH_VALIDITY, \
@@ -842,9 +895,11 @@
TARGET_SECONDARY_RELOAD, \
TARGET_EXPAND_TO_RTL_HOOK, \
TARGET_INSTANTIATE_DECLS, \
+ TARGET_HARD_REGNO_SCRATCH_OK, \
TARGET_C, \
TARGET_CXX, \
TARGET_EMUTLS, \
+ TARGET_OPTION_HOOKS, \
TARGET_EXTRA_LIVE_ON_ENTRY, \
TARGET_UNWIND_TABLES_DEFAULT, \
TARGET_HAVE_NAMED_SECTIONS, \
diff --git a/gcc/target.h b/gcc/target.h
index 012d1c0099b..331cc53d8f4 100644
--- a/gcc/target.h
+++ b/gcc/target.h
@@ -697,12 +697,18 @@ struct gcc_target
/* Create the __builtin_va_list type. */
tree (* build_builtin_va_list) (void);
+ /* Get the cfun/fndecl calling abi __builtin_va_list type. */
+ tree (* fn_abi_va_list) (tree);
+
+ /* Get the __builtin_va_list type dependent on input type. */
+ tree (* canonical_va_list_type) (tree);
+
/* Expand the __builtin_va_start builtin. */
void (* expand_builtin_va_start) (tree valist, rtx nextarg);
/* Gimplifies a VA_ARG_EXPR. */
- tree (* gimplify_va_arg_expr) (tree valist, tree type, tree *pre_p,
- tree *post_p);
+ tree (* gimplify_va_arg_expr) (tree valist, tree type, gimple_seq *pre_p,
+ gimple_seq *post_p);
/* Validity-checking routines for PCH files, target-specific.
get_pch_validity returns a pointer to the data to be stored,
@@ -748,10 +754,9 @@ struct gcc_target
void (* dwarf_handle_frame_unspec) (const char *, rtx, int);
/* Perform architecture specific checking of statements gimplified
- from VA_ARG_EXPR. LHS is left hand side of MODIFY_EXPR, RHS
- is right hand side. Returns true if the statements doesn't need
- to be checked for va_list references. */
- bool (* stdarg_optimize_hook) (struct stdarg_info *ai, const_tree lhs, const_tree rhs);
+ from VA_ARG_EXPR. STMT is the statement. Returns true if the statement
+ doesn't need to be checked for va_list references. */
+ bool (* stdarg_optimize_hook) (struct stdarg_info *ai, const_gimple stmt);
/* This target hook allows the operating system to override the DECL
that represents the external variable that contains the stack
@@ -866,6 +871,10 @@ struct gcc_target
but will be later. */
void (* instantiate_decls) (void);
+ /* Return true if is OK to use a hard register REGNO as scratch register
+ in peephole2. */
+ bool (* hard_regno_scratch_ok) (unsigned int regno);
+
/* Functions specific to the C family of frontends. */
struct c {
/* Return machine mode for non-standard suffix
@@ -953,6 +962,40 @@ struct gcc_target
bool debug_form_tls_address;
} emutls;
+ struct target_option_hooks {
+ /* Function to validate the attribute((option(...))) strings or NULL. If
+ the option is validated, it is assumed that DECL_FUNCTION_SPECIFIC will
+ be filled in in the function decl node. */
+ bool (*valid_attribute_p) (tree, tree, tree, int);
+
+ /* Function to save any extra target state in the target options
+ structure. */
+ void (*save) (struct cl_target_option *);
+
+ /* Function to restore any extra target state from the target options
+ structure. */
+ void (*restore) (struct cl_target_option *);
+
+ /* Function to print any extra target state from the target options
+ structure. */
+ void (*print) (FILE *, int, struct cl_target_option *);
+
+ /* Function to parse arguments to be validated for #pragma option, and to
+ change the state if the options are valid. If the arguments are NULL,
+ use the default target options. Return true if the options are valid,
+ and set the current state. */
+ bool (*pragma_parse) (tree);
+
+ /* Function to determine if one function can inline another function. */
+ bool (*can_inline_p) (tree, tree);
+
+ /* Whether the cold attribute changes the optimization level. */
+ bool cold_attribute_sets_optimization;
+
+ /* Whether the hot attribute changes the optimization level. */
+ bool hot_attribute_sets_optimization;
+ } target_option;
+
/* For targets that need to mark extra registers as live on entry to
the function, they should define this target hook and set their
bits in the bitmap passed in. */
diff --git a/gcc/targhooks.c b/gcc/targhooks.c
index 7e931c5ed9d..4e9b9ad0675 100644
--- a/gcc/targhooks.c
+++ b/gcc/targhooks.c
@@ -581,7 +581,7 @@ default_secondary_reload (bool in_p ATTRIBUTE_UNUSED, rtx x ATTRIBUTE_UNUSED,
enum machine_mode reload_mode ATTRIBUTE_UNUSED,
secondary_reload_info *sri)
{
- enum reg_class class = NO_REGS;
+ enum reg_class rclass = NO_REGS;
if (sri->prev_sri && sri->prev_sri->t_icode != CODE_FOR_nothing)
{
@@ -590,13 +590,13 @@ default_secondary_reload (bool in_p ATTRIBUTE_UNUSED, rtx x ATTRIBUTE_UNUSED,
}
#ifdef SECONDARY_INPUT_RELOAD_CLASS
if (in_p)
- class = SECONDARY_INPUT_RELOAD_CLASS (reload_class, reload_mode, x);
+ rclass = SECONDARY_INPUT_RELOAD_CLASS (reload_class, reload_mode, x);
#endif
#ifdef SECONDARY_OUTPUT_RELOAD_CLASS
if (! in_p)
- class = SECONDARY_OUTPUT_RELOAD_CLASS (reload_class, reload_mode, x);
+ rclass = SECONDARY_OUTPUT_RELOAD_CLASS (reload_class, reload_mode, x);
#endif
- if (class != NO_REGS)
+ if (rclass != NO_REGS)
{
enum insn_code icode = (in_p ? reload_in_optab[(int) reload_mode]
: reload_out_optab[(int) reload_mode]);
@@ -648,19 +648,19 @@ default_secondary_reload (bool in_p ATTRIBUTE_UNUSED, rtx x ATTRIBUTE_UNUSED,
if (reg_class_subset_p (reload_class, insn_class))
{
- gcc_assert (scratch_class == class);
- class = NO_REGS;
+ gcc_assert (scratch_class == rclass);
+ rclass = NO_REGS;
}
else
- class = insn_class;
+ rclass = insn_class;
}
- if (class == NO_REGS)
+ if (rclass == NO_REGS)
sri->icode = icode;
else
sri->t_icode = icode;
}
- return class;
+ return rclass;
}
bool
@@ -703,4 +703,44 @@ default_builtin_vector_alignment_reachable (const_tree type, bool is_packed)
return true;
}
+bool
+default_hard_regno_scratch_ok (unsigned int regno ATTRIBUTE_UNUSED)
+{
+ return true;
+}
+
+bool
+default_target_option_valid_attribute_p (tree ARG_UNUSED (fndecl),
+ tree ARG_UNUSED (name),
+ tree ARG_UNUSED (args),
+ int ARG_UNUSED (flags))
+{
+ return false;
+}
+
+bool
+default_target_option_can_inline_p (tree caller, tree callee)
+{
+ bool ret = false;
+ tree callee_opts = DECL_FUNCTION_SPECIFIC_TARGET (callee);
+ tree caller_opts = DECL_FUNCTION_SPECIFIC_TARGET (caller);
+
+ /* If callee has no option attributes, then it is ok to inline */
+ if (!callee_opts)
+ ret = true;
+
+ /* If caller has no option attributes, but callee does then it is not ok to
+ inline */
+ else if (!caller_opts)
+ ret = false;
+
+ /* If both caller and callee have attributes, assume that if the pointer is
+ different, the the two functions have different target options since
+ build_target_option_node uses a hash table for the options. */
+ else
+ ret = (callee_opts == caller_opts);
+
+ return ret;
+}
+
#include "gt-targhooks.h"
diff --git a/gcc/targhooks.h b/gcc/targhooks.h
index 5aebc7e667b..efb487c0d8b 100644
--- a/gcc/targhooks.h
+++ b/gcc/targhooks.h
@@ -97,3 +97,6 @@ extern int default_reloc_rw_mask (void);
extern tree default_mangle_decl_assembler_name (tree, tree);
extern tree default_emutls_var_fields (tree, tree *);
extern tree default_emutls_var_init (tree, tree, tree);
+extern bool default_hard_regno_scratch_ok (unsigned int);
+extern bool default_target_option_valid_attribute_p (tree, tree, tree, int);
+extern bool default_target_option_can_inline_p (tree, tree);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 35df102f0ca..dc2bb162abf 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,583 @@
+2008-07-28 Richard Guenther <rguenther@suse.de>
+
+ Merge from gimple-tuples-branch.
+
+ * gcc.c-torture/compile/20080721-1.c: New testcase.
+ * gcc.dg/torture/20080716-1.c: Likewise.
+ * gcc.dg/tree-ssa/tailcall-3.c: Likewise.
+ * gcc.dg/tree-ssa/20080530.c: Likewise.
+ * gcc.dg/20080615-1.c: Likewise.
+ * g++.dg/torture/pr36826.C: Likewise.
+ * gcc.dg/fold-alloca-1.c: Look into cleanup_cfg1 dump instead of
+ useless dump.
+ * gcc.dg/tree-ssa/pr21658.c: Update search pattern.
+ * gfortran.dg/gomp/block-1.f90: Adjust dg-error.
+ * gcc.dg/tree-ssa/20030728-1.c: Test final_cleanup instead of
+ optimized dump.
+
+2008-07-28 Simon Baldwin <simonb@google.com>
+
+ * gcc.dg/pragma-message.c: New.
+
+2008-07-27 Victor Kaplansky <victork@il.ibm.com>
+
+ PR tree-optimization/35252
+ * gcc.dg/vect/vect-complex-1.c, gcc.dg/vect/vect-complex-2.c,
+ gcc.dg/vect/fast-math-vect-complex-3.c,
+ gcc.dg/vect/vect-complex-4.c: New tests.
+
+2008-07-27 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR c++/36944
+ * g++.dg/other/pr36944.C: New.
+
+2008-07-27 Daniel Franke <franke.daniel@gmail.com>
+
+ PR fortran/36724
+ * gfortran.dg/pointer_to_substring.f90: New test.
+
+2008-07-27 Tobias Burnus <burnus@net-b.de>
+
+ PR fortran/36132
+ PR fortran/29952
+ PR fortran/36909
+ * gfortran.dg/internal_pack_4.f90: New.
+ * gfortran.dg/internal_pack_5.f90: New.
+ * gfortran.dg/array_temporaries_2.f90: New.
+
+2008-07-26 Thomas Koenig <tkoenig@gcc.gnu.org>
+
+ PR fortran/36934
+ * gfortran.dg/allocatable_module_1.f90: New test case.
+
+2008-07-25 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR target/36936
+ * gcc.target/i386/cmov8.c: New.
+ * gcc.target/i386/funcspec-10.c: Likewise.
+ * gcc.target/i386/funcspec-11.c: Likewise.
+
+2008-07-25 Joseph Myers <joseph@codesourcery.com>
+
+ * lib/target-supports.exp (check_effective_target_arm_thumb1_ok):
+ New.
+ * g++.dg/inherit/thunk8.C: Use it.
+
+2008-07-24 Jan Hubicka <jh@suse.cz>
+
+ * gcc.dg/winline-4.c: Remove.
+ * gcc.dg/pch/valid-3.hs: Remove.
+ * gcc.dg/pch/valid-3.c: Remove.
+ * g++.old-deja/g++.brendan/crash52.C: Accept returning void warning
+ * g++.old-deja/g++.jason/report.C: Likewise.
+ * testsuite/g++.dg/warn/pr23075.C: We get returning void warning
+ instead of control flow warning.
+
+2008-07-24 Daniel Kraft <d@domob.eu>
+
+ PR fortran/33141
+ * gfortran.dg/intrinsic_shadow_1.f03: New test for -Wintrinsic-shadow.
+ * gfortran.dg/intrinsic_shadow_2.f03: Ditto.
+ * gfortran.dg/intrinsic_shadow_3.f03: Ditto.
+ * gfortran.dg/intrinsic_std_1.f90: New test for -Wintrinsics-std.
+ * gfortran.dg/intrinsic_std_2.f90: Ditto.
+ * gfortran.dg/intrinsic_std_3.f90: Ditto.
+ * gfortran.dg/intrinsic_std_4.f90: Ditto.
+ * gfortran.dg/warn_std_1.f90: Removed option -Wnonstd-intrinsics.
+ * gfortran.dg/warn_std_2.f90: Replaced -Wnonstd-intrinsics by
+ -Wintrinsics-std and adapted expected errors/warnings.
+ * gfortran.dg/warn_std_3.f90: Ditto.
+ * gfortran.dg/c_sizeof_2.f90: Adapted expected error/warning message.
+ * gfortran.dg/gamma_2.f90: Ditto.
+ * gfortran.dg/selected_char_kind_3.f90: Ditto.
+ * gfortran.dg/fmt_g0_2.f08: Call with -fall-intrinsics to allow abort.
+
+2008-07-24 Thomas Koenig <tkoenig@gcc.gnu.org>
+
+ PR fortran/29952
+ * gfortran.dg/array_temporaries_1.f90: New test case.
+
+2008-07-23 Ian Lance Taylor <iant@google.com>
+
+ * gcc.target/i386/20080723-1.c: New test.
+
+2008-07-24 Ben Elliston <bje@au.ibm.com>
+
+ * gcc.target/spu/vector.c: New test.
+ * gcc.target/spu/vector-ansi.c: Likewise.
+
+2008-07-23 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
+
+ PR 35058
+ * gcc.dg/Wdeclaration-after-statement-3.c: New.
+ * gcc/testsuite/gcc.dg/Wpointer-arith.c: New.
+
+2008-07-22 Jerry DeLisle <jvdelisle@gcc.gnu.org>
+
+ PR libfortran/36852
+ * gfortran.dg/namelist_52.f90: New test.
+
+2008-07-22 Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
+
+ * lib/target-supports.exp (check_effective_target_spu_auto_overlay):
+ New procedure.
+ * lib/compat.exp (compat-execute): Use it to test whether toolchain
+ supports automatic overlay generation for the SPU.
+
+2008-07-22 Daniel Kraft <d@domob.eu>
+
+ PR fortran/29835
+ * gfortran.dg/fmt_error_3.f90: New test.
+ * gfortran.dg/fmt_error_4.f90: New test.
+ * gfortran.dg/fmt_error_5.f90: New test.
+
+2008-07-22 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
+
+ PR 28079
+ * gcc.dg/cpp/line6.c: New.
+
+2008-07-21 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
+
+ * gfortran.dg/fmt_g0_3.f08: Fix typo in expected error message.
+
+2008-07-21 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/36871
+ PR c++/36872
+ * g++.dg/ext/has_nothrow_copy.C: Rename to...
+ * g++.dg/ext/has_nothrow_copy-1.C: ... this.
+ * g++.dg/ext/has_nothrow_copy-2.C: New.
+ * g++.dg/ext/has_nothrow_copy-3.C: Likewise.
+ * g++.dg/ext/has_nothrow_copy-4.C: Likewise.
+ * g++.dg/ext/has_nothrow_copy-5.C: Likewise.
+ * g++.dg/ext/has_nothrow_copy-6.C: Likewise.
+ * g++.dg/ext/has_nothrow_copy-7.C: Likewise.
+
+2008-07-21 Thomas Koenig <tkoenig@gcc.gnu.org>
+
+ PR libfortran/36773
+ * gfortran.dg/zero_sized_5.f90: New test case.
+
+2008-07-21 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/36870
+ * g++.dg/ext/has_nothrow_assign_odr.C: New.
+ * g++.dg/ext/has_nothrow_copy_odr.C: Likewise.
+ * g++.dg/ext/has_nothrow_constructor_odr.C: Likewise.
+ * g++.dg/ext/has_nothrow_assign.C: Adjust.
+ * g++.dg/ext/has_nothrow_copy.C: Likewise.
+ * g++.dg/ext/has_nothrow_constructor.C: Likewise.
+
+2008-07-17 Andreas Krebbel <krebbel1@de.ibm.com>
+
+ PR target/36822
+ * gcc.target/s390/pr36822.c: New testcase.
+
+2008-07-21 Hans-Peter Nilsson <hp@axis.com>
+
+ PR middle-end/36143
+ * g++.dg/tree-ssa/pr19637.C: XFAIL.
+
+ PR rtl-optimization/33642
+ * gcc.c-torture/compile/pr11832.c: Skip for CRIS.
+ * gcc.c-torture/compile/pr33009.c: Likewise.
+
+ PR middle-end/36509
+ * gcc.dg/Wstrict-aliasing-float-ptr-int-obj.c: XFAIL.
+
+2008-07-20 Andrew Pinski <andrew_pinski@playstation.sony.com>
+
+ PR tree-opt/36879
+ * gcc.c-torture/execute/20080719-1.c: New testcase.
+
+2008-07-20 Hans-Peter Nilsson <hp@axis.com>
+
+ * gcc.dg/tree-ssa/data-dep-1.c: XFAIL.
+
+2008-07-20 Daniel Berlin <dberlin@dberlin.org>
+
+ * gcc.dg/tree-ssa/ssa-fre-7.c: XFAIL.
+ * gcc.dg/tree-ssa/ssa-fre-8.c: Ditto.
+ * gcc.dg/tree-ssa/ssa-fre-9.c: Ditto.
+ * gcc.dg/tree-ssa/ssa-fre-13.c: Ditto.
+ * gcc.dg/tree-ssa/ssa-fre-14.c: Ditto.
+ * gcc.dg/tree-ssa/ssa-fre-17.c: Ditto.
+ * gcc.dg/tree-ssa/ssa-pre-15.c: Ditto.
+ * gcc.dg/tree-ssa/loadpre1.c: PASS.
+
+2008-07-19 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/36877
+ * gcc.dg/gomp/atomic-11.c: New test.
+
+2008-07-19 Tobias Burnus <burnus@net-b.de>
+
+ PR fortran/36795
+ * char_expr_1.f90: New.
+ * char_expr_2.f90: New.
+
+2008-07-19 Olivier Hainque <hainque@adacore.com>
+
+ * gcc.dg/mallign.c: New test.
+ * gnat.dg/allocator_maxalign1.adb: New test.
+ * gnat.dg/test_allocator_maxalign2.adb: Main caller for ...
+ * gnat.dg/allocator_maxalign2.ad[bs]: New test.
+
+2008-07-19 Tobias Burnus <burnus@net-b.de>
+
+ * gfortran.dg/intrinsic_argument_conformance_2.f90: New.
+ * gfortran.dg/zero_sized_1.f90: Fix conformance bugs.
+
+2008-07-18 Kris Van Hees <kris.van.hees@oracle.com>
+
+ * g++.dg/ext/utf-array.C: Fix broken merge/checkin.
+ * g++.dg/ext/utf-array-short-wchar.C: Idem
+ * gcc.dg/utf-array.c: Idem
+ * gcc.dg/utf-array-short-wchar.c: Idem
+
+2008-07-18 Joseph Myers <joseph@codesourcery.com>
+
+ * gcc.dg/fshort-wchar.c: Use -Wl,--no-wchar-size-warning on
+ arm*-*-*eabi.
+
+2008-07-18 Uros Bizjak <ubizjak@gmail.com>
+
+ PR target/36786
+ * gcc.target/i386/pr36786.c: New test.
+
+2008-07-18 Dodji Seketeli <dseketel@redhat.com>
+
+ PR c++/36407
+ * g++.dg/conversion/op5.C: New testcase.
+
+2008-07-18 Kris Van Hees <kris.van.hees@oracle.com>
+
+ * g++.dg/ext/utf-array.C: Fix broken merge/checkin.
+ * g++.dg/ext/utf-array-short-wchar.C: Idem
+ * gcc.dg/utf-array.c: Idem
+ * gcc.dg/utf-array-short-wchar.c: Idem
+
+2008-07-18 Kris Van Hees <kris.van.hees@oracle.com>
+
+ Tests for char16_t and char32_t support.
+ * g++.dg/ext/utf-array.C: New
+ * g++.dg/ext/utf-array-short-wchar.C: New
+ * g++.dg/ext/utf-rtti.C: New
+ * g++.dg/ext/utf-type.c: New
+ * gcc.dg/utf-array.c: New
+ * gcc.dg/utf-array-short-wchar.c: New
+ * gcc.dg/utf-inc-init.c: New
+ * gcc.dg/utf-type.c: New
+
+2008-07-18 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR middle-end/36859
+ * gcc.target/i386/vararg-2.c: New.
+
+2008-07-18 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR middle-end/36858
+ * gcc.target/i386/vararg-1.c: New.
+
+2008-07-18 Tobias Burnus <burnus@net-b.de>
+
+ * gfortran.dg/parameter_array_init_4.f90: Silence pedantic warning.
+
+2008-07-17 Olivier Hainque <hainque@adacore.com>
+
+ * gnat.dg/tree_static_def.ad[bs]: Support for ...
+ * gnat.dg/tree_static_use.adb: New test.
+ * gnat.dg/decl_ctx_def.ads: Support for ...
+ * gnat.dg/decl_ctx_use.ad[bs]: New test.
+
+2008-07-17 Julian Brown <julian@codesourcery.com>
+ Mark Mitchell <mark@codesourcery.com>
+
+ * g++.dg/ext/visibility/arm3.C: Add explanatory text. Skip on
+ non-DLL targets.
+ * g++.dg/ext/visibility/arm1.C: Skip on non-DLL targets.
+
+2008-07-17 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/36855
+ * g++.dg/ext/has_trivial_destructor.C: Rename to...
+ * g++.dg/ext/has_trivial_destructor-1.C: ... this.
+ * g++.dg/ext/has_trivial_destructor-2.C: New.
+
+2008-07-17 Paolo Bonzini <bonzini@gnu.org>
+
+ PR rtl-optimization/36753
+ * gcc.target/i386/pr36753.c: New.
+
+2008-07-17 Tobias Burnus <burnus@net-b.de>
+
+ PR fortran/36825
+ PR fortran/36824
+ * gfortran.dg/rank_2.f90: Add additional array-rank test.
+ * gfortran.dg/array_4.f90: New.
+
+2008-07-17 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR testsuite/36443
+ * objc.dg/gnu-encoding/gnu-encoding.exp: Temporarily unset
+ GCC_EXEC_PREFIX from environment when running $HOSTCC.
+
+2008-07-16 Dodji Seketeli <dseketel@redhat.com>
+
+ PR c++/13699
+ * g++.dg/lookup/extern-c-redecl.C: New test.
+
+2008-07-15 Richard Guenther <rguenther@suse.de>
+
+ PR middle-end/36369
+ * gcc.dg/Wstrict-aliasing-bogus-ref-all.c: New testcase.
+
+2008-07-15 Andrew Pinski <andrew_pinski@playstation.sony.com>
+
+ PR target/31568
+ * gcc.target/powerpc/asm-y.c: New testcase.
+
+2008-07-14 Eric Botcazou <ebotcazou@adacore.com>
+
+ * case_optimization1.ad[sb]: New test.
+ * case_optimization_pkg1.ads: New helper.
+
+2008-07-14 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/36745
+ * g++.dg/torture/pr36745.C: Use __SIZE_TYPE__ in size_t typedef.
+
+2008-07-14 Andreas Krebbel <krebbel1@de.ibm.com>
+
+ PR target/36745
+ * g++.dg/torture/pr36745.C: New testcase.
+
+2008-07-14 Ben Elliston <bje@au.ibm.com>
+
+ * gcc.target/powerpc/altivec-macros.c: New test.
+ * gcc.target/powerpc/altviec-26.c: Likewise.
+ * gcc.dg/vmx/1b-06.c: Remove bool variable.
+ * gcc.dg/vmx/1b-07.c: Likewise.
+ * gcc.dg/vmx/1b-06-ansi.c: New test for the pre-define method.
+ * gcc.dg/vmx/1b-07-ansi.c: Likewise.
+
+2008-07-14 Jerry DeLisle <jvdelisle@gcc.gnu.org>
+
+ PR fortran/36725
+ gfortran.dg/fmt_go_4.f08: New test.
+
+2008-07-14 Hans-Peter Nilsson <hp@axis.com>
+
+ PR target/35492
+ * gcc.c-torture/compile/pr35492.c: New test.
+
+2008-07-12 Daniel Kraft <d@domob.eu>
+
+ * gfortran.dg/used_types_21.f90: New test.
+
+2008-07-11 Ian Lance Taylor <iant@google.com>
+
+ * gcc.dg/Wcxx-compat-2.c: New test.
+
+2008-07-11 Dodji Seketeli <dseketel@redhat.com>
+
+ PR c++/13101
+ * g++.dg/parse/func-ptr-decl.C: New test.
+ * gcc/testsuite/g++.old-deja/g++.jason/crash11.C: Update this to
+ catch a warning that is generated by virtue of fixing this bug.
+
+2008-07-11 Dodji Seketeli <dseketel@redhat.com>
+
+ * g++.dg/other/semicolon.C: Tighten this test, making it column aware.
+ * g++.dg/parse/error15.C: update this because of more accurate column
+ numbers in error reporting.
+ * g++.old-deja/g++.brendan/crash16.C: Tighten the test, making it
+ column aware.
+ * g++.old-deja/g++.law/ctors5.C: Likewise.
+ * g++.old-deja/g++.other/crash25.C: Likewise.
+
+2008-06-30 Dodji Seketeli <dseketel@redhat.com>
+
+ * g++.dg/parse/constructor1.C, g++.dg/parse/error*.C: Update these
+ tests to make them catch column number regressions. Make these tests
+ run with the -fshow-column option.
+ * g++.dg/parse/error-column.C: new column number test.
+
+2008-07-11 Richard Guenther <rguenther@suse.de>
+
+ PR tree-optimization/36765
+ * gcc.c-torture/execute/pr36765.c: New testcase.
+
+2008-07-10 Joseph Myers <joseph@codesourcery.com>
+
+ PR middle-end/29056
+ * gcc.target/powerpc/ppc-negeq0-1.c: Use long instead of int.
+ Adjust shift and scan-assembler-not pattern to allow for 64-bit
+ case.
+
+2008-07-10 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/36790
+ * gcc.dg/gomp/pr36790.c: New test.
+ * g++.dg/gomp/pr36790.C: New test.
+
+ PR rtl-optimization/36419
+ * g++.dg/eh/async-unwind1.C: New test.
+
+2008-07-10 Peter Maydell <pmaydell@chiark.greenend.org.uk>
+
+ PR other/28322
+ * gcc.dg/pr28322-2.c: Check that emitted diagnostic for -Wno-foobar
+ is a warning and not an error.
+
+2008-07-09 Ian Lance Taylor <iant@google.com>
+
+ * gcc.dg/no-asm-1.c: New test.
+ * gcc.dg/no-asm-2.c: New test.
+ * gcc.dg/no-asm-3.c: New test.
+ * gcc.dg/no-asm-4.c: New test.
+ * g++.dg/ext/no-asm-1.C: New test.
+ * g++.dg/ext/no-asm-2.C: New test.
+ * g++.dg/ext/no-gnu-keywords-1.C: New test.
+
+2008-07-09 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/36760
+ * g++.dg/warn/Wreturn-type-4.C: Adjust.
+
+2008-07-09 Richard Sandiford <rdsandiford@googlemail.com>
+
+ PR target/35802
+ * gcc.target/mips/pr35802.c: New test.
+
+2008-07-09 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/36760
+ * g++.dg/warn/pragma-system_header5.C: New.
+ * g++.dg/warn/pragma-system_header5.h: Likewise.
+
+2008-07-09 Raksit Ashok <raksit@google.com>
+
+ * gcc.dg/wdisallowed-functions-1.c: New test.
+ * gcc.dg/wdisallowed-functions-2.c: New test.
+ * g++.dg/warn/Wdisallowed-functions-1.C: New test.
+ * g++.dg/warn/Wdisallowed-functions-2.C: New test.
+
+2008-07-08 Simon Martin <simartin@users.sourceforge.net>
+
+ PR c++/34963
+ * g++.dg/parse/dtor13.C: New test.
+
+2008-07-07 H.J. Lu <hongjiu.lu@intel.com>
+
+ * gcc.dg/compat/struct-layout-1_generate.c (vector_types): Add
+ v32qi, v16hi, v8si, v4di, v8sf, v4df, u32qi, u16hi, u8si, u4di,
+ u8sf and u4df.
+
+ * gcc.dg/compat/union-m128-1_main.c: Run only on x86. Remove
+ __x86_64__ check. Include "cpuid.h".
+ (main): Check SSE2 at runtime.
+
+ * gcc.dg/compat/union-m128-1_x.c: Compile with -msse2. Remove
+ __x86_64__ check.
+ * gcc.dg/compat/union-m128-1_y.c: Likewise.
+
+ * gcc.dg/compat/vector-1_x.c: Add 32byte vector tests.
+ * gcc.dg/compat/vector-1_y.c: Likewise.
+ * gcc.dg/compat/vector-2_x.c: Likewise.
+ * gcc.dg/compat/vector-2_y.c: Likewise.
+
+ * gcc.dg/compat/vector-1a_main.c: New.
+ * gcc.dg/compat/vector-1a_x.c: Likewise.
+ * gcc.dg/compat/vector-1a_y.c: Likewise.
+ * gcc.dg/compat/vector-2a_main.c: Likewise.
+ * gcc.dg/compat/vector-2a_x.c: Likewise.
+ * gcc.dg/compat/vector-2a_y.c: Likewise.
+
+ * gcc.dg/compat/vector-defs.h (v32qi): New.
+ (v16hi): Likewise.
+ (v8si): Likewise.
+ (v4di): Likewise.
+ (v8sf): Likewise.
+ (v4df): Likewise.
+ (u32qi): Likewise.
+ (u16hi): Likewise.
+ (u8si): Likewise.
+ (u4di): Likewise.
+ (u8sf): Likewise.
+ (u4df): Likewise.
+
+ * lib/compat.exp (compat-get-options-main): Support dg-skip-if.
+
+2008-07-07 Andy Hutchinson <hutchinsonandy@aim.com>
+
+ * gcc.c-torture/compile/20080625-1.c: Skip for AVR target.
+ * gcc.dg/torture/pr36373-10.c: Correct test where target pointer
+ is not same size as unsigned long.
+
+2008-07-07 Thomas Koenig <tkoenig@gcc.gnu.org>
+
+ PR fortran/36670
+ * gfortran.dg/product_sum_bounds_1.f90: New test case.
+
+2008-07-07 Thomas Koenig <tkoenig@gcc.gnu.org>
+
+ PR fortran/36341
+ PR fortran/34670
+ * gfortran.dg/matmul_bounds_2.f90: New test.
+ * gfortran.dg/matmul_bounds_3.f90: New test.
+ * gfortran.dg/matmul_bounds_4.f90: New test.
+ * gfortran.dg/matmul_bounds_5.f90: New test.
+
+2008-07-07 Richard Guenther <rguenther@suse.de>
+
+ * gcc.dg/torture/pta-ptrarith-1.c: New testcase.
+ * gcc.dg/torture/pta-ptrarith-2.c: Likewise.
+ * gcc.dg/torture/ipa-pta-1.c: Likewise.
+
+2008-07-07 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/36726
+ * gfortran.dg/gomp/pr36726.f90: New test.
+
+2008-07-06 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * gcc.target/mips/gcc-have-sync-compare-and-swap-1.c: Expect the
+ macros to be defined for MIPS16 too.
+ * gcc.target/mips/gcc-have-sync-compare-and-swap-2.c: Likewise.
+ * gcc.target/mips/gcc-have-sync-compare-and-swap-3.c: New test.
+ * gcc.target/mips/gcc-have-sync-compare-and-swap-4.c: Likewise.
+
+2008-07-06 Richard Guenther <rguenther@suse.de>
+
+ * gcc.dg/tree-ssa/pta-callused.c: Adjust testcase.
+
+2008-07-06 Kai Tietz <kai.tietz@onevision.com>
+
+ * gcc.dg/callabi/callabi.h: New.
+ * gcc.dg/callabi/vaarg-1.c: New.
+ * gcc.dg/callabi/vaarg-2.c: New.
+ * gcc.dg/callabi/vaarg-3.c: New.
+ * gcc.dg/callabi/func-1.c: New.
+
+2008-07-05 Andrew Pinski <andrew_pinski@playstation.sony.com>
+
+ * g++.dg/tree-ssa/ptrmemfield.C: New testcase.
+
+2008-07-05 Joseph Myers <joseph@codesourcery.com>
+
+ * lib/gcc-dg.exp (remove-build-file): Remove files on remote host
+ as well as on build.
+
+2008-07-04 Richard Guenther <rguenther@suse.de>
+
+ * gcc.dg/tree-ssa/pta-callused.c: New testcase.
+
+2008-07-04 Richard Sandiford <richard@codesourcery.com>
+
+ * gcc.target/m68k/interrupt-2.c: New file.
+ * gcc.dg/tree-ssa/20040204-1.c: Don't XFAIL for m68k*-*-*.
+
2008-07-03 H.J. Lu <hongjiu.lu@intel.com>
* gcc.dg/compat/struct-by-value-17a_x.c: Remove duplicated code.
diff --git a/gcc/testsuite/g++.dg/conversion/op5.C b/gcc/testsuite/g++.dg/conversion/op5.C
new file mode 100644
index 00000000000..69ef996d5c2
--- /dev/null
+++ b/gcc/testsuite/g++.dg/conversion/op5.C
@@ -0,0 +1,20 @@
+// Contributed by Dodji Seketeli <dseketel@redhat.com>
+// Origin: PR c++/36407
+// { dg-do compile }
+
+struct A
+{
+ A (const A&);
+};
+
+struct B
+{
+ operator A&();
+};
+
+void
+foo (const B& b)
+{
+ const A a = b; // { dg-error "conversion from 'const B' to non-scalar type 'const A' requested" }
+}
+
diff --git a/gcc/testsuite/g++.dg/cpp0x/defaulted1.C b/gcc/testsuite/g++.dg/cpp0x/defaulted1.C
new file mode 100644
index 00000000000..e8fe37eb39a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/defaulted1.C
@@ -0,0 +1,43 @@
+// Positive test for defaulted/deleted fns
+// { dg-do run }
+// { dg-options "-std=c++0x" }
+
+struct A
+{
+ int i;
+ A() = default;
+ A(const A&) = delete;
+ A& operator=(const A&) = default;
+ ~A();
+};
+
+A::~A() = default;
+
+void f() = delete;
+
+struct B
+{
+ int i;
+ B() = default;
+};
+
+int main()
+{
+ A a1, a2;
+ B b = {1};
+ a1 = a2;
+}
+
+// fns defaulted in class defn are trivial
+struct C
+{
+ C() = default;
+ C(const C&) = default;
+ C& operator=(const C&) = default;
+ ~C() = default;
+};
+
+union U
+{
+ C c;
+};
diff --git a/gcc/testsuite/g++.dg/cpp0x/defaulted2.C b/gcc/testsuite/g++.dg/cpp0x/defaulted2.C
new file mode 100644
index 00000000000..ea06d92530f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/defaulted2.C
@@ -0,0 +1,66 @@
+// Negative test for defaulted/deleted fns.
+// { dg-options "-std=c++0x" }
+
+void f(); // { dg-error "previous" }
+void f() = delete; // { dg-error "deleted" }
+
+struct A
+{
+ A() { } // { dg-error "previous" }
+ void f() = default; // { dg-error "default" }
+};
+
+A::A() = default; // { dg-error "redefinition" }
+
+void g() {} // { dg-error "previous" }
+void g() = delete; // { dg-error "redefinition" }
+
+struct B
+{
+ B() = default;
+};
+
+const B b; // { dg-error "uninitialized const" }
+
+struct C
+{
+ virtual void f() = delete; // { dg-error "overriding deleted" }
+};
+
+struct D: public C
+{
+ virtual void f(); // { dg-error "non-deleted function" }
+};
+
+struct E
+{
+ const B b;
+ E() { } // { dg-error "uninitialized" }
+};
+
+struct F
+{
+ F() = default;
+ F(const F&) = delete; // { dg-error "deleted" }
+};
+
+struct G
+{
+ G();
+};
+
+// ctor defaulted after class defn is not trivial
+G::G() = default;
+
+union U
+{
+ G g; // { dg-error "constructor" }
+};
+
+int main()
+{
+ F f;
+ F f2(f); // { dg-error "used" }
+ B* b = new const B; // { dg-error "uninitialized const" }
+}
+
diff --git a/gcc/testsuite/g++.dg/eh/async-unwind1.C b/gcc/testsuite/g++.dg/eh/async-unwind1.C
new file mode 100644
index 00000000000..69b2c345e75
--- /dev/null
+++ b/gcc/testsuite/g++.dg/eh/async-unwind1.C
@@ -0,0 +1,61 @@
+// PR rtl-optimization/36419
+// { dg-do run { target { { i?86-*-* x86_64-*-* } && ilp32 } } }
+// { dg-options "-Os -fasynchronous-unwind-tables -mpreferred-stack-boundary=4" }
+
+extern "C" void abort ();
+
+int v = -1;
+unsigned int n;
+
+__attribute__((noinline, used))
+void foo (int a, int)
+{
+ if (v < 0)
+ v = ((unsigned long) &a) & 15;
+ else if ((((unsigned long) &a) & 15) != v)
+ abort ();
+ if (n++ == 0)
+ throw 1;
+}
+
+__attribute__((noinline, used))
+void baz (int a, int, int, int, int, int, int)
+{
+ if (v < 0)
+ v = ((unsigned long) &a) & 15;
+ else if ((((unsigned long) &a) & 15) != v)
+ abort ();
+ if (n++ == 0)
+ throw 1;
+}
+
+struct A { A () { }; ~A (); char c[24]; };
+
+__attribute__((noinline))
+A::~A ()
+{
+ asm volatile ("" : : : "memory");
+}
+
+__attribute__((noinline))
+void bar ()
+{
+ A a;
+ try
+ {
+ foo (1, 2);
+ baz (3, 4, 5, 6, 7, 8, 9);
+ }
+ catch (...)
+ {
+ }
+ foo (1, 2);
+ baz (3, 4, 5, 6, 7, 8, 9);
+}
+
+int
+main ()
+{
+ bar ();
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/ext/has_nothrow_assign.C b/gcc/testsuite/g++.dg/ext/has_nothrow_assign.C
index 525cac7aa48..73a904eac25 100644
--- a/gcc/testsuite/g++.dg/ext/has_nothrow_assign.C
+++ b/gcc/testsuite/g++.dg/ext/has_nothrow_assign.C
@@ -136,19 +136,13 @@ int main()
assert (PTEST (C));
assert (NTEST (C[]));
assert (PTEST (D));
-#ifndef __PIC__
- assert (PTEST (E));
-#endif
+ assert (NTEST (E));
assert (NTEST (E1));
assert (PTEST (F));
assert (PTEST (G));
-#ifndef __PIC__
- assert (PTEST (H));
-#endif
+ assert (NTEST (H));
assert (NTEST (H1));
-#ifndef __PIC__
- assert (PTEST (I));
-#endif
+ assert (NTEST (I));
assert (NTEST (I1));
assert (PTEST (J));
assert (NTEST (const K));
diff --git a/gcc/testsuite/g++.dg/ext/has_nothrow_assign_odr.C b/gcc/testsuite/g++.dg/ext/has_nothrow_assign_odr.C
new file mode 100644
index 00000000000..c38d76d44a6
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/has_nothrow_assign_odr.C
@@ -0,0 +1,16 @@
+// PR c++/36870
+// { dg-do "run" }
+#include <cassert>
+
+struct S { const S& operator= (const S&); };
+
+bool f ();
+
+int main ()
+{
+ assert (__has_nothrow_assign (S) == f ());
+}
+
+const S& S::operator= (const S&) { }
+
+bool f () { return __has_nothrow_assign (S); }
diff --git a/gcc/testsuite/g++.dg/ext/has_nothrow_constructor.C b/gcc/testsuite/g++.dg/ext/has_nothrow_constructor.C
index 7e747bcd11e..60e9be8d0be 100644
--- a/gcc/testsuite/g++.dg/ext/has_nothrow_constructor.C
+++ b/gcc/testsuite/g++.dg/ext/has_nothrow_constructor.C
@@ -97,9 +97,7 @@ int main()
assert (PTEST (C));
assert (PTEST (C[]));
assert (PTEST (D));
-#ifndef __PIC__
- assert (PTEST (E));
-#endif
+ assert (NTEST (E));
assert (NTEST (E1));
assert (NTEST (F));
assert (NTEST (G));
diff --git a/gcc/testsuite/g++.dg/ext/has_nothrow_constructor_odr.C b/gcc/testsuite/g++.dg/ext/has_nothrow_constructor_odr.C
new file mode 100644
index 00000000000..775e74a2631
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/has_nothrow_constructor_odr.C
@@ -0,0 +1,16 @@
+// PR c++/36870
+// { dg-do "run" }
+#include <cassert>
+
+struct S { S (); };
+
+bool f ();
+
+int main ()
+{
+ assert (__has_nothrow_constructor (S) == f ());
+}
+
+S::S () { }
+
+bool f () { return __has_nothrow_constructor (S); }
diff --git a/gcc/testsuite/g++.dg/ext/has_nothrow_copy.C b/gcc/testsuite/g++.dg/ext/has_nothrow_copy-1.C
index 6843d51b4c4..e8507cf582c 100644
--- a/gcc/testsuite/g++.dg/ext/has_nothrow_copy.C
+++ b/gcc/testsuite/g++.dg/ext/has_nothrow_copy-1.C
@@ -126,19 +126,13 @@ int main()
assert (PTEST (C));
assert (NTEST (C[]));
assert (PTEST (D));
-#ifndef __PIC__
- assert (PTEST (E));
-#endif
+ assert (NTEST (E));
assert (NTEST (E1));
assert (PTEST (F));
assert (PTEST (G));
-#ifndef __PIC__
- assert (PTEST (H));
-#endif
+ assert (NTEST (H));
assert (NTEST (H1));
-#ifndef __PIC__
- assert (PTEST (I));
-#endif
+ assert (NTEST (I));
assert (NTEST (I1));
assert (PTEST (J));
diff --git a/gcc/testsuite/g++.dg/ext/has_nothrow_copy-2.C b/gcc/testsuite/g++.dg/ext/has_nothrow_copy-2.C
new file mode 100644
index 00000000000..276b11d574c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/has_nothrow_copy-2.C
@@ -0,0 +1,12 @@
+// PR c++/36871
+// { dg-do "run" }
+#include <cassert>
+
+struct A { template <class T> A (T) throw (int); };
+struct B { B (B&) throw (); template <class T> B (T) throw (int); };
+
+int main ()
+{
+ assert (__has_nothrow_copy (A));
+ assert (__has_nothrow_copy (B));
+}
diff --git a/gcc/testsuite/g++.dg/ext/has_nothrow_copy-3.C b/gcc/testsuite/g++.dg/ext/has_nothrow_copy-3.C
new file mode 100644
index 00000000000..2fbcf8c8096
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/has_nothrow_copy-3.C
@@ -0,0 +1,13 @@
+// PR c++/36871
+// { dg-do "run" }
+#include <cassert>
+
+struct F {
+ F (const F&) throw () { }
+ template <class T> F (T) throw () { }
+};
+
+int main ()
+{
+ assert (__has_nothrow_copy (F));
+}
diff --git a/gcc/testsuite/g++.dg/ext/has_nothrow_copy-4.C b/gcc/testsuite/g++.dg/ext/has_nothrow_copy-4.C
new file mode 100644
index 00000000000..4bd7475ea7c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/has_nothrow_copy-4.C
@@ -0,0 +1,13 @@
+// PR c++/36872
+// { dg-do "run" }
+#include <cassert>
+
+struct S {
+ S (const S&) throw ();
+ S (...) throw (int);
+};
+
+int main ()
+{
+ assert (__has_nothrow_copy (S));
+}
diff --git a/gcc/testsuite/g++.dg/ext/has_nothrow_copy-5.C b/gcc/testsuite/g++.dg/ext/has_nothrow_copy-5.C
new file mode 100644
index 00000000000..051675c4d00
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/has_nothrow_copy-5.C
@@ -0,0 +1,13 @@
+// PR c++/36872
+// { dg-do "run" }
+#include <cassert>
+
+struct S {
+ S (const S&) throw ();
+ S (int) throw (int);
+};
+
+int main ()
+{
+ assert (__has_nothrow_copy (S));
+}
diff --git a/gcc/testsuite/g++.dg/ext/has_nothrow_copy-6.C b/gcc/testsuite/g++.dg/ext/has_nothrow_copy-6.C
new file mode 100644
index 00000000000..4330edd2941
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/has_nothrow_copy-6.C
@@ -0,0 +1,12 @@
+// { dg-do "run" }
+#include <cassert>
+
+struct S {
+ S (S&) throw ();
+ S (const S&, int) throw (int);
+};
+
+int main ()
+{
+ assert (__has_nothrow_copy (S));
+}
diff --git a/gcc/testsuite/g++.dg/ext/has_nothrow_copy-7.C b/gcc/testsuite/g++.dg/ext/has_nothrow_copy-7.C
new file mode 100644
index 00000000000..a85224c3abc
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/has_nothrow_copy-7.C
@@ -0,0 +1,13 @@
+// { dg-do "run" }
+// { dg-options "-std=c++0x" }
+#include <cassert>
+
+struct S {
+ S (const S&) throw ();
+ S (S&&) throw (int);
+};
+
+int main ()
+{
+ assert (__has_nothrow_copy (S));
+}
diff --git a/gcc/testsuite/g++.dg/ext/has_nothrow_copy_odr.C b/gcc/testsuite/g++.dg/ext/has_nothrow_copy_odr.C
new file mode 100644
index 00000000000..499a11e25be
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/has_nothrow_copy_odr.C
@@ -0,0 +1,16 @@
+// PR c++/36870
+// { dg-do "run" }
+#include <cassert>
+
+struct S { S (const S&); };
+
+bool f ();
+
+int main ()
+{
+ assert (__has_nothrow_copy (S) == f ());
+}
+
+S::S (const S&) { }
+
+bool f () { return __has_nothrow_copy (S); }
diff --git a/gcc/testsuite/g++.dg/ext/has_trivial_destructor.C b/gcc/testsuite/g++.dg/ext/has_trivial_destructor-1.C
index 719f05fd7a5..719f05fd7a5 100644
--- a/gcc/testsuite/g++.dg/ext/has_trivial_destructor.C
+++ b/gcc/testsuite/g++.dg/ext/has_trivial_destructor-1.C
diff --git a/gcc/testsuite/g++.dg/ext/has_trivial_destructor-2.C b/gcc/testsuite/g++.dg/ext/has_trivial_destructor-2.C
new file mode 100644
index 00000000000..f9dacf179e1
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/has_trivial_destructor-2.C
@@ -0,0 +1,3 @@
+// PR c++/36855
+
+typedef char assert_0 [__has_trivial_destructor (int&) ? 1 : -1];
diff --git a/gcc/testsuite/g++.dg/ext/no-asm-1.C b/gcc/testsuite/g++.dg/ext/no-asm-1.C
new file mode 100644
index 00000000000..6c4c2043959
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/no-asm-1.C
@@ -0,0 +1,10 @@
+// { dg-do compile }
+// { dg-options "" }
+
+// Verify that asm and the GNU extension typeof are recognized as
+// keywords.
+
+int asm; // { dg-error "before .asm." }
+int typeof; // { dg-error "expected" }
+// { dg-error "multiple types" "" { target *-*-* } 8 }
+// { dg-error "declaration" "" { target *-*-* } 8 }
diff --git a/gcc/testsuite/g++.dg/ext/no-asm-2.C b/gcc/testsuite/g++.dg/ext/no-asm-2.C
new file mode 100644
index 00000000000..fa614d8e24e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/no-asm-2.C
@@ -0,0 +1,10 @@
+// { dg-do compile }
+// { dg-options "-fno-asm" }
+
+// Verify that the keyword asm and the GNU extension typeof are not
+// recognized as keywords when using -fno-asm. Having -fno-asm affect
+// a standard C++ keyword seems strange, but that is existing
+// behaviour. If that behaviour changes, this test should change.
+
+int asm; // { dg-bogus "before .asm." }
+int typeof; // { dg-bogus "before .typeof." }
diff --git a/gcc/testsuite/g++.dg/ext/no-gnu-keywords-1.C b/gcc/testsuite/g++.dg/ext/no-gnu-keywords-1.C
new file mode 100644
index 00000000000..8dbbd5f3482
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/no-gnu-keywords-1.C
@@ -0,0 +1,9 @@
+// { dg-do compile }
+// { dg-options "-fno-gnu-keywords" }
+
+// Verify that the keyword asm is recognized and that the GNU
+// extension typeof is not recognized as a keyword when using
+// -fno-gnu-keywords.
+
+int asm; // { dg-error "before .asm." }
+int typeof; // { dg-bogus "before .typeof." }
diff --git a/gcc/testsuite/g++.dg/ext/utf-array-short-wchar.C b/gcc/testsuite/g++.dg/ext/utf-array-short-wchar.C
new file mode 100644
index 00000000000..43ae508d64d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/utf-array-short-wchar.C
@@ -0,0 +1,36 @@
+/* Contributed by Kris Van Hees <kris.van.hees@oracle.com> */
+/* Expected errors for char16_t/char32_t string literals. */
+/* { dg-do compile } */
+/* { dg-options "-std=c++0x -fshort-wchar" } */
+
+const char s_0[] = "ab";
+const char s_1[] = u"ab"; /* { dg-error "from wide string" } */
+const char s_2[] = U"ab"; /* { dg-error "from wide string" } */
+const char s_3[] = L"ab"; /* { dg-error "from wide string" } */
+
+const char16_t s16_0[] = "ab"; /* { dg-error "from non-wide" } */
+const char16_t s16_1[] = u"ab";
+const char16_t s16_2[] = U"ab"; /* { dg-error "from incompatible" } */
+const char16_t s16_3[] = L"ab"; /* { dg-error "from incompatible" } */
+
+const char16_t s16_4[0] = u"ab"; /* { dg-warning "chars is too long" } */
+const char16_t s16_5[1] = u"ab"; /* { dg-warning "chars is too long" } */
+const char16_t s16_6[2] = u"ab"; /* { dg-warning "chars is too long" } */
+const char16_t s16_7[3] = u"ab";
+const char16_t s16_8[4] = u"ab";
+
+const char32_t s32_0[] = "ab"; /* { dg-error "from non-wide" } */
+const char32_t s32_1[] = u"ab"; /* { dg-error "from incompatible" } */
+const char32_t s32_2[] = U"ab";
+const char32_t s32_3[] = L"ab"; /* { dg-error "from incompatible" } */
+
+const char32_t s32_4[0] = U"ab"; /* { dg-warning "chars is too long" } */
+const char32_t s32_5[1] = U"ab"; /* { dg-warning "chars is too long" } */
+const char32_t s32_6[2] = U"ab"; /* { dg-warning "chars is too long" } */
+const char32_t s32_7[3] = U"ab";
+const char32_t s32_8[4] = U"ab";
+
+const wchar_t sw_0[] = "ab"; /* { dg-error "from non-wide" } */
+const wchar_t sw_1[] = u"ab"; /* { dg-error "from incompatible" } */
+const wchar_t sw_2[] = U"ab"; /* { dg-error "from incompatible" } */
+const wchar_t sw_3[] = L"ab";
diff --git a/gcc/testsuite/g++.dg/ext/utf-array.C b/gcc/testsuite/g++.dg/ext/utf-array.C
new file mode 100644
index 00000000000..65d8453d99d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/utf-array.C
@@ -0,0 +1,36 @@
+/* Contributed by Kris Van Hees <kris.van.hees@oracle.com> */
+/* Expected errors for char16_t/char32_t string literals. */
+/* { dg-do compile } */
+/* { dg-options "-std=c++0x" } */
+
+const char s_0[] = "ab";
+const char s_1[] = u"ab"; /* { dg-error "from wide string" } */
+const char s_2[] = U"ab"; /* { dg-error "from wide string" } */
+const char s_3[] = L"ab"; /* { dg-error "from wide string" } */
+
+const char16_t s16_0[] = "ab"; /* { dg-error "from non-wide" } */
+const char16_t s16_1[] = u"ab";
+const char16_t s16_2[] = U"ab"; /* { dg-error "from incompatible" } */
+const char16_t s16_3[] = L"ab"; /* { dg-error "from incompatible" } */
+
+const char16_t s16_4[0] = u"ab"; /* { dg-warning "chars is too long" } */
+const char16_t s16_5[1] = u"ab"; /* { dg-warning "chars is too long" } */
+const char16_t s16_6[2] = u"ab"; /* { dg-warning "chars is too long" } */
+const char16_t s16_7[3] = u"ab";
+const char16_t s16_8[4] = u"ab";
+
+const char32_t s32_0[] = "ab"; /* { dg-error "from non-wide" } */
+const char32_t s32_1[] = u"ab"; /* { dg-error "from incompatible" } */
+const char32_t s32_2[] = U"ab";
+const char32_t s32_3[] = L"ab"; /* { dg-error "from incompatible" } */
+
+const char32_t s32_4[0] = U"ab"; /* { dg-warning "chars is too long" } */
+const char32_t s32_5[1] = U"ab"; /* { dg-warning "chars is too long" } */
+const char32_t s32_6[2] = U"ab"; /* { dg-warning "chars is too long" } */
+const char32_t s32_7[3] = U"ab";
+const char32_t s32_8[4] = U"ab";
+
+const wchar_t sw_0[] = "ab"; /* { dg-error "from non-wide" } */
+const wchar_t sw_1[] = u"ab"; /* { dg-error "from incompatible" } */
+const wchar_t sw_2[] = U"ab"; /* { dg-error "from incompatible" } */
+const wchar_t sw_3[] = L"ab";
diff --git a/gcc/testsuite/g++.dg/ext/utf-rtti.C b/gcc/testsuite/g++.dg/ext/utf-rtti.C
new file mode 100644
index 00000000000..b5d201b4d7a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/utf-rtti.C
@@ -0,0 +1,12 @@
+/* Contributed by Kris Van Hees <kris.van.hees@oracle.com> */
+/* Ensure that typeinfo data is generated for char16_t/char32_t. */
+/* { dg-do link } */
+/* { dg-options "-std=c++0x" } */
+
+#include <typeinfo>
+
+int main(void)
+{
+ typeid(char16_t).name();
+ typeid(char32_t).name();
+}
diff --git a/gcc/testsuite/g++.dg/ext/utf-type.C b/gcc/testsuite/g++.dg/ext/utf-type.C
new file mode 100644
index 00000000000..41a83ff2ef0
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/utf-type.C
@@ -0,0 +1,15 @@
+/* Contributed by Kris Van Hees <kris.van.hees@oracle.com> */
+/* Ensure that __CHAR16_TYPE__ and __CHAR32_TYPE__ exist, match the types they
+ are the underlying data type for. */
+/* { dg-do run } */
+/* { dg-options "-std=c++0x -Wall -Werror" } */
+
+extern "C" void abort (void);
+
+int main ()
+{
+ if (sizeof (__CHAR16_TYPE__) != sizeof (char16_t))
+ abort();
+ if (sizeof (__CHAR32_TYPE__) != sizeof (char32_t))
+ abort();
+}
diff --git a/gcc/testsuite/g++.dg/ext/visibility/arm1.C b/gcc/testsuite/g++.dg/ext/visibility/arm1.C
index 8b4949492a1..2c2e3d0664a 100644
--- a/gcc/testsuite/g++.dg/ext/visibility/arm1.C
+++ b/gcc/testsuite/g++.dg/ext/visibility/arm1.C
@@ -1,4 +1,5 @@
// { dg-do compile { target arm*-*-eabi* arm*-*-symbianelf* } }
+// { dg-require-dll "" }
// { dg-options "-fvisibility=hidden" }
// Most class data should be exported.
// { dg-final { scan-not-hidden "_ZTV1S" } }
diff --git a/gcc/testsuite/g++.dg/ext/visibility/arm3.C b/gcc/testsuite/g++.dg/ext/visibility/arm3.C
index f97813d7f21..9be7082ce1d 100644
--- a/gcc/testsuite/g++.dg/ext/visibility/arm3.C
+++ b/gcc/testsuite/g++.dg/ext/visibility/arm3.C
@@ -1,6 +1,30 @@
// { dg-do compile { target arm*-*-*eabi* } }
+// { dg-require-dll "" }
// { dg-options "-fvisibility=hidden" }
-// Class data should be exported.
+
+/* From ARM C++ ABI \S 3.2.5.5:
+
+ A class should be exported unless explicitly tagged otherwise.
+
+ This admonition applies even on DLL-based systems where hidden
+ visibility is the default. We want -fvisibility=hidden to behave
+ identically to the situation where hidden visibility is the
+ hard-wired default. So, both A and B are exported classes.
+
+ Furthermore:
+
+ If CAG symbol Y names one of the impedimenta associated with an
+ exported class X:
+
+ ...
+
+ * Otherwise, if X has no key function:
+
+ - Y is exported from ... each DLL that refers to X and uses Y.
+
+ So, the type-info and virtual-table symbols associated with A and B
+ must be exported. */
+
// { dg-final { scan-not-hidden "_ZTI1A" } }
// { dg-final { scan-not-hidden "_ZTS1A" } }
// { dg-final { scan-not-hidden "_ZTV1B" } }
diff --git a/gcc/testsuite/g++.dg/gomp/pr36790.C b/gcc/testsuite/g++.dg/gomp/pr36790.C
new file mode 100644
index 00000000000..07e8b105252
--- /dev/null
+++ b/gcc/testsuite/g++.dg/gomp/pr36790.C
@@ -0,0 +1,23 @@
+// PR middle-end/36790
+// { dg-do compile }
+// { dg-options "-fopenmp -O2" }
+
+void
+foo (bool b)
+{
+}
+
+void
+bar (bool b)
+{
+ foo (b);
+ #pragma omp task default (shared)
+ b = false;
+}
+
+int
+main ()
+{
+ bar (false);
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/inherit/thunk8.C b/gcc/testsuite/g++.dg/inherit/thunk8.C
index f7761349f8e..ef645356898 100644
--- a/gcc/testsuite/g++.dg/inherit/thunk8.C
+++ b/gcc/testsuite/g++.dg/inherit/thunk8.C
@@ -3,7 +3,7 @@
Make sure that won't happen anymore. */
/* { dg-do compile } */
-/* { dg-require-effective-target arm32 } */
+/* { dg-require-effective-target arm_thumb1_ok } */
/* { dg-options "-mthumb -fPIC" } */
struct A {
diff --git a/gcc/testsuite/g++.dg/ipa/iinline-1.C b/gcc/testsuite/g++.dg/ipa/iinline-1.C
new file mode 100644
index 00000000000..be3be71f96a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ipa/iinline-1.C
@@ -0,0 +1,47 @@
+/* Verify that simple indirect calls are inlined even without early
+ inlining.. */
+/* { dg-do compile } */
+/* { dg-options "-O3 -c -fdump-ipa-inline -fno-early-inlining" } */
+
+extern void non_existent (const char *, int);
+
+class String
+{
+private:
+ const char *data;
+
+public:
+ String (const char *d) : data(d)
+ {}
+
+ int funcOne (int delim) const;
+ int printStuffTwice (int delim) const;
+};
+
+
+int String::funcOne (int delim) const
+{
+ int i;
+ for (i = 0; i < delim; i++)
+ non_existent(data, i);
+
+ return 1;
+}
+
+int docalling (int (String::* f)(int delim) const)
+{
+ String S ("muhehehe");
+
+ return (S.*f)(4);
+}
+
+int main (int argc, char *argv[])
+{
+ int i;
+ i = docalling (&String::funcOne);
+ non_existent ("done", i);
+ return 0;
+}
+
+/* { dg-final { scan-ipa-dump "String::funcOne\[^\\n\]*inline copy in int main" "inline" } } */
+/* { dg-final { cleanup-tree-dump "inline" } } */
diff --git a/gcc/testsuite/g++.dg/lookup/extern-c-redecl.C b/gcc/testsuite/g++.dg/lookup/extern-c-redecl.C
new file mode 100644
index 00000000000..31d100a74f9
--- /dev/null
+++ b/gcc/testsuite/g++.dg/lookup/extern-c-redecl.C
@@ -0,0 +1,11 @@
+// Contributed by Dodji Seketeli <dseketel@redhat.com>
+// Origin: PR c++/13699
+// { dg-do compile }
+
+namespace A {
+ extern "C" void foo_func () throw(); // { dg-error "conflicts" }
+}
+// next line should trigger an error because
+// it conflicts with previous declaration of foo_func (), due to
+// different exception specifications.
+extern "C" void foo_func (); // { dg-error "C language|exception specifications" }
diff --git a/gcc/testsuite/g++.dg/other/pr36944.C b/gcc/testsuite/g++.dg/other/pr36944.C
new file mode 100644
index 00000000000..b4a1dfa46fd
--- /dev/null
+++ b/gcc/testsuite/g++.dg/other/pr36944.C
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+
+class XObject
+{
+public:
+ int foo;
+};
+
+class XObjectPtr
+{
+public:
+ explicit
+ XObjectPtr(XObject* theXObject = 0) : m_xobjectPtr(theXObject)
+ {
+ }
+
+private:
+ XObject * m_xobjectPtr;
+};
+
+class SelectionEvent
+{
+public:
+ SelectionEvent(bool selection) : m_selection() {}
+ const XObjectPtr m_selection;
+};
diff --git a/gcc/testsuite/g++.dg/other/semicolon.C b/gcc/testsuite/g++.dg/other/semicolon.C
index 6bc3d95217b..542d3b7b554 100644
--- a/gcc/testsuite/g++.dg/other/semicolon.C
+++ b/gcc/testsuite/g++.dg/other/semicolon.C
@@ -1,9 +1,10 @@
// PR c++/18368
// Origin: Chris Lattner <sabre@nondot.org>
// { dg-do compile }
+// { dg-options "-fshow-column" }
struct A
{
- struct B { int i; }
- void foo(); // { dg-error "two or more|return type" }
-}; // { dg-error "semicolon is missing" "" { target *-*-* } 8 }
+ struct B { int i; } // { dg-error "3: error: new types may not be defined in a return type|note: \\(perhaps a semicolon is missing" }
+ void foo(); // { dg-error "12: error: two or more|return type" }
+};
diff --git a/gcc/testsuite/g++.dg/parse/constructor1.C b/gcc/testsuite/g++.dg/parse/constructor1.C
index 3011862ffbc..8f222f80b10 100644
--- a/gcc/testsuite/g++.dg/parse/constructor1.C
+++ b/gcc/testsuite/g++.dg/parse/constructor1.C
@@ -1,4 +1,7 @@
+// { dg-do compile }
+// { dg-options "-fshow-column" }
+
ACE_Process_Descriptor::ACE_Process_Descriptor () : // { dg-error "" }
- process_ (0)
+ process_ (0) // { dg-error "3: error: only constructors take base initializers" }
{
}
diff --git a/gcc/testsuite/g++.dg/parse/crash27.C b/gcc/testsuite/g++.dg/parse/crash27.C
index 069436666d3..217928781d3 100644
--- a/gcc/testsuite/g++.dg/parse/crash27.C
+++ b/gcc/testsuite/g++.dg/parse/crash27.C
@@ -1,5 +1,4 @@
// Bug: 23225
void Dispatcher()
- (__builtin_offsetof (ArgsType, largeMsgLen))
- /* { dg-error "function " "function" { target *-*-* } 4 } */
+ (__builtin_offsetof (ArgsType, largeMsgLen)) // { dg-error "initialize|end of input" }
diff --git a/gcc/testsuite/g++.dg/parse/dtor13.C b/gcc/testsuite/g++.dg/parse/dtor13.C
new file mode 100644
index 00000000000..66cd5f7f34c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/parse/dtor13.C
@@ -0,0 +1,8 @@
+/* PR c++/34963 This used to ICE */
+/* { dg-do "compile" } */
+
+struct A
+{
+ static friend A::~A(); /* { dg-error "storage class specifiers|extra qualification|implicitly friend" } */
+};
+
diff --git a/gcc/testsuite/g++.dg/parse/error-column.C b/gcc/testsuite/g++.dg/parse/error-column.C
new file mode 100644
index 00000000000..812a499ff4d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/parse/error-column.C
@@ -0,0 +1,9 @@
+// { dg-do compile }
+// Make sure column information is correctly shown in error reporting
+// { dg-options "-fshow-column" }
+
+
+void foo ()
+{
+ cout << "blah"; // { dg-error "3: error: 'cout'" }
+}
diff --git a/gcc/testsuite/g++.dg/parse/error1.C b/gcc/testsuite/g++.dg/parse/error1.C
index 8756df64592..60e7d6587b3 100644
--- a/gcc/testsuite/g++.dg/parse/error1.C
+++ b/gcc/testsuite/g++.dg/parse/error1.C
@@ -1,6 +1,7 @@
+// { dg-options "-fshow-column" }
struct INCOMPLETE;
template <int> struct X {
static INCOMPLETE value;
};
-template <> INCOMPLETE X<1>::value = 0; // { dg-error "" }
+template <> INCOMPLETE X<1>::value = 0; // { dg-error "30: error: variable 'INCOMPLETE X<1>::value' has initializer but incomplete type" }
diff --git a/gcc/testsuite/g++.dg/parse/error10.C b/gcc/testsuite/g++.dg/parse/error10.C
index 242c421c463..6e46922a115 100644
--- a/gcc/testsuite/g++.dg/parse/error10.C
+++ b/gcc/testsuite/g++.dg/parse/error10.C
@@ -1,5 +1,5 @@
// PR c++/3478
-// { dg-options "" }
+// { dg-options "-fshow-column" }
template <typename> struct A
{
@@ -11,5 +11,9 @@ template <typename T> void foo()
enum A<void>::E e1;
typename A<T>::E e2;
enum A<T>::E e3;
- enum typename A<T>::E e4; // { dg-error "" }
+ enum typename A<T>::E e4;
}
+
+// Here, columns nums are not very accurate either. Still acceptable though
+// { dg-error "30: error: invalid type in declaration before ';' token" "" { target *-*-* } { 14 } }
+// { dg-error "30: error: two or more data types in declaration of 'e4'" "" { target *-*-* } { 14 } }
diff --git a/gcc/testsuite/g++.dg/parse/error11.C b/gcc/testsuite/g++.dg/parse/error11.C
index 0a8e2e4fc3d..f7093a8f987 100644
--- a/gcc/testsuite/g++.dg/parse/error11.C
+++ b/gcc/testsuite/g++.dg/parse/error11.C
@@ -1,4 +1,5 @@
// { dg-do compile }
+// { dg-options "-fshow-column" }"
// Origin: Giovanni Bajo <giovannibajo at gcc dot gnu dot org>
// Try to find out when the digraph '<:' is used as a mistake, and parse it
// correctly to avoid cascaded errors.
@@ -15,16 +16,16 @@ struct Foo
};
void method(void) {
- typename Foo<::B>::template Nested<::B> n; // { dg-error "cannot begin|alternate spelling" }
+ typename Foo<::B>::template Nested<::B> n; // { dg-error "17: error: '<::' cannot begin|17: note: '<:' is an alternate spelling|39: error: '<::' cannot begin|39: note: '<:' is an alternate" }
n.template Nested<B>::method();
- n.template Nested<::B>::method(); // { dg-error "cannot begin|alternate spelling" }
+ n.template Nested<::B>::method(); // { dg-error "22: error: '<::' cannot begin|22: note: '<:' is an alternate" }
Nested<B>::method();
- Nested<::B>::method(); // { dg-error "cannot begin|alternate spelling" }
+ Nested<::B>::method(); // { dg-error "11: error: '<::' cannot begin|11: note: '<:' is an alternate" }
}
};
template <int N> struct Foo2 {};
-template struct Foo2<::B>; // { dg-error "cannot begin|alternate spelling|type/value mismatch|expected a constant" }
+template struct Foo2<::B>; // { dg-error "21: error: '<::' cannot begin|21: note: '<:' is an alternate|25: error: type/value mismatch|25: error: expected a constant" }
int value = 0;
@@ -32,22 +33,28 @@ void func(void)
{
Foo<::B> f; // { dg-error "cannot begin|alternate spelling" }
f.Foo<B>::method();
- f.Foo<::B>::method(); // { dg-error "cannot begin|alternate spelling" }
+ f.Foo<::B>::method(); // { dg-error "8: error|8: note" }
// Check cases where we the token sequence is the correct one, but there
// was no digraph or whitespaces in the middle, so we should not emit
// the special error message.
Foo<: :B> k2; // { dg-bogus "cannot begin|alternate spelling" "smart error should not be triggered here" }
Foo[:B> k1; // { dg-bogus "cannot begin|alternate spelling" "smart error should not be triggered here" }
-// { dg-error "" "" { target *-*-* } 40 }
-// { dg-error "" "" { target *-*-* } 41 }
-
+// { dg-error "6: error: missing template arguments before" "" { target *-*-* } { 41 } }
+// { dg-error "9: error: expected primary-expression before ':' token" "" { target *-*-* } 41 }
+// { dg-error "9: error: expected '\]' before ':' token" "" { target *-*-* } 41 }
+// { dg-error "9: error: expected ';' before ':' token" "" { target *-*-* } 41 }
+// { dg-error "6: error: missing template arguments before" "" { target *-*-* } 42 }
+// { dg-error "7: error: expected primary-expression before ':' token" "" { target *-*-* } 42 }
+// { dg-error "7: error: expected '\]' before ':' token" "" { target *-*-* } 42 }
+// { dg-error "7: error: expected ';' before ':' token" "" { target *-*-* } 42 }
+//
int Foo[2];
Foo[::value] = 0;
}
-template struct Foo<::B>; // { dg-error "cannot begin|alternate spelling" }
+template struct Foo<::B>; // { dg-error "20: error: '<::' cannot begin|20: note: '<:' is an alternate" }
// On the first error message, an additional note about the use of
// -fpermissive should be present
-// { dg-error "-fpermissive" "-fpermissive" { target *-*-* } 18 }
+// { dg-error "17: note: \\(if you use '-fpermissive' G\\+\\+ will accept your code\\)" "-fpermissive" { target *-*-* } 19 }
diff --git a/gcc/testsuite/g++.dg/parse/error12.C b/gcc/testsuite/g++.dg/parse/error12.C
index ea04fd06d11..b0025885bf4 100644
--- a/gcc/testsuite/g++.dg/parse/error12.C
+++ b/gcc/testsuite/g++.dg/parse/error12.C
@@ -1,7 +1,7 @@
// { dg-do compile }
// Origin: Giovanni Bajo <giovannibajo at gcc dot gnu dot org>
// Make sure the error about '<:' can be turned into a warning
-// { dg-options "-fpermissive" }
+// { dg-options "-fpermissive -fshow-column" }
struct B;
@@ -9,4 +9,5 @@ template <class A>
struct Foo {};
Foo<::B> foo; // { dg-bogus "error" "error in place of warning" }
-// { dg-error "" "" { target *-*-* } 11 }
+// { dg-error "4: warning: '<::' cannot begin a template-argument list" "warning <::" { target *-*-* } 11 }
+// { dg-error "4: note: '<:' is an alternate spelling for '.'. Insert whitespace between '<' and '::'" "note <:" { target *-*-* } 11 }
diff --git a/gcc/testsuite/g++.dg/parse/error13.C b/gcc/testsuite/g++.dg/parse/error13.C
index 15642e39ed7..94ddae89705 100644
--- a/gcc/testsuite/g++.dg/parse/error13.C
+++ b/gcc/testsuite/g++.dg/parse/error13.C
@@ -1,13 +1,14 @@
+// { dg-options "-fshow-column" }
// PR c++/13975
-public: // { dg-error "" }
+public: // { dg-error "1: error: expected unqualified-id before 'public'" }
int i;
-protected: // { dg-error "" }
+protected: // { dg-error "1: error: expected unqualified-id before 'protected'" }
int j;
-private: // { dg-error "" }
+private: // { dg-error "1: error: expected unqualified-id before 'private'" }
int k;
diff --git a/gcc/testsuite/g++.dg/parse/error14.C b/gcc/testsuite/g++.dg/parse/error14.C
index 4b230453867..906b98f87e2 100644
--- a/gcc/testsuite/g++.dg/parse/error14.C
+++ b/gcc/testsuite/g++.dg/parse/error14.C
@@ -1,3 +1,4 @@
+// { dg-options "-fshow-column" }
// PR c++/13970
struct X
@@ -18,5 +19,5 @@ struct X
Zinc<int>( //);
// }
-}; // { dg-error "" }
+}; // { dg-error "2: error: expected '.' at end of input|1: error: expected primary-expression before '.' token|1: error: expected ';' before '.' token|1: error: expected unqualified-id at end of input" }
diff --git a/gcc/testsuite/g++.dg/parse/error15.C b/gcc/testsuite/g++.dg/parse/error15.C
index b343970336f..5d30b554369 100644
--- a/gcc/testsuite/g++.dg/parse/error15.C
+++ b/gcc/testsuite/g++.dg/parse/error15.C
@@ -1,5 +1,6 @@
// { dg-do compile }
// Contributed by Volker Reichelt <reichelt at gcc dot gnu dot org>
+// { dg-options "-fshow-column" }
// PR c++/14008: Improve diagnostic on invalid types in declarators.
namespace N
@@ -9,29 +10,29 @@ namespace N
int K;
}
-N::A f2; // { dg-error "without an argument list" }
-N::INVALID f3; // { dg-error "in namespace 'N' does not name a type" }
-N::C::INVALID f4; // { dg-error "in class 'N::C' does not name a type" }
-N::K f6; // { dg-error "in namespace 'N' does not name a type" }
-typename N::A f7; // { dg-error "without an argument list|outside of template" }
+N::A f2; // { dg-error "1: error: invalid use of template-name 'N::A' without an argument list" }
+N::INVALID f3; // { dg-error "1: error: 'INVALID' in namespace 'N' does not name a type" }
+N::C::INVALID f4; // { dg-error "1: error: 'INVALID' in class 'N::C' does not name a type" }
+N::K f6; // { dg-error "1: error: 'K' in namespace 'N' does not name a type" }
+typename N::A f7; // { dg-error "1: error: using 'typename' outside of template|13: error: invalid use of template-name 'N::A' without an argument list|17: error: invalid type in declaration before ';' token" }
struct B
{
- N::A f2; // { dg-error "without an argument list" }
- N::INVALID f3; // { dg-error "in namespace 'N' does not name a type" }
- N::C::INVALID f4; // { dg-error "in class 'N::C' does not name a type" }
- N::K f6; // { dg-error "in namespace 'N' does not name a type" }
- typename N::A f7; // { dg-error "without an argument list|outside of template" }
+ N::A f2; // { dg-error "3: error: invalid use of template-name 'N::A' without an argument list" }
+ N::INVALID f3; // { dg-error "3: error: 'INVALID' in namespace 'N' does not name a type" }
+ N::C::INVALID f4; // { dg-error "3: error: 'INVALID' in class 'N::C' does not name a type" }
+ N::K f6; // { dg-error "3: error: 'K' in namespace 'N' does not name a type" }
+ typename N::A f7; // { dg-error "3: error: using 'typename' outside of template|15: error: invalid use of template-name 'N::A' without an argument list" }
};
template <int>
struct C
{
- N::A f2; // { dg-error "without an argument list" }
- N::INVALID f3; // { dg-error "in namespace 'N' does not name a type" }
- N::C::INVALID f4; // { dg-error "in class 'N::C' does not name a type" }
- N::K f6; // { dg-error "in namespace 'N' does not name a type" }
- typename N::A f7; // { dg-error "without an argument list" }
+ N::A f2; // { dg-error "3: error: invalid use of template-name 'N::A' without an argument list" }
+ N::INVALID f3; // { dg-error "3: error: 'INVALID' in namespace 'N' does not name a type" }
+ N::C::INVALID f4; // { dg-error "3: error: 'INVALID' in class 'N::C' does not name a type" }
+ N::K f6; // { dg-error "3: error: 'K' in namespace 'N' does not name a type" }
+ typename N::A f7; // { dg-error "15: error: invalid use of template-name 'N::A' without an argument list" }
};
-// { dg-bogus "" "bogus excess errors in declaration" { xfail *-*-* } 16 }
+// { dg-bogus "bogus excess errors in declaration" "bogus excess errors in declaration" { target *-*-* } 17 }
diff --git a/gcc/testsuite/g++.dg/parse/error16.C b/gcc/testsuite/g++.dg/parse/error16.C
index 3dc58ad53c0..ddc302c7cd6 100644
--- a/gcc/testsuite/g++.dg/parse/error16.C
+++ b/gcc/testsuite/g++.dg/parse/error16.C
@@ -1,8 +1,9 @@
+// { dg-options "-fshow-column" }
// PR c++/16964
struct A
{
- struct B {}; // { dg-error "previous" }
+ struct B {}; // { dg-error "12: error: previous definition of 'struct A::B'" }
};
-struct A::B{}; // { dg-error "redefinition" }
+struct A::B{}; // { dg-error "11: error: redefinition of 'struct A::B'" }
diff --git a/gcc/testsuite/g++.dg/parse/error17.C b/gcc/testsuite/g++.dg/parse/error17.C
index 2a8f3f829ca..0e05217c04d 100644
--- a/gcc/testsuite/g++.dg/parse/error17.C
+++ b/gcc/testsuite/g++.dg/parse/error17.C
@@ -1,8 +1,9 @@
+// { dg-options "-fshow-column" }
// PR c++/16965
template <typename T> struct B {
- static int Bar(T); // { dg-error "" }
+ static int Bar(T); // { dg-error "19: error: candidates are: |19: error: " }
};
struct D : B<int>, B<char> {};
-int i2 = D::Bar(2); // { dg-error "" }
+int i2 = D::Bar(2); // { dg-error "13: error: reference to 'Bar' is ambiguous|10: error: reference to 'Bar' is ambiguous" }
diff --git a/gcc/testsuite/g++.dg/parse/error18.C b/gcc/testsuite/g++.dg/parse/error18.C
index 363aae99879..926af11eb6a 100644
--- a/gcc/testsuite/g++.dg/parse/error18.C
+++ b/gcc/testsuite/g++.dg/parse/error18.C
@@ -1,7 +1,8 @@
+// { dg-options "-fshow-column" }
// PR c++/16002
void f()
{
- double Q *= 5.0; // { dg-error "initializer" }
+ double Q *= 5.0; // { dg-error "12: error: expected initializer before '..' token" }
}
diff --git a/gcc/testsuite/g++.dg/parse/error19.C b/gcc/testsuite/g++.dg/parse/error19.C
index 24a66affdae..b22156a5d71 100644
--- a/gcc/testsuite/g++.dg/parse/error19.C
+++ b/gcc/testsuite/g++.dg/parse/error19.C
@@ -1,7 +1,8 @@
+// { dg-options "-fshow-column -fmessage-length=0 -ansi -pedantic-errors -Wno-long-long " }
// PR C++/17867
struct A
-{ // { dg-error "candidate" }
+{ // { dg-error "1: note: candidates are:" }
A(int);
};
@@ -9,5 +10,5 @@ const A& foo();
void bar()
{
- foo()=A(0); // { dg-error "A" }
+ foo()=A(0); // { dg-error "12: error: no match for 'operator='" }
}
diff --git a/gcc/testsuite/g++.dg/parse/error2.C b/gcc/testsuite/g++.dg/parse/error2.C
index 8dd1e9d30da..075dcc2b0d1 100644
--- a/gcc/testsuite/g++.dg/parse/error2.C
+++ b/gcc/testsuite/g++.dg/parse/error2.C
@@ -1,4 +1,5 @@
// { dg-do compile }
+// { dg-options "-fshow-column" }
// Properly print CALL_EXPRs while dumping expressions
double g;
@@ -7,4 +8,8 @@ int func(double);
template <int>
struct Foo {};
-Foo<func(g)> f; // { dg-error "" "func(g)" }
+Foo<func(g)> f; // { dg-error "5: error: 'int func.double.' cannot appear in a constant-expression" "" { target *-*-* } { 11 } }
+// { dg-error "10: error: 'g' cannot appear in a constant-expression" "" { target *-*-* } { 11 } }
+// { dg-error "11: error: a function call cannot appear in a constant-expression" "" { target *-*-* } { 11 } }
+// { dg-error "12: error: template argument 1 is invalid" "" { target *-*-* } { 11 } }
+// { dg-error "15: error: invalid type in declaration before ';' token" "" { target *-*-* } { 11 } }
diff --git a/gcc/testsuite/g++.dg/parse/error20.C b/gcc/testsuite/g++.dg/parse/error20.C
index ee7390a633c..9564fab757b 100644
--- a/gcc/testsuite/g++.dg/parse/error20.C
+++ b/gcc/testsuite/g++.dg/parse/error20.C
@@ -1,3 +1,4 @@
+// { dg-options "-fshow-column -ansi -pedantic-errors -Wno-long-long" }
// PR c++/17821
struct A {
@@ -11,7 +12,7 @@ struct C {
};
int main() {
C c;
- A(c.p.i); // { dg-error "member.*non-class" }
+ A(c.p.i); // { dg-error "9: error: request for member 'i' in 'c.C::p', which is of non-class type 'B" }
return 0;
}
diff --git a/gcc/testsuite/g++.dg/parse/error21.C b/gcc/testsuite/g++.dg/parse/error21.C
index 6e24ae2244e..f60bf2b9c54 100644
--- a/gcc/testsuite/g++.dg/parse/error21.C
+++ b/gcc/testsuite/g++.dg/parse/error21.C
@@ -1,5 +1,5 @@
// PR c++/17393
-// { dg-options "-Wall" }
+// { dg-options "-Wall -fshow-column" }
struct A { };
@@ -7,6 +7,6 @@ void foo()
{
// Check that we do not complain about an unused
// compiler-generated variable.
- A& = a; // { dg-error "token|declarator|not declared" }
+ A& = a; // { dg-error "6: error: expected unqualified-id before '=' token|8: error: 'a' was not declared in this scope" }
}
diff --git a/gcc/testsuite/g++.dg/parse/error22.C b/gcc/testsuite/g++.dg/parse/error22.C
index da3a62f788a..30141219abc 100644
--- a/gcc/testsuite/g++.dg/parse/error22.C
+++ b/gcc/testsuite/g++.dg/parse/error22.C
@@ -1,5 +1,6 @@
+// { dg-options "-fshow-column -ansi -pedantic-errors -Wno-long-long" }
// PR c++/15786
struct A {
- void foo(bar* p); /* { dg-error "declared" } */
+ void foo(bar* p); /* { dg-error "12: error: 'bar' has not been declared" } */
};
diff --git a/gcc/testsuite/g++.dg/parse/error23.C b/gcc/testsuite/g++.dg/parse/error23.C
index 7d6fda2cc41..21b24349608 100644
--- a/gcc/testsuite/g++.dg/parse/error23.C
+++ b/gcc/testsuite/g++.dg/parse/error23.C
@@ -1,7 +1,9 @@
+// { dg-options "-fshow-column -ansi -pedantic-errors -Wno-long-long" }
// PR c++/19149
struct QChar {
QChar( char c );
QChar( const QChar& c );
- static const ; // { dg-error "" }
+ //following column number is not accurate enough but will make it for now
+ static const ; // { dg-error "10: error: declaration does not declare anything" }
};
diff --git a/gcc/testsuite/g++.dg/parse/error24.C b/gcc/testsuite/g++.dg/parse/error24.C
index c0722504271..e341c341291 100644
--- a/gcc/testsuite/g++.dg/parse/error24.C
+++ b/gcc/testsuite/g++.dg/parse/error24.C
@@ -1,7 +1,8 @@
+// { dg-options "-fshow-column -ansi -pedantic-errors -Wno-long-long" }
// PR c++/19395
struct A {
- typedef int ::X; // { dg-error "" }
+ typedef int ::X; // { dg-error "17: error: typedef name may not be a nested-name-specifier" }
};
diff --git a/gcc/testsuite/g++.dg/parse/error25.C b/gcc/testsuite/g++.dg/parse/error25.C
index 360b40f2e7e..b5cb57ee1f0 100644
--- a/gcc/testsuite/g++.dg/parse/error25.C
+++ b/gcc/testsuite/g++.dg/parse/error25.C
@@ -1,4 +1,5 @@
// { dg-do compile }
+// { dg-options "-fshow-column -ansi -pedantic-errors -Wno-long-long" }
// Origin: Steven Bosscher <steven at gcc dot gnu dot org>
// PR c++/17401: ICE with invalid pure specifier
@@ -8,10 +9,10 @@
class foo
{
virtual void bar1 () = 0;
- virtual void bar2 () = __null; // { dg-error "invalid pure specifier" }
- virtual void bar3 () = 4; // { dg-error "invalid pure specifier" }
- virtual void bar4 () = A::f; // { dg-error "invalid pure specifier" }
- virtual void bar5 () = 0l; // { dg-error "invalid pure specifier" }
- virtual void bar6 () = 00; // { dg-error "invalid pure specifier" }
- virtual void bar7 () = 0x0; // { dg-error "invalid pure specifier" }
+ virtual void bar2 () = __null; // { dg-error "32: error: invalid pure specifier" }
+ virtual void bar3 () = 4; // { dg-error "27: error: invalid pure specifier" }
+ virtual void bar4 () = A::f; // { dg-error "27: error: invalid pure specifier" }
+ virtual void bar5 () = 0l; // { dg-error "28: error: invalid pure specifier" }
+ virtual void bar6 () = 00; // { dg-error "28: error: invalid pure specifier" }
+ virtual void bar7 () = 0x0; // { dg-error "29: error: invalid pure specifier" }
};
diff --git a/gcc/testsuite/g++.dg/parse/error26.C b/gcc/testsuite/g++.dg/parse/error26.C
index 6e2b897d92b..81f7ba6d382 100644
--- a/gcc/testsuite/g++.dg/parse/error26.C
+++ b/gcc/testsuite/g++.dg/parse/error26.C
@@ -1,12 +1,12 @@
// PR c++/20148
-// { dg-options "" }
+// { dg-options "-fshow-column -ansi -pedantic-errors -Wno-long-long" }
void foo()
{
- if (({int c[2];})) ; // { dg-error "\{\.\.\.\}" }
+ if (({int c[2];})) ; // { dg-error "7: error: ISO C.. forbids|20: error: could not convert" }
}
void bar()
{
- if (({})); // { dg-error "\{\.\.\.\}" }
+ if (({})); // { dg-error "7: error: ISO C.. forbids|11: error: could not convert" }
}
diff --git a/gcc/testsuite/g++.dg/parse/error27.C b/gcc/testsuite/g++.dg/parse/error27.C
index f52d3cecce6..f1fd5376e59 100644
--- a/gcc/testsuite/g++.dg/parse/error27.C
+++ b/gcc/testsuite/g++.dg/parse/error27.C
@@ -1,7 +1,8 @@
+// { dg-options "-fshow-column -ansi -pedantic-errors -Wno-long-long" }
// PR c++/20152
-struct KrSelectionMode { virtual void init() = 0; }; // { dg-error "previous definition" }
-struct KrKDESelectionMode : public KrSelectionMode { void init() { } }; // { dg-error "previous definition" }
-struct KrSelectionMode { virtual void init() = 0; }; // { dg-error "" }
-struct KrKDESelectionMode : public KrSelectionMode { void init() { } }; // { dg-error "" }
+struct KrSelectionMode { virtual void init() = 0; }; // { dg-error "24: error: previous definition of 'struct KrSelectionMode'" }
+struct KrKDESelectionMode : public KrSelectionMode { void init() { } }; // { dg-error "52: error: previous definition of 'struct KrKDESelectionMode'" }
+struct KrSelectionMode { virtual void init() = 0; }; // { dg-error "8: error: redefinition of 'struct KrSelectionMode'" }
+struct KrKDESelectionMode : public KrSelectionMode { void init() { } }; // { dg-error "8: error: redefinition of 'struct KrKDESelectionMode'" }
KrKDESelectionMode krKDESelectionMode;
diff --git a/gcc/testsuite/g++.dg/parse/error28.C b/gcc/testsuite/g++.dg/parse/error28.C
index 046cc501f0b..fd202a10767 100644
--- a/gcc/testsuite/g++.dg/parse/error28.C
+++ b/gcc/testsuite/g++.dg/parse/error28.C
@@ -1,10 +1,11 @@
+// { dg-options "-fshow-column -ansi -pedantic-errors -Wno-long-long" }
// PR c++/21908
struct virt { virt () {} virt (int i) {} };
-struct der : public virtual virt { // { dg-error "der" }
- der (int i) : virt(i) {} // { dg-error "der" }
+struct der : public virtual virt { // { dg-error "34: note: der::der" }
+ der (int i) : virt(i) {} // { dg-error "13: note: candidates are: der" }
};
struct top : public der {
- // { dg-error "der\\(\\)" "" { target *-*-* } 9 }
top () {} // { dg-bogus "der\\(const" }
};
+// { dg-error "10: error: no matching function for call to 'der" "" { target *-*-* } 9 }
diff --git a/gcc/testsuite/g++.dg/parse/error29.C b/gcc/testsuite/g++.dg/parse/error29.C
index b50b275a9e6..fcd091b0b65 100644
--- a/gcc/testsuite/g++.dg/parse/error29.C
+++ b/gcc/testsuite/g++.dg/parse/error29.C
@@ -1,3 +1,4 @@
+// { dg-options "-fshow-column -ansi -pedantic-errors -Wno-long-long" }
// PR c++/25637
struct A {
@@ -6,7 +7,7 @@ struct A {
void operator delete(void *);
};
struct B {
- friend void A::foo() {} // { dg-error "define" }
- friend void A::operator delete(void*) {} // { dg-error "define" }
- friend A::A() {} // { dg-error "define" }
+ friend void A::foo() {} // { dg-error "22: error: cannot define member function 'A::foo' within 'B'" }
+ friend void A::operator delete(void*) {} // { dg-error "39: error: cannot define member function 'A::operator delete' within 'B'" }
+ friend A::A() {} // { dg-error "15: error: cannot define member function 'A::A' within 'B'" }
};
diff --git a/gcc/testsuite/g++.dg/parse/error3.C b/gcc/testsuite/g++.dg/parse/error3.C
index a052346d8ca..1f337e91cde 100644
--- a/gcc/testsuite/g++.dg/parse/error3.C
+++ b/gcc/testsuite/g++.dg/parse/error3.C
@@ -1,6 +1,19 @@
+// { dg-options "-fshow-column" }
// PR c++/10779
static void InstantiateConstraint(const float&, unsigned,
- void(*AddFunction)(const TYPE&,bool&, // { dg-error "" }
+ void(*AddFunction)(const TYPE&,bool&,
char*, char*,
- unsigned*)); // { dg-error "" }
+ unsigned*));
+// { dg-error "64: error: expected ',' or '...' before '&' token" "" { target *-*-* } { 5 } }
+
+/// in the coming test, the column information is broken as it points to
+// the end of the declaration instead of pointing to the begining of the
+// 'TYPE' identifier. This is due to the warning being generated by the
+// declaration groking code (gcc/cp/decl.c) and not the parser. So in that
+// code, the exact token location information is lost as the declaration
+// groking code manipulates TREEs only. The token location used is then
+// the global one that is not accurate enough. Anyway, let's say it is
+// good enough for now, until we find a way to propagate token location to
+// code paths that manipulate TREEs only.
+// { dg-error "64: error: ISO C\\+\\+ forbids declaration of 'TYPE' with no type" "" { target *-*-* } { 7 } }
diff --git a/gcc/testsuite/g++.dg/parse/error30.C b/gcc/testsuite/g++.dg/parse/error30.C
index 734a2552cb4..5c52d1ee67a 100644
--- a/gcc/testsuite/g++.dg/parse/error30.C
+++ b/gcc/testsuite/g++.dg/parse/error30.C
@@ -1,5 +1,6 @@
// PR c++/30854
// { dg-do compile }
+// { dg-options "-fshow-column -ansi -pedantic-errors -Wno-long-long" }
struct A
{
@@ -7,5 +8,5 @@ struct A
A(int);
};
-A a = -A(); // { dg-error "no match for.*operator-.*in.*-A\\(\\)" }
-A b = -A(5); // { dg-error "no match for.*operator-.*in.*-A\\(5\\)" }
+A a = -A(); // { dg-error "10: error: no match for.*operator-.*in.*-A\\(\\)" }
+A b = -A(5); // { dg-error "11: error: no match for.*operator-.*in.*-A\\(5\\)" }
diff --git a/gcc/testsuite/g++.dg/parse/error31.C b/gcc/testsuite/g++.dg/parse/error31.C
index 5264f442b31..d354cc3e0dd 100644
--- a/gcc/testsuite/g++.dg/parse/error31.C
+++ b/gcc/testsuite/g++.dg/parse/error31.C
@@ -1,10 +1,12 @@
+// { dg-options "-fshow-column -ansi -pedantic-errors -Wno-long-long" }
// PR c++/32190
template<typename T> class foo{ };
int main() {
foo<int> i;
- foo<foo<int> j; // { dg-error "template argument" }
+ // this column number is not accurate yet, but that will make it for now.
+ foo<foo<int> j; // { dg-error "18: error: template argument 1 is invalid" }
int k;
int l;
foo<int> m;
diff --git a/gcc/testsuite/g++.dg/parse/error4.C b/gcc/testsuite/g++.dg/parse/error4.C
index aa1bfad0dc9..790e5c9a40b 100644
--- a/gcc/testsuite/g++.dg/parse/error4.C
+++ b/gcc/testsuite/g++.dg/parse/error4.C
@@ -1,7 +1,10 @@
// PR c++/12160
+// { dg-options "-fshow-column" }
-struct X {
- virtual void f(int,
- itn, // { dg-error "declared" }
+struct X {
+ virtual void f(int,
+ itn,
int);
-};
+};
+
+// { dg-error "4: error: 'itn' has not been declared" "" { target *-*-* } { 6 } }
diff --git a/gcc/testsuite/g++.dg/parse/error5.C b/gcc/testsuite/g++.dg/parse/error5.C
index 81356ced1b0..8c9a039ac3c 100644
--- a/gcc/testsuite/g++.dg/parse/error5.C
+++ b/gcc/testsuite/g++.dg/parse/error5.C
@@ -1,4 +1,19 @@
// PR c++/13269
+// { dg-options "-fshow-column" }
-class Foo { int foo() return 0; } }; // { dg-error "" }
+class Foo { int foo() return 0; } };
+
+// { dg-error "30: error: expected identifier before numeric constant" "" { target *-*-* } { 4 } }
+
+// { dg-error "23: error: named return values are no longer supported" "" { target *-*-* } { 4 } }
+
+// the column number info of this error output is still wrong because the error
+// message has been generated by cp_parser_error() which does not
+// necessarily allow accurate column number display. At some point, we will
+// need make cp_parser_error() report more accurate column numbers.
+// { dg-error "30: error: expected '\{' at end of input" "" { target *-*-* } { 4 } }
+
+// { dg-error "35: error: expected unqualified-id before '\}' token" "" {target *-*-* } { 4 } }
+
+// { dg-error "35: error: expected declaration before '\}' token" "" {target *-*-* } { 4 } }
diff --git a/gcc/testsuite/g++.dg/parse/error6.C b/gcc/testsuite/g++.dg/parse/error6.C
index 3a1666995eb..cd1b6b8cd33 100644
--- a/gcc/testsuite/g++.dg/parse/error6.C
+++ b/gcc/testsuite/g++.dg/parse/error6.C
@@ -1,6 +1,11 @@
// PR c++/10603
+// { dg-options "-fshow-column" }
-int f(int not) { // { dg-error "!" }
- return 1-not; // { dg-error "" }
+int f(int not) {
+ return 1-not;
}
+// { dg-error "11: error: expected ',' or '...' before '!' token" "" { target *-*-* } { 4 } }
+
+// { dg-error "15: error: expected primary\\-expression before ';' token" "" { target *-*-* } { 5 } }
+
diff --git a/gcc/testsuite/g++.dg/parse/error7.C b/gcc/testsuite/g++.dg/parse/error7.C
index 50e7f84dca5..f71c9aa9fa0 100644
--- a/gcc/testsuite/g++.dg/parse/error7.C
+++ b/gcc/testsuite/g++.dg/parse/error7.C
@@ -1,4 +1,7 @@
// PR c++/12827
+// { dg-options "-fshow-column" }
void f(int x
- int y); // { dg-error "," }
+ int y);
+
+// { dg-error "8: error: expected ',' or '...' before 'int'" "" { target *-*-* } { 5 } }
diff --git a/gcc/testsuite/g++.dg/parse/error8.C b/gcc/testsuite/g++.dg/parse/error8.C
index 125f2e42c6b..a399cfe63f7 100644
--- a/gcc/testsuite/g++.dg/parse/error8.C
+++ b/gcc/testsuite/g++.dg/parse/error8.C
@@ -1,4 +1,10 @@
// PR c++/13438
+// { dg-options "-fshow-column" }
-struct A { friend typename struct B; }; // { dg-error "" }
-
+struct A { friend typename struct B; };
+
+
+// { dg-error "19: error: using 'typename' outside of template" "" { target *-*-* } { 4 } }
+// { dg-error "28: error: expected nested-name-specifier before 'struct'" "" { target *-*-* } { 4 } }
+// { dg-error "35: error: multiple types in one declaration" "" { target *-*-* } { 4 } }
+// { dg-error "12: error: friend declaration does not name a class or function" "" { target *-*-* } { 4 } }
diff --git a/gcc/testsuite/g++.dg/parse/error9.C b/gcc/testsuite/g++.dg/parse/error9.C
index aa9109fd22b..c1be6979b47 100644
--- a/gcc/testsuite/g++.dg/parse/error9.C
+++ b/gcc/testsuite/g++.dg/parse/error9.C
@@ -1,5 +1,9 @@
// PR c++/12613
-// { dg-options "" }
+// { dg-options "-fshow-column" }
enum { FOO = 1, BAR = 2 };
-int a[] = { FOO: 1, BAR: 2 }; // { dg-error "" }
+int a[] = { FOO: 1, BAR: 2 };
+
+// the following 2 column locations are still not accurate enough
+// { dg-error "28: error: name 'FOO' used in a GNU-style designated initializer for an array" "" { target *-*-* } { 5 } }
+// { dg-error "28: error: name 'BAR' used in a GNU-style designated initializer for an array" "" { target *-*-* } { 5 } }
diff --git a/gcc/testsuite/g++.dg/template/crash60.C b/gcc/testsuite/g++.dg/template/crash60.C
index 9e1d88b2432..c579775917e 100644
--- a/gcc/testsuite/g++.dg/template/crash60.C
+++ b/gcc/testsuite/g++.dg/template/crash60.C
@@ -5,5 +5,5 @@ struct A
template<int> void foo(X); // { dg-error "declared" }
};
-template<int> void f()(0); // { dg-error "initialized" }
+template<int> void f()(0); // { dg-error "initialize" }
diff --git a/gcc/testsuite/g++.dg/template/crash7.C b/gcc/testsuite/g++.dg/template/crash7.C
index 5b17928f5bb..ae07d91e739 100644
--- a/gcc/testsuite/g++.dg/template/crash7.C
+++ b/gcc/testsuite/g++.dg/template/crash7.C
@@ -6,8 +6,10 @@
// nested type.
template <typename> struct A
-{ // { dg-error "candidates" }
+{ // { not-dg-error "candidates" }
template <typename> A(typename A::X) {} // { dg-error "no type" }
};
-A<void> a; // { dg-error "instantiated|no match" }
+A<void> a; // { not-dg-error "instantiated|no match" }
+// We currently don't give the "no match" error because we don't add the
+// invalid constructor template to TYPE_METHODS.
diff --git a/gcc/testsuite/g++.dg/torture/pr36745.C b/gcc/testsuite/g++.dg/torture/pr36745.C
new file mode 100644
index 00000000000..86047f1f0d8
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/pr36745.C
@@ -0,0 +1,121 @@
+/* PR target/36745 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fPIC" } */
+/* { dg-require-effective-target fpic } */
+
+typedef __SIZE_TYPE__ size_t;
+class QBasicAtomicInt
+{
+public:
+ int _q_value;
+ inline bool operator== (int value) const
+ {
+ }
+ bool ref ();
+ bool deref ();
+};
+inline bool
+QBasicAtomicInt::ref ()
+{
+ __asm__ ("": "=m" (_q_value): :);
+ return true;
+}
+
+namespace std
+{
+ using::size_t;
+}
+extern "C++"
+{
+ inline void *operator new (std::size_t, void *__p)
+ {
+ return __p;
+ }
+}
+struct QMapData
+{
+ QBasicAtomicInt ref;
+ static QMapData shared_null;
+};
+template < class Key, class T > class QMap
+{
+ QMapData *d;
+public: inline QMap ():d (&QMapData::shared_null)
+ {
+ }
+ inline ~ QMap ()
+ {
+ if (!d->ref.deref ())
+ freeData (d);
+ }
+ void freeData (QMapData * d);
+};
+struct QVectorData
+{
+ static QVectorData shared_null;
+};
+template < typename T > struct QVectorTypedData
+{
+ QBasicAtomicInt ref;
+};
+template < typename T > class QVector
+{
+ union
+ {
+ QVectorData *p;
+ QVectorTypedData < T > *d;
+ };
+public: inline QVector ():p (&QVectorData::shared_null)
+ {
+ d->ref.ref ();
+ }
+ inline void detach ()
+ {
+ if (d->ref == 1)
+ detach_helper ();
+ }
+ inline T *data ()
+ {
+ detach ();
+ }
+ T & operator[](int i);
+ void detach_helper ();
+ void realloc ();
+};
+template < typename T > void QVector < T >::detach_helper ()
+{
+ realloc ();
+}
+
+template < typename T > inline T & QVector < T >::operator[](int i)
+{
+ return data ()[i];
+}
+template < typename T > void QVector < T >::realloc ()
+{
+ T *j, *i;
+ i->~T ();
+ while (j-- == i)
+ new (j) T;
+}
+
+void
+mergeInto (QVector < int >*a)
+{
+};
+struct QRegExpAutomatonState
+{
+ QVector < int >outs;
+ QMap < int, int >reenter;
+ QMap < int, int >anchors;
+};
+class QRegExpEngine
+{
+ void addCatTransitions ();
+ QVector < QRegExpAutomatonState > s;
+};
+void
+QRegExpEngine::addCatTransitions ()
+{
+ mergeInto (&s[2].outs);
+}
diff --git a/gcc/testsuite/g++.dg/torture/pr36826.C b/gcc/testsuite/g++.dg/torture/pr36826.C
new file mode 100644
index 00000000000..436220ba8a7
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/pr36826.C
@@ -0,0 +1,166 @@
+template <class T> T CoinMax(register const T x1, register const T x2);
+template <class T> T CoinMin(register const T x1, register const T x2);
+class CoinIndexedVector;
+class ClpModel {
+protected:
+ double objectiveScale_;
+ double rhsScale_;
+ int numberRows_;
+ int numberColumns_;
+ double * rowActivity_;
+ double * columnActivity_;
+ double * dual_;
+ double * reducedCost_;
+ double* rowLower_;
+ double* rowUpper_;
+ double * rowObjective_;
+ double * columnLower_;
+ double * columnUpper_;
+ double * rowScale_;
+ double * columnScale_;
+ double * inverseRowScale_;
+ double * inverseColumnScale_;
+ int problemStatus_;
+ int secondaryStatus_;
+};
+class ClpSimplex : public ClpModel {
+ void deleteRim(int getRidOfFactorizationData=2);
+ double upperOut_;
+ double dualTolerance_;
+ double primalTolerance_;
+ double * rowLowerWork_;
+ double * columnLowerWork_;
+ double * rowUpperWork_;
+ double * columnUpperWork_;
+ double * rowObjectiveWork_;
+ CoinIndexedVector * columnArray_[6];
+ double * reducedCostWork_;
+ double * rowActivityWork_;
+ double * columnActivityWork_;
+ ClpSimplex * auxiliaryModel_;
+};
+class CoinIndexedVector {
+public:
+ void clear();
+};
+void ClpSimplex::deleteRim(int getRidOfFactorizationData)
+{
+ int numberRows=numberRows_;
+ int numberColumns=numberColumns_;
+ int i;
+ int numberPrimalScaled=0;
+ int numberPrimalUnscaled=0;
+ int numberDualScaled=0;
+ int numberDualUnscaled=0;
+ double scaleC = 1.0/objectiveScale_;
+ double scaleR = 1.0/rhsScale_;
+ if (!inverseColumnScale_) {
+ for (i=0; i<numberColumns; i++)
+ {
+ double scaleFactor = columnScale_[i];
+ double valueScaled = columnActivityWork_[i];
+ double lowerScaled = columnLowerWork_[i];
+ double upperScaled = columnUpperWork_[i];
+ if (lowerScaled>-1.0e20||upperScaled<1.0e20) {
+ if (valueScaled<lowerScaled-primalTolerance_|| valueScaled>upperScaled+primalTolerance_)
+ numberPrimalScaled++;
+ else
+ upperOut_ = CoinMax(upperOut_,CoinMin(valueScaled-lowerScaled,upperScaled-valueScaled));
+ }
+ columnActivity_[i] = valueScaled*scaleFactor*scaleR;
+ double value = columnActivity_[i];
+ if (value<columnLower_[i]-primalTolerance_)
+ numberPrimalUnscaled++;
+ else if (value>columnUpper_[i]+primalTolerance_)
+ numberPrimalUnscaled++;
+ double valueScaledDual = reducedCostWork_[i];
+ if (valueScaled>columnLowerWork_[i]+primalTolerance_&&valueScaledDual>dualTolerance_)
+ numberDualScaled++;
+ if (valueScaled<columnUpperWork_[i]-primalTolerance_&&valueScaledDual<-dualTolerance_)
+ numberDualScaled++;
+ reducedCost_[i] = (valueScaledDual*scaleC)/scaleFactor;
+ double valueDual = reducedCost_[i];
+ if (value>columnLower_[i]+primalTolerance_&&valueDual>dualTolerance_)
+ numberDualUnscaled++;
+ if (value<columnUpper_[i]-primalTolerance_&&valueDual<-dualTolerance_)
+ numberDualUnscaled++;
+ }
+ for (i=0; i<numberRows; i++)
+ {
+ double scaleFactor = rowScale_[i];
+ double valueScaled = rowActivityWork_[i];
+ double lowerScaled = rowLowerWork_[i];
+ double upperScaled = rowUpperWork_[i];
+ if (lowerScaled>-1.0e20||upperScaled<1.0e20) { if (valueScaled<lowerScaled-primalTolerance_|| valueScaled>upperScaled+primalTolerance_) numberPrimalScaled++; else upperOut_ = CoinMax(upperOut_,CoinMin(valueScaled-lowerScaled,upperScaled-valueScaled)); }
+ rowActivity_[i] = (valueScaled*scaleR)/scaleFactor;
+ double value = rowActivity_[i];
+ if (value<rowLower_[i]-primalTolerance_) numberPrimalUnscaled++;
+ else if (value>rowUpper_[i]+primalTolerance_) numberPrimalUnscaled++;
+ double valueScaledDual = dual_[i]+rowObjectiveWork_[i];
+ ;
+ if (valueScaled>rowLowerWork_[i]+primalTolerance_&&valueScaledDual>dualTolerance_) numberDualScaled++;
+ if (valueScaled<rowUpperWork_[i]-primalTolerance_&&valueScaledDual<-dualTolerance_) numberDualScaled++;
+ dual_[i] *= scaleFactor*scaleC;
+ double valueDual = dual_[i];
+ if (rowObjective_) valueDual += rowObjective_[i];
+ if (value>rowLower_[i]+primalTolerance_&&valueDual>dualTolerance_) numberDualUnscaled++;
+ if (value<rowUpper_[i]-primalTolerance_&&valueDual<-dualTolerance_) numberDualUnscaled++;
+ }
+ }
+ const double * inverseScale = inverseColumnScale_;
+ for (i=0; i<numberColumns; i++)
+ {
+ double scaleFactor = columnScale_[i];
+ double valueScaled = columnActivityWork_[i];
+ double lowerScaled = columnLowerWork_[i];
+ double upperScaled = columnUpperWork_[i];
+ if (lowerScaled>-1.0e20||upperScaled<1.0e20) { if (valueScaled<lowerScaled-primalTolerance_|| valueScaled>upperScaled+primalTolerance_) numberPrimalScaled++; else upperOut_ = CoinMax(upperOut_,CoinMin(valueScaled-lowerScaled,upperScaled-valueScaled)); }
+ columnActivity_[i] = valueScaled*scaleFactor*scaleR;
+ double value = columnActivity_[i];
+ if (value<columnLower_[i]-primalTolerance_) numberPrimalUnscaled++;
+ else if (value>columnUpper_[i]+primalTolerance_) numberPrimalUnscaled++;
+ double valueScaledDual = reducedCostWork_[i];
+ if (valueScaled>columnLowerWork_[i]+primalTolerance_&&valueScaledDual>dualTolerance_) numberDualScaled++;
+ if (valueScaled<columnUpperWork_[i]-primalTolerance_&&valueScaledDual<-dualTolerance_) numberDualScaled++;
+ reducedCost_[i] = (valueScaledDual*scaleC)*inverseScale[i];
+ double valueDual = reducedCost_[i];
+ if (value>columnLower_[i]+primalTolerance_&&valueDual>dualTolerance_) numberDualUnscaled++;
+ if (value<columnUpper_[i]-primalTolerance_&&valueDual<-dualTolerance_) numberDualUnscaled++;
+ }
+ inverseScale = inverseRowScale_;
+ for (i=0; i<numberRows; i++)
+ {
+ double scaleFactor = rowScale_[i];
+ double valueScaled = rowActivityWork_[i];
+ double lowerScaled = rowLowerWork_[i];
+ double upperScaled = rowUpperWork_[i];
+ if (lowerScaled>-1.0e20||upperScaled<1.0e20) { if (valueScaled<lowerScaled-primalTolerance_|| valueScaled>upperScaled+primalTolerance_) numberPrimalScaled++; else upperOut_ = CoinMax(upperOut_,CoinMin(valueScaled-lowerScaled,upperScaled-valueScaled)); }
+ rowActivity_[i] = (valueScaled*scaleR)*inverseScale[i];
+ double value = rowActivity_[i];
+ if (value<rowLower_[i]-primalTolerance_) numberPrimalUnscaled++;
+ else if (value>rowUpper_[i]+primalTolerance_) numberPrimalUnscaled++;
+ double valueScaledDual = dual_[i]+rowObjectiveWork_[i];
+ ;
+ if (valueScaled>rowLowerWork_[i]+primalTolerance_&&valueScaledDual>dualTolerance_) numberDualScaled++;
+ if (valueScaled<rowUpperWork_[i]-primalTolerance_&&valueScaledDual<-dualTolerance_) numberDualScaled++;
+ dual_[i] *= scaleFactor*scaleC;
+ double valueDual = dual_[i];
+ if (rowObjective_) valueDual += rowObjective_[i];
+ if (value>rowLower_[i]+primalTolerance_&&valueDual>dualTolerance_) numberDualUnscaled++;
+ if (value<rowUpper_[i]-primalTolerance_&&valueDual<-dualTolerance_) numberDualUnscaled++;
+ }
+ if (numberPrimalUnscaled) {
+ if (numberDualUnscaled)
+ secondaryStatus_=4;
+ else
+ secondaryStatus_=2;
+ }
+ if (numberDualUnscaled)
+ secondaryStatus_=3;
+ int iRow,iColumn;
+ for (iRow=0; iRow<4; iRow++)
+ ;
+ for (iColumn=0; iColumn<2; iColumn++)
+ if (columnArray_[iColumn])
+ columnArray_[iColumn]->clear();
+}
diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr19637.C b/gcc/testsuite/g++.dg/tree-ssa/pr19637.C
index 2d1dcceba42..cf70e404123 100644
--- a/gcc/testsuite/g++.dg/tree-ssa/pr19637.C
+++ b/gcc/testsuite/g++.dg/tree-ssa/pr19637.C
@@ -29,5 +29,6 @@ int foo_void_offset(void)
return reinterpret_cast<Foo *>(&i[0])->i[0];
}
-/* { dg-final { scan-tree-dump-times "return 1;" 3 "dom1" } } */
+/* Regarding the xfail, see PR36143. */
+/* { dg-final { scan-tree-dump-times "return 1;" 3 "dom1" { xfail *-*-* } } } */
/* { dg-final { cleanup-tree-dump "dom1" } } */
diff --git a/gcc/testsuite/g++.dg/tree-ssa/ptrmemfield.C b/gcc/testsuite/g++.dg/tree-ssa/ptrmemfield.C
new file mode 100644
index 00000000000..38189eb43af
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tree-ssa/ptrmemfield.C
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+// { dg-options "-O2 -fdump-tree-final_cleanup" }
+
+
+struct f
+{
+ char m;
+ char m1;
+};
+
+static inline char f:: *g(int a)
+{
+ return a?0:&f::m;
+}
+
+int h(void)
+{
+ char f:: *a = g(0);
+ return a == 0;
+}
+
+/* We should have no cast to offset_type. */
+/* { dg-final { scan-tree-dump-times "offset_type" 0 "final_cleanup"} } */
+// And we should optimized this code to just return 0
+/* { dg-final { scan-tree-dump-times "return 0" 1 "final_cleanup"} } */
+/* { dg-final { cleanup-tree-dump "final_cleanup" } } */
+
diff --git a/gcc/testsuite/g++.dg/warn/Wdisallowed-functions-1.C b/gcc/testsuite/g++.dg/warn/Wdisallowed-functions-1.C
new file mode 100644
index 00000000000..39760950d69
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/Wdisallowed-functions-1.C
@@ -0,0 +1,7 @@
+/* { dg-do compile } */
+/* { dg-options "-Wdisallowed-function-list=foobar" } */
+
+int foobar (int i)
+{
+ return (i * 5);
+}
diff --git a/gcc/testsuite/g++.dg/warn/Wdisallowed-functions-2.C b/gcc/testsuite/g++.dg/warn/Wdisallowed-functions-2.C
new file mode 100644
index 00000000000..ca5aab0e50d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/Wdisallowed-functions-2.C
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-Wdisallowed-function-list=foo,foobar,bar,foobar" } */
+
+int foobar (int i)
+{
+ return (i * 5);
+}
+
+int foobar1 (int i)
+{
+ return foobar (i); /* { dg-warning "disallowed call to 'foobar'" } */
+}
diff --git a/gcc/testsuite/g++.dg/warn/Wreturn-type-4.C b/gcc/testsuite/g++.dg/warn/Wreturn-type-4.C
index 20c34a836a9..4f02678e7f9 100644
--- a/gcc/testsuite/g++.dg/warn/Wreturn-type-4.C
+++ b/gcc/testsuite/g++.dg/warn/Wreturn-type-4.C
@@ -16,7 +16,7 @@ template<typename T> const T getfoo(const T def) /* { dg-bogus "type qualifiers
template<typename T> class Pair
{
public:
- T getLeft() const { return T(); } /* { dg-warning "type qualifiers ignored" } */
+ T getLeft() const { return T(); } /* { dg-bogus "type qualifiers ignored" } */
const T getRight() const { return T(); } /* { dg-bogus "type qualifiers ignored" } */
};
diff --git a/gcc/testsuite/g++.dg/warn/pr23075.C b/gcc/testsuite/g++.dg/warn/pr23075.C
index 1521b658139..e5b1b483d76 100644
--- a/gcc/testsuite/g++.dg/warn/pr23075.C
+++ b/gcc/testsuite/g++.dg/warn/pr23075.C
@@ -6,4 +6,4 @@ int
foo (void)
{
return; // { dg-error "with no value" }
-} // { dg-bogus "control reaches end" }
+} // { dg-warning "no return statement" }
diff --git a/gcc/testsuite/g++.dg/warn/pragma-system_header5.C b/gcc/testsuite/g++.dg/warn/pragma-system_header5.C
new file mode 100644
index 00000000000..771db3d7ce7
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/pragma-system_header5.C
@@ -0,0 +1,10 @@
+// PR c++/36760
+// { dg-options "-Wextra" }
+
+#include "pragma-system_header5.h"
+
+void f()
+{
+ g<const double>();
+ g<volatile void>();
+}
diff --git a/gcc/testsuite/g++.dg/warn/pragma-system_header5.h b/gcc/testsuite/g++.dg/warn/pragma-system_header5.h
new file mode 100644
index 00000000000..5732e4afd3a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/pragma-system_header5.h
@@ -0,0 +1,3 @@
+#pragma GCC system_header
+
+template <typename T> T g();
diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/crash16.C b/gcc/testsuite/g++.old-deja/g++.brendan/crash16.C
index 7151eb13618..ddcae3c97cb 100644
--- a/gcc/testsuite/g++.old-deja/g++.brendan/crash16.C
+++ b/gcc/testsuite/g++.old-deja/g++.brendan/crash16.C
@@ -1,12 +1,14 @@
// { dg-do compile }
+// { dg-options "-fshow-column" }
// GROUPS passed old-abort
-class Graph {
+
+class Graph { // { dg-error "1: error: new types|1: note: \\(perhaps" }
public:
unsigned char N;
- Graph(void) {} // { dg-error "previously defined here" }
+ Graph(void) {} // { dg-error "17: error: 'Graph" }
}
-Graph::Graph(void) // { dg-error "return type|redefinition|semicolon" }
+Graph::Graph(void) // { dg-error "18: error: return type|18: error: redefinition" }
{ N = 10;
}
diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/crash52.C b/gcc/testsuite/g++.old-deja/g++.brendan/crash52.C
index 9e72fb5cbb0..74df601554e 100644
--- a/gcc/testsuite/g++.old-deja/g++.brendan/crash52.C
+++ b/gcc/testsuite/g++.old-deja/g++.brendan/crash52.C
@@ -10,4 +10,4 @@ public:
A &f(A &a) {// { dg-error "" } new decl.*
std::cout << "Blah\n";
-}
+} // { dg-error "no return statement" }
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/crash11.C b/gcc/testsuite/g++.old-deja/g++.jason/crash11.C
index e88eb78d53e..5cc8e5f3d6b 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/crash11.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/crash11.C
@@ -6,4 +6,4 @@ struct A {
};
const char foo[] = "bar";
const A a = { foo };
-extern const A* ap = &a;
+extern const A* ap = &a; //{ dg-warning "warning: 'ap' initialized and declared 'extern'" }
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/report.C b/gcc/testsuite/g++.old-deja/g++.jason/report.C
index e2d805e082c..f4e02a4dc35 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/report.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/report.C
@@ -56,7 +56,7 @@ bar2 baz (X::Y y) // { dg-error "" } in this context
bar2 wa [5];
wa[0] = baz(f);
undef2 (1); // { dg-error "" } implicit declaration
-}
+} // { dg-error "no return statement" }
int ninny ()
{
@@ -71,4 +71,4 @@ int ninny ()
int darg (char X::*p)
{
undef3 (1); // { dg-error "" } implicit declaration
-}
+} // { dg-error "no return statement" }
diff --git a/gcc/testsuite/g++.old-deja/g++.law/ctors5.C b/gcc/testsuite/g++.old-deja/g++.law/ctors5.C
index 334b59781b1..1f469cf5d49 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/ctors5.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/ctors5.C
@@ -1,11 +1,12 @@
// { dg-do assemble }
+// { dg-options "-fshow-column" }
// GROUPS passed constructors
// ctors file
// Subject: bug in handling static const object of the enclosing class
// Date: Tue, 1 Sep 92 10:38:44 EDT
class X
-{ // { dg-error "X::X" } implicit constructor
+{ // { dg-error "1: note: X::X\\(const X&\\)" } implicit constructor
private:
int x;
public:
@@ -13,21 +14,21 @@ class X
X( int );
};
-class Y
+class Y // { dg-error "1: error: new types may not be defined in a return type|1: note: \\(perhaps a semicolon is missing after the definition of 'Y'\\)" }
{
private:
X xx;
public:
Y();
}
-X::X( int xi ) // { dg-error "return type|X::X|semicolon" }
+X::X( int xi ) // { dg-error "14: error: return type specification for constructor invalid|14: note: candidates are: X::X\\(int\\)" }
{
x = xi;
}
const X X::x0( 0 );
-Y::Y() // { dg-error "no match" }
+Y::Y() // { dg-error "6: error: no matching function for call to 'X::X\\(\\)'" }
{
xx = X::x0;
}
diff --git a/gcc/testsuite/g++.old-deja/g++.other/crash25.C b/gcc/testsuite/g++.old-deja/g++.other/crash25.C
index b8417e8512e..517bac2d5d6 100644
--- a/gcc/testsuite/g++.old-deja/g++.other/crash25.C
+++ b/gcc/testsuite/g++.old-deja/g++.other/crash25.C
@@ -1,16 +1,17 @@
// { dg-do assemble }
+// { dg-options "-fshow-column" }
// Origin: Jakub Jelinek <jakub@redhat.com>
-class X {
+class X { // { dg-error "1: error: new types may not be defined in a return type|1: note: \\(perhaps a semicolon is missing after the definition of 'X'\\)" }
public:
X();
virtual ~X();
}
-X::x() // { dg-error "return type|member function|semicolon" }
+X::x() // { dg-error "6: error: no 'X X::x\\(\\)' member function declared in class 'X'" }
{
}
-X::~x() // { dg-error "expected class-name" }
+X::~x() // { dg-error "6: error: expected class-name before '\\(' token" }
{
}
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/error2.C b/gcc/testsuite/g++.old-deja/g++.pt/error2.C
index 2f777afdc70..40f7a7cb67f 100644
--- a/gcc/testsuite/g++.old-deja/g++.pt/error2.C
+++ b/gcc/testsuite/g++.old-deja/g++.pt/error2.C
@@ -2,7 +2,7 @@
// Origin: Carl Nygard <cnygard@bellatlantic.net>
template <class RT>
-class Test { // { dg-error "" } in instantiation
+class Test {
public:
Test(const RT& c = RT()) {} // { dg-error "" } reference to void
};
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/niklas01a.C b/gcc/testsuite/g++.old-deja/g++.pt/niklas01a.C
index 42a21fcb072..7fe07a2df0e 100644
--- a/gcc/testsuite/g++.old-deja/g++.pt/niklas01a.C
+++ b/gcc/testsuite/g++.old-deja/g++.pt/niklas01a.C
@@ -1,8 +1,9 @@
// { dg-do assemble }
+// { dg-options "-fshow-column" }
struct A { // { dg-error "" } forward declaration
- friend struct B : A { // { dg-error "" }
+ friend struct B : A { // { dg-error "invalid use of incomplete type 'struct A'" }
int x;
- }; // { dg-error "" } class definition cannot be a friend
+ }; // { dg-error "class definition may not be declared a friend" "" { target *-*-* } { 5 } }
int y;
};
diff --git a/gcc/testsuite/gcc.c-torture/compile/20080625-1.c b/gcc/testsuite/gcc.c-torture/compile/20080625-1.c
index f0900fd9693..226bea1ffae 100644
--- a/gcc/testsuite/gcc.c-torture/compile/20080625-1.c
+++ b/gcc/testsuite/gcc.c-torture/compile/20080625-1.c
@@ -1,3 +1,4 @@
+/* { dg-skip-if "too much data" { "avr-*-*" } { "*" } { "" } } */
struct peakbufStruct {
unsigned int lnum [5000];
int lscan [5000][4000];
diff --git a/gcc/testsuite/gcc.c-torture/compile/20080704-1.c b/gcc/testsuite/gcc.c-torture/compile/20080704-1.c
new file mode 100644
index 00000000000..b5e38b4ba60
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/20080704-1.c
@@ -0,0 +1,43 @@
+/* This code used to crash fold_convert due to PRE
+ wanting to fold_convert from a REAL_TYPE to an INTEGER_TYPE. */
+typedef unsigned int uint32_t;
+union double_union
+{
+ double d;
+ uint32_t i[2];
+};
+struct _Jv_reent
+{
+ int _errno;
+};
+_Jv_strtod_r (struct _Jv_reent *ptr, char **se)
+{
+ int bb2, sign;
+ double aadj, aadj1, adj;
+ unsigned long y, z;
+ union double_union rv, *bs = ((void *) 0), *delta = ((void *) 0);
+ {
+ ovfl:ptr->_errno = 34;
+ {
+ (((uint32_t) 0xfffffL) | ((uint32_t) 0x100000L) * (1024 + 1023 - 1));
+ }
+ if ((aadj = _Jv_ratio (delta, bs)) <= 2.)
+ {
+ {
+ if (aadj < 2. / 2)
+ aadj = 1. / 2;
+ aadj1 = -aadj;
+ }
+ }
+ {
+ (rv.i[1]) -= 53 * ((uint32_t) 0x100000L);
+ adj = aadj1 * _Jv_ulp (rv.d);
+ rv.d += adj;
+ if (((rv.i[1]) & ((uint32_t) 0x7ff00000L)) >=
+ ((uint32_t) 0x100000L) * (1024 + 1023 - 53))
+ {
+ goto ovfl;
+ }
+ }
+ }
+}
diff --git a/gcc/testsuite/gcc.c-torture/compile/20080721-1.c b/gcc/testsuite/gcc.c-torture/compile/20080721-1.c
new file mode 100644
index 00000000000..35ef352bc6d
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/20080721-1.c
@@ -0,0 +1,15 @@
+void foo(void);
+void bar(void);
+
+int test(int b)
+{
+ void *p, **q;
+ if (b)
+ p = (void *)foo;
+ else
+ p = (void *)bar;
+ q = (void **)p;
+ if (*q == (void *)0)
+ return 1;
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr11832.c b/gcc/testsuite/gcc.c-torture/compile/pr11832.c
index 88469ff6940..60017d3fb88 100644
--- a/gcc/testsuite/gcc.c-torture/compile/pr11832.c
+++ b/gcc/testsuite/gcc.c-torture/compile/pr11832.c
@@ -1,6 +1,6 @@
/* { dg-do compile } */
-/* Currently ICEs for MIPS and PowerPC; see PR33642. */
-/* { dg-xfail-if "PR33642" { mips*-*-* powerpc*-*-linux* } { "*" } { "" } } */
+/* Currently ICEs for MIPS, CRIS and PowerPC; see PR33642. */
+/* { dg-xfail-if "PR33642" { mips*-*-* powerpc*-*-linux* cris-*-* crisv32-*-* } { "*" } { "" } } */
/* Currently ICEs for (x86 && ilp32 && pic). */
/* { dg-xfail-if "PR33642/36240" { { i?86-*-* x86_64-*-* } && { ilp32 && { ! nonpic } } } { "*" } { "" } } */
/* { dg-prune-output ".*internal compiler error.*" }
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr33009.c b/gcc/testsuite/gcc.c-torture/compile/pr33009.c
index 79a4b62a3a6..026162c2e70 100644
--- a/gcc/testsuite/gcc.c-torture/compile/pr33009.c
+++ b/gcc/testsuite/gcc.c-torture/compile/pr33009.c
@@ -1,6 +1,6 @@
/* { dg-do compile } */
-/* Currently ICEs for MIPS and PowerPC; see PR33642. */
-/* { dg-xfail-if "PR33642" { mips*-*-* powerpc*-*-linux* } { "*" } { "" } } */
+/* Currently ICEs for MIPS, CRIS and PowerPC; see PR33642. */
+/* { dg-xfail-if "PR33642" { mips*-*-* powerpc*-*-linux* cris-*-* crisv32-*-* } { "*" } { "" } } */
/* Currently ICEs for (x86 && ilp32 && pic). */
/* { dg-xfail-if "PR33642/36240" { { i?86-*-* x86_64-*-* } && { ilp32 && { ! nonpic } } } { "*" } { "" } } */
/* { dg-prune-output ".*internal compiler error.*" }
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr35492.c b/gcc/testsuite/gcc.c-torture/compile/pr35492.c
new file mode 100644
index 00000000000..a1681f0a09d
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr35492.c
@@ -0,0 +1,26 @@
+void prepare_to_wait (void *, void *, int);
+void finish_wait (void *, void *);
+extern signed long schedule_timeout (signed long);
+struct sock
+{
+ unsigned char skc_state;
+ void *sk_sleep;
+ int sk_err;
+};
+
+void
+sk_stream_wait_connect (struct sock *sk, long *timeo_p)
+{
+ int done;
+ int wait;
+ do
+ {
+ if ((1 << sk->skc_state) & ~12)
+ return;
+ prepare_to_wait (sk->sk_sleep, &wait, 1);
+ *(timeo_p) = schedule_timeout (0);
+ done = !sk->sk_err;
+ finish_wait (sk->sk_sleep, &wait);
+ }
+ while (!done);
+}
diff --git a/gcc/testsuite/gcc.c-torture/execute/20080719-1.c b/gcc/testsuite/gcc.c-torture/execute/20080719-1.c
new file mode 100644
index 00000000000..694abcbf985
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/20080719-1.c
@@ -0,0 +1,65 @@
+typedef unsigned int u32;
+
+static const u32 deadfish = 0xdeadf155;
+
+static const u32 cfb_tab8_be[] = {
+ 0x00000000,0x000000ff,0x0000ff00,0x0000ffff,
+ 0x00ff0000,0x00ff00ff,0x00ffff00,0x00ffffff,
+ 0xff000000,0xff0000ff,0xff00ff00,0xff00ffff,
+ 0xffff0000,0xffff00ff,0xffffff00,0xffffffff
+};
+
+static const u32 cfb_tab8_le[] = {
+ 0x00000000,0xff000000,0x00ff0000,0xffff0000,
+ 0x0000ff00,0xff00ff00,0x00ffff00,0xffffff00,
+ 0x000000ff,0xff0000ff,0x00ff00ff,0xffff00ff,
+ 0x0000ffff,0xff00ffff,0x00ffffff,0xffffffff
+};
+
+static const u32 cfb_tab16_be[] = {
+ 0x00000000, 0x0000ffff, 0xffff0000, 0xffffffff
+};
+
+static const u32 cfb_tab16_le[] = {
+ 0x00000000, 0xffff0000, 0x0000ffff, 0xffffffff
+};
+
+static const u32 cfb_tab32[] = {
+ 0x00000000, 0xffffffff
+};
+
+
+
+
+
+
+const u32 *xxx(int bpp)
+{
+ const u32 *tab;
+
+if (0) return &deadfish;
+
+ switch (bpp) {
+ case 8:
+ tab = cfb_tab8_be;
+ break;
+ case 16:
+ tab = cfb_tab16_be;
+ break;
+ case 32:
+ default:
+ tab = cfb_tab32;
+ break;
+ }
+
+ return tab;
+}
+
+int main(void)
+{
+ const u32 *a = xxx(8);
+ int b = a[0];
+ if (b != cfb_tab8_be[0])
+ __builtin_abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr36765.c b/gcc/testsuite/gcc.c-torture/execute/pr36765.c
new file mode 100644
index 00000000000..6883b0cfd75
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr36765.c
@@ -0,0 +1,15 @@
+int __attribute__((noinline))
+foo(int i)
+{
+ int *p = __builtin_malloc (4 * sizeof(int));
+ *p = 0;
+ p[i] = 1;
+ return *p;
+}
+extern void abort (void);
+int main()
+{
+ if (foo(0) != 1)
+ abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/20080615-1.c b/gcc/testsuite/gcc.dg/20080615-1.c
new file mode 100644
index 00000000000..bce9476cddb
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/20080615-1.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-options "-w -O2" } */
+
+static int *see_bb_splay_ar = ((void *) 0);
+static void
+see_merge_and_eliminate_extensions (void)
+{
+ int i = 0;
+ printf ("* Phase 2: Merge and eliminate locally redundant extensions. *\n");
+ splay_tree_foreach (see_bb_splay_ar[i], ((void *) 0), ((void *) 0));
+}
+static void
+see_main (void)
+{
+ int i = 0;
+ see_merge_and_eliminate_extensions ();
+ printf ("Searching register properties in bb %d\n", i);
+}
+gate_handle_see (void)
+{
+}
+rest_of_handle_see (void)
+{
+ see_main ();
+}
diff --git a/gcc/testsuite/gcc.dg/Wcxx-compat-2.c b/gcc/testsuite/gcc.dg/Wcxx-compat-2.c
new file mode 100644
index 00000000000..5a46fbe4bd5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wcxx-compat-2.c
@@ -0,0 +1,35 @@
+/* { dg-options "-Wc++-compat" } */
+
+int bool;
+int catch;
+int char16_t;
+int char32_t;
+int class;
+int const_cast; /* { dg-warning "keyword" } */
+int decltype;
+int delete;
+int dynamic_cast; /* { dg-warning "keyword" } */
+int explicit;
+int export;
+int false;
+int friend;
+int mutable; /* { dg-warning "keyword" } */
+int namespace;
+int new;
+int operator;
+int private;
+int protected;
+int public;
+int reinterpret_cast; /* { dg-warning "keyword" } */
+int static_assert; /* { dg-warning "keyword" } */
+int static_cast; /* { dg-warning "keyword" } */
+int template;
+int this;
+int throw;
+int true;
+int try;
+int typename;
+int typeid;
+int using;
+int virtual;
+int wchar_t;
diff --git a/gcc/testsuite/gcc.dg/Wdeclaration-after-statement-3.c b/gcc/testsuite/gcc.dg/Wdeclaration-after-statement-3.c
new file mode 100644
index 00000000000..63b2bac5de8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wdeclaration-after-statement-3.c
@@ -0,0 +1,24 @@
+/* PR 35058: -Werror= works only with some warnings. */
+/* { dg-do compile } */
+/* { dg-options "-std=c99 -pedantic -Werror=declaration-after-statement" } */
+
+extern void abort (void);
+extern void exit (int);
+
+int
+main (void)
+{
+ int i = 0;
+ if (i != 0)
+ abort ();
+ i++;
+ if (i != 1)
+ abort ();
+ int j = i; /* { dg-error "" "declaration-after-statement" } */
+ if (j != 1)
+ abort ();
+ struct foo { int i0; } k = { 4 }; /* { dg-error "" "declaration-after-statement" } */
+ if (k.i0 != 4)
+ abort ();
+ exit (0);
+}
diff --git a/gcc/testsuite/gcc.dg/Wpointer-arith.c b/gcc/testsuite/gcc.dg/Wpointer-arith.c
new file mode 100644
index 00000000000..d7a19079cc4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wpointer-arith.c
@@ -0,0 +1,10 @@
+/* PR 35058: -Werror= works only with some warnings. */
+/* { dg-do compile } */
+/* { dg-options "-Werror=pointer-arith" } */
+void *a;
+
+void *test(){
+ int x=5;
+ if(a) a++; /* { dg-error "wrong type argument to increment" } */
+ return a+x; /* { dg-error "pointer of type" } */
+}
diff --git a/gcc/testsuite/gcc.dg/Wstrict-aliasing-bogus-ref-all.c b/gcc/testsuite/gcc.dg/Wstrict-aliasing-bogus-ref-all.c
new file mode 100644
index 00000000000..7e8d1771568
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wstrict-aliasing-bogus-ref-all.c
@@ -0,0 +1,41 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -Wall" } */
+
+struct g { long a; };
+unsigned long f(struct g *a) { return *(unsigned long *)&a->a; }
+
+struct A
+{
+ void *a;
+};
+
+int g(const struct A *x, long *y)
+{
+ typedef long __attribute__ ((may_alias)) long_a;
+ *y = *(const long_a *) (&x->a);
+ return 1;
+}
+
+void *a;
+
+int
+f0 (long *y)
+{
+ *y = *(const long *) &a; /* { dg-warning "will break" } */
+ return 1;
+}
+
+int
+f1 (long *y)
+{
+ typedef long __attribute__ ((may_alias)) long_a;
+ *y = *(const long_a *) &a;
+ return 1;
+}
+
+int
+f2 (long *y)
+{
+ *y = *(const long *) &a; /* { dg-warning "will break" } */
+ return 1;
+}
diff --git a/gcc/testsuite/gcc.dg/Wstrict-aliasing-float-ptr-int-obj.c b/gcc/testsuite/gcc.dg/Wstrict-aliasing-float-ptr-int-obj.c
index 7780fa6fcd6..73719157411 100644
--- a/gcc/testsuite/gcc.dg/Wstrict-aliasing-float-ptr-int-obj.c
+++ b/gcc/testsuite/gcc.dg/Wstrict-aliasing-float-ptr-int-obj.c
@@ -11,9 +11,9 @@ int foo() {
float* r;
if (flag) {
- q = (float*) &x; /* { dg-warning "type-punn" } */
+ q = (float*) &x; /* { dg-warning "type-punn" "" { xfail *-*-* } } */
} else {
- q = (float*) &y; /* { dg-warning "type-punn" } */
+ q = (float*) &y; /* { dg-warning "type-punn" "" { xfail *-*-* } } */
}
*q = 1.0;
diff --git a/gcc/testsuite/gcc.dg/callabi/callabi.h b/gcc/testsuite/gcc.dg/callabi/callabi.h
new file mode 100644
index 00000000000..d008ad659cb
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/callabi/callabi.h
@@ -0,0 +1,50 @@
+/* First the default target definition. */
+#ifndef __GNUC_VA_LIST
+#define __GNUC_VA_LIST
+ typedef __builtin_va_list __gnuc_va_list;
+#endif
+
+#ifndef _VA_LIST_DEFINED
+#define _VA_LIST_DEFINED
+ typedef __gnuc_va_list va_list;
+#endif
+
+#define __va_copy(d,s) __builtin_va_copy(d,s)
+#define __va_start(v,l) __builtin_va_start(v,l)
+#define __va_arg(v,l) __builtin_va_arg(v,l)
+#define __va_end(v) __builtin_va_end(v)
+
+#define __ms_va_copy(d,s) __builtin_ms_va_copy(d,s)
+#define __ms_va_start(v,l) __builtin_ms_va_start(v,l)
+#define __ms_va_arg(v,l) __builtin_va_arg(v,l)
+#define __ms_va_end(v) __builtin_ms_va_end(v)
+
+#define __sysv_va_copy(d,s) __builtin_sysv_va_copy(d,s)
+#define __sysv_va_start(v,l) __builtin_sysv_va_start(v,l)
+#define __sysv_va_arg(v,l) __builtin_va_arg(v,l)
+#define __sysv_va_end(v) __builtin_sysv_va_end(v)
+
+#define CALLABI_NATIVE
+
+#ifdef _WIN64
+#define CALLABI_CROSS __attribute__ ((sysv_abi))
+
+#define CROSS_VA_LIST __builtin_sysv_va_list
+
+#define CROSS_VA_COPY(d,s) __sysv_va_copy(d,s)
+#define CROSS_VA_START(v,l) __sysv_va_start(v,l)
+#define CROSS_VA_ARG(v,l) __sysv_va_arg(v,l)
+#define CROSS_VA_END(v) __sysv_va_end(v)
+
+#else
+
+#define CALLABI_CROSS __attribute__ ((ms_abi))
+
+#define CROSS_VA_LIST __builtin_ms_va_list
+
+#define CROSS_VA_COPY(d,s) __ms_va_copy(d,s)
+#define CROSS_VA_START(v,l) __ms_va_start(v,l)
+#define CROSS_VA_ARG(v,l) __ms_va_arg(v,l)
+#define CROSS_VA_END(v) __ms_va_end(v)
+
+#endif \ No newline at end of file
diff --git a/gcc/testsuite/gcc.dg/callabi/func-1.c b/gcc/testsuite/gcc.dg/callabi/func-1.c
new file mode 100644
index 00000000000..c727dbe6e53
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/callabi/func-1.c
@@ -0,0 +1,40 @@
+/* Test for cross x86_64<->w64 abi standard calls.
+*/
+/* Origin: Kai Tietz <kai.tietz@onevision.com> */
+/* { dg-do run { target { x86_64-*-* } } } */
+/* { dg-options "-std=gnu99 -ffast-math" } */
+#include "callabi.h"
+
+extern void abort (void);
+
+long double
+CALLABI_CROSS func_cross (long double a, double b, float c, long d, int e,
+ char f)
+{
+ long double ret;
+ ret = a + (long double) b + (long double) c;
+ ret *= (long double) (d + (long) e);
+ if (f>0)
+ ret += func_cross (a,b,c,d,e,-f);
+ return ret;
+}
+
+long double
+CALLABI_NATIVE func_native (long double a, double b, float c, long d, int e,
+ char f)
+{
+ long double ret;
+ ret = a + (long double) b + (long double) c;
+ ret *= (long double) (d + (long) e);
+ if (f>0)
+ ret += func_native (a,b,c,d,e,-f);
+ return ret;
+}
+
+int main ()
+{
+ if (func_cross (1.0,2.0,3.0,1,2,3)
+ != func_native (1.0,2.0,3.0,1,2,3))
+ abort ();
+ return 0;
+} \ No newline at end of file
diff --git a/gcc/testsuite/gcc.dg/callabi/vaarg-1.c b/gcc/testsuite/gcc.dg/callabi/vaarg-1.c
new file mode 100644
index 00000000000..1e745e56085
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/callabi/vaarg-1.c
@@ -0,0 +1,47 @@
+/* Test for cross x86_64<->w64 abi va_list calls.
+*/
+/* Origin: Kai Tietz <kai.tietz@onevision.com> */
+/* { dg-do run { target { x86_64-*-* } } } */
+/* { dg-options "-std=gnu99" } */
+#include "callabi.h"
+
+extern __SIZE_TYPE__ strlen (const char *);
+extern int sprintf (char *,const char *, ...);
+extern void abort (void);
+
+static
+void CALLABI_CROSS vdo_cpy (char *s, CROSS_VA_LIST argp)
+{
+ __SIZE_TYPE__ len;
+ char *r = s;
+ char *e;
+ *r = 0;
+ for (;;) {
+ e = CROSS_VA_ARG (argp,char *);
+ if (*e == 0) break;
+ sprintf (r,"%s", e);
+ r += strlen (r);
+ }
+}
+
+static
+void CALLABI_CROSS do_cpy (char *s, ...)
+{
+ CROSS_VA_LIST argp;
+ CROSS_VA_START (argp, s);
+ vdo_cpy (s, argp);
+ CROSS_VA_END (argp);
+}
+
+int main ()
+{
+ char s[256];
+
+ do_cpy (s, "1","2","3","4", "5", "6", "7", "");
+
+ if (s[0] != '1' || s[1] !='2' || s[2] != '3' || s[3] != '4'
+ || s[4] != '5' || s[5] != '6' || s[6] != '7' || s[7] != 0)
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/callabi/vaarg-2.c b/gcc/testsuite/gcc.dg/callabi/vaarg-2.c
new file mode 100644
index 00000000000..c9b716194a6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/callabi/vaarg-2.c
@@ -0,0 +1,47 @@
+/* Test for cross x86_64<->w64 abi va_list calls.
+*/
+/* Origin: Kai Tietz <kai.tietz@onevision.com> */
+/* { dg-do run { target { x86_64-*-* } } } */
+/* { dg-options "-std=gnu99" } */
+#include "callabi.h"
+
+extern void abort (void);
+
+#define SZ_ARGS 1ll,2ll,3ll,4ll,5ll,6ll,7ll,0ll
+
+static
+int CALLABI_CROSS fct1 (va_list argp, ...)
+{
+ long long p1,p2;
+ int ret = 1;
+ CROSS_VA_LIST argp_2;
+ CROSS_VA_START (argp_2,argp);
+
+ do {
+ p1 = CROSS_VA_ARG (argp_2, long long);
+ p2 = __va_arg (argp, long long);
+ if (p1 != p2)
+ ret = 0;
+ } while (ret && p1 != 0);
+ CROSS_VA_END (argp_2);
+ return ret;
+}
+
+static
+int fct2 (int dummy, ...)
+{
+ va_list argp;
+ int ret = dummy;
+
+ __va_start (argp, dummy);
+ ret += fct1 (argp, SZ_ARGS);
+ __va_end (argp);
+ return ret;
+}
+
+int main()
+{
+ if (fct2 (-1, SZ_ARGS) != 0)
+ abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/callabi/vaarg-3.c b/gcc/testsuite/gcc.dg/callabi/vaarg-3.c
new file mode 100644
index 00000000000..d0d068754e1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/callabi/vaarg-3.c
@@ -0,0 +1,47 @@
+/* Test for cross x86_64<->w64 abi va_list calls.
+*/
+/* Origin: Kai Tietz <kai.tietz@onevision.com> */
+/* { dg-do run { target { x86_64-*-* } } } */
+/* { dg-options "-std=gnu99" } */
+#include "callabi.h"
+
+extern void abort (void);
+
+#define SZ_ARGS 1ll,2ll,3ll,4ll,5ll,6ll,7ll,0ll
+
+static
+int fct1 (CROSS_VA_LIST argp, ...)
+{
+ long long p1,p2;
+ int ret = 1;
+ va_list argp_2;
+
+ __va_start (argp_2,argp);
+ do {
+ p1 = __va_arg (argp_2, long long);
+ p2 = CROSS_VA_ARG (argp, long long);
+ if (p1 != p2)
+ ret = 0;
+ } while (ret && p1 != 0);
+ __va_end (argp_2);
+ return ret;
+}
+
+static
+int CALLABI_CROSS fct2 (int dummy, ...)
+{
+ CROSS_VA_LIST argp;
+ int ret = dummy;
+
+ CROSS_VA_START (argp, dummy);
+ ret += fct1 (argp, SZ_ARGS);
+ CROSS_VA_END (argp);
+ return ret;
+}
+
+int main()
+{
+ if (fct2 (-1, SZ_ARGS) != 0)
+ abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/compat/struct-layout-1_generate.c b/gcc/testsuite/gcc.dg/compat/struct-layout-1_generate.c
index c53c3e8c2bd..f6a217e6f56 100644
--- a/gcc/testsuite/gcc.dg/compat/struct-layout-1_generate.c
+++ b/gcc/testsuite/gcc.dg/compat/struct-layout-1_generate.c
@@ -186,30 +186,42 @@ struct types vector_types[] = {
/* vector-defs.h typedefs */
{ "v8qi", TYPE_OTHER, 0, 0 },
{ "v16qi", TYPE_OTHER, 0, 0 },
+{ "v32qi", TYPE_OTHER, 0, 0 },
{ "v2hi", TYPE_OTHER, 0, 0 },
{ "v4hi", TYPE_OTHER, 0, 0 },
{ "v8hi", TYPE_OTHER, 0, 0 },
+{ "v16hi", TYPE_OTHER, 0, 0 },
{ "v2si", TYPE_OTHER, 0, 0 },
{ "v4si", TYPE_OTHER, 0, 0 },
+{ "v8si", TYPE_OTHER, 0, 0 },
{ "v1di", TYPE_OTHER, 0, 0 },
{ "v2di", TYPE_OTHER, 0, 0 },
+{ "v4di", TYPE_OTHER, 0, 0 },
{ "v2sf", TYPE_OTHER, 0, 0 },
{ "v4sf", TYPE_OTHER, 0, 0 },
+{ "v8sf", TYPE_OTHER, 0, 0 },
{ "v16sf", TYPE_OTHER, 0, 0 },
{ "v2df", TYPE_OTHER, 0, 0 },
+{ "v4df", TYPE_OTHER, 0, 0 },
{ "u8qi", TYPE_OTHER, 0, 0 },
{ "u16qi", TYPE_OTHER, 0, 0 },
+{ "u32qi", TYPE_OTHER, 0, 0 },
{ "u2hi", TYPE_OTHER, 0, 0 },
{ "u4hi", TYPE_OTHER, 0, 0 },
{ "u8hi", TYPE_OTHER, 0, 0 },
+{ "u16hi", TYPE_OTHER, 0, 0 },
{ "u2si", TYPE_OTHER, 0, 0 },
{ "u4si", TYPE_OTHER, 0, 0 },
+{ "u8si", TYPE_OTHER, 0, 0 },
{ "u1di", TYPE_OTHER, 0, 0 },
{ "u2di", TYPE_OTHER, 0, 0 },
+{ "u4di", TYPE_OTHER, 0, 0 },
{ "u2sf", TYPE_OTHER, 0, 0 },
{ "u4sf", TYPE_OTHER, 0, 0 },
+{ "u8sf", TYPE_OTHER, 0, 0 },
{ "u16sf", TYPE_OTHER, 0, 0 },
{ "u2df", TYPE_OTHER, 0, 0 },
+{ "u4df", TYPE_OTHER, 0, 0 },
{ "__m64", TYPE_OTHER, 0, 0 },
{ "__m128", TYPE_OTHER, 0, 0 }
#define NVTYPES2 (sizeof (vector_types) / sizeof (vector_types[0]))
diff --git a/gcc/testsuite/gcc.dg/compat/union-m128-1_main.c b/gcc/testsuite/gcc.dg/compat/union-m128-1_main.c
index 69dd34dce57..11f872154eb 100644
--- a/gcc/testsuite/gcc.dg/compat/union-m128-1_main.c
+++ b/gcc/testsuite/gcc.dg/compat/union-m128-1_main.c
@@ -1,6 +1,8 @@
+/* { dg-skip-if "test SSE2 support" { ! { i?86-*-* x86_64-*-* } } } */
/* { dg-options "-O" } */
-#ifdef __x86_64__
+#include "cpuid.h"
+
/* Test function argument passing. PR target/15301. */
extern void union_m128_1_x (void);
@@ -9,13 +11,14 @@ extern void exit (int);
int
main ()
{
- union_m128_1_x ();
+ unsigned int eax, ebx, ecx, edx;
+
+ if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx))
+ return 0;
+
+ /* Run SSE vector test only if host has SSE2 support. */
+ if (edx & bit_SSE2)
+ union_m128_1_x ();
+
exit (0);
}
-#else
-int
-main ()
-{
- return 0;
-}
-#endif
diff --git a/gcc/testsuite/gcc.dg/compat/union-m128-1_x.c b/gcc/testsuite/gcc.dg/compat/union-m128-1_x.c
index 06a4ef5ffdb..1f92303d95b 100644
--- a/gcc/testsuite/gcc.dg/compat/union-m128-1_x.c
+++ b/gcc/testsuite/gcc.dg/compat/union-m128-1_x.c
@@ -1,6 +1,5 @@
-/* { dg-options "-O" } */
+/* { dg-options "-O -msse2" } */
-#ifdef __x86_64__
#include "union-m128-1.h"
SS_union_mi128 un;
@@ -23,7 +22,3 @@ union_m128_1_x ()
foo(un);
foo(st);
}
-#else
-int dummy_x;
-#endif
-
diff --git a/gcc/testsuite/gcc.dg/compat/union-m128-1_y.c b/gcc/testsuite/gcc.dg/compat/union-m128-1_y.c
index 2b6eb0a6ee8..be9d6e8f3d5 100644
--- a/gcc/testsuite/gcc.dg/compat/union-m128-1_y.c
+++ b/gcc/testsuite/gcc.dg/compat/union-m128-1_y.c
@@ -1,6 +1,5 @@
-/* { dg-options "-O" } */
+/* { dg-options "-O -msse2" } */
-#ifdef __x86_64__
#include <stdlib.h>
#include "union-m128-1.h"
@@ -26,7 +25,3 @@ foo (SS_struct_mi128 st)
|| x.u [1] != 0xfedcba9876543210LL)
abort ();
}
-#else
-int dummy_y;
-#endif
-
diff --git a/gcc/testsuite/gcc.dg/compat/vector-1_x.c b/gcc/testsuite/gcc.dg/compat/vector-1_x.c
index 11995b496e5..ab4f88bf48b 100644
--- a/gcc/testsuite/gcc.dg/compat/vector-1_x.c
+++ b/gcc/testsuite/gcc.dg/compat/vector-1_x.c
@@ -8,13 +8,17 @@
SETUP (8, qi);
SETUP (16, qi);
+SETUP (32, qi);
SETUP (2, hi);
SETUP (4, hi);
SETUP (8, hi);
+SETUP (16, hi);
SETUP (2, si);
SETUP (4, si);
+SETUP (8, si);
SETUP (1, di);
SETUP (2, di);
+SETUP (4, di);
#endif
@@ -26,13 +30,17 @@ vector_1_x (void)
CHECK (8, qi);
CHECK (16, qi);
+ CHECK (32, qi);
CHECK (2, hi);
CHECK (4, hi);
CHECK (8, hi);
+ CHECK (16, hi);
CHECK (2, si);
CHECK (4, si);
+ CHECK (8, si);
CHECK (1, di);
CHECK (2, di);
+ CHECK (4, di);
DEBUG_FINI
diff --git a/gcc/testsuite/gcc.dg/compat/vector-1_y.c b/gcc/testsuite/gcc.dg/compat/vector-1_y.c
index 1cec61734b4..5a09c0eadb6 100644
--- a/gcc/testsuite/gcc.dg/compat/vector-1_y.c
+++ b/gcc/testsuite/gcc.dg/compat/vector-1_y.c
@@ -8,12 +8,16 @@
TEST (8, qi, 101)
TEST (16, qi, 101)
+TEST (32, qi, 90)
TEST (2, hi, 201)
TEST (4, hi, 202)
TEST (8, hi, 203)
+TEST (16, hi, 203)
TEST (2, si, 301)
TEST (4, si, 302)
+TEST (8, si, 303)
TEST (1, di, 401)
TEST (2, di, 402)
+TEST (4, di, 403)
#endif
diff --git a/gcc/testsuite/gcc.dg/compat/vector-1a_main.c b/gcc/testsuite/gcc.dg/compat/vector-1a_main.c
new file mode 100644
index 00000000000..76fb2915e1d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/compat/vector-1a_main.c
@@ -0,0 +1,26 @@
+/* { dg-skip-if "test SSE2 vector" { ! { i?86-*-* x86_64-*-* } } } */
+
+/* Test compatibility of vector types: layout between separately-compiled
+ modules, parameter passing, and function return. This test uses
+ vectors of integer values. */
+
+#include "cpuid.h"
+
+extern void vector_1_x (void);
+extern void exit (int);
+int fails;
+
+int
+main ()
+{
+ unsigned int eax, ebx, ecx, edx;
+
+ if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx))
+ return 0;
+
+ /* Run SSE vector test only if host has SSE2 support. */
+ if (edx & bit_SSE2)
+ vector_1_x ();
+
+ exit (0);
+}
diff --git a/gcc/testsuite/gcc.dg/compat/vector-1a_x.c b/gcc/testsuite/gcc.dg/compat/vector-1a_x.c
new file mode 100644
index 00000000000..aa0fa7f208c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/compat/vector-1a_x.c
@@ -0,0 +1,3 @@
+/* { dg-options "-w -mno-mmx -msse2" } */
+
+#include "vector-1_x.c"
diff --git a/gcc/testsuite/gcc.dg/compat/vector-1a_y.c b/gcc/testsuite/gcc.dg/compat/vector-1a_y.c
new file mode 100644
index 00000000000..2c88e198845
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/compat/vector-1a_y.c
@@ -0,0 +1,3 @@
+/* { dg-options "-w -mno-mmx -msse2" } */
+
+#include "vector-1_y.c"
diff --git a/gcc/testsuite/gcc.dg/compat/vector-2_x.c b/gcc/testsuite/gcc.dg/compat/vector-2_x.c
index de5f29c2688..d08c77fe3a0 100644
--- a/gcc/testsuite/gcc.dg/compat/vector-2_x.c
+++ b/gcc/testsuite/gcc.dg/compat/vector-2_x.c
@@ -10,7 +10,9 @@
SETUP (2, sf);
SETUP (4, sf);
SETUP (16, sf);
+SETUP (8, sf);
SETUP (2, df);
+SETUP (4, df);
#endif
@@ -22,7 +24,9 @@ vector_2_x (void)
CHECK (2, sf);
CHECK (4, sf);
+ CHECK (8, sf);
CHECK (16, sf);
+ CHECK (4, df);
CHECK (2, df);
DEBUG_FINI
diff --git a/gcc/testsuite/gcc.dg/compat/vector-2_y.c b/gcc/testsuite/gcc.dg/compat/vector-2_y.c
index 10d7a064532..fd5830c35b3 100644
--- a/gcc/testsuite/gcc.dg/compat/vector-2_y.c
+++ b/gcc/testsuite/gcc.dg/compat/vector-2_y.c
@@ -9,7 +9,9 @@
TEST (2, sf, 301.0)
TEST (4, sf, 302.0)
+TEST (8, sf, 303.0)
TEST (16, sf, 304.0)
TEST (2, df, 402.0)
+TEST (4, df, 402.0)
#endif
diff --git a/gcc/testsuite/gcc.dg/compat/vector-2a_main.c b/gcc/testsuite/gcc.dg/compat/vector-2a_main.c
new file mode 100644
index 00000000000..96c1111fddc
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/compat/vector-2a_main.c
@@ -0,0 +1,26 @@
+/* { dg-skip-if "test SSE2 support" { ! { i?86-*-* x86_64-*-* } } } */
+
+/* Test compatibility of vector types: layout between separately-compiled
+ modules, parameter passing, and function return. This test uses
+ vectors of floating points values. */
+
+#include "cpuid.h"
+
+extern void vector_2_x (void);
+extern void exit (int);
+int fails;
+
+int
+main ()
+{
+ unsigned int eax, ebx, ecx, edx;
+
+ if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx))
+ return 0;
+
+ /* Run SSE vector test only if host has SSE2 support. */
+ if (edx & bit_SSE2)
+ vector_2_x ();
+
+ exit (0);
+}
diff --git a/gcc/testsuite/gcc.dg/compat/vector-2a_x.c b/gcc/testsuite/gcc.dg/compat/vector-2a_x.c
new file mode 100644
index 00000000000..fcfacec04e8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/compat/vector-2a_x.c
@@ -0,0 +1,3 @@
+/* { dg-options "-w -mno-mmx -msse2" } */
+
+#include "vector-2_x.c"
diff --git a/gcc/testsuite/gcc.dg/compat/vector-2a_y.c b/gcc/testsuite/gcc.dg/compat/vector-2a_y.c
new file mode 100644
index 00000000000..3797acb6a57
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/compat/vector-2a_y.c
@@ -0,0 +1,3 @@
+/* { dg-options "-w -mno-mmx -msse2" } */
+
+#include "vector-2_y.c"
diff --git a/gcc/testsuite/gcc.dg/compat/vector-defs.h b/gcc/testsuite/gcc.dg/compat/vector-defs.h
index 7574e28c53d..f2f050527ec 100644
--- a/gcc/testsuite/gcc.dg/compat/vector-defs.h
+++ b/gcc/testsuite/gcc.dg/compat/vector-defs.h
@@ -56,6 +56,20 @@ typedef float __attribute__((mode(V2DF))) v2df;
#endif
+typedef qi __attribute__((vector_size (32))) v32qi;
+typedef hi __attribute__((vector_size (32))) v16hi;
+typedef si __attribute__((vector_size (32))) v8si;
+typedef di __attribute__((vector_size (32))) v4di;
+typedef sf __attribute__((vector_size (32))) v8sf;
+typedef df __attribute__((vector_size (32))) v4df;
+
+typedef union U32QI { v32qi v; qi a[32]; } u32qi;
+typedef union U16HI { v16hi v; hi a[16]; } u16hi;
+typedef union U8SI { v8si v; si a[8]; } u8si;
+typedef union U4DI { v4di v; di a[4]; } u4di;
+typedef union U8SF { v8sf v; sf a[8]; } u8sf;
+typedef union U4DF { v4df v; df a[4]; } u4df;
+
typedef union U8QI { v8qi v; qi a[8]; } u8qi;
typedef union U16QI { v16qi v; qi a[16]; } u16qi;
diff --git a/gcc/testsuite/gcc.dg/cpp/line6.c b/gcc/testsuite/gcc.dg/cpp/line6.c
new file mode 100644
index 00000000000..c59ea3af7f1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/cpp/line6.c
@@ -0,0 +1,7 @@
+/* PR 28079 */
+/* { dg-do preprocess } */
+/* { dg-options "" } */
+
+#line 18446744073709551616 /* { dg-warning "line number out of range" } */
+
+#line 12312312312435 /* { dg-warning "line number out of range" "" { target *-*-* } 0 } */
diff --git a/gcc/testsuite/gcc.dg/fold-alloca-1.c b/gcc/testsuite/gcc.dg/fold-alloca-1.c
index 735a22f3a7e..c4645364701 100644
--- a/gcc/testsuite/gcc.dg/fold-alloca-1.c
+++ b/gcc/testsuite/gcc.dg/fold-alloca-1.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-fdump-tree-useless" } */
+/* { dg-options "-fdump-tree-cleanup_cfg1" } */
void *alloca (__SIZE_TYPE__);
void link_error ();
@@ -10,5 +10,5 @@ int main (int argc, char *argv[]) {
link_error ();
return 0;
}
-/* { dg-final { scan-tree-dump-times "link_error" 0 "useless" } } */
-/* { dg-final { cleanup-tree-dump "useless" } } */
+/* { dg-final { scan-tree-dump-times "link_error" 0 "cleanup_cfg1" } } */
+/* { dg-final { cleanup-tree-dump "cleanup_cfg1" } } */
diff --git a/gcc/testsuite/gcc.dg/fshort-wchar.c b/gcc/testsuite/gcc.dg/fshort-wchar.c
index 9f4946307f0..c9c751504df 100644
--- a/gcc/testsuite/gcc.dg/fshort-wchar.c
+++ b/gcc/testsuite/gcc.dg/fshort-wchar.c
@@ -2,6 +2,7 @@
/* { dg-do run } */
/* { dg-options "-fshort-wchar" } */
+/* { dg-options "-fshort-wchar -Wl,--no-wchar-size-warning" { target arm*-*-*eabi } } */
/* Source: Neil Booth, 10 Dec 2002.
diff --git a/gcc/testsuite/gcc.dg/gomp/atomic-11.c b/gcc/testsuite/gcc.dg/gomp/atomic-11.c
new file mode 100644
index 00000000000..397972b3cf2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/gomp/atomic-11.c
@@ -0,0 +1,17 @@
+/* PR middle-end/36877 */
+/* { dg-do compile } */
+/* { dg-options "-fopenmp" } */
+/* { dg-options "-fopenmp -march=i386" { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
+
+int i;
+float f;
+
+void foo (void)
+{
+#pragma omp atomic
+ i++;
+#pragma omp atomic
+ f += 1.0;
+}
+
+/* { dg-final { scan-assembler-not "__sync_(fetch|add|bool|val)" { target i?86-*-* x86_64-*-* powerpc*-*-* ia64-*-* s390*-*-* sparc*-*-* } } } */
diff --git a/gcc/testsuite/gcc.dg/gomp/block-1.c b/gcc/testsuite/gcc.dg/gomp/block-1.c
index abc66e580fd..dd7fe7783a9 100644
--- a/gcc/testsuite/gcc.dg/gomp/block-1.c
+++ b/gcc/testsuite/gcc.dg/gomp/block-1.c
@@ -4,7 +4,7 @@ void foo()
{
bad1:
#pragma omp parallel
- goto bad1; // { dg-error "invalid exit" }
+ goto bad1; // { dg-error "invalid branch" }
goto bad2; // { dg-error "invalid entry" }
#pragma omp parallel
diff --git a/gcc/testsuite/gcc.dg/gomp/block-2.c b/gcc/testsuite/gcc.dg/gomp/block-2.c
index 810b2da07b4..4c56add570c 100644
--- a/gcc/testsuite/gcc.dg/gomp/block-2.c
+++ b/gcc/testsuite/gcc.dg/gomp/block-2.c
@@ -11,7 +11,7 @@ void foo()
bad1:
#pragma omp for
for (i = 0; i < 10; ++i)
- goto bad1; // { dg-error "invalid exit" }
+ goto bad1; // { dg-error "invalid branch" }
goto bad2; // { dg-error "invalid entry" }
#pragma omp for
diff --git a/gcc/testsuite/gcc.dg/gomp/block-3.c b/gcc/testsuite/gcc.dg/gomp/block-3.c
index 160047c394c..c72b04c35d0 100644
--- a/gcc/testsuite/gcc.dg/gomp/block-3.c
+++ b/gcc/testsuite/gcc.dg/gomp/block-3.c
@@ -9,7 +9,7 @@ void foo()
{
#pragma omp sections
{
- continue; // { dg-error "invalid exit" }
+ continue; // { dg-error "invalid branch" }
}
}
@@ -18,12 +18,12 @@ void foo()
#pragma omp section
{ bad1: ; }
#pragma omp section
- goto bad1; // { dg-error "invalid exit" }
+ goto bad1; // { dg-error "invalid branch" }
}
#pragma omp sections
{
- goto bad2; // { dg-error "invalid exit" }
+ goto bad2; // { dg-error "invalid branch" }
}
bad2:;
diff --git a/gcc/testsuite/gcc.dg/gomp/block-4.c b/gcc/testsuite/gcc.dg/gomp/block-4.c
index 815d36b2e39..61f490c0033 100644
--- a/gcc/testsuite/gcc.dg/gomp/block-4.c
+++ b/gcc/testsuite/gcc.dg/gomp/block-4.c
@@ -4,6 +4,6 @@ void foo()
{
#pragma omp critical
{
- return; // { dg-error "invalid exit" }
+ return; // { dg-error "invalid branch" }
}
}
diff --git a/gcc/testsuite/gcc.dg/gomp/block-5.c b/gcc/testsuite/gcc.dg/gomp/block-5.c
index 450106feeb1..741049fddea 100644
--- a/gcc/testsuite/gcc.dg/gomp/block-5.c
+++ b/gcc/testsuite/gcc.dg/gomp/block-5.c
@@ -4,12 +4,12 @@ void foo()
{
#pragma omp master
{
- goto bad1; // { dg-error "invalid exit" }
+ goto bad1; // { dg-error "invalid branch" }
}
#pragma omp master
{
bad1:
- return; // { dg-error "invalid exit" }
+ return; // { dg-error "invalid branch" }
}
}
diff --git a/gcc/testsuite/gcc.dg/gomp/block-6.c b/gcc/testsuite/gcc.dg/gomp/block-6.c
index fa4c5eab5f4..87e6392e5b3 100644
--- a/gcc/testsuite/gcc.dg/gomp/block-6.c
+++ b/gcc/testsuite/gcc.dg/gomp/block-6.c
@@ -4,6 +4,6 @@ void foo()
{
#pragma omp ordered
{
- return; // { dg-error "invalid exit" }
+ return; // { dg-error "invalid branch" }
}
}
diff --git a/gcc/testsuite/gcc.dg/gomp/block-7.c b/gcc/testsuite/gcc.dg/gomp/block-7.c
index 802b3b3a383..2bc1cdb5723 100644
--- a/gcc/testsuite/gcc.dg/gomp/block-7.c
+++ b/gcc/testsuite/gcc.dg/gomp/block-7.c
@@ -6,15 +6,15 @@ void foo()
for (i = 0; i < 10; ++i)
{
#pragma omp for
- for (j = ({ continue; 0; }); // { dg-error "invalid exit" }
- j < ({ continue; 10; }); // { dg-error "invalid exit" }
- j += ({ continue; 1; })) // { dg-error "invalid exit" }
+ for (j = ({ continue; 0; }); // { dg-error "invalid branch" }
+ j < ({ continue; 10; }); // { dg-error "invalid branch" }
+ j += ({ continue; 1; })) // { dg-error "invalid branch" }
continue;
#pragma omp for
- for (j = ({ break; 0; }); // { dg-error "invalid exit" }
- j < ({ break; 10; }); // { dg-error "invalid exit" }
- j += ({ break; 1; })) // { dg-error "invalid exit" }
+ for (j = ({ break; 0; }); // { dg-error "invalid branch" }
+ j < ({ break; 10; }); // { dg-error "invalid branch" }
+ j += ({ break; 1; })) // { dg-error "invalid branch" }
break; // { dg-error "break" }
}
}
diff --git a/gcc/testsuite/gcc.dg/gomp/block-8.c b/gcc/testsuite/gcc.dg/gomp/block-8.c
index 177acaa28c0..3c717d927be 100644
--- a/gcc/testsuite/gcc.dg/gomp/block-8.c
+++ b/gcc/testsuite/gcc.dg/gomp/block-8.c
@@ -7,5 +7,5 @@ int foo()
#pragma omp parallel for
for (i = 0; i < 10; ++i)
- return 0; // { dg-error "invalid exit" }
+ return 0; // { dg-error "invalid branch" }
}
diff --git a/gcc/testsuite/gcc.dg/gomp/pr36790.c b/gcc/testsuite/gcc.dg/gomp/pr36790.c
new file mode 100644
index 00000000000..b3379f1564a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/gomp/pr36790.c
@@ -0,0 +1,23 @@
+/* PR middle-end/36790 */
+/* { dg-do compile } */
+/* { dg-options "-fopenmp" } */
+
+void
+foo (char b)
+{
+}
+
+void
+bar (char b)
+{
+ foo (b);
+ #pragma omp task default (shared)
+ b = 0;
+}
+
+int
+main ()
+{
+ bar (0);
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/ipa/iinline-1.c b/gcc/testsuite/gcc.dg/ipa/iinline-1.c
new file mode 100644
index 00000000000..da548f46648
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/iinline-1.c
@@ -0,0 +1,26 @@
+/* Verify that simple indirect calls are inlined even without early
+ inlining.. */
+/* { dg-do compile } */
+/* { dg-options "-O3 -c -fdump-ipa-inline -fno-early-inlining" } */
+
+extern void non_existent(int);
+
+static void hooray ()
+{
+ non_existent (1);
+}
+
+static void hiphip (void (*f)())
+{
+ non_existent (2);
+ f ();
+}
+
+int main (int argc, int *argv[])
+{
+ hiphip (hooray);
+ return 0;
+}
+
+/* { dg-final { scan-ipa-dump "hooray\[^\\n\]*inline copy in main" "inline" } } */
+/* { dg-final { cleanup-tree-dump "inline" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/modif-1.c b/gcc/testsuite/gcc.dg/ipa/modif-1.c
new file mode 100644
index 00000000000..7d160cb7e74
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/modif-1.c
@@ -0,0 +1,44 @@
+/* Verify that modification analysis detects modfications. */
+/* { dg-do compile } */
+/* { dg-options "-O3 -c -fdump-ipa-inline -fno-early-inlining" } */
+
+struct whatever
+{
+ int first;
+ unsigned second;
+};
+
+void func1 (struct whatever w);
+void func2 (struct whatever *pw);
+void func3 (int i);
+void func4 (int *pi);
+
+void the_test (struct whatever u, struct whatever v,
+ struct whatever w, struct whatever x,
+ int i, int j, int k, int l)
+{
+ struct whatever *pw = &w;
+ int *pk = &k;
+
+ j = l+3;
+ v.first = 9;
+
+ func1 (u);
+ func1 (v);
+ func2 (pw);
+ func2 (&x);
+ func3 (i);
+ func3 (j);
+ func4 (pk);
+ func4 (&l);
+}
+
+/* { dg-final { scan-ipa-dump-not "param 0 flags:\[^\\n\]*modified" "inline" } } */
+/* { dg-final { scan-ipa-dump "param 1 flags:\[^\\n\]*modified" "inline" } } */
+/* { dg-final { scan-ipa-dump "param 2 flags:\[^\\n\]*modified" "inline" } } */
+/* { dg-final { scan-ipa-dump "param 3 flags:\[^\\n\]*modified" "inline" } } */
+/* { dg-final { scan-ipa-dump-not "param 4 flags:\[^\\n\]*modified" "inline" } } */
+/* { dg-final { scan-ipa-dump "param 5 flags:\[^\\n\]*modified" "inline" } } */
+/* { dg-final { scan-ipa-dump "param 6 flags:\[^\\n\]*modified" "inline" } } */
+/* { dg-final { scan-ipa-dump "param 7 flags:\[^\\n\]*modified" "inline" } } */
+/* { dg-final { cleanup-ipa-dump "inline" } } */
diff --git a/gcc/testsuite/gcc.dg/mallign.c b/gcc/testsuite/gcc.dg/mallign.c
new file mode 100644
index 00000000000..4a64dbbcc3b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/mallign.c
@@ -0,0 +1,15 @@
+/* Check that malloc's alignment honors what we trust it
+ minimally should. */
+
+/* { dg-do run } */
+/* { dg-options "-fno-builtin-malloc" } */
+
+#include <stdlib.h>
+typedef int word __attribute__((mode(word)));
+
+int main()
+{
+ if ((long)malloc (1) & (sizeof(word)-1))
+ abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/no-asm-1.c b/gcc/testsuite/gcc.dg/no-asm-1.c
new file mode 100644
index 00000000000..fdcf05459a4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/no-asm-1.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-std=gnu89" } */
+
+/* Verify that these GNU extensions are recognized as keywords in
+ GNU89 mode. */
+
+int asm; /* { dg-error "before .asm." } */
+int inline; /* { dg-warning "empty declaration" } */
+/* { dg-error "empty declaration" "" { target *-*-* } 8 } */
+int typeof; /* { dg-error "before .typeof." } */
diff --git a/gcc/testsuite/gcc.dg/no-asm-2.c b/gcc/testsuite/gcc.dg/no-asm-2.c
new file mode 100644
index 00000000000..3cd41141de1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/no-asm-2.c
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-options "-std=gnu89 -fno-asm" } */
+
+/* Verify that these GNU extensions are not recognized as keywords
+ when using -fno-asm in GNU89 mode. */
+
+int asm; /* { dg-bogus "before .asm." } */
+int inline; /* { dg-bogus "empty declaration" } */
+int typeof; /* { dg-bogus "before .typeof." } */
diff --git a/gcc/testsuite/gcc.dg/no-asm-3.c b/gcc/testsuite/gcc.dg/no-asm-3.c
new file mode 100644
index 00000000000..9c806e43533
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/no-asm-3.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-std=gnu99" } */
+
+/* Verify that these GNU extensions are recognized as keywords in
+ GNU99 mode. */
+
+int asm; /* { dg-error "before .asm." } */
+int inline; /* { dg-warning "empty declaration" } */
+/* { dg-error "empty declaration" "" { target *-*-* } 8 } */
+int typeof; /* { dg-error "before .typeof." } */
diff --git a/gcc/testsuite/gcc.dg/no-asm-4.c b/gcc/testsuite/gcc.dg/no-asm-4.c
new file mode 100644
index 00000000000..c4c1687800c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/no-asm-4.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-std=gnu99 -fno-asm" } */
+
+/* Verify that the GNU extensions asm and typeof are not recognized as
+ keywords when using -fno-asm in GNU89 mode, but that inline (which
+ is a keyword in C99 but not C89) is recognized. */
+
+int asm; /* { dg-bogus "before .asm." } */
+int inline; /* { dg-warning "empty declaration" } */
+/* { dg-error "empty declaration" "" { target *-*-* } 9 } */
+int typeof; /* { dg-bogus "before .typeof." } */
diff --git a/gcc/testsuite/gcc.dg/pch/valid-3.c b/gcc/testsuite/gcc.dg/pch/valid-3.c
deleted file mode 100644
index c7884f993a0..00000000000
--- a/gcc/testsuite/gcc.dg/pch/valid-3.c
+++ /dev/null
@@ -1,6 +0,0 @@
-/* { dg-options "-I. -Winvalid-pch -fno-unit-at-a-time" } */
-
-#include "valid-3.h"/* { dg-warning "settings for -funit-at-a-time do not match" } */
-/* { dg-error "No such file" "no such file" { target *-*-* } 3 } */
-/* { dg-error "they were invalid" "invalid files" { target *-*-* } 3 } */
-int x;
diff --git a/gcc/testsuite/gcc.dg/pch/valid-3.hs b/gcc/testsuite/gcc.dg/pch/valid-3.hs
deleted file mode 100644
index 2a0af94c9f7..00000000000
--- a/gcc/testsuite/gcc.dg/pch/valid-3.hs
+++ /dev/null
@@ -1,3 +0,0 @@
-/* { dg-options "-I. -Winvalid-pch -funit-at-a-time" } */
-
-extern int x;
diff --git a/gcc/testsuite/gcc.dg/pr28322-2.c b/gcc/testsuite/gcc.dg/pr28322-2.c
index 8fde7b21aa3..89dd15390f8 100644
--- a/gcc/testsuite/gcc.dg/pr28322-2.c
+++ b/gcc/testsuite/gcc.dg/pr28322-2.c
@@ -8,5 +8,5 @@ int foo (void)
return i;
}
-/* { dg-message "unrecognized command line option .-Wno-foobar." "" { target *-*-* } 0 } */
+/* { dg-warning "unrecognized command line option .-Wno-foobar." "" { target *-*-* } 0 } */
diff --git a/gcc/testsuite/gcc.dg/pragma-message.c b/gcc/testsuite/gcc.dg/pragma-message.c
new file mode 100644
index 00000000000..0f9c6bf447b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pragma-message.c
@@ -0,0 +1,53 @@
+/* Test that #pragma message "..." writes compiler messages. */
+
+#pragma message /* { dg-warning "expected a string" } */
+#pragma message 0 /* { dg-warning "expected a string" } */
+#pragma message id /* { dg-warning "expected a string" } */
+#pragma message ( /* { dg-warning "expected a string" } */
+#pragma message (0 /* { dg-warning "expected a string" } */
+#pragma message (id /* { dg-warning "expected a string" } */
+#pragma message () /* { dg-warning "expected a string" } */
+#pragma message (0) /* { dg-warning "expected a string" } */
+#pragma message (id) /* { dg-warning "expected a string" } */
+
+/* gcc prefixes '#pragma message ...' output with filename and line number,
+ then 'note: #pragma message: ', allowing dg-message to check output.
+ If unexpected pragma messages are printed (anything not caught by a
+ matching dg-message), dejagnu will report these as excess errors. */
+
+#pragma message "
+/* { dg-error "missing terminating" "" { target *-*-* } 18 } */
+/* { dg-warning "expected a string" "" { target *-*-* } 18 } */
+#pragma message "Bad 1
+/* { dg-error "missing terminating" "" { target *-*-* } 21 } */
+/* { dg-warning "expected a string" "" { target *-*-* } 21 } */
+#pragma message ("Bad 2
+/* { dg-error "missing terminating" "" { target *-*-* } 24 } */
+/* { dg-warning "expected a string" "" { target *-*-* } 24 } */
+#pragma message ("Bad 3"
+/* { dg-warning "malformed '#pragma message" "" { target *-*-* } 27 } */
+
+#pragma message "" junk
+/* { dg-warning "junk at end of '#pragma message'" "" { target *-*-* } 30 } */
+
+#pragma message ("") junk
+/* { dg-warning "junk at end of '#pragma message'" "" { target *-*-* } 33 } */
+
+#pragma message "" /* No output expected for empty messages. */
+#pragma message ("")
+
+#pragma message "Okay 1" /* { dg-message "Okay 1" } */
+#pragma message ("Okay 2") /* { dg-message "Okay 2" } */
+#define THREE "3"
+#pragma message ("Okay " THREE) /* { dg-message "Okay 3" } */
+
+/* Create a TODO() that prints a message on compilation. */
+#define DO_PRAGMA(x) _Pragma (#x)
+#define TODO(x) DO_PRAGMA(message ("TODO - " #x))
+TODO(Okay 4) /* { dg-message "TODO - Okay 4" } */
+
+#if 0
+#pragma message ("Not printed")
+#endif
+
+int unused; /* Silence `ISO C forbids an empty translation unit' warning. */
diff --git a/gcc/testsuite/gcc.dg/torture/20080716-1.c b/gcc/testsuite/gcc.dg/torture/20080716-1.c
new file mode 100644
index 00000000000..91fcd2b00d3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/20080716-1.c
@@ -0,0 +1,58 @@
+/* { dg-do run } */
+/* { dg-require-effective-target lp64 } */
+
+typedef unsigned long size_t;
+struct tree_base
+{
+ int code;
+};
+struct tree_decl_minimal
+{
+ struct tree_base base;
+ const char *name;
+};
+typedef union tree_node {
+ struct tree_base base;
+ struct tree_decl_minimal decl_minimal;
+} *tree;
+struct tree_overload
+{
+ struct tree_base common;
+ tree function;
+};
+typedef struct VEC_tree_base { unsigned num; unsigned alloc; tree vec[1]; } VEC_tree_base;
+typedef struct VEC_tree_gc { VEC_tree_base base; } VEC_tree_gc;
+static __inline__ unsigned VEC_tree_base_length (const VEC_tree_base *vec_)
+{ return vec_ ? vec_->num : 0; }
+static __inline__ int VEC_tree_base_iterate (const VEC_tree_base *vec_, unsigned ix_, tree *ptr)
+{
+ if (vec_ && ix_ < vec_->num) { *ptr = vec_->vec[ix_]; return 1; } else { *ptr = 0; return 0; }
+}
+extern void abort (void);
+void __attribute__((noinline)) foo (size_t x)
+{
+ if (x != 18446744073709551614UL)
+ abort ();
+}
+void
+resort_type_method_vec (VEC_tree_gc *method_vec)
+{
+ int len = (VEC_tree_base_length(((method_vec) ? &(method_vec)->base : 0)));
+ size_t slot;
+ tree fn;
+
+ for (slot = 2;
+ (VEC_tree_base_iterate(((method_vec) ? &(method_vec)->base : 0),slot,&(fn)));
+ ++slot)
+ if (!(((((((fn)->base.code) == 225) ? (((struct tree_overload*)(fn))->function) : (fn)))->decl_minimal.name)))
+ break;
+
+ if (len - slot > 1)
+ foo (len - slot);
+}
+
+int main ()
+{
+ resort_type_method_vec ((void *)0);
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/ipa-pta-1.c b/gcc/testsuite/gcc.dg/torture/ipa-pta-1.c
new file mode 100644
index 00000000000..c5adb259d26
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/ipa-pta-1.c
@@ -0,0 +1,40 @@
+/* { dg-do compile } */
+/* { dg-options "-fipa-pta -fdump-ipa-pta" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" } { "" } } */
+
+struct X { char x; char y; };
+
+void bar (char *p);
+
+void test1 (char a, char b, char c, char d, char e, char f, char g, char h)
+{
+ char *p = &a;
+ p++;
+ bar (p);
+}
+
+void test2 (struct X a, char b, char c, char d, char e, char f, char g, char h)
+{
+ char *p = &a.x;
+ p++;
+ bar (p);
+}
+
+void test3 (struct X a, char b, char c, char d, char e, char f, char g, char h)
+{
+ char *p = &a.y;
+ bar (p);
+}
+
+void test4 (int a, char b, char c, char d, char e, char f, char g, char h)
+{
+ char *p = (char *)&a;
+ p++;
+ p++;
+ p++;
+ p++;
+ bar (p);
+}
+
+/* { dg-final { scan-ipa-dump "bar.arg0 = { test4.arg0 test3.arg0 test2.arg0 test1.arg0 }" "pta" } } */
+/* { dg-final { cleanup-ipa-dump "pta" } } */
diff --git a/gcc/testsuite/gcc.dg/torture/pr35842.c b/gcc/testsuite/gcc.dg/torture/pr35842.c
index 05b26d84c11..05b26d84c11 100755..100644
--- a/gcc/testsuite/gcc.dg/torture/pr35842.c
+++ b/gcc/testsuite/gcc.dg/torture/pr35842.c
diff --git a/gcc/testsuite/gcc.dg/torture/pr36373-10.c b/gcc/testsuite/gcc.dg/torture/pr36373-10.c
index b84e2544152..ed701772828 100644
--- a/gcc/testsuite/gcc.dg/torture/pr36373-10.c
+++ b/gcc/testsuite/gcc.dg/torture/pr36373-10.c
@@ -1,6 +1,14 @@
/* { dg-do run } */
+#if (__SIZEOF_LONG_LONG__ == __SIZEOF_POINTER__)
+typedef unsigned long long uintptr_t;
+#elif (__SIZEOF_LONG__ == __SIZEOF_POINTER__)
typedef unsigned long uintptr_t;
+#elif (__SIZEOF_INT__ == __SIZEOF_POINTER__)
+typedef unsigned int uintptr_t;
+#else
+#error Add target support here
+#endif
void __attribute__((noinline))
foo(uintptr_t l)
diff --git a/gcc/testsuite/gcc.dg/torture/pta-ptrarith-1.c b/gcc/testsuite/gcc.dg/torture/pta-ptrarith-1.c
new file mode 100644
index 00000000000..2a8dc9e3037
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pta-ptrarith-1.c
@@ -0,0 +1,33 @@
+/* { dg-do run } */
+/* { dg-options "-fdump-tree-alias" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" } { "" } } */
+
+struct Foo {
+ int *p;
+};
+
+void __attribute__((noinline))
+foo (void *p)
+{
+ struct Foo *f = (struct Foo *)p - 1;
+ *f->p = 0;
+}
+
+int bar (void)
+{
+ struct Foo f;
+ int i = 1;
+ f.p = &i;
+ foo (&f + 1);
+ return i;
+}
+extern void abort (void);
+int main()
+{
+ if (bar () != 0)
+ abort ();
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump "ESCAPED = { ESCAPED NONLOCAL f .* i }" "alias" } } */
+/* { dg-final { cleanup-tree-dump "alias" } } */
diff --git a/gcc/testsuite/gcc.dg/torture/pta-ptrarith-2.c b/gcc/testsuite/gcc.dg/torture/pta-ptrarith-2.c
new file mode 100644
index 00000000000..fb5b2e15ede
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pta-ptrarith-2.c
@@ -0,0 +1,36 @@
+/* { dg-do run } */
+/* { dg-options "-fdump-tree-alias" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" } { "" } } */
+
+struct Foo {
+ int **p;
+ int **q;
+};
+
+int __attribute__((noinline))
+bar (void)
+{
+ struct Foo f;
+ int j, i = 1;
+ char *p;
+ int *x = &i;
+ int *y = &j;
+ f.p = &y;
+ f.q = &x;
+ p = (char *)&f;
+ for (j = 0; j < sizeof (int *); ++j)
+ p++;
+ return ***(int ***)p;
+}
+extern void abort (void);
+int main()
+{
+ if (bar () != 1)
+ abort ();
+ return 0;
+}
+
+/* In theory = { i } is the correct solution. But it's not easy to scan
+ for that reliably, so just use what we create now. */
+/* { dg-final { scan-tree-dump "= { i j }" "alias" } } */
+/* { dg-final { cleanup-tree-dump "alias" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030728-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20030728-1.c
index 3b1ace80f39..1ad2c63653c 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/20030728-1.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20030728-1.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-optimized" } */
+/* { dg-options "-O2 -fdump-tree-final_cleanup" } */
union tree_node;
@@ -42,6 +42,6 @@ objects_must_conflict_p (t1, t2)
}
/* There should be two assignments of variables to the value zero. */
-/* { dg-final { scan-tree-dump-times " = 0" 2 "optimized"} } */
+/* { dg-final { scan-tree-dump-times " = 0" 2 "final_cleanup"} } */
-/* { dg-final { cleanup-tree-dump "optimized" } } */
+/* { dg-final { cleanup-tree-dump "final_cleanup" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20040204-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20040204-1.c
index 28cdfd23181..d7aea1b8430 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/20040204-1.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20040204-1.c
@@ -33,5 +33,5 @@ void test55 (int x, int y)
that the && should be emitted (based on BRANCH_COST). Fix this
by teaching dom to look through && and register all components
as true. */
-/* { dg-final { scan-tree-dump-times "link_error" 0 "optimized" { xfail { ! "powerpc*-*-* cris-*-* crisv32-*-* mmix-*-* mips*-*-*" } } } } */
+/* { dg-final { scan-tree-dump-times "link_error" 0 "optimized" { xfail { ! "powerpc*-*-* cris-*-* crisv32-*-* mmix-*-* mips*-*-* m68k*-*-*" } } } } */
/* { dg-final { cleanup-tree-dump "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20080530.c b/gcc/testsuite/gcc.dg/tree-ssa/20080530.c
new file mode 100644
index 00000000000..6da7cb8a03a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20080530.c
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-einline" } */
+
+void bar (char *);
+int i;
+
+static void
+foo (void)
+{
+ char *p = __builtin_alloca (i);
+ bar (p);
+}
+
+int
+baz (void)
+{
+ foo (); /* foo() should not be inlined here because it calls alloca */
+ return 6;
+}
+
+/* { dg-final { scan-tree-dump-times "Inlining foo into baz" 0 "einline2"} } */
+/* { dg-final { cleanup-tree-dump "einline2" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/data-dep-1.c b/gcc/testsuite/gcc.dg/tree-ssa/data-dep-1.c
index 5eb71d9be9e..92b60999495 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/data-dep-1.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/data-dep-1.c
@@ -25,5 +25,5 @@ int foo (int n, int m)
outermost "k" loop: the 4 comes from the instantiation of the
number of iterations of loop "j". */
-/* { dg-final { scan-tree-dump-times "4, \\+, 1" 0 "ltrans" } } */
+/* { dg-final { scan-tree-dump-times "4, \\+, 1" 0 "ltrans" { xfail *-*-* } } } */
/* { dg-final { cleanup-tree-dump "ltrans" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/loadpre1.c b/gcc/testsuite/gcc.dg/tree-ssa/loadpre1.c
index d3264367db8..e26fa9302b4 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/loadpre1.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/loadpre1.c
@@ -14,5 +14,5 @@ int main(int *a, int argc)
e = *a;
return d + e;
}
-/* { dg-final { scan-tree-dump-times "Eliminated: 1" 1 "pre" { xfail *-*-* } } } */
+/* { dg-final { scan-tree-dump-times "Eliminated: 1" 1 "pre" } } */
/* { dg-final { cleanup-tree-dump "pre" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/loadpre24.c b/gcc/testsuite/gcc.dg/tree-ssa/loadpre24.c
index 1e6b954bfa8..31fcc9f8b74 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/loadpre24.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/loadpre24.c
@@ -18,7 +18,7 @@ int foo(int argc)
return d + e;
}
-/* PRE of globals doesn't work. */
+/* We will move the load of a out of the loop. */
-/* { dg-final { scan-tree-dump-times "Eliminated: 1" 1 "pre" { xfail *-*-* } } } */
+/* { dg-final { scan-tree-dump-times "Eliminated: 1" 1 "pre" } } */
/* { dg-final { cleanup-tree-dump "pre" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr21658.c b/gcc/testsuite/gcc.dg/tree-ssa/pr21658.c
index 577e1795e74..d7b72f9f754 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/pr21658.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr21658.c
@@ -17,5 +17,5 @@ f (void)
link_error ();
}
-/* { dg-final { scan-tree-dump-times "Folded statement: if " 1 "ccp1"} } */
+/* { dg-final { scan-tree-dump-times "Folded into: if " 1 "ccp1"} } */
/* { dg-final { cleanup-tree-dump "ccp\[1-2\]" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr23455.c b/gcc/testsuite/gcc.dg/tree-ssa/pr23455.c
new file mode 100644
index 00000000000..3814d90e373
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr23455.c
@@ -0,0 +1,23 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-pre-stats" } */
+unsigned long outcnt;
+extern void flush_outbuf(void);
+
+void
+bi_windup(unsigned int *outbuf, unsigned int bi_buf)
+{
+ unsigned long t1 = outcnt;
+ outbuf[t1] = bi_buf;
+
+ unsigned long t2 = outcnt;
+ if (t2 == 16384)
+ flush_outbuf();
+
+ unsigned long t3 = outcnt;
+ outbuf[t3] = bi_buf;
+}
+/* We should eliminate one load of outcnt, which will in turn let us eliminate
+ one multiply of outcnt which will in turn let us eliminate
+ one add involving outcnt and outbuf. */
+/* { dg-final { scan-tree-dump-times "Eliminated: 3" 1 "pre"} } */
+/* { dg-final { cleanup-tree-dump "pre" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr30375.c b/gcc/testsuite/gcc.dg/tree-ssa/pr30375.c
index 33c3f5c530c..50b3bfd565a 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/pr30375.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr30375.c
@@ -22,5 +22,5 @@ void test_signed_msg_encoding(void)
f();
}
-/* { dg-final { scan-tree-dump-times "signInfo = {};" 1 "dse1" } } */
+/* { dg-final { scan-tree-dump-times "signInfo = {}" 1 "dse1" } } */
/* { dg-final { cleanup-tree-dump "dse*" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr35286.c b/gcc/testsuite/gcc.dg/tree-ssa/pr35286.c
new file mode 100644
index 00000000000..8601cabeca4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr35286.c
@@ -0,0 +1,23 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-pre-stats" } */
+int g2;
+struct A {
+ int a; int b;
+}g1;
+int foo(int a, int b)
+{
+ if (a > 0)
+ {
+ g1.a = a+ b;
+ }
+ else
+ g1.a = b;
+
+ g2 = a+b;
+
+ return g1.a;
+}
+/* We will eliminate the g1.a from the return statement as fully redundant,
+ and remove one calculation of a + b. */
+/* { dg-final { scan-tree-dump-times "Eliminated: 2" 1 "pre"} } */
+/* { dg-final { cleanup-tree-dump "pre" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr35287.c b/gcc/testsuite/gcc.dg/tree-ssa/pr35287.c
new file mode 100644
index 00000000000..1e976628096
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr35287.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-pre-stats" } */
+int *gp;
+int foo(int p)
+{
+ int t = 0;
+ if (p)
+ t = *gp + 1;
+
+ return (*gp + t);
+}
+
+/* We will eliminate one load of gp and one indirect load of *gp. */
+/* { dg-final { scan-tree-dump-times "Eliminated: 2" 1 "pre"} } */
+/* { dg-final { cleanup-tree-dump "pre" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pta-callused.c b/gcc/testsuite/gcc.dg/tree-ssa/pta-callused.c
new file mode 100644
index 00000000000..c2b512a12e9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pta-callused.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 --param max-fields-for-field-sensitive=2 -fdump-tree-alias" } */
+
+struct Foo {
+ int *p, *q;
+};
+
+int foo (int ***x) __attribute__((pure));
+
+int bar (int b)
+{
+ int i;
+ struct Foo f;
+ int *p, **q;
+ p = &i;
+ f.p = &i;
+ f.q = f.p;
+ if (b)
+ q = &f.p;
+ else
+ q = &f.q;
+ return foo (&q);
+}
+
+/* { dg-final { scan-tree-dump "CALLUSED = { f.* i q }" "alias" } } */
+/* { dg-final { cleanup-tree-dump "alias" } } */
+
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-13.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-13.c
index 3253afe2927..bb48c0a391b 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-13.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-13.c
@@ -25,6 +25,6 @@ void foo(double (*q)[4], struct Foo *tmp1)
}
}
-/* { dg-final { scan-tree-dump "Inserted .* &a" "fre" } } */
-/* { dg-final { scan-tree-dump "Replaced tmp1_.\\\(D\\\)->data" "fre" } } */
+/* { dg-final { scan-tree-dump "Inserted .* &a" "fre" { xfail *-*-* } } } */
+/* { dg-final { scan-tree-dump "Replaced tmp1_.\\\(D\\\)->data" "fre" { xfail *-*-* } } } */
/* { dg-final { cleanup-tree-dump "fre" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-14.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-14.c
index d2d5e01bcc4..61c5e00b554 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-14.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-14.c
@@ -27,6 +27,6 @@ void foo(double (*q)[4])
}
}
-/* { dg-final { scan-tree-dump "Inserted .* &a" "fre" } } */
-/* { dg-final { scan-tree-dump "Replaced tmp1.data" "fre" } } */
+/* { dg-final { scan-tree-dump "Inserted .* &a" "fre" { xfail *-*-* } } } */
+/* { dg-final { scan-tree-dump "Replaced tmp1.data" "fre" { xfail *-*-* } } } */
/* { dg-final { cleanup-tree-dump "fre" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-17.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-17.c
index aced64977ea..68fbb454c76 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-17.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-17.c
@@ -18,6 +18,6 @@ int foo(int i, int j, int k)
return f.doms[0LL].dom;
}
-/* { dg-final { scan-tree-dump "Replaced f.doms\\\[0\\\].dom with i_" "fre" } } */
+/* { dg-final { scan-tree-dump "Replaced f.doms\\\[0\\\].dom with i_" "fre" { xfail *-*-* } } } */
/* { dg-final { cleanup-tree-dump "fre" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-7.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-7.c
index bd81831eba8..d93a1a21456 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-7.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-7.c
@@ -29,10 +29,10 @@ intflt foo(intflt j)
return a.u.k;
}
-/* { dg-final { scan-tree-dump-times "Inserted pretmp" 1 "fre" } } */
-/* { dg-final { scan-tree-dump-times "Replaced a.u.f with pretmp" 3 "fre" } } */
-/* { dg-final { scan-tree-dump-times "Replaced a.u.k with j" 1 "fre" } } */
-/* { dg-final { scan-tree-dump "= VIEW_CONVERT_EXPR<float>\\\(j_" "fre" } } */
-/* { dg-final { scan-tree-dump "return j" "optimized" } } */
+/* { dg-final { scan-tree-dump-times "Inserted pretmp" 1 "fre" { xfail *-*-* } } } */
+/* { dg-final { scan-tree-dump-times "Replaced a.u.f with pretmp" 3 "fre" { xfail *-*-* } } } */
+/* { dg-final { scan-tree-dump-times "Replaced a.u.k with j" 1 "fre" { xfail *-*-* } } } */
+/* { dg-final { scan-tree-dump "= VIEW_CONVERT_EXPR<float>\\\(j_" "fre" { xfail *-*-* } } } */
+/* { dg-final { scan-tree-dump "return j" "optimized" { xfail *-*-* } } } */
/* { dg-final { cleanup-tree-dump "fre" } } */
/* { dg-final { cleanup-tree-dump "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-8.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-8.c
index 6e17bd531b3..1494dbbbd94 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-8.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-8.c
@@ -28,6 +28,6 @@ intflt foo(int i, int b)
}
}
-/* { dg-final { scan-tree-dump-times "Replaced u.f with pretmp" 2 "fre" } } */
-/* { dg-final { scan-tree-dump-times "Inserted pretmp" 2 "fre" } } */
+/* { dg-final { scan-tree-dump-times "Replaced u.f with pretmp" 2 "fre" { xfail *-*-* } } } */
+/* { dg-final { scan-tree-dump-times "Inserted pretmp" 2 "fre" { xfail *-*-* } } } */
/* { dg-final { cleanup-tree-dump "fre" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-9.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-9.c
index 18595ed6fe5..24c4ae37167 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-9.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-9.c
@@ -23,6 +23,6 @@ void __frame_state_for1 (volatile char *state_in)
}
}
-/* { dg-final { scan-tree-dump-times "Eliminated: 1" 2 "fre" } } */
-/* { dg-final { scan-tree-dump-times "Insertions: 1" 2 "fre" } } */
+/* { dg-final { scan-tree-dump-times "Eliminated: 1" 2 "fre" { xfail *-*-* } } } */
+/* { dg-final { scan-tree-dump-times "Insertions: 1" 2 "fre" { xfail *-*-* } } } */
/* { dg-final { cleanup-tree-dump "fre" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-15.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-15.c
index 518fda854e6..f080989d1de 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-15.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-15.c
@@ -12,5 +12,5 @@ __SIZE_TYPE__ mystrlen (const char *s)
return strlen(s);
}
-/* { dg-final { scan-tree-dump "= 0;" "optimized" } } */
+/* { dg-final { scan-tree-dump "= 0;" "optimized" { xfail *-*-* } } } */
/* { dg-final { cleanup-tree-dump "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/tailcall-3.c b/gcc/testsuite/gcc.dg/tree-ssa/tailcall-3.c
new file mode 100644
index 00000000000..4055bc3f52d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/tailcall-3.c
@@ -0,0 +1,28 @@
+/* The return argument needs a type conversion which on some targets
+ (e.g. s390) needs additional code. So it is invalid to do tail
+ call optimization here. */
+
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+extern void abort (void);
+
+long long __attribute__((noinline))
+foo ()
+{
+ return 3;
+}
+
+int __attribute__((noinline))
+boo ()
+{
+ return foo ();
+}
+
+int
+main ()
+{
+ if (boo () != 3)
+ abort ();
+}
+
diff --git a/gcc/testsuite/gcc.dg/utf-array-short-wchar.c b/gcc/testsuite/gcc.dg/utf-array-short-wchar.c
new file mode 100644
index 00000000000..7d8c319d99a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/utf-array-short-wchar.c
@@ -0,0 +1,41 @@
+/* Contributed by Kris Van Hees <kris.van.hees@oracle.com> */
+/* Expected errors for char16_t/char32_t string literals. */
+/* { dg-do compile } */
+/* { dg-options "-std=gnu99 -fshort-wchar" } */
+
+#include <wchar.h>
+
+typedef short unsigned int char16_t;
+typedef unsigned int char32_t;
+
+const char s_0[] = "ab";
+const char s_1[] = u"ab"; /* { dg-error "from wide string" } */
+const char s_2[] = U"ab"; /* { dg-error "from wide string" } */
+const char s_3[] = L"ab"; /* { dg-error "from wide string" } */
+
+const char16_t s16_0[] = "ab"; /* { dg-error "from non-wide" } */
+const char16_t s16_1[] = u"ab";
+const char16_t s16_2[] = U"ab"; /* { dg-error "from incompatible" } */
+const char16_t s16_3[] = L"ab";
+
+const char16_t s16_4[0] = u"ab"; /* { dg-warning "chars is too long" } */
+const char16_t s16_5[1] = u"ab"; /* { dg-warning "chars is too long" } */
+const char16_t s16_6[2] = u"ab";
+const char16_t s16_7[3] = u"ab";
+const char16_t s16_8[4] = u"ab";
+
+const char32_t s32_0[] = "ab"; /* { dg-error "from non-wide" } */
+const char32_t s32_1[] = u"ab"; /* { dg-error "from incompatible" } */
+const char32_t s32_2[] = U"ab";
+const char32_t s32_3[] = L"ab"; /* { dg-error "from incompatible" } */
+
+const char32_t s32_4[0] = U"ab"; /* { dg-warning "chars is too long" } */
+const char32_t s32_5[1] = U"ab"; /* { dg-warning "chars is too long" } */
+const char32_t s32_6[2] = U"ab";
+const char32_t s32_7[3] = U"ab";
+const char32_t s32_8[4] = U"ab";
+
+const wchar_t sw_0[] = "ab"; /* { dg-error "from non-wide" } */
+const wchar_t sw_1[] = u"ab";
+const wchar_t sw_2[] = U"ab"; /* { dg-error "from incompatible" } */
+const wchar_t sw_3[] = L"ab";
diff --git a/gcc/testsuite/gcc.dg/utf-array.c b/gcc/testsuite/gcc.dg/utf-array.c
new file mode 100644
index 00000000000..50a29fe9375
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/utf-array.c
@@ -0,0 +1,41 @@
+/* Contributed by Kris Van Hees <kris.van.hees@oracle.com> */
+/* Expected errors for char16_t/char32_t string literals. */
+/* { dg-do compile } */
+/* { dg-options "-std=gnu99" } */
+
+#include <wchar.h>
+
+typedef short unsigned int char16_t;
+typedef unsigned int char32_t;
+
+const char s_0[] = "ab";
+const char s_1[] = u"ab"; /* { dg-error "from wide string" } */
+const char s_2[] = U"ab"; /* { dg-error "from wide string" } */
+const char s_3[] = L"ab"; /* { dg-error "from wide string" } */
+
+const char16_t s16_0[] = "ab"; /* { dg-error "from non-wide" } */
+const char16_t s16_1[] = u"ab";
+const char16_t s16_2[] = U"ab"; /* { dg-error "from incompatible" } */
+const char16_t s16_3[] = L"ab"; /* { dg-error "from incompatible" } */
+
+const char16_t s16_4[0] = u"ab"; /* { dg-warning "chars is too long" } */
+const char16_t s16_5[1] = u"ab"; /* { dg-warning "chars is too long" } */
+const char16_t s16_6[2] = u"ab";
+const char16_t s16_7[3] = u"ab";
+const char16_t s16_8[4] = u"ab";
+
+const char32_t s32_0[] = "ab"; /* { dg-error "from non-wide" } */
+const char32_t s32_1[] = u"ab"; /* { dg-error "from incompatible" } */
+const char32_t s32_2[] = U"ab";
+const char32_t s32_3[] = L"ab"; /* { dg-error "from incompatible" } */
+
+const char32_t s32_4[0] = U"ab"; /* { dg-warning "chars is too long" } */
+const char32_t s32_5[1] = U"ab"; /* { dg-warning "chars is too long" } */
+const char32_t s32_6[2] = U"ab";
+const char32_t s32_7[3] = U"ab";
+const char32_t s32_8[4] = U"ab";
+
+const wchar_t sw_0[] = "ab"; /* { dg-error "from non-wide" } */
+const wchar_t sw_1[] = u"ab"; /* { dg-error "from incompatible" } */
+const wchar_t sw_2[] = U"ab"; /* { dg-error "from incompatible" } */
+const wchar_t sw_3[] = L"ab";
diff --git a/gcc/testsuite/gcc.dg/utf-inc-init.c b/gcc/testsuite/gcc.dg/utf-inc-init.c
new file mode 100644
index 00000000000..17d59f3782f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/utf-inc-init.c
@@ -0,0 +1,45 @@
+/* Contributed by Kris Van Hees <kris.van.hees@oracle.com> */
+/* Test incremental initializers for char16_t/char32_t arrays. */
+/* { dg-do run } */
+/* { dg-options "-std=gnu99" } */
+
+typedef __SIZE_TYPE__ size_t;
+typedef short unsigned int char16_t;
+typedef unsigned int char32_t;
+
+extern int memcmp (const void *, const void *, size_t);
+extern void abort (void);
+extern void exit (int);
+
+struct A {
+ char16_t S[6];
+ int M;
+} a[] = { { { u"foo" }, 1 }, [0].S[2] = u'x', [0].S[4] = u'y' };
+struct A b[] = { { { u"foo" }, 1 }, [0] = { .S[0] = u'b' } };
+struct A c[] = { { { u"foo" }, 1 }, [0].S = { u"a" }, [0].M = 2 };
+
+struct B {
+ char32_t S[6];
+ int M;
+} d[] = { { { U"foo" }, 1 }, [0].S[2] = U'x', [0].S[4] = U'y' };
+struct B e[] = { { { U"foo" }, 1 }, [0] = { .S[0] = U'b' } };
+struct B f[] = { { { U"foo" }, 1 }, [0].S = { U"a" }, [0].M = 2 };
+
+int main (void)
+{
+ if (memcmp (a[0].S, u"fox\0y", 6 * sizeof(char16_t)) || a[0].M != 1)
+ abort ();
+ if (memcmp (b[0].S, u"b\0\0\0\0", 6) || b[0].M)
+ abort ();
+ if (memcmp (c[0].S, u"a\0\0\0\0", 6) || c[0].M != 2)
+ abort ();
+
+ if (memcmp (d[0].S, U"fox\0y", 6 * sizeof(char32_t)) || d[0].M != 1)
+ abort ();
+ if (memcmp (e[0].S, U"b\0\0\0\0", 6) || e[0].M)
+ abort ();
+ if (memcmp (f[0].S, U"a\0\0\0\0", 6) || f[0].M != 2)
+ abort ();
+
+ exit(0);
+}
diff --git a/gcc/testsuite/gcc.dg/utf-type.c b/gcc/testsuite/gcc.dg/utf-type.c
new file mode 100644
index 00000000000..1aa6020cbef
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/utf-type.c
@@ -0,0 +1,18 @@
+/* Contributed by Kris Van Hees <kris.van.hees@oracle.com> */
+/* Ensure that __CHAR16_TYPE__ and __CHAR32_TYPE__ exist, and are of the
+ correct width. */
+/* { dg-do run } */
+/* { dg-options "-std=gnu99 -Wall -Werror" } */
+
+typedef __CHAR16_TYPE__ char16_t;
+typedef __CHAR32_TYPE__ char32_t;
+
+extern void abort (void);
+
+int main ()
+{
+ if (sizeof (char16_t) != sizeof (u'a'))
+ abort();
+ if (sizeof (char32_t) != sizeof (U'a'))
+ abort();
+}
diff --git a/gcc/testsuite/gcc.dg/vect/fast-math-vect-complex-3.c b/gcc/testsuite/gcc.dg/vect/fast-math-vect-complex-3.c
new file mode 100644
index 00000000000..1dff116dd5a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/fast-math-vect-complex-3.c
@@ -0,0 +1,61 @@
+/* { dg-require-effective-target vect_float } */
+
+#include <stdio.h>
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define N 16
+
+_Complex float a[N] =
+ { 10.0F + 20.0iF, 11.0F + 21.0iF, 12.0F + 22.0iF, 13.0F + 23.0iF,
+ 14.0F + 24.0iF, 15.0F + 25.0iF, 16.0F + 26.0iF, 17.0F + 27.0iF,
+ 18.0F + 28.0iF, 19.0F + 29.0iF, 20.0F + 30.0iF, 21.0F + 31.0iF,
+ 22.0F + 32.0iF, 23.0F + 33.0iF, 24.0F + 34.0iF, 25.0F + 35.0iF };
+_Complex float b[N] =
+ { 30.0F + 40.0iF, 31.0F + 41.0iF, 32.0F + 42.0iF, 33.0F + 43.0iF,
+ 34.0F + 44.0iF, 35.0F + 45.0iF, 36.0F + 46.0iF, 37.0F + 47.0iF,
+ 38.0F + 48.0iF, 39.0F + 49.0iF, 40.0F + 50.0iF, 41.0F + 51.0iF,
+ 42.0F + 52.0iF, 43.0F + 53.0iF, 44.0F + 54.0iF, 45.0F + 55.0iF };
+
+_Complex float c[N];
+_Complex float res[N] =
+ { -500.0F + 1000.0iF, -520.0F + 1102.0iF,
+ -540.0F + 1208.0iF, -560.0F + 1318.0iF,
+ -580.0F + 1432.0iF, -600.0F + 1550.0iF,
+ -620.0F + 1672.0iF, -640.0F + 1798.0iF,
+ -660.0F + 1928.0iF, -680.0F + 2062.0iF,
+ -700.0F + 2200.0iF, -720.0F + 2342.0iF,
+ -740.0F + 2488.0iF, -760.0F + 2638.0iF,
+ -780.0F + 2792.0iF, -800.0F + 2950.0iF };
+
+
+__attribute__ ((noinline)) void
+foo (void)
+{
+ int i;
+
+ for (i = 0; i < N; i++)
+ c[i] = a[i] * b[i];
+
+}
+
+int
+main (void)
+{
+ int i;
+ check_vect ();
+
+ foo ();
+
+ /* check results: */
+ for (i = 0; i < N; i++)
+ {
+ if (c[i] != res[i])
+ abort ();
+ }
+
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { vect_interleave && vect_extract_even_odd } } } } */
+/* { dg-final { cleanup-tree-dump "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-complex-1.c b/gcc/testsuite/gcc.dg/vect/vect-complex-1.c
new file mode 100644
index 00000000000..9be88644b63
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-complex-1.c
@@ -0,0 +1,56 @@
+/* { dg-require-effective-target vect_float } */
+
+#include <stdio.h>
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define N 16
+
+_Complex float a[N] =
+ { 10.0F + 20.0iF, 11.0F + 21.0iF, 12.0F + 22.0iF, 13.0F + 23.0iF,
+ 14.0F + 24.0iF, 15.0F + 25.0iF, 16.0F + 26.0iF, 17.0F + 27.0iF,
+ 18.0F + 28.0iF, 19.0F + 29.0iF, 20.0F + 30.0iF, 21.0F + 31.0iF,
+ 22.0F + 32.0iF, 23.0F + 33.0iF, 24.0F + 34.0iF, 25.0F + 35.0iF };
+_Complex float b[N] =
+ { 30.0F + 40.0iF, 31.0F + 41.0iF, 32.0F + 42.0iF, 33.0F + 43.0iF,
+ 34.0F + 44.0iF, 35.0F + 45.0iF, 36.0F + 46.0iF, 37.0F + 47.0iF,
+ 38.0F + 48.0iF, 39.0F + 49.0iF, 40.0F + 50.0iF, 41.0F + 51.0iF,
+ 42.0F + 52.0iF, 43.0F + 53.0iF, 44.0F + 54.0iF, 45.0F + 55.0iF };
+
+_Complex float c[N];
+_Complex float res[N] =
+ { 40.0F + 60.0iF, 42.0F + 62.0iF, 44.0F + 64.0iF, 46.0F + 66.0iF,
+ 48.0F + 68.0iF, 50.0F + 70.0iF, 52.0F + 72.0iF, 54.0F + 74.0iF,
+ 56.0F + 76.0iF, 58.0F + 78.0iF, 60.0F + 80.0iF, 62.0F + 82.0iF,
+ 64.0F + 84.0iF, 66.0F + 86.0iF, 68.0F + 88.0iF, 70.0F + 90.0iF };
+
+
+__attribute__ ((noinline)) void
+foo (void)
+{
+ int i;
+
+ for (i = 0; i < N; i++)
+ c[i] = a[i] + b[i];
+
+}
+
+int
+main (void)
+{
+ int i;
+ check_vect ();
+
+ foo ();
+
+ /* check results: */
+ for (i = 0; i < N; i++)
+ if (c[i] != res[i])
+ abort ();
+
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */
+/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" } } */
+/* { dg-final { cleanup-tree-dump "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-complex-2.c b/gcc/testsuite/gcc.dg/vect/vect-complex-2.c
new file mode 100644
index 00000000000..a034082cd4d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-complex-2.c
@@ -0,0 +1,56 @@
+/* { dg-require-effective-target vect_double } */
+
+#include <stdio.h>
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define N 16
+
+_Complex double a[N] =
+ { 10.0F + 20.0iF, 11.0F + 21.0iF, 12.0F + 22.0iF, 13.0F + 23.0iF,
+ 14.0F + 24.0iF, 15.0F + 25.0iF, 16.0F + 26.0iF, 17.0F + 27.0iF,
+ 18.0F + 28.0iF, 19.0F + 29.0iF, 20.0F + 30.0iF, 21.0F + 31.0iF,
+ 22.0F + 32.0iF, 23.0F + 33.0iF, 24.0F + 34.0iF, 25.0F + 35.0iF };
+_Complex double b[N] =
+ { 30.0F + 40.0iF, 31.0F + 41.0iF, 32.0F + 42.0iF, 33.0F + 43.0iF,
+ 34.0F + 44.0iF, 35.0F + 45.0iF, 36.0F + 46.0iF, 37.0F + 47.0iF,
+ 38.0F + 48.0iF, 39.0F + 49.0iF, 40.0F + 50.0iF, 41.0F + 51.0iF,
+ 42.0F + 52.0iF, 43.0F + 53.0iF, 44.0F + 54.0iF, 45.0F + 55.0iF };
+
+_Complex double c[N];
+_Complex double res[N] =
+ { 40.0F + 60.0iF, 42.0F + 62.0iF, 44.0F + 64.0iF, 46.0F + 66.0iF,
+ 48.0F + 68.0iF, 50.0F + 70.0iF, 52.0F + 72.0iF, 54.0F + 74.0iF,
+ 56.0F + 76.0iF, 58.0F + 78.0iF, 60.0F + 80.0iF, 62.0F + 82.0iF,
+ 64.0F + 84.0iF, 66.0F + 86.0iF, 68.0F + 88.0iF, 70.0F + 90.0iF };
+
+
+__attribute__ ((noinline)) void
+foo (void)
+{
+ int i;
+
+ for (i = 0; i < N; i++)
+ c[i] = a[i] + b[i];
+
+}
+
+int
+main (void)
+{
+ int i;
+ check_vect ();
+
+ foo ();
+
+ /* check results: */
+ for (i = 0; i < N; i++)
+ if (c[i] != res[i])
+ abort ();
+
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */
+/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" } } */
+/* { dg-final { cleanup-tree-dump "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-complex-4.c b/gcc/testsuite/gcc.dg/vect/vect-complex-4.c
new file mode 100644
index 00000000000..85c416597f6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-complex-4.c
@@ -0,0 +1,109 @@
+/* { dg-require-effective-target vect_int } */
+
+#include <stdio.h>
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define N 16
+
+struct foostr {
+ _Complex short f1;
+ _Complex short f2;
+};
+
+struct foostr a[16] __attribute__ ((__aligned__(16))) =
+ {
+ 11 + 23i, 24 + 22i,
+ 11 + 26i, 24 + 35i,
+ 19 + 20i, 29 + 14i,
+ 23 + 31i, 26 + 30i,
+ 29 + 39i, 24 + 18i,
+ 20 + 32i, 16 + 23i,
+ 13 + 26i, 37 + 34i,
+ 12 + 23i, 26 + 14i,
+ 36 + 14i, 31 + 17i,
+ 35 + 17i, 17 + 36i,
+ 13 + 34i, 19 + 12i,
+ 27 + 34i, 36 + 19i,
+ 21 + 39i, 16 + 33i,
+ 28 + 18i, 39 + 26i,
+ 32 + 27i, 13 + 38i,
+ 35 + 36i, 34 + 28i,
+ };
+
+struct foostr b[16] __attribute__ ((__aligned__(16))) =
+ {
+ 37 + 12i, 23 + 15i,
+ 14 + 11i, 13 + 25i,
+ 35 + 29i, 22 + 34i,
+ 24 + 34i, 16 + 39i,
+ 34 + 32i, 26 + 21i,
+ 34 + 36i, 11 + 37i,
+ 25 + 21i, 10 + 39i,
+ 10 + 36i, 35 + 22i,
+ 39 + 29i, 23 + 21i,
+ 34 + 33i, 39 + 14i,
+ 16 + 31i, 32 + 33i,
+ 20 + 14i, 35 + 30i,
+ 26 + 24i, 36 + 37i,
+ 31 + 20i, 32 + 28i,
+ 25 + 27i, 15 + 30i,
+ 10 + 31i, 37 + 37i,
+ };
+struct foostr c[16] __attribute__ ((__aligned__(16)));
+struct foostr res[N] =
+ {
+ 48 + 35i, 47 + 37i,
+ 25 + 37i, 37 + 60i,
+ 54 + 49i, 51 + 48i,
+ 47 + 65i, 42 + 69i,
+ 63 + 71i, 50 + 39i,
+ 54 + 68i, 27 + 60i,
+ 38 + 47i, 47 + 73i,
+ 22 + 59i, 61 + 36i,
+ 75 + 43i, 54 + 38i,
+ 69 + 50i, 56 + 50i,
+ 29 + 65i, 51 + 45i,
+ 47 + 48i, 71 + 49i,
+ 47 + 63i, 52 + 70i,
+ 59 + 38i, 71 + 54i,
+ 57 + 54i, 28 + 68i,
+ 45 + 67i, 71 + 65i,
+ };
+
+__attribute__ ((noinline)) void
+foo (void)
+{
+ int i;
+
+ for (i = 0; i < N; i++)
+ {
+ c[i].f1 = a[i].f1 + b[i].f1;
+ c[i].f2 = a[i].f2 + b[i].f2;
+ }
+
+}
+
+int
+main (void)
+{
+ int i;
+ check_vect ();
+
+ foo ();
+
+ /* check results: */
+ for (i = 0; i < N; i++)
+ {
+ if (c[i].f1 != res[i].f1)
+ abort ();
+ if (c[i].f2 != res[i].f2)
+ abort ();
+ }
+
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */
+/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" } } */
+/* { dg-final { cleanup-tree-dump "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vmx/1b-06-ansi.c b/gcc/testsuite/gcc.dg/vmx/1b-06-ansi.c
new file mode 100644
index 00000000000..780a4e6bc68
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/1b-06-ansi.c
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-options "-ansi -maltivec" } */
+
+#include <altivec.h>
+vector char bool _4 ;
+vector char unsigned _31 ;
+vector char signed _59 ;
+/* bool is permitted in the predefine method, as it is expanded
+ unconditionally to int. */
+bool _84 ;
+vector pixel _89 ;
+vector int bool _95 ;
+vector short bool _102 ;
+vector unsigned int _122 ;
+vector unsigned short _129 ;
+vector signed int _150 ;
+vector signed short _157 ;
+vector int bool _179 ;
+vector int short bool _186 ;
+vector unsigned int _206 ;
+vector int unsigned short _213 ;
+vector signed int _234 ;
+vector int signed short _241 ;
+vector float _339 ;
diff --git a/gcc/testsuite/gcc.dg/vmx/1b-06.c b/gcc/testsuite/gcc.dg/vmx/1b-06.c
index 84c69813ce4..d25164c3151 100644
--- a/gcc/testsuite/gcc.dg/vmx/1b-06.c
+++ b/gcc/testsuite/gcc.dg/vmx/1b-06.c
@@ -3,7 +3,6 @@
vector char bool _4 ;
vector char unsigned _31 ;
vector char signed _59 ;
-bool _84 ;
vector pixel _89 ;
vector int bool _95 ;
vector short bool _102 ;
diff --git a/gcc/testsuite/gcc.dg/vmx/1b-07-ansi.c b/gcc/testsuite/gcc.dg/vmx/1b-07-ansi.c
new file mode 100644
index 00000000000..cfc98639b55
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vmx/1b-07-ansi.c
@@ -0,0 +1,59 @@
+/* { dg-do compile } */
+/* { dg-options "-ansi -maltivec" } */
+
+#include <altivec.h>
+vector char bool _0 ;
+vector bool char _8 ;
+vector char unsigned _56 ;
+vector unsigned char _64 ;
+vector char signed _112 ;
+vector signed char _120 ;
+/* bool is permitted in the predefine method, as it is expanded
+ unconditionally to int. */
+bool _168 ;
+vector pixel _170 ;
+vector int bool _178 ;
+vector bool int _186 ;
+vector short bool _234 ;
+vector bool short _242 ;
+vector unsigned int _290 ;
+vector int unsigned _298 ;
+vector unsigned short _346 ;
+vector short unsigned _354 ;
+vector signed int _402 ;
+vector int signed _410 ;
+vector signed short _458 ;
+vector short signed _466 ;
+vector int bool _514 ;
+vector int bool _544 ;
+vector int bool _559 ;
+vector bool int _589 ;
+vector int short bool _874 ;
+vector int bool short _889 ;
+vector short int bool _904 ;
+vector short bool int _919 ;
+vector bool int short _934 ;
+vector bool short int _949 ;
+vector unsigned int _1234 ;
+vector int unsigned _1249 ;
+vector unsigned int _1279 ;
+vector int unsigned _1294 ;
+vector unsigned int _1309 ;
+vector int unsigned short _1594 ;
+vector int short unsigned _1609 ;
+vector unsigned int short _1624 ;
+vector unsigned short int _1639 ;
+vector short int unsigned _1654 ;
+vector short unsigned int _1669 ;
+vector signed int _1954 ;
+vector int signed _1969 ;
+vector signed int _1999 ;
+vector int signed _2014 ;
+vector signed int _2029 ;
+vector int signed short _2314 ;
+vector int short signed _2329 ;
+vector signed int short _2344 ;
+vector signed short int _2359 ;
+vector short int signed _2374 ;
+vector short signed int _2389 ;
+vector float _2674 ;
diff --git a/gcc/testsuite/gcc.dg/vmx/1b-07.c b/gcc/testsuite/gcc.dg/vmx/1b-07.c
index b1f4bb6e8a3..44bf4029f08 100644
--- a/gcc/testsuite/gcc.dg/vmx/1b-07.c
+++ b/gcc/testsuite/gcc.dg/vmx/1b-07.c
@@ -6,7 +6,6 @@ vector char unsigned _56 ;
vector unsigned char _64 ;
vector char signed _112 ;
vector signed char _120 ;
-bool _168 ;
vector pixel _170 ;
vector int bool _178 ;
vector bool int _186 ;
diff --git a/gcc/testsuite/gcc.dg/wdisallowed-functions-1.c b/gcc/testsuite/gcc.dg/wdisallowed-functions-1.c
new file mode 100644
index 00000000000..39760950d69
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/wdisallowed-functions-1.c
@@ -0,0 +1,7 @@
+/* { dg-do compile } */
+/* { dg-options "-Wdisallowed-function-list=foobar" } */
+
+int foobar (int i)
+{
+ return (i * 5);
+}
diff --git a/gcc/testsuite/gcc.dg/wdisallowed-functions-2.c b/gcc/testsuite/gcc.dg/wdisallowed-functions-2.c
new file mode 100644
index 00000000000..ca5aab0e50d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/wdisallowed-functions-2.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-Wdisallowed-function-list=foo,foobar,bar,foobar" } */
+
+int foobar (int i)
+{
+ return (i * 5);
+}
+
+int foobar1 (int i)
+{
+ return foobar (i); /* { dg-warning "disallowed call to 'foobar'" } */
+}
diff --git a/gcc/testsuite/gcc.dg/winline-4.c b/gcc/testsuite/gcc.dg/winline-4.c
deleted file mode 100644
index 5ce0a02202d..00000000000
--- a/gcc/testsuite/gcc.dg/winline-4.c
+++ /dev/null
@@ -1,11 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-Winline -O1 -fno-unit-at-a-time" } */
-
-inline int q(void); /* { dg-warning "body not available" } */
-inline int t(void)
-{
- return q(); /* { dg-warning "called from here" } */
-}
-int q(void)
-{
-}
diff --git a/gcc/testsuite/gcc.target/i386/20080723-1.c b/gcc/testsuite/gcc.target/i386/20080723-1.c
new file mode 100644
index 00000000000..a2ed5bf86df
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/20080723-1.c
@@ -0,0 +1,49 @@
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+
+extern void abort (void);
+extern void exit (int);
+
+static inline __attribute__((always_inline))
+void
+prefetch (void *x)
+{
+ asm volatile("prefetcht0 %0" : : "m" (*(unsigned long *)x));
+}
+
+struct hlist_head
+{
+ struct hlist_node *first;
+};
+
+struct hlist_node
+{
+ struct hlist_node *next;
+ unsigned long i_ino;
+};
+
+struct hlist_node * find_inode_fast(struct hlist_head *head, unsigned long ino)
+{
+ struct hlist_node *node;
+
+ for (node = head->first;
+ node && (prefetch (node->next), 1);
+ node = node->next)
+ {
+ if (node->i_ino == ino)
+ break;
+ }
+ return node ? node : 0;
+}
+
+struct hlist_node g2;
+struct hlist_node g1 = { &g2 };
+struct hlist_head h = { &g1 };
+
+int
+main()
+{
+ if (find_inode_fast (&h, 1) != 0)
+ abort ();
+ exit (0);
+}
diff --git a/gcc/testsuite/gcc.target/i386/cmov8.c b/gcc/testsuite/gcc.target/i386/cmov8.c
new file mode 100644
index 00000000000..639fb62b0c0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/cmov8.c
@@ -0,0 +1,13 @@
+/* PR target/36936 */
+/* { dg-do compile } */
+/* { dg-require-effective-target ilp32 } */
+/* { dg-options "-O2 -march=i686" } */
+/* { dg-final { scan-assembler "cmov\[^8\]" } } */
+
+int
+foo (int x)
+{
+ if (x < 0)
+ x = 1;
+ return x;
+}
diff --git a/gcc/testsuite/gcc.target/i386/cold-1.c b/gcc/testsuite/gcc.target/i386/cold-1.c
new file mode 100644
index 00000000000..bcdc471eb58
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/cold-1.c
@@ -0,0 +1,13 @@
+/* Test whether using attribute((cold)) really turns on -Os. Do this test
+ by checking whether strcpy calls the library function rather than doing
+ the move inline. */
+/* { dg-do compile } */
+/* { dg-options "-O3 -march=k8" } */
+/* { dg-final { scan-assembler "(jmp|call)\t(.*)strcpy" } } */
+
+void cold (char *) __attribute__((__cold__));
+
+void cold (char *a)
+{
+ __builtin_strcpy (a, "testing 1.2.3 testing 1.2.3");
+}
diff --git a/gcc/testsuite/gcc.target/i386/funcspec-1.c b/gcc/testsuite/gcc.target/i386/funcspec-1.c
new file mode 100644
index 00000000000..1ee43a0bbb8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/funcspec-1.c
@@ -0,0 +1,34 @@
+/* Test whether using target specific options, we can generate SSE2 code on
+ 32-bit, which does not generate SSE2 by default, but still generate 387 code
+ for a function that doesn't use attribute((option)). */
+/* { dg-do compile } */
+/* { dg-require-effective-target ilp32 } */
+/* { dg-options "-O3 -ftree-vectorize -march=i386" } */
+/* { dg-final { scan-assembler "addps\[ \t\]" } } */
+/* { dg-final { scan-assembler "fsubs\[ \t\]" } } */
+
+#ifndef SIZE
+#define SIZE 1024
+#endif
+
+static float a[SIZE] __attribute__((__aligned__(16)));
+static float b[SIZE] __attribute__((__aligned__(16)));
+static float c[SIZE] __attribute__((__aligned__(16)));
+
+void sse_addnums (void) __attribute__ ((__option__ ("sse2")));
+
+void
+sse_addnums (void)
+{
+ int i = 0;
+ for (; i < SIZE; ++i)
+ a[i] = b[i] + c[i];
+}
+
+void
+i387_subnums (void)
+{
+ int i = 0;
+ for (; i < SIZE; ++i)
+ a[i] = b[i] - c[i];
+}
diff --git a/gcc/testsuite/gcc.target/i386/funcspec-10.c b/gcc/testsuite/gcc.target/i386/funcspec-10.c
new file mode 100644
index 00000000000..9446cdf8f35
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/funcspec-10.c
@@ -0,0 +1,15 @@
+/* PR target/36936 */
+/* { dg-do compile } */
+/* { dg-require-effective-target ilp32 } */
+/* { dg-options "-O2 -march=i686" } */
+/* { dg-final { scan-assembler-not "cmov" } } */
+
+extern int foo (int) __attribute__((__option__("arch=i386")));
+
+int
+foo (int x)
+{
+ if (x < 0)
+ x = 1;
+ return x;
+}
diff --git a/gcc/testsuite/gcc.target/i386/funcspec-11.c b/gcc/testsuite/gcc.target/i386/funcspec-11.c
new file mode 100644
index 00000000000..ec32e0c669e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/funcspec-11.c
@@ -0,0 +1,15 @@
+/* PR target/36936 */
+/* { dg-do compile } */
+/* { dg-require-effective-target ilp32 } */
+/* { dg-options "-O2 -march=i386" } */
+/* { dg-final { scan-assembler "cmov" } } */
+
+extern int foo (int) __attribute__((__option__("arch=i686")));
+
+int
+foo (int x)
+{
+ if (x < 0)
+ x = 1;
+ return x;
+}
diff --git a/gcc/testsuite/gcc.target/i386/funcspec-2.c b/gcc/testsuite/gcc.target/i386/funcspec-2.c
new file mode 100644
index 00000000000..eb6f48bae1f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/funcspec-2.c
@@ -0,0 +1,99 @@
+/* Test whether using target specific options, we can generate SSE5 code. */
+/* { dg-do compile } */
+/* { dg-require-effective-target lp64 } */
+/* { dg-options "-O2 -march=k8" } */
+
+extern void exit (int);
+
+#define SSE5_ATTR __attribute__((__option__("sse5,fused-madd")))
+extern float flt_mul_add (float a, float b, float c) SSE5_ATTR;
+extern float flt_mul_sub (float a, float b, float c) SSE5_ATTR;
+extern float flt_neg_mul_add (float a, float b, float c) SSE5_ATTR;
+extern float flt_neg_mul_sub (float a, float b, float c) SSE5_ATTR;
+
+extern double dbl_mul_add (double a, double b, double c) SSE5_ATTR;
+extern double dbl_mul_sub (double a, double b, double c) SSE5_ATTR;
+extern double dbl_neg_mul_add (double a, double b, double c) SSE5_ATTR;
+extern double dbl_neg_mul_sub (double a, double b, double c) SSE5_ATTR;
+
+float
+flt_mul_add (float a, float b, float c)
+{
+ return (a * b) + c;
+}
+
+double
+dbl_mul_add (double a, double b, double c)
+{
+ return (a * b) + c;
+}
+
+float
+flt_mul_sub (float a, float b, float c)
+{
+ return (a * b) - c;
+}
+
+double
+dbl_mul_sub (double a, double b, double c)
+{
+ return (a * b) - c;
+}
+
+float
+flt_neg_mul_add (float a, float b, float c)
+{
+ return (-(a * b)) + c;
+}
+
+double
+dbl_neg_mul_add (double a, double b, double c)
+{
+ return (-(a * b)) + c;
+}
+
+float
+flt_neg_mul_sub (float a, float b, float c)
+{
+ return (-(a * b)) - c;
+}
+
+double
+dbl_neg_mul_sub (double a, double b, double c)
+{
+ return (-(a * b)) - c;
+}
+
+float f[10] = { 2, 3, 4 };
+double d[10] = { 2, 3, 4 };
+
+int main ()
+{
+ f[3] = flt_mul_add (f[0], f[1], f[2]);
+ f[4] = flt_mul_sub (f[0], f[1], f[2]);
+ f[5] = flt_neg_mul_add (f[0], f[1], f[2]);
+ f[6] = flt_neg_mul_sub (f[0], f[1], f[2]);
+
+ d[3] = dbl_mul_add (d[0], d[1], d[2]);
+ d[4] = dbl_mul_sub (d[0], d[1], d[2]);
+ d[5] = dbl_neg_mul_add (d[0], d[1], d[2]);
+ d[6] = dbl_neg_mul_sub (d[0], d[1], d[2]);
+ exit (0);
+}
+
+/* { dg-final { scan-assembler "fmaddss" } } */
+/* { dg-final { scan-assembler "fmaddsd" } } */
+/* { dg-final { scan-assembler "fmsubss" } } */
+/* { dg-final { scan-assembler "fmsubsd" } } */
+/* { dg-final { scan-assembler "fnmaddss" } } */
+/* { dg-final { scan-assembler "fnmaddsd" } } */
+/* { dg-final { scan-assembler "fnmsubss" } } */
+/* { dg-final { scan-assembler "fnmsubsd" } } */
+/* { dg-final { scan-assembler "call\t(.*)flt_mul_add" } } */
+/* { dg-final { scan-assembler "call\t(.*)flt_mul_sub" } } */
+/* { dg-final { scan-assembler "call\t(.*)flt_neg_mul_add" } } */
+/* { dg-final { scan-assembler "call\t(.*)flt_neg_mul_sub" } } */
+/* { dg-final { scan-assembler "call\t(.*)dbl_mul_add" } } */
+/* { dg-final { scan-assembler "call\t(.*)dbl_mul_sub" } } */
+/* { dg-final { scan-assembler "call\t(.*)dbl_neg_mul_add" } } */
+/* { dg-final { scan-assembler "call\t(.*)dbl_neg_mul_sub" } } */
diff --git a/gcc/testsuite/gcc.target/i386/funcspec-3.c b/gcc/testsuite/gcc.target/i386/funcspec-3.c
new file mode 100644
index 00000000000..80ec23da09f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/funcspec-3.c
@@ -0,0 +1,66 @@
+/* Test whether using target specific options, we can generate popcnt by
+ setting the architecture. */
+/* { dg-do compile } */
+/* { dg-require-effective-target lp64 } */
+/* { dg-options "-O2 -march=k8" } */
+
+extern void exit (int);
+extern void abort (void);
+
+#define SSE4A_ATTR __attribute__((__option__("arch=amdfam10")))
+#define SSE42_ATTR __attribute__((__option__("sse4.2")))
+
+static int sse4a_pop_i (int a) SSE4A_ATTR;
+static long sse42_pop_l (long a) SSE42_ATTR;
+static int generic_pop_i (int a);
+static long generic_pop_l (long a);
+
+static
+int sse4a_pop_i (int a)
+{
+ return __builtin_popcount (a);
+}
+
+static
+long sse42_pop_l (long a)
+{
+ return __builtin_popcountl (a);
+}
+
+static
+int generic_pop_i (int a)
+{
+ return __builtin_popcount (a);
+}
+
+static
+long generic_pop_l (long a)
+{
+ return __builtin_popcountl (a);
+}
+
+int five = 5;
+long seven = 7;
+
+int main ()
+{
+ if (sse4a_pop_i (five) != 2)
+ abort ();
+
+ if (sse42_pop_l (seven) != 3L)
+ abort ();
+
+ if (generic_pop_i (five) != 2)
+ abort ();
+
+ if (generic_pop_l (seven) != 3L)
+ abort ();
+
+ exit (0);
+}
+
+/* { dg-final { scan-assembler "popcntl" } } */
+/* { dg-final { scan-assembler "popcntq" } } */
+/* { dg-final { scan-assembler "call\t(.*)sse4a_pop_i" } } */
+/* { dg-final { scan-assembler "call\t(.*)sse42_pop_l" } } */
+/* { dg-final { scan-assembler "call\t(.*)popcountdi2" } } */
diff --git a/gcc/testsuite/gcc.target/i386/funcspec-4.c b/gcc/testsuite/gcc.target/i386/funcspec-4.c
new file mode 100644
index 00000000000..71251c314bb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/funcspec-4.c
@@ -0,0 +1,14 @@
+/* Test some error conditions with function specific options. */
+/* { dg-do compile } */
+
+/* no sse500 switch */
+extern void error1 (void) __attribute__((__option__("sse500"))); /* { dg-error "unknown" } */
+
+/* Multiple arch switches */
+extern void error2 (void) __attribute__((__option__("arch=core2,arch=k8"))); /* { dg-error "already specified" } */
+
+/* Unknown tune target */
+extern void error3 (void) __attribute__((__option__("tune=foobar"))); /* { dg-error "bad value" } */
+
+/* option on a variable */
+extern int error4 __attribute__((__option__("sse2"))); /* { dg-warning "ignored" } */
diff --git a/gcc/testsuite/gcc.target/i386/funcspec-5.c b/gcc/testsuite/gcc.target/i386/funcspec-5.c
new file mode 100644
index 00000000000..d4204bb1411
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/funcspec-5.c
@@ -0,0 +1,125 @@
+/* Test whether all of the 32-bit function specific options are accepted
+ without error. */
+/* { dg-do compile } */
+/* { dg-require-effective-target ilp32 } */
+
+extern void test_abm (void) __attribute__((__option__("abm")));
+extern void test_aes (void) __attribute__((__option__("aes")));
+extern void test_fused_madd (void) __attribute__((__option__("fused-madd")));
+extern void test_mmx (void) __attribute__((__option__("mmx")));
+extern void test_pclmul (void) __attribute__((__option__("pclmul")));
+extern void test_popcnt (void) __attribute__((__option__("popcnt")));
+extern void test_recip (void) __attribute__((__option__("recip")));
+extern void test_sse (void) __attribute__((__option__("sse")));
+extern void test_sse2 (void) __attribute__((__option__("sse2")));
+extern void test_sse3 (void) __attribute__((__option__("sse3")));
+extern void test_sse4 (void) __attribute__((__option__("sse4")));
+extern void test_sse4_1 (void) __attribute__((__option__("sse4.1")));
+extern void test_sse4_2 (void) __attribute__((__option__("sse4.2")));
+extern void test_sse4a (void) __attribute__((__option__("sse4a")));
+extern void test_sse5 (void) __attribute__((__option__("sse5")));
+extern void test_ssse3 (void) __attribute__((__option__("ssse3")));
+
+extern void test_no_abm (void) __attribute__((__option__("no-abm")));
+extern void test_no_aes (void) __attribute__((__option__("no-aes")));
+extern void test_no_fused_madd (void) __attribute__((__option__("no-fused-madd")));
+extern void test_no_mmx (void) __attribute__((__option__("no-mmx")));
+extern void test_no_pclmul (void) __attribute__((__option__("no-pclmul")));
+extern void test_no_popcnt (void) __attribute__((__option__("no-popcnt")));
+extern void test_no_recip (void) __attribute__((__option__("no-recip")));
+extern void test_no_sse (void) __attribute__((__option__("no-sse")));
+extern void test_no_sse2 (void) __attribute__((__option__("no-sse2")));
+extern void test_no_sse3 (void) __attribute__((__option__("no-sse3")));
+extern void test_no_sse4 (void) __attribute__((__option__("no-sse4")));
+extern void test_no_sse4_1 (void) __attribute__((__option__("no-sse4.1")));
+extern void test_no_sse4_2 (void) __attribute__((__option__("no-sse4.2")));
+extern void test_no_sse4a (void) __attribute__((__option__("no-sse4a")));
+extern void test_no_sse5 (void) __attribute__((__option__("no-sse5")));
+extern void test_no_ssse3 (void) __attribute__((__option__("no-ssse3")));
+
+extern void test_arch_i386 (void) __attribute__((__option__("arch=i386")));
+extern void test_arch_i486 (void) __attribute__((__option__("arch=i486")));
+extern void test_arch_i586 (void) __attribute__((__option__("arch=i586")));
+extern void test_arch_pentium (void) __attribute__((__option__("arch=pentium")));
+extern void test_arch_pentium_mmx (void) __attribute__((__option__("arch=pentium-mmx")));
+extern void test_arch_winchip_c6 (void) __attribute__((__option__("arch=winchip-c6")));
+extern void test_arch_winchip2 (void) __attribute__((__option__("arch=winchip2")));
+extern void test_arch_c3 (void) __attribute__((__option__("arch=c3")));
+extern void test_arch_c3_2 (void) __attribute__((__option__("arch=c3-2")));
+extern void test_arch_i686 (void) __attribute__((__option__("arch=i686")));
+extern void test_arch_pentiumpro (void) __attribute__((__option__("arch=pentiumpro")));
+extern void test_arch_pentium2 (void) __attribute__((__option__("arch=pentium2")));
+extern void test_arch_pentium3 (void) __attribute__((__option__("arch=pentium3")));
+extern void test_arch_pentium3m (void) __attribute__((__option__("arch=pentium3m")));
+extern void test_arch_pentium_m (void) __attribute__((__option__("arch=pentium-m")));
+extern void test_arch_pentium4 (void) __attribute__((__option__("arch=pentium4")));
+extern void test_arch_pentium4m (void) __attribute__((__option__("arch=pentium4m")));
+extern void test_arch_prescott (void) __attribute__((__option__("arch=prescott")));
+extern void test_arch_nocona (void) __attribute__((__option__("arch=nocona")));
+extern void test_arch_core2 (void) __attribute__((__option__("arch=core2")));
+extern void test_arch_geode (void) __attribute__((__option__("arch=geode")));
+extern void test_arch_k6 (void) __attribute__((__option__("arch=k6")));
+extern void test_arch_k6_2 (void) __attribute__((__option__("arch=k6-2")));
+extern void test_arch_k6_3 (void) __attribute__((__option__("arch=k6-3")));
+extern void test_arch_athlon (void) __attribute__((__option__("arch=athlon")));
+extern void test_arch_athlon_tbird (void) __attribute__((__option__("arch=athlon-tbird")));
+extern void test_arch_athlon_4 (void) __attribute__((__option__("arch=athlon-4")));
+extern void test_arch_athlon_xp (void) __attribute__((__option__("arch=athlon-xp")));
+extern void test_arch_athlon_mp (void) __attribute__((__option__("arch=athlon-mp")));
+extern void test_arch_k8 (void) __attribute__((__option__("arch=k8")));
+extern void test_arch_k8_sse3 (void) __attribute__((__option__("arch=k8-sse3")));
+extern void test_arch_opteron (void) __attribute__((__option__("arch=opteron")));
+extern void test_arch_opteron_sse3 (void) __attribute__((__option__("arch=opteron-sse3")));
+extern void test_arch_athlon64 (void) __attribute__((__option__("arch=athlon64")));
+extern void test_arch_athlon64_sse3 (void) __attribute__((__option__("arch=athlon64-sse3")));
+extern void test_arch_athlon_fx (void) __attribute__((__option__("arch=athlon-fx")));
+extern void test_arch_amdfam10 (void) __attribute__((__option__("arch=amdfam10")));
+extern void test_arch_barcelona (void) __attribute__((__option__("arch=barcelona")));
+extern void test_arch_foo (void) __attribute__((__option__("arch=foo"))); /* { dg-error "bad value" } */
+
+extern void test_tune_i386 (void) __attribute__((__option__("tune=i386")));
+extern void test_tune_i486 (void) __attribute__((__option__("tune=i486")));
+extern void test_tune_i586 (void) __attribute__((__option__("tune=i586")));
+extern void test_tune_pentium (void) __attribute__((__option__("tune=pentium")));
+extern void test_tune_pentium_mmx (void) __attribute__((__option__("tune=pentium-mmx")));
+extern void test_tune_winchip_c6 (void) __attribute__((__option__("tune=winchip-c6")));
+extern void test_tune_winchip2 (void) __attribute__((__option__("tune=winchip2")));
+extern void test_tune_c3 (void) __attribute__((__option__("tune=c3")));
+extern void test_tune_c3_2 (void) __attribute__((__option__("tune=c3-2")));
+extern void test_tune_i686 (void) __attribute__((__option__("tune=i686")));
+extern void test_tune_pentiumpro (void) __attribute__((__option__("tune=pentiumpro")));
+extern void test_tune_pentium2 (void) __attribute__((__option__("tune=pentium2")));
+extern void test_tune_pentium3 (void) __attribute__((__option__("tune=pentium3")));
+extern void test_tune_pentium3m (void) __attribute__((__option__("tune=pentium3m")));
+extern void test_tune_pentium_m (void) __attribute__((__option__("tune=pentium-m")));
+extern void test_tune_pentium4 (void) __attribute__((__option__("tune=pentium4")));
+extern void test_tune_pentium4m (void) __attribute__((__option__("tune=pentium4m")));
+extern void test_tune_prescott (void) __attribute__((__option__("tune=prescott")));
+extern void test_tune_nocona (void) __attribute__((__option__("tune=nocona")));
+extern void test_tune_core2 (void) __attribute__((__option__("tune=core2")));
+extern void test_tune_geode (void) __attribute__((__option__("tune=geode")));
+extern void test_tune_k6 (void) __attribute__((__option__("tune=k6")));
+extern void test_tune_k6_2 (void) __attribute__((__option__("tune=k6-2")));
+extern void test_tune_k6_3 (void) __attribute__((__option__("tune=k6-3")));
+extern void test_tune_athlon (void) __attribute__((__option__("tune=athlon")));
+extern void test_tune_athlon_tbird (void) __attribute__((__option__("tune=athlon-tbird")));
+extern void test_tune_athlon_4 (void) __attribute__((__option__("tune=athlon-4")));
+extern void test_tune_athlon_xp (void) __attribute__((__option__("tune=athlon-xp")));
+extern void test_tune_athlon_mp (void) __attribute__((__option__("tune=athlon-mp")));
+extern void test_tune_k8 (void) __attribute__((__option__("tune=k8")));
+extern void test_tune_k8_sse3 (void) __attribute__((__option__("tune=k8-sse3")));
+extern void test_tune_opteron (void) __attribute__((__option__("tune=opteron")));
+extern void test_tune_opteron_sse3 (void) __attribute__((__option__("tune=opteron-sse3")));
+extern void test_tune_athlon64 (void) __attribute__((__option__("tune=athlon64")));
+extern void test_tune_athlon64_sse3 (void) __attribute__((__option__("tune=athlon64-sse3")));
+extern void test_tune_athlon_fx (void) __attribute__((__option__("tune=athlon-fx")));
+extern void test_tune_amdfam10 (void) __attribute__((__option__("tune=amdfam10")));
+extern void test_tune_barcelona (void) __attribute__((__option__("tune=barcelona")));
+extern void test_tune_generic (void) __attribute__((__option__("tune=generic")));
+extern void test_tune_foo (void) __attribute__((__option__("tune=foo"))); /* { dg-error "bad value" } */
+
+extern void test_fpmath_sse (void) __attribute__((__option__("sse2,fpmath=sse")));
+extern void test_fpmath_387 (void) __attribute__((__option__("sse2,fpmath=387")));
+extern void test_fpmath_sse_387 (void) __attribute__((__option__("sse2,fpmath=sse+387")));
+extern void test_fpmath_387_sse (void) __attribute__((__option__("sse2,fpmath=387+sse")));
+extern void test_fpmath_both (void) __attribute__((__option__("sse2,fpmath=both")));
diff --git a/gcc/testsuite/gcc.target/i386/funcspec-6.c b/gcc/testsuite/gcc.target/i386/funcspec-6.c
new file mode 100644
index 00000000000..0c915975894
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/funcspec-6.c
@@ -0,0 +1,71 @@
+/* Test whether all of the 64-bit function specific options are accepted
+ without error. */
+/* { dg-do compile } */
+/* { dg-require-effective-target lp64 } */
+
+extern void test_abm (void) __attribute__((__option__("abm")));
+extern void test_aes (void) __attribute__((__option__("aes")));
+extern void test_fused_madd (void) __attribute__((__option__("fused-madd")));
+extern void test_mmx (void) __attribute__((__option__("mmx")));
+extern void test_pclmul (void) __attribute__((__option__("pclmul")));
+extern void test_popcnt (void) __attribute__((__option__("popcnt")));
+extern void test_recip (void) __attribute__((__option__("recip")));
+extern void test_sse (void) __attribute__((__option__("sse")));
+extern void test_sse2 (void) __attribute__((__option__("sse2")));
+extern void test_sse3 (void) __attribute__((__option__("sse3")));
+extern void test_sse4 (void) __attribute__((__option__("sse4")));
+extern void test_sse4_1 (void) __attribute__((__option__("sse4.1")));
+extern void test_sse4_2 (void) __attribute__((__option__("sse4.2")));
+extern void test_sse4a (void) __attribute__((__option__("sse4a")));
+extern void test_sse5 (void) __attribute__((__option__("sse5")));
+extern void test_ssse3 (void) __attribute__((__option__("ssse3")));
+
+extern void test_no_abm (void) __attribute__((__option__("no-abm")));
+extern void test_no_aes (void) __attribute__((__option__("no-aes")));
+extern void test_no_fused_madd (void) __attribute__((__option__("no-fused-madd")));
+extern void test_no_mmx (void) __attribute__((__option__("no-mmx")));
+extern void test_no_pclmul (void) __attribute__((__option__("no-pclmul")));
+extern void test_no_popcnt (void) __attribute__((__option__("no-popcnt")));
+extern void test_no_recip (void) __attribute__((__option__("no-recip")));
+extern void test_no_sse (void) __attribute__((__option__("no-sse")));
+extern void test_no_sse2 (void) __attribute__((__option__("no-sse2")));
+extern void test_no_sse3 (void) __attribute__((__option__("no-sse3")));
+extern void test_no_sse4 (void) __attribute__((__option__("no-sse4")));
+extern void test_no_sse4_1 (void) __attribute__((__option__("no-sse4.1")));
+extern void test_no_sse4_2 (void) __attribute__((__option__("no-sse4.2")));
+extern void test_no_sse4a (void) __attribute__((__option__("no-sse4a")));
+extern void test_no_sse5 (void) __attribute__((__option__("no-sse5")));
+extern void test_no_ssse3 (void) __attribute__((__option__("no-ssse3")));
+
+extern void test_arch_nocona (void) __attribute__((__option__("arch=nocona")));
+extern void test_arch_core2 (void) __attribute__((__option__("arch=core2")));
+extern void test_arch_k8 (void) __attribute__((__option__("arch=k8")));
+extern void test_arch_k8_sse3 (void) __attribute__((__option__("arch=k8-sse3")));
+extern void test_arch_opteron (void) __attribute__((__option__("arch=opteron")));
+extern void test_arch_opteron_sse3 (void) __attribute__((__option__("arch=opteron-sse3")));
+extern void test_arch_athlon64 (void) __attribute__((__option__("arch=athlon64")));
+extern void test_arch_athlon64_sse3 (void) __attribute__((__option__("arch=athlon64-sse3")));
+extern void test_arch_athlon_fx (void) __attribute__((__option__("arch=athlon-fx")));
+extern void test_arch_amdfam10 (void) __attribute__((__option__("arch=amdfam10")));
+extern void test_arch_barcelona (void) __attribute__((__option__("arch=barcelona")));
+extern void test_arch_foo (void) __attribute__((__option__("arch=foo"))); /* { dg-error "bad value" } */
+
+extern void test_tune_nocona (void) __attribute__((__option__("tune=nocona")));
+extern void test_tune_core2 (void) __attribute__((__option__("tune=core2")));
+extern void test_tune_k8 (void) __attribute__((__option__("tune=k8")));
+extern void test_tune_k8_sse3 (void) __attribute__((__option__("tune=k8-sse3")));
+extern void test_tune_opteron (void) __attribute__((__option__("tune=opteron")));
+extern void test_tune_opteron_sse3 (void) __attribute__((__option__("tune=opteron-sse3")));
+extern void test_tune_athlon64 (void) __attribute__((__option__("tune=athlon64")));
+extern void test_tune_athlon64_sse3 (void) __attribute__((__option__("tune=athlon64-sse3")));
+extern void test_tune_athlon_fx (void) __attribute__((__option__("tune=athlon-fx")));
+extern void test_tune_amdfam10 (void) __attribute__((__option__("tune=amdfam10")));
+extern void test_tune_barcelona (void) __attribute__((__option__("tune=barcelona")));
+extern void test_tune_generic (void) __attribute__((__option__("tune=generic")));
+extern void test_tune_foo (void) __attribute__((__option__("tune=foo"))); /* { dg-error "bad value" } */
+
+extern void test_fpmath_sse (void) __attribute__((__option__("sse2,fpmath=sse")));
+extern void test_fpmath_387 (void) __attribute__((__option__("sse2,fpmath=387")));
+extern void test_fpmath_sse_387 (void) __attribute__((__option__("sse2,fpmath=sse+387")));
+extern void test_fpmath_387_sse (void) __attribute__((__option__("sse2,fpmath=387+sse")));
+extern void test_fpmath_both (void) __attribute__((__option__("sse2,fpmath=both")));
diff --git a/gcc/testsuite/gcc.target/i386/funcspec-7.c b/gcc/testsuite/gcc.target/i386/funcspec-7.c
new file mode 100644
index 00000000000..a65ae251978
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/funcspec-7.c
@@ -0,0 +1,13 @@
+/* Test whether using target specific options, we can generate the reciprocal
+ square root instruction. */
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=k8 -mno-recip -mfpmath=sse -ffast-math" } */
+
+float do_recip (float a) __attribute__((__option__("recip")));
+float do_normal (float a);
+
+float do_recip (float a) { return 1.0f / __builtin_sqrtf (a); }
+float do_normal (float a) { return 1.0f / __builtin_sqrtf (a); }
+
+/* { dg-final { scan-assembler "sqrtss" } } */
+/* { dg-final { scan-assembler "rsqrtss" } } */
diff --git a/gcc/testsuite/gcc.target/i386/funcspec-8.c b/gcc/testsuite/gcc.target/i386/funcspec-8.c
new file mode 100644
index 00000000000..115f60866a2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/funcspec-8.c
@@ -0,0 +1,161 @@
+/* Test whether using target specific options, we can use the x86 builtin
+ functions in functions with the appropriate function specific options. */
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=k8 -mfpmath=sse" } */
+
+typedef float __m128 __attribute__ ((__vector_size__ (16), __may_alias__));
+typedef double __m128d __attribute__ ((__vector_size__ (16), __may_alias__));
+typedef int __m128w __attribute__ ((__vector_size__ (16), __may_alias__));
+typedef long long __m128i __attribute__ ((__vector_size__ (16), __may_alias__));
+
+#ifdef __SSE3__
+#error "-msse3 should not be set for this test"
+#endif
+
+__m128d sse3_hsubpd (__m128d a, __m128d b) __attribute__((__option__("sse3")));
+__m128d generic_hsubpd (__m128d a, __m128d b);
+
+__m128d
+sse3_hsubpd (__m128d a, __m128d b)
+{
+ return __builtin_ia32_hsubpd (a, b);
+}
+
+__m128d
+generic_hsubpd (__m128d a, __m128d b)
+{
+ return __builtin_ia32_hsubpd (a, b); /* { dg-error "needs isa option" } */
+}
+
+#ifdef __SSSE3__
+#error "-mssse3 should not be set for this test"
+#endif
+
+__m128w ssse3_psignd128 (__m128w a, __m128w b) __attribute__((__option__("ssse3")));
+__m128w generic_psignd (__m128w ab, __m128w b);
+
+__m128w
+ssse3_psignd128 (__m128w a, __m128w b)
+{
+ return __builtin_ia32_psignd128 (a, b);
+}
+
+__m128w
+generic_psignd128 (__m128w a, __m128w b)
+{
+ return __builtin_ia32_psignd128 (a, b); /* { dg-error "needs isa option" } */
+}
+
+#ifdef __SSE4_1__
+#error "-msse4.1 should not be set for this test"
+#endif
+
+__m128d sse4_1_blendvpd (__m128d a, __m128d b, __m128d c) __attribute__((__option__("sse4.1")));
+__m128d generic_blendvpd (__m128d a, __m128d b, __m128d c);
+
+__m128d
+sse4_1_blendvpd (__m128d a, __m128d b, __m128d c)
+{
+ return __builtin_ia32_blendvpd (a, b, c);
+}
+
+__m128d
+generic_blendvpd (__m128d a, __m128d b, __m128d c)
+{
+ return __builtin_ia32_blendvpd (a, b, c); /* { dg-error "needs isa option" } */
+}
+
+#ifdef __SSE4_2__
+#error "-msse4.2 should not be set for this test"
+#endif
+
+__m128i sse4_2_pcmpgtq (__m128i a, __m128i b) __attribute__((__option__("sse4.2")));
+__m128i generic_pcmpgtq (__m128i ab, __m128i b);
+
+__m128i
+sse4_2_pcmpgtq (__m128i a, __m128i b)
+{
+ return __builtin_ia32_pcmpgtq (a, b);
+}
+
+__m128i
+generic_pcmpgtq (__m128i a, __m128i b)
+{
+ return __builtin_ia32_pcmpgtq (a, b); /* { dg-error "needs isa option" } */
+}
+
+#ifdef __SSE4A__
+#error "-msse4a should not be set for this test"
+#endif
+
+__m128i sse4_2_insertq (__m128i a, __m128i b) __attribute__((__option__("sse4a")));
+__m128i generic_insertq (__m128i ab, __m128i b);
+
+__m128i
+sse4_2_insertq (__m128i a, __m128i b)
+{
+ return __builtin_ia32_insertq (a, b);
+}
+
+__m128i
+generic_insertq (__m128i a, __m128i b)
+{
+ return __builtin_ia32_insertq (a, b); /* { dg-error "needs isa option" } */
+}
+
+#ifdef __SSE5__
+#error "-msse5 should not be set for this test"
+#endif
+
+__m128d sse5_fmaddpd (__m128d a, __m128d b, __m128d c) __attribute__((__option__("sse5")));
+__m128d generic_fmaddpd (__m128d a, __m128d b, __m128d c);
+
+__m128d
+sse5_fmaddpd (__m128d a, __m128d b, __m128d c)
+{
+ return __builtin_ia32_fmaddpd (a, b, c);
+}
+
+__m128d
+generic_fmaddpd (__m128d a, __m128d b, __m128d c)
+{
+ return __builtin_ia32_fmaddpd (a, b, c); /* { dg-error "needs isa option" } */
+}
+
+#ifdef __AES__
+#error "-maes should not be set for this test"
+#endif
+
+__m128i aes_aesimc128 (__m128i a) __attribute__((__option__("aes")));
+__m128i generic_aesimc128 (__m128i a);
+
+__m128i
+aes_aesimc128 (__m128i a)
+{
+ return __builtin_ia32_aesimc128 (a);
+}
+
+__m128i
+generic_aesimc128 (__m128i a)
+{
+ return __builtin_ia32_aesimc128 (a); /* { dg-error "needs isa option" } */
+}
+
+#ifdef __PCLMUL__
+#error "-mpclmul should not be set for this test"
+#endif
+
+__m128i pclmul_pclmulqdq128 (__m128i a, __m128i b) __attribute__((__option__("pclmul")));
+__m128i generic_pclmulqdq128 (__m128i a, __m128i b);
+
+__m128i
+pclmul_pclmulqdq128 (__m128i a, __m128i b)
+{
+ return __builtin_ia32_pclmulqdq128 (a, b, 5);
+}
+
+__m128i
+generic_pclmulqdq128 (__m128i a, __m128i b)
+{
+ return __builtin_ia32_pclmulqdq128 (a, b, 5); /* { dg-error "needs isa option" } */
+}
diff --git a/gcc/testsuite/gcc.target/i386/funcspec-9.c b/gcc/testsuite/gcc.target/i386/funcspec-9.c
new file mode 100644
index 00000000000..e6d19013101
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/funcspec-9.c
@@ -0,0 +1,36 @@
+/* Test whether using target specific options, we can generate SSE5 code. */
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=k8 -mfpmath=sse -msse2" } */
+
+extern void exit (int);
+
+#ifdef __SSE5__
+#warning "__SSE5__ should not be defined before #pragma GCC option."
+#endif
+
+#pragma GCC option (push)
+#pragma GCC option ("sse5,fused-madd")
+
+#ifndef __SSE5__
+#warning "__SSE5__ should have be defined after #pragma GCC option."
+#endif
+
+float
+flt_mul_add (float a, float b, float c)
+{
+ return (a * b) + c;
+}
+
+#pragma GCC option (pop)
+#ifdef __SSE5__
+#warning "__SSE5__ should not be defined after #pragma GCC pop option."
+#endif
+
+double
+dbl_mul_add (double a, double b, double c)
+{
+ return (a * b) + c;
+}
+
+/* { dg-final { scan-assembler "fmaddss" } } */
+/* { dg-final { scan-assembler "addsd" } } */
diff --git a/gcc/testsuite/gcc.target/i386/hot-1.c b/gcc/testsuite/gcc.target/i386/hot-1.c
new file mode 100644
index 00000000000..608f52fd6eb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/hot-1.c
@@ -0,0 +1,33 @@
+/* Test whether using attribute((hot)) really turns on -O3. Do this test
+ by checking whether we vectorize a simple loop. */
+/* { dg-do compile } */
+/* { dg-options "-O1 -msse2 -mfpmath=sse -march=k8" } */
+/* { dg-final { scan-assembler "addps" } } */
+/* { dg-final { scan-assembler "subss" } } */
+
+#define SIZE 1024
+float a[SIZE] __attribute__((__aligned__(32)));
+float b[SIZE] __attribute__((__aligned__(32)));
+float c[SIZE] __attribute__((__aligned__(32)));
+
+/* This should vectorize. */
+void hot (void) __attribute__((__hot__));
+
+void
+hot (void)
+{
+ int i;
+
+ for (i = 0; i < SIZE; i++)
+ a[i] = b[i] + c[i];
+}
+
+/* This should not vectorize. */
+void
+not_hot (void)
+{
+ int i;
+
+ for (i = 0; i < SIZE; i++)
+ a[i] = b[i] - c[i];
+}
diff --git a/gcc/testsuite/gcc.target/i386/opt-1.c b/gcc/testsuite/gcc.target/i386/opt-1.c
new file mode 100644
index 00000000000..28e2ef38c34
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/opt-1.c
@@ -0,0 +1,35 @@
+/* Test the attribute((optimize)) really works. Do this test by checking
+ whether we vectorize a simple loop. */
+/* { dg-do compile } */
+/* { dg-options "-O1 -msse2 -mfpmath=sse -march=k8" } */
+/* { dg-final { scan-assembler "prefetcht0" } } */
+/* { dg-final { scan-assembler "addps" } } */
+/* { dg-final { scan-assembler "subss" } } */
+
+#define SIZE 10240
+float a[SIZE] __attribute__((__aligned__(32)));
+float b[SIZE] __attribute__((__aligned__(32)));
+float c[SIZE] __attribute__((__aligned__(32)));
+
+/* This should vectorize. */
+void opt3 (void) __attribute__((__optimize__(3,"unroll-all-loops,-fprefetch-loop-arrays")));
+
+void
+opt3 (void)
+{
+ int i;
+
+ for (i = 0; i < SIZE; i++)
+ a[i] = b[i] + c[i];
+}
+
+/* This should not vectorize. */
+void
+not_opt3 (void)
+{
+ int i;
+
+ for (i = 0; i < SIZE; i++)
+ a[i] = b[i] - c[i];
+}
+
diff --git a/gcc/testsuite/gcc.target/i386/opt-2.c b/gcc/testsuite/gcc.target/i386/opt-2.c
new file mode 100644
index 00000000000..8d6ba6fe925
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/opt-2.c
@@ -0,0 +1,38 @@
+/* Test the attribute((optimize)) really works. Do this test by checking
+ whether we vectorize a simple loop. */
+/* { dg-do compile } */
+/* { dg-options "-O1 -msse2 -mfpmath=sse -march=k8" } */
+/* { dg-final { scan-assembler "prefetcht0" } } */
+/* { dg-final { scan-assembler "addps" } } */
+/* { dg-final { scan-assembler "subss" } } */
+
+#define SIZE 10240
+float a[SIZE] __attribute__((__aligned__(32)));
+float b[SIZE] __attribute__((__aligned__(32)));
+float c[SIZE] __attribute__((__aligned__(32)));
+
+/* This should vectorize. */
+#pragma GCC optimize push
+#pragma GCC optimize (3, "unroll-all-loops", "-fprefetch-loop-arrays")
+
+void
+opt3 (void)
+{
+ int i;
+
+ for (i = 0; i < SIZE; i++)
+ a[i] = b[i] + c[i];
+}
+
+#pragma GCC optimize pop
+
+/* This should not vectorize. */
+void
+not_opt3 (void)
+{
+ int i;
+
+ for (i = 0; i < SIZE; i++)
+ a[i] = b[i] - c[i];
+}
+
diff --git a/gcc/testsuite/gcc.target/i386/pr36753.c b/gcc/testsuite/gcc.target/i386/pr36753.c
new file mode 100644
index 00000000000..2d43d42a021
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr36753.c
@@ -0,0 +1,31 @@
+/* { dg-options "-O2" } */
+/* { dg-do run } */
+
+#if defined __i386__
+#define REG "edi"
+#else
+#define REG "r14"
+#endif
+
+register unsigned long *ds asm(REG);
+
+extern void abort (void);
+
+__attribute__ ((noinline)) void
+test (void)
+{
+ *++ds = 31337;
+}
+
+int
+main ()
+{
+ unsigned long stack[2];
+ stack[0] = 0;
+ stack[1] = 0;
+ ds = stack;
+ test ();
+ if (ds != stack + 1 || *ds != 31337)
+ abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr36786.c b/gcc/testsuite/gcc.target/i386/pr36786.c
new file mode 100644
index 00000000000..692518e1bd1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr36786.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target lp64 } */
+
+typedef int DItype __attribute__ ((mode (DI)));
+typedef unsigned int UDItype __attribute__ ((mode (DI)));
+typedef int TItype __attribute__ ((mode (TI)));
+
+__floattisf (TItype u)
+{
+ DItype hi = u >> (8 * 8);
+ UDItype count, shift;
+ hi = u >> shift;
+}
diff --git a/gcc/testsuite/gcc.target/i386/sse-22.c b/gcc/testsuite/gcc.target/i386/sse-22.c
new file mode 100644
index 00000000000..a9b10333157
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/sse-22.c
@@ -0,0 +1,171 @@
+/* Same as sse-14, except converted to use #pragma GCC option. */
+/* { dg-do compile } */
+/* { dg-options "-O0 -Werror-implicit-function-declaration" } */
+
+#include <mm_malloc.h>
+
+/* Test that the intrinsics compile without optimization. All of them are
+ defined as inline functions in {,x,e,p,t,s,w,a,b}mmintrin.h and mm3dnow.h
+ that reference the proper builtin functions. Defining away "extern" and
+ "__inline" results in all of them being compiled as proper functions. */
+
+#define extern
+#define __inline
+
+#define _CONCAT(x,y) x ## y
+
+#define test_1(func, type, op1_type, imm) \
+ type _CONCAT(_,func) (op1_type A, int const I) \
+ { return func (A, imm); }
+
+#define test_1x(func, type, op1_type, imm1, imm2) \
+ type _CONCAT(_,func) (op1_type A, int const I, int const L) \
+ { return func (A, imm1, imm2); }
+
+#define test_2(func, type, op1_type, op2_type, imm) \
+ type _CONCAT(_,func) (op1_type A, op2_type B, int const I) \
+ { return func (A, B, imm); }
+
+#define test_2x(func, type, op1_type, op2_type, imm1, imm2) \
+ type _CONCAT(_,func) (op1_type A, op2_type B, int const I, int const L) \
+ { return func (A, B, imm1, imm2); }
+
+#define test_4(func, type, op1_type, op2_type, op3_type, op4_type, imm) \
+ type _CONCAT(_,func) (op1_type A, op2_type B, \
+ op3_type C, op4_type D, int const I) \
+ { return func (A, B, C, D, imm); }
+
+
+#ifndef DIFFERENT_PRAGMAS
+#pragma GCC option ("mmx,3dnow,sse,sse2,sse3,ssse3,sse4.1,sse4.2,sse5,aes,pclmul")
+#endif
+
+/* Following intrinsics require immediate arguments. They
+ are defined as macros for non-optimized compilations. */
+
+/* mmintrin.h (MMX). */
+#ifdef DIFFERENT_PRAGMAS
+#pragma GCC option ("mmx")
+#endif
+#include <mmintrin.h>
+
+/* mm3dnow.h (3DNOW). */
+#ifdef DIFFERENT_PRAGMAS
+#pragma GCC option ("3dnow")
+#endif
+#include <mm3dnow.h>
+
+/* xmmintrin.h (SSE). */
+#ifdef DIFFERENT_PRAGMAS
+#pragma GCC option ("sse")
+#endif
+#include <xmmintrin.h>
+test_2 (_mm_shuffle_ps, __m128, __m128, __m128, 1)
+test_1 (_mm_extract_pi16, int, __m64, 1)
+test_1 (_m_pextrw, int, __m64, 1)
+test_2 (_mm_insert_pi16, __m64, __m64, int, 1)
+test_2 (_m_pinsrw, __m64, __m64, int, 1)
+test_1 (_mm_shuffle_pi16, __m64, __m64, 1)
+test_1 (_m_pshufw, __m64, __m64, 1)
+test_1 (_mm_prefetch, void, void *, _MM_HINT_NTA)
+
+/* emmintrin.h (SSE2). */
+#ifdef DIFFERENT_PRAGMAS
+#pragma GCC option ("sse2")
+#endif
+#include <emmintrin.h>
+test_2 (_mm_shuffle_pd, __m128d, __m128d, __m128d, 1)
+test_1 (_mm_srli_si128, __m128i, __m128i, 1)
+test_1 (_mm_slli_si128, __m128i, __m128i, 1)
+test_1 (_mm_extract_epi16, int, __m128i, 1)
+test_2 (_mm_insert_epi16, __m128i, __m128i, int, 1)
+test_1 (_mm_shufflehi_epi16, __m128i, __m128i, 1)
+test_1 (_mm_shufflelo_epi16, __m128i, __m128i, 1)
+test_1 (_mm_shuffle_epi32, __m128i, __m128i, 1)
+
+/* pmmintrin.h (SSE3). */
+#ifdef DIFFERENT_PRAGMAS
+#pragma GCC option ("sse3")
+#endif
+#include <pmmintrin.h>
+
+/* tmmintrin.h (SSSE3). */
+#ifdef DIFFERENT_PRAGMAS
+#pragma GCC option ("ssse3")
+#endif
+#include <tmmintrin.h>
+test_2 (_mm_alignr_epi8, __m128i, __m128i, __m128i, 1)
+test_2 (_mm_alignr_pi8, __m64, __m64, __m64, 1)
+
+/* ammintrin.h (SSE4A). */
+#ifdef DIFFERENT_PRAGMAS
+#pragma GCC option ("sse4a")
+#endif
+#include <ammintrin.h>
+test_1x (_mm_extracti_si64, __m128i, __m128i, 1, 1)
+test_2x (_mm_inserti_si64, __m128i, __m128i, __m128i, 1, 1)
+
+/* smmintrin.h (SSE4.1). */
+/* nmmintrin.h (SSE4.2). */
+/* Note, nmmintrin.h includes smmintrin.h, and smmintrin.h checks for the
+ #ifdef. So just set the option to SSE4.2. */
+#ifdef DIFFERENT_PRAGMAS
+#pragma GCC option ("sse4.2")
+#endif
+#include <nmmintrin.h>
+test_2 (_mm_blend_epi16, __m128i, __m128i, __m128i, 1)
+test_2 (_mm_blend_ps, __m128, __m128, __m128, 1)
+test_2 (_mm_blend_pd, __m128d, __m128d, __m128d, 1)
+test_2 (_mm_dp_ps, __m128, __m128, __m128, 1)
+test_2 (_mm_dp_pd, __m128d, __m128d, __m128d, 1)
+test_2 (_mm_insert_ps, __m128, __m128, __m128, 1)
+test_1 (_mm_extract_ps, int, __m128, 1)
+test_2 (_mm_insert_epi8, __m128i, __m128i, int, 1)
+test_2 (_mm_insert_epi32, __m128i, __m128i, int, 1)
+#ifdef __x86_64__
+test_2 (_mm_insert_epi64, __m128i, __m128i, long long, 1)
+#endif
+test_1 (_mm_extract_epi8, int, __m128i, 1)
+test_1 (_mm_extract_epi32, int, __m128i, 1)
+#ifdef __x86_64__
+test_1 (_mm_extract_epi64, long long, __m128i, 1)
+#endif
+test_2 (_mm_mpsadbw_epu8, __m128i, __m128i, __m128i, 1)
+test_2 (_mm_cmpistrm, __m128i, __m128i, __m128i, 1)
+test_2 (_mm_cmpistri, int, __m128i, __m128i, 1)
+test_4 (_mm_cmpestrm, __m128i, __m128i, int, __m128i, int, 1)
+test_4 (_mm_cmpestri, int, __m128i, int, __m128i, int, 1)
+test_2 (_mm_cmpistra, int, __m128i, __m128i, 1)
+test_2 (_mm_cmpistrc, int, __m128i, __m128i, 1)
+test_2 (_mm_cmpistro, int, __m128i, __m128i, 1)
+test_2 (_mm_cmpistrs, int, __m128i, __m128i, 1)
+test_2 (_mm_cmpistrz, int, __m128i, __m128i, 1)
+test_4 (_mm_cmpestra, int, __m128i, int, __m128i, int, 1)
+test_4 (_mm_cmpestrc, int, __m128i, int, __m128i, int, 1)
+test_4 (_mm_cmpestro, int, __m128i, int, __m128i, int, 1)
+test_4 (_mm_cmpestrs, int, __m128i, int, __m128i, int, 1)
+test_4 (_mm_cmpestrz, int, __m128i, int, __m128i, int, 1)
+
+/* bmmintrin.h (SSE5). */
+#ifdef DIFFERENT_PRAGMAS
+#pragma GCC option ("sse5")
+#endif
+#include <bmmintrin.h>
+test_1 (_mm_roti_epi8, __m128i, __m128i, 1)
+test_1 (_mm_roti_epi16, __m128i, __m128i, 1)
+test_1 (_mm_roti_epi32, __m128i, __m128i, 1)
+test_1 (_mm_roti_epi64, __m128i, __m128i, 1)
+
+/* wmmintrin.h (AES/PCLMUL). */
+#ifdef DIFFERENT_PRAGMAS
+#pragma GCC option ("aes,pclmul")
+#endif
+#include <wmmintrin.h>
+test_1 (_mm_aeskeygenassist_si128, __m128i, __m128i, 1)
+test_2 (_mm_clmulepi64_si128, __m128i, __m128i, __m128i, 1)
+
+/* mmintrin-common.h */
+test_1 (_mm_round_pd, __m128d, __m128d, 1)
+test_1 (_mm_round_ps, __m128, __m128, 1)
+test_2 (_mm_round_sd, __m128d, __m128d, __m128d, 1)
+test_2 (_mm_round_ss, __m128, __m128, __m128, 1)
diff --git a/gcc/testsuite/gcc.target/i386/sse-23.c b/gcc/testsuite/gcc.target/i386/sse-23.c
new file mode 100644
index 00000000000..27b601452a5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/sse-23.c
@@ -0,0 +1,108 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -Werror-implicit-function-declaration -march=k8" } */
+
+#include <mm_malloc.h>
+
+/* Test that the intrinsics compile with optimization. All of them are
+ defined as inline functions in {,x,e,p,t,s,w,a,b}mmintrin.h and mm3dnow.h
+ that reference the proper builtin functions. Defining away "extern" and
+ "__inline" results in all of them being compiled as proper functions. */
+
+#define extern
+#define __inline
+
+/* Following intrinsics require immediate arguments. */
+
+/* ammintrin.h */
+#define __builtin_ia32_extrqi(X, I, L) __builtin_ia32_extrqi(X, 1, 1)
+#define __builtin_ia32_insertqi(X, Y, I, L) __builtin_ia32_insertqi(X, Y, 1, 1)
+
+/* wmmintrin.h */
+#define __builtin_ia32_aeskeygenassist128(X, C) __builtin_ia32_aeskeygenassist128(X, 1)
+#define __builtin_ia32_pclmulqdq128(X, Y, I) __builtin_ia32_pclmulqdq128(X, Y, 1)
+
+/* mmintrin-common.h */
+#define __builtin_ia32_roundpd(V, M) __builtin_ia32_roundpd(V, 1)
+#define __builtin_ia32_roundsd(D, V, M) __builtin_ia32_roundsd(D, V, 1)
+#define __builtin_ia32_roundps(V, M) __builtin_ia32_roundps(V, 1)
+#define __builtin_ia32_roundss(D, V, M) __builtin_ia32_roundss(D, V, 1)
+
+/* smmintrin.h */
+#define __builtin_ia32_pblendw128(X, Y, M) __builtin_ia32_pblendw128 (X, Y, 1)
+#define __builtin_ia32_blendps(X, Y, M) __builtin_ia32_blendps(X, Y, 1)
+#define __builtin_ia32_blendpd(X, Y, M) __builtin_ia32_blendpd(X, Y, 1)
+#define __builtin_ia32_dpps(X, Y, M) __builtin_ia32_dpps(X, Y, 1)
+#define __builtin_ia32_dppd(X, Y, M) __builtin_ia32_dppd(X, Y, 1)
+#define __builtin_ia32_insertps128(D, S, N) __builtin_ia32_insertps128(D, S, 1)
+#define __builtin_ia32_vec_ext_v4sf(X, N) __builtin_ia32_vec_ext_v4sf(X, 1)
+#define __builtin_ia32_vec_set_v16qi(D, S, N) __builtin_ia32_vec_set_v16qi(D, S, 1)
+#define __builtin_ia32_vec_set_v4si(D, S, N) __builtin_ia32_vec_set_v4si(D, S, 1)
+#define __builtin_ia32_vec_set_v2di(D, S, N) __builtin_ia32_vec_set_v2di(D, S, 1)
+#define __builtin_ia32_vec_ext_v16qi(X, N) __builtin_ia32_vec_ext_v16qi(X, 1)
+#define __builtin_ia32_vec_ext_v4si(X, N) __builtin_ia32_vec_ext_v4si(X, 1)
+#define __builtin_ia32_vec_ext_v2di(X, N) __builtin_ia32_vec_ext_v2di(X, 1)
+#define __builtin_ia32_mpsadbw128(X, Y, M) __builtin_ia32_mpsadbw128(X, Y, 1)
+#define __builtin_ia32_pcmpistrm128(X, Y, M) \
+ __builtin_ia32_pcmpistrm128(X, Y, 1)
+#define __builtin_ia32_pcmpistri128(X, Y, M) \
+ __builtin_ia32_pcmpistri128(X, Y, 1)
+#define __builtin_ia32_pcmpestrm128(X, LX, Y, LY, M) \
+ __builtin_ia32_pcmpestrm128(X, LX, Y, LY, 1)
+#define __builtin_ia32_pcmpestri128(X, LX, Y, LY, M) \
+ __builtin_ia32_pcmpestri128(X, LX, Y, LY, 1)
+#define __builtin_ia32_pcmpistria128(X, Y, M) \
+ __builtin_ia32_pcmpistria128(X, Y, 1)
+#define __builtin_ia32_pcmpistric128(X, Y, M) \
+ __builtin_ia32_pcmpistric128(X, Y, 1)
+#define __builtin_ia32_pcmpistrio128(X, Y, M) \
+ __builtin_ia32_pcmpistrio128(X, Y, 1)
+#define __builtin_ia32_pcmpistris128(X, Y, M) \
+ __builtin_ia32_pcmpistris128(X, Y, 1)
+#define __builtin_ia32_pcmpistriz128(X, Y, M) \
+ __builtin_ia32_pcmpistriz128(X, Y, 1)
+#define __builtin_ia32_pcmpestria128(X, LX, Y, LY, M) \
+ __builtin_ia32_pcmpestria128(X, LX, Y, LY, 1)
+#define __builtin_ia32_pcmpestric128(X, LX, Y, LY, M) \
+ __builtin_ia32_pcmpestric128(X, LX, Y, LY, 1)
+#define __builtin_ia32_pcmpestrio128(X, LX, Y, LY, M) \
+ __builtin_ia32_pcmpestrio128(X, LX, Y, LY, 1)
+#define __builtin_ia32_pcmpestris128(X, LX, Y, LY, M) \
+ __builtin_ia32_pcmpestris128(X, LX, Y, LY, 1)
+#define __builtin_ia32_pcmpestriz128(X, LX, Y, LY, M) \
+ __builtin_ia32_pcmpestriz128(X, LX, Y, LY, 1)
+
+/* tmmintrin.h */
+#define __builtin_ia32_palignr128(X, Y, N) __builtin_ia32_palignr128(X, Y, 8)
+#define __builtin_ia32_palignr(X, Y, N) __builtin_ia32_palignr(X, Y, 8)
+
+/* emmintrin.h */
+#define __builtin_ia32_psrldqi128(A, B) __builtin_ia32_psrldqi128(A, 8)
+#define __builtin_ia32_pslldqi128(A, B) __builtin_ia32_pslldqi128(A, 8)
+#define __builtin_ia32_pshufhw(A, N) __builtin_ia32_pshufhw(A, 0)
+#define __builtin_ia32_pshuflw(A, N) __builtin_ia32_pshuflw(A, 0)
+#define __builtin_ia32_pshufd(A, N) __builtin_ia32_pshufd(A, 0)
+#define __builtin_ia32_vec_set_v8hi(A, D, N) \
+ __builtin_ia32_vec_set_v8hi(A, D, 0)
+#define __builtin_ia32_vec_ext_v8hi(A, N) __builtin_ia32_vec_ext_v8hi(A, 0)
+#define __builtin_ia32_shufpd(A, B, N) __builtin_ia32_shufpd(A, B, 0)
+
+/* xmmintrin.h */
+#define __builtin_prefetch(P, A, I) __builtin_prefetch(P, A, _MM_HINT_NTA)
+#define __builtin_ia32_pshufw(A, N) __builtin_ia32_pshufw(A, 0)
+#define __builtin_ia32_vec_set_v4hi(A, D, N) \
+ __builtin_ia32_vec_set_v4hi(A, D, 0)
+#define __builtin_ia32_vec_ext_v4hi(A, N) __builtin_ia32_vec_ext_v4hi(A, 0)
+#define __builtin_ia32_shufps(A, B, N) __builtin_ia32_shufps(A, B, 0)
+
+/* bmmintrin.h */
+#define __builtin_ia32_protbi(A, B) __builtin_ia32_protbi(A,1)
+#define __builtin_ia32_protwi(A, B) __builtin_ia32_protwi(A,1)
+#define __builtin_ia32_protdi(A, B) __builtin_ia32_protdi(A,1)
+#define __builtin_ia32_protqi(A, B) __builtin_ia32_protqi(A,1)
+
+
+#pragma GCC option ("3dnow,sse4,sse5,aes,pclmul")
+#include <wmmintrin.h>
+#include <bmmintrin.h>
+#include <smmintrin.h>
+#include <mm3dnow.h>
diff --git a/gcc/testsuite/gcc.target/i386/vararg-1.c b/gcc/testsuite/gcc.target/i386/vararg-1.c
new file mode 100644
index 00000000000..1875e0a6973
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/vararg-1.c
@@ -0,0 +1,32 @@
+/* PR middle-end/36858 */
+/* { dg-do run } */
+/* { dg-options "-w" { target { lp64 } } } */
+/* { dg-options "-w -msse2 -mpreferred-stack-boundary=2" { target { ilp32 } } } */
+
+#include "sse2-check.h"
+#include <stdarg.h>
+#include <emmintrin.h>
+
+int
+__attribute__((noinline))
+test (int a, ...)
+{
+ return a;
+}
+
+__m128 n1 = { -283.3, -23.3, 213.4, 1119.03 };
+
+int
+__attribute__((noinline))
+foo (void)
+{
+ return test (1, n1);
+}
+
+static void
+__attribute__((noinline))
+sse2_test (void)
+{
+ if (foo () != 1)
+ abort ();
+}
diff --git a/gcc/testsuite/gcc.target/i386/vararg-2.c b/gcc/testsuite/gcc.target/i386/vararg-2.c
new file mode 100644
index 00000000000..0534ac77478
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/vararg-2.c
@@ -0,0 +1,40 @@
+/* PR middle-end/36859 */
+/* { dg-do run } */
+/* { dg-options "-w" { target { lp64 } } } */
+/* { dg-options "-w -msse2 -mpreferred-stack-boundary=2" { target { ilp32 } } } */
+
+#include "sse2-check.h"
+#include <stdarg.h>
+#include <emmintrin.h>
+
+__m128
+__attribute__((noinline))
+test (int a, ...)
+{
+ __m128 x;
+ va_list va_arglist;
+
+ va_start (va_arglist, a);
+ x = va_arg (va_arglist, __m128);
+ va_end (va_arglist);
+ return x;
+}
+
+__m128 n1 = { -283.3, -23.3, 213.4, 1119.03 };
+
+int
+__attribute__((noinline))
+foo (void)
+{
+ __m128 x = test (1, n1);
+ if (__builtin_memcmp (&x, &n1, sizeof (x)) != 0)
+ abort ();
+ return 0;
+}
+
+static void
+__attribute__((noinline))
+sse2_test (void)
+{
+ foo ();
+}
diff --git a/gcc/testsuite/gcc.target/m68k/interrupt-2.c b/gcc/testsuite/gcc.target/m68k/interrupt-2.c
new file mode 100644
index 00000000000..7d4cb68c121
--- /dev/null
+++ b/gcc/testsuite/gcc.target/m68k/interrupt-2.c
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+int x;
+volatile unsigned int y;
+
+#define REPEAT10(X, Y) \
+ X(Y##0); X(Y##1); X(Y##2); X(Y##3); X(Y##4); \
+ X(Y##5); X(Y##6); X(Y##7); X(Y##8); X(Y##9)
+
+#define REPEAT30(X) REPEAT10 (X, 0); REPEAT10 (X, 1); REPEAT10 (X, 2)
+#define IN(X) unsigned int x##X = y
+#define OUT(X) y = x##X
+
+void __attribute__ ((interrupt_handler)) f1 (void)
+{
+ x = y + 11;
+}
+
+void __attribute__ ((interrupt_handler)) f2 (void)
+{
+ REPEAT30 (IN);
+ REPEAT30 (OUT);
+}
diff --git a/gcc/testsuite/gcc.target/mips/gcc-have-sync-compare-and-swap-1.c b/gcc/testsuite/gcc.target/mips/gcc-have-sync-compare-and-swap-1.c
index 4c642258f7b..c12d08e0521 100644
--- a/gcc/testsuite/gcc.target/mips/gcc-have-sync-compare-and-swap-1.c
+++ b/gcc/testsuite/gcc.target/mips/gcc-have-sync-compare-and-swap-1.c
@@ -1,15 +1,15 @@
/* { dg-do preprocess } */
/* { dg-mips-options "-mips2" } */
-#if defined (__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1) == defined (__mips16)
+#ifndef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1
#error nonono
#endif
-#if defined (__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2) == defined (__mips16)
+#ifndef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2
#error nonono
#endif
-#if defined (__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4) == defined (__mips16)
+#ifndef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4
#error nonono
#endif
diff --git a/gcc/testsuite/gcc.target/mips/gcc-have-sync-compare-and-swap-2.c b/gcc/testsuite/gcc.target/mips/gcc-have-sync-compare-and-swap-2.c
index 4265e4167ba..eaae7801754 100644
--- a/gcc/testsuite/gcc.target/mips/gcc-have-sync-compare-and-swap-2.c
+++ b/gcc/testsuite/gcc.target/mips/gcc-have-sync-compare-and-swap-2.c
@@ -1,19 +1,19 @@
/* { dg-do preprocess } */
/* { dg-mips-options "-mgp64" } */
-#if defined (__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1) == defined (__mips16)
+#ifndef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1
#error nonono
#endif
-#if defined (__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2) == defined (__mips16)
+#ifndef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2
#error nonono
#endif
-#if defined (__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4) == defined (__mips16)
+#ifndef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4
#error nonono
#endif
-#if defined (__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8) == defined (__mips16)
+#ifndef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8
#error nonono
#endif
diff --git a/gcc/testsuite/gcc.target/mips/gcc-have-sync-compare-and-swap-3.c b/gcc/testsuite/gcc.target/mips/gcc-have-sync-compare-and-swap-3.c
new file mode 100644
index 00000000000..faf50fc69ca
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/gcc-have-sync-compare-and-swap-3.c
@@ -0,0 +1,23 @@
+/* { dg-do preprocess { target mips16_attribute } } */
+/* { dg-mips-options "-mips2 -mips16" } */
+/* { dg-add-options mips16_attribute } */
+
+#ifndef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1
+#error nonono
+#endif
+
+#ifndef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2
+#error nonono
+#endif
+
+#ifndef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4
+#error nonono
+#endif
+
+#ifdef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8
+#error nonono
+#endif
+
+#ifdef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_16
+#error nonono
+#endif
diff --git a/gcc/testsuite/gcc.target/mips/gcc-have-sync-compare-and-swap-4.c b/gcc/testsuite/gcc.target/mips/gcc-have-sync-compare-and-swap-4.c
new file mode 100644
index 00000000000..b53f4b05b61
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/gcc-have-sync-compare-and-swap-4.c
@@ -0,0 +1,23 @@
+/* { dg-do preprocess { target mips16_attribute } } */
+/* { dg-mips-options "-mgp64 -mips16" } */
+/* { dg-add-options mips16_attribute } */
+
+#ifndef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1
+#error nonono
+#endif
+
+#ifndef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2
+#error nonono
+#endif
+
+#ifndef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4
+#error nonono
+#endif
+
+#ifndef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8
+#error nonono
+#endif
+
+#ifdef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_16
+#error nonono
+#endif
diff --git a/gcc/testsuite/gcc.target/mips/pr35802.c b/gcc/testsuite/gcc.target/mips/pr35802.c
new file mode 100644
index 00000000000..34300980695
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/pr35802.c
@@ -0,0 +1,17 @@
+/* { dg-mips-options "-O2 -march=74kc -mgp32" } */
+__thread int x __attribute__((tls_model("initial-exec")));
+__thread int y __attribute__((tls_model("initial-exec")));
+
+int bar (void);
+
+NOMIPS16 void
+foo (int n)
+{
+ if (n > 5)
+ {
+ y = 0;
+ do
+ x += bar ();
+ while (n--);
+ }
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/altivec-26.c b/gcc/testsuite/gcc.target/powerpc/altivec-26.c
new file mode 100644
index 00000000000..689d13a514f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/altivec-26.c
@@ -0,0 +1,11 @@
+/* { dg-do compile { target powerpc*-*-* } } */
+/* { dg-require-effective-target powerpc_altivec_ok } */
+/* { dg-options "-maltivec" } */
+
+/* A compiler implementing context-sensitive keywords must define this
+ preprocessor macro so that altivec.h does not provide the vector,
+ pixel, etc. macros. */
+
+#ifndef __APPLE_ALTIVEC__
+#error __APPLE_ALTIVEC__ not pre-defined
+#endif
diff --git a/gcc/testsuite/gcc.target/powerpc/altivec-macros.c b/gcc/testsuite/gcc.target/powerpc/altivec-macros.c
new file mode 100644
index 00000000000..d95a68dd966
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/altivec-macros.c
@@ -0,0 +1,63 @@
+/* Copyright (C) 2007 Free Software Foundation, Inc. */
+
+/* { dg-do preprocess } */
+/* { dg-options "-maltivec" } */
+
+/* Conditional macros should not be expanded by pragmas. */
+#pragma __vector
+_Pragma ("__vector")
+
+/* Redefinition of conditional macros. */
+/* No warning should be generated. */
+
+#define __vector __new_vector
+#define __pixel __new_pixel
+#define __bool __new_bool
+#define vector new_vector
+#define pixel new_pixel
+#define bool new_bool
+
+/* Definition of conditional macros. */
+/* No warning should be generated. */
+
+#undef __vector
+#define __vector __new_vector
+
+#undef __pixel
+#define __pixel __new_pixel
+
+#undef __bool
+#define __bool __new_bool
+
+#undef vector
+#define vector new_vector
+
+#undef pixel
+#define pixel new_pixel
+
+#undef bool
+#define bool new_bool
+
+/* Re-definition of "unconditional" macros. */
+/* Warnings should be generated as usual. */
+
+#define __vector __newer_vector
+#define __pixel __newer_pixel
+#define __bool __newer_bool
+#define vector newer_vector
+#define pixel newer_pixel
+#define bool newer_bool
+
+/* { dg-warning "redefined" "__vector redefined" { target *-*-* } 44 } */
+/* { dg-warning "redefined" "__pixel redefined" { target *-*-* } 45 } */
+/* { dg-warning "redefined" "__bool redefined" { target *-*-* } 46 } */
+/* { dg-warning "redefined" "vector redefined" { target *-*-* } 47 } */
+/* { dg-warning "redefined" "pixel redefined" { target *-*-* } 48 } */
+/* { dg-warning "redefined" "bool redefined" { target *-*-* } 49 } */
+
+/* { dg-warning "previous" "prev __vector defn" { target *-*-* } 24 } */
+/* { dg-warning "previous" "prev __pixel defn" { target *-*-* } 27 } */
+/* { dg-warning "previous" "prev __bool defn" { target *-*-* } 30 } */
+/* { dg-warning "previous" "prev vector defn" { target *-*-* } 33 } */
+/* { dg-warning "previous" "prev pixel defn" { target *-*-* } 36 } */
+/* { dg-warning "previous" "prev bool defn" { target *-*-* } 39 } */
diff --git a/gcc/testsuite/gcc.target/powerpc/asm-y.c b/gcc/testsuite/gcc.target/powerpc/asm-y.c
new file mode 100644
index 00000000000..7d5a6a61795
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/asm-y.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-O1" } */
+
+/* Test that %yN does not cause an internal error if used incorrectly. */
+
+int f(int *a)
+{
+ asm ("#%y0" : "=m"(a[2])); /* { dg-error "try using the 'Z' constraint" } */
+ asm ("#%y0" : "=m"(a[1])); /* { dg-error "try using the 'Z' constraint" } */
+ asm ("#%y0" : "=m"(a[0]));
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/ppc-negeq0-1.c b/gcc/testsuite/gcc.target/powerpc/ppc-negeq0-1.c
index 37d10bc5b68..0386ecba7ca 100644
--- a/gcc/testsuite/gcc.target/powerpc/ppc-negeq0-1.c
+++ b/gcc/testsuite/gcc.target/powerpc/ppc-negeq0-1.c
@@ -1,15 +1,15 @@
/* { dg-do compile } */
/* { dg-options "-O2" } */
-int foo(int x)
+long foo(long x)
{
return -(x == 0);
}
-int bar(int x)
+long bar(long x)
{
- int t = __builtin_clz(x);
- return -(t>>5);
+ long t = __builtin_clzl(x);
+ return -(t>>(sizeof(long) == 8 ? 6 : 5));
}
-/* { dg-final { scan-assembler-not "cntlzw" } } */
+/* { dg-final { scan-assembler-not "cntlz" } } */
diff --git a/gcc/testsuite/gcc.target/s390/pr36822.c b/gcc/testsuite/gcc.target/s390/pr36822.c
new file mode 100644
index 00000000000..a427d2e1eb1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/pr36822.c
@@ -0,0 +1,16 @@
+/* This used to ICE on s390 due to bug in the definition of the 'R'
+ constraint which replaced the 'm' constraint (together with 'T')
+ while adding z10 support. */
+
+/* { dg-do compile } */
+/* { dg-options "-O" } */
+
+int boo()
+{
+ struct {
+ unsigned char pad[4096];
+ unsigned long long bar;
+ } *foo;
+ asm volatile( "" : "=m" (*(unsigned long long*)(foo->bar))
+ : "a" (&foo->bar));
+}
diff --git a/gcc/testsuite/gcc.target/spu/vector-ansi.c b/gcc/testsuite/gcc.target/spu/vector-ansi.c
new file mode 100644
index 00000000000..3c086169947
--- /dev/null
+++ b/gcc/testsuite/gcc.target/spu/vector-ansi.c
@@ -0,0 +1,35 @@
+/* { dg-do compile } */
+/* { dg-options "-ansi" } */
+
+/* This is done by spu_internals.h, but we not include it here to keep
+ down the dependencies. */
+
+#ifndef __VECTOR_KEYWORD_SUPPORTED__
+#define vector __vector
+#endif
+
+/* __vector is expanded unconditionally by the preprocessor. */
+__vector int vi;
+__vector unsigned char vuc;
+__vector signed char vsc;
+__vector unsigned short vus;
+__vector signed short vss;
+__vector unsigned int vui;
+__vector signed int vsi;
+__vector unsigned long long ull;
+__vector signed long long sll;
+__vector float vf;
+__vector double vd;
+
+/* vector is expanded by the define above, regardless of context. */
+vector int vi;
+vector unsigned char vuc;
+vector signed char vsc;
+vector unsigned short vus;
+vector signed short vss;
+vector unsigned int vui;
+vector signed int vsi;
+vector unsigned long long ull;
+vector signed long long sll;
+vector float vf;
+vector double vd;
diff --git a/gcc/testsuite/gcc.target/spu/vector.c b/gcc/testsuite/gcc.target/spu/vector.c
new file mode 100644
index 00000000000..237f93b7e58
--- /dev/null
+++ b/gcc/testsuite/gcc.target/spu/vector.c
@@ -0,0 +1,32 @@
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+#ifndef __VECTOR_KEYWORD_SUPPORTED__
+#error __VECTOR_KEYWORD_SUPPORTED__ is not defined
+#endif
+
+/* __vector is expanded unconditionally. */
+__vector int vi;
+__vector unsigned char vuc;
+__vector signed char vsc;
+__vector unsigned short vus;
+__vector signed short vss;
+__vector unsigned int vui;
+__vector signed int vsi;
+__vector unsigned long long ull;
+__vector signed long long sll;
+__vector float vf;
+__vector double vd;
+
+/* vector is expanded conditionally, based on the context. */
+vector int vi;
+vector unsigned char vuc;
+vector signed char vsc;
+vector unsigned short vus;
+vector signed short vss;
+vector unsigned int vui;
+vector signed int vsi;
+vector unsigned long long ull;
+vector signed long long sll;
+vector float vf;
+vector double vd;
diff --git a/gcc/testsuite/gfortran.dg/allocatable_module_1.f90 b/gcc/testsuite/gfortran.dg/allocatable_module_1.f90
new file mode 100644
index 00000000000..47f10008efa
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/allocatable_module_1.f90
@@ -0,0 +1,18 @@
+! { dg-do compile }
+! PR 36934 - this used to give a spurious error and segfault with a
+! patch that wasn't complete
+! Test case contributed by Philip Mason
+
+module fred1
+real, allocatable :: default_clocks(:)
+end module fred1
+
+module fred2
+real, allocatable :: locks(:)
+end module fred2
+
+program fred
+use fred1
+use fred2
+end program fred
+! { dg-final { cleanup-modules "fred1 fred2" } }
diff --git a/gcc/testsuite/gfortran.dg/array_4.f90 b/gcc/testsuite/gfortran.dg/array_4.f90
new file mode 100644
index 00000000000..869522af08f
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/array_4.f90
@@ -0,0 +1,12 @@
+! { dg-do compile }
+! PR fortran/36824
+!
+! Dimension of tgclist was not recognized as having constant bounds
+!
+program test
+implicit none
+integer, dimension( 3 ), parameter :: tgc = (/5, 6, 7 /)
+type tgccomp
+ integer, dimension( tgc( 1 ) : tgc( 2 ) ) :: tgclist
+end type tgccomp
+end program
diff --git a/gcc/testsuite/gfortran.dg/array_temporaries_1.f90 b/gcc/testsuite/gfortran.dg/array_temporaries_1.f90
new file mode 100644
index 00000000000..64fc59046f4
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/array_temporaries_1.f90
@@ -0,0 +1,19 @@
+! { dg-do compile }
+! { dg-options "-Warray-temporaries" }
+
+subroutine bar(a)
+ real, dimension(2) :: a
+end
+
+program main
+ integer, parameter :: n=3
+ integer :: i
+ real, dimension(n) :: a, b
+
+ a = 0.2
+ i = 2
+ a(i:i+1) = a(1:2) ! { dg-warning "Creating array temporary" }
+ a = cshift(a,1) ! { dg-warning "Creating array temporary" }
+ b = cshift(a,1)
+ call bar(a(1:3:2)) ! { dg-warning "Creating array temporary" }
+end program main
diff --git a/gcc/testsuite/gfortran.dg/array_temporaries_2.f90 b/gcc/testsuite/gfortran.dg/array_temporaries_2.f90
new file mode 100644
index 00000000000..86e0a45e712
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/array_temporaries_2.f90
@@ -0,0 +1,15 @@
+! { dg-do run }
+! { dg-options "-fcheck-array-temporaries" }
+ program test
+ implicit none
+ integer :: a(3,3)
+ call foo(a(:,1)) ! OK, no temporary created
+ call foo(a(1,:)) ! BAD, temporary var created
+contains
+ subroutine foo(x)
+ integer :: x(3)
+ x = 5
+ end subroutine foo
+end program test
+
+! { dg-output "At line 7 of file .*array_temporaries_2.f90(\n|\r\n|\r)Fortran runtime warning: An array temporary was created for argument 'x' of procedure 'foo'" }
diff --git a/gcc/testsuite/gfortran.dg/c_sizeof_2.f90 b/gcc/testsuite/gfortran.dg/c_sizeof_2.f90
index f6c3077f83d..6e32cb34687 100644
--- a/gcc/testsuite/gfortran.dg/c_sizeof_2.f90
+++ b/gcc/testsuite/gfortran.dg/c_sizeof_2.f90
@@ -2,8 +2,7 @@
! { dg-options "-std=f2003 -Wall" }
! Support F2008's c_sizeof()
!
-integer(4) :: i, j(10)
-i = c_sizeof(i) ! { dg-error "not included in the selected standard" }
-i = c_sizeof(j) ! { dg-error "not included in the selected standard" }
+integer(4) :: i
+i = c_sizeof(i) ! { dg-warning "Fortran 2008" }
end
diff --git a/gcc/testsuite/gfortran.dg/char_expr_1.f90 b/gcc/testsuite/gfortran.dg/char_expr_1.f90
new file mode 100644
index 00000000000..ba0e1f23350
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/char_expr_1.f90
@@ -0,0 +1,20 @@
+! { dg-do "run" }
+! PR fortran/36795
+! "(str)" (= an expression) was regarded as "str" (= a variable)
+! and thus when yy was deallocated so was xx. Result: An invalid
+! memory access.
+!
+program main
+ implicit none
+ character (len=10), allocatable :: str(:)
+ allocate (str(1))
+ str(1) = "dog"
+ if (size(str) /= 1 .or. str(1) /= "dog") call abort()
+contains
+ subroutine foo(xx,yy)
+ character (len=*), intent(in) :: xx(:)
+ character (len=*), intent(out), allocatable :: yy(:)
+ allocate (yy(size(xx)))
+ yy = xx
+ end subroutine foo
+end program main
diff --git a/gcc/testsuite/gfortran.dg/char_expr_2.f90 b/gcc/testsuite/gfortran.dg/char_expr_2.f90
new file mode 100644
index 00000000000..86499eb454c
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/char_expr_2.f90
@@ -0,0 +1,15 @@
+! { dg-do compile }
+! PR fortran/36803
+! PR fortran/36795
+!
+! "(n)" was simplified to the EXPR_VARIABLE "n"
+! and thus "(n)" was judged as definable.
+!
+interface
+ subroutine foo(x)
+ character, intent(out) :: x(:) ! or INTENT(INOUT)
+ end subroutine foo
+end interface
+character :: n(5)
+call foo( (n) ) ! { dg-error "must be definable" }
+end
diff --git a/gcc/testsuite/gfortran.dg/fmt_error_3.f90 b/gcc/testsuite/gfortran.dg/fmt_error_3.f90
new file mode 100644
index 00000000000..257f876ed80
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/fmt_error_3.f90
@@ -0,0 +1,36 @@
+! { dg-do compile }
+
+! PR fortran/29835
+! Check for improved format error messages with correct locus and more detailed
+! "unexpected element" messages.
+
+SUBROUTINE format_labels
+ IMPLICIT NONE
+
+1 FORMAT (A, &
+ A, &
+ Q, & ! { dg-error "Unexpected element 'Q'" }
+ A)
+
+2 FORMAT (A, &
+ I, & ! { dg-error "Nonnegative width" }
+ A)
+
+END SUBROUTINE format_labels
+
+SUBROUTINE format_strings
+ IMPLICIT NONE
+ CHARACTER(len=32), PARAMETER :: str = "hello"
+ INTEGER :: x
+
+ PRINT '(A, Q, A)', & ! { dg-error "Unexpected element 'Q'" }
+ str, str, str ! { dg-bogus "Unexpected element" }
+
+ PRINT '(A, ' // & ! { dg-error "Nonnegative width" }
+ ' I, ' // &
+ ' A)', str, str, str ! { dg-bogus "Nonnegative width" }
+
+ READ '(Q)', & ! { dg-error "Unexpected element 'Q'" }
+ x ! { dg-bogus "Unexpected element" }
+
+END SUBROUTINE format_strings
diff --git a/gcc/testsuite/gfortran.dg/fmt_error_4.f90 b/gcc/testsuite/gfortran.dg/fmt_error_4.f90
new file mode 100644
index 00000000000..2310573bd1f
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/fmt_error_4.f90
@@ -0,0 +1,22 @@
+! { dg-do run }
+! { dg-shouldfail "runtime error" }
+
+! PR fortran/29835
+! Check for improved format error messages with correct locus and more detailed
+! "unexpected element" messages.
+
+! Now with runtime supplied format strings
+SUBROUTINE format_runtime (fmtstr)
+ IMPLICIT NONE
+ CHARACTER(len=*) :: fmtstr
+ CHARACTER(len=32), PARAMETER :: str = "hello"
+
+ PRINT fmtstr, str, str, str
+END SUBROUTINE format_runtime
+
+PROGRAM main
+ IMPLICIT NONE
+ CALL format_runtime ('(A, Q, A)')
+END PROGRAM main
+
+! { dg-output "Unexpected element 'Q'.*(\n|\r\n|\r)\\(A, Q, A\\)(\n|\r\n|\r) \\^" }
diff --git a/gcc/testsuite/gfortran.dg/fmt_error_5.f90 b/gcc/testsuite/gfortran.dg/fmt_error_5.f90
new file mode 100644
index 00000000000..18de68e0719
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/fmt_error_5.f90
@@ -0,0 +1,22 @@
+! { dg-do run }
+! { dg-shouldfail "runtime error" }
+
+! PR fortran/29835
+! Check for improved format error messages with correct locus and more detailed
+! "unexpected element" messages.
+
+! Now with runtime supplied format strings
+SUBROUTINE format_runtime (fmtstr)
+ IMPLICIT NONE
+ CHARACTER(len=*) :: fmtstr
+ INTEGER :: x
+
+ PRINT fmtstr, x
+END SUBROUTINE format_runtime
+
+PROGRAM main
+ IMPLICIT NONE
+ CALL format_runtime ('(Q)')
+END PROGRAM main
+
+! { dg-output "Unexpected element 'Q'.*(\n|\r\n|\r)\\(Q\\)(\n|\r\n|\r) \\^" }
diff --git a/gcc/testsuite/gfortran.dg/fmt_g0_2.f08 b/gcc/testsuite/gfortran.dg/fmt_g0_2.f08
index c19e3f2dca4..3567561802b 100644
--- a/gcc/testsuite/gfortran.dg/fmt_g0_2.f08
+++ b/gcc/testsuite/gfortran.dg/fmt_g0_2.f08
@@ -1,5 +1,5 @@
! { dg-do run }
-! { dg-options "-std=f95 -pedantic" }
+! { dg-options "-std=f95 -pedantic -fall-intrinsics" }
! { dg-shouldfail "Zero width in format descriptor" }
! PR36420 Fortran 2008: g0 edit descriptor
! Test case provided by Jerry DeLisle <jvdelisle@gcc.gnu.org>
diff --git a/gcc/testsuite/gfortran.dg/fmt_g0_3.f08 b/gcc/testsuite/gfortran.dg/fmt_g0_3.f08
index a84b1f10847..b0b8139a3f3 100644
--- a/gcc/testsuite/gfortran.dg/fmt_g0_3.f08
+++ b/gcc/testsuite/gfortran.dg/fmt_g0_3.f08
@@ -3,5 +3,5 @@
! Test case provided by Jerry DeLisle <jvdelisle@gcc.gnu.org>
character(25) :: string = "(g0,g0,g0)"
character(33) :: buffer
- write(buffer, '(g0,g0,g0)') ':',12340,':' ! { dg-error "Fortran F2008:" }
+ write(buffer, '(g0,g0,g0)') ':',12340,':' ! { dg-error "Fortran 2008:" }
end
diff --git a/gcc/testsuite/gfortran.dg/fmt_g0_4.f08 b/gcc/testsuite/gfortran.dg/fmt_g0_4.f08
new file mode 100644
index 00000000000..149b1aa400a
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/fmt_g0_4.f08
@@ -0,0 +1,5 @@
+! { dg-do compile }
+! { dg-options "-std=f2008" }
+! PR36725 Compile time error for g0 edit descriptor
+print '(g0.9)', 0.1 ! { dg-error "Specifying precision" }
+end
diff --git a/gcc/testsuite/gfortran.dg/gamma_2.f90 b/gcc/testsuite/gfortran.dg/gamma_2.f90
index 6e8cefa6858..5b0e922cb92 100644
--- a/gcc/testsuite/gfortran.dg/gamma_2.f90
+++ b/gcc/testsuite/gfortran.dg/gamma_2.f90
@@ -8,11 +8,11 @@
! PR fortran/32980
!
subroutine foo()
-intrinsic :: gamma
-intrinsic :: dgamma
-intrinsic :: lgamma
-intrinsic :: algama
-intrinsic :: dlgama
+intrinsic :: gamma ! { dg-error "Fortran 2008" }
+intrinsic :: dgamma ! { dg-error "extension" }
+intrinsic :: lgamma ! { dg-error "extension" }
+intrinsic :: algama ! { dg-error "extension" }
+intrinsic :: dlgama ! { dg-error "extension" }
integer, parameter :: sp = kind(1.0)
integer, parameter :: dp = kind(1.0d0)
@@ -20,13 +20,13 @@ integer, parameter :: dp = kind(1.0d0)
real(sp) :: rsp = 1.0_sp
real(dp) :: rdp = 1.0_dp
-rsp = gamma(rsp) ! FIXME "is not included in the selected standard"
-rdp = gamma(rdp) ! FIXME "is not included in the selected standard"
-rdp = dgamma(rdp) ! { dg-error "is not included in the selected standard" }
+rsp = gamma(rsp)
+rdp = gamma(rdp)
+rdp = dgamma(rdp)
-rsp = lgamma(rsp) ! { dg-error "is not included in the selected standard" }
-rdp = lgamma(rdp) ! { dg-error "is not included in the selected standard" }
-rsp = algama(rsp) ! { dg-error "is not included in the selected standard" }
-rdp = dlgama(rdp) ! { dg-error "is not included in the selected standard" }
+rsp = lgamma(rsp)
+rdp = lgamma(rdp)
+rsp = algama(rsp)
+rdp = dlgama(rdp)
end subroutine foo
end
diff --git a/gcc/testsuite/gfortran.dg/gomp/block-1.f90 b/gcc/testsuite/gfortran.dg/gomp/block-1.f90
index f03602ab2f4..04c39a40a02 100644
--- a/gcc/testsuite/gfortran.dg/gomp/block-1.f90
+++ b/gcc/testsuite/gfortran.dg/gomp/block-1.f90
@@ -2,7 +2,7 @@
!$omp parallel
!$omp critical
- goto 10 ! { dg-error "invalid exit" }
+ goto 10 ! { dg-error "invalid (exit|branch)" }
!$omp end critical
10 x = 1
!$omp end parallel
diff --git a/gcc/testsuite/gfortran.dg/gomp/pr36726.f90 b/gcc/testsuite/gfortran.dg/gomp/pr36726.f90
new file mode 100644
index 00000000000..99e170ad798
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/pr36726.f90
@@ -0,0 +1,20 @@
+! PR middle-end/36726
+! { dg-do compile }
+! { dg-options "-fopenmp" }
+
+subroutine foo
+ integer, allocatable :: vs(:)
+ !$omp parallel private (vs)
+ allocate (vs(10))
+ vs = 2
+ deallocate (vs)
+ !$omp end parallel
+end subroutine foo
+subroutine bar
+ integer, allocatable :: vs(:)
+ !$omp parallel private (vs)
+ allocate (vs(10))
+ vs = 2
+ deallocate (vs)
+ !$omp end parallel
+end subroutine bar
diff --git a/gcc/testsuite/gfortran.dg/internal_pack_4.f90 b/gcc/testsuite/gfortran.dg/internal_pack_4.f90
new file mode 100644
index 00000000000..049931a4f4f
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/internal_pack_4.f90
@@ -0,0 +1,31 @@
+! { dg-do run }
+! { dg-options "-fdump-tree-original" }
+!
+! PR fortran/36132
+!
+! Before invalid memory was accessed because an absent, optional
+! argument was packed before passing it as absent actual.
+! Getting it to crash is difficult, but valgrind shows the problem.
+!
+MODULE M1
+ INTEGER, PARAMETER :: dp=KIND(0.0D0)
+CONTAINS
+ SUBROUTINE S1(a)
+ REAL(dp), DIMENSION(45), INTENT(OUT), &
+ OPTIONAL :: a
+ if (present(a)) call abort()
+ END SUBROUTINE S1
+ SUBROUTINE S2(a)
+ REAL(dp), DIMENSION(:, :), INTENT(OUT), &
+ OPTIONAL :: a
+ CALL S1(a)
+ END SUBROUTINE
+END MODULE M1
+
+USE M1
+CALL S2()
+END
+
+! { dg-final { scan-tree-dump-times "a != 0B \\? _gfortran_internal_pack" 1 "original" } }
+! { dg-final { scan-tree-dump-times "if \\(a != 0B &&" 1 "original" } }
+! { dg-final { cleanup-tree-dump "original" } }
diff --git a/gcc/testsuite/gfortran.dg/internal_pack_5.f90 b/gcc/testsuite/gfortran.dg/internal_pack_5.f90
new file mode 100644
index 00000000000..87705fa716a
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/internal_pack_5.f90
@@ -0,0 +1,21 @@
+! { dg-do compile }
+! { dg-options "-fdump-tree-original" }
+!
+! PR fortran/36909
+!
+! Check that no unneeded internal_unpack is
+! called (INTENT(IN)!).
+!
+program test
+ implicit none
+ integer :: a(3,3)
+ call foo(a(1,:))
+contains
+ subroutine foo(x)
+ integer,intent(in) :: x(3)
+ end subroutine foo
+end program test
+
+! { dg-final { scan-tree-dump-times "_gfortran_internal_pack" 1 "original" } }
+! { dg-final { scan-tree-dump-times "_gfortran_internal_unpack" 0 "original" } }
+! { dg-final { cleanup-tree-dump "original" } }
diff --git a/gcc/testsuite/gfortran.dg/intrinsic_argument_conformance_2.f90 b/gcc/testsuite/gfortran.dg/intrinsic_argument_conformance_2.f90
new file mode 100644
index 00000000000..44a4b39f742
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/intrinsic_argument_conformance_2.f90
@@ -0,0 +1,44 @@
+! { dg-do compile }
+! Some CSHIFT, EOSHIFT and UNPACK conformance tests
+!
+program main
+ implicit none
+ real, dimension(1) :: a1, b1, c1
+ real, dimension(1,1) :: a2, b2, c2
+ real, dimension(1,0) :: a, b, c
+ real :: tempn(1), tempv(5)
+ real,allocatable :: foo(:)
+ allocate(foo(0))
+ tempn = 2.0
+
+ a1 = 0
+ a2 = 0
+ c1 = 0
+ a2 = 0
+
+ b1 = cshift (a1,1)
+ b1 = cshift (a1,(/1/)) ! { dg-error "must be a scalar" }
+ b1 = eoshift (a1,1)
+ b2 = eoshift (a1,c1(1)) ! { dg-error "must be INTEGER" }
+ b1 = eoshift (a1,(/1/)) ! { dg-error "must be a scalar" }
+ b1 = eoshift (a1,1,boundary=c1) ! { dg-error "must be a scalar" }
+ b1 = eoshift (a1,(/1/), boundary=c2) ! { dg-error "must be a scalar" }
+
+ b2 = cshift (a2,1)
+ b2 = cshift (a2,(/1/))
+ b2 = cshift (a2,reshape([1],[1,1])) ! { dg-error "have rank 1 or be a scalar" }
+ b2 = eoshift (a2,1)
+ b2 = eoshift (a2,c1) ! { dg-error "must be INTEGER" }
+ b2 = eoshift (a2,(/1/))
+ b2 = eoshift (a2,reshape([1],[1,1]), boundary=c1) ! { dg-error "have rank 1 or be a scalar" }
+ b2 = eoshift (a2,1,boundary=c2(:,:)) ! { dg-error "have rank 1 or be a scalar" }
+ b2 = eoshift (a2,(/1/), boundary=c2(:,:)) ! { dg-error "have rank 1 or be a scalar" }
+
+ b = eoshift (a,(/1/), boundary=c(1,:)) ! { dg-error "Different shape in dimension 1" }
+
+ if (any(eoshift(foo,dim=1,shift=1,boundary=(/42.0,-7.0/))/= 0)) call abort() ! { dg-error "must be a scalar" }
+ if (any(eoshift(tempn(2:1),dim=1,shift=1,boundary=(/42.0,-7.0/))/= 0)) call abort() ! { dg-error "must be a scalar" }
+
+ if (any(unpack(tempv,tempv(1:0)/=0,tempv) /= -47)) call abort() ! { dg-error "Different shape" }
+ if (any(unpack(tempv(5:4),tempv(1:0)/=0,tempv) /= -47)) call abort() ! { dg-error "Different shape" }
+end program main
diff --git a/gcc/testsuite/gfortran.dg/intrinsic_shadow_1.f03 b/gcc/testsuite/gfortran.dg/intrinsic_shadow_1.f03
new file mode 100644
index 00000000000..776d0f692d9
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/intrinsic_shadow_1.f03
@@ -0,0 +1,57 @@
+! { dg-do compile }
+! { dg-options "-std=f2003 -Wintrinsic-shadow" }
+
+! PR fortran/33141
+! Check that the expected warnings are emitted if a user-procedure has the same
+! name as an intrinsic, but only if it is matched by the current -std=*.
+
+MODULE testmod
+ IMPLICIT NONE
+
+CONTAINS
+
+ ! ASIN is an intrinsic
+ REAL FUNCTION asin (arg) ! { dg-warning "shadow the intrinsic" }
+ IMPLICIT NONE
+ REAL :: arg
+ END FUNCTION asin
+
+ ! ASINH is one but not in F2003
+ REAL FUNCTION asinh (arg) ! { dg-bogus "shadow the intrinsic" }
+ IMPLICIT NONE
+ REAL :: arg
+ END FUNCTION asinh
+
+END MODULE testmod
+
+! ACOS is an intrinsic
+REAL FUNCTION acos (arg) ! { dg-warning "of an intrinsic" }
+ IMPLICIT NONE
+ REAL :: arg
+END FUNCTION acos
+
+! ACOSH not for F2003
+REAL FUNCTION acosh (arg) ! { dg-bogus "of an intrinsic" }
+ IMPLICIT NONE
+ REAL :: arg
+END FUNCTION acosh
+
+! A subroutine with the same name as an intrinsic subroutine
+SUBROUTINE random_number (arg) ! { dg-warning "of an intrinsic" }
+ IMPLICIT NONE
+ REAL, INTENT(OUT) :: arg
+END SUBROUTINE random_number
+
+! But a subroutine with the name of an intrinsic function is ok.
+SUBROUTINE atan (arg) ! { dg-bogus "of an intrinsic" }
+ IMPLICIT NONE
+ REAL :: arg
+END SUBROUTINE atan
+
+! As should be a function with the name of an intrinsic subroutine.
+REAL FUNCTION random_seed () ! { dg-bogus "of an intrinsic" }
+END FUNCTION random_seed
+
+! We do only compile, so no main program needed.
+
+! { dg-final { cleanup-modules "testmod" } }
diff --git a/gcc/testsuite/gfortran.dg/intrinsic_shadow_2.f03 b/gcc/testsuite/gfortran.dg/intrinsic_shadow_2.f03
new file mode 100644
index 00000000000..5c046166d76
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/intrinsic_shadow_2.f03
@@ -0,0 +1,29 @@
+! { dg-do compile }
+! { dg-options "-std=f2003 -Wintrinsic-shadow -fall-intrinsics" }
+
+! PR fortran/33141
+! Check that the expected warnings are emitted if a user-procedure has the same
+! name as an intrinsic, with -fall-intrinsics even regardless of std=*.
+
+MODULE testmod
+ IMPLICIT NONE
+
+CONTAINS
+
+ ! ASINH is one but not in F2003
+ REAL FUNCTION asinh (arg) ! { dg-warning "shadow the intrinsic" }
+ IMPLICIT NONE
+ REAL :: arg
+ END FUNCTION asinh
+
+END MODULE testmod
+
+! ACOSH not for F2003
+REAL FUNCTION acosh (arg) ! { dg-warning "of an intrinsic" }
+ IMPLICIT NONE
+ REAL :: arg
+END FUNCTION acosh
+
+! We do only compile, so no main program needed.
+
+! { dg-final { cleanup-modules "testmod" } }
diff --git a/gcc/testsuite/gfortran.dg/intrinsic_shadow_3.f03 b/gcc/testsuite/gfortran.dg/intrinsic_shadow_3.f03
new file mode 100644
index 00000000000..069a99b3433
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/intrinsic_shadow_3.f03
@@ -0,0 +1,27 @@
+! { dg-do compile }
+! { dg-options "-Wno-intrinsic-shadow -fall-intrinsics" }
+
+! PR fortran/33141
+! Check that the "intrinsic shadow" warnings are not emitted if the warning
+! is negated.
+
+MODULE testmod
+ IMPLICIT NONE
+
+CONTAINS
+
+ REAL FUNCTION asin (arg) ! { dg-bogus "shadow the intrinsic" }
+ IMPLICIT NONE
+ REAL :: arg
+ END FUNCTION asin
+
+END MODULE testmod
+
+REAL FUNCTION acos (arg) ! { dg-bogus "of an intrinsic" }
+ IMPLICIT NONE
+ REAL :: arg
+END FUNCTION acos
+
+! We do only compile, so no main program needed.
+
+! { dg-final { cleanup-modules "testmod" } }
diff --git a/gcc/testsuite/gfortran.dg/intrinsic_std_1.f90 b/gcc/testsuite/gfortran.dg/intrinsic_std_1.f90
new file mode 100644
index 00000000000..efb1dce5456
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/intrinsic_std_1.f90
@@ -0,0 +1,48 @@
+! { dg-do compile }
+! { dg-options "-std=f95 -Wintrinsics-std -fdump-tree-original" }
+
+! PR fortran/33141
+! Check for the expected behaviour when an intrinsic function/subroutine is
+! called that is not available in the defined standard or that is a GNU
+! extension:
+! There should be a warning emitted on the call, and the reference should be
+! treated like an external call.
+! For declaring a non-standard intrinsic INTRINSIC, a hard error should be
+! generated, of course.
+
+SUBROUTINE no_implicit
+ IMPLICIT NONE
+ REAL :: asinh ! { dg-warning "Fortran 2008" }
+
+ ! abort is a GNU extension
+ CALL abort () ! { dg-warning "extension" }
+
+ ! ASINH is an intrinsic of F2008
+ ! The warning should be issued in the declaration above where it is declared
+ ! EXTERNAL.
+ WRITE (*,*) ASINH (1.) ! { dg-bogus "Fortran 2008" }
+END SUBROUTINE no_implicit
+
+SUBROUTINE implicit_type
+ ! acosh has implicit type
+
+ WRITE (*,*) ACOSH (1.) ! { dg-warning "Fortran 2008" }
+ WRITE (*,*) ACOSH (1.) ! { dg-bogus "Fortran 2008" }
+END SUBROUTINE implicit_type
+
+SUBROUTINE specification_expression
+ CHARACTER(KIND=selected_char_kind("ascii")) :: x
+! { dg-error "specification function" "" { target "*-*-*" } 34 }
+! { dg-warning "Fortran 2003" "" { target "*-*-*" } 34 }
+END SUBROUTINE specification_expression
+
+SUBROUTINE intrinsic_decl
+ IMPLICIT NONE
+ INTRINSIC :: atanh ! { dg-error "Fortran 2008" }
+ INTRINSIC :: abort ! { dg-error "extension" }
+END SUBROUTINE intrinsic_decl
+
+! Scan that really external functions are called.
+! { dg-final { scan-tree-dump " abort " "original" } }
+! { dg-final { scan-tree-dump " asinh " "original" } }
+! { dg-final { scan-tree-dump " acosh " "original" } }
diff --git a/gcc/testsuite/gfortran.dg/intrinsic_std_2.f90 b/gcc/testsuite/gfortran.dg/intrinsic_std_2.f90
new file mode 100644
index 00000000000..6112d906d42
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/intrinsic_std_2.f90
@@ -0,0 +1,15 @@
+! { dg-do link }
+! { dg-options "-std=f95 -Wintrinsics-std -fall-intrinsics" }
+
+! PR fortran/33141
+! Check that -fall-intrinsics makes all intrinsics available.
+
+PROGRAM main
+ IMPLICIT NONE
+
+ ! abort is a GNU extension
+ CALL abort () ! { dg-bogus "extension" }
+
+ ! ASINH is an intrinsic of F2008
+ WRITE (*,*) ASINH (1.) ! { dg-bogus "Fortran 2008" }
+END PROGRAM main
diff --git a/gcc/testsuite/gfortran.dg/intrinsic_std_3.f90 b/gcc/testsuite/gfortran.dg/intrinsic_std_3.f90
new file mode 100644
index 00000000000..15a424b1c91
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/intrinsic_std_3.f90
@@ -0,0 +1,15 @@
+! { dg-do link }
+! { dg-options "-std=gnu -Wintrinsics-std" }
+
+! PR fortran/33141
+! -std=gnu should allow every intrinsic.
+
+PROGRAM main
+ IMPLICIT NONE
+
+ ! abort is a GNU extension
+ CALL abort () ! { dg-bogus "extension" }
+
+ ! ASINH is an intrinsic of F2008
+ WRITE (*,*) ASINH (1.) ! { dg-bogus "Fortran 2008" }
+END PROGRAM main
diff --git a/gcc/testsuite/gfortran.dg/intrinsic_std_4.f90 b/gcc/testsuite/gfortran.dg/intrinsic_std_4.f90
new file mode 100644
index 00000000000..e83ed4c884d
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/intrinsic_std_4.f90
@@ -0,0 +1,46 @@
+! { dg-do run }
+! { dg-options "-std=f95 -Wno-intrinsics-std" }
+
+! PR fortran/33141
+! Check that calls to intrinsics not in the current standard are "allowed" and
+! linked to external procedures with that name.
+! Addionally, this checks that -Wno-intrinsics-std turns off the warning.
+
+SUBROUTINE abort ()
+ IMPLICIT NONE
+ WRITE (*,*) "Correct"
+END SUBROUTINE abort
+
+REAL FUNCTION asinh (arg)
+ IMPLICIT NONE
+ REAL :: arg
+
+ WRITE (*,*) "Correct"
+ asinh = arg
+END FUNCTION asinh
+
+SUBROUTINE implicit_none
+ IMPLICIT NONE
+ REAL :: asinh ! { dg-bogus "Fortran 2008" }
+ REAL :: x
+
+ ! Both times our version above should be called
+ CALL abort () ! { dg-bogus "extension" }
+ x = ASINH (1.) ! { dg-bogus "Fortran 2008" }
+END SUBROUTINE implicit_none
+
+SUBROUTINE implicit_type
+ ! ASINH has implicit type here
+ REAL :: x
+
+ ! Our version should be called
+ x = ASINH (1.) ! { dg-bogus "Fortran 2008" }
+END SUBROUTINE implicit_type
+
+PROGRAM main
+ ! This should give a total of three "Correct"s
+ CALL implicit_none ()
+ CALL implicit_type ()
+END PROGRAM main
+
+! { dg-output "Correct\.*Correct\.*Correct" }
diff --git a/gcc/testsuite/gfortran.dg/matmul_bounds_2.f90 b/gcc/testsuite/gfortran.dg/matmul_bounds_2.f90
new file mode 100644
index 00000000000..429b28c3016
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/matmul_bounds_2.f90
@@ -0,0 +1,16 @@
+! { dg-do run }
+! { dg-options "-fbounds-check" }
+! { dg-shouldfail "Fortran runtime error: Incorrect extent in return array in MATMUL intrinsic for dimension 2: is 2, should be 3" }
+program main
+ real, dimension(3,2) :: a
+ real, dimension(2,3) :: b
+ real, dimension(:,:), allocatable :: ret
+ allocate (ret(2,2))
+ a = 1.0
+ b = 2.3
+ ret = matmul(b,a) ! This is OK
+ deallocate(ret)
+ allocate(ret(3,2))
+ ret = matmul(a,b) ! This should throw an error.
+end program main
+! { dg-output "Fortran runtime error: Incorrect extent in return array in MATMUL intrinsic for dimension 2: is 2, should be 3" }
diff --git a/gcc/testsuite/gfortran.dg/matmul_bounds_3.f90 b/gcc/testsuite/gfortran.dg/matmul_bounds_3.f90
new file mode 100644
index 00000000000..c5830ded729
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/matmul_bounds_3.f90
@@ -0,0 +1,16 @@
+! { dg-do run }
+! { dg-options "-fbounds-check" }
+! { dg-shouldfail "Fortran runtime error: Incorrect extent in return array in MATMUL intrinsic for dimension 1: is 2, should be 3" }
+program main
+ real, dimension(3,2) :: a
+ real, dimension(2,3) :: b
+ real, dimension(:,:), allocatable :: ret
+ allocate (ret(3,3))
+ a = 1.0
+ b = 2.3
+ ret = matmul(a,b) ! This is OK
+ deallocate(ret)
+ allocate(ret(2,3))
+ ret = matmul(a,b) ! This should throw an error.
+end program main
+! { dg-output "Fortran runtime error: Incorrect extent in return array in MATMUL intrinsic for dimension 1: is 2, should be 3" }
diff --git a/gcc/testsuite/gfortran.dg/matmul_bounds_4.f90 b/gcc/testsuite/gfortran.dg/matmul_bounds_4.f90
new file mode 100644
index 00000000000..a61bacc1d2b
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/matmul_bounds_4.f90
@@ -0,0 +1,16 @@
+! { dg-do run }
+! { dg-options "-fbounds-check" }
+! { dg-shouldfail "Fortran runtime error: Incorrect extent in return array in MATMUL intrinsic: is 3, should be 2" }
+program main
+ real, dimension(3) :: a
+ real, dimension(3,2) :: b
+ real, dimension(:), allocatable :: ret
+ allocate (ret(2))
+ a = 1.0
+ b = 2.3
+ ret = matmul(a,b) ! This is OK
+ deallocate(ret)
+ allocate(ret(3))
+ ret = matmul(a,b) ! This should throw an error.
+end program main
+! { dg-output "Fortran runtime error: Incorrect extent in return array in MATMUL intrinsic: is 3, should be 2" }
diff --git a/gcc/testsuite/gfortran.dg/matmul_bounds_5.f90 b/gcc/testsuite/gfortran.dg/matmul_bounds_5.f90
new file mode 100644
index 00000000000..4b20098f50f
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/matmul_bounds_5.f90
@@ -0,0 +1,16 @@
+! { dg-do run }
+! { dg-options "-fbounds-check" }
+! { dg-shouldfail "Fortran runtime error: Incorrect extent in return array in MATMUL intrinsic: is 3, should be 2" }
+program main
+ real, dimension(2,3) :: a
+ real, dimension(3) :: b
+ real, dimension(:), allocatable :: ret
+ allocate (ret(2))
+ a = 1.0
+ b = 2.3
+ ret = matmul(a,b) ! This is OK
+ deallocate(ret)
+ allocate(ret(3))
+ ret = matmul(a,b) ! This should throw an error.
+end program main
+! { dg-output "Fortran runtime error: Incorrect extent in return array in MATMUL intrinsic: is 3, should be 2" }
diff --git a/gcc/testsuite/gfortran.dg/namelist_52.f90 b/gcc/testsuite/gfortran.dg/namelist_52.f90
new file mode 100644
index 00000000000..6e31382927f
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/namelist_52.f90
@@ -0,0 +1,32 @@
+! { dg-do run }
+! PR36582 Namelist I/O error: Bogus "Cannot match namelist object"
+! Test case derived from PR.
+module mod1
+
+type screen_io_type
+integer :: begin
+end type screen_io_type
+
+type adjoint_type
+type(screen_io_type) :: screen_io_fs_ntime
+character(12) :: solver_type
+end type adjoint_type
+
+type(adjoint_type) :: adjoint
+namelist/info_adjoint/adjoint
+
+end module mod1
+
+program gfortran_error_2
+use mod1
+adjoint%solver_type = "abcdefghijkl"
+open(31,status='scratch')
+write(31, '(a)') "&info_adjoint"
+write(31, '(a)') "adjoint%solver_type = 'direct'"
+write(31, '(a)') "adjoint%screen_io_fs_ntime%begin = 42"
+write(31, '(a)') "/"
+rewind(31)
+read(31,nml=info_adjoint)
+if (adjoint%solver_type /= 'direct') call abort
+if (adjoint%screen_io_fs_ntime%begin /= 42) call abort
+end program gfortran_error_2
diff --git a/gcc/testsuite/gfortran.dg/parameter_array_init_4.f90 b/gcc/testsuite/gfortran.dg/parameter_array_init_4.f90
index 5bdcb3723b1..f6c2f84b2a8 100644
--- a/gcc/testsuite/gfortran.dg/parameter_array_init_4.f90
+++ b/gcc/testsuite/gfortran.dg/parameter_array_init_4.f90
@@ -15,10 +15,10 @@ character(kind=1,len=*), parameter :: str1(2) = [ 1_'Ac',1_'cc']
character(kind=1,len=*), parameter :: str_s1 = 'Acc'
CHARACTER (kind=4,len=*) MY_STRING4(1:3), my_string_s4
-PARAMETER ( MY_STRING4 = (/ "A" , "B", "C" /) )
-PARAMETER ( MY_STRING_S4 = "AB C" )
-character(kind=4,len=*), parameter :: str4(2) = [ 1_'Ac',1_'cc']
-character(kind=4,len=*), parameter :: str_s4 = 'Acc'
+PARAMETER ( MY_STRING4 = (/ 4_"A" , 4_"B", 4_"C" /) )
+PARAMETER ( MY_STRING_S4 = 4_"AB C" )
+character(kind=4,len=*), parameter :: str4(2) = [ 4_'Ac',4_'cc']
+character(kind=4,len=*), parameter :: str_s4 = 4_'Acc'
if(len(MY_STRING) /= 1) call abort()
if( MY_STRING(1) /= "A" &
diff --git a/gcc/testsuite/gfortran.dg/pointer_to_substring.f90 b/gcc/testsuite/gfortran.dg/pointer_to_substring.f90
new file mode 100644
index 00000000000..054a29d56bb
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pointer_to_substring.f90
@@ -0,0 +1,10 @@
+! { dg-do compile }
+! PR36724 - ICE on pointer to substring
+! testcase contributed by Loukas Peristeras.
+
+ character(LEN=132), target :: line
+ character(LEN=1), pointer :: t
+
+ read(*,'(A)') line
+ t=>line(1:1)
+end
diff --git a/gcc/testsuite/gfortran.dg/product_sum_bounds_1.f90 b/gcc/testsuite/gfortran.dg/product_sum_bounds_1.f90
new file mode 100644
index 00000000000..c6390896c17
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/product_sum_bounds_1.f90
@@ -0,0 +1,8 @@
+! { dg-do compile }
+program main
+ real, dimension(4,3) :: a
+ real, dimension(2) :: b
+ a = 21.
+ b = product(a,dim=1) ! { dg-error "Different shape" }
+ b = sum(a,dim=2) ! { dg-error "Different shape" }
+end program main
diff --git a/gcc/testsuite/gfortran.dg/rank_2.f90 b/gcc/testsuite/gfortran.dg/rank_2.f90
index b7d75dbeae4..cd52cc446e2 100644
--- a/gcc/testsuite/gfortran.dg/rank_2.f90
+++ b/gcc/testsuite/gfortran.dg/rank_2.f90
@@ -5,4 +5,8 @@
! Fortran 2008 allows 15 dimensions (including co-array ranks)
!
integer :: a(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15) ! { dg-error "more than 7 dimensions" }
+
+! PR fortran/36825:
+integer,parameter :: N=10
+complex,dimension(-N:N,-N:N,0:1,0:1,-N:N,-N:N,0:1,0:1) :: P ! { dg-error "more than 7 dimensions" }
end
diff --git a/gcc/testsuite/gfortran.dg/selected_char_kind_3.f90 b/gcc/testsuite/gfortran.dg/selected_char_kind_3.f90
index 5cc7b112496..a7b7ae7d895 100644
--- a/gcc/testsuite/gfortran.dg/selected_char_kind_3.f90
+++ b/gcc/testsuite/gfortran.dg/selected_char_kind_3.f90
@@ -1,10 +1,10 @@
! { dg-do compile }
-! { dg-options "-std=f95 -pedantic -Wall" }
+! { dg-options "-std=f95 -pedantic -Wall -Wno-intrinsics-std" }
!
! Check that SELECTED_CHAR_KIND is rejected with -std=f95
!
implicit none
- character(kind=selected_char_kind("ascii")) :: s ! { dg-error "is not included in the selected standard" }
+ character(kind=selected_char_kind("ascii")) :: s ! { dg-error "must be an intrinsic or a specification function" }
s = "" ! { dg-error "has no IMPLICIT type" }
print *, s
end
diff --git a/gcc/testsuite/gfortran.dg/used_types_21.f90 b/gcc/testsuite/gfortran.dg/used_types_21.f90
new file mode 100644
index 00000000000..04b109f139a
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/used_types_21.f90
@@ -0,0 +1,11 @@
+! { dg-do compile }
+! Check that pointer components are allowed to empty types.
+
+TYPE :: empty_t
+END TYPE empty_t
+
+TYPE :: comp_t
+ TYPE(empty_t), POINTER :: ptr
+END TYPE comp_t
+
+END
diff --git a/gcc/testsuite/gfortran.dg/warn_std_1.f90 b/gcc/testsuite/gfortran.dg/warn_std_1.f90
index 4d709a12cdf..b0e4b5d4148 100644
--- a/gcc/testsuite/gfortran.dg/warn_std_1.f90
+++ b/gcc/testsuite/gfortran.dg/warn_std_1.f90
@@ -1,5 +1,5 @@
! { dg-do compile }
-! { dg-options "-Wnonstd-intrinsics -std=gnu" }
+! { dg-options "-std=gnu" }
!
! PR fortran/32778 - pedantic warning: intrinsics that
! are GNU extensions not part of -std=gnu
diff --git a/gcc/testsuite/gfortran.dg/warn_std_2.f90 b/gcc/testsuite/gfortran.dg/warn_std_2.f90
index 0a8c509d5c6..325fc8cb6e1 100644
--- a/gcc/testsuite/gfortran.dg/warn_std_2.f90
+++ b/gcc/testsuite/gfortran.dg/warn_std_2.f90
@@ -1,5 +1,5 @@
! { dg-do compile }
-! { dg-options "-Wnonstd-intrinsics -std=f95" }
+! { dg-options "-std=f95 -Wintrinsics-std" }
!
! PR fortran/32778 - pedantic warning: intrinsics that
! are GNU extensions not part of -std=gnu
@@ -11,15 +11,15 @@ CHARACTER(len=255) :: tmp
REAL(8) :: x
! GNU extension, check overload of F77 standard intrinsic
-x = ZABS(CMPLX(0.0, 1.0, 8)) ! { dg-error "is not included in the selected standard" }
+x = ZABS(CMPLX(0.0, 1.0, 8)) ! { dg-warning "extension" }
! GNU extension
-CALL flush() ! { dg-error "is not included in the selected standard" }
+CALL flush() ! { dg-warning "extension" }
! F95
tmp = ADJUSTL(" gfortran ")
! F2003
-CALL GET_COMMAND (tmp) ! { dg-error "is not included in the selected standard" }
+CALL GET_COMMAND (tmp) ! { dg-warning "Fortran 2003" }
END
diff --git a/gcc/testsuite/gfortran.dg/warn_std_3.f90 b/gcc/testsuite/gfortran.dg/warn_std_3.f90
index 0d0a0f149bd..89fe257389b 100644
--- a/gcc/testsuite/gfortran.dg/warn_std_3.f90
+++ b/gcc/testsuite/gfortran.dg/warn_std_3.f90
@@ -1,5 +1,5 @@
! { dg-do compile }
-! { dg-options "-Wnonstd-intrinsics -std=f2003" }
+! { dg-options "-std=f2003 -Wintrinsics-std" }
!
! PR fortran/32778 - pedantic warning: intrinsics that
! are GNU extensions not part of -std=gnu
@@ -11,10 +11,10 @@ CHARACTER(len=255) :: tmp
REAL(8) :: x
! GNU extension, check overload of F77 standard intrinsic
-x = ZABS(CMPLX(0.0, 1.0, 8)) ! { dg-error "is not included in the selected standard" }
+x = ZABS(CMPLX(0.0, 1.0, 8)) ! { dg-warning "extension" }
! GNU extension
-CALL flush() ! { dg-error "is not included in the selected standard" }
+CALL flush() ! { dg-warning "extension" }
! F95
tmp = ADJUSTL(" gfortran ")
diff --git a/gcc/testsuite/gfortran.dg/zero_sized_1.f90 b/gcc/testsuite/gfortran.dg/zero_sized_1.f90
index 224b2c007d3..5461fb1a7f0 100644
--- a/gcc/testsuite/gfortran.dg/zero_sized_1.f90
+++ b/gcc/testsuite/gfortran.dg/zero_sized_1.f90
@@ -49,8 +49,8 @@ subroutine test_eoshift
if (any(eoshift(tempm(:,5:4),shift=(/1,-1/),dim=1,boundary=42.0)/= 0)) call abort
if (any(eoshift(tempm(:,5:4),shift=(/1,-1/),dim=2,boundary=42.0)/= 0)) call abort
- if (any(eoshift(foo,dim=1,shift=1,boundary=(/42.0,-7.0/))/= 0)) call abort
- if (any(eoshift(tempn(2:1),dim=1,shift=1,boundary=(/42.0,-7.0/))/= 0)) call abort
+ if (any(eoshift(foo,dim=1,shift=1,boundary=42.0)/= 0)) call abort
+ if (any(eoshift(tempn(2:1),dim=1,shift=1,boundary=-7.0)/= 0)) call abort
if (any(eoshift(bar,shift=(/1,-1/),dim=1,boundary=(/42.0,-7.0/))/= 0)) call abort
if (any(eoshift(bar,shift=(/1,-1/),dim=2,boundary=(/42.0,-7.0/))/= 0)) call abort
if (any(eoshift(gee,shift=(/1,-1/),dim=1,boundary=(/42.0,-7.0/))/= 0)) call abort
@@ -159,15 +159,17 @@ end
subroutine test_unpack
integer :: tempn(1,5), tempv(5)
integer,allocatable :: foo(:,:), bar(:)
+ integer :: zero
tempn = 2
tempv = 5
+ zero = 0
allocate(foo(0,1:7),bar(0:-1))
if (any(unpack(tempv,tempv/=0,tempv) /= 5) .or. &
size(unpack(tempv,tempv/=0,tempv)) /= 5) call abort
if (any(unpack(tempv(1:0),tempv/=0,tempv) /= 5) .or. &
size(unpack(tempv(1:0),tempv/=0,tempv)) /= 5) call abort
- if (any(unpack(tempv,tempv(1:0)/=0,tempv) /= -47)) call abort
- if (any(unpack(tempv(5:4),tempv(1:0)/=0,tempv) /= -47)) call abort
+ if (any(unpack(tempv,tempv(1:zero)/=0,tempv) /= -47)) call abort
+ if (any(unpack(tempv(5:4),tempv(1:zero)/=0,tempv) /= -47)) call abort
if (any(unpack(bar,foo==foo,foo) /= -47)) call abort
deallocate(foo,bar)
end
diff --git a/gcc/testsuite/gfortran.dg/zero_sized_5.f90 b/gcc/testsuite/gfortran.dg/zero_sized_5.f90
new file mode 100644
index 00000000000..30ca8bf8199
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/zero_sized_5.f90
@@ -0,0 +1,15 @@
+! { dg-do run }
+! These used to segfault.
+program main
+ real, dimension(1,0) :: a, b, c
+ integer, dimension(0) :: j
+ a = 0
+ c = 0
+ b = cshift (a,1)
+ b = cshift (a,j)
+ b = eoshift (a,1)
+ b = eoshift (a,(/1/))
+ b = eoshift (a,1,boundary=c(1,:))
+ b = eoshift (a, j, boundary=c(1,:))
+
+end program main
diff --git a/gcc/testsuite/gnat.dg/allocator_maxalign1.adb b/gcc/testsuite/gnat.dg/allocator_maxalign1.adb
new file mode 100644
index 00000000000..062c39bbf87
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/allocator_maxalign1.adb
@@ -0,0 +1,42 @@
+-- { dg-do run }
+
+with System.Storage_Elements; use System.Storage_Elements;
+with Ada.Unchecked_Deallocation;
+
+procedure Allocator_Maxalign1 is
+
+ Max_Alignment : constant := Standard'Maximum_Alignment;
+
+ type Block is record
+ X : Integer;
+ end record;
+ for Block'Alignment use Standard'Maximum_Alignment;
+
+ type Block_Access is access all Block;
+ procedure Free is new Ada.Unchecked_Deallocation (Block, Block_Access);
+
+ N_Blocks : constant := 500;
+ Blocks : array (1 .. N_Blocks) of Block_Access;
+begin
+ if Block'Alignment /= Max_Alignment then
+ raise Program_Error;
+ end if;
+
+ for K in 1 .. 4 loop
+
+ for I in Blocks'Range loop
+ Blocks (I) := new Block;
+ if Blocks (I).all'Address mod Block'Alignment /= 0 then
+ raise Program_Error;
+ end if;
+ Blocks(I).all.X := I;
+ end loop;
+
+ for I in Blocks'Range loop
+ Free (Blocks (I));
+ end loop;
+
+ end loop;
+
+end;
+
diff --git a/gcc/testsuite/gnat.dg/allocator_maxalign2.adb b/gcc/testsuite/gnat.dg/allocator_maxalign2.adb
new file mode 100644
index 00000000000..10644ea6b3c
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/allocator_maxalign2.adb
@@ -0,0 +1,33 @@
+with System, System.Storage_Elements;
+use System.Storage_Elements;
+
+package body Allocator_Maxalign2 is
+
+ Max_Align : constant Storage_Offset := Standard'Maximum_Alignment;
+
+ procedure Validate is
+ use type System.Address;
+ begin
+ if Addr mod Max_Align /= 0 then
+ raise Program_Error;
+ end if;
+ end;
+
+ procedure Check is
+ I : Integer;
+ B : Block;
+ type Block_Access is access all Block;
+ A : Block_Access;
+ begin
+ Addr := I'Address;
+ Addr := B'Address;
+ Validate;
+ for I in 1 .. 50 loop
+ A := new Block;
+ Addr := A.all'Address;
+ Validate;
+ end loop;
+
+ end;
+
+end;
diff --git a/gcc/testsuite/gnat.dg/allocator_maxalign2.ads b/gcc/testsuite/gnat.dg/allocator_maxalign2.ads
new file mode 100644
index 00000000000..43c01081cb6
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/allocator_maxalign2.ads
@@ -0,0 +1,12 @@
+with System;
+
+package Allocator_Maxalign2 is
+ type Block is record
+ X : Integer;
+ end record;
+ for Block'Alignment use Standard'Maximum_Alignment;
+
+ Addr : System.Address;
+
+ procedure Check;
+end;
diff --git a/gcc/testsuite/gnat.dg/case_optimization1.adb b/gcc/testsuite/gnat.dg/case_optimization1.adb
new file mode 100644
index 00000000000..3273b16fe77
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/case_optimization1.adb
@@ -0,0 +1,21 @@
+-- { dg-do compile }
+-- { dg-options "-O2" }
+
+package body Case_Optimization1 is
+
+ function F (Op_Kind : Internal_Operator_Symbol_Kinds) return Integer is
+ begin
+ case Op_Kind is
+ when A_Not_Operator => return 3;
+ when An_Exponentiate_Operator => return 2;
+ when others => return 1;
+ end case;
+ end;
+
+ function Len (E : Element) return Integer is
+ Op_Kind : Internal_Element_Kinds := Int_Kind (E);
+ begin
+ return F (Int_Kind (E));
+ end;
+
+end Case_Optimization1;
diff --git a/gcc/testsuite/gnat.dg/case_optimization1.ads b/gcc/testsuite/gnat.dg/case_optimization1.ads
new file mode 100644
index 00000000000..737c9b70a56
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/case_optimization1.ads
@@ -0,0 +1,7 @@
+with Case_Optimization_Pkg1; use Case_Optimization_Pkg1;
+
+package Case_Optimization1 is
+
+ function Len (E : Element) return Integer;
+
+end Case_Optimization1;
diff --git a/gcc/testsuite/gnat.dg/case_optimization_pkg1.ads b/gcc/testsuite/gnat.dg/case_optimization_pkg1.ads
new file mode 100644
index 00000000000..da458645e9c
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/case_optimization_pkg1.ads
@@ -0,0 +1,432 @@
+package Case_Optimization_Pkg1 is
+
+ type Element is null record;
+
+ type Internal_Element_Kinds is
+ (Not_An_Element,
+ An_All_Calls_Remote_Pragma,
+ An_Asynchronous_Pragma,
+ An_Atomic_Pragma,
+ An_Atomic_Components_Pragma,
+ An_Attach_Handler_Pragma,
+ A_Controlled_Pragma,
+ A_Convention_Pragma,
+ A_Discard_Names_Pragma,
+ An_Elaborate_Pragma,
+ An_Elaborate_All_Pragma,
+ An_Elaborate_Body_Pragma,
+ An_Export_Pragma,
+ An_Import_Pragma,
+ An_Inline_Pragma,
+ An_Inspection_Point_Pragma,
+ An_Interrupt_Handler_Pragma,
+ An_Interrupt_Priority_Pragma,
+ A_Linker_Options_Pragma,
+ A_List_Pragma,
+ A_Locking_Policy_Pragma,
+ A_Normalize_Scalars_Pragma,
+ An_Optimize_Pragma,
+ A_Pack_Pragma,
+ A_Page_Pragma,
+ A_Preelaborate_Pragma,
+ A_Priority_Pragma,
+ A_Pure_Pragma,
+ A_Queuing_Policy_Pragma,
+ A_Remote_Call_Interface_Pragma,
+ A_Remote_Types_Pragma,
+ A_Restrictions_Pragma,
+ A_Reviewable_Pragma,
+ A_Shared_Passive_Pragma,
+ A_Storage_Size_Pragma,
+ A_Suppress_Pragma,
+ A_Task_Dispatching_Policy_Pragma,
+ A_Volatile_Pragma,
+ A_Volatile_Components_Pragma,
+ An_Assert_Pragma,
+ An_Assertion_Policy_Pragma,
+ A_Detect_Blocking_Pragma,
+ A_No_Return_Pragma,
+ A_Partition_Elaboration_Policy_Pragma,
+ A_Preelaborable_Initialization_Pragma,
+ A_Priority_Specific_Dispatching_Pragma,
+ A_Profile_Pragma,
+ A_Relative_Deadline_Pragma,
+ An_Unchecked_Union_Pragma,
+ An_Unsuppress_Pragma,
+ An_Implementation_Defined_Pragma,
+ An_Unknown_Pragma,
+ A_Defining_Identifier,
+ A_Defining_Character_Literal,
+ A_Defining_Enumeration_Literal,
+ A_Defining_And_Operator,
+ A_Defining_Or_Operator,
+ A_Defining_Xor_Operator,
+ A_Defining_Equal_Operator,
+ A_Defining_Not_Equal_Operator,
+ A_Defining_Less_Than_Operator,
+ A_Defining_Less_Than_Or_Equal_Operator,
+ A_Defining_Greater_Than_Operator,
+ A_Defining_Greater_Than_Or_Equal_Operator,
+ A_Defining_Plus_Operator,
+ A_Defining_Minus_Operator,
+ A_Defining_Concatenate_Operator,
+ A_Defining_Unary_Plus_Operator,
+ A_Defining_Unary_Minus_Operator,
+ A_Defining_Multiply_Operator,
+ A_Defining_Divide_Operator,
+ A_Defining_Mod_Operator,
+ A_Defining_Rem_Operator,
+ A_Defining_Exponentiate_Operator,
+ A_Defining_Abs_Operator,
+ A_Defining_Not_Operator,
+ A_Defining_Expanded_Name,
+ An_Ordinary_Type_Declaration,
+ A_Task_Type_Declaration,
+ A_Protected_Type_Declaration,
+ An_Incomplete_Type_Declaration,
+ A_Tagged_Incomplete_Type_Declaration,
+ A_Private_Type_Declaration,
+ A_Private_Extension_Declaration,
+ A_Subtype_Declaration,
+ A_Variable_Declaration,
+ A_Constant_Declaration,
+ A_Deferred_Constant_Declaration,
+ A_Single_Task_Declaration,
+ A_Single_Protected_Declaration,
+ An_Integer_Number_Declaration,
+ A_Real_Number_Declaration,
+ An_Enumeration_Literal_Specification,
+ A_Discriminant_Specification,
+ A_Component_Declaration,
+ A_Loop_Parameter_Specification,
+ A_Procedure_Declaration,
+ A_Function_Declaration,
+ A_Parameter_Specification,
+ A_Procedure_Body_Declaration,
+ A_Function_Body_Declaration,
+ A_Return_Object_Declaration,
+ A_Null_Procedure_Declaration,
+ A_Package_Declaration,
+ A_Package_Body_Declaration,
+ An_Object_Renaming_Declaration,
+ An_Exception_Renaming_Declaration,
+ A_Package_Renaming_Declaration,
+ A_Procedure_Renaming_Declaration,
+ A_Function_Renaming_Declaration,
+ A_Generic_Package_Renaming_Declaration,
+ A_Generic_Procedure_Renaming_Declaration,
+ A_Generic_Function_Renaming_Declaration,
+ A_Task_Body_Declaration,
+ A_Protected_Body_Declaration,
+ An_Entry_Declaration,
+ An_Entry_Body_Declaration,
+ An_Entry_Index_Specification,
+ A_Procedure_Body_Stub,
+ A_Function_Body_Stub,
+ A_Package_Body_Stub,
+ A_Task_Body_Stub,
+ A_Protected_Body_Stub,
+ An_Exception_Declaration,
+ A_Choice_Parameter_Specification,
+ A_Generic_Procedure_Declaration,
+ A_Generic_Function_Declaration,
+ A_Generic_Package_Declaration,
+ A_Package_Instantiation,
+ A_Procedure_Instantiation,
+ A_Function_Instantiation,
+ A_Formal_Object_Declaration,
+ A_Formal_Type_Declaration,
+ A_Formal_Procedure_Declaration,
+ A_Formal_Function_Declaration,
+ A_Formal_Package_Declaration,
+ A_Formal_Package_Declaration_With_Box,
+ A_Derived_Type_Definition,
+ A_Derived_Record_Extension_Definition,
+ An_Enumeration_Type_Definition,
+ A_Signed_Integer_Type_Definition,
+ A_Modular_Type_Definition,
+ A_Root_Integer_Definition,
+ A_Root_Real_Definition,
+ A_Universal_Integer_Definition,
+ A_Universal_Real_Definition,
+ A_Universal_Fixed_Definition,
+ A_Floating_Point_Definition,
+ An_Ordinary_Fixed_Point_Definition,
+ A_Decimal_Fixed_Point_Definition,
+ An_Unconstrained_Array_Definition,
+ A_Constrained_Array_Definition,
+ A_Record_Type_Definition,
+ A_Tagged_Record_Type_Definition,
+ An_Ordinary_Interface,
+ A_Limited_Interface,
+ A_Task_Interface,
+ A_Protected_Interface,
+ A_Synchronized_Interface,
+ A_Pool_Specific_Access_To_Variable,
+ An_Access_To_Variable,
+ An_Access_To_Constant,
+ An_Access_To_Procedure,
+ An_Access_To_Protected_Procedure,
+ An_Access_To_Function,
+ An_Access_To_Protected_Function,
+ A_Subtype_Indication,
+ A_Range_Attribute_Reference,
+ A_Simple_Expression_Range,
+ A_Digits_Constraint,
+ A_Delta_Constraint,
+ An_Index_Constraint,
+ A_Discriminant_Constraint,
+ A_Component_Definition,
+ A_Discrete_Subtype_Indication_As_Subtype_Definition,
+ A_Discrete_Range_Attribute_Reference_As_Subtype_Definition,
+ A_Discrete_Simple_Expression_Range_As_Subtype_Definition,
+ A_Discrete_Subtype_Indication,
+ A_Discrete_Range_Attribute_Reference,
+ A_Discrete_Simple_Expression_Range,
+ An_Unknown_Discriminant_Part,
+ A_Known_Discriminant_Part,
+ A_Record_Definition,
+ A_Null_Record_Definition,
+ A_Null_Component,
+ A_Variant_Part,
+ A_Variant,
+ An_Others_Choice,
+ An_Anonymous_Access_To_Variable,
+ An_Anonymous_Access_To_Constant,
+ An_Anonymous_Access_To_Procedure,
+ An_Anonymous_Access_To_Protected_Procedure,
+ An_Anonymous_Access_To_Function,
+ An_Anonymous_Access_To_Protected_Function,
+ A_Private_Type_Definition,
+ A_Tagged_Private_Type_Definition,
+ A_Private_Extension_Definition,
+ A_Task_Definition,
+ A_Protected_Definition,
+ A_Formal_Private_Type_Definition,
+ A_Formal_Tagged_Private_Type_Definition,
+ A_Formal_Derived_Type_Definition,
+ A_Formal_Discrete_Type_Definition,
+ A_Formal_Signed_Integer_Type_Definition,
+ A_Formal_Modular_Type_Definition,
+ A_Formal_Floating_Point_Definition,
+ A_Formal_Ordinary_Fixed_Point_Definition,
+ A_Formal_Decimal_Fixed_Point_Definition,
+ A_Formal_Ordinary_Interface,
+ A_Formal_Limited_Interface,
+ A_Formal_Task_Interface,
+ A_Formal_Protected_Interface,
+ A_Formal_Synchronized_Interface,
+ A_Formal_Unconstrained_Array_Definition,
+ A_Formal_Constrained_Array_Definition,
+ A_Formal_Pool_Specific_Access_To_Variable,
+ A_Formal_Access_To_Variable,
+ A_Formal_Access_To_Constant,
+ A_Formal_Access_To_Procedure,
+ A_Formal_Access_To_Protected_Procedure,
+ A_Formal_Access_To_Function,
+ A_Formal_Access_To_Protected_Function,
+ An_Integer_Literal,
+ A_Real_Literal,
+ A_String_Literal,
+ An_Identifier,
+ An_And_Operator,
+ An_Or_Operator,
+ An_Xor_Operator,
+ An_Equal_Operator,
+ A_Not_Equal_Operator,
+ A_Less_Than_Operator,
+ A_Less_Than_Or_Equal_Operator,
+ A_Greater_Than_Operator,
+ A_Greater_Than_Or_Equal_Operator,
+ A_Plus_Operator,
+ A_Minus_Operator,
+ A_Concatenate_Operator,
+ A_Unary_Plus_Operator,
+ A_Unary_Minus_Operator,
+ A_Multiply_Operator,
+ A_Divide_Operator,
+ A_Mod_Operator,
+ A_Rem_Operator,
+ An_Exponentiate_Operator,
+ An_Abs_Operator,
+ A_Not_Operator,
+ A_Character_Literal,
+ An_Enumeration_Literal,
+ An_Explicit_Dereference,
+ A_Function_Call,
+ An_Indexed_Component,
+ A_Slice,
+ A_Selected_Component,
+ An_Access_Attribute,
+ An_Address_Attribute,
+ An_Adjacent_Attribute,
+ An_Aft_Attribute,
+ An_Alignment_Attribute,
+ A_Base_Attribute,
+ A_Bit_Order_Attribute,
+ A_Body_Version_Attribute,
+ A_Callable_Attribute,
+ A_Caller_Attribute,
+ A_Ceiling_Attribute,
+ A_Class_Attribute,
+ A_Component_Size_Attribute,
+ A_Compose_Attribute,
+ A_Constrained_Attribute,
+ A_Copy_Sign_Attribute,
+ A_Count_Attribute,
+ A_Definite_Attribute,
+ A_Delta_Attribute,
+ A_Denorm_Attribute,
+ A_Digits_Attribute,
+ An_Exponent_Attribute,
+ An_External_Tag_Attribute,
+ A_First_Attribute,
+ A_First_Bit_Attribute,
+ A_Floor_Attribute,
+ A_Fore_Attribute,
+ A_Fraction_Attribute,
+ An_Identity_Attribute,
+ An_Image_Attribute,
+ An_Input_Attribute,
+ A_Last_Attribute,
+ A_Last_Bit_Attribute,
+ A_Leading_Part_Attribute,
+ A_Length_Attribute,
+ A_Machine_Attribute,
+ A_Machine_Emax_Attribute,
+ A_Machine_Emin_Attribute,
+ A_Machine_Mantissa_Attribute,
+ A_Machine_Overflows_Attribute,
+ A_Machine_Radix_Attribute,
+ A_Machine_Rounds_Attribute,
+ A_Max_Attribute,
+ A_Max_Size_In_Storage_Elements_Attribute,
+ A_Min_Attribute,
+ A_Model_Attribute,
+ A_Model_Emin_Attribute,
+ A_Model_Epsilon_Attribute,
+ A_Model_Mantissa_Attribute,
+ A_Model_Small_Attribute,
+ A_Modulus_Attribute,
+ An_Output_Attribute,
+ A_Partition_ID_Attribute,
+ A_Pos_Attribute,
+ A_Position_Attribute,
+ A_Pred_Attribute,
+ A_Range_Attribute,
+ A_Read_Attribute,
+ A_Remainder_Attribute,
+ A_Round_Attribute,
+ A_Rounding_Attribute,
+ A_Safe_First_Attribute,
+ A_Safe_Last_Attribute,
+ A_Scale_Attribute,
+ A_Scaling_Attribute,
+ A_Signed_Zeros_Attribute,
+ A_Size_Attribute,
+ A_Small_Attribute,
+ A_Storage_Pool_Attribute,
+ A_Storage_Size_Attribute,
+ A_Succ_Attribute,
+ A_Tag_Attribute,
+ A_Terminated_Attribute,
+ A_Truncation_Attribute,
+ An_Unbiased_Rounding_Attribute,
+ An_Unchecked_Access_Attribute,
+ A_Val_Attribute,
+ A_Valid_Attribute,
+ A_Value_Attribute,
+ A_Version_Attribute,
+ A_Wide_Image_Attribute,
+ A_Wide_Value_Attribute,
+ A_Wide_Width_Attribute,
+ A_Width_Attribute,
+ A_Write_Attribute,
+ A_Machine_Rounding_Attribute,
+ A_Mod_Attribute,
+ A_Priority_Attribute,
+ A_Stream_Size_Attribute,
+ A_Wide_Wide_Image_Attribute,
+ A_Wide_Wide_Value_Attribute,
+ A_Wide_Wide_Width_Attribute,
+ An_Implementation_Defined_Attribute,
+ An_Unknown_Attribute,
+ A_Record_Aggregate,
+ An_Extension_Aggregate,
+ A_Positional_Array_Aggregate,
+ A_Named_Array_Aggregate,
+ An_And_Then_Short_Circuit,
+ An_Or_Else_Short_Circuit,
+ An_In_Range_Membership_Test,
+ A_Not_In_Range_Membership_Test,
+ An_In_Type_Membership_Test,
+ A_Not_In_Type_Membership_Test,
+ A_Null_Literal,
+ A_Parenthesized_Expression,
+ A_Type_Conversion,
+ A_Qualified_Expression,
+ An_Allocation_From_Subtype,
+ An_Allocation_From_Qualified_Expression,
+ A_Pragma_Argument_Association,
+ A_Discriminant_Association,
+ A_Record_Component_Association,
+ An_Array_Component_Association,
+ A_Parameter_Association,
+ A_Generic_Association,
+ A_Null_Statement,
+ An_Assignment_Statement,
+ An_If_Statement,
+ A_Case_Statement,
+ A_Loop_Statement,
+ A_While_Loop_Statement,
+ A_For_Loop_Statement,
+ A_Block_Statement,
+ An_Exit_Statement,
+ A_Goto_Statement,
+ A_Procedure_Call_Statement,
+ A_Return_Statement,
+ An_Extended_Return_Statement,
+ An_Accept_Statement,
+ An_Entry_Call_Statement,
+ A_Requeue_Statement,
+ A_Requeue_Statement_With_Abort,
+ A_Delay_Until_Statement,
+ A_Delay_Relative_Statement,
+ A_Terminate_Alternative_Statement,
+ A_Selective_Accept_Statement,
+ A_Timed_Entry_Call_Statement,
+ A_Conditional_Entry_Call_Statement,
+ An_Asynchronous_Select_Statement,
+ An_Abort_Statement,
+ A_Raise_Statement,
+ A_Code_Statement,
+ An_If_Path,
+ An_Elsif_Path,
+ An_Else_Path,
+ A_Case_Path,
+ A_Select_Path,
+ An_Or_Path,
+ A_Then_Abort_Path,
+ A_Use_Package_Clause,
+ A_Use_Type_Clause,
+ A_With_Clause,
+ An_Attribute_Definition_Clause,
+ An_Enumeration_Representation_Clause,
+ A_Record_Representation_Clause,
+ An_At_Clause,
+ A_Component_Clause,
+ An_Exception_Handler,
+ Non_Trivial_Mapping,
+ Not_Implemented_Mapping,
+ Trivial_Mapping,
+ No_Mapping);
+
+ subtype Internal_Expression_Kinds is Internal_Element_Kinds
+ range An_Integer_Literal .. An_Allocation_From_Qualified_Expression;
+
+ subtype Internal_Operator_Symbol_Kinds is Internal_Expression_Kinds
+ range An_And_Operator .. A_Not_Operator;
+
+ function Int_Kind (E : Element) return Internal_Element_Kinds;
+
+end Case_Optimization_Pkg1;
diff --git a/gcc/testsuite/gnat.dg/decl_ctx_def.ads b/gcc/testsuite/gnat.dg/decl_ctx_def.ads
new file mode 100644
index 00000000000..dd004dfe07a
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/decl_ctx_def.ads
@@ -0,0 +1,4 @@
+
+package DECL_CTX_Def is
+ X : exception;
+end;
diff --git a/gcc/testsuite/gnat.dg/decl_ctx_use.adb b/gcc/testsuite/gnat.dg/decl_ctx_use.adb
new file mode 100644
index 00000000000..c4fde2b3eb2
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/decl_ctx_use.adb
@@ -0,0 +1,14 @@
+-- { dg-do compile }
+-- { dg-options "-O1" }
+with DECL_CTX_Def; use DECL_CTX_Def;
+package body DECL_CTX_Use is
+ procedure Check_1 is
+ begin
+ raise X;
+ end;
+
+ procedure Check_2 is
+ begin
+ raise X;
+ end;
+end;
diff --git a/gcc/testsuite/gnat.dg/decl_ctx_use.ads b/gcc/testsuite/gnat.dg/decl_ctx_use.ads
new file mode 100644
index 00000000000..2f38f891793
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/decl_ctx_use.ads
@@ -0,0 +1,5 @@
+
+package DECL_CTX_Use is
+ procedure Check_1;
+ procedure Check_2;
+end;
diff --git a/gcc/testsuite/gnat.dg/test_allocator_maxalign2.adb b/gcc/testsuite/gnat.dg/test_allocator_maxalign2.adb
new file mode 100644
index 00000000000..144914d2dc4
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/test_allocator_maxalign2.adb
@@ -0,0 +1,8 @@
+-- { dg-do run }
+
+with Allocator_Maxalign2;
+
+procedure Test_Allocator_Maxalign2 is
+begin
+ Allocator_Maxalign2.Check;
+end;
diff --git a/gcc/testsuite/gnat.dg/tree_static_def.adb b/gcc/testsuite/gnat.dg/tree_static_def.adb
new file mode 100644
index 00000000000..ed86747a8b1
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/tree_static_def.adb
@@ -0,0 +1,11 @@
+
+package body TREE_STATIC_Def is
+
+ procedure check (i : int; v : integer) is
+ begin
+ if i.value /= v then
+ raise program_error;
+ end if;
+ end;
+end;
+
diff --git a/gcc/testsuite/gnat.dg/tree_static_def.ads b/gcc/testsuite/gnat.dg/tree_static_def.ads
new file mode 100644
index 00000000000..1ea58ee03e4
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/tree_static_def.ads
@@ -0,0 +1,10 @@
+package TREE_STATIC_Def is
+
+ type Int is record
+ Value : Integer;
+ end record;
+
+ procedure check (I : Int; v : integer);
+
+ One : constant Int := (Value => 1);
+end;
diff --git a/gcc/testsuite/gnat.dg/tree_static_use.adb b/gcc/testsuite/gnat.dg/tree_static_use.adb
new file mode 100644
index 00000000000..ff02b54565c
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/tree_static_use.adb
@@ -0,0 +1,12 @@
+-- { dg-do run }
+-- { dg-options "-O1" }
+
+with TREE_STATIC_Def; use TREE_STATIC_Def;
+
+procedure TREE_STATIC_Use is
+ I : Int := One;
+begin
+ check (I, 1);
+end;
+
+
diff --git a/gcc/testsuite/lib/compat.exp b/gcc/testsuite/lib/compat.exp
index 84538a6f8b4..e8ca8fc7987 100644
--- a/gcc/testsuite/lib/compat.exp
+++ b/gcc/testsuite/lib/compat.exp
@@ -156,6 +156,8 @@ proc compat-run { testname objlist dest optall optfile optstr } {
proc compat-get-options-main { src } {
# dg-options sets a variable called dg-extra-tool-flags.
set dg-extra-tool-flags ""
+ # dg-options sets a variable called tool_flags.
+ set tool_flags ""
# dg-require-* sets dg-do-what.
upvar dg-do-what dg-do-what
@@ -164,6 +166,7 @@ proc compat-get-options-main { src } {
foreach op $tmp {
set cmd [lindex $op 0]
if { ![string compare "dg-options" $cmd] \
+ || [string match "dg-skip-if" $cmd] \
|| [string match "dg-require-*" $cmd] } {
set status [catch "$op" errmsg]
if { $status != 0 } {
@@ -277,7 +280,7 @@ proc compat-execute { src1 sid use_alt } {
# On the SPU, most of the compat test cases exceed local store size.
# Use automatic overlay support to make them fit.
- if { [istarget spu-*-elf*] } {
+ if { [check_effective_target_spu_auto_overlay] } {
set extra_flags_1 "$extra_flags_1 -Wl,--auto-overlay"
set extra_flags_1 "$extra_flags_1 -ffunction-sections"
set extra_flags_2 "$extra_flags_2 -ffunction-sections"
diff --git a/gcc/testsuite/lib/g++.exp b/gcc/testsuite/lib/g++.exp
index c188824b841..7ca5b739781 100644
--- a/gcc/testsuite/lib/g++.exp
+++ b/gcc/testsuite/lib/g++.exp
@@ -273,7 +273,6 @@ proc g++_target_compile { source dest type options } {
}
lappend options "additional_flags=[libio_include_flags]"
- lappend options "additional_flags=-fno-show-column"
lappend options "compiler=$GXX_UNDER_TEST"
set options [concat $gpp_compile_options $options]
diff --git a/gcc/testsuite/lib/gcc-dg.exp b/gcc/testsuite/lib/gcc-dg.exp
index 9a3f12b5131..8d308d42461 100644
--- a/gcc/testsuite/lib/gcc-dg.exp
+++ b/gcc/testsuite/lib/gcc-dg.exp
@@ -354,6 +354,11 @@ proc remove-build-file { pat } {
set file_list "[glob -nocomplain $pat]"
verbose "remove-build-file `$file_list'" 2
foreach output_file $file_list {
+ if [is_remote host] {
+ # Ensure the host knows the file is gone by deleting there
+ # first.
+ remote_file host delete $output_file
+ }
remote_file build delete $output_file
}
}
diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp
index 9c12dddaeed..5f426669265 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -1249,6 +1249,17 @@ proc check_effective_target_arm_neon_ok { } {
}
}
+# Return 1 is this is an ARM target where -mthumb causes Thumb-1 to be
+# used.
+
+proc check_effective_target_arm_thumb1_ok { } {
+ return [check_no_compiler_messages arm_thumb1_ok assembly {
+ #if !defined(__arm__) || !defined(__thumb__) || defined(__thumb2__)
+ #error FOO
+ #endif
+ } "-mthumb"]
+}
+
# Return 1 if the target supports executing NEON instructions, 0
# otherwise. Cache the result.
@@ -1390,6 +1401,19 @@ proc check_effective_target_powerpc_altivec { } {
}
}
+# Return 1 if this is a SPU target with a toolchain that
+# supports automatic overlay generation.
+
+proc check_effective_target_spu_auto_overlay { } {
+ if { [istarget spu*-*-elf*] } {
+ return [check_no_compiler_messages spu_auto_overlay executable {
+ int main (void) { }
+ } "-Wl,--auto-overlay" ]
+ } else {
+ return 0
+ }
+}
+
# The VxWorks SPARC simulator accepts only EM_SPARC executables and
# chokes on EM_SPARC32PLUS or EM_SPARCV9 executables. Return 1 if the
# test environment appears to run executables on such a simulator.
diff --git a/gcc/testsuite/objc.dg/gnu-encoding/gnu-encoding.exp b/gcc/testsuite/objc.dg/gnu-encoding/gnu-encoding.exp
index dc4d9245a32..75d1dcf6316 100644
--- a/gcc/testsuite/objc.dg/gnu-encoding/gnu-encoding.exp
+++ b/gcc/testsuite/objc.dg/gnu-encoding/gnu-encoding.exp
@@ -37,8 +37,20 @@ set generator_src "$srcdir/$subdir/struct-layout-encoding-1_generate.c"
set generator_src "$generator_src $srcdir/$subdir/generate-random.c"
set generator_src "$generator_src $srcdir/$subdir/generate-random_r.c"
set generator_cmd "-o $generator $generator_src"
+# Temporarily unset GCC_EXEC_PREFIX from environment, as that might
+# confuse the $HOSTCC.
+set orig_gcc_exec_prefix_saved 0
+if [info exists env(GCC_EXEC_PREFIX)] {
+ set orig_gcc_exec_prefix "$env(GCC_EXEC_PREFIX)"
+ set orig_gcc_exec_prefix_saved 1
+ unsetenv GCC_EXEC_PREFIX
+}
set status [remote_exec build "$HOSTCC $HOSTCFLAGS $generator_cmd"]
set status [lindex $status 0]
+if { $orig_gcc_exec_prefix_saved } {
+ set orig_gcc_exec_prefix_saved 0
+ setenv GCC_EXEC_PREFIX "$orig_gcc_exec_prefix"
+}
if { $status == 0 } then {
file delete -force $tstobjdir
file mkdir $tstobjdir
diff --git a/gcc/toplev.c b/gcc/toplev.c
index d711d10d784..25647412685 100644
--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -83,6 +83,7 @@ along with GCC; see the file COPYING3. If not see
#include "alloc-pool.h"
#include "tree-mudflap.h"
#include "tree-pass.h"
+#include "gimple.h"
#if defined (DWARF2_UNWIND_INFO) || defined (DWARF2_DEBUGGING_INFO)
#include "dwarf2out.h"
@@ -203,11 +204,6 @@ tree current_function_decl;
if none. */
const char * current_function_func_begin_label;
-/* Temporarily suppress certain warnings.
- This is set while reading code from a system header file. */
-
-int in_system_header = 0;
-
/* Nonzero means to collect statistics which might be expensive
and to print them when we are done. */
int flag_detailed_statistics = 0;
@@ -839,7 +835,7 @@ check_global_declaration_1 (tree decl)
|| TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))))
{
if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
- pedwarn ("%q+F used but never defined", decl);
+ pedwarn (0, "%q+F used but never defined", decl);
else
warning (OPT_Wunused_function, "%q+F declared %<static%> but never defined", decl);
/* This symbol is effectively an "extern" declaration now. */
@@ -1716,9 +1712,6 @@ process_options (void)
if (flag_asynchronous_unwind_tables)
flag_unwind_tables = 1;
- if (!flag_unit_at_a_time)
- flag_section_anchors = 0;
-
if (flag_value_profile_transformations)
flag_profile_values = 1;
@@ -2103,6 +2096,7 @@ dump_memory_report (bool final)
ggc_print_statistics ();
stringpool_statistics ();
dump_tree_statistics ();
+ dump_gimple_statistics ();
dump_rtx_statistics ();
dump_varray_statistics ();
dump_alloc_pool_statistics ();
diff --git a/gcc/toplev.h b/gcc/toplev.h
index 32d0f857ee9..4aaefe3816e 100644
--- a/gcc/toplev.h
+++ b/gcc/toplev.h
@@ -20,6 +20,7 @@ along with GCC; see the file COPYING3. If not see
#ifndef GCC_TOPLEV_H
#define GCC_TOPLEV_H
+#include "input.h"
/* If non-NULL, return one past-the-end of the matching SUBPART of
the WHOLE string. */
@@ -58,10 +59,14 @@ extern void internal_error (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2)
extern void warning0 (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2);
/* Pass one of the OPT_W* from options.h as the first parameter. */
extern void warning (int, const char *, ...) ATTRIBUTE_GCC_DIAG(2,3);
+extern void warning_at (location_t, int, const char *, ...)
+ ATTRIBUTE_GCC_DIAG(3,4);
extern void error (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2);
extern void fatal_error (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2)
ATTRIBUTE_NORETURN;
-extern void pedwarn (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2);
+extern void pedwarn0 (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2);
+/* Pass one of the OPT_W* from options.h as the first parameter. */
+extern void pedwarn (int, const char *, ...) ATTRIBUTE_GCC_DIAG(2,3);
extern void permerror (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2);
extern void sorry (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2);
extern void inform (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2);
@@ -79,6 +84,7 @@ extern void announce_function (tree);
extern void error_for_asm (const_rtx, const char *, ...) ATTRIBUTE_GCC_DIAG(2,3);
extern void warning_for_asm (const_rtx, const char *, ...) ATTRIBUTE_GCC_DIAG(2,3);
extern void warn_deprecated_use (tree);
+extern bool parse_optimize_options (tree, bool);
#ifdef BUFSIZ
extern void output_quoted_string (FILE *, const char *);
@@ -161,6 +167,7 @@ extern void decode_d_option (const char *);
/* Return true iff flags are set as if -ffast-math. */
extern bool fast_math_flags_set_p (void);
+extern bool fast_math_flags_struct_set_p (struct cl_optimization *);
/* Return log2, or -1 if not exact. */
extern int exact_log2 (unsigned HOST_WIDE_INT);
diff --git a/gcc/tracer.c b/gcc/tracer.c
index 98f66cea949..fab2f49fa9f 100644
--- a/gcc/tracer.c
+++ b/gcc/tracer.c
@@ -102,13 +102,13 @@ ignore_bb_p (const_basic_block bb)
static int
count_insns (basic_block bb)
{
- block_stmt_iterator bsi;
- tree stmt;
+ gimple_stmt_iterator gsi;
+ gimple stmt;
int n = 0;
- for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
- stmt = bsi_stmt (bsi);
+ stmt = gsi_stmt (gsi);
n += estimate_num_insns (stmt, &eni_size_weights);
}
return n;
diff --git a/gcc/tree-affine.c b/gcc/tree-affine.c
index 59ac3d786b4..0d329d06efd 100644
--- a/gcc/tree-affine.c
+++ b/gcc/tree-affine.c
@@ -30,7 +30,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-dump.h"
#include "pointer-set.h"
#include "tree-affine.h"
-#include "tree-gimple.h"
+#include "gimple.h"
#include "flags.h"
/* Extends CST as appropriate for the affine combinations COMB. */
@@ -567,11 +567,13 @@ struct name_expansion
results. */
void
-aff_combination_expand (aff_tree *comb, struct pointer_map_t **cache)
+aff_combination_expand (aff_tree *comb ATTRIBUTE_UNUSED,
+ struct pointer_map_t **cache ATTRIBUTE_UNUSED)
{
unsigned i;
aff_tree to_add, current, curre;
- tree e, def, rhs;
+ tree e, rhs;
+ gimple def;
double_int scale;
void **slot;
struct name_expansion *exp;
@@ -580,6 +582,8 @@ aff_combination_expand (aff_tree *comb, struct pointer_map_t **cache)
for (i = 0; i < comb->n; i++)
{
tree type, name;
+ enum tree_code code;
+
e = comb->elts[i].val;
type = TREE_TYPE (e);
name = e;
@@ -591,19 +595,19 @@ aff_combination_expand (aff_tree *comb, struct pointer_map_t **cache)
if (TREE_CODE (name) != SSA_NAME)
continue;
def = SSA_NAME_DEF_STMT (name);
- if (TREE_CODE (def) != GIMPLE_MODIFY_STMT
- || GIMPLE_STMT_OPERAND (def, 0) != name)
+ if (!is_gimple_assign (def) || gimple_assign_lhs (def) != name)
continue;
- rhs = GIMPLE_STMT_OPERAND (def, 1);
- if (TREE_CODE (rhs) != SSA_NAME
- && !EXPR_P (rhs)
- && !is_gimple_min_invariant (rhs))
+ code = gimple_assign_rhs_code (def);
+ if (code != SSA_NAME
+ && !IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (code))
+ && (get_gimple_rhs_class (code) != GIMPLE_SINGLE_RHS
+ || !is_gimple_min_invariant (gimple_assign_rhs1 (def))))
continue;
/* We do not know whether the reference retains its value at the
place where the expansion is used. */
- if (REFERENCE_CLASS_P (rhs))
+ if (TREE_CODE_CLASS (code) == tcc_reference)
continue;
if (!*cache)
@@ -616,29 +620,27 @@ aff_combination_expand (aff_tree *comb, struct pointer_map_t **cache)
exp = XNEW (struct name_expansion);
exp->in_progress = 1;
*slot = exp;
- if (e != name)
+ /* In principle this is a generally valid folding, but
+ it is not unconditionally an optimization, so do it
+ here and not in fold_unary. */
+ /* Convert (T1)(X *+- CST) into (T1)X *+- (T1)CST if T1 is wider
+ than the type of X and overflow for the type of X is
+ undefined. */
+ if (e != name
+ && INTEGRAL_TYPE_P (type)
+ && INTEGRAL_TYPE_P (TREE_TYPE (name))
+ && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (name))
+ && TYPE_PRECISION (type) > TYPE_PRECISION (TREE_TYPE (name))
+ && (code == PLUS_EXPR || code == MINUS_EXPR || code == MULT_EXPR)
+ && TREE_CODE (gimple_assign_rhs2 (def)) == INTEGER_CST)
+ rhs = fold_build2 (code, type,
+ fold_convert (type, gimple_assign_rhs1 (def)),
+ fold_convert (type, gimple_assign_rhs2 (def)));
+ else
{
- /* In principle this is a generally valid folding, but
- it is not unconditionally an optimization, so do it
- here and not in fold_unary. */
- /* Convert (T1)(X *+- CST) into (T1)X *+- (T1)CST if T1 is wider
- than the type of X and overflow for the type of X is
- undefined. */
- if (INTEGRAL_TYPE_P (type)
- && INTEGRAL_TYPE_P (TREE_TYPE (rhs))
- && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (rhs))
- && TYPE_PRECISION (type) > TYPE_PRECISION (TREE_TYPE (rhs))
- && (TREE_CODE (rhs) == PLUS_EXPR
- || TREE_CODE (rhs) == MINUS_EXPR
- || TREE_CODE (rhs) == MULT_EXPR)
- && TREE_CODE (TREE_OPERAND (rhs, 1)) == INTEGER_CST)
- {
- rhs = fold_build2 (TREE_CODE (rhs), type,
- fold_convert (type, TREE_OPERAND (rhs, 0)),
- fold_convert (type, TREE_OPERAND (rhs, 1)));
- }
- else
- rhs = fold_convert (type, rhs);
+ rhs = gimple_assign_rhs_to_tree (def);
+ if (e != name)
+ rhs = fold_convert (type, rhs);
}
tree_to_aff_combination_expand (rhs, comb->type, &current, cache);
exp->expansion = current;
diff --git a/gcc/tree-call-cdce.c b/gcc/tree-call-cdce.c
index 4be0cf9bd89..ce9572ca142 100644
--- a/gcc/tree-call-cdce.c
+++ b/gcc/tree-call-cdce.c
@@ -35,7 +35,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree.h"
#include "diagnostic.h"
#include "tree-flow.h"
-#include "tree-gimple.h"
+#include "gimple.h"
#include "tree-dump.h"
#include "tree-pass.h"
#include "timevar.h"
@@ -99,7 +99,7 @@ typedef struct input_domain
bool is_ub_inclusive;
} inp_domain;
-static VEC (tree, heap) *cond_dead_built_in_calls;
+static VEC (gimple, heap) *cond_dead_built_in_calls;
/* A helper function to construct and return an input
domain object. LB is the lower bound, HAS_LB is
@@ -142,8 +142,10 @@ check_target_format (tree arg)
type = TREE_TYPE (arg);
mode = TYPE_MODE (type);
rfmt = REAL_MODE_FORMAT (mode);
- if ((mode == SFmode && rfmt == &ieee_single_format)
- || (mode == DFmode && rfmt == &ieee_double_format)
+ if ((mode == SFmode
+ && (rfmt == &ieee_single_format || rfmt == &mips_single_format))
+ || (mode == DFmode
+ && (rfmt == &ieee_double_format || rfmt == &mips_double_format))
/* For long double, we can not really check XFmode
which is only defined on intel platforms.
Candidate pre-selection using builtin function
@@ -151,6 +153,7 @@ check_target_format (tree arg)
for long double modes: double, quad, and extended. */
|| (mode != SFmode && mode != DFmode
&& (rfmt == &ieee_quad_format
+ || rfmt == &mips_quad_format
|| rfmt == &ieee_extended_intel_96_format
|| rfmt == &ieee_extended_intel_128_format
|| rfmt == &ieee_extended_intel_96_round_53_format)))
@@ -171,16 +174,16 @@ check_target_format (tree arg)
#define MAX_BASE_INT_BIT_SIZE 32
static bool
-check_pow (tree pow_call)
+check_pow (gimple pow_call)
{
tree base, expn;
enum tree_code bc, ec;
- if (call_expr_nargs (pow_call) != 2)
+ if (gimple_call_num_args (pow_call) != 2)
return false;
- base = CALL_EXPR_ARG (pow_call, 0);
- expn = CALL_EXPR_ARG (pow_call, 1);
+ base = gimple_call_arg (pow_call, 0);
+ expn = gimple_call_arg (pow_call, 1);
if (!check_target_format (expn))
return false;
@@ -209,20 +212,19 @@ check_pow (tree pow_call)
}
else if (bc == SSA_NAME)
{
- tree base_def, base_val, base_val0, base_var, type;
+ tree base_val0, base_var, type;
+ gimple base_def;
int bit_sz;
/* Only handles cases where base value is converted
from integer values. */
base_def = SSA_NAME_DEF_STMT (base);
- if (TREE_CODE (base_def) != GIMPLE_MODIFY_STMT)
+ if (gimple_code (base_def) != GIMPLE_ASSIGN)
return false;
- base_val = GIMPLE_STMT_OPERAND (base_def, 1);
-
- if (TREE_CODE (base_val) != FLOAT_EXPR)
+ if (gimple_assign_rhs_code (base_def) != FLOAT_EXPR)
return false;
- base_val0 = TREE_OPERAND (base_val, 0);
+ base_val0 = gimple_assign_rhs1 (base_def);
base_var = SSA_NAME_VAR (base_val0);
if (!DECL_P (base_var))
@@ -250,11 +252,11 @@ check_pow (tree pow_call)
Returns true if the function call is a candidate. */
static bool
-check_builtin_call (tree bcall)
+check_builtin_call (gimple bcall)
{
tree arg;
- arg = CALL_EXPR_ARG (bcall, 0);
+ arg = gimple_call_arg (bcall, 0);
return check_target_format (arg);
}
@@ -263,18 +265,18 @@ check_builtin_call (tree bcall)
is a candidate. */
static bool
-is_call_dce_candidate (tree call)
+is_call_dce_candidate (gimple call)
{
tree fn;
enum built_in_function fnc;
- if (!flag_tree_builtin_call_dce)
+ /* Only potentially dead calls are considered. */
+ if (gimple_call_lhs (call))
return false;
- gcc_assert (call && TREE_CODE (call) == CALL_EXPR);
-
- fn = get_callee_fndecl (call);
- if (!fn || !DECL_BUILT_IN (fn)
+ fn = gimple_call_fndecl (call);
+ if (!fn
+ || !DECL_BUILT_IN (fn)
|| (DECL_BUILT_IN_CLASS (fn) != BUILT_IN_NORMAL))
return false;
@@ -328,38 +330,35 @@ static void
gen_one_condition (tree arg, int lbub,
enum tree_code tcode,
const char *temp_name1,
- const char *temp_name2,
- VEC (tree, heap) *conds,
+ const char *temp_name2,
+ VEC (gimple, heap) *conds,
unsigned *nconds)
{
tree lbub_real_cst, lbub_cst, float_type;
tree temp, tempn, tempc, tempcn;
- tree stmt1, stmt2, stmt3;
+ gimple stmt1, stmt2, stmt3;
float_type = TREE_TYPE (arg);
lbub_cst = build_int_cst (integer_type_node, lbub);
lbub_real_cst = build_real_from_int_cst (float_type, lbub_cst);
temp = create_tmp_var (float_type, temp_name1);
- stmt1 = build_gimple_modify_stmt (temp, arg);
+ stmt1 = gimple_build_assign (temp, arg);
tempn = make_ssa_name (temp, stmt1);
- GIMPLE_STMT_OPERAND (stmt1, 0) = tempn;
+ gimple_assign_set_lhs (stmt1, tempn);
tempc = create_tmp_var (boolean_type_node, temp_name2);
- stmt2 = build_gimple_modify_stmt (tempc,
- fold_build2 (tcode,
- boolean_type_node,
- tempn, lbub_real_cst));
+ stmt2 = gimple_build_assign (tempc,
+ fold_build2 (tcode,
+ boolean_type_node,
+ tempn, lbub_real_cst));
tempcn = make_ssa_name (tempc, stmt2);
- GIMPLE_STMT_OPERAND (stmt2, 0) = tempcn;
-
- /* fold_built3 not used for gimple statement here,
- as it will hit assertion. */
- stmt3 = build3 (COND_EXPR, void_type_node,
- tempcn, NULL_TREE, NULL_TREE);
- VEC_quick_push (tree, conds, stmt1);
- VEC_quick_push (tree, conds, stmt2);
- VEC_quick_push (tree, conds, stmt3);
+ gimple_assign_set_lhs (stmt2, tempcn);
+
+ stmt3 = gimple_build_cond_from_tree (tempcn, NULL_TREE, NULL_TREE);
+ VEC_quick_push (gimple, conds, stmt1);
+ VEC_quick_push (gimple, conds, stmt2);
+ VEC_quick_push (gimple, conds, stmt3);
(*nconds)++;
}
@@ -374,7 +373,7 @@ gen_one_condition (tree arg, int lbub,
static void
gen_conditions_for_domain (tree arg, inp_domain domain,
- VEC (tree, heap) *conds,
+ VEC (gimple, heap) *conds,
unsigned *nconds)
{
if (domain.has_lb)
@@ -388,7 +387,7 @@ gen_conditions_for_domain (tree arg, inp_domain domain,
{
/* Now push a separator. */
if (domain.has_lb)
- VEC_quick_push (tree, conds, NULL);
+ VEC_quick_push (gimple, conds, NULL);
gen_one_condition (arg, domain.ub,
(domain.is_ub_inclusive
@@ -417,7 +416,7 @@ gen_conditions_for_domain (tree arg, inp_domain domain,
static void
gen_conditions_for_pow_cst_base (tree base, tree expn,
- VEC (tree, heap) *conds,
+ VEC (gimple, heap) *conds,
unsigned *nconds)
{
inp_domain exp_domain;
@@ -453,20 +452,21 @@ gen_conditions_for_pow_cst_base (tree base, tree expn,
static void
gen_conditions_for_pow_int_base (tree base, tree expn,
- VEC (tree, heap) *conds,
+ VEC (gimple, heap) *conds,
unsigned *nconds)
{
- tree base_def, base_nm, base_val, base_val0;
+ gimple base_def;
+ tree base_nm, base_val0;
tree base_var, int_type;
tree temp, tempn;
- tree cst0, stmt1, stmt2;
+ tree cst0;
+ gimple stmt1, stmt2;
int bit_sz, max_exp;
inp_domain exp_domain;
base_def = SSA_NAME_DEF_STMT (base);
- base_nm = GIMPLE_STMT_OPERAND (base_def, 0);
- base_val = GIMPLE_STMT_OPERAND (base_def, 1);
- base_val0 = TREE_OPERAND (base_val, 0);
+ base_nm = gimple_assign_lhs (base_def);
+ base_val0 = gimple_assign_rhs1 (base_def);
base_var = SSA_NAME_VAR (base_val0);
int_type = TREE_TYPE (base_var);
bit_sz = TYPE_PRECISION (int_type);
@@ -511,19 +511,17 @@ gen_conditions_for_pow_int_base (tree base, tree expn,
type is integer. */
/* Push a separator. */
- VEC_quick_push (tree, conds, NULL);
+ VEC_quick_push (gimple, conds, NULL);
temp = create_tmp_var (int_type, "DCE_COND1");
cst0 = build_int_cst (int_type, 0);
- stmt1 = build_gimple_modify_stmt (temp, base_val0);
+ stmt1 = gimple_build_assign (temp, base_val0);
tempn = make_ssa_name (temp, stmt1);
- GIMPLE_STMT_OPERAND (stmt1, 0) = tempn;
- stmt2 = build3 (COND_EXPR, void_type_node,
- fold_build2 (LE_EXPR, boolean_type_node, tempn, cst0),
- NULL_TREE, NULL_TREE);
+ gimple_assign_set_lhs (stmt1, tempn);
+ stmt2 = gimple_build_cond (LE_EXPR, tempn, cst0, NULL_TREE, NULL_TREE);
- VEC_quick_push (tree, conds, stmt1);
- VEC_quick_push (tree, conds, stmt2);
+ VEC_quick_push (gimple, conds, stmt1);
+ VEC_quick_push (gimple, conds, stmt2);
(*nconds)++;
}
@@ -545,7 +543,7 @@ gen_conditions_for_pow_int_base (tree base, tree expn,
and *NCONDS is the number of logical conditions. */
static void
-gen_conditions_for_pow (tree pow_call, VEC (tree, heap) *conds,
+gen_conditions_for_pow (gimple pow_call, VEC (gimple, heap) *conds,
unsigned *nconds)
{
tree base, expn;
@@ -557,18 +555,16 @@ gen_conditions_for_pow (tree pow_call, VEC (tree, heap) *conds,
*nconds = 0;
- base = CALL_EXPR_ARG (pow_call, 0);
- expn = CALL_EXPR_ARG (pow_call, 1);
+ base = gimple_call_arg (pow_call, 0);
+ expn = gimple_call_arg (pow_call, 1);
bc = TREE_CODE (base);
ec = TREE_CODE (expn);
if (bc == REAL_CST)
- gen_conditions_for_pow_cst_base (base, expn,
- conds, nconds);
+ gen_conditions_for_pow_cst_base (base, expn, conds, nconds);
else if (bc == SSA_NAME)
- gen_conditions_for_pow_int_base (base, expn,
- conds, nconds);
+ gen_conditions_for_pow_int_base (base, expn, conds, nconds);
else
gcc_unreachable ();
}
@@ -686,22 +682,19 @@ get_no_error_domain (enum built_in_function fnc)
condition are separated by NULL tree in the vector. */
static void
-gen_shrink_wrap_conditions (tree bi_call, VEC (tree, heap) *conds,
+gen_shrink_wrap_conditions (gimple bi_call, VEC (gimple, heap) *conds,
unsigned int *nconds)
{
- tree call, fn;
+ gimple call;
+ tree fn;
enum built_in_function fnc;
gcc_assert (nconds && conds);
- gcc_assert (VEC_length (tree, conds) == 0);
- gcc_assert (TREE_CODE (bi_call) == GIMPLE_MODIFY_STMT
- || TREE_CODE (bi_call) == CALL_EXPR);
+ gcc_assert (VEC_length (gimple, conds) == 0);
+ gcc_assert (is_gimple_call (bi_call));
call = bi_call;
- if (TREE_CODE (call) == GIMPLE_MODIFY_STMT)
- call = get_call_expr_in (bi_call);
-
- fn = get_callee_fndecl (call);
+ fn = gimple_call_fndecl (call);
gcc_assert (fn && DECL_BUILT_IN (fn));
fnc = DECL_FUNCTION_CODE (fn);
*nconds = 0;
@@ -713,7 +706,7 @@ gen_shrink_wrap_conditions (tree bi_call, VEC (tree, heap) *conds,
tree arg;
inp_domain domain = get_no_error_domain (fnc);
*nconds = 0;
- arg = CALL_EXPR_ARG (bi_call, 0);
+ arg = gimple_call_arg (bi_call, 0);
gen_conditions_for_domain (arg, domain, conds, nconds);
}
@@ -730,21 +723,21 @@ gen_shrink_wrap_conditions (tree bi_call, VEC (tree, heap) *conds,
transformation actually happens. */
static bool
-shrink_wrap_one_built_in_call (tree bi_call)
+shrink_wrap_one_built_in_call (gimple bi_call)
{
- block_stmt_iterator bi_call_bsi;
+ gimple_stmt_iterator bi_call_bsi;
basic_block bi_call_bb, join_tgt_bb, guard_bb, guard_bb0;
edge join_tgt_in_edge_from_call, join_tgt_in_edge_fall_thru;
edge bi_call_in_edge0, guard_bb_in_edge;
- VEC (tree, heap) *conds;
+ VEC (gimple, heap) *conds;
unsigned tn_cond_stmts, nconds;
unsigned ci;
- tree cond_expr = NULL;
- tree cond_expr_start;
+ gimple cond_expr = NULL;
+ gimple cond_expr_start;
tree bi_call_label_decl;
- tree bi_call_label;
+ gimple bi_call_label;
- conds = VEC_alloc (tree, heap, 12);
+ conds = VEC_alloc (gimple, heap, 12);
gen_shrink_wrap_conditions (bi_call, conds, &nconds);
/* This can happen if the condition generator decides
@@ -754,40 +747,40 @@ shrink_wrap_one_built_in_call (tree bi_call)
if (nconds == 0)
return false;
- bi_call_bb = bb_for_stmt (bi_call);
+ bi_call_bb = gimple_bb (bi_call);
/* Now find the join target bb -- split
bi_call_bb if needed. */
- bi_call_bsi = bsi_for_stmt (bi_call);
+ bi_call_bsi = gsi_for_stmt (bi_call);
join_tgt_in_edge_from_call = split_block (bi_call_bb, bi_call);
- bi_call_bsi = bsi_for_stmt (bi_call);
+ bi_call_bsi = gsi_for_stmt (bi_call);
join_tgt_bb = join_tgt_in_edge_from_call->dest;
/* Now it is time to insert the first conditional expression
into bi_call_bb and split this bb so that bi_call is
shrink-wrapped. */
- tn_cond_stmts = VEC_length (tree, conds);
+ tn_cond_stmts = VEC_length (gimple, conds);
cond_expr = NULL;
- cond_expr_start = VEC_index (tree, conds, 0);
+ cond_expr_start = VEC_index (gimple, conds, 0);
for (ci = 0; ci < tn_cond_stmts; ci++)
{
- tree c = VEC_index (tree, conds, ci);
+ gimple c = VEC_index (gimple, conds, ci);
gcc_assert (c || ci != 0);
if (!c)
break;
- bsi_insert_before (&bi_call_bsi, c, BSI_SAME_STMT);
+ gsi_insert_before (&bi_call_bsi, c, GSI_SAME_STMT);
cond_expr = c;
}
nconds--;
ci++;
- gcc_assert (cond_expr && TREE_CODE (cond_expr) == COND_EXPR);
+ gcc_assert (cond_expr && gimple_code (cond_expr) == GIMPLE_COND);
/* Now the label. */
bi_call_label_decl = create_artificial_label ();
- bi_call_label = build1 (LABEL_EXPR, void_type_node, bi_call_label_decl);
- bsi_insert_before (&bi_call_bsi, bi_call_label, BSI_SAME_STMT);
+ bi_call_label = gimple_build_label (bi_call_label_decl);
+ gsi_insert_before (&bi_call_bsi, bi_call_label, GSI_SAME_STMT);
bi_call_in_edge0 = split_block (bi_call_bb, cond_expr);
bi_call_in_edge0->flags &= ~EDGE_FALLTHRU;
@@ -807,21 +800,21 @@ shrink_wrap_one_built_in_call (tree bi_call)
{
unsigned ci0;
edge bi_call_in_edge;
- block_stmt_iterator guard_bsi = bsi_for_stmt (cond_expr_start);
+ gimple_stmt_iterator guard_bsi = gsi_for_stmt (cond_expr_start);
ci0 = ci;
- cond_expr_start = VEC_index (tree, conds, ci0);
+ cond_expr_start = VEC_index (gimple, conds, ci0);
for (; ci < tn_cond_stmts; ci++)
{
- tree c = VEC_index (tree, conds, ci);
+ gimple c = VEC_index (gimple, conds, ci);
gcc_assert (c || ci != ci0);
if (!c)
break;
- bsi_insert_before (&guard_bsi, c, BSI_SAME_STMT);
+ gsi_insert_before (&guard_bsi, c, GSI_SAME_STMT);
cond_expr = c;
}
nconds--;
ci++;
- gcc_assert (cond_expr && TREE_CODE (cond_expr) == COND_EXPR);
+ gcc_assert (cond_expr && gimple_code (cond_expr) == GIMPLE_COND);
guard_bb_in_edge = split_block (guard_bb, cond_expr);
guard_bb_in_edge->flags &= ~EDGE_FALLTHRU;
guard_bb_in_edge->flags |= EDGE_FALSE_VALUE;
@@ -833,11 +826,11 @@ shrink_wrap_one_built_in_call (tree bi_call)
REG_BR_PROB_BASE - bi_call_in_edge->probability;
}
- VEC_free (tree, heap, conds);
+ VEC_free (gimple, heap, conds);
if (dump_file && (dump_flags & TDF_DETAILS))
{
location_t loc;
- loc = EXPR_LOCATION (bi_call);
+ loc = gimple_location (bi_call);
fprintf (dump_file,
"%s:%d: note: function call is shrink-wrapped"
" into error conditions.\n",
@@ -856,13 +849,13 @@ shrink_wrap_conditional_dead_built_in_calls (void)
bool changed = false;
unsigned i = 0;
- unsigned n = VEC_length (tree, cond_dead_built_in_calls);
+ unsigned n = VEC_length (gimple, cond_dead_built_in_calls);
if (n == 0)
return false;
for (; i < n ; i++)
{
- tree bi_call = VEC_index (tree, cond_dead_built_in_calls, i);
+ gimple bi_call = VEC_index (gimple, cond_dead_built_in_calls, i);
changed |= shrink_wrap_one_built_in_call (bi_call);
}
@@ -875,34 +868,33 @@ static unsigned int
tree_call_cdce (void)
{
basic_block bb;
- block_stmt_iterator i;
+ gimple_stmt_iterator i;
bool something_changed = false;
- cond_dead_built_in_calls = VEC_alloc (tree, heap, 64);
+ cond_dead_built_in_calls = VEC_alloc (gimple, heap, 64);
FOR_EACH_BB (bb)
{
/* Collect dead call candidates. */
- for (i = bsi_start (bb); ! bsi_end_p (i); bsi_next (&i))
+ for (i = gsi_start_bb (bb); !gsi_end_p (i); gsi_next (&i))
{
- tree stmt = bsi_stmt (i);
- if (TREE_CODE (stmt) == CALL_EXPR
+ gimple stmt = gsi_stmt (i);
+ if (is_gimple_call (stmt)
&& is_call_dce_candidate (stmt))
{
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "Found conditional dead call: ");
- print_generic_stmt (dump_file, stmt, TDF_SLIM);
+ print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
fprintf (dump_file, "\n");
}
- VEC_quick_push (tree, cond_dead_built_in_calls, stmt);
+ VEC_quick_push (gimple, cond_dead_built_in_calls, stmt);
}
}
}
- something_changed =
- shrink_wrap_conditional_dead_built_in_calls ();
+ something_changed = shrink_wrap_conditional_dead_built_in_calls ();
- VEC_free (tree, heap, cond_dead_built_in_calls);
+ VEC_free (gimple, heap, cond_dead_built_in_calls);
if (something_changed)
{
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index 341a1de749d..00979bd82ab 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -59,7 +59,7 @@ static const int initial_cfg_capacity = 20;
/* This hash table allows us to efficiently lookup all CASE_LABEL_EXPRs
which use a particular edge. The CASE_LABEL_EXPRs are chained together
via their TREE_CHAIN field, which we clear after we're done with the
- hash table to prevent problems with duplication of SWITCH_EXPRs.
+ hash table to prevent problems with duplication of GIMPLE_SWITCHes.
Access to this list of CASE_LABEL_EXPRs allows us to efficiently
update the case vector in response to edge redirections.
@@ -83,35 +83,32 @@ static struct cfg_stats_d cfg_stats;
static bool found_computed_goto;
/* Basic blocks and flowgraphs. */
-static basic_block create_bb (void *, void *, basic_block);
-static void make_blocks (tree);
+static void make_blocks (gimple_seq);
static void factor_computed_gotos (void);
/* Edges. */
static void make_edges (void);
static void make_cond_expr_edges (basic_block);
-static void make_switch_expr_edges (basic_block);
+static void make_gimple_switch_edges (basic_block);
static void make_goto_expr_edges (basic_block);
-static edge tree_redirect_edge_and_branch (edge, basic_block);
-static edge tree_try_redirect_by_replacing_jump (edge, basic_block);
+static edge gimple_redirect_edge_and_branch (edge, basic_block);
+static edge gimple_try_redirect_by_replacing_jump (edge, basic_block);
static unsigned int split_critical_edges (void);
/* Various helpers. */
-static inline bool stmt_starts_bb_p (const_tree, const_tree);
-static int tree_verify_flow_info (void);
-static void tree_make_forwarder_block (edge);
-static void tree_cfg2vcg (FILE *);
-static inline void change_bb_for_stmt (tree t, basic_block bb);
-static bool computed_goto_p (const_tree);
+static inline bool stmt_starts_bb_p (gimple, gimple);
+static int gimple_verify_flow_info (void);
+static void gimple_make_forwarder_block (edge);
+static void gimple_cfg2vcg (FILE *);
/* Flowgraph optimization and cleanup. */
-static void tree_merge_blocks (basic_block, basic_block);
-static bool tree_can_merge_blocks_p (basic_block, basic_block);
+static void gimple_merge_blocks (basic_block, basic_block);
+static bool gimple_can_merge_blocks_p (basic_block, basic_block);
static void remove_bb (basic_block);
static edge find_taken_edge_computed_goto (basic_block, tree);
static edge find_taken_edge_cond_expr (basic_block, tree);
static edge find_taken_edge_switch_expr (basic_block, tree);
-static tree find_case_label_for_value (tree, tree);
+static tree find_case_label_for_value (gimple, tree);
void
init_empty_tree_cfg_for_function (struct function *fn)
@@ -155,21 +152,21 @@ init_empty_tree_cfg (void)
Create basic blocks
---------------------------------------------------------------------------*/
-/* Entry point to the CFG builder for trees. TP points to the list of
+/* Entry point to the CFG builder for trees. SEQ is the sequence of
statements to be added to the flowgraph. */
static void
-build_tree_cfg (tree *tp)
+build_gimple_cfg (gimple_seq seq)
{
- /* Register specific tree functions. */
- tree_register_cfg_hooks ();
+ /* Register specific gimple functions. */
+ gimple_register_cfg_hooks ();
memset ((void *) &cfg_stats, 0, sizeof (cfg_stats));
init_empty_tree_cfg ();
found_computed_goto = 0;
- make_blocks (*tp);
+ make_blocks (seq);
/* Computed gotos are hell to deal with, especially if there are
lots of them with a large number of destinations. So we factor
@@ -207,7 +204,7 @@ build_tree_cfg (tree *tp)
FILE *vcg_file = dump_begin (TDI_vcg, &local_dump_flags);
if (vcg_file)
{
- tree_cfg2vcg (vcg_file);
+ gimple_cfg2vcg (vcg_file);
dump_end (TDI_vcg, vcg_file);
}
}
@@ -218,13 +215,13 @@ build_tree_cfg (tree *tp)
/* Dump a textual representation of the flowgraph. */
if (dump_file)
- dump_tree_cfg (dump_file, dump_flags);
+ gimple_dump_cfg (dump_file, dump_flags);
}
static unsigned int
execute_build_cfg (void)
{
- build_tree_cfg (&DECL_SAVED_TREE (current_function_decl));
+ build_gimple_cfg (gimple_body (current_function_decl));
return 0;
}
@@ -239,7 +236,7 @@ struct gimple_opt_pass pass_build_cfg =
NULL, /* next */
0, /* static_pass_number */
TV_TREE_CFG, /* tv_id */
- PROP_gimple_leh, /* properties_required */
+ PROP_gimple_leh, /* properties_required */
PROP_cfg, /* properties_provided */
0, /* properties_destroyed */
0, /* todo_flags_start */
@@ -247,6 +244,17 @@ struct gimple_opt_pass pass_build_cfg =
}
};
+
+/* Return true if T is a computed goto. */
+
+static bool
+computed_goto_p (gimple t)
+{
+ return (gimple_code (t) == GIMPLE_GOTO
+ && TREE_CODE (gimple_goto_dest (t)) != LABEL_DECL);
+}
+
+
/* Search the CFG for any computed gotos. If found, factor them to a
common computed goto site. Also record the location of that site so
that we can un-factor the gotos after we have converted back to
@@ -258,8 +266,8 @@ factor_computed_gotos (void)
basic_block bb;
tree factored_label_decl = NULL;
tree var = NULL;
- tree factored_computed_goto_label = NULL;
- tree factored_computed_goto = NULL;
+ gimple factored_computed_goto_label = NULL;
+ gimple factored_computed_goto = NULL;
/* We know there are one or more computed gotos in this function.
Examine the last statement in each basic block to see if the block
@@ -267,12 +275,13 @@ factor_computed_gotos (void)
FOR_EACH_BB (bb)
{
- block_stmt_iterator bsi = bsi_last (bb);
- tree last;
+ gimple_stmt_iterator gsi = gsi_last_bb (bb);
+ gimple last;
- if (bsi_end_p (bsi))
+ if (gsi_end_p (gsi))
continue;
- last = bsi_stmt (bsi);
+
+ last = gsi_stmt (gsi);
/* Ignore the computed goto we create when we factor the original
computed gotos. */
@@ -282,15 +291,15 @@ factor_computed_gotos (void)
/* If the last statement is a computed goto, factor it. */
if (computed_goto_p (last))
{
- tree assignment;
+ gimple assignment;
/* The first time we find a computed goto we need to create
the factored goto block and the variable each original
computed goto will use for their goto destination. */
- if (! factored_computed_goto)
+ if (!factored_computed_goto)
{
basic_block new_bb = create_empty_bb (bb);
- block_stmt_iterator new_bsi = bsi_start (new_bb);
+ gimple_stmt_iterator new_gsi = gsi_start_bb (new_bb);
/* Create the destination of the factored goto. Each original
computed goto will put its desired destination into this
@@ -302,60 +311,58 @@ factor_computed_gotos (void)
factored computed goto. */
factored_label_decl = create_artificial_label ();
factored_computed_goto_label
- = build1 (LABEL_EXPR, void_type_node, factored_label_decl);
- bsi_insert_after (&new_bsi, factored_computed_goto_label,
- BSI_NEW_STMT);
+ = gimple_build_label (factored_label_decl);
+ gsi_insert_after (&new_gsi, factored_computed_goto_label,
+ GSI_NEW_STMT);
/* Build our new computed goto. */
- factored_computed_goto = build1 (GOTO_EXPR, void_type_node, var);
- bsi_insert_after (&new_bsi, factored_computed_goto,
- BSI_NEW_STMT);
+ factored_computed_goto = gimple_build_goto (var);
+ gsi_insert_after (&new_gsi, factored_computed_goto, GSI_NEW_STMT);
}
/* Copy the original computed goto's destination into VAR. */
- assignment = build_gimple_modify_stmt (var,
- GOTO_DESTINATION (last));
- bsi_insert_before (&bsi, assignment, BSI_SAME_STMT);
+ assignment = gimple_build_assign (var, gimple_goto_dest (last));
+ gsi_insert_before (&gsi, assignment, GSI_SAME_STMT);
/* And re-vector the computed goto to the new destination. */
- GOTO_DESTINATION (last) = factored_label_decl;
+ gimple_goto_set_dest (last, factored_label_decl);
}
}
}
-/* Build a flowgraph for the statement_list STMT_LIST. */
+/* Build a flowgraph for the sequence of stmts SEQ. */
static void
-make_blocks (tree stmt_list)
+make_blocks (gimple_seq seq)
{
- tree_stmt_iterator i = tsi_start (stmt_list);
- tree stmt = NULL;
+ gimple_stmt_iterator i = gsi_start (seq);
+ gimple stmt = NULL;
bool start_new_block = true;
- bool first_stmt_of_list = true;
+ bool first_stmt_of_seq = true;
basic_block bb = ENTRY_BLOCK_PTR;
- while (!tsi_end_p (i))
+ while (!gsi_end_p (i))
{
- tree prev_stmt;
+ gimple prev_stmt;
prev_stmt = stmt;
- stmt = tsi_stmt (i);
+ stmt = gsi_stmt (i);
/* If the statement starts a new basic block or if we have determined
in a previous pass that we need to create a new block for STMT, do
so now. */
if (start_new_block || stmt_starts_bb_p (stmt, prev_stmt))
{
- if (!first_stmt_of_list)
- stmt_list = tsi_split_statement_list_before (&i);
- bb = create_basic_block (stmt_list, NULL, bb);
+ if (!first_stmt_of_seq)
+ seq = gsi_split_seq_before (&i);
+ bb = create_basic_block (seq, NULL, bb);
start_new_block = false;
}
/* Now add STMT to BB and create the subgraphs for special statement
codes. */
- set_bb_for_stmt (stmt, bb);
+ gimple_set_bb (stmt, bb);
if (computed_goto_p (stmt))
found_computed_goto = true;
@@ -365,8 +372,8 @@ make_blocks (tree stmt_list)
if (stmt_ends_bb_p (stmt))
start_new_block = true;
- tsi_next (&i);
- first_stmt_of_list = false;
+ gsi_next (&i);
+ first_stmt_of_seq = false;
}
}
@@ -387,8 +394,8 @@ create_bb (void *h, void *e, basic_block after)
bb->index = last_basic_block;
bb->flags = BB_NEW;
- bb->il.tree = GGC_CNEW (struct tree_bb_info);
- set_bb_stmt_list (bb, h ? (tree) h : alloc_stmt_list ());
+ bb->il.gimple = GGC_CNEW (struct gimple_bb_info);
+ set_bb_seq (bb, h ? (gimple_seq) h : gimple_seq_alloc ());
/* Add the new block to the linked list of blocks. */
link_block (bb, after);
@@ -423,25 +430,31 @@ fold_cond_expr_cond (void)
FOR_EACH_BB (bb)
{
- tree stmt = last_stmt (bb);
+ gimple stmt = last_stmt (bb);
- if (stmt
- && TREE_CODE (stmt) == COND_EXPR)
+ if (stmt && gimple_code (stmt) == GIMPLE_COND)
{
tree cond;
bool zerop, onep;
fold_defer_overflow_warnings ();
- cond = fold (COND_EXPR_COND (stmt));
- zerop = integer_zerop (cond);
- onep = integer_onep (cond);
+ cond = fold_binary (gimple_cond_code (stmt), boolean_type_node,
+ gimple_cond_lhs (stmt), gimple_cond_rhs (stmt));
+ if (cond)
+ {
+ zerop = integer_zerop (cond);
+ onep = integer_onep (cond);
+ }
+ else
+ zerop = onep = false;
+
fold_undefer_overflow_warnings (zerop || onep,
stmt,
WARN_STRICT_OVERFLOW_CONDITIONAL);
if (zerop)
- COND_EXPR_COND (stmt) = boolean_false_node;
+ gimple_cond_make_false (stmt);
else if (onep)
- COND_EXPR_COND (stmt) = boolean_true_node;
+ gimple_cond_make_true (stmt);
}
}
}
@@ -461,40 +474,40 @@ make_edges (void)
/* Traverse the basic block array placing edges. */
FOR_EACH_BB (bb)
{
- tree last = last_stmt (bb);
+ gimple last = last_stmt (bb);
bool fallthru;
if (last)
{
- enum tree_code code = TREE_CODE (last);
+ enum gimple_code code = gimple_code (last);
switch (code)
{
- case GOTO_EXPR:
+ case GIMPLE_GOTO:
make_goto_expr_edges (bb);
fallthru = false;
break;
- case RETURN_EXPR:
+ case GIMPLE_RETURN:
make_edge (bb, EXIT_BLOCK_PTR, 0);
fallthru = false;
break;
- case COND_EXPR:
+ case GIMPLE_COND:
make_cond_expr_edges (bb);
fallthru = false;
break;
- case SWITCH_EXPR:
- make_switch_expr_edges (bb);
+ case GIMPLE_SWITCH:
+ make_gimple_switch_edges (bb);
fallthru = false;
break;
- case RESX_EXPR:
+ case GIMPLE_RESX:
make_eh_edges (last);
fallthru = false;
break;
- case CALL_EXPR:
+ case GIMPLE_CALL:
/* If this function receives a nonlocal goto, then we need to
make edges from this call site to all the nonlocal goto
handlers. */
- if (tree_can_make_abnormal_goto (last))
+ if (stmt_can_make_abnormal_goto (last))
make_abnormal_goto_edges (bb, true);
/* If this statement has reachable exception handlers, then
@@ -502,83 +515,78 @@ make_edges (void)
make_eh_edges (last);
/* Some calls are known not to return. */
- fallthru = !(call_expr_flags (last) & ECF_NORETURN);
+ fallthru = !(gimple_call_flags (last) & ECF_NORETURN);
break;
- case MODIFY_EXPR:
- gcc_unreachable ();
-
- case GIMPLE_MODIFY_STMT:
+ case GIMPLE_ASSIGN:
+ /* A GIMPLE_ASSIGN may throw internally and thus be considered
+ control-altering. */
if (is_ctrl_altering_stmt (last))
{
- /* A GIMPLE_MODIFY_STMT may have a CALL_EXPR on its RHS and
- the CALL_EXPR may have an abnormal edge. Search the RHS
- for this case and create any required edges. */
- if (tree_can_make_abnormal_goto (last))
- make_abnormal_goto_edges (bb, true);
-
make_eh_edges (last);
}
fallthru = true;
break;
- case OMP_PARALLEL:
- case OMP_TASK:
- case OMP_FOR:
- case OMP_SINGLE:
- case OMP_MASTER:
- case OMP_ORDERED:
- case OMP_CRITICAL:
- case OMP_SECTION:
+ case GIMPLE_OMP_PARALLEL:
+ case GIMPLE_OMP_TASK:
+ case GIMPLE_OMP_FOR:
+ case GIMPLE_OMP_SINGLE:
+ case GIMPLE_OMP_MASTER:
+ case GIMPLE_OMP_ORDERED:
+ case GIMPLE_OMP_CRITICAL:
+ case GIMPLE_OMP_SECTION:
cur_region = new_omp_region (bb, code, cur_region);
fallthru = true;
break;
- case OMP_SECTIONS:
+ case GIMPLE_OMP_SECTIONS:
cur_region = new_omp_region (bb, code, cur_region);
fallthru = true;
break;
- case OMP_SECTIONS_SWITCH:
+ case GIMPLE_OMP_SECTIONS_SWITCH:
fallthru = false;
break;
- case OMP_ATOMIC_LOAD:
- case OMP_ATOMIC_STORE:
+ case GIMPLE_OMP_ATOMIC_LOAD:
+ case GIMPLE_OMP_ATOMIC_STORE:
fallthru = true;
break;
- case OMP_RETURN:
- /* In the case of an OMP_SECTION, the edge will go somewhere
- other than the next block. This will be created later. */
+ case GIMPLE_OMP_RETURN:
+ /* In the case of a GIMPLE_OMP_SECTION, the edge will go
+ somewhere other than the next block. This will be
+ created later. */
cur_region->exit = bb;
- fallthru = cur_region->type != OMP_SECTION;
+ fallthru = cur_region->type != GIMPLE_OMP_SECTION;
cur_region = cur_region->outer;
break;
- case OMP_CONTINUE:
+ case GIMPLE_OMP_CONTINUE:
cur_region->cont = bb;
switch (cur_region->type)
{
- case OMP_FOR:
- /* Mark all OMP_FOR and OMP_CONTINUE succs edges as abnormal
- to prevent splitting them. */
+ case GIMPLE_OMP_FOR:
+ /* Mark all GIMPLE_OMP_FOR and GIMPLE_OMP_CONTINUE
+ succs edges as abnormal to prevent splitting
+ them. */
single_succ_edge (cur_region->entry)->flags |= EDGE_ABNORMAL;
/* Make the loopback edge. */
make_edge (bb, single_succ (cur_region->entry),
EDGE_ABNORMAL);
- /* Create an edge from OMP_FOR to exit, which corresponds to
- the case that the body of the loop is not executed at
- all. */
+ /* Create an edge from GIMPLE_OMP_FOR to exit, which
+ corresponds to the case that the body of the loop
+ is not executed at all. */
make_edge (cur_region->entry, bb->next_bb, EDGE_ABNORMAL);
make_edge (bb, bb->next_bb, EDGE_FALLTHRU | EDGE_ABNORMAL);
fallthru = false;
break;
- case OMP_SECTIONS:
+ case GIMPLE_OMP_SECTIONS:
/* Wire up the edges into and out of the nested sections. */
{
basic_block switch_bb = single_succ (cur_region->entry);
@@ -586,13 +594,13 @@ make_edges (void)
struct omp_region *i;
for (i = cur_region->inner; i ; i = i->next)
{
- gcc_assert (i->type == OMP_SECTION);
+ gcc_assert (i->type == GIMPLE_OMP_SECTION);
make_edge (switch_bb, i->entry, 0);
make_edge (i->exit, bb, EDGE_FALLTHRU);
}
/* Make the loopback edge to the block with
- OMP_SECTIONS_SWITCH. */
+ GIMPLE_OMP_SECTIONS_SWITCH. */
make_edge (bb, switch_bb, 0);
/* Make the edge from the switch to exit. */
@@ -626,35 +634,37 @@ make_edges (void)
}
-/* Create the edges for a COND_EXPR starting at block BB.
- At this point, both clauses must contain only simple gotos. */
+/* Create the edges for a GIMPLE_COND starting at block BB. */
static void
make_cond_expr_edges (basic_block bb)
{
- tree entry = last_stmt (bb);
+ gimple entry = last_stmt (bb);
+ gimple then_stmt, else_stmt;
basic_block then_bb, else_bb;
tree then_label, else_label;
edge e;
gcc_assert (entry);
- gcc_assert (TREE_CODE (entry) == COND_EXPR);
+ gcc_assert (gimple_code (entry) == GIMPLE_COND);
/* Entry basic blocks for each component. */
- then_label = GOTO_DESTINATION (COND_EXPR_THEN (entry));
- else_label = GOTO_DESTINATION (COND_EXPR_ELSE (entry));
+ then_label = gimple_cond_true_label (entry);
+ else_label = gimple_cond_false_label (entry);
then_bb = label_to_block (then_label);
else_bb = label_to_block (else_label);
+ then_stmt = first_stmt (then_bb);
+ else_stmt = first_stmt (else_bb);
e = make_edge (bb, then_bb, EDGE_TRUE_VALUE);
- e->goto_locus = EXPR_LOCATION (COND_EXPR_THEN (entry));
+ e->goto_locus = gimple_location (then_stmt);
e = make_edge (bb, else_bb, EDGE_FALSE_VALUE);
if (e)
- e->goto_locus = EXPR_LOCATION (COND_EXPR_ELSE (entry));
+ e->goto_locus = gimple_location (else_stmt);
- /* We do not need the gotos anymore. */
- COND_EXPR_THEN (entry) = NULL_TREE;
- COND_EXPR_ELSE (entry) = NULL_TREE;
+ /* We do not need the labels anymore. */
+ gimple_cond_set_true_label (entry, NULL_TREE);
+ gimple_cond_set_false_label (entry, NULL_TREE);
}
@@ -714,11 +724,10 @@ end_recording_case_labels (void)
Otherwise return NULL. */
static tree
-get_cases_for_edge (edge e, tree t)
+get_cases_for_edge (edge e, gimple t)
{
void **slot;
size_t i, n;
- tree vec;
/* If we are not recording cases, then we do not have CASE_LABEL_EXPR
chains available. Return NULL so the caller can detect this case. */
@@ -733,11 +742,10 @@ get_cases_for_edge (edge e, tree t)
time we have been queried for information about E & T. Add all the
elements from T to the hash table then perform the query again. */
- vec = SWITCH_LABELS (t);
- n = TREE_VEC_LENGTH (vec);
+ n = gimple_switch_num_labels (t);
for (i = 0; i < n; i++)
{
- tree elt = TREE_VEC_ELT (vec, i);
+ tree elt = gimple_switch_label (t, i);
tree lab = CASE_LABEL (elt);
basic_block label_bb = label_to_block (lab);
edge this_edge = find_edge (e->src, label_bb);
@@ -752,23 +760,19 @@ get_cases_for_edge (edge e, tree t)
return (tree) *pointer_map_contains (edge_to_cases, e);
}
-/* Create the edges for a SWITCH_EXPR starting at block BB.
- At this point, the switch body has been lowered and the
- SWITCH_LABELS filled in, so this is in effect a multi-way branch. */
+/* Create the edges for a GIMPLE_SWITCH starting at block BB. */
static void
-make_switch_expr_edges (basic_block bb)
+make_gimple_switch_edges (basic_block bb)
{
- tree entry = last_stmt (bb);
+ gimple entry = last_stmt (bb);
size_t i, n;
- tree vec;
- vec = SWITCH_LABELS (entry);
- n = TREE_VEC_LENGTH (vec);
+ n = gimple_switch_num_labels (entry);
for (i = 0; i < n; ++i)
{
- tree lab = CASE_LABEL (TREE_VEC_ELT (vec, i));
+ tree lab = CASE_LABEL (gimple_switch_label (entry, i));
basic_block label_bb = label_to_block (lab);
make_edge (bb, label_bb, 0);
}
@@ -787,12 +791,11 @@ label_to_block_fn (struct function *ifun, tree dest)
and undefined variable warnings quite right. */
if ((errorcount || sorrycount) && uid < 0)
{
- block_stmt_iterator bsi =
- bsi_start (BASIC_BLOCK (NUM_FIXED_BLOCKS));
- tree stmt;
+ gimple_stmt_iterator gsi = gsi_start_bb (BASIC_BLOCK (NUM_FIXED_BLOCKS));
+ gimple stmt;
- stmt = build1 (LABEL_EXPR, void_type_node, dest);
- bsi_insert_before (&bsi, stmt, BSI_NEW_STMT);
+ stmt = gimple_build_label (dest);
+ gsi_insert_before (&gsi, stmt, GSI_NEW_STMT);
uid = LABEL_DECL_UID (dest);
}
if (VEC_length (basic_block, ifun->cfg->x_label_to_block_map)
@@ -808,17 +811,18 @@ void
make_abnormal_goto_edges (basic_block bb, bool for_call)
{
basic_block target_bb;
- block_stmt_iterator bsi;
+ gimple_stmt_iterator gsi;
FOR_EACH_BB (target_bb)
- for (bsi = bsi_start (target_bb); !bsi_end_p (bsi); bsi_next (&bsi))
+ for (gsi = gsi_start_bb (target_bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
- tree target = bsi_stmt (bsi);
+ gimple label_stmt = gsi_stmt (gsi);
+ tree target;
- if (TREE_CODE (target) != LABEL_EXPR)
+ if (gimple_code (label_stmt) != GIMPLE_LABEL)
break;
- target = LABEL_EXPR_LABEL (target);
+ target = gimple_label_label (label_stmt);
/* Make an edge to every label block that has been marked as a
potential target for a computed goto or a non-local goto. */
@@ -836,16 +840,16 @@ make_abnormal_goto_edges (basic_block bb, bool for_call)
static void
make_goto_expr_edges (basic_block bb)
{
- block_stmt_iterator last = bsi_last (bb);
- tree goto_t = bsi_stmt (last);
+ gimple_stmt_iterator last = gsi_last_bb (bb);
+ gimple goto_t = gsi_stmt (last);
/* A simple GOTO creates normal edges. */
if (simple_goto_p (goto_t))
{
- tree dest = GOTO_DESTINATION (goto_t);
+ tree dest = gimple_goto_dest (goto_t);
edge e = make_edge (bb, label_to_block (dest), EDGE_FALLTHRU);
- e->goto_locus = EXPR_LOCATION (goto_t);
- bsi_remove (&last, true);
+ e->goto_locus = gimple_location (goto_t);
+ gsi_remove (&last, true);
return;
}
@@ -898,7 +902,9 @@ update_eh_label (struct eh_region *region)
}
}
+
/* Given LABEL return the first label in the same basic block. */
+
static tree
main_block_label (tree label)
{
@@ -931,16 +937,17 @@ cleanup_dead_labels (void)
label if there is one, or otherwise just the first label we see. */
FOR_EACH_BB (bb)
{
- block_stmt_iterator i;
+ gimple_stmt_iterator i;
- for (i = bsi_start (bb); !bsi_end_p (i); bsi_next (&i))
+ for (i = gsi_start_bb (bb); !gsi_end_p (i); gsi_next (&i))
{
- tree label, stmt = bsi_stmt (i);
+ tree label;
+ gimple stmt = gsi_stmt (i);
- if (TREE_CODE (stmt) != LABEL_EXPR)
+ if (gimple_code (stmt) != GIMPLE_LABEL)
break;
- label = LABEL_EXPR_LABEL (stmt);
+ label = gimple_label_label (stmt);
/* If we have not yet seen a label for the current block,
remember this one and see if there are more labels. */
@@ -966,52 +973,45 @@ cleanup_dead_labels (void)
First do so for each block ending in a control statement. */
FOR_EACH_BB (bb)
{
- tree stmt = last_stmt (bb);
+ gimple stmt = last_stmt (bb);
if (!stmt)
continue;
- switch (TREE_CODE (stmt))
+ switch (gimple_code (stmt))
{
- case COND_EXPR:
+ case GIMPLE_COND:
{
- tree true_branch, false_branch;
-
- true_branch = COND_EXPR_THEN (stmt);
- false_branch = COND_EXPR_ELSE (stmt);
-
- if (true_branch)
- GOTO_DESTINATION (true_branch)
- = main_block_label (GOTO_DESTINATION (true_branch));
- if (false_branch)
- GOTO_DESTINATION (false_branch)
- = main_block_label (GOTO_DESTINATION (false_branch));
+ tree true_label = gimple_cond_true_label (stmt);
+ tree false_label = gimple_cond_false_label (stmt);
+ if (true_label)
+ gimple_cond_set_true_label (stmt, main_block_label (true_label));
+ if (false_label)
+ gimple_cond_set_false_label (stmt, main_block_label (false_label));
break;
}
- case SWITCH_EXPR:
+ case GIMPLE_SWITCH:
{
- size_t i;
- tree vec = SWITCH_LABELS (stmt);
- size_t n = TREE_VEC_LENGTH (vec);
+ size_t i, n = gimple_switch_num_labels (stmt);
/* Replace all destination labels. */
for (i = 0; i < n; ++i)
{
- tree elt = TREE_VEC_ELT (vec, i);
- tree label = main_block_label (CASE_LABEL (elt));
- CASE_LABEL (elt) = label;
+ tree case_label = gimple_switch_label (stmt, i);
+ tree label = main_block_label (CASE_LABEL (case_label));
+ CASE_LABEL (case_label) = label;
}
break;
}
- /* We have to handle GOTO_EXPRs until they're removed, and we don't
+ /* We have to handle gotos until they're removed, and we don't
remove them until after we've created the CFG edges. */
- case GOTO_EXPR:
- if (! computed_goto_p (stmt))
+ case GIMPLE_GOTO:
+ if (!computed_goto_p (stmt))
{
- GOTO_DESTINATION (stmt)
- = main_block_label (GOTO_DESTINATION (stmt));
+ tree new_dest = main_block_label (gimple_goto_dest (stmt));
+ gimple_goto_set_dest (stmt, new_dest);
break;
}
@@ -1027,7 +1027,7 @@ cleanup_dead_labels (void)
address taken are preserved. */
FOR_EACH_BB (bb)
{
- block_stmt_iterator i;
+ gimple_stmt_iterator i;
tree label_for_this_bb = label_for_bb[bb->index].label;
if (!label_for_this_bb)
@@ -1037,22 +1037,23 @@ cleanup_dead_labels (void)
if (!label_for_bb[bb->index].used)
label_for_this_bb = NULL;
- for (i = bsi_start (bb); !bsi_end_p (i); )
+ for (i = gsi_start_bb (bb); !gsi_end_p (i); )
{
- tree label, stmt = bsi_stmt (i);
+ tree label;
+ gimple stmt = gsi_stmt (i);
- if (TREE_CODE (stmt) != LABEL_EXPR)
+ if (gimple_code (stmt) != GIMPLE_LABEL)
break;
- label = LABEL_EXPR_LABEL (stmt);
+ label = gimple_label_label (stmt);
if (label == label_for_this_bb
- || ! DECL_ARTIFICIAL (label)
+ || !DECL_ARTIFICIAL (label)
|| DECL_NONLOCAL (label)
|| FORCED_LABEL (label))
- bsi_next (&i);
+ gsi_next (&i);
else
- bsi_remove (&i, true);
+ gsi_remove (&i, true);
}
}
@@ -1071,32 +1072,37 @@ group_case_labels (void)
FOR_EACH_BB (bb)
{
- tree stmt = last_stmt (bb);
- if (stmt && TREE_CODE (stmt) == SWITCH_EXPR)
+ gimple stmt = last_stmt (bb);
+ if (stmt && gimple_code (stmt) == GIMPLE_SWITCH)
{
- tree labels = SWITCH_LABELS (stmt);
- int old_size = TREE_VEC_LENGTH (labels);
+ int old_size = gimple_switch_num_labels (stmt);
int i, j, new_size = old_size;
tree default_case = NULL_TREE;
tree default_label = NULL_TREE;
+ bool has_default;
- /* The default label is always the last case in a switch
+ /* The default label is always the first case in a switch
statement after gimplification if it was not optimized
- away. */
- if (!CASE_LOW (TREE_VEC_ELT (labels, old_size - 1))
- && !CASE_HIGH (TREE_VEC_ELT (labels, old_size - 1)))
+ away */
+ if (!CASE_LOW (gimple_switch_default_label (stmt))
+ && !CASE_HIGH (gimple_switch_default_label (stmt)))
{
- default_case = TREE_VEC_ELT (labels, old_size - 1);
+ default_case = gimple_switch_default_label (stmt);
default_label = CASE_LABEL (default_case);
- old_size--;
+ has_default = true;
}
+ else
+ has_default = false;
/* Look for possible opportunities to merge cases. */
- i = 0;
+ if (has_default)
+ i = 1;
+ else
+ i = 0;
while (i < old_size)
{
tree base_case, base_label, base_high;
- base_case = TREE_VEC_ELT (labels, i);
+ base_case = gimple_switch_label (stmt, i);
gcc_assert (base_case);
base_label = CASE_LABEL (base_case);
@@ -1105,21 +1111,23 @@ group_case_labels (void)
default case. */
if (base_label == default_label)
{
- TREE_VEC_ELT (labels, i) = NULL_TREE;
+ gimple_switch_set_label (stmt, i, NULL_TREE);
i++;
new_size--;
continue;
}
- base_high = CASE_HIGH (base_case) ?
- CASE_HIGH (base_case) : CASE_LOW (base_case);
+ base_high = CASE_HIGH (base_case)
+ ? CASE_HIGH (base_case)
+ : CASE_LOW (base_case);
i++;
+
/* Try to merge case labels. Break out when we reach the end
of the label vector or when we cannot merge the next case
label with the current one. */
while (i < old_size)
{
- tree merge_case = TREE_VEC_ELT (labels, i);
+ tree merge_case = gimple_switch_label (stmt, i);
tree merge_label = CASE_LABEL (merge_case);
tree t = int_const_binop (PLUS_EXPR, base_high,
integer_one_node, 1);
@@ -1132,7 +1140,7 @@ group_case_labels (void)
base_high = CASE_HIGH (merge_case) ?
CASE_HIGH (merge_case) : CASE_LOW (merge_case);
CASE_HIGH (base_case) = base_high;
- TREE_VEC_ELT (labels, i) = NULL_TREE;
+ gimple_switch_set_label (stmt, i, NULL_TREE);
new_size--;
i++;
}
@@ -1145,11 +1153,14 @@ group_case_labels (void)
length of the vector. */
for (i = 0, j = 0; i < new_size; i++)
{
- while (! TREE_VEC_ELT (labels, j))
+ while (! gimple_switch_label (stmt, j))
j++;
- TREE_VEC_ELT (labels, i) = TREE_VEC_ELT (labels, j++);
+ gimple_switch_set_label (stmt, i,
+ gimple_switch_label (stmt, j++));
}
- TREE_VEC_LENGTH (labels) = new_size;
+
+ gcc_assert (new_size <= old_size);
+ gimple_switch_set_num_labels (stmt, new_size);
}
}
}
@@ -1157,11 +1168,11 @@ group_case_labels (void)
/* Checks whether we can merge block B into block A. */
static bool
-tree_can_merge_blocks_p (basic_block a, basic_block b)
+gimple_can_merge_blocks_p (basic_block a, basic_block b)
{
- const_tree stmt;
- block_stmt_iterator bsi;
- tree phi;
+ gimple stmt;
+ gimple_stmt_iterator gsi;
+ gimple_seq phis;
if (!single_succ_p (a))
return false;
@@ -1180,40 +1191,46 @@ tree_can_merge_blocks_p (basic_block a, basic_block b)
/* If A ends by a statement causing exceptions or something similar, we
cannot merge the blocks. */
- /* This CONST_CAST is okay because last_stmt doesn't modify its
- argument and the return value is assign to a const_tree. */
- stmt = last_stmt (CONST_CAST_BB (a));
+ stmt = last_stmt (a);
if (stmt && stmt_ends_bb_p (stmt))
return false;
/* Do not allow a block with only a non-local label to be merged. */
- if (stmt && TREE_CODE (stmt) == LABEL_EXPR
- && DECL_NONLOCAL (LABEL_EXPR_LABEL (stmt)))
+ if (stmt
+ && gimple_code (stmt) == GIMPLE_LABEL
+ && DECL_NONLOCAL (gimple_label_label (stmt)))
return false;
/* It must be possible to eliminate all phi nodes in B. If ssa form
is not up-to-date, we cannot eliminate any phis; however, if only
some symbols as whole are marked for renaming, this is not a problem,
as phi nodes for those symbols are irrelevant in updating anyway. */
- phi = phi_nodes (b);
- if (phi)
+ phis = phi_nodes (b);
+ if (!gimple_seq_empty_p (phis))
{
+ gimple_stmt_iterator i;
+
if (name_mappings_registered_p ())
return false;
- for (; phi; phi = PHI_CHAIN (phi))
- if (!is_gimple_reg (PHI_RESULT (phi))
- && !may_propagate_copy (PHI_RESULT (phi), PHI_ARG_DEF (phi, 0)))
- return false;
+ for (i = gsi_start (phis); !gsi_end_p (i); gsi_next (&i))
+ {
+ gimple phi = gsi_stmt (i);
+
+ if (!is_gimple_reg (gimple_phi_result (phi))
+ && !may_propagate_copy (gimple_phi_result (phi),
+ gimple_phi_arg_def (phi, 0)))
+ return false;
+ }
}
/* Do not remove user labels. */
- for (bsi = bsi_start (b); !bsi_end_p (bsi); bsi_next (&bsi))
+ for (gsi = gsi_start_bb (b); !gsi_end_p (gsi); gsi_next (&gsi))
{
- stmt = bsi_stmt (bsi);
- if (TREE_CODE (stmt) != LABEL_EXPR)
+ stmt = gsi_stmt (gsi);
+ if (gimple_code (stmt) != GIMPLE_LABEL)
break;
- if (!DECL_ARTIFICIAL (LABEL_EXPR_LABEL (stmt)))
+ if (!DECL_ARTIFICIAL (gimple_label_label (stmt)))
return false;
}
@@ -1232,21 +1249,21 @@ replace_uses_by (tree name, tree val)
{
imm_use_iterator imm_iter;
use_operand_p use;
- tree stmt;
+ gimple stmt;
edge e;
FOR_EACH_IMM_USE_STMT (stmt, imm_iter, name)
{
- if (TREE_CODE (stmt) != PHI_NODE)
+ if (gimple_code (stmt) != GIMPLE_PHI)
push_stmt_changes (&stmt);
FOR_EACH_IMM_USE_ON_STMT (use, imm_iter)
{
replace_exp (use, val);
- if (TREE_CODE (stmt) == PHI_NODE)
+ if (gimple_code (stmt) == GIMPLE_PHI)
{
- e = PHI_ARG_EDGE (stmt, PHI_ARG_INDEX_FROM_USE (use));
+ e = gimple_phi_arg_edge (stmt, PHI_ARG_INDEX_FROM_USE (use));
if (e->flags & EDGE_ABNORMAL)
{
/* This can only occur for virtual operands, since
@@ -1258,18 +1275,24 @@ replace_uses_by (tree name, tree val)
}
}
- if (TREE_CODE (stmt) != PHI_NODE)
+ if (gimple_code (stmt) != GIMPLE_PHI)
{
- tree rhs;
+ size_t i;
fold_stmt_inplace (stmt);
if (cfgcleanup_altered_bbs)
- bitmap_set_bit (cfgcleanup_altered_bbs, bb_for_stmt (stmt)->index);
+ bitmap_set_bit (cfgcleanup_altered_bbs, gimple_bb (stmt)->index);
/* FIXME. This should go in pop_stmt_changes. */
- rhs = get_rhs (stmt);
- if (TREE_CODE (rhs) == ADDR_EXPR)
- recompute_tree_invariant_for_addr_expr (rhs);
+ for (i = 0; i < gimple_num_ops (stmt); i++)
+ {
+ tree op = gimple_op (stmt, i);
+ /* Operands may be empty here. For example, the labels
+ of a GIMPLE_COND are nulled out following the creation
+ of the corresponding CFG edges. */
+ if (op && TREE_CODE (op) == ADDR_EXPR)
+ recompute_tree_invariant_for_addr_expr (op);
+ }
maybe_clean_or_replace_eh_stmt (stmt, stmt);
@@ -1295,23 +1318,24 @@ replace_uses_by (tree name, tree val)
/* Merge block B into block A. */
static void
-tree_merge_blocks (basic_block a, basic_block b)
+gimple_merge_blocks (basic_block a, basic_block b)
{
- block_stmt_iterator bsi;
- tree_stmt_iterator last;
- tree phi;
+ gimple_stmt_iterator last, gsi, psi;
+ gimple_seq phis = phi_nodes (b);
if (dump_file)
fprintf (dump_file, "Merging blocks %d and %d\n", a->index, b->index);
/* Remove all single-valued PHI nodes from block B of the form
V_i = PHI <V_j> by propagating V_j to all the uses of V_i. */
- bsi = bsi_last (a);
- for (phi = phi_nodes (b); phi; phi = phi_nodes (b))
+ gsi = gsi_last_bb (a);
+ for (psi = gsi_start (phis); !gsi_end_p (psi); )
{
- tree def = PHI_RESULT (phi), use = PHI_ARG_DEF (phi, 0);
- tree copy;
- bool may_replace_uses = may_propagate_copy (def, use);
+ gimple phi = gsi_stmt (psi);
+ tree def = gimple_phi_result (phi), use = gimple_phi_arg_def (phi, 0);
+ gimple copy;
+ bool may_replace_uses = !is_gimple_reg (def)
+ || may_propagate_copy (def, use);
/* In case we maintain loop closed ssa form, do not propagate arguments
of loop exit phi nodes. */
@@ -1330,10 +1354,9 @@ tree_merge_blocks (basic_block a, basic_block b)
with ordering of phi nodes. This is because A is the single
predecessor of B, therefore results of the phi nodes cannot
appear as arguments of the phi nodes. */
- copy = build_gimple_modify_stmt (def, use);
- bsi_insert_after (&bsi, copy, BSI_NEW_STMT);
- SSA_NAME_DEF_STMT (def) = copy;
- remove_phi_node (phi, NULL, false);
+ copy = gimple_build_assign (def, use);
+ gsi_insert_after (&gsi, copy, GSI_NEW_STMT);
+ remove_phi_node (&psi, false);
}
else
{
@@ -1344,7 +1367,7 @@ tree_merge_blocks (basic_block a, basic_block b)
{
imm_use_iterator iter;
use_operand_p use_p;
- tree stmt;
+ gimple stmt;
FOR_EACH_IMM_USE_STMT (stmt, iter, def)
FOR_EACH_IMM_USE_ON_STMT (use_p, iter)
@@ -1352,7 +1375,8 @@ tree_merge_blocks (basic_block a, basic_block b)
}
else
replace_uses_by (def, use);
- remove_phi_node (phi, NULL, true);
+
+ remove_phi_node (&psi, true);
}
}
@@ -1362,37 +1386,38 @@ tree_merge_blocks (basic_block a, basic_block b)
gcc_assert (single_succ_edge (a)->flags & EDGE_FALLTHRU);
gcc_assert (!last_stmt (a) || !stmt_ends_bb_p (last_stmt (a)));
- /* Remove labels from B and set bb_for_stmt to A for other statements. */
- for (bsi = bsi_start (b); !bsi_end_p (bsi);)
+ /* Remove labels from B and set gimple_bb to A for other statements. */
+ for (gsi = gsi_start_bb (b); !gsi_end_p (gsi);)
{
- if (TREE_CODE (bsi_stmt (bsi)) == LABEL_EXPR)
+ if (gimple_code (gsi_stmt (gsi)) == GIMPLE_LABEL)
{
- tree label = bsi_stmt (bsi);
+ gimple label = gsi_stmt (gsi);
+
+ gsi_remove (&gsi, false);
- bsi_remove (&bsi, false);
/* Now that we can thread computed gotos, we might have
a situation where we have a forced label in block B
However, the label at the start of block B might still be
used in other ways (think about the runtime checking for
Fortran assigned gotos). So we can not just delete the
label. Instead we move the label to the start of block A. */
- if (FORCED_LABEL (LABEL_EXPR_LABEL (label)))
+ if (FORCED_LABEL (gimple_label_label (label)))
{
- block_stmt_iterator dest_bsi = bsi_start (a);
- bsi_insert_before (&dest_bsi, label, BSI_NEW_STMT);
+ gimple_stmt_iterator dest_gsi = gsi_start_bb (a);
+ gsi_insert_before (&dest_gsi, label, GSI_NEW_STMT);
}
}
else
{
- change_bb_for_stmt (bsi_stmt (bsi), a);
- bsi_next (&bsi);
+ gimple_set_bb (gsi_stmt (gsi), a);
+ gsi_next (&gsi);
}
}
- /* Merge the chains. */
- last = tsi_last (bb_stmt_list (a));
- tsi_link_after (&last, bb_stmt_list (b), TSI_NEW_STMT);
- set_bb_stmt_list (b, NULL_TREE);
+ /* Merge the sequences. */
+ last = gsi_last_bb (a);
+ gsi_insert_seq_after (&last, bb_seq (b), GSI_NEW_STMT);
+ set_bb_seq (b, NULL);
if (cfgcleanup_altered_bbs)
bitmap_set_bit (cfgcleanup_altered_bbs, a->index);
@@ -1432,6 +1457,8 @@ single_noncomplex_succ (basic_block bb)
* Some unnecessary BIND_EXPRs are removed
+ * GOTO_EXPRs immediately preceding destination are removed.
+
Clearly more work could be done. The trick is doing the analysis
and removal fast enough to be a net improvement in compile times.
@@ -1441,208 +1468,172 @@ single_noncomplex_succ (basic_block bb)
struct rus_data
{
- tree *last_goto;
bool repeat;
bool may_throw;
bool may_branch;
bool has_label;
+ bool last_was_goto;
+ gimple_stmt_iterator last_goto_gsi;
};
-static void remove_useless_stmts_1 (tree *, struct rus_data *);
+
+static void remove_useless_stmts_1 (gimple_stmt_iterator *gsi, struct rus_data *);
+
+/* Given a statement sequence, find the first executable statement with
+ location information, and warn that it is unreachable. When searching,
+ descend into containers in execution order. */
static bool
-remove_useless_stmts_warn_notreached (tree stmt)
+remove_useless_stmts_warn_notreached (gimple_seq stmts)
{
- if (EXPR_HAS_LOCATION (stmt))
- {
- location_t loc = EXPR_LOCATION (stmt);
- if (LOCATION_LINE (loc) > 0)
- {
- warning (OPT_Wunreachable_code, "%Hwill never be executed", &loc);
- return true;
- }
- }
+ gimple_stmt_iterator gsi;
- switch (TREE_CODE (stmt))
+ for (gsi = gsi_start (stmts); !gsi_end_p (gsi); gsi_next (&gsi))
{
- case STATEMENT_LIST:
- {
- tree_stmt_iterator i;
- for (i = tsi_start (stmt); !tsi_end_p (i); tsi_next (&i))
- if (remove_useless_stmts_warn_notreached (tsi_stmt (i)))
- return true;
- }
- break;
+ gimple stmt = gsi_stmt (gsi);
- case COND_EXPR:
- if (remove_useless_stmts_warn_notreached (COND_EXPR_COND (stmt)))
- return true;
- if (remove_useless_stmts_warn_notreached (COND_EXPR_THEN (stmt)))
- return true;
- if (remove_useless_stmts_warn_notreached (COND_EXPR_ELSE (stmt)))
- return true;
- break;
+ if (gimple_has_location (stmt))
+ {
+ location_t loc = gimple_location (stmt);
+ if (LOCATION_LINE (loc) > 0)
+ {
+ warning (OPT_Wunreachable_code, "%Hwill never be executed", &loc);
+ return true;
+ }
+ }
- case TRY_FINALLY_EXPR:
- case TRY_CATCH_EXPR:
- if (remove_useless_stmts_warn_notreached (TREE_OPERAND (stmt, 0)))
- return true;
- if (remove_useless_stmts_warn_notreached (TREE_OPERAND (stmt, 1)))
- return true;
- break;
+ switch (gimple_code (stmt))
+ {
+ /* Unfortunately, we need the CFG now to detect unreachable
+ branches in a conditional, so conditionals are not handled here. */
- case CATCH_EXPR:
- return remove_useless_stmts_warn_notreached (CATCH_BODY (stmt));
- case EH_FILTER_EXPR:
- return remove_useless_stmts_warn_notreached (EH_FILTER_FAILURE (stmt));
- case BIND_EXPR:
- return remove_useless_stmts_warn_notreached (BIND_EXPR_BLOCK (stmt));
+ case GIMPLE_TRY:
+ if (remove_useless_stmts_warn_notreached (gimple_try_eval (stmt)))
+ return true;
+ if (remove_useless_stmts_warn_notreached (gimple_try_cleanup (stmt)))
+ return true;
+ break;
- default:
- /* Not a live container. */
- break;
+ case GIMPLE_CATCH:
+ return remove_useless_stmts_warn_notreached (gimple_catch_handler (stmt));
+
+ case GIMPLE_EH_FILTER:
+ return remove_useless_stmts_warn_notreached (gimple_eh_filter_failure (stmt));
+
+ case GIMPLE_BIND:
+ return remove_useless_stmts_warn_notreached (gimple_bind_body (stmt));
+
+ default:
+ break;
+ }
}
return false;
}
+/* Helper for remove_useless_stmts_1. Handle GIMPLE_COND statements. */
+
static void
-remove_useless_stmts_cond (tree *stmt_p, struct rus_data *data)
+remove_useless_stmts_cond (gimple_stmt_iterator *gsi, struct rus_data *data)
{
- tree then_clause, else_clause, cond;
- bool save_has_label, then_has_label, else_has_label;
-
- save_has_label = data->has_label;
- data->has_label = false;
- data->last_goto = NULL;
-
- remove_useless_stmts_1 (&COND_EXPR_THEN (*stmt_p), data);
+ gimple stmt = gsi_stmt (*gsi);
- then_has_label = data->has_label;
- data->has_label = false;
- data->last_goto = NULL;
+ /* The folded result must still be a conditional statement. */
+ fold_stmt_inplace (stmt);
- remove_useless_stmts_1 (&COND_EXPR_ELSE (*stmt_p), data);
-
- else_has_label = data->has_label;
- data->has_label = save_has_label | then_has_label | else_has_label;
-
- then_clause = COND_EXPR_THEN (*stmt_p);
- else_clause = COND_EXPR_ELSE (*stmt_p);
- cond = fold (COND_EXPR_COND (*stmt_p));
+ data->may_branch = true;
- /* If neither arm does anything at all, we can remove the whole IF. */
- if (!TREE_SIDE_EFFECTS (then_clause) && !TREE_SIDE_EFFECTS (else_clause))
+ /* Replace trivial conditionals with gotos. */
+ if (gimple_cond_true_p (stmt))
{
- *stmt_p = build_empty_stmt ();
- data->repeat = true;
- }
+ /* Goto THEN label. */
+ tree then_label = gimple_cond_true_label (stmt);
- /* If there are no reachable statements in an arm, then we can
- zap the entire conditional. */
- else if (integer_nonzerop (cond) && !else_has_label)
- {
- if (warn_notreached)
- remove_useless_stmts_warn_notreached (else_clause);
- *stmt_p = then_clause;
+ gsi_replace (gsi, gimple_build_goto (then_label), false);
+ data->last_goto_gsi = *gsi;
+ data->last_was_goto = true;
data->repeat = true;
}
- else if (integer_zerop (cond) && !then_has_label)
+ else if (gimple_cond_false_p (stmt))
{
- if (warn_notreached)
- remove_useless_stmts_warn_notreached (then_clause);
- *stmt_p = else_clause;
+ /* Goto ELSE label. */
+ tree else_label = gimple_cond_false_label (stmt);
+
+ gsi_replace (gsi, gimple_build_goto (else_label), false);
+ data->last_goto_gsi = *gsi;
+ data->last_was_goto = true;
data->repeat = true;
}
-
- /* Check a couple of simple things on then/else with single stmts. */
else
{
- tree then_stmt = expr_only (then_clause);
- tree else_stmt = expr_only (else_clause);
+ tree then_label = gimple_cond_true_label (stmt);
+ tree else_label = gimple_cond_false_label (stmt);
- /* Notice branches to a common destination. */
- if (then_stmt && else_stmt
- && TREE_CODE (then_stmt) == GOTO_EXPR
- && TREE_CODE (else_stmt) == GOTO_EXPR
- && (GOTO_DESTINATION (then_stmt) == GOTO_DESTINATION (else_stmt)))
- {
- *stmt_p = then_stmt;
+ if (then_label == else_label)
+ {
+ /* Goto common destination. */
+ gsi_replace (gsi, gimple_build_goto (then_label), false);
+ data->last_goto_gsi = *gsi;
+ data->last_was_goto = true;
data->repeat = true;
}
-
- /* If the THEN/ELSE clause merely assigns a value to a variable or
- parameter which is already known to contain that value, then
- remove the useless THEN/ELSE clause. */
- else if (TREE_CODE (cond) == VAR_DECL || TREE_CODE (cond) == PARM_DECL)
- {
- if (else_stmt
- && TREE_CODE (else_stmt) == GIMPLE_MODIFY_STMT
- && GIMPLE_STMT_OPERAND (else_stmt, 0) == cond
- && integer_zerop (GIMPLE_STMT_OPERAND (else_stmt, 1)))
- COND_EXPR_ELSE (*stmt_p) = alloc_stmt_list ();
- }
- else if ((TREE_CODE (cond) == EQ_EXPR || TREE_CODE (cond) == NE_EXPR)
- && (TREE_CODE (TREE_OPERAND (cond, 0)) == VAR_DECL
- || TREE_CODE (TREE_OPERAND (cond, 0)) == PARM_DECL)
- && TREE_CONSTANT (TREE_OPERAND (cond, 1)))
- {
- tree stmt = (TREE_CODE (cond) == EQ_EXPR
- ? then_stmt : else_stmt);
- tree *location = (TREE_CODE (cond) == EQ_EXPR
- ? &COND_EXPR_THEN (*stmt_p)
- : &COND_EXPR_ELSE (*stmt_p));
-
- if (stmt
- && TREE_CODE (stmt) == GIMPLE_MODIFY_STMT
- && GIMPLE_STMT_OPERAND (stmt, 0) == TREE_OPERAND (cond, 0)
- && GIMPLE_STMT_OPERAND (stmt, 1) == TREE_OPERAND (cond, 1))
- *location = alloc_stmt_list ();
- }
}
- /* Protect GOTOs in the arm of COND_EXPRs from being removed. They
- would be re-introduced during lowering. */
- data->last_goto = NULL;
+ gsi_next (gsi);
+
+ data->last_was_goto = false;
}
+/* Helper for remove_useless_stmts_1.
+ Handle the try-finally case for GIMPLE_TRY statements. */
static void
-remove_useless_stmts_tf (tree *stmt_p, struct rus_data *data)
+remove_useless_stmts_tf (gimple_stmt_iterator *gsi, struct rus_data *data)
{
bool save_may_branch, save_may_throw;
bool this_may_branch, this_may_throw;
+ gimple_seq eval_seq, cleanup_seq;
+ gimple_stmt_iterator eval_gsi, cleanup_gsi;
+
+ gimple stmt = gsi_stmt (*gsi);
+
/* Collect may_branch and may_throw information for the body only. */
save_may_branch = data->may_branch;
save_may_throw = data->may_throw;
data->may_branch = false;
data->may_throw = false;
- data->last_goto = NULL;
+ data->last_was_goto = false;
- remove_useless_stmts_1 (&TREE_OPERAND (*stmt_p, 0), data);
+ eval_seq = gimple_try_eval (stmt);
+ eval_gsi = gsi_start (eval_seq);
+ remove_useless_stmts_1 (&eval_gsi, data);
this_may_branch = data->may_branch;
this_may_throw = data->may_throw;
data->may_branch |= save_may_branch;
data->may_throw |= save_may_throw;
- data->last_goto = NULL;
+ data->last_was_goto = false;
- remove_useless_stmts_1 (&TREE_OPERAND (*stmt_p, 1), data);
+ cleanup_seq = gimple_try_cleanup (stmt);
+ cleanup_gsi = gsi_start (cleanup_seq);
+ remove_useless_stmts_1 (&cleanup_gsi, data);
/* If the body is empty, then we can emit the FINALLY block without
the enclosing TRY_FINALLY_EXPR. */
- if (!TREE_SIDE_EFFECTS (TREE_OPERAND (*stmt_p, 0)))
+ if (gimple_seq_empty_p (eval_seq))
{
- *stmt_p = TREE_OPERAND (*stmt_p, 1);
+ gsi_insert_seq_before (gsi, cleanup_seq, GSI_SAME_STMT);
+ gsi_remove (gsi, false);
data->repeat = true;
}
/* If the handler is empty, then we can emit the TRY block without
the enclosing TRY_FINALLY_EXPR. */
- else if (!TREE_SIDE_EFFECTS (TREE_OPERAND (*stmt_p, 1)))
+ else if (gimple_seq_empty_p (cleanup_seq))
{
- *stmt_p = TREE_OPERAND (*stmt_p, 0);
+ gsi_insert_seq_before (gsi, eval_seq, GSI_SAME_STMT);
+ gsi_remove (gsi, false);
data->repeat = true;
}
@@ -1650,37 +1641,51 @@ remove_useless_stmts_tf (tree *stmt_p, struct rus_data *data)
string the TRY and FINALLY blocks together. */
else if (!this_may_branch && !this_may_throw)
{
- tree stmt = *stmt_p;
- *stmt_p = TREE_OPERAND (stmt, 0);
- append_to_statement_list (TREE_OPERAND (stmt, 1), stmt_p);
+ gsi_insert_seq_before (gsi, eval_seq, GSI_SAME_STMT);
+ gsi_insert_seq_before (gsi, cleanup_seq, GSI_SAME_STMT);
+ gsi_remove (gsi, false);
data->repeat = true;
}
+ else
+ gsi_next (gsi);
}
+/* Helper for remove_useless_stmts_1.
+ Handle the try-catch case for GIMPLE_TRY statements. */
static void
-remove_useless_stmts_tc (tree *stmt_p, struct rus_data *data)
+remove_useless_stmts_tc (gimple_stmt_iterator *gsi, struct rus_data *data)
{
bool save_may_throw, this_may_throw;
- tree_stmt_iterator i;
- tree stmt;
+
+ gimple_seq eval_seq, cleanup_seq, handler_seq, failure_seq;
+ gimple_stmt_iterator eval_gsi, cleanup_gsi, handler_gsi, failure_gsi;
+
+ gimple stmt = gsi_stmt (*gsi);
/* Collect may_throw information for the body only. */
save_may_throw = data->may_throw;
data->may_throw = false;
- data->last_goto = NULL;
+ data->last_was_goto = false;
- remove_useless_stmts_1 (&TREE_OPERAND (*stmt_p, 0), data);
+ eval_seq = gimple_try_eval (stmt);
+ eval_gsi = gsi_start (eval_seq);
+ remove_useless_stmts_1 (&eval_gsi, data);
this_may_throw = data->may_throw;
data->may_throw = save_may_throw;
+ cleanup_seq = gimple_try_cleanup (stmt);
+
/* If the body cannot throw, then we can drop the entire TRY_CATCH_EXPR. */
if (!this_may_throw)
{
if (warn_notreached)
- remove_useless_stmts_warn_notreached (TREE_OPERAND (*stmt_p, 1));
- *stmt_p = TREE_OPERAND (*stmt_p, 0);
+ {
+ remove_useless_stmts_warn_notreached (cleanup_seq);
+ }
+ gsi_insert_seq_before (gsi, eval_seq, GSI_SAME_STMT);
+ gsi_remove (gsi, false);
data->repeat = true;
return;
}
@@ -1689,142 +1694,164 @@ remove_useless_stmts_tc (tree *stmt_p, struct rus_data *data)
no exceptions propagate past this point. */
this_may_throw = true;
- i = tsi_start (TREE_OPERAND (*stmt_p, 1));
- stmt = tsi_stmt (i);
- data->last_goto = NULL;
+ cleanup_gsi = gsi_start (cleanup_seq);
+ stmt = gsi_stmt (cleanup_gsi);
+ data->last_was_goto = false;
- switch (TREE_CODE (stmt))
+ switch (gimple_code (stmt))
{
- case CATCH_EXPR:
- for (; !tsi_end_p (i); tsi_next (&i))
- {
- stmt = tsi_stmt (i);
+ case GIMPLE_CATCH:
+ /* If the first element is a catch, they all must be. */
+ while (!gsi_end_p (cleanup_gsi))
+ {
+ stmt = gsi_stmt (cleanup_gsi);
/* If we catch all exceptions, then the body does not
propagate exceptions past this point. */
- if (CATCH_TYPES (stmt) == NULL)
+ if (gimple_catch_types (stmt) == NULL)
this_may_throw = false;
- data->last_goto = NULL;
- remove_useless_stmts_1 (&CATCH_BODY (stmt), data);
+ data->last_was_goto = false;
+ handler_seq = gimple_catch_handler (stmt);
+ handler_gsi = gsi_start (handler_seq);
+ remove_useless_stmts_1 (&handler_gsi, data);
+ gsi_next (&cleanup_gsi);
}
+ gsi_next (gsi);
break;
- case EH_FILTER_EXPR:
- if (EH_FILTER_MUST_NOT_THROW (stmt))
+ case GIMPLE_EH_FILTER:
+ /* If the first element is an eh_filter, it should stand alone. */
+ if (gimple_eh_filter_must_not_throw (stmt))
this_may_throw = false;
- else if (EH_FILTER_TYPES (stmt) == NULL)
+ else if (gimple_eh_filter_types (stmt) == NULL)
this_may_throw = false;
- remove_useless_stmts_1 (&EH_FILTER_FAILURE (stmt), data);
+ failure_seq = gimple_eh_filter_failure (stmt);
+ failure_gsi = gsi_start (failure_seq);
+ remove_useless_stmts_1 (&failure_gsi, data);
+ gsi_next (gsi);
break;
default:
- /* Otherwise this is a cleanup. */
- remove_useless_stmts_1 (&TREE_OPERAND (*stmt_p, 1), data);
+ /* Otherwise this is a list of cleanup statements. */
+ remove_useless_stmts_1 (&cleanup_gsi, data);
/* If the cleanup is empty, then we can emit the TRY block without
the enclosing TRY_CATCH_EXPR. */
- if (!TREE_SIDE_EFFECTS (TREE_OPERAND (*stmt_p, 1)))
+ if (gimple_seq_empty_p (cleanup_seq))
{
- *stmt_p = TREE_OPERAND (*stmt_p, 0);
+ gsi_insert_seq_before (gsi, eval_seq, GSI_SAME_STMT);
+ gsi_remove(gsi, false);
data->repeat = true;
}
+ else
+ gsi_next (gsi);
break;
}
+
data->may_throw |= this_may_throw;
}
+/* Helper for remove_useless_stmts_1. Handle GIMPLE_BIND statements. */
static void
-remove_useless_stmts_bind (tree *stmt_p, struct rus_data *data)
+remove_useless_stmts_bind (gimple_stmt_iterator *gsi, struct rus_data *data ATTRIBUTE_UNUSED)
{
tree block;
+ gimple_seq body_seq, fn_body_seq;
+ gimple_stmt_iterator body_gsi;
+
+ gimple stmt = gsi_stmt (*gsi);
/* First remove anything underneath the BIND_EXPR. */
- remove_useless_stmts_1 (&BIND_EXPR_BODY (*stmt_p), data);
+
+ body_seq = gimple_bind_body (stmt);
+ body_gsi = gsi_start (body_seq);
+ remove_useless_stmts_1 (&body_gsi, data);
- /* If the BIND_EXPR has no variables, then we can pull everything
- up one level and remove the BIND_EXPR, unless this is the toplevel
- BIND_EXPR for the current function or an inlined function.
+ /* If the GIMPLE_BIND has no variables, then we can pull everything
+ up one level and remove the GIMPLE_BIND, unless this is the toplevel
+ GIMPLE_BIND for the current function or an inlined function.
When this situation occurs we will want to apply this
optimization again. */
- block = BIND_EXPR_BLOCK (*stmt_p);
- if (BIND_EXPR_VARS (*stmt_p) == NULL_TREE
- && *stmt_p != DECL_SAVED_TREE (current_function_decl)
+ block = gimple_bind_block (stmt);
+ fn_body_seq = gimple_body (current_function_decl);
+ if (gimple_bind_vars (stmt) == NULL_TREE
+ && (gimple_seq_empty_p (fn_body_seq)
+ || stmt != gimple_seq_first_stmt (fn_body_seq))
&& (! block
|| ! BLOCK_ABSTRACT_ORIGIN (block)
|| (TREE_CODE (BLOCK_ABSTRACT_ORIGIN (block))
!= FUNCTION_DECL)))
{
- *stmt_p = BIND_EXPR_BODY (*stmt_p);
+ gsi_insert_seq_before (gsi, body_seq, GSI_SAME_STMT);
+ gsi_remove (gsi, false);
data->repeat = true;
}
+ else
+ gsi_next (gsi);
}
+/* Helper for remove_useless_stmts_1. Handle GIMPLE_GOTO statements. */
static void
-remove_useless_stmts_goto (tree *stmt_p, struct rus_data *data)
+remove_useless_stmts_goto (gimple_stmt_iterator *gsi, struct rus_data *data)
{
- tree dest = GOTO_DESTINATION (*stmt_p);
+ gimple stmt = gsi_stmt (*gsi);
+
+ tree dest = gimple_goto_dest (stmt);
data->may_branch = true;
- data->last_goto = NULL;
+ data->last_was_goto = false;
- /* Record the last goto expr, so that we can delete it if unnecessary. */
+ /* Record iterator for last goto expr, so that we can delete it if unnecessary. */
if (TREE_CODE (dest) == LABEL_DECL)
- data->last_goto = stmt_p;
+ {
+ data->last_goto_gsi = *gsi;
+ data->last_was_goto = true;
+ }
+
+ gsi_next(gsi);
}
+/* Helper for remove_useless_stmts_1. Handle GIMPLE_LABEL statements. */
static void
-remove_useless_stmts_label (tree *stmt_p, struct rus_data *data)
+remove_useless_stmts_label (gimple_stmt_iterator *gsi, struct rus_data *data)
{
- tree label = LABEL_EXPR_LABEL (*stmt_p);
+ gimple stmt = gsi_stmt (*gsi);
+
+ tree label = gimple_label_label (stmt);
data->has_label = true;
/* We do want to jump across non-local label receiver code. */
if (DECL_NONLOCAL (label))
- data->last_goto = NULL;
+ data->last_was_goto = false;
- else if (data->last_goto && GOTO_DESTINATION (*data->last_goto) == label)
+ else if (data->last_was_goto
+ && gimple_goto_dest (gsi_stmt (data->last_goto_gsi)) == label)
{
- *data->last_goto = build_empty_stmt ();
+ /* Replace the preceding GIMPLE_GOTO statement with
+ a GIMPLE_NOP, which will be subsequently removed.
+ In this way, we avoid invalidating other iterators
+ active on the statement sequence. */
+ gsi_replace(&data->last_goto_gsi, gimple_build_nop(), false);
+ data->last_was_goto = false;
data->repeat = true;
}
/* ??? Add something here to delete unused labels. */
-}
-
-
-/* If the function is "const" or "pure", then clear TREE_SIDE_EFFECTS on its
- decl. This allows us to eliminate redundant or useless
- calls to "const" functions.
- Gimplifier already does the same operation, but we may notice functions
- being const and pure once their calls has been gimplified, so we need
- to update the flag. */
-
-static void
-update_call_expr_flags (tree call)
-{
- tree decl = get_callee_fndecl (call);
- int flags;
- if (!decl)
- return;
- flags = call_expr_flags (call);
- if (flags & (ECF_CONST | ECF_PURE) && !(flags & ECF_LOOPING_CONST_OR_PURE))
- TREE_SIDE_EFFECTS (call) = 0;
- if (TREE_NOTHROW (decl))
- TREE_NOTHROW (call) = 1;
+ gsi_next (gsi);
}
/* T is CALL_EXPR. Set current_function_calls_* flags. */
void
-notice_special_calls (tree t)
+notice_special_calls (gimple call)
{
- int flags = call_expr_flags (t);
+ int flags = gimple_call_flags (call);
if (flags & ECF_MAY_BE_ALLOCA)
cfun->calls_alloca = true;
@@ -1843,133 +1870,144 @@ clear_special_calls (void)
cfun->calls_setjmp = false;
}
+/* Remove useless statements from a statement sequence, and perform
+ some preliminary simplifications. */
static void
-remove_useless_stmts_1 (tree *tp, struct rus_data *data)
+remove_useless_stmts_1 (gimple_stmt_iterator *gsi, struct rus_data *data)
{
- tree t = *tp, op;
-
- switch (TREE_CODE (t))
+ while (!gsi_end_p (*gsi))
{
- case COND_EXPR:
- remove_useless_stmts_cond (tp, data);
- break;
-
- case TRY_FINALLY_EXPR:
- remove_useless_stmts_tf (tp, data);
- break;
+ gimple stmt = gsi_stmt (*gsi);
- case TRY_CATCH_EXPR:
- remove_useless_stmts_tc (tp, data);
- break;
-
- case BIND_EXPR:
- remove_useless_stmts_bind (tp, data);
- break;
-
- case GOTO_EXPR:
- remove_useless_stmts_goto (tp, data);
- break;
-
- case LABEL_EXPR:
- remove_useless_stmts_label (tp, data);
- break;
-
- case RETURN_EXPR:
- fold_stmt (tp);
- data->last_goto = NULL;
- data->may_branch = true;
- break;
-
- case CALL_EXPR:
- fold_stmt (tp);
- data->last_goto = NULL;
- notice_special_calls (t);
- update_call_expr_flags (t);
- if (tree_could_throw_p (t))
- data->may_throw = true;
- break;
-
- case MODIFY_EXPR:
- gcc_unreachable ();
-
- case GIMPLE_MODIFY_STMT:
- data->last_goto = NULL;
- fold_stmt (tp);
- op = get_call_expr_in (t);
- if (op)
- {
- update_call_expr_flags (op);
- notice_special_calls (op);
- }
- if (tree_could_throw_p (t))
- data->may_throw = true;
- break;
-
- case STATEMENT_LIST:
- {
- tree_stmt_iterator i = tsi_start (t);
- while (!tsi_end_p (i))
- {
- t = tsi_stmt (i);
- if (IS_EMPTY_STMT (t))
- {
- tsi_delink (&i);
- continue;
- }
-
- remove_useless_stmts_1 (tsi_stmt_ptr (i), data);
-
- t = tsi_stmt (i);
- if (TREE_CODE (t) == STATEMENT_LIST)
- {
- tsi_link_before (&i, t, TSI_SAME_STMT);
- tsi_delink (&i);
- }
- else
- tsi_next (&i);
- }
- }
- break;
- case ASM_EXPR:
- fold_stmt (tp);
- data->last_goto = NULL;
- break;
-
- case OMP_PARALLEL:
- case OMP_TASK:
- /* Make sure the outermost BIND_EXPR in OMP_BODY isn't removed
- as useless. */
- remove_useless_stmts_1 (&BIND_EXPR_BODY (OMP_TASKREG_BODY (*tp)), data);
- data->last_goto = NULL;
- break;
-
- case OMP_SECTIONS:
- case OMP_SINGLE:
- case OMP_SECTION:
- case OMP_MASTER:
- case OMP_ORDERED:
- case OMP_CRITICAL:
- remove_useless_stmts_1 (&OMP_BODY (*tp), data);
- data->last_goto = NULL;
- break;
-
- case OMP_FOR:
- remove_useless_stmts_1 (&OMP_FOR_BODY (*tp), data);
- data->last_goto = NULL;
- if (OMP_FOR_PRE_BODY (*tp))
- {
- remove_useless_stmts_1 (&OMP_FOR_PRE_BODY (*tp), data);
- data->last_goto = NULL;
- }
- break;
-
- default:
- data->last_goto = NULL;
- break;
+ switch (gimple_code (stmt))
+ {
+ case GIMPLE_COND:
+ remove_useless_stmts_cond (gsi, data);
+ break;
+
+ case GIMPLE_GOTO:
+ remove_useless_stmts_goto (gsi, data);
+ break;
+
+ case GIMPLE_LABEL:
+ remove_useless_stmts_label (gsi, data);
+ break;
+
+ case GIMPLE_ASSIGN:
+ fold_stmt (gsi);
+ stmt = gsi_stmt (*gsi);
+ data->last_was_goto = false;
+ if (stmt_could_throw_p (stmt))
+ data->may_throw = true;
+ gsi_next (gsi);
+ break;
+
+ case GIMPLE_ASM:
+ fold_stmt (gsi);
+ data->last_was_goto = false;
+ gsi_next (gsi);
+ break;
+
+ case GIMPLE_CALL:
+ fold_stmt (gsi);
+ stmt = gsi_stmt (*gsi);
+ data->last_was_goto = false;
+ if (is_gimple_call (stmt))
+ notice_special_calls (stmt);
+
+ /* We used to call update_gimple_call_flags here,
+ which copied side-effects and nothrows status
+ from the function decl to the call. In the new
+ tuplified GIMPLE, the accessors for this information
+ always consult the function decl, so this copying
+ is no longer necessary. */
+ if (stmt_could_throw_p (stmt))
+ data->may_throw = true;
+ gsi_next (gsi);
+ break;
+
+ case GIMPLE_RETURN:
+ fold_stmt (gsi);
+ data->last_was_goto = false;
+ data->may_branch = true;
+ gsi_next (gsi);
+ break;
+
+ case GIMPLE_BIND:
+ remove_useless_stmts_bind (gsi, data);
+ break;
+
+ case GIMPLE_TRY:
+ if (gimple_try_kind (stmt) == GIMPLE_TRY_CATCH)
+ remove_useless_stmts_tc (gsi, data);
+ else if (gimple_try_kind (stmt) == GIMPLE_TRY_FINALLY)
+ remove_useless_stmts_tf (gsi, data);
+ else
+ gcc_unreachable ();
+ break;
+
+ case GIMPLE_CATCH:
+ gcc_unreachable ();
+ break;
+
+ case GIMPLE_NOP:
+ gsi_remove (gsi, false);
+ break;
+
+ case GIMPLE_OMP_FOR:
+ {
+ gimple_seq pre_body_seq = gimple_omp_for_pre_body (stmt);
+ gimple_stmt_iterator pre_body_gsi = gsi_start (pre_body_seq);
+
+ remove_useless_stmts_1 (&pre_body_gsi, data);
+ data->last_was_goto = false;
+ }
+ /* FALLTHROUGH */
+ case GIMPLE_OMP_CRITICAL:
+ case GIMPLE_OMP_CONTINUE:
+ case GIMPLE_OMP_MASTER:
+ case GIMPLE_OMP_ORDERED:
+ case GIMPLE_OMP_SECTION:
+ case GIMPLE_OMP_SECTIONS:
+ case GIMPLE_OMP_SINGLE:
+ {
+ gimple_seq body_seq = gimple_omp_body (stmt);
+ gimple_stmt_iterator body_gsi = gsi_start (body_seq);
+
+ remove_useless_stmts_1 (&body_gsi, data);
+ data->last_was_goto = false;
+ gsi_next (gsi);
+ }
+ break;
+
+ case GIMPLE_OMP_PARALLEL:
+ case GIMPLE_OMP_TASK:
+ {
+ /* Make sure the outermost GIMPLE_BIND isn't removed
+ as useless. */
+ gimple_seq body_seq = gimple_omp_body (stmt);
+ gimple bind = gimple_seq_first_stmt (body_seq);
+ gimple_seq bind_seq = gimple_bind_body (bind);
+ gimple_stmt_iterator bind_gsi = gsi_start (bind_seq);
+
+ remove_useless_stmts_1 (&bind_gsi, data);
+ data->last_was_goto = false;
+ gsi_next (gsi);
+ }
+ break;
+
+ default:
+ data->last_was_goto = false;
+ gsi_next (gsi);
+ break;
+ }
}
}
+/* Walk the function tree, removing useless statements and performing
+ some preliminary simplifications. */
+
static unsigned int
remove_useless_stmts (void)
{
@@ -1979,8 +2017,11 @@ remove_useless_stmts (void)
do
{
+ gimple_stmt_iterator gsi;
+
+ gsi = gsi_start (gimple_body (current_function_decl));
memset (&data, 0, sizeof (data));
- remove_useless_stmts_1 (&DECL_SAVED_TREE (current_function_decl), &data);
+ remove_useless_stmts_1 (&gsi, &data);
}
while (data.repeat);
return 0;
@@ -2011,17 +2052,14 @@ struct gimple_opt_pass pass_remove_useless_stmts =
static void
remove_phi_nodes_and_edges_for_unreachable_block (basic_block bb)
{
- tree phi;
+ gimple_stmt_iterator gsi;
/* Since this block is no longer reachable, we can just delete all
of its PHI nodes. */
- phi = phi_nodes (bb);
- while (phi)
- {
- tree next = PHI_CHAIN (phi);
- remove_phi_node (phi, NULL_TREE, true);
- phi = next;
- }
+ for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); )
+ remove_phi_node (&gsi, true);
+
+ set_phi_nodes (bb, NULL);
/* Remove edges to BB's successors. */
while (EDGE_COUNT (bb->succs) > 0)
@@ -2034,7 +2072,7 @@ remove_phi_nodes_and_edges_for_unreachable_block (basic_block bb)
static void
remove_bb (basic_block bb)
{
- block_stmt_iterator i;
+ gimple_stmt_iterator i;
source_location loc = UNKNOWN_LOCATION;
if (dump_file)
@@ -2059,31 +2097,31 @@ remove_bb (basic_block bb)
}
/* Remove all the instructions in the block. */
- if (bb_stmt_list (bb) != NULL_TREE)
+ if (bb_seq (bb) != NULL)
{
- for (i = bsi_start (bb); !bsi_end_p (i);)
+ for (i = gsi_start_bb (bb); !gsi_end_p (i);)
{
- tree stmt = bsi_stmt (i);
- if (TREE_CODE (stmt) == LABEL_EXPR
- && (FORCED_LABEL (LABEL_EXPR_LABEL (stmt))
- || DECL_NONLOCAL (LABEL_EXPR_LABEL (stmt))))
+ gimple stmt = gsi_stmt (i);
+ if (gimple_code (stmt) == GIMPLE_LABEL
+ && (FORCED_LABEL (gimple_label_label (stmt))
+ || DECL_NONLOCAL (gimple_label_label (stmt))))
{
basic_block new_bb;
- block_stmt_iterator new_bsi;
+ gimple_stmt_iterator new_gsi;
/* A non-reachable non-local label may still be referenced.
But it no longer needs to carry the extra semantics of
non-locality. */
- if (DECL_NONLOCAL (LABEL_EXPR_LABEL (stmt)))
+ if (DECL_NONLOCAL (gimple_label_label (stmt)))
{
- DECL_NONLOCAL (LABEL_EXPR_LABEL (stmt)) = 0;
- FORCED_LABEL (LABEL_EXPR_LABEL (stmt)) = 1;
+ DECL_NONLOCAL (gimple_label_label (stmt)) = 0;
+ FORCED_LABEL (gimple_label_label (stmt)) = 1;
}
new_bb = bb->prev_bb;
- new_bsi = bsi_start (new_bb);
- bsi_remove (&i, false);
- bsi_insert_before (&new_bsi, stmt, BSI_NEW_STMT);
+ new_gsi = gsi_start_bb (new_bb);
+ gsi_remove (&i, false);
+ gsi_insert_before (&new_gsi, stmt, GSI_NEW_STMT);
}
else
{
@@ -2094,18 +2132,17 @@ remove_bb (basic_block bb)
if (gimple_in_ssa_p (cfun))
release_defs (stmt);
- bsi_remove (&i, true);
+ gsi_remove (&i, true);
}
/* Don't warn for removed gotos. Gotos are often removed due to
jump threading, thus resulting in bogus warnings. Not great,
since this way we lose warnings for gotos in the original
program that are indeed unreachable. */
- if (TREE_CODE (stmt) != GOTO_EXPR && EXPR_HAS_LOCATION (stmt) && !loc)
- {
- if (EXPR_HAS_LOCATION (stmt))
- loc = EXPR_LOCATION (stmt);
- }
+ if (gimple_code (stmt) != GIMPLE_GOTO
+ && gimple_has_location (stmt)
+ && !loc)
+ loc = gimple_location (stmt);
}
}
@@ -2117,7 +2154,7 @@ remove_bb (basic_block bb)
warning (OPT_Wunreachable_code, "%Hwill never be executed", &loc);
remove_phi_nodes_and_edges_for_unreachable_block (bb);
- bb->il.tree = NULL;
+ bb->il.gimple = NULL;
}
@@ -2128,21 +2165,23 @@ remove_bb (basic_block bb)
edge
find_taken_edge (basic_block bb, tree val)
{
- tree stmt;
+ gimple stmt;
stmt = last_stmt (bb);
gcc_assert (stmt);
gcc_assert (is_ctrl_stmt (stmt));
- gcc_assert (val);
- if (! is_gimple_min_invariant (val))
+ if (val == NULL)
+ return NULL;
+
+ if (!is_gimple_min_invariant (val))
return NULL;
- if (TREE_CODE (stmt) == COND_EXPR)
+ if (gimple_code (stmt) == GIMPLE_COND)
return find_taken_edge_cond_expr (bb, val);
- if (TREE_CODE (stmt) == SWITCH_EXPR)
+ if (gimple_code (stmt) == GIMPLE_SWITCH)
return find_taken_edge_switch_expr (bb, val);
if (computed_goto_p (stmt))
@@ -2204,12 +2243,13 @@ find_taken_edge_cond_expr (basic_block bb, tree val)
static edge
find_taken_edge_switch_expr (basic_block bb, tree val)
{
- tree switch_expr, taken_case;
basic_block dest_bb;
edge e;
+ gimple switch_stmt;
+ tree taken_case;
- switch_expr = last_stmt (bb);
- taken_case = find_case_label_for_value (switch_expr, val);
+ switch_stmt = last_stmt (bb);
+ taken_case = find_case_label_for_value (switch_stmt, val);
dest_bb = label_to_block (CASE_LABEL (taken_case));
e = find_edge (bb, dest_bb);
@@ -2218,21 +2258,20 @@ find_taken_edge_switch_expr (basic_block bb, tree val)
}
-/* Return the CASE_LABEL_EXPR that SWITCH_EXPR will take for VAL.
+/* Return the CASE_LABEL_EXPR that SWITCH_STMT will take for VAL.
We can make optimal use here of the fact that the case labels are
sorted: We can do a binary search for a case matching VAL. */
static tree
-find_case_label_for_value (tree switch_expr, tree val)
+find_case_label_for_value (gimple switch_stmt, tree val)
{
- tree vec = SWITCH_LABELS (switch_expr);
- size_t low, high, n = TREE_VEC_LENGTH (vec);
- tree default_case = TREE_VEC_ELT (vec, n - 1);
+ size_t low, high, n = gimple_switch_num_labels (switch_stmt);
+ tree default_case = gimple_switch_default_label (switch_stmt);
- for (low = -1, high = n - 1; high - low > 1; )
+ for (low = 0, high = n; high - low > 1; )
{
size_t i = (high + low) / 2;
- tree t = TREE_VEC_ELT (vec, i);
+ tree t = gimple_switch_label (switch_stmt, i);
int cmp;
/* Cache the result of comparing CASE_LOW and val. */
@@ -2261,36 +2300,21 @@ find_case_label_for_value (tree switch_expr, tree val)
}
-
-
-/*---------------------------------------------------------------------------
- Debugging functions
----------------------------------------------------------------------------*/
-
-/* Dump tree-specific information of block BB to file OUTF. */
-
-void
-tree_dump_bb (basic_block bb, FILE *outf, int indent)
-{
- dump_generic_bb (outf, bb, indent, TDF_VOPS|TDF_MEMSYMS);
-}
-
-
/* Dump a basic block on stderr. */
void
-debug_tree_bb (basic_block bb)
+gimple_debug_bb (basic_block bb)
{
- dump_bb (bb, stderr, 0);
+ gimple_dump_bb (bb, stderr, 0, TDF_VOPS|TDF_MEMSYMS);
}
/* Dump basic block with index N on stderr. */
basic_block
-debug_tree_bb_n (int n)
+gimple_debug_bb_n (int n)
{
- debug_tree_bb (BASIC_BLOCK (n));
+ gimple_debug_bb (BASIC_BLOCK (n));
return BASIC_BLOCK (n);
}
@@ -2301,9 +2325,9 @@ debug_tree_bb_n (int n)
(see TDF_* in tree-pass.h). */
void
-debug_tree_cfg (int flags)
+gimple_debug_cfg (int flags)
{
- dump_tree_cfg (stderr, flags);
+ gimple_dump_cfg (stderr, flags);
}
@@ -2313,7 +2337,7 @@ debug_tree_cfg (int flags)
tree.h). */
void
-dump_tree_cfg (FILE *file, int flags)
+gimple_dump_cfg (FILE *file, int flags)
{
if (flags & TDF_DETAILS)
{
@@ -2401,7 +2425,7 @@ debug_cfg_stats (void)
/* Dump the flowgraph to a .vcg FILE. */
static void
-tree_cfg2vcg (FILE *file)
+gimple_cfg2vcg (FILE *file)
{
edge e;
edge_iterator ei;
@@ -2431,17 +2455,17 @@ tree_cfg2vcg (FILE *file)
FOR_EACH_BB (bb)
{
- enum tree_code head_code, end_code;
+ enum gimple_code head_code, end_code;
const char *head_name, *end_name;
int head_line = 0;
int end_line = 0;
- tree first = first_stmt (bb);
- tree last = last_stmt (bb);
+ gimple first = first_stmt (bb);
+ gimple last = last_stmt (bb);
if (first)
{
- head_code = TREE_CODE (first);
- head_name = tree_code_name[head_code];
+ head_code = gimple_code (first);
+ head_name = gimple_code_name[head_code];
head_line = get_lineno (first);
}
else
@@ -2449,8 +2473,8 @@ tree_cfg2vcg (FILE *file)
if (last)
{
- end_code = TREE_CODE (last);
- end_name = tree_code_name[end_code];
+ end_code = gimple_code (last);
+ end_name = gimple_code_name[end_code];
end_line = get_lineno (last);
}
else
@@ -2491,13 +2515,13 @@ tree_cfg2vcg (FILE *file)
/* Return true if T represents a stmt that always transfers control. */
bool
-is_ctrl_stmt (const_tree t)
+is_ctrl_stmt (gimple t)
{
- return (TREE_CODE (t) == COND_EXPR
- || TREE_CODE (t) == SWITCH_EXPR
- || TREE_CODE (t) == GOTO_EXPR
- || TREE_CODE (t) == RETURN_EXPR
- || TREE_CODE (t) == RESX_EXPR);
+ return gimple_code (t) == GIMPLE_COND
+ || gimple_code (t) == GIMPLE_SWITCH
+ || gimple_code (t) == GIMPLE_GOTO
+ || gimple_code (t) == GIMPLE_RETURN
+ || gimple_code (t) == GIMPLE_RESX;
}
@@ -2505,50 +2529,41 @@ is_ctrl_stmt (const_tree t)
(e.g., a call to a non-returning function). */
bool
-is_ctrl_altering_stmt (const_tree t)
+is_ctrl_altering_stmt (gimple t)
{
- const_tree call;
-
gcc_assert (t);
- call = get_call_expr_in (CONST_CAST_TREE (t));
- if (call)
+
+ if (is_gimple_call (t))
{
- /* A non-pure/const CALL_EXPR alters flow control if the current
+ int flags = gimple_call_flags (t);
+
+ /* A non-pure/const call alters flow control if the current
function has nonlocal labels. */
- if (TREE_SIDE_EFFECTS (call) && cfun->has_nonlocal_label)
+ if (!(flags & (ECF_CONST | ECF_PURE))
+ && cfun->has_nonlocal_label)
return true;
- /* A CALL_EXPR also alters control flow if it does not return. */
- if (call_expr_flags (call) & ECF_NORETURN)
+ /* A call also alters control flow if it does not return. */
+ if (gimple_call_flags (t) & ECF_NORETURN)
return true;
}
/* OpenMP directives alter control flow. */
- if (OMP_DIRECTIVE_P (t))
+ if (is_gimple_omp (t))
return true;
/* If a statement can throw, it alters control flow. */
- return tree_can_throw_internal (t);
-}
-
-
-/* Return true if T is a computed goto. */
-
-static bool
-computed_goto_p (const_tree t)
-{
- return (TREE_CODE (t) == GOTO_EXPR
- && TREE_CODE (GOTO_DESTINATION (t)) != LABEL_DECL);
+ return stmt_can_throw_internal (t);
}
/* Return true if T is a simple local goto. */
bool
-simple_goto_p (const_tree t)
+simple_goto_p (gimple t)
{
- return (TREE_CODE (t) == GOTO_EXPR
- && TREE_CODE (GOTO_DESTINATION (t)) == LABEL_DECL);
+ return (gimple_code (t) == GIMPLE_GOTO
+ && TREE_CODE (gimple_goto_dest (t)) == LABEL_DECL);
}
@@ -2556,46 +2571,42 @@ simple_goto_p (const_tree t)
Transfers of control flow associated with EH are excluded. */
bool
-tree_can_make_abnormal_goto (const_tree t)
+stmt_can_make_abnormal_goto (gimple t)
{
if (computed_goto_p (t))
return true;
- if (TREE_CODE (t) == GIMPLE_MODIFY_STMT)
- t = GIMPLE_STMT_OPERAND (t, 1);
- if (TREE_CODE (t) == WITH_SIZE_EXPR)
- t = TREE_OPERAND (t, 0);
- if (TREE_CODE (t) == CALL_EXPR)
- return TREE_SIDE_EFFECTS (t) && cfun->has_nonlocal_label;
+ if (is_gimple_call (t))
+ return gimple_has_side_effects (t) && cfun->has_nonlocal_label;
return false;
}
-/* Return true if T should start a new basic block. PREV_T is the
- statement preceding T. It is used when T is a label or a case label.
- Labels should only start a new basic block if their previous statement
- wasn't a label. Otherwise, sequence of labels would generate
- unnecessary basic blocks that only contain a single label. */
+/* Return true if STMT should start a new basic block. PREV_STMT is
+ the statement preceding STMT. It is used when STMT is a label or a
+ case label. Labels should only start a new basic block if their
+ previous statement wasn't a label. Otherwise, sequence of labels
+ would generate unnecessary basic blocks that only contain a single
+ label. */
static inline bool
-stmt_starts_bb_p (const_tree t, const_tree prev_t)
+stmt_starts_bb_p (gimple stmt, gimple prev_stmt)
{
- if (t == NULL_TREE)
+ if (stmt == NULL)
return false;
- /* LABEL_EXPRs start a new basic block only if the preceding
- statement wasn't a label of the same type. This prevents the
- creation of consecutive blocks that have nothing but a single
- label. */
- if (TREE_CODE (t) == LABEL_EXPR)
+ /* Labels start a new basic block only if the preceding statement
+ wasn't a label of the same type. This prevents the creation of
+ consecutive blocks that have nothing but a single label. */
+ if (gimple_code (stmt) == GIMPLE_LABEL)
{
/* Nonlocal and computed GOTO targets always start a new block. */
- if (DECL_NONLOCAL (LABEL_EXPR_LABEL (t))
- || FORCED_LABEL (LABEL_EXPR_LABEL (t)))
+ if (DECL_NONLOCAL (gimple_label_label (stmt))
+ || FORCED_LABEL (gimple_label_label (stmt)))
return true;
- if (prev_t && TREE_CODE (prev_t) == LABEL_EXPR)
+ if (prev_stmt && gimple_code (prev_stmt) == GIMPLE_LABEL)
{
- if (DECL_NONLOCAL (LABEL_EXPR_LABEL (prev_t)))
+ if (DECL_NONLOCAL (gimple_label_label (prev_stmt)))
return true;
cfg_stats.num_merged_labels++;
@@ -2612,502 +2623,97 @@ stmt_starts_bb_p (const_tree t, const_tree prev_t)
/* Return true if T should end a basic block. */
bool
-stmt_ends_bb_p (const_tree t)
+stmt_ends_bb_p (gimple t)
{
return is_ctrl_stmt (t) || is_ctrl_altering_stmt (t);
}
-/* Remove block annotations and other datastructures. */
+/* Remove block annotations and other data structures. */
void
delete_tree_cfg_annotations (void)
{
- basic_block bb;
- block_stmt_iterator bsi;
-
- /* Remove annotations from every tree in the function. */
- FOR_EACH_BB (bb)
- for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
- {
- tree stmt = bsi_stmt (bsi);
- ggc_free (stmt->base.ann);
- stmt->base.ann = NULL;
- }
label_to_block_map = NULL;
}
/* Return the first statement in basic block BB. */
-tree
+gimple
first_stmt (basic_block bb)
{
- block_stmt_iterator i = bsi_start (bb);
- return !bsi_end_p (i) ? bsi_stmt (i) : NULL_TREE;
+ gimple_stmt_iterator i = gsi_start_bb (bb);
+ return !gsi_end_p (i) ? gsi_stmt (i) : NULL;
}
/* Return the last statement in basic block BB. */
-tree
+gimple
last_stmt (basic_block bb)
{
- block_stmt_iterator b = bsi_last (bb);
- return !bsi_end_p (b) ? bsi_stmt (b) : NULL_TREE;
+ gimple_stmt_iterator b = gsi_last_bb (bb);
+ return !gsi_end_p (b) ? gsi_stmt (b) : NULL;
}
/* Return the last statement of an otherwise empty block. Return NULL
if the block is totally empty, or if it contains more than one
statement. */
-tree
+gimple
last_and_only_stmt (basic_block bb)
{
- block_stmt_iterator i = bsi_last (bb);
- tree last, prev;
+ gimple_stmt_iterator i = gsi_last_bb (bb);
+ gimple last, prev;
- if (bsi_end_p (i))
- return NULL_TREE;
+ if (gsi_end_p (i))
+ return NULL;
- last = bsi_stmt (i);
- bsi_prev (&i);
- if (bsi_end_p (i))
+ last = gsi_stmt (i);
+ gsi_prev (&i);
+ if (gsi_end_p (i))
return last;
/* Empty statements should no longer appear in the instruction stream.
Everything that might have appeared before should be deleted by
- remove_useless_stmts, and the optimizers should just bsi_remove
+ remove_useless_stmts, and the optimizers should just gsi_remove
instead of smashing with build_empty_stmt.
Thus the only thing that should appear here in a block containing
one executable statement is a label. */
- prev = bsi_stmt (i);
- if (TREE_CODE (prev) == LABEL_EXPR)
+ prev = gsi_stmt (i);
+ if (gimple_code (prev) == GIMPLE_LABEL)
return last;
else
- return NULL_TREE;
-}
-
-
-/* Mark BB as the basic block holding statement T. */
-
-void
-set_bb_for_stmt (tree t, basic_block bb)
-{
- if (TREE_CODE (t) == PHI_NODE)
- PHI_BB (t) = bb;
- else if (TREE_CODE (t) == STATEMENT_LIST)
- {
- tree_stmt_iterator i;
- for (i = tsi_start (t); !tsi_end_p (i); tsi_next (&i))
- set_bb_for_stmt (tsi_stmt (i), bb);
- }
- else
- {
- stmt_ann_t ann = get_stmt_ann (t);
- ann->bb = bb;
-
- /* If the statement is a label, add the label to block-to-labels map
- so that we can speed up edge creation for GOTO_EXPRs. */
- if (TREE_CODE (t) == LABEL_EXPR)
- {
- int uid;
-
- t = LABEL_EXPR_LABEL (t);
- uid = LABEL_DECL_UID (t);
- if (uid == -1)
- {
- unsigned old_len = VEC_length (basic_block, label_to_block_map);
- LABEL_DECL_UID (t) = uid = cfun->cfg->last_label_uid++;
- if (old_len <= (unsigned) uid)
- {
- unsigned new_len = 3 * uid / 2;
-
- VEC_safe_grow_cleared (basic_block, gc, label_to_block_map,
- new_len);
- }
- }
- else
- /* We're moving an existing label. Make sure that we've
- removed it from the old block. */
- gcc_assert (!bb
- || !VEC_index (basic_block, label_to_block_map, uid));
- VEC_replace (basic_block, label_to_block_map, uid, bb);
- }
- }
-}
-
-/* Faster version of set_bb_for_stmt that assume that statement is being moved
- from one basic block to another.
- For BB splitting we can run into quadratic case, so performance is quite
- important and knowing that the tables are big enough, change_bb_for_stmt
- can inline as leaf function. */
-static inline void
-change_bb_for_stmt (tree t, basic_block bb)
-{
- get_stmt_ann (t)->bb = bb;
- if (TREE_CODE (t) == LABEL_EXPR)
- VEC_replace (basic_block, label_to_block_map,
- LABEL_DECL_UID (LABEL_EXPR_LABEL (t)), bb);
-}
-
-/* Finds iterator for STMT. */
-
-extern block_stmt_iterator
-bsi_for_stmt (tree stmt)
-{
- block_stmt_iterator bsi;
-
- for (bsi = bsi_start (bb_for_stmt (stmt)); !bsi_end_p (bsi); bsi_next (&bsi))
- if (bsi_stmt (bsi) == stmt)
- return bsi;
-
- gcc_unreachable ();
-}
-
-/* Mark statement T as modified, and update it. */
-static inline void
-update_modified_stmts (tree t)
-{
- if (!ssa_operands_active ())
- return;
- if (TREE_CODE (t) == STATEMENT_LIST)
- {
- tree_stmt_iterator i;
- tree stmt;
- for (i = tsi_start (t); !tsi_end_p (i); tsi_next (&i))
- {
- stmt = tsi_stmt (i);
- update_stmt_if_modified (stmt);
- }
- }
- else
- update_stmt_if_modified (t);
-}
-
-/* Insert statement (or statement list) T before the statement
- pointed-to by iterator I. M specifies how to update iterator I
- after insertion (see enum bsi_iterator_update). */
-
-void
-bsi_insert_before (block_stmt_iterator *i, tree t, enum bsi_iterator_update m)
-{
- set_bb_for_stmt (t, i->bb);
- update_modified_stmts (t);
- tsi_link_before (&i->tsi, t, m);
-}
-
-
-/* Insert statement (or statement list) T after the statement
- pointed-to by iterator I. M specifies how to update iterator I
- after insertion (see enum bsi_iterator_update). */
-
-void
-bsi_insert_after (block_stmt_iterator *i, tree t, enum bsi_iterator_update m)
-{
- set_bb_for_stmt (t, i->bb);
- update_modified_stmts (t);
- tsi_link_after (&i->tsi, t, m);
-}
-
-
-/* Remove the statement pointed to by iterator I. The iterator is updated
- to the next statement.
-
- When REMOVE_EH_INFO is true we remove the statement pointed to by
- iterator I from the EH tables. Otherwise we do not modify the EH
- tables.
-
- Generally, REMOVE_EH_INFO should be true when the statement is going to
- be removed from the IL and not reinserted elsewhere. */
-
-void
-bsi_remove (block_stmt_iterator *i, bool remove_eh_info)
-{
- tree t = bsi_stmt (*i);
- set_bb_for_stmt (t, NULL);
- delink_stmt_imm_use (t);
- tsi_delink (&i->tsi);
- mark_stmt_modified (t);
- if (remove_eh_info)
- {
- remove_stmt_from_eh_region (t);
- gimple_remove_stmt_histograms (cfun, t);
- }
-}
-
-
-/* Move the statement at FROM so it comes right after the statement at TO. */
-
-void
-bsi_move_after (block_stmt_iterator *from, block_stmt_iterator *to)
-{
- tree stmt = bsi_stmt (*from);
- bsi_remove (from, false);
- /* We must have BSI_NEW_STMT here, as bsi_move_after is sometimes used to
- move statements to an empty block. */
- bsi_insert_after (to, stmt, BSI_NEW_STMT);
-}
-
-
-/* Move the statement at FROM so it comes right before the statement at TO. */
-
-void
-bsi_move_before (block_stmt_iterator *from, block_stmt_iterator *to)
-{
- tree stmt = bsi_stmt (*from);
- bsi_remove (from, false);
- /* For consistency with bsi_move_after, it might be better to have
- BSI_NEW_STMT here; however, that breaks several places that expect
- that TO does not change. */
- bsi_insert_before (to, stmt, BSI_SAME_STMT);
-}
-
-
-/* Move the statement at FROM to the end of basic block BB. */
-
-void
-bsi_move_to_bb_end (block_stmt_iterator *from, basic_block bb)
-{
- block_stmt_iterator last = bsi_last (bb);
-
- /* Have to check bsi_end_p because it could be an empty block. */
- if (!bsi_end_p (last) && is_ctrl_stmt (bsi_stmt (last)))
- bsi_move_before (from, &last);
- else
- bsi_move_after (from, &last);
-}
-
-
-/* Replace the contents of the statement pointed to by iterator BSI
- with STMT. If UPDATE_EH_INFO is true, the exception handling
- information of the original statement is moved to the new statement. */
-
-void
-bsi_replace (const block_stmt_iterator *bsi, tree stmt, bool update_eh_info)
-{
- int eh_region;
- tree orig_stmt = bsi_stmt (*bsi);
-
- if (stmt == orig_stmt)
- return;
- SET_EXPR_LOCUS (stmt, EXPR_LOCUS (orig_stmt));
- set_bb_for_stmt (stmt, bsi->bb);
-
- /* Preserve EH region information from the original statement, if
- requested by the caller. */
- if (update_eh_info)
- {
- eh_region = lookup_stmt_eh_region (orig_stmt);
- if (eh_region >= 0)
- {
- remove_stmt_from_eh_region (orig_stmt);
- add_stmt_to_eh_region (stmt, eh_region);
- }
- }
-
- gimple_duplicate_stmt_histograms (cfun, stmt, cfun, orig_stmt);
- gimple_remove_stmt_histograms (cfun, orig_stmt);
- delink_stmt_imm_use (orig_stmt);
- *bsi_stmt_ptr (*bsi) = stmt;
- mark_stmt_modified (stmt);
- update_modified_stmts (stmt);
-}
-
-
-/* Insert the statement pointed-to by BSI into edge E. Every attempt
- is made to place the statement in an existing basic block, but
- sometimes that isn't possible. When it isn't possible, the edge is
- split and the statement is added to the new block.
-
- In all cases, the returned *BSI points to the correct location. The
- return value is true if insertion should be done after the location,
- or false if it should be done before the location. If new basic block
- has to be created, it is stored in *NEW_BB. */
-
-static bool
-tree_find_edge_insert_loc (edge e, block_stmt_iterator *bsi,
- basic_block *new_bb)
-{
- basic_block dest, src;
- tree tmp;
-
- dest = e->dest;
- restart:
-
- /* If the destination has one predecessor which has no PHI nodes,
- insert there. Except for the exit block.
-
- The requirement for no PHI nodes could be relaxed. Basically we
- would have to examine the PHIs to prove that none of them used
- the value set by the statement we want to insert on E. That
- hardly seems worth the effort. */
- if (single_pred_p (dest)
- && ! phi_nodes (dest)
- && dest != EXIT_BLOCK_PTR)
- {
- *bsi = bsi_start (dest);
- if (bsi_end_p (*bsi))
- return true;
-
- /* Make sure we insert after any leading labels. */
- tmp = bsi_stmt (*bsi);
- while (TREE_CODE (tmp) == LABEL_EXPR)
- {
- bsi_next (bsi);
- if (bsi_end_p (*bsi))
- break;
- tmp = bsi_stmt (*bsi);
- }
-
- if (bsi_end_p (*bsi))
- {
- *bsi = bsi_last (dest);
- return true;
- }
- else
- return false;
- }
-
- /* If the source has one successor, the edge is not abnormal and
- the last statement does not end a basic block, insert there.
- Except for the entry block. */
- src = e->src;
- if ((e->flags & EDGE_ABNORMAL) == 0
- && single_succ_p (src)
- && src != ENTRY_BLOCK_PTR)
- {
- *bsi = bsi_last (src);
- if (bsi_end_p (*bsi))
- return true;
-
- tmp = bsi_stmt (*bsi);
- if (!stmt_ends_bb_p (tmp))
- return true;
-
- /* Insert code just before returning the value. We may need to decompose
- the return in the case it contains non-trivial operand. */
- if (TREE_CODE (tmp) == RETURN_EXPR)
- {
- tree op = TREE_OPERAND (tmp, 0);
- if (op && !is_gimple_val (op))
- {
- gcc_assert (TREE_CODE (op) == GIMPLE_MODIFY_STMT);
- bsi_insert_before (bsi, op, BSI_NEW_STMT);
- TREE_OPERAND (tmp, 0) = GIMPLE_STMT_OPERAND (op, 0);
- }
- bsi_prev (bsi);
- return true;
- }
- }
-
- /* Otherwise, create a new basic block, and split this edge. */
- dest = split_edge (e);
- if (new_bb)
- *new_bb = dest;
- e = single_pred_edge (dest);
- goto restart;
-}
-
-
-/* This routine will commit all pending edge insertions, creating any new
- basic blocks which are necessary. */
-
-void
-bsi_commit_edge_inserts (void)
-{
- basic_block bb;
- edge e;
- edge_iterator ei;
-
- bsi_commit_one_edge_insert (single_succ_edge (ENTRY_BLOCK_PTR), NULL);
-
- FOR_EACH_BB (bb)
- FOR_EACH_EDGE (e, ei, bb->succs)
- bsi_commit_one_edge_insert (e, NULL);
-}
-
-
-/* Commit insertions pending at edge E. If a new block is created, set NEW_BB
- to this block, otherwise set it to NULL. */
-
-void
-bsi_commit_one_edge_insert (edge e, basic_block *new_bb)
-{
- if (new_bb)
- *new_bb = NULL;
- if (PENDING_STMT (e))
- {
- block_stmt_iterator bsi;
- tree stmt = PENDING_STMT (e);
-
- PENDING_STMT (e) = NULL_TREE;
-
- if (tree_find_edge_insert_loc (e, &bsi, new_bb))
- bsi_insert_after (&bsi, stmt, BSI_NEW_STMT);
- else
- bsi_insert_before (&bsi, stmt, BSI_NEW_STMT);
- }
-}
-
-
-/* Add STMT to the pending list of edge E. No actual insertion is
- made until a call to bsi_commit_edge_inserts () is made. */
-
-void
-bsi_insert_on_edge (edge e, tree stmt)
-{
- append_to_statement_list (stmt, &PENDING_STMT (e));
-}
-
-/* Similar to bsi_insert_on_edge+bsi_commit_edge_inserts. If a new
- block has to be created, it is returned. */
-
-basic_block
-bsi_insert_on_edge_immediate (edge e, tree stmt)
-{
- block_stmt_iterator bsi;
- basic_block new_bb = NULL;
-
- gcc_assert (!PENDING_STMT (e));
-
- if (tree_find_edge_insert_loc (e, &bsi, &new_bb))
- bsi_insert_after (&bsi, stmt, BSI_NEW_STMT);
- else
- bsi_insert_before (&bsi, stmt, BSI_NEW_STMT);
-
- return new_bb;
+ return NULL;
}
-/*---------------------------------------------------------------------------
- Tree specific functions for CFG manipulation
----------------------------------------------------------------------------*/
-
/* Reinstall those PHI arguments queued in OLD_EDGE to NEW_EDGE. */
static void
reinstall_phi_args (edge new_edge, edge old_edge)
{
- tree phi;
edge_var_map_vector v;
edge_var_map *vm;
int i;
-
+ gimple_stmt_iterator phis;
+
v = redirect_edge_var_map_vector (old_edge);
if (!v)
return;
-
- for (i = 0, phi = phi_nodes (new_edge->dest);
- VEC_iterate (edge_var_map, v, i, vm) && phi;
- i++, phi = PHI_CHAIN (phi))
+
+ for (i = 0, phis = gsi_start_phis (new_edge->dest);
+ VEC_iterate (edge_var_map, v, i, vm) && !gsi_end_p (phis);
+ i++, gsi_next (&phis))
{
+ gimple phi = gsi_stmt (phis);
tree result = redirect_edge_var_map_result (vm);
tree arg = redirect_edge_var_map_def (vm);
-
- gcc_assert (result == PHI_RESULT (phi));
-
+
+ gcc_assert (result == gimple_phi_result (phi));
+
add_phi_arg (phi, arg, new_edge);
}
-
+
redirect_edge_var_map_clear (old_edge);
}
@@ -3131,7 +2737,7 @@ split_edge_bb_loc (edge edge_in)
Abort on abnormal edges. */
static basic_block
-tree_split_edge (edge edge_in)
+gimple_split_edge (edge edge_in)
{
basic_block new_bb, after_bb, dest;
edge new_edge, e;
@@ -3194,10 +2800,7 @@ verify_expr (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
break;
case MODIFY_EXPR:
- gcc_unreachable ();
-
- case GIMPLE_MODIFY_STMT:
- x = GIMPLE_STMT_OPERAND (t, 0);
+ x = TREE_OPERAND (t, 0);
if (TREE_CODE (x) == BIT_FIELD_REF
&& is_gimple_reg (TREE_OPERAND (x, 0)))
{
@@ -3420,74 +3023,12 @@ verify_expr (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
#undef CHECK_OP
}
-/* Verifies if EXPR is a valid GIMPLE unary expression. Returns true
- if there is an error, otherwise false. */
-
-static bool
-verify_gimple_unary_expr (const_tree expr)
-{
- tree op = TREE_OPERAND (expr, 0);
- tree type = TREE_TYPE (expr);
-
- if (!is_gimple_val (op))
- {
- error ("invalid operand in unary expression");
- return true;
- }
-
- /* For general unary expressions we have the operations type
- as the effective type the operation is carried out on. So all
- we need to require is that the operand is trivially convertible
- to that type. */
- if (!useless_type_conversion_p (type, TREE_TYPE (op)))
- {
- error ("type mismatch in unary expression");
- debug_generic_expr (type);
- debug_generic_expr (TREE_TYPE (op));
- return true;
- }
-
- return false;
-}
-
-/* Verifies if EXPR is a valid GIMPLE binary expression. Returns true
- if there is an error, otherwise false. */
-
-static bool
-verify_gimple_binary_expr (const_tree expr)
-{
- tree op0 = TREE_OPERAND (expr, 0);
- tree op1 = TREE_OPERAND (expr, 1);
- tree type = TREE_TYPE (expr);
-
- if (!is_gimple_val (op0) || !is_gimple_val (op1))
- {
- error ("invalid operands in binary expression");
- return true;
- }
-
- /* For general binary expressions we have the operations type
- as the effective type the operation is carried out on. So all
- we need to require is that both operands are trivially convertible
- to that type. */
- if (!useless_type_conversion_p (type, TREE_TYPE (op0))
- || !useless_type_conversion_p (type, TREE_TYPE (op1)))
- {
- error ("type mismatch in binary expression");
- debug_generic_stmt (type);
- debug_generic_stmt (TREE_TYPE (op0));
- debug_generic_stmt (TREE_TYPE (op1));
- return true;
- }
-
- return false;
-}
/* Verify if EXPR is either a GIMPLE ID or a GIMPLE indirect reference.
Returns true if there is an error, otherwise false. */
static bool
-verify_gimple_min_lval (tree expr)
+verify_types_in_gimple_min_lval (tree expr)
{
tree op;
@@ -3525,7 +3066,7 @@ verify_gimple_min_lval (tree expr)
if there is an error, otherwise false. */
static bool
-verify_gimple_reference (tree expr)
+verify_types_in_gimple_reference (tree expr)
{
while (handled_component_p (expr))
{
@@ -3594,7 +3135,7 @@ verify_gimple_reference (tree expr)
expr = op;
}
- return verify_gimple_min_lval (expr);
+ return verify_types_in_gimple_min_lval (expr);
}
/* Returns true if there is one pointer type in TYPE_POINTER_TO (SRC_OBJ)
@@ -3627,59 +3168,123 @@ valid_fixed_convert_types_p (tree type1, tree type2)
|| FIXED_POINT_TYPE_P (type2)));
}
-/* Verify the GIMPLE expression EXPR. Returns true if there is an
- error, otherwise false. */
+/* Verify that OP is a valid GIMPLE operand. Return true if there is
+ an error, false otherwise. */
static bool
-verify_gimple_expr (tree expr)
+verify_types_in_gimple_op (tree op)
{
- tree type = TREE_TYPE (expr);
+ if (!is_gimple_val (op) && !is_gimple_lvalue (op))
+ {
+ error ("Invalid GIMPLE operand");
+ debug_generic_expr (op);
+ return true;
+ }
- if (is_gimple_val (expr))
- return false;
+ return false;
+}
+
+
+/* Verify the contents of a GIMPLE_CALL STMT. Returns true when there
+ is a problem, otherwise false. */
+
+static bool
+verify_types_in_gimple_call (gimple stmt)
+{
+ bool failed = false;
+ unsigned int i;
+ tree fn;
+
+ if (gimple_call_lhs (stmt))
+ failed |= verify_types_in_gimple_op (gimple_call_lhs (stmt));
+
+ fn = gimple_call_fn (stmt);
+ if (TREE_CODE (fn) != OBJ_TYPE_REF
+ && verify_types_in_gimple_op (fn))
+ failed = true;
+
+ if (gimple_call_chain (stmt))
+ failed |= verify_types_in_gimple_op (gimple_call_chain (stmt));
+
+ for (i = 0; i < gimple_call_num_args (stmt); i++)
+ failed |= verify_types_in_gimple_op (gimple_call_arg (stmt,i));
+
+ return failed;
+}
+
+
+/* Verify the contents of a GIMPLE_COND STMT. Returns true when there
+ is a problem, otherwise false. */
+
+static bool
+verify_types_in_gimple_cond (gimple stmt)
+{
+ bool failed = false;
+
+ failed |= verify_types_in_gimple_op (gimple_cond_lhs (stmt));
+ failed |= verify_types_in_gimple_op (gimple_cond_rhs (stmt));
+ failed |= verify_types_in_gimple_op (gimple_cond_true_label (stmt));
+ failed |= verify_types_in_gimple_op (gimple_cond_false_label (stmt));
+
+ return failed;
+}
+
+
+/* Verify the contents of a GIMPLE_ASSIGN STMT. Returns true when there
+ is a problem, otherwise false.
+
+ Verify that the types of the LHS and the RHS operands are
+ compatible. This verification largely depends on what kind of
+ operation is done on the RHS of the assignment. It is not always
+ the case that all the types of the operands must match (e.g., 'a =
+ (unsigned long) b' or 'ptr = ptr + 1'). */
+
+static bool
+verify_types_in_gimple_assign (gimple stmt)
+{
+ enum tree_code rhs_code = gimple_assign_rhs_code (stmt);
+ tree lhs = gimple_assign_lhs (stmt);
+ tree rhs1 = gimple_assign_rhs1 (stmt);
+ tree rhs2 = (gimple_num_ops (stmt) == 3) ? gimple_assign_rhs2 (stmt) : NULL;
+ tree lhs_type = TREE_TYPE (lhs);
+ tree rhs1_type = TREE_TYPE (rhs1);
+ tree rhs2_type = (rhs2) ? TREE_TYPE (rhs2) : NULL;
/* Special codes we cannot handle via their class. */
- switch (TREE_CODE (expr))
+ switch (rhs_code)
{
CASE_CONVERT:
{
- tree op = TREE_OPERAND (expr, 0);
- if (!is_gimple_val (op))
+ if (!is_gimple_val (rhs1))
{
error ("invalid operand in conversion");
return true;
}
- /* Allow conversions between integral types and between
- pointer types. */
- if ((INTEGRAL_TYPE_P (type) && INTEGRAL_TYPE_P (TREE_TYPE (op)))
- || (POINTER_TYPE_P (type) && POINTER_TYPE_P (TREE_TYPE (op))))
- return false;
-
/* Allow conversions between integral types and pointers only if
there is no sign or zero extension involved. */
- if (((POINTER_TYPE_P (type) && INTEGRAL_TYPE_P (TREE_TYPE (op)))
- || (POINTER_TYPE_P (TREE_TYPE (op)) && INTEGRAL_TYPE_P (type)))
- && (TYPE_PRECISION (type) == TYPE_PRECISION (TREE_TYPE (op))
+ if (((POINTER_TYPE_P (lhs_type) && INTEGRAL_TYPE_P (rhs1_type))
+ || (POINTER_TYPE_P (rhs1_type) && INTEGRAL_TYPE_P (lhs_type)))
+ && (TYPE_PRECISION (lhs_type) == TYPE_PRECISION (rhs1_type)
/* For targets were the precision of sizetype doesn't
match that of pointers we need the following. */
- || type == sizetype || TREE_TYPE (op) == sizetype))
+ || lhs_type == sizetype || rhs1_type == sizetype))
return false;
/* Allow conversion from integer to offset type and vice versa. */
- if ((TREE_CODE (type) == OFFSET_TYPE
- && TREE_CODE (TREE_TYPE (op)) == INTEGER_TYPE)
- || (TREE_CODE (type) == INTEGER_TYPE
- && TREE_CODE (TREE_TYPE (op)) == OFFSET_TYPE))
+ if ((TREE_CODE (lhs_type) == OFFSET_TYPE
+ && TREE_CODE (rhs1_type) == INTEGER_TYPE)
+ || (TREE_CODE (lhs_type) == INTEGER_TYPE
+ && TREE_CODE (rhs1_type) == OFFSET_TYPE))
return false;
/* Otherwise assert we are converting between types of the
same kind. */
- if (TREE_CODE (type) != TREE_CODE (TREE_TYPE (op)))
+ if (INTEGRAL_TYPE_P (lhs_type) != INTEGRAL_TYPE_P (rhs1_type))
{
error ("invalid types in nop conversion");
- debug_generic_expr (type);
- debug_generic_expr (TREE_TYPE (op));
+ debug_generic_expr (lhs_type);
+ debug_generic_expr (rhs1_type);
return true;
}
@@ -3688,19 +3293,18 @@ verify_gimple_expr (tree expr)
case FIXED_CONVERT_EXPR:
{
- tree op = TREE_OPERAND (expr, 0);
- if (!is_gimple_val (op))
+ if (!is_gimple_val (rhs1))
{
error ("invalid operand in conversion");
return true;
}
- if (!valid_fixed_convert_types_p (type, TREE_TYPE (op))
- && !valid_fixed_convert_types_p (TREE_TYPE (op), type))
+ if (!valid_fixed_convert_types_p (lhs_type, rhs1_type)
+ && !valid_fixed_convert_types_p (rhs1_type, lhs_type))
{
error ("invalid types in fixed-point conversion");
- debug_generic_expr (type);
- debug_generic_expr (TREE_TYPE (op));
+ debug_generic_expr (lhs_type);
+ debug_generic_expr (rhs1_type);
return true;
}
@@ -3709,79 +3313,70 @@ verify_gimple_expr (tree expr)
case FLOAT_EXPR:
{
- tree op = TREE_OPERAND (expr, 0);
- if (!is_gimple_val (op))
+ if (!is_gimple_val (rhs1))
{
error ("invalid operand in int to float conversion");
return true;
}
- if (!INTEGRAL_TYPE_P (TREE_TYPE (op))
- || !SCALAR_FLOAT_TYPE_P (type))
+
+ if (!INTEGRAL_TYPE_P (rhs1_type) || !SCALAR_FLOAT_TYPE_P (lhs_type))
{
error ("invalid types in conversion to floating point");
- debug_generic_expr (type);
- debug_generic_expr (TREE_TYPE (op));
+ debug_generic_expr (lhs_type);
+ debug_generic_expr (rhs1_type);
return true;
}
+
return false;
}
case FIX_TRUNC_EXPR:
{
- tree op = TREE_OPERAND (expr, 0);
- if (!is_gimple_val (op))
+ if (!is_gimple_val (rhs1))
{
error ("invalid operand in float to int conversion");
return true;
}
- if (!INTEGRAL_TYPE_P (type)
- || !SCALAR_FLOAT_TYPE_P (TREE_TYPE (op)))
+
+ if (!INTEGRAL_TYPE_P (lhs_type) || !SCALAR_FLOAT_TYPE_P (rhs1_type))
{
error ("invalid types in conversion to integer");
- debug_generic_expr (type);
- debug_generic_expr (TREE_TYPE (op));
+ debug_generic_expr (lhs_type);
+ debug_generic_expr (rhs1_type);
return true;
}
+
return false;
}
case COMPLEX_EXPR:
{
- tree op0 = TREE_OPERAND (expr, 0);
- tree op1 = TREE_OPERAND (expr, 1);
- if (!is_gimple_val (op0) || !is_gimple_val (op1))
+ if (!is_gimple_val (rhs1) || !is_gimple_val (rhs2))
{
error ("invalid operands in complex expression");
return true;
}
- if (!TREE_CODE (type) == COMPLEX_TYPE
- || !(TREE_CODE (TREE_TYPE (op0)) == INTEGER_TYPE
- || SCALAR_FLOAT_TYPE_P (TREE_TYPE (op0)))
- || !(TREE_CODE (TREE_TYPE (op1)) == INTEGER_TYPE
- || SCALAR_FLOAT_TYPE_P (TREE_TYPE (op1)))
- || !useless_type_conversion_p (TREE_TYPE (type),
- TREE_TYPE (op0))
- || !useless_type_conversion_p (TREE_TYPE (type),
- TREE_TYPE (op1)))
+
+ if (!TREE_CODE (lhs_type) == COMPLEX_TYPE
+ || !(TREE_CODE (rhs1_type) == INTEGER_TYPE
+ || SCALAR_FLOAT_TYPE_P (rhs1_type))
+ || !(TREE_CODE (rhs2_type) == INTEGER_TYPE
+ || SCALAR_FLOAT_TYPE_P (rhs2_type)))
{
error ("type mismatch in complex expression");
- debug_generic_stmt (TREE_TYPE (expr));
- debug_generic_stmt (TREE_TYPE (op0));
- debug_generic_stmt (TREE_TYPE (op1));
+ debug_generic_expr (lhs_type);
+ debug_generic_expr (rhs1_type);
+ debug_generic_expr (rhs2_type);
return true;
}
+
return false;
}
case CONSTRUCTOR:
{
- /* This is used like COMPLEX_EXPR but for vectors. */
- if (TREE_CODE (type) != VECTOR_TYPE)
- {
- error ("constructor not allowed for non-vector types");
- debug_generic_stmt (type);
- return true;
- }
+ /* In this context we know that we are on the RHS of an
+ assignment, so CONSTRUCTOR operands are OK. */
/* FIXME: verify constructor arguments. */
return false;
}
@@ -3791,113 +3386,83 @@ verify_gimple_expr (tree expr)
case LROTATE_EXPR:
case RROTATE_EXPR:
{
- tree op0 = TREE_OPERAND (expr, 0);
- tree op1 = TREE_OPERAND (expr, 1);
- if (!is_gimple_val (op0) || !is_gimple_val (op1))
+ if (!is_gimple_val (rhs1) || !is_gimple_val (rhs2))
{
error ("invalid operands in shift expression");
return true;
}
- if (!TREE_CODE (TREE_TYPE (op1)) == INTEGER_TYPE
- || !useless_type_conversion_p (type, TREE_TYPE (op0)))
+
+ if (!TREE_CODE (rhs1_type) == INTEGER_TYPE
+ || !useless_type_conversion_p (lhs_type, rhs1_type))
{
error ("type mismatch in shift expression");
- debug_generic_stmt (TREE_TYPE (expr));
- debug_generic_stmt (TREE_TYPE (op0));
- debug_generic_stmt (TREE_TYPE (op1));
+ debug_generic_expr (lhs_type);
+ debug_generic_expr (rhs1_type);
+ debug_generic_expr (rhs2_type);
return true;
}
+
return false;
}
case PLUS_EXPR:
case MINUS_EXPR:
{
- tree op0 = TREE_OPERAND (expr, 0);
- tree op1 = TREE_OPERAND (expr, 1);
- if (POINTER_TYPE_P (type)
- || POINTER_TYPE_P (TREE_TYPE (op0))
- || POINTER_TYPE_P (TREE_TYPE (op1)))
+ if (POINTER_TYPE_P (lhs_type)
+ || POINTER_TYPE_P (rhs1_type)
+ || POINTER_TYPE_P (rhs2_type))
{
error ("invalid (pointer) operands to plus/minus");
return true;
}
+
/* Continue with generic binary expression handling. */
break;
}
case POINTER_PLUS_EXPR:
{
- tree op0 = TREE_OPERAND (expr, 0);
- tree op1 = TREE_OPERAND (expr, 1);
- if (!is_gimple_val (op0) || !is_gimple_val (op1))
+ if (!is_gimple_val (rhs1) || !is_gimple_val (rhs2))
{
error ("invalid operands in pointer plus expression");
return true;
}
- if (!POINTER_TYPE_P (TREE_TYPE (op0))
- || !useless_type_conversion_p (type, TREE_TYPE (op0))
- || !useless_type_conversion_p (sizetype, TREE_TYPE (op1)))
+ if (!POINTER_TYPE_P (rhs1_type)
+ || !useless_type_conversion_p (lhs_type, rhs1_type)
+ || !useless_type_conversion_p (sizetype, rhs2_type))
{
error ("type mismatch in pointer plus expression");
- debug_generic_stmt (type);
- debug_generic_stmt (TREE_TYPE (op0));
- debug_generic_stmt (TREE_TYPE (op1));
+ debug_generic_stmt (lhs_type);
+ debug_generic_stmt (rhs1_type);
+ debug_generic_stmt (rhs2_type);
return true;
}
- return false;
- }
- case COND_EXPR:
- {
- tree op0 = TREE_OPERAND (expr, 0);
- tree op1 = TREE_OPERAND (expr, 1);
- tree op2 = TREE_OPERAND (expr, 2);
- if ((!is_gimple_val (op1)
- && TREE_CODE (TREE_TYPE (op1)) != VOID_TYPE)
- || (!is_gimple_val (op2)
- && TREE_CODE (TREE_TYPE (op2)) != VOID_TYPE))
- {
- error ("invalid operands in conditional expression");
- return true;
- }
- if (!INTEGRAL_TYPE_P (TREE_TYPE (op0))
- || (TREE_CODE (TREE_TYPE (op1)) != VOID_TYPE
- && !useless_type_conversion_p (type, TREE_TYPE (op1)))
- || (TREE_CODE (TREE_TYPE (op2)) != VOID_TYPE
- && !useless_type_conversion_p (type, TREE_TYPE (op2))))
- {
- error ("type mismatch in conditional expression");
- debug_generic_stmt (type);
- debug_generic_stmt (TREE_TYPE (op0));
- debug_generic_stmt (TREE_TYPE (op1));
- debug_generic_stmt (TREE_TYPE (op2));
- return true;
- }
- return verify_gimple_expr (op0);
- }
+ return false;
+ }
case ADDR_EXPR:
{
- tree op = TREE_OPERAND (expr, 0);
+ tree op = TREE_OPERAND (rhs1, 0);
if (!is_gimple_addressable (op))
{
error ("invalid operand in unary expression");
return true;
}
- if (!one_pointer_to_useless_type_conversion_p (type, TREE_TYPE (op))
+
+ if (!one_pointer_to_useless_type_conversion_p (lhs_type, TREE_TYPE (op))
/* FIXME: a longstanding wart, &a == &a[0]. */
&& (TREE_CODE (TREE_TYPE (op)) != ARRAY_TYPE
- || !one_pointer_to_useless_type_conversion_p (type,
+ || !one_pointer_to_useless_type_conversion_p (lhs_type,
TREE_TYPE (TREE_TYPE (op)))))
{
error ("type mismatch in address expression");
- debug_generic_stmt (TREE_TYPE (expr));
+ debug_generic_stmt (lhs_type);
debug_generic_stmt (TYPE_POINTER_TO (TREE_TYPE (op)));
return true;
}
- return verify_gimple_reference (op);
+ return verify_types_in_gimple_reference (TREE_OPERAND (rhs1, 0));
}
case TRUTH_ANDIF_EXPR:
@@ -3908,24 +3473,21 @@ verify_gimple_expr (tree expr)
case TRUTH_OR_EXPR:
case TRUTH_XOR_EXPR:
{
- tree op0 = TREE_OPERAND (expr, 0);
- tree op1 = TREE_OPERAND (expr, 1);
-
- if (!is_gimple_val (op0) || !is_gimple_val (op1))
+ if (!is_gimple_val (rhs1) || !is_gimple_val (rhs2))
{
error ("invalid operands in truth expression");
return true;
}
/* We allow any kind of integral typed argument and result. */
- if (!INTEGRAL_TYPE_P (TREE_TYPE (op0))
- || !INTEGRAL_TYPE_P (TREE_TYPE (op1))
- || !INTEGRAL_TYPE_P (type))
+ if (!INTEGRAL_TYPE_P (rhs1_type)
+ || !INTEGRAL_TYPE_P (rhs2_type)
+ || !INTEGRAL_TYPE_P (lhs_type))
{
error ("type mismatch in binary truth expression");
- debug_generic_stmt (type);
- debug_generic_stmt (TREE_TYPE (op0));
- debug_generic_stmt (TREE_TYPE (op1));
+ debug_generic_expr (lhs_type);
+ debug_generic_expr (rhs1_type);
+ debug_generic_expr (rhs2_type);
return true;
}
@@ -3934,9 +3496,7 @@ verify_gimple_expr (tree expr)
case TRUTH_NOT_EXPR:
{
- tree op = TREE_OPERAND (expr, 0);
-
- if (!is_gimple_val (op))
+ if (!is_gimple_val (rhs1))
{
error ("invalid operand in unary not");
return true;
@@ -3944,33 +3504,37 @@ verify_gimple_expr (tree expr)
/* For TRUTH_NOT_EXPR we can have any kind of integral
typed arguments and results. */
- if (!INTEGRAL_TYPE_P (TREE_TYPE (op))
- || !INTEGRAL_TYPE_P (type))
+ if (!INTEGRAL_TYPE_P (rhs1_type)
+ || !INTEGRAL_TYPE_P (lhs_type))
{
error ("type mismatch in not expression");
- debug_generic_expr (TREE_TYPE (expr));
- debug_generic_expr (TREE_TYPE (op));
+ debug_generic_expr (lhs_type);
+ debug_generic_expr (rhs1_type);
return true;
}
return false;
}
+ /* After gimplification we should not have any of these. */
+ case ASM_EXPR:
+ case BIND_EXPR:
case CALL_EXPR:
- /* FIXME. The C frontend passes unpromoted arguments in case it
- didn't see a function declaration before the call. */
+ case COND_EXPR:
+ case TREE_LIST:
+ case COMPOUND_EXPR:
+ case MODIFY_EXPR:
+ case INIT_EXPR:
+ case GOTO_EXPR:
+ case LABEL_EXPR:
+ case RETURN_EXPR:
+ case TRY_FINALLY_EXPR:
+ case TRY_CATCH_EXPR:
+ case EH_FILTER_EXPR:
+ case STATEMENT_LIST:
{
- tree decl = CALL_EXPR_FN (expr);
-
- if (TREE_CODE (decl) == FUNCTION_DECL
- && DECL_LOOPING_CONST_OR_PURE_P (decl)
- && (!DECL_PURE_P (decl))
- && (!TREE_READONLY (decl)))
- {
- error ("invalid pure const state for function");
- return true;
- }
- return false;
+ error ("tree node that should already be gimple.");
+ return true;
}
case OBJ_TYPE_REF:
@@ -3981,26 +3545,29 @@ verify_gimple_expr (tree expr)
}
/* Generic handling via classes. */
- switch (TREE_CODE_CLASS (TREE_CODE (expr)))
+ switch (TREE_CODE_CLASS (rhs_code))
{
case tcc_unary:
- return verify_gimple_unary_expr (expr);
-
- case tcc_binary:
- return verify_gimple_binary_expr (expr);
+ if (!useless_type_conversion_p (lhs_type, rhs1_type))
+ {
+ error ("non-trivial conversion at assignment");
+ debug_generic_expr (lhs);
+ debug_generic_expr (rhs1);
+ return true;
+ }
+ break;
case tcc_reference:
- return verify_gimple_reference (expr);
+ return verify_types_in_gimple_reference (rhs1);
case tcc_comparison:
{
- tree op0 = TREE_OPERAND (expr, 0);
- tree op1 = TREE_OPERAND (expr, 1);
- if (!is_gimple_val (op0) || !is_gimple_val (op1))
+ if (!is_gimple_val (rhs1) || !is_gimple_val (rhs2))
{
error ("invalid operands in comparison expression");
return true;
}
+
/* For comparisons we do not have the operations type as the
effective type the comparison is carried out in. Instead
we require that either the first operand is trivially
@@ -4008,186 +3575,196 @@ verify_gimple_expr (tree expr)
The resulting type of a comparison may be any integral type.
Because we special-case pointers to void we allow
comparisons of pointers with the same mode as well. */
- if ((!useless_type_conversion_p (TREE_TYPE (op0), TREE_TYPE (op1))
- && !useless_type_conversion_p (TREE_TYPE (op1), TREE_TYPE (op0))
- && (!POINTER_TYPE_P (TREE_TYPE (op0))
- || !POINTER_TYPE_P (TREE_TYPE (op1))
- || TYPE_MODE (TREE_TYPE (op0)) != TYPE_MODE (TREE_TYPE (op1))))
- || !INTEGRAL_TYPE_P (type))
+ if ((!useless_type_conversion_p (rhs1_type, rhs2_type)
+ && !useless_type_conversion_p (rhs2_type, rhs1_type)
+ && (!POINTER_TYPE_P (rhs1_type)
+ || !POINTER_TYPE_P (rhs2_type)
+ || TYPE_MODE (rhs1_type) != TYPE_MODE (rhs2_type)))
+ || !INTEGRAL_TYPE_P (lhs_type))
{
error ("type mismatch in comparison expression");
- debug_generic_stmt (TREE_TYPE (expr));
- debug_generic_stmt (TREE_TYPE (op0));
- debug_generic_stmt (TREE_TYPE (op1));
+ debug_generic_expr (lhs_type);
+ debug_generic_expr (rhs1_type);
+ debug_generic_expr (rhs2_type);
return true;
}
break;
}
- default:
- gcc_unreachable ();
+ default:;
}
return false;
}
-/* Verify the GIMPLE assignment statement STMT. Returns true if there
- is an error, otherwise false. */
+
+/* Verify the contents of a GIMPLE_RETURN STMT. Returns true when there
+ is a problem, otherwise false. */
static bool
-verify_gimple_modify_stmt (const_tree stmt)
+verify_types_in_gimple_return (gimple stmt)
{
- tree lhs = GIMPLE_STMT_OPERAND (stmt, 0);
- tree rhs = GIMPLE_STMT_OPERAND (stmt, 1);
+ tree op = gimple_return_retval (stmt);
+
+ if (op == NULL)
+ return false;
+
+ return verify_types_in_gimple_op (op);
+}
- gcc_assert (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT);
- if (!useless_type_conversion_p (TREE_TYPE (lhs),
- TREE_TYPE (rhs)))
+/* Verify the contents of a GIMPLE_SWITCH STMT. Returns true when there
+ is a problem, otherwise false. */
+
+static bool
+verify_types_in_gimple_switch (gimple stmt)
+{
+ if (!is_gimple_val (gimple_switch_index (stmt)))
{
- error ("non-trivial conversion at assignment");
- debug_generic_expr (TREE_TYPE (lhs));
- debug_generic_expr (TREE_TYPE (rhs));
+ error ("invalid operand to switch statement");
+ debug_generic_expr (gimple_switch_index (stmt));
return true;
}
- /* Loads/stores from/to a variable are ok. */
- if ((is_gimple_val (lhs)
- && is_gimple_variable (rhs))
- || (is_gimple_val (rhs)
- && is_gimple_variable (lhs)))
- return false;
+ return false;
+}
- /* Aggregate copies are ok. */
- if (!is_gimple_reg_type (TREE_TYPE (lhs))
- && !is_gimple_reg_type (TREE_TYPE (rhs)))
- return false;
- /* We might get 'loads' from a parameter which is not a gimple value. */
- if (TREE_CODE (rhs) == PARM_DECL)
- return verify_gimple_expr (lhs);
+/* Verify the contents of a GIMPLE_PHI. Returns true if there is a problem,
+ and false otherwise. */
- if (!is_gimple_variable (lhs)
- && verify_gimple_expr (lhs))
- return true;
+static bool
+verify_types_in_gimple_phi (gimple stmt)
+{
+ size_t i;
- if (!is_gimple_variable (rhs)
- && verify_gimple_expr (rhs))
+ if (verify_types_in_gimple_op (gimple_phi_result (stmt)))
return true;
+ for (i = 0; i < gimple_phi_num_args (stmt); i++)
+ if (verify_types_in_gimple_op (gimple_phi_arg_def (stmt, i)))
+ return true;
+
return false;
}
+
/* Verify the GIMPLE statement STMT. Returns true if there is an
error, otherwise false. */
static bool
-verify_gimple_stmt (tree stmt)
+verify_types_in_gimple_stmt (gimple stmt)
{
- if (!is_gimple_stmt (stmt))
- {
- error ("is not a valid GIMPLE statement");
- return true;
- }
-
- if (OMP_DIRECTIVE_P (stmt))
+ if (is_gimple_omp (stmt))
{
/* OpenMP directives are validated by the FE and never operated
- on by the optimizers. Furthermore, OMP_FOR may contain
+ on by the optimizers. Furthermore, GIMPLE_OMP_FOR may contain
non-gimple expressions when the main index variable has had
its address taken. This does not affect the loop itself
- because the header of an OMP_FOR is merely used to determine
+ because the header of an GIMPLE_OMP_FOR is merely used to determine
how to setup the parallel iteration. */
return false;
}
- switch (TREE_CODE (stmt))
+ switch (gimple_code (stmt))
{
- case GIMPLE_MODIFY_STMT:
- return verify_gimple_modify_stmt (stmt);
+ case GIMPLE_ASSIGN:
+ return verify_types_in_gimple_assign (stmt);
- case GOTO_EXPR:
- case LABEL_EXPR:
- return false;
+ case GIMPLE_LABEL:
+ return TREE_CODE (gimple_label_label (stmt)) != LABEL_DECL;
- case SWITCH_EXPR:
- if (!is_gimple_val (TREE_OPERAND (stmt, 0)))
- {
- error ("invalid operand to switch statement");
- debug_generic_expr (TREE_OPERAND (stmt, 0));
- }
- return false;
+ case GIMPLE_CALL:
+ return verify_types_in_gimple_call (stmt);
- case RETURN_EXPR:
- {
- tree op = TREE_OPERAND (stmt, 0);
+ case GIMPLE_COND:
+ return verify_types_in_gimple_cond (stmt);
- if (TREE_CODE (TREE_TYPE (stmt)) != VOID_TYPE)
- {
- error ("type error in return expression");
- return true;
- }
+ case GIMPLE_GOTO:
+ return verify_types_in_gimple_op (gimple_goto_dest (stmt));
- if (op == NULL_TREE
- || TREE_CODE (op) == RESULT_DECL)
- return false;
+ case GIMPLE_NOP:
+ case GIMPLE_PREDICT:
+ return false;
- return verify_gimple_modify_stmt (op);
- }
+ case GIMPLE_SWITCH:
+ return verify_types_in_gimple_switch (stmt);
- case CALL_EXPR:
- case COND_EXPR:
- return verify_gimple_expr (stmt);
+ case GIMPLE_RETURN:
+ return verify_types_in_gimple_return (stmt);
- case NOP_EXPR:
- case CHANGE_DYNAMIC_TYPE_EXPR:
- case ASM_EXPR:
- case PREDICT_EXPR:
+ case GIMPLE_ASM:
return false;
+ case GIMPLE_CHANGE_DYNAMIC_TYPE:
+ return verify_types_in_gimple_op (gimple_cdt_location (stmt));
+
+ case GIMPLE_PHI:
+ return verify_types_in_gimple_phi (stmt);
+
default:
gcc_unreachable ();
}
}
-/* Verify the GIMPLE statements inside the statement list STMTS.
- Returns true if there were any errors. */
+/* Verify the GIMPLE statements inside the sequence STMTS. */
static bool
-verify_gimple_2 (tree stmts)
+verify_types_in_gimple_seq_2 (gimple_seq stmts)
{
- tree_stmt_iterator tsi;
+ gimple_stmt_iterator ittr;
bool err = false;
- for (tsi = tsi_start (stmts); !tsi_end_p (tsi); tsi_next (&tsi))
+ for (ittr = gsi_start (stmts); !gsi_end_p (ittr); gsi_next (&ittr))
{
- tree stmt = tsi_stmt (tsi);
-
- switch (TREE_CODE (stmt))
- {
- case BIND_EXPR:
- err |= verify_gimple_2 (BIND_EXPR_BODY (stmt));
- break;
+ gimple stmt = gsi_stmt (ittr);
- case TRY_CATCH_EXPR:
- case TRY_FINALLY_EXPR:
- err |= verify_gimple_2 (TREE_OPERAND (stmt, 0));
- err |= verify_gimple_2 (TREE_OPERAND (stmt, 1));
- break;
-
- case CATCH_EXPR:
- err |= verify_gimple_2 (CATCH_BODY (stmt));
- break;
-
- case EH_FILTER_EXPR:
- err |= verify_gimple_2 (EH_FILTER_FAILURE (stmt));
- break;
+ switch (gimple_code (stmt))
+ {
+ case GIMPLE_BIND:
+ err |= verify_types_in_gimple_seq_2 (gimple_bind_body (stmt));
+ break;
+
+ case GIMPLE_TRY:
+ err |= verify_types_in_gimple_seq_2 (gimple_try_eval (stmt));
+ err |= verify_types_in_gimple_seq_2 (gimple_try_cleanup (stmt));
+ break;
+
+ case GIMPLE_EH_FILTER:
+ err |= verify_types_in_gimple_seq_2
+ (gimple_eh_filter_failure (stmt));
+ break;
+
+ case GIMPLE_CATCH:
+ err |= verify_types_in_gimple_seq_2 (gimple_catch_handler (stmt));
+ break;
+
+ case GIMPLE_OMP_CRITICAL:
+ case GIMPLE_OMP_CONTINUE:
+ case GIMPLE_OMP_MASTER:
+ case GIMPLE_OMP_ORDERED:
+ case GIMPLE_OMP_SECTION:
+ case GIMPLE_OMP_FOR:
+ case GIMPLE_OMP_PARALLEL:
+ case GIMPLE_OMP_TASK:
+ case GIMPLE_OMP_SECTIONS:
+ case GIMPLE_OMP_SINGLE:
+ case GIMPLE_OMP_ATOMIC_STORE:
+ case GIMPLE_OMP_ATOMIC_LOAD:
+ break;
+
+ /* Tuples that do not have trees. */
+ case GIMPLE_NOP:
+ case GIMPLE_RESX:
+ case GIMPLE_OMP_RETURN:
+ case GIMPLE_PREDICT:
+ break;
default:
{
- bool err2 = verify_gimple_stmt (stmt);
+ bool err2 = verify_types_in_gimple_stmt (stmt);
if (err2)
- debug_generic_expr (stmt);
+ debug_gimple_stmt (stmt);
err |= err2;
}
}
@@ -4200,54 +3777,58 @@ verify_gimple_2 (tree stmts)
/* Verify the GIMPLE statements inside the statement list STMTS. */
void
-verify_gimple_1 (tree stmts)
+verify_types_in_gimple_seq (gimple_seq stmts)
{
- if (verify_gimple_2 (stmts))
+ if (verify_types_in_gimple_seq_2 (stmts))
internal_error ("verify_gimple failed");
}
-/* Verify the GIMPLE statements inside the current function. */
-
-void
-verify_gimple (void)
-{
- verify_gimple_1 (BIND_EXPR_BODY (DECL_SAVED_TREE (cfun->decl)));
-}
/* Verify STMT, return true if STMT is not in GIMPLE form.
TODO: Implement type checking. */
static bool
-verify_stmt (tree stmt, bool last_in_block)
+verify_stmt (gimple_stmt_iterator *gsi)
{
tree addr;
+ struct walk_stmt_info wi;
+ bool last_in_block = gsi_one_before_end_p (*gsi);
+ gimple stmt = gsi_stmt (*gsi);
- if (OMP_DIRECTIVE_P (stmt))
+ if (is_gimple_omp (stmt))
{
/* OpenMP directives are validated by the FE and never operated
- on by the optimizers. Furthermore, OMP_FOR may contain
+ on by the optimizers. Furthermore, GIMPLE_OMP_FOR may contain
non-gimple expressions when the main index variable has had
its address taken. This does not affect the loop itself
- because the header of an OMP_FOR is merely used to determine
+ because the header of an GIMPLE_OMP_FOR is merely used to determine
how to setup the parallel iteration. */
return false;
}
- if (!is_gimple_stmt (stmt))
+ /* FIXME. The C frontend passes unpromoted arguments in case it
+ didn't see a function declaration before the call. */
+ if (is_gimple_call (stmt))
{
- error ("is not a valid GIMPLE statement");
- goto fail;
+ tree decl = gimple_call_fn (stmt);
+
+ if (TREE_CODE (decl) == FUNCTION_DECL
+ && DECL_LOOPING_CONST_OR_PURE_P (decl)
+ && (!DECL_PURE_P (decl))
+ && (!TREE_READONLY (decl)))
+ {
+ error ("invalid pure const state for function");
+ return true;
+ }
}
- addr = walk_tree (&stmt, verify_expr, NULL, NULL);
+ memset (&wi, 0, sizeof (wi));
+ addr = walk_gimple_op (gsi_stmt (*gsi), verify_expr, &wi);
if (addr)
{
- debug_generic_stmt (addr);
- if (addr != stmt)
- {
- inform ("in statement");
- debug_generic_stmt (stmt);
- }
+ debug_generic_expr (addr);
+ inform ("in statement");
+ debug_gimple_stmt (stmt);
return true;
}
@@ -4258,12 +3839,12 @@ verify_stmt (tree stmt, bool last_in_block)
to match. */
if (lookup_stmt_eh_region (stmt) >= 0)
{
- if (!tree_could_throw_p (stmt))
+ if (!stmt_could_throw_p (stmt))
{
error ("statement marked for throw, but doesn%'t");
goto fail;
}
- if (!last_in_block && tree_can_throw_internal (stmt))
+ if (!last_in_block && stmt_can_throw_internal (stmt))
{
error ("statement marked for throw in middle of block");
goto fail;
@@ -4273,7 +3854,7 @@ verify_stmt (tree stmt, bool last_in_block)
return false;
fail:
- debug_generic_stmt (stmt);
+ debug_gimple_stmt (stmt);
return true;
}
@@ -4307,12 +3888,13 @@ tree_node_can_be_shared (tree t)
}
-/* Called via walk_trees. Verify tree sharing. */
+/* Called via walk_gimple_stmt. Verify tree sharing. */
static tree
-verify_node_sharing (tree * tp, int *walk_subtrees, void *data)
+verify_node_sharing (tree *tp, int *walk_subtrees, void *data)
{
- struct pointer_set_t *visited = (struct pointer_set_t *) data;
+ struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
+ struct pointer_set_t *visited = (struct pointer_set_t *) wi->info;
if (tree_node_can_be_shared (*tp))
{
@@ -4327,35 +3909,6 @@ verify_node_sharing (tree * tp, int *walk_subtrees, void *data)
}
-/* Helper function for verify_gimple_tuples. */
-
-static tree
-verify_gimple_tuples_1 (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
- void *data ATTRIBUTE_UNUSED)
-{
- switch (TREE_CODE (*tp))
- {
- case MODIFY_EXPR:
- error ("unexpected non-tuple");
- debug_tree (*tp);
- gcc_unreachable ();
- return NULL_TREE;
-
- default:
- return NULL_TREE;
- }
-}
-
-/* Verify that there are no trees that should have been converted to
- gimple tuples. Return true if T contains a node that should have
- been converted to a gimple tuple, but hasn't. */
-
-static bool
-verify_gimple_tuples (tree t)
-{
- return walk_tree (&t, verify_gimple_tuples_1, NULL, NULL) != NULL;
-}
-
static bool eh_error_found;
static int
verify_eh_throw_stmt_node (void **slot, void *data)
@@ -4366,52 +3919,56 @@ verify_eh_throw_stmt_node (void **slot, void *data)
if (!pointer_set_contains (visited, node->stmt))
{
error ("Dead STMT in EH table");
- debug_generic_stmt (node->stmt);
+ debug_gimple_stmt (node->stmt);
eh_error_found = true;
}
return 0;
}
-/* Verify the GIMPLE statement chain. */
+
+/* Verify the GIMPLE statements in every basic block. */
void
verify_stmts (void)
{
basic_block bb;
- block_stmt_iterator bsi;
+ gimple_stmt_iterator gsi;
bool err = false;
struct pointer_set_t *visited, *visited_stmts;
tree addr;
+ struct walk_stmt_info wi;
timevar_push (TV_TREE_STMT_VERIFY);
visited = pointer_set_create ();
visited_stmts = pointer_set_create ();
+ memset (&wi, 0, sizeof (wi));
+ wi.info = (void *) visited;
+
FOR_EACH_BB (bb)
{
- tree phi;
- int i;
+ gimple phi;
+ size_t i;
- for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
+ for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
- int phi_num_args = PHI_NUM_ARGS (phi);
-
+ phi = gsi_stmt (gsi);
pointer_set_insert (visited_stmts, phi);
- if (bb_for_stmt (phi) != bb)
+ if (gimple_bb (phi) != bb)
{
- error ("bb_for_stmt (phi) is set to a wrong basic block");
+ error ("gimple_bb (phi) is set to a wrong basic block");
err |= true;
}
- for (i = 0; i < phi_num_args; i++)
+ for (i = 0; i < gimple_phi_num_args (phi); i++)
{
- tree t = PHI_ARG_DEF (phi, i);
+ tree t = gimple_phi_arg_def (phi, i);
tree addr;
if (!t)
{
error ("missing PHI def");
- debug_generic_stmt (phi);
+ debug_gimple_stmt (phi);
err |= true;
continue;
}
@@ -4421,9 +3978,9 @@ verify_stmts (void)
&& TREE_CODE (t) != FUNCTION_DECL
&& !is_gimple_min_invariant (t))
{
- error ("PHI def is not a GIMPLE value");
- debug_generic_stmt (phi);
- debug_generic_stmt (t);
+ error ("PHI argument is not a GIMPLE value");
+ debug_gimple_stmt (phi);
+ debug_generic_expr (t);
err |= true;
}
@@ -4431,38 +3988,59 @@ verify_stmts (void)
if (addr)
{
error ("incorrect sharing of tree nodes");
- debug_generic_stmt (phi);
- debug_generic_stmt (addr);
+ debug_gimple_stmt (phi);
+ debug_generic_expr (addr);
err |= true;
}
}
}
- for (bsi = bsi_start (bb); !bsi_end_p (bsi); )
+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); )
{
- tree stmt = bsi_stmt (bsi);
+ gimple stmt = gsi_stmt (gsi);
+
+ if (gimple_code (stmt) == GIMPLE_WITH_CLEANUP_EXPR
+ || gimple_code (stmt) == GIMPLE_BIND)
+ {
+ error ("invalid GIMPLE statement");
+ debug_gimple_stmt (stmt);
+ err |= true;
+ }
pointer_set_insert (visited_stmts, stmt);
- err |= verify_gimple_tuples (stmt);
- if (bb_for_stmt (stmt) != bb)
+ if (gimple_bb (stmt) != bb)
{
- error ("bb_for_stmt (stmt) is set to a wrong basic block");
+ error ("gimple_bb (stmt) is set to a wrong basic block");
err |= true;
}
- bsi_next (&bsi);
- err |= verify_stmt (stmt, bsi_end_p (bsi));
- addr = walk_tree (&stmt, verify_node_sharing, visited, NULL);
+ if (gimple_code (stmt) == GIMPLE_LABEL)
+ {
+ tree decl = gimple_label_label (stmt);
+ int uid = LABEL_DECL_UID (decl);
+
+ if (uid == -1
+ || VEC_index (basic_block, label_to_block_map, uid) != bb)
+ {
+ error ("incorrect entry in label_to_block_map.\n");
+ err |= true;
+ }
+ }
+
+ err |= verify_stmt (&gsi);
+ addr = walk_gimple_op (gsi_stmt (gsi), verify_node_sharing, &wi);
if (addr)
{
error ("incorrect sharing of tree nodes");
- debug_generic_stmt (stmt);
- debug_generic_stmt (addr);
+ debug_gimple_stmt (stmt);
+ debug_generic_expr (addr);
err |= true;
}
+ gsi_next (&gsi);
}
}
+
eh_error_found = false;
if (get_eh_throw_stmt_table (cfun))
htab_traverse (get_eh_throw_stmt_table (cfun),
@@ -4482,22 +4060,22 @@ verify_stmts (void)
/* Verifies that the flow information is OK. */
static int
-tree_verify_flow_info (void)
+gimple_verify_flow_info (void)
{
int err = 0;
basic_block bb;
- block_stmt_iterator bsi;
- tree stmt;
+ gimple_stmt_iterator gsi;
+ gimple stmt;
edge e;
edge_iterator ei;
- if (ENTRY_BLOCK_PTR->il.tree)
+ if (ENTRY_BLOCK_PTR->il.gimple)
{
error ("ENTRY_BLOCK has IL associated with it");
err = 1;
}
- if (EXIT_BLOCK_PTR->il.tree)
+ if (EXIT_BLOCK_PTR->il.gimple)
{
error ("EXIT_BLOCK has IL associated with it");
err = 1;
@@ -4514,41 +4092,42 @@ tree_verify_flow_info (void)
{
bool found_ctrl_stmt = false;
- stmt = NULL_TREE;
+ stmt = NULL;
/* Skip labels on the start of basic block. */
- for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
- tree prev_stmt = stmt;
+ tree label;
+ gimple prev_stmt = stmt;
- stmt = bsi_stmt (bsi);
+ stmt = gsi_stmt (gsi);
- if (TREE_CODE (stmt) != LABEL_EXPR)
+ if (gimple_code (stmt) != GIMPLE_LABEL)
break;
- if (prev_stmt && DECL_NONLOCAL (LABEL_EXPR_LABEL (stmt)))
+ label = gimple_label_label (stmt);
+ if (prev_stmt && DECL_NONLOCAL (label))
{
error ("nonlocal label ");
- print_generic_expr (stderr, LABEL_EXPR_LABEL (stmt), 0);
+ print_generic_expr (stderr, label, 0);
fprintf (stderr, " is not first in a sequence of labels in bb %d",
bb->index);
err = 1;
}
- if (label_to_block (LABEL_EXPR_LABEL (stmt)) != bb)
+ if (label_to_block (label) != bb)
{
error ("label ");
- print_generic_expr (stderr, LABEL_EXPR_LABEL (stmt), 0);
+ print_generic_expr (stderr, label, 0);
fprintf (stderr, " to block does not match in bb %d",
bb->index);
err = 1;
}
- if (decl_function_context (LABEL_EXPR_LABEL (stmt))
- != current_function_decl)
+ if (decl_function_context (label) != current_function_decl)
{
error ("label ");
- print_generic_expr (stderr, LABEL_EXPR_LABEL (stmt), 0);
+ print_generic_expr (stderr, label, 0);
fprintf (stderr, " has incorrect context in bb %d",
bb->index);
err = 1;
@@ -4556,9 +4135,9 @@ tree_verify_flow_info (void)
}
/* Verify that body of basic block BB is free of control flow. */
- for (; !bsi_end_p (bsi); bsi_next (&bsi))
+ for (; !gsi_end_p (gsi); gsi_next (&gsi))
{
- tree stmt = bsi_stmt (bsi);
+ gimple stmt = gsi_stmt (gsi);
if (found_ctrl_stmt)
{
@@ -4570,20 +4149,20 @@ tree_verify_flow_info (void)
if (stmt_ends_bb_p (stmt))
found_ctrl_stmt = true;
- if (TREE_CODE (stmt) == LABEL_EXPR)
+ if (gimple_code (stmt) == GIMPLE_LABEL)
{
error ("label ");
- print_generic_expr (stderr, LABEL_EXPR_LABEL (stmt), 0);
+ print_generic_expr (stderr, gimple_label_label (stmt), 0);
fprintf (stderr, " in the middle of basic block %d", bb->index);
err = 1;
}
}
- bsi = bsi_last (bb);
- if (bsi_end_p (bsi))
+ gsi = gsi_last_bb (bb);
+ if (gsi_end_p (gsi))
continue;
- stmt = bsi_stmt (bsi);
+ stmt = gsi_stmt (gsi);
err |= verify_eh_edges (stmt);
@@ -4598,37 +4177,30 @@ tree_verify_flow_info (void)
}
}
- if (TREE_CODE (stmt) != COND_EXPR)
+ if (gimple_code (stmt) != GIMPLE_COND)
{
/* Verify that there are no edges with EDGE_TRUE/FALSE_FLAG set
after anything else but if statement. */
FOR_EACH_EDGE (e, ei, bb->succs)
if (e->flags & (EDGE_TRUE_VALUE | EDGE_FALSE_VALUE))
{
- error ("true/false edge after a non-COND_EXPR in bb %d",
+ error ("true/false edge after a non-GIMPLE_COND in bb %d",
bb->index);
err = 1;
}
}
- switch (TREE_CODE (stmt))
+ switch (gimple_code (stmt))
{
- case COND_EXPR:
+ case GIMPLE_COND:
{
edge true_edge;
edge false_edge;
- if (COND_EXPR_THEN (stmt) != NULL_TREE
- || COND_EXPR_ELSE (stmt) != NULL_TREE)
- {
- error ("COND_EXPR with code in branches at the end of bb %d",
- bb->index);
- err = 1;
- }
-
extract_true_false_edges_from_block (bb, &true_edge, &false_edge);
- if (!true_edge || !false_edge
+ if (!true_edge
+ || !false_edge
|| !(true_edge->flags & EDGE_TRUE_VALUE)
|| !(false_edge->flags & EDGE_FALSE_VALUE)
|| (true_edge->flags & (EDGE_FALLTHRU | EDGE_ABNORMAL))
@@ -4642,7 +4214,7 @@ tree_verify_flow_info (void)
}
break;
- case GOTO_EXPR:
+ case GIMPLE_GOTO:
if (simple_goto_p (stmt))
{
error ("explicit goto at end of bb %d", bb->index);
@@ -4664,7 +4236,7 @@ tree_verify_flow_info (void)
}
break;
- case RETURN_EXPR:
+ case GIMPLE_RETURN:
if (!single_succ_p (bb)
|| (single_succ_edge (bb)->flags
& (EDGE_FALLTHRU | EDGE_ABNORMAL
@@ -4681,41 +4253,37 @@ tree_verify_flow_info (void)
}
break;
- case SWITCH_EXPR:
+ case GIMPLE_SWITCH:
{
tree prev;
edge e;
size_t i, n;
- tree vec;
- vec = SWITCH_LABELS (stmt);
- n = TREE_VEC_LENGTH (vec);
+ n = gimple_switch_num_labels (stmt);
/* Mark all the destination basic blocks. */
for (i = 0; i < n; ++i)
{
- tree lab = CASE_LABEL (TREE_VEC_ELT (vec, i));
+ tree lab = CASE_LABEL (gimple_switch_label (stmt, i));
basic_block label_bb = label_to_block (lab);
-
gcc_assert (!label_bb->aux || label_bb->aux == (void *)1);
label_bb->aux = (void *)1;
}
/* Verify that the case labels are sorted. */
- prev = TREE_VEC_ELT (vec, 0);
+ prev = gimple_switch_label (stmt, 0);
for (i = 1; i < n; ++i)
{
- tree c = TREE_VEC_ELT (vec, i);
- if (! CASE_LOW (c))
+ tree c = gimple_switch_label (stmt, i);
+ if (!CASE_LOW (c))
{
- if (i != n - 1)
- {
- error ("found default case not at end of case vector");
- err = 1;
- }
+ error ("found default case not at the start of "
+ "case vector");
+ err = 1;
continue;
}
- if (! tree_int_cst_lt (CASE_LOW (prev), CASE_LOW (c)))
+ if (CASE_LOW (prev)
+ && !tree_int_cst_lt (CASE_LOW (prev), CASE_LOW (c)))
{
error ("case labels not sorted: ");
print_generic_expr (stderr, prev, 0);
@@ -4738,6 +4306,7 @@ tree_verify_flow_info (void)
bb->index, e->dest->index);
err = 1;
}
+
e->dest->aux = (void *)2;
if ((e->flags & (EDGE_FALLTHRU | EDGE_ABNORMAL
| EDGE_TRUE_VALUE | EDGE_FALSE_VALUE)))
@@ -4751,13 +4320,12 @@ tree_verify_flow_info (void)
/* Check that we have all of them. */
for (i = 0; i < n; ++i)
{
- tree lab = CASE_LABEL (TREE_VEC_ELT (vec, i));
+ tree lab = CASE_LABEL (gimple_switch_label (stmt, i));
basic_block label_bb = label_to_block (lab);
if (label_bb->aux != (void *)2)
{
- error ("missing edge %i->%i",
- bb->index, label_bb->index);
+ error ("missing edge %i->%i", bb->index, label_bb->index);
err = 1;
}
}
@@ -4781,12 +4349,13 @@ tree_verify_flow_info (void)
by edge FALLTHRU. */
static void
-tree_make_forwarder_block (edge fallthru)
+gimple_make_forwarder_block (edge fallthru)
{
edge e;
edge_iterator ei;
basic_block dummy, bb;
- tree phi, new_phi, var;
+ tree var;
+ gimple_stmt_iterator gsi;
dummy = fallthru->src;
bb = fallthru->dest;
@@ -4796,18 +4365,18 @@ tree_make_forwarder_block (edge fallthru)
/* If we redirected a branch we must create new PHI nodes at the
start of BB. */
- for (phi = phi_nodes (dummy); phi; phi = PHI_CHAIN (phi))
+ for (gsi = gsi_start_phis (dummy); !gsi_end_p (gsi); gsi_next (&gsi))
{
- var = PHI_RESULT (phi);
+ gimple phi, new_phi;
+
+ phi = gsi_stmt (gsi);
+ var = gimple_phi_result (phi);
new_phi = create_phi_node (var, bb);
SSA_NAME_DEF_STMT (var) = new_phi;
- SET_PHI_RESULT (phi, make_ssa_name (SSA_NAME_VAR (var), phi));
- add_phi_arg (new_phi, PHI_RESULT (phi), fallthru);
+ gimple_phi_set_result (phi, make_ssa_name (SSA_NAME_VAR (var), phi));
+ add_phi_arg (new_phi, gimple_phi_result (phi), fallthru);
}
- /* Ensure that the PHI node chain is in the same order. */
- set_phi_nodes (bb, phi_reverse (phi_nodes (bb)));
-
/* Add the arguments we have stored on edges. */
FOR_EACH_EDGE (e, ei, bb->preds)
{
@@ -4823,29 +4392,30 @@ tree_make_forwarder_block (edge fallthru)
Create one if it doesn't exist. */
tree
-tree_block_label (basic_block bb)
+gimple_block_label (basic_block bb)
{
- block_stmt_iterator i, s = bsi_start (bb);
+ gimple_stmt_iterator i, s = gsi_start_bb (bb);
bool first = true;
- tree label, stmt;
+ tree label;
+ gimple stmt;
- for (i = s; !bsi_end_p (i); first = false, bsi_next (&i))
+ for (i = s; !gsi_end_p (i); first = false, gsi_next (&i))
{
- stmt = bsi_stmt (i);
- if (TREE_CODE (stmt) != LABEL_EXPR)
+ stmt = gsi_stmt (i);
+ if (gimple_code (stmt) != GIMPLE_LABEL)
break;
- label = LABEL_EXPR_LABEL (stmt);
+ label = gimple_label_label (stmt);
if (!DECL_NONLOCAL (label))
{
if (!first)
- bsi_move_before (&i, &s);
+ gsi_move_before (&i, &s);
return label;
}
}
label = create_artificial_label ();
- stmt = build1 (LABEL_EXPR, void_type_node, label);
- bsi_insert_before (&s, stmt, BSI_NEW_STMT);
+ stmt = gimple_build_label (label);
+ gsi_insert_before (&s, stmt, GSI_NEW_STMT);
return label;
}
@@ -4857,11 +4427,11 @@ tree_block_label (basic_block bb)
redirect_edge_and_branch. */
static edge
-tree_try_redirect_by_replacing_jump (edge e, basic_block target)
+gimple_try_redirect_by_replacing_jump (edge e, basic_block target)
{
basic_block src = e->src;
- block_stmt_iterator b;
- tree stmt;
+ gimple_stmt_iterator i;
+ gimple stmt;
/* We can replace or remove a complex jump only when we have exactly
two edges. */
@@ -4871,15 +4441,15 @@ tree_try_redirect_by_replacing_jump (edge e, basic_block target)
|| EDGE_SUCC (src, EDGE_SUCC (src, 0) == e)->dest != target)
return NULL;
- b = bsi_last (src);
- if (bsi_end_p (b))
+ i = gsi_last_bb (src);
+ if (gsi_end_p (i))
return NULL;
- stmt = bsi_stmt (b);
- if (TREE_CODE (stmt) == COND_EXPR
- || TREE_CODE (stmt) == SWITCH_EXPR)
+ stmt = gsi_stmt (i);
+
+ if (gimple_code (stmt) == GIMPLE_COND || gimple_code (stmt) == GIMPLE_SWITCH)
{
- bsi_remove (&b, true);
+ gsi_remove (&i, true);
e = ssa_redirect_edge (e, target);
e->flags = EDGE_FALLTHRU;
return e;
@@ -4893,41 +4463,41 @@ tree_try_redirect_by_replacing_jump (edge e, basic_block target)
edge representing the redirected branch. */
static edge
-tree_redirect_edge_and_branch (edge e, basic_block dest)
+gimple_redirect_edge_and_branch (edge e, basic_block dest)
{
basic_block bb = e->src;
- block_stmt_iterator bsi;
+ gimple_stmt_iterator gsi;
edge ret;
- tree stmt;
+ gimple stmt;
if (e->flags & EDGE_ABNORMAL)
return NULL;
if (e->src != ENTRY_BLOCK_PTR
- && (ret = tree_try_redirect_by_replacing_jump (e, dest)))
+ && (ret = gimple_try_redirect_by_replacing_jump (e, dest)))
return ret;
if (e->dest == dest)
return NULL;
- bsi = bsi_last (bb);
- stmt = bsi_end_p (bsi) ? NULL : bsi_stmt (bsi);
+ gsi = gsi_last_bb (bb);
+ stmt = gsi_end_p (gsi) ? NULL : gsi_stmt (gsi);
- switch (stmt ? TREE_CODE (stmt) : ERROR_MARK)
+ switch (stmt ? gimple_code (stmt) : ERROR_MARK)
{
- case COND_EXPR:
+ case GIMPLE_COND:
/* For COND_EXPR, we only need to redirect the edge. */
break;
- case GOTO_EXPR:
+ case GIMPLE_GOTO:
/* No non-abnormal edges should lead from a non-simple goto, and
simple ones should be represented implicitly. */
gcc_unreachable ();
- case SWITCH_EXPR:
+ case GIMPLE_SWITCH:
{
+ tree label = gimple_block_label (dest);
tree cases = get_cases_for_edge (e, stmt);
- tree label = tree_block_label (dest);
/* If we have a list of cases associated with E, then use it
as it's a lot faster than walking the entire case vector. */
@@ -4956,13 +4526,11 @@ tree_redirect_edge_and_branch (edge e, basic_block dest)
}
else
{
- tree vec = SWITCH_LABELS (stmt);
- size_t i, n = TREE_VEC_LENGTH (vec);
+ size_t i, n = gimple_switch_num_labels (stmt);
for (i = 0; i < n; i++)
{
- tree elt = TREE_VEC_ELT (vec, i);
-
+ tree elt = gimple_switch_label (stmt, i);
if (label_to_block (CASE_LABEL (elt)) == e->dest)
CASE_LABEL (elt) = label;
}
@@ -4971,15 +4539,15 @@ tree_redirect_edge_and_branch (edge e, basic_block dest)
break;
}
- case RETURN_EXPR:
- bsi_remove (&bsi, true);
+ case GIMPLE_RETURN:
+ gsi_remove (&gsi, true);
e->flags |= EDGE_FALLTHRU;
break;
- case OMP_RETURN:
- case OMP_CONTINUE:
- case OMP_SECTIONS_SWITCH:
- case OMP_FOR:
+ case GIMPLE_OMP_RETURN:
+ case GIMPLE_OMP_CONTINUE:
+ case GIMPLE_OMP_SECTIONS_SWITCH:
+ case GIMPLE_OMP_FOR:
/* The edges from OMP constructs can be simply redirected. */
break;
@@ -5002,7 +4570,7 @@ tree_redirect_edge_and_branch (edge e, basic_block dest)
it to the destination of the other edge from E->src. */
static bool
-tree_can_remove_branch_p (const_edge e)
+gimple_can_remove_branch_p (const_edge e)
{
if (e->flags & EDGE_ABNORMAL)
return false;
@@ -5013,9 +4581,9 @@ tree_can_remove_branch_p (const_edge e)
/* Simple wrapper, as we can always redirect fallthru edges. */
static basic_block
-tree_redirect_edge_and_branch_force (edge e, basic_block dest)
+gimple_redirect_edge_and_branch_force (edge e, basic_block dest)
{
- e = tree_redirect_edge_and_branch (e, dest);
+ e = gimple_redirect_edge_and_branch (e, dest);
gcc_assert (e);
return NULL;
@@ -5026,11 +4594,12 @@ tree_redirect_edge_and_branch_force (edge e, basic_block dest)
labels). If STMT is NULL, BB is split just after the labels. */
static basic_block
-tree_split_block (basic_block bb, void *stmt)
+gimple_split_block (basic_block bb, void *stmt)
{
- block_stmt_iterator bsi;
- tree_stmt_iterator tsi_tgt;
- tree act, list;
+ gimple_stmt_iterator gsi;
+ gimple_stmt_iterator gsi_tgt;
+ gimple act;
+ gimple_seq list;
basic_block new_bb;
edge e;
edge_iterator ei;
@@ -5043,14 +4612,14 @@ tree_split_block (basic_block bb, void *stmt)
FOR_EACH_EDGE (e, ei, new_bb->succs)
e->src = new_bb;
- if (stmt && TREE_CODE ((tree) stmt) == LABEL_EXPR)
+ if (stmt && gimple_code ((gimple) stmt) == GIMPLE_LABEL)
stmt = NULL;
- /* Move everything from BSI to the new basic block. */
- for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
+ /* Move everything from GSI to the new basic block. */
+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
- act = bsi_stmt (bsi);
- if (TREE_CODE (act) == LABEL_EXPR)
+ act = gsi_stmt (gsi);
+ if (gimple_code (act) == GIMPLE_LABEL)
continue;
if (!stmt)
@@ -5058,23 +4627,23 @@ tree_split_block (basic_block bb, void *stmt)
if (stmt == act)
{
- bsi_next (&bsi);
+ gsi_next (&gsi);
break;
}
}
- if (bsi_end_p (bsi))
+ if (gsi_end_p (gsi))
return new_bb;
/* Split the statement list - avoid re-creating new containers as this
brings ugly quadratic memory consumption in the inliner.
(We are still quadratic since we need to update stmt BB pointers,
sadly.) */
- list = tsi_split_statement_list_before (&bsi.tsi);
- set_bb_stmt_list (new_bb, list);
- for (tsi_tgt = tsi_start (list);
- !tsi_end_p (tsi_tgt); tsi_next (&tsi_tgt))
- change_bb_for_stmt (tsi_stmt (tsi_tgt), new_bb);
+ list = gsi_split_seq_before (&gsi);
+ set_bb_seq (new_bb, list);
+ for (gsi_tgt = gsi_start (list);
+ !gsi_end_p (gsi_tgt); gsi_next (&gsi_tgt))
+ gimple_set_bb (gsi_stmt (gsi_tgt), new_bb);
return new_bb;
}
@@ -5083,7 +4652,7 @@ tree_split_block (basic_block bb, void *stmt)
/* Moves basic block BB after block AFTER. */
static bool
-tree_move_block_after (basic_block bb, basic_block after)
+gimple_move_block_after (basic_block bb, basic_block after)
{
if (bb->prev_bb == after)
return true;
@@ -5098,52 +4667,49 @@ tree_move_block_after (basic_block bb, basic_block after)
/* Return true if basic_block can be duplicated. */
static bool
-tree_can_duplicate_bb_p (const_basic_block bb ATTRIBUTE_UNUSED)
+gimple_can_duplicate_bb_p (const_basic_block bb ATTRIBUTE_UNUSED)
{
return true;
}
-
/* Create a duplicate of the basic block BB. NOTE: This does not
preserve SSA form. */
static basic_block
-tree_duplicate_bb (basic_block bb)
+gimple_duplicate_bb (basic_block bb)
{
basic_block new_bb;
- block_stmt_iterator bsi, bsi_tgt;
- tree phi;
+ gimple_stmt_iterator gsi, gsi_tgt;
+ gimple_seq phis = phi_nodes (bb);
+ gimple phi, stmt, copy;
new_bb = create_empty_bb (EXIT_BLOCK_PTR->prev_bb);
/* Copy the PHI nodes. We ignore PHI node arguments here because
the incoming edges have not been setup yet. */
- for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
+ for (gsi = gsi_start (phis); !gsi_end_p (gsi); gsi_next (&gsi))
{
- tree copy = create_phi_node (PHI_RESULT (phi), new_bb);
- create_new_def_for (PHI_RESULT (copy), copy, PHI_RESULT_PTR (copy));
+ phi = gsi_stmt (gsi);
+ copy = create_phi_node (gimple_phi_result (phi), new_bb);
+ create_new_def_for (gimple_phi_result (copy), copy,
+ gimple_phi_result_ptr (copy));
}
- /* Keep the chain of PHI nodes in the same order so that they can be
- updated by ssa_redirect_edge. */
- set_phi_nodes (new_bb, phi_reverse (phi_nodes (new_bb)));
-
- bsi_tgt = bsi_start (new_bb);
- for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
+ gsi_tgt = gsi_start_bb (new_bb);
+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
def_operand_p def_p;
ssa_op_iter op_iter;
- tree stmt, copy;
int region;
- stmt = bsi_stmt (bsi);
- if (TREE_CODE (stmt) == LABEL_EXPR)
+ stmt = gsi_stmt (gsi);
+ if (gimple_code (stmt) == GIMPLE_LABEL)
continue;
/* Create a new copy of STMT and duplicate STMT's virtual
operands. */
- copy = unshare_expr (stmt);
- bsi_insert_after (&bsi_tgt, copy, BSI_NEW_STMT);
+ copy = gimple_copy (stmt);
+ gsi_insert_after (&gsi_tgt, copy, GSI_NEW_STMT);
copy_virtual_operands (copy, stmt);
region = lookup_stmt_eh_region (stmt);
if (region >= 0)
@@ -5167,9 +4733,11 @@ add_phi_args_after_copy_edge (edge e_copy)
basic_block bb, bb_copy = e_copy->src, dest;
edge e;
edge_iterator ei;
- tree phi, phi_copy, phi_next, def;
+ gimple phi, phi_copy;
+ tree def;
+ gimple_stmt_iterator psi, psi_copy;
- if (!phi_nodes (e_copy->dest))
+ if (gimple_seq_empty_p (phi_nodes (e_copy->dest)))
return;
bb = bb_copy->flags & BB_DUPLICATED ? get_bb_original (bb_copy) : bb_copy;
@@ -5195,11 +4763,13 @@ add_phi_args_after_copy_edge (edge e_copy)
gcc_assert (e != NULL);
}
- for (phi = phi_nodes (e->dest), phi_copy = phi_nodes (e_copy->dest);
- phi;
- phi = phi_next, phi_copy = PHI_CHAIN (phi_copy))
+ for (psi = gsi_start_phis (e->dest),
+ psi_copy = gsi_start_phis (e_copy->dest);
+ !gsi_end_p (psi);
+ gsi_next (&psi), gsi_next (&psi_copy))
{
- phi_next = PHI_CHAIN (phi);
+ phi = gsi_stmt (psi);
+ phi_copy = gsi_stmt (psi_copy);
def = PHI_ARG_DEF_FROM_EDGE (phi, e);
add_phi_arg (phi_copy, def, e_copy);
}
@@ -5213,8 +4783,8 @@ add_phi_args_after_copy_edge (edge e_copy)
void
add_phi_args_after_copy_bb (basic_block bb_copy)
{
- edge_iterator ei;
edge e_copy;
+ edge_iterator ei;
FOR_EACH_EDGE (e_copy, ei, bb_copy->succs)
{
@@ -5256,7 +4826,7 @@ add_phi_args_after_copy (basic_block *region_copy, unsigned n_region,
true otherwise. */
bool
-tree_duplicate_sese_region (edge entry, edge exit,
+gimple_duplicate_sese_region (edge entry, edge exit,
basic_block *region, unsigned n_region,
basic_block *region_copy)
{
@@ -5422,9 +4992,9 @@ tree_duplicate_sese_region (edge entry, edge exit,
*/
bool
-tree_duplicate_sese_tail (edge entry, edge exit,
- basic_block *region, unsigned n_region,
- basic_block *region_copy)
+gimple_duplicate_sese_tail (edge entry ATTRIBUTE_UNUSED, edge exit ATTRIBUTE_UNUSED,
+ basic_block *region ATTRIBUTE_UNUSED, unsigned n_region ATTRIBUTE_UNUSED,
+ basic_block *region_copy ATTRIBUTE_UNUSED)
{
unsigned i;
bool free_region_copy = false;
@@ -5435,8 +5005,8 @@ tree_duplicate_sese_tail (edge entry, edge exit,
int total_freq = 0, exit_freq = 0;
gcov_type total_count = 0, exit_count = 0;
edge exits[2], nexits[2], e;
- block_stmt_iterator bsi;
- tree cond;
+ gimple_stmt_iterator gsi;
+ gimple cond_stmt;
edge sorig, snew;
gcc_assert (EDGE_COUNT (exit->src->succs) == 2);
@@ -5525,10 +5095,13 @@ tree_duplicate_sese_tail (edge entry, edge exit,
switch_bb = split_edge (entry);
set_immediate_dominator (CDI_DOMINATORS, nentry_bb, switch_bb);
- bsi = bsi_last (switch_bb);
- cond = last_stmt (exit->src);
- gcc_assert (TREE_CODE (cond) == COND_EXPR);
- bsi_insert_after (&bsi, unshare_expr (cond), BSI_NEW_STMT);
+ gsi = gsi_last_bb (switch_bb);
+ cond_stmt = last_stmt (exit->src);
+ gcc_assert (gimple_code (cond_stmt) == GIMPLE_COND);
+ cond_stmt = gimple_copy (cond_stmt);
+ gimple_cond_set_lhs (cond_stmt, unshare_expr (gimple_cond_lhs (cond_stmt)));
+ gimple_cond_set_rhs (cond_stmt, unshare_expr (gimple_cond_rhs (cond_stmt)));
+ gsi_insert_after (&gsi, cond_stmt, GSI_NEW_STMT);
sorig = single_succ_edge (switch_bb);
sorig->flags = exits[1]->flags;
@@ -5543,9 +5116,9 @@ tree_duplicate_sese_tail (edge entry, edge exit,
/* Get rid of now superfluous conditions and associated edges (and phi node
arguments). */
e = redirect_edge_and_branch (exits[0], exits[1]->dest);
- PENDING_STMT (e) = NULL_TREE;
+ PENDING_STMT (e) = NULL;
e = redirect_edge_and_branch (nexits[1], nexits[0]->dest);
- PENDING_STMT (e) = NULL_TREE;
+ PENDING_STMT (e) = NULL;
/* Anything that is outside of the region, but was dominated by something
inside needs to update dominance info. */
@@ -5562,11 +5135,6 @@ tree_duplicate_sese_tail (edge entry, edge exit,
return true;
}
-/*
-DEF_VEC_P(basic_block);
-DEF_VEC_ALLOC_P(basic_block,heap);
-*/
-
/* Add all the blocks dominated by ENTRY to the array BBS_P. Stop
adding blocks when the dominator traversal reaches EXIT. This
function silently assumes that ENTRY strictly dominates EXIT. */
@@ -5627,6 +5195,7 @@ replace_by_duplicate_decl (tree *tp, struct pointer_map_t *vars_map,
*tp = new_t;
}
+
/* Creates an ssa name in TO_CONTEXT equivalent to NAME.
VARS_MAP maps old ssa names and var_decls to the new ones. */
@@ -5679,44 +5248,16 @@ struct move_stmt_d
DECL_CONTEXT of every local variable referenced in *TP. */
static tree
-move_stmt_r (tree *tp, int *walk_subtrees, void *data)
+move_stmt_op (tree *tp, int *walk_subtrees, void *data)
{
- struct move_stmt_d *p = (struct move_stmt_d *) data;
+ struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
+ struct move_stmt_d *p = (struct move_stmt_d *) wi->info;
tree t = *tp;
- if (EXPR_P (t) || GIMPLE_STMT_P (t))
- {
- tree block = TREE_BLOCK (t);
- if (p->orig_block == NULL_TREE
- || block == p->orig_block
- || block == NULL_TREE)
- TREE_BLOCK (t) = p->new_block;
-#ifdef ENABLE_CHECKING
- else if (block != p->new_block)
- {
- while (block && block != p->orig_block)
- block = BLOCK_SUPERCONTEXT (block);
- gcc_assert (block);
- }
-#endif
- }
-
- if (OMP_DIRECTIVE_P (t)
- && TREE_CODE (t) != OMP_RETURN
- && TREE_CODE (t) != OMP_CONTINUE)
- {
- /* Do not remap variables inside OMP directives. Variables
- referenced in clauses and directive header belong to the
- parent function and should not be moved into the child
- function. */
- bool save_remap_decls_p = p->remap_decls_p;
- p->remap_decls_p = false;
- *walk_subtrees = 0;
-
- walk_tree (&OMP_BODY (t), move_stmt_r, p, NULL);
+ if (EXPR_P (t))
+ /* We should never have TREE_BLOCK set on non-statements. */
+ gcc_assert (!TREE_BLOCK (t));
- p->remap_decls_p = save_remap_decls_p;
- }
else if (DECL_P (t) || TREE_CODE (t) == SSA_NAME)
{
if (TREE_CODE (t) == SSA_NAME)
@@ -5764,20 +5305,67 @@ move_stmt_r (tree *tp, int *walk_subtrees, void *data)
return NULL_TREE;
}
+/* Like move_stmt_op, but for gimple statements.
+
+ Helper for move_block_to_fn. Set GIMPLE_BLOCK in every expression
+ contained in the current statement in *GSI_P and change the
+ DECL_CONTEXT of every local variable referenced in the current
+ statement. */
+
+static tree
+move_stmt_r (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
+ struct walk_stmt_info *wi)
+{
+ struct move_stmt_d *p = (struct move_stmt_d *) wi->info;
+ gimple stmt = gsi_stmt (*gsi_p);
+ tree block = gimple_block (stmt);
+
+ if (p->orig_block == NULL_TREE
+ || block == p->orig_block
+ || block == NULL_TREE)
+ gimple_set_block (stmt, p->new_block);
+#ifdef ENABLE_CHECKING
+ else if (block != p->new_block)
+ {
+ while (block && block != p->orig_block)
+ block = BLOCK_SUPERCONTEXT (block);
+ gcc_assert (block);
+ }
+#endif
+
+ if (is_gimple_omp (stmt)
+ && gimple_code (stmt) != GIMPLE_OMP_RETURN
+ && gimple_code (stmt) != GIMPLE_OMP_CONTINUE)
+ {
+ /* Do not remap variables inside OMP directives. Variables
+ referenced in clauses and directive header belong to the
+ parent function and should not be moved into the child
+ function. */
+ bool save_remap_decls_p = p->remap_decls_p;
+ p->remap_decls_p = false;
+ *handled_ops_p = true;
+
+ walk_gimple_seq (gimple_omp_body (stmt), move_stmt_r, move_stmt_op, wi);
+
+ p->remap_decls_p = save_remap_decls_p;
+ }
+
+ return NULL_TREE;
+}
+
/* Marks virtual operands of all statements in basic blocks BBS for
renaming. */
void
mark_virtual_ops_in_bb (basic_block bb)
{
- tree phi;
- block_stmt_iterator bsi;
+ gimple_stmt_iterator gsi;
- for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
- mark_virtual_ops_for_renaming (phi);
+ for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+ mark_virtual_ops_for_renaming (gsi_stmt (gsi));
- for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
- mark_virtual_ops_for_renaming (bsi_stmt (bsi));
+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+ mark_virtual_ops_for_renaming (gsi_stmt (gsi));
}
/* Marks virtual operands of all statements in basic blocks BBS for
@@ -5811,9 +5399,8 @@ move_block_to_fn (struct function *dest_cfun, basic_block bb,
struct control_flow_graph *cfg;
edge_iterator ei;
edge e;
- block_stmt_iterator si;
+ gimple_stmt_iterator si;
unsigned old_len, new_len;
- tree phi, next_phi;
/* Remove BB from dominance structures. */
delete_from_dominance_info (CDI_DOMINATORS, bb);
@@ -5853,18 +5440,18 @@ move_block_to_fn (struct function *dest_cfun, basic_block bb,
bb->index, bb);
/* Remap the variables in phi nodes. */
- for (phi = phi_nodes (bb); phi; phi = next_phi)
+ for (si = gsi_start_phis (bb); !gsi_end_p (si); )
{
+ gimple phi = gsi_stmt (si);
use_operand_p use;
tree op = PHI_RESULT (phi);
ssa_op_iter oi;
- next_phi = PHI_CHAIN (phi);
if (!is_gimple_reg (op))
{
/* Remove the phi nodes for virtual operands (alias analysis will be
run for the new function, anyway). */
- remove_phi_node (phi, NULL, true);
+ remove_phi_node (&si, true);
continue;
}
@@ -5876,18 +5463,23 @@ move_block_to_fn (struct function *dest_cfun, basic_block bb,
if (TREE_CODE (op) == SSA_NAME)
SET_USE (use, replace_ssa_name (op, d->vars_map, dest_cfun->decl));
}
+
+ gsi_next (&si);
}
- for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
+ for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
{
- tree stmt = bsi_stmt (si);
+ gimple stmt = gsi_stmt (si);
int region;
+ struct walk_stmt_info wi;
- walk_tree (&stmt, move_stmt_r, d, NULL);
+ memset (&wi, 0, sizeof (wi));
+ wi.info = d;
+ walk_gimple_stmt (&si, move_stmt_r, move_stmt_op, &wi);
- if (TREE_CODE (stmt) == LABEL_EXPR)
+ if (gimple_code (stmt) == GIMPLE_LABEL)
{
- tree label = LABEL_EXPR_LABEL (stmt);
+ tree label = gimple_label_label (stmt);
int uid = LABEL_DECL_UID (label);
gcc_assert (uid > -1);
@@ -5908,11 +5500,8 @@ move_block_to_fn (struct function *dest_cfun, basic_block bb,
if (uid >= dest_cfun->cfg->last_label_uid)
dest_cfun->cfg->last_label_uid = uid + 1;
}
- else if (TREE_CODE (stmt) == RESX_EXPR && eh_offset != 0)
- TREE_OPERAND (stmt, 0) =
- build_int_cst (NULL_TREE,
- TREE_INT_CST_LOW (TREE_OPERAND (stmt, 0))
- + eh_offset);
+ else if (gimple_code (stmt) == GIMPLE_RESX && eh_offset != 0)
+ gimple_resx_set_region (stmt, gimple_resx_region (stmt) + eh_offset);
region = lookup_stmt_eh_region (stmt);
if (region >= 0)
@@ -5939,15 +5528,15 @@ static int
find_outermost_region_in_block (struct function *src_cfun,
basic_block bb, int region)
{
- block_stmt_iterator si;
+ gimple_stmt_iterator si;
- for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
+ for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
{
- tree stmt = bsi_stmt (si);
+ gimple stmt = gsi_stmt (si);
int stmt_region;
- if (TREE_CODE (stmt) == RESX_EXPR)
- stmt_region = TREE_INT_CST_LOW (TREE_OPERAND (stmt, 0));
+ if (gimple_code (stmt) == GIMPLE_RESX)
+ stmt_region = gimple_resx_region (stmt);
else
stmt_region = lookup_stmt_eh_region_fn (src_cfun, stmt);
if (stmt_region > 0)
@@ -6242,7 +5831,8 @@ move_sese_region_to_fn (struct function *dest_cfun, basic_block entry_bb,
}
-/* Dump FUNCTION_DECL FN to file FILE using FLAGS (see TDF_* in tree.h) */
+/* Dump FUNCTION_DECL FN to file FILE using FLAGS (see TDF_* in tree-pass.h)
+ */
void
dump_function_to_file (tree fn, FILE *file, int flags)
@@ -6276,7 +5866,7 @@ dump_function_to_file (tree fn, FILE *file, int flags)
if (dsf && (flags & TDF_DETAILS))
dump_eh_tree (file, dsf);
- if (flags & TDF_RAW)
+ if (flags & TDF_RAW && !gimple_body (fn))
{
dump_node (fn, TDF_SLIM | flags, file);
return;
@@ -6307,7 +5897,7 @@ dump_function_to_file (tree fn, FILE *file, int flags)
if (cfun && cfun->decl == fn && cfun->cfg && basic_block_info)
{
- /* Make a CFG based dump. */
+ /* If the CFG has been built, emit a CFG-based dump. */
check_bb_profile (ENTRY_BLOCK_PTR, file);
if (!ignore_topmost_bind)
fprintf (file, "{\n");
@@ -6316,11 +5906,34 @@ dump_function_to_file (tree fn, FILE *file, int flags)
fprintf (file, "\n");
FOR_EACH_BB (bb)
- dump_generic_bb (file, bb, 2, flags);
+ gimple_dump_bb (bb, file, 2, flags);
fprintf (file, "}\n");
check_bb_profile (EXIT_BLOCK_PTR, file);
}
+ else if (DECL_SAVED_TREE (fn) == NULL)
+ {
+ /* The function is now in GIMPLE form but the CFG has not been
+ built yet. Emit the single sequence of GIMPLE statements
+ that make up its body. */
+ gimple_seq body = gimple_body (fn);
+
+ if (gimple_seq_first_stmt (body)
+ && gimple_seq_first_stmt (body) == gimple_seq_last_stmt (body)
+ && gimple_code (gimple_seq_first_stmt (body)) == GIMPLE_BIND)
+ print_gimple_seq (file, body, 0, flags);
+ else
+ {
+ if (!ignore_topmost_bind)
+ fprintf (file, "{\n");
+
+ if (any_var)
+ fprintf (file, "\n");
+
+ print_gimple_seq (file, body, 2, flags);
+ fprintf (file, "}\n");
+ }
+ }
else
{
int indent;
@@ -6417,7 +6030,7 @@ print_loops_bb (FILE *file, basic_block bb, int indent, int verbosity)
if (verbosity >= 3)
{
fprintf (file, "%s {\n", s_indent);
- tree_dump_bb (bb, file, indent + 4);
+ gimple_dump_bb (bb, file, indent + 4, TDF_VOPS|TDF_MEMSYMS);
fprintf (file, "%s }\n", s_indent);
}
}
@@ -6531,10 +6144,10 @@ debug_loop_num (unsigned num, int verbosity)
otherwise. */
static bool
-tree_block_ends_with_call_p (basic_block bb)
+gimple_block_ends_with_call_p (basic_block bb)
{
- block_stmt_iterator bsi = bsi_last (bb);
- return get_call_expr_in (bsi_stmt (bsi)) != NULL;
+ gimple_stmt_iterator gsi = gsi_last_bb (bb);
+ return is_gimple_call (gsi_stmt (gsi));
}
@@ -6542,23 +6155,21 @@ tree_block_ends_with_call_p (basic_block bb)
otherwise. */
static bool
-tree_block_ends_with_condjump_p (const_basic_block bb)
+gimple_block_ends_with_condjump_p (const_basic_block bb)
{
- /* This CONST_CAST is okay because last_stmt doesn't modify its
- argument and the return value is not modified. */
- const_tree stmt = last_stmt (CONST_CAST_BB(bb));
- return (stmt && TREE_CODE (stmt) == COND_EXPR);
+ gimple stmt = last_stmt (CONST_CAST_BB (bb));
+ return (stmt && gimple_code (stmt) == GIMPLE_COND);
}
/* Return true if we need to add fake edge to exit at statement T.
- Helper function for tree_flow_call_edges_add. */
+ Helper function for gimple_flow_call_edges_add. */
static bool
-need_fake_edge_p (tree t)
+need_fake_edge_p (gimple t)
{
- tree call, fndecl = NULL_TREE;
- int call_flags;
+ tree fndecl = NULL_TREE;
+ int call_flags = 0;
/* NORETURN and LONGJMP calls already have an edge to exit.
CONST and PURE calls do not need one.
@@ -6567,24 +6178,26 @@ need_fake_edge_p (tree t)
figured out from the RTL in mark_constant_function, and
the counter incrementation code from -fprofile-arcs
leads to different results from -fbranch-probabilities. */
- call = get_call_expr_in (t);
- if (call)
+ if (is_gimple_call (t))
{
- fndecl = get_callee_fndecl (call);
- call_flags = call_expr_flags (call);
+ fndecl = gimple_call_fndecl (t);
+ call_flags = gimple_call_flags (t);
}
- if (call && fndecl && DECL_BUILT_IN (fndecl)
+ if (is_gimple_call (t)
+ && fndecl
+ && DECL_BUILT_IN (fndecl)
&& (call_flags & ECF_NOTHROW)
&& !(call_flags & ECF_NORETURN)
&& !(call_flags & ECF_RETURNS_TWICE))
return false;
- if (call && !(call_flags & ECF_NORETURN))
+ if (is_gimple_call (t)
+ && !(call_flags & ECF_NORETURN))
return true;
- if (TREE_CODE (t) == ASM_EXPR
- && (ASM_VOLATILE_P (t) || ASM_INPUT_P (t)))
+ if (gimple_code (t) == ASM_EXPR
+ && (gimple_asm_volatile_p (t) || gimple_asm_input_p (t)))
return true;
return false;
@@ -6600,7 +6213,7 @@ need_fake_edge_p (tree t)
not imply that all subsequent instructions must be executed. */
static int
-tree_flow_call_edges_add (sbitmap blocks)
+gimple_flow_call_edges_add (sbitmap blocks)
{
int i;
int blocks_split = 0;
@@ -6630,10 +6243,11 @@ tree_flow_call_edges_add (sbitmap blocks)
if (check_last_block)
{
basic_block bb = EXIT_BLOCK_PTR->prev_bb;
- block_stmt_iterator bsi = bsi_last (bb);
- tree t = NULL_TREE;
- if (!bsi_end_p (bsi))
- t = bsi_stmt (bsi);
+ gimple_stmt_iterator gsi = gsi_last_bb (bb);
+ gimple t = NULL;
+
+ if (!gsi_end_p (gsi))
+ t = gsi_stmt (gsi);
if (t && need_fake_edge_p (t))
{
@@ -6642,8 +6256,8 @@ tree_flow_call_edges_add (sbitmap blocks)
e = find_edge (bb, EXIT_BLOCK_PTR);
if (e)
{
- bsi_insert_on_edge (e, build_empty_stmt ());
- bsi_commit_edge_inserts ();
+ gsi_insert_on_edge (e, gimple_build_nop ());
+ gsi_commit_edge_inserts ();
}
}
}
@@ -6654,8 +6268,8 @@ tree_flow_call_edges_add (sbitmap blocks)
for (i = 0; i < last_bb; i++)
{
basic_block bb = BASIC_BLOCK (i);
- block_stmt_iterator bsi;
- tree stmt, last_stmt;
+ gimple_stmt_iterator gsi;
+ gimple stmt, last_stmt;
if (!bb)
continue;
@@ -6663,16 +6277,17 @@ tree_flow_call_edges_add (sbitmap blocks)
if (blocks && !TEST_BIT (blocks, i))
continue;
- bsi = bsi_last (bb);
- if (!bsi_end_p (bsi))
+ gsi = gsi_last_bb (bb);
+ if (!gsi_end_p (gsi))
{
- last_stmt = bsi_stmt (bsi);
+ last_stmt = gsi_stmt (gsi);
do
{
- stmt = bsi_stmt (bsi);
+ stmt = gsi_stmt (gsi);
if (need_fake_edge_p (stmt))
{
edge e;
+
/* The handling above of the final block before the
epilogue should be enough to verify that there is
no edge to the exit block in CFG already.
@@ -6696,9 +6311,9 @@ tree_flow_call_edges_add (sbitmap blocks)
}
make_edge (bb, EXIT_BLOCK_PTR, EDGE_FAKE);
}
- bsi_prev (&bsi);
+ gsi_prev (&gsi);
}
- while (!bsi_end_p (bsi));
+ while (!gsi_end_p (gsi));
}
}
@@ -6711,17 +6326,17 @@ tree_flow_call_edges_add (sbitmap blocks)
/* Purge dead abnormal call edges from basic block BB. */
bool
-tree_purge_dead_abnormal_call_edges (basic_block bb)
+gimple_purge_dead_abnormal_call_edges (basic_block bb)
{
- bool changed = tree_purge_dead_eh_edges (bb);
+ bool changed = gimple_purge_dead_eh_edges (bb);
if (cfun->has_nonlocal_label)
{
- tree stmt = last_stmt (bb);
+ gimple stmt = last_stmt (bb);
edge_iterator ei;
edge e;
- if (!(stmt && tree_can_make_abnormal_goto (stmt)))
+ if (!(stmt && stmt_can_make_abnormal_goto (stmt)))
for (ei = ei_start (bb->succs); (e = ei_safe_edge (ei)); )
{
if (e->flags & EDGE_ABNORMAL)
@@ -6733,7 +6348,7 @@ tree_purge_dead_abnormal_call_edges (basic_block bb)
ei_next (&ei);
}
- /* See tree_purge_dead_eh_edges below. */
+ /* See gimple_purge_dead_eh_edges below. */
if (changed)
free_dominance_info (CDI_DOMINATORS);
}
@@ -6880,14 +6495,14 @@ remove_edge_and_dominated_blocks (edge e)
/* Purge dead EH edges from basic block BB. */
bool
-tree_purge_dead_eh_edges (basic_block bb)
+gimple_purge_dead_eh_edges (basic_block bb)
{
bool changed = false;
edge e;
edge_iterator ei;
- tree stmt = last_stmt (bb);
+ gimple stmt = last_stmt (bb);
- if (stmt && tree_can_throw_internal (stmt))
+ if (stmt && stmt_can_throw_internal (stmt))
return false;
for (ei = ei_start (bb->succs); (e = ei_safe_edge (ei)); )
@@ -6905,7 +6520,7 @@ tree_purge_dead_eh_edges (basic_block bb)
}
bool
-tree_purge_all_dead_eh_edges (const_bitmap blocks)
+gimple_purge_all_dead_eh_edges (const_bitmap blocks)
{
bool changed = false;
unsigned i;
@@ -6913,7 +6528,7 @@ tree_purge_all_dead_eh_edges (const_bitmap blocks)
EXECUTE_IF_SET_IN_BITMAP (blocks, 0, i, bi)
{
- changed |= tree_purge_dead_eh_edges (BASIC_BLOCK (i));
+ changed |= gimple_purge_dead_eh_edges (BASIC_BLOCK (i));
}
return changed;
@@ -6923,7 +6538,7 @@ tree_purge_all_dead_eh_edges (const_bitmap blocks)
redirected. */
static void
-tree_execute_on_growing_pred (edge e)
+gimple_execute_on_growing_pred (edge e)
{
basic_block bb = e->dest;
@@ -6935,7 +6550,7 @@ tree_execute_on_growing_pred (edge e)
the edge vector E->dest->preds. */
static void
-tree_execute_on_shrinking_pred (edge e)
+gimple_execute_on_shrinking_pred (edge e)
{
if (phi_nodes (e->dest))
remove_phi_args (e);
@@ -6951,14 +6566,15 @@ tree_execute_on_shrinking_pred (edge e)
on the edge by split_edge(). Later, additional edge 'e' was created to
connect 'new_head' and 'first'. Now this routine adds phi args on this
additional edge 'e' that new_head to second edge received as part of edge
- splitting.
-*/
+ splitting. */
static void
-tree_lv_adjust_loop_header_phi (basic_block first, basic_block second,
- basic_block new_head, edge e)
+gimple_lv_adjust_loop_header_phi (basic_block first, basic_block second,
+ basic_block new_head, edge e)
{
- tree phi1, phi2;
+ gimple phi1, phi2;
+ gimple_stmt_iterator psi1, psi2;
+ tree def;
edge e2 = find_edge (new_head, second);
/* Because NEW_HEAD has been created by splitting SECOND's incoming
@@ -6968,35 +6584,41 @@ tree_lv_adjust_loop_header_phi (basic_block first, basic_block second,
/* Browse all 'second' basic block phi nodes and add phi args to
edge 'e' for 'first' head. PHI args are always in correct order. */
- for (phi2 = phi_nodes (second), phi1 = phi_nodes (first);
- phi2 && phi1;
- phi2 = PHI_CHAIN (phi2), phi1 = PHI_CHAIN (phi1))
+ for (psi2 = gsi_start_phis (second),
+ psi1 = gsi_start_phis (first);
+ !gsi_end_p (psi2) && !gsi_end_p (psi1);
+ gsi_next (&psi2), gsi_next (&psi1))
{
- tree def = PHI_ARG_DEF (phi2, e2->dest_idx);
+ phi1 = gsi_stmt (psi1);
+ phi2 = gsi_stmt (psi2);
+ def = PHI_ARG_DEF (phi2, e2->dest_idx);
add_phi_arg (phi1, def, e);
}
}
+
/* Adds a if else statement to COND_BB with condition COND_EXPR.
SECOND_HEAD is the destination of the THEN and FIRST_HEAD is
the destination of the ELSE part. */
+
static void
-tree_lv_add_condition_to_bb (basic_block first_head ATTRIBUTE_UNUSED,
- basic_block second_head ATTRIBUTE_UNUSED,
- basic_block cond_bb, void *cond_e)
+gimple_lv_add_condition_to_bb (basic_block first_head ATTRIBUTE_UNUSED,
+ basic_block second_head ATTRIBUTE_UNUSED,
+ basic_block cond_bb, void *cond_e)
{
- block_stmt_iterator bsi;
- tree new_cond_expr = NULL_TREE;
+ gimple_stmt_iterator gsi;
+ gimple new_cond_expr;
tree cond_expr = (tree) cond_e;
edge e0;
/* Build new conditional expr */
- new_cond_expr = build3 (COND_EXPR, void_type_node, cond_expr,
- NULL_TREE, NULL_TREE);
+ new_cond_expr = gimple_build_cond_from_tree (cond_expr,
+ NULL_TREE, NULL_TREE);
/* Add new cond in cond_bb. */
- bsi = bsi_start (cond_bb);
- bsi_insert_after (&bsi, new_cond_expr, BSI_NEW_STMT);
+ gsi = gsi_last_bb (cond_bb);
+ gsi_insert_after (&gsi, new_cond_expr, GSI_NEW_STMT);
+
/* Adjust edges appropriately to connect new head with first head
as well as second head. */
e0 = single_succ_edge (cond_bb);
@@ -7004,34 +6626,34 @@ tree_lv_add_condition_to_bb (basic_block first_head ATTRIBUTE_UNUSED,
e0->flags |= EDGE_FALSE_VALUE;
}
-struct cfg_hooks tree_cfg_hooks = {
- "tree",
- tree_verify_flow_info,
- tree_dump_bb, /* dump_bb */
+struct cfg_hooks gimple_cfg_hooks = {
+ "gimple",
+ gimple_verify_flow_info,
+ gimple_dump_bb, /* dump_bb */
create_bb, /* create_basic_block */
- tree_redirect_edge_and_branch,/* redirect_edge_and_branch */
- tree_redirect_edge_and_branch_force,/* redirect_edge_and_branch_force */
- tree_can_remove_branch_p, /* can_remove_branch_p */
+ gimple_redirect_edge_and_branch, /* redirect_edge_and_branch */
+ gimple_redirect_edge_and_branch_force, /* redirect_edge_and_branch_force */
+ gimple_can_remove_branch_p, /* can_remove_branch_p */
remove_bb, /* delete_basic_block */
- tree_split_block, /* split_block */
- tree_move_block_after, /* move_block_after */
- tree_can_merge_blocks_p, /* can_merge_blocks_p */
- tree_merge_blocks, /* merge_blocks */
- tree_predict_edge, /* predict_edge */
- tree_predicted_by_p, /* predicted_by_p */
- tree_can_duplicate_bb_p, /* can_duplicate_block_p */
- tree_duplicate_bb, /* duplicate_block */
- tree_split_edge, /* split_edge */
- tree_make_forwarder_block, /* make_forward_block */
+ gimple_split_block, /* split_block */
+ gimple_move_block_after, /* move_block_after */
+ gimple_can_merge_blocks_p, /* can_merge_blocks_p */
+ gimple_merge_blocks, /* merge_blocks */
+ gimple_predict_edge, /* predict_edge */
+ gimple_predicted_by_p, /* predicted_by_p */
+ gimple_can_duplicate_bb_p, /* can_duplicate_block_p */
+ gimple_duplicate_bb, /* duplicate_block */
+ gimple_split_edge, /* split_edge */
+ gimple_make_forwarder_block, /* make_forward_block */
NULL, /* tidy_fallthru_edge */
- tree_block_ends_with_call_p, /* block_ends_with_call_p */
- tree_block_ends_with_condjump_p, /* block_ends_with_condjump_p */
- tree_flow_call_edges_add, /* flow_call_edges_add */
- tree_execute_on_growing_pred, /* execute_on_growing_pred */
- tree_execute_on_shrinking_pred, /* execute_on_shrinking_pred */
- tree_duplicate_loop_to_header_edge, /* duplicate loop for trees */
- tree_lv_add_condition_to_bb, /* lv_add_condition_to_bb */
- tree_lv_adjust_loop_header_phi, /* lv_adjust_loop_header_phi*/
+ gimple_block_ends_with_call_p,/* block_ends_with_call_p */
+ gimple_block_ends_with_condjump_p, /* block_ends_with_condjump_p */
+ gimple_flow_call_edges_add, /* flow_call_edges_add */
+ gimple_execute_on_growing_pred, /* execute_on_growing_pred */
+ gimple_execute_on_shrinking_pred, /* execute_on_shrinking_pred */
+ gimple_duplicate_loop_to_header_edge, /* duplicate loop for trees */
+ gimple_lv_add_condition_to_bb, /* lv_add_condition_to_bb */
+ gimple_lv_adjust_loop_header_phi, /* lv_adjust_loop_header_phi*/
extract_true_false_edges_from_block, /* extract_cond_bb_edges */
flush_pending_stmts /* flush_pending_stmts */
};
@@ -7081,39 +6703,12 @@ struct gimple_opt_pass pass_split_crit_edges =
}
};
-
-/* Return EXP if it is a valid GIMPLE rvalue, else gimplify it into
- a temporary, make sure and register it to be renamed if necessary,
- and finally return the temporary. Put the statements to compute
- EXP before the current statement in BSI. */
-
-tree
-gimplify_val (block_stmt_iterator *bsi, tree type, tree exp)
-{
- tree t, new_stmt, orig_stmt;
-
- if (is_gimple_val (exp))
- return exp;
-
- t = make_rename_temp (type, NULL);
- new_stmt = build_gimple_modify_stmt (t, exp);
-
- orig_stmt = bsi_stmt (*bsi);
- SET_EXPR_LOCUS (new_stmt, EXPR_LOCUS (orig_stmt));
- TREE_BLOCK (new_stmt) = TREE_BLOCK (orig_stmt);
-
- bsi_insert_before (bsi, new_stmt, BSI_SAME_STMT);
- if (gimple_in_ssa_p (cfun))
- mark_symbols_for_renaming (new_stmt);
-
- return t;
-}
-/* Build a ternary operation and gimplify it. Emit code before BSI.
+/* Build a ternary operation and gimplify it. Emit code before GSI.
Return the gimple_val holding the result. */
tree
-gimplify_build3 (block_stmt_iterator *bsi, enum tree_code code,
+gimplify_build3 (gimple_stmt_iterator *gsi, enum tree_code code,
tree type, tree a, tree b, tree c)
{
tree ret;
@@ -7121,14 +6716,15 @@ gimplify_build3 (block_stmt_iterator *bsi, enum tree_code code,
ret = fold_build3 (code, type, a, b, c);
STRIP_NOPS (ret);
- return gimplify_val (bsi, type, ret);
+ return force_gimple_operand_gsi (gsi, ret, true, NULL, true,
+ GSI_SAME_STMT);
}
-/* Build a binary operation and gimplify it. Emit code before BSI.
+/* Build a binary operation and gimplify it. Emit code before GSI.
Return the gimple_val holding the result. */
tree
-gimplify_build2 (block_stmt_iterator *bsi, enum tree_code code,
+gimplify_build2 (gimple_stmt_iterator *gsi, enum tree_code code,
tree type, tree a, tree b)
{
tree ret;
@@ -7136,14 +6732,15 @@ gimplify_build2 (block_stmt_iterator *bsi, enum tree_code code,
ret = fold_build2 (code, type, a, b);
STRIP_NOPS (ret);
- return gimplify_val (bsi, type, ret);
+ return force_gimple_operand_gsi (gsi, ret, true, NULL, true,
+ GSI_SAME_STMT);
}
-/* Build a unary operation and gimplify it. Emit code before BSI.
+/* Build a unary operation and gimplify it. Emit code before GSI.
Return the gimple_val holding the result. */
tree
-gimplify_build1 (block_stmt_iterator *bsi, enum tree_code code, tree type,
+gimplify_build1 (gimple_stmt_iterator *gsi, enum tree_code code, tree type,
tree a)
{
tree ret;
@@ -7151,7 +6748,8 @@ gimplify_build1 (block_stmt_iterator *bsi, enum tree_code code, tree type,
ret = fold_build1 (code, type, a);
STRIP_NOPS (ret);
- return gimplify_val (bsi, type, ret);
+ return force_gimple_operand_gsi (gsi, ret, true, NULL, true,
+ GSI_SAME_STMT);
}
@@ -7162,7 +6760,7 @@ static unsigned int
execute_warn_function_return (void)
{
source_location location;
- tree last;
+ gimple last;
edge e;
edge_iterator ei;
@@ -7174,8 +6772,8 @@ execute_warn_function_return (void)
FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR->preds)
{
last = last_stmt (e->src);
- if (TREE_CODE (last) == RETURN_EXPR
- && (location = EXPR_LOCATION (last)) != UNKNOWN_LOCATION)
+ if (gimple_code (last) == GIMPLE_RETURN
+ && (location = gimple_location (last)) != UNKNOWN_LOCATION)
break;
}
if (location == UNKNOWN_LOCATION)
@@ -7192,15 +6790,15 @@ execute_warn_function_return (void)
{
FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR->preds)
{
- tree last = last_stmt (e->src);
- if (TREE_CODE (last) == RETURN_EXPR
- && TREE_OPERAND (last, 0) == NULL
- && !TREE_NO_WARNING (last))
+ gimple last = last_stmt (e->src);
+ if (gimple_code (last) == GIMPLE_RETURN
+ && gimple_return_retval (last) == NULL
+ && !gimple_no_warning_p (last))
{
- location = EXPR_LOCATION (last);
+ location = gimple_location (last);
if (location == UNKNOWN_LOCATION)
location = cfun->function_end_locus;
- warning (OPT_Wreturn_type, "%Hcontrol reaches end of non-void function", &location);
+ warning_at (location, OPT_Wreturn_type, "control reaches end of non-void function");
TREE_NO_WARNING (cfun->decl) = 1;
break;
}
diff --git a/gcc/tree-cfgcleanup.c b/gcc/tree-cfgcleanup.c
index 8970a9b96eb..433900c3a14 100644
--- a/gcc/tree-cfgcleanup.c
+++ b/gcc/tree-cfgcleanup.c
@@ -73,15 +73,17 @@ remove_fallthru_edge (VEC(edge,gc) *ev)
return false;
}
+
/* Disconnect an unreachable block in the control expression starting
at block BB. */
static bool
-cleanup_control_expr_graph (basic_block bb, block_stmt_iterator bsi)
+cleanup_control_expr_graph (basic_block bb, gimple_stmt_iterator gsi)
{
edge taken_edge;
bool retval = false;
- tree expr = bsi_stmt (bsi), val;
+ gimple stmt = gsi_stmt (gsi);
+ tree val;
if (!single_succ_p (bb))
{
@@ -90,26 +92,7 @@ cleanup_control_expr_graph (basic_block bb, block_stmt_iterator bsi)
bool warned;
fold_defer_overflow_warnings ();
-
- switch (TREE_CODE (expr))
- {
- case COND_EXPR:
- val = fold (COND_EXPR_COND (expr));
- break;
-
- case SWITCH_EXPR:
- val = fold (SWITCH_COND (expr));
- if (TREE_CODE (val) != INTEGER_CST)
- {
- fold_undefer_and_ignore_overflow_warnings ();
- return false;
- }
- break;
-
- default:
- gcc_unreachable ();
- }
-
+ val = gimple_fold (stmt);
taken_edge = find_taken_edge (bb, val);
if (!taken_edge)
{
@@ -126,7 +109,7 @@ cleanup_control_expr_graph (basic_block bb, block_stmt_iterator bsi)
if (!warned)
{
fold_undefer_overflow_warnings
- (true, expr, WARN_STRICT_OVERFLOW_CONDITIONAL);
+ (true, stmt, WARN_STRICT_OVERFLOW_CONDITIONAL);
warned = true;
}
@@ -147,7 +130,7 @@ cleanup_control_expr_graph (basic_block bb, block_stmt_iterator bsi)
taken_edge = single_succ_edge (bb);
bitmap_set_bit (cfgcleanup_altered_bbs, bb->index);
- bsi_remove (&bsi, true);
+ gsi_remove (&gsi, true);
taken_edge->flags = EDGE_FALLTHRU;
return retval;
@@ -159,30 +142,30 @@ cleanup_control_expr_graph (basic_block bb, block_stmt_iterator bsi)
static bool
cleanup_control_flow_bb (basic_block bb)
{
- block_stmt_iterator bsi;
+ gimple_stmt_iterator gsi;
bool retval = false;
- tree stmt;
+ gimple stmt;
/* If the last statement of the block could throw and now cannot,
we need to prune cfg. */
- retval |= tree_purge_dead_eh_edges (bb);
+ retval |= gimple_purge_dead_eh_edges (bb);
- bsi = bsi_last (bb);
- if (bsi_end_p (bsi))
+ gsi = gsi_last_bb (bb);
+ if (gsi_end_p (gsi))
return retval;
- stmt = bsi_stmt (bsi);
+ stmt = gsi_stmt (gsi);
- if (TREE_CODE (stmt) == COND_EXPR
- || TREE_CODE (stmt) == SWITCH_EXPR)
- retval |= cleanup_control_expr_graph (bb, bsi);
- /* If we had a computed goto which has a compile-time determinable
- destination, then we can eliminate the goto. */
- else if (TREE_CODE (stmt) == GOTO_EXPR
- && TREE_CODE (GOTO_DESTINATION (stmt)) == ADDR_EXPR
- && (TREE_CODE (TREE_OPERAND (GOTO_DESTINATION (stmt), 0))
+ if (gimple_code (stmt) == GIMPLE_COND
+ || gimple_code (stmt) == GIMPLE_SWITCH)
+ retval |= cleanup_control_expr_graph (bb, gsi);
+ else if (gimple_code (stmt) == GIMPLE_GOTO
+ && TREE_CODE (gimple_goto_dest (stmt)) == ADDR_EXPR
+ && (TREE_CODE (TREE_OPERAND (gimple_goto_dest (stmt), 0))
== LABEL_DECL))
{
+ /* If we had a computed goto which has a compile-time determinable
+ destination, then we can eliminate the goto. */
edge e;
tree label;
edge_iterator ei;
@@ -191,7 +174,7 @@ cleanup_control_flow_bb (basic_block bb)
/* First look at all the outgoing edges. Delete any outgoing
edges which do not go to the right block. For the one
edge which goes to the right block, fix up its flags. */
- label = TREE_OPERAND (GOTO_DESTINATION (stmt), 0);
+ label = TREE_OPERAND (gimple_goto_dest (stmt), 0);
target_block = label_to_block (label);
for (ei = ei_start (bb->succs); (e = ei_safe_edge (ei)); )
{
@@ -213,13 +196,15 @@ cleanup_control_flow_bb (basic_block bb)
/* Remove the GOTO_EXPR as it is not needed. The CFG has all the
relevant information we need. */
- bsi_remove (&bsi, true);
+ gsi_remove (&gsi, true);
retval = true;
}
/* Check for indirect calls that have been turned into
noreturn calls. */
- else if (noreturn_call_p (stmt) && remove_fallthru_edge (bb->succs))
+ else if (is_gimple_call (stmt)
+ && gimple_call_noreturn_p (stmt)
+ && remove_fallthru_edge (bb->succs))
retval = true;
return retval;
@@ -235,7 +220,7 @@ cleanup_control_flow_bb (basic_block bb)
static bool
tree_forwarder_block_p (basic_block bb, bool phi_wanted)
{
- block_stmt_iterator bsi;
+ gimple_stmt_iterator gsi;
edge_iterator ei;
edge e, succ;
basic_block dest;
@@ -244,7 +229,7 @@ tree_forwarder_block_p (basic_block bb, bool phi_wanted)
if (single_succ_p (bb) != 1
/* If PHI_WANTED is false, BB must not have any PHI nodes.
Otherwise, BB must have PHI nodes. */
- || (phi_nodes (bb) != NULL_TREE) != phi_wanted
+ || gimple_seq_empty_p (phi_nodes (bb)) == phi_wanted
/* BB may not be a predecessor of EXIT_BLOCK_PTR. */
|| single_succ (bb) == EXIT_BLOCK_PTR
/* Nor should this be an infinite loop. */
@@ -259,14 +244,14 @@ tree_forwarder_block_p (basic_block bb, bool phi_wanted)
/* Now walk through the statements backward. We can ignore labels,
anything else means this is not a forwarder block. */
- for (bsi = bsi_last (bb); !bsi_end_p (bsi); bsi_prev (&bsi))
+ for (gsi = gsi_last_bb (bb); !gsi_end_p (gsi); gsi_prev (&gsi))
{
- tree stmt = bsi_stmt (bsi);
+ gimple stmt = gsi_stmt (gsi);
- switch (TREE_CODE (stmt))
+ switch (gimple_code (stmt))
{
- case LABEL_EXPR:
- if (DECL_NONLOCAL (LABEL_EXPR_LABEL (stmt)))
+ case GIMPLE_LABEL:
+ if (DECL_NONLOCAL (gimple_label_label (stmt)))
return false;
break;
@@ -333,12 +318,13 @@ phi_alternatives_equal (basic_block dest, edge e1, edge e2)
{
int n1 = e1->dest_idx;
int n2 = e2->dest_idx;
- tree phi;
+ gimple_stmt_iterator gsi;
- for (phi = phi_nodes (dest); phi; phi = PHI_CHAIN (phi))
+ for (gsi = gsi_start_phis (dest); !gsi_end_p (gsi); gsi_next (&gsi))
{
- tree val1 = PHI_ARG_DEF (phi, n1);
- tree val2 = PHI_ARG_DEF (phi, n2);
+ gimple phi = gsi_stmt (gsi);
+ tree val1 = gimple_phi_arg_def (phi, n1);
+ tree val2 = gimple_phi_arg_def (phi, n2);
gcc_assert (val1 != NULL_TREE);
gcc_assert (val2 != NULL_TREE);
@@ -357,10 +343,9 @@ remove_forwarder_block (basic_block bb)
{
edge succ = single_succ_edge (bb), e, s;
basic_block dest = succ->dest;
- tree label;
- tree phi;
+ gimple label;
edge_iterator ei;
- block_stmt_iterator bsi, bsi_to;
+ gimple_stmt_iterator gsi, gsi_to;
bool seen_abnormal_edge = false;
/* We check for infinite loops already in tree_forwarder_block_p.
@@ -373,8 +358,8 @@ remove_forwarder_block (basic_block bb)
it. */
label = first_stmt (dest);
if (label
- && TREE_CODE (label) == LABEL_EXPR
- && DECL_NONLOCAL (LABEL_EXPR_LABEL (label)))
+ && gimple_code (label) == GIMPLE_LABEL
+ && DECL_NONLOCAL (gimple_label_label (label)))
return false;
/* If there is an abnormal edge to basic block BB, but not into
@@ -393,14 +378,14 @@ remove_forwarder_block (basic_block bb)
seen_abnormal_edge = true;
if (has_abnormal_incoming_edge_p (dest)
- || phi_nodes (dest) != NULL_TREE)
+ || !gimple_seq_empty_p (phi_nodes (dest)))
return false;
}
/* If there are phi nodes in DEST, and some of the blocks that are
predecessors of BB are also predecessors of DEST, check that the
phi node arguments match. */
- if (phi_nodes (dest))
+ if (!gimple_seq_empty_p (phi_nodes (dest)))
{
FOR_EACH_EDGE (e, ei, bb->preds)
{
@@ -431,8 +416,13 @@ remove_forwarder_block (basic_block bb)
{
/* Create arguments for the phi nodes, since the edge was not
here before. */
- for (phi = phi_nodes (dest); phi; phi = PHI_CHAIN (phi))
- add_phi_arg (phi, PHI_ARG_DEF (phi, succ->dest_idx), s);
+ for (gsi = gsi_start_phis (dest);
+ !gsi_end_p (gsi);
+ gsi_next (&gsi))
+ {
+ gimple phi = gsi_stmt (gsi);
+ add_phi_arg (phi, gimple_phi_arg_def (phi, succ->dest_idx), s);
+ }
}
}
@@ -440,14 +430,13 @@ remove_forwarder_block (basic_block bb)
{
/* Move the labels to the new block, so that the redirection of
the abnormal edges works. */
-
- bsi_to = bsi_start (dest);
- for (bsi = bsi_start (bb); !bsi_end_p (bsi); )
+ gsi_to = gsi_start_bb (dest);
+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); )
{
- label = bsi_stmt (bsi);
- gcc_assert (TREE_CODE (label) == LABEL_EXPR);
- bsi_remove (&bsi, false);
- bsi_insert_before (&bsi_to, label, BSI_CONTINUE_LINKING);
+ label = gsi_stmt (gsi);
+ gcc_assert (gimple_code (label) == GIMPLE_LABEL);
+ gsi_remove (&gsi, false);
+ gsi_insert_before (&gsi_to, label, GSI_CONTINUE_LINKING);
}
}
@@ -485,18 +474,18 @@ static bool
split_bbs_on_noreturn_calls (void)
{
bool changed = false;
- tree stmt;
+ gimple stmt;
basic_block bb;
/* Detect cases where a mid-block call is now known not to return. */
if (cfun->gimple_df)
- while (VEC_length (tree, MODIFIED_NORETURN_CALLS (cfun)))
+ while (VEC_length (gimple, MODIFIED_NORETURN_CALLS (cfun)))
{
- stmt = VEC_pop (tree, MODIFIED_NORETURN_CALLS (cfun));
- bb = bb_for_stmt (stmt);
+ stmt = VEC_pop (gimple, MODIFIED_NORETURN_CALLS (cfun));
+ bb = gimple_bb (stmt);
if (bb == NULL
|| last_stmt (bb) == stmt
- || !noreturn_call_p (stmt))
+ || !gimple_call_noreturn_p (stmt))
continue;
changed = true;
@@ -507,23 +496,23 @@ split_bbs_on_noreturn_calls (void)
return changed;
}
-/* If OMP_RETURN in basic block BB is unreachable, remove it. */
+/* If GIMPLE_OMP_RETURN in basic block BB is unreachable, remove it. */
static bool
cleanup_omp_return (basic_block bb)
{
- tree stmt = last_stmt (bb);
+ gimple stmt = last_stmt (bb);
basic_block control_bb;
- if (stmt == NULL_TREE
- || TREE_CODE (stmt) != OMP_RETURN
+ if (stmt == NULL
+ || gimple_code (stmt) != GIMPLE_OMP_RETURN
|| !single_pred_p (bb))
return false;
control_bb = single_pred (bb);
stmt = last_stmt (control_bb);
- if (TREE_CODE (stmt) != OMP_SECTIONS_SWITCH)
+ if (gimple_code (stmt) != GIMPLE_OMP_SECTIONS_SWITCH)
return false;
/* The block with the control statement normally has two entry edges -- one
@@ -553,7 +542,6 @@ cleanup_tree_cfg_bb (basic_block bb)
/* Forwarder blocks can carry line number information which is
useful when debugging, so we only clean them up when
optimizing. */
-
if (optimize > 0
&& tree_forwarder_block_p (bb, false)
&& remove_forwarder_block (bb))
@@ -716,7 +704,7 @@ remove_forwarder_block_with_phi (basic_block bb)
{
edge succ = single_succ_edge (bb);
basic_block dest = succ->dest;
- tree label;
+ gimple label;
basic_block dombb, domdest, dom;
/* We check for infinite loops already in tree_forwarder_block_p.
@@ -729,15 +717,15 @@ remove_forwarder_block_with_phi (basic_block bb)
merge it. */
label = first_stmt (dest);
if (label
- && TREE_CODE (label) == LABEL_EXPR
- && DECL_NONLOCAL (LABEL_EXPR_LABEL (label)))
+ && gimple_code (label) == GIMPLE_LABEL
+ && DECL_NONLOCAL (gimple_label_label (label)))
return;
/* Redirect each incoming edge to BB to DEST. */
while (EDGE_COUNT (bb->preds) > 0)
{
edge e = EDGE_PRED (bb, 0), s;
- tree phi;
+ gimple_stmt_iterator gsi;
s = find_edge (e->src, dest);
if (s)
@@ -765,9 +753,12 @@ remove_forwarder_block_with_phi (basic_block bb)
/* Add to the PHI nodes at DEST each PHI argument removed at the
destination of E. */
- for (phi = phi_nodes (dest); phi; phi = PHI_CHAIN (phi))
+ for (gsi = gsi_start_phis (dest);
+ !gsi_end_p (gsi);
+ gsi_next (&gsi))
{
- tree def = PHI_ARG_DEF (phi, succ->dest_idx);
+ gimple phi = gsi_stmt (gsi);
+ tree def = gimple_phi_arg_def (phi, succ->dest_idx);
if (TREE_CODE (def) == SSA_NAME)
{
@@ -879,7 +870,7 @@ merge_phi_nodes (void)
}
else
{
- tree phi;
+ gimple_stmt_iterator gsi;
unsigned int dest_idx = single_succ_edge (bb)->dest_idx;
/* BB dominates DEST. There may be many users of the PHI
@@ -887,11 +878,13 @@ merge_phi_nodes (void)
can handle. If the result of every PHI in BB is used
only by a PHI in DEST, then we can trivially merge the
PHI nodes from BB into DEST. */
- for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
+ for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi);
+ gsi_next (&gsi))
{
- tree result = PHI_RESULT (phi);
+ gimple phi = gsi_stmt (gsi);
+ tree result = gimple_phi_result (phi);
use_operand_p imm_use;
- tree use_stmt;
+ gimple use_stmt;
/* If the PHI's result is never used, then we can just
ignore it. */
@@ -900,15 +893,15 @@ merge_phi_nodes (void)
/* Get the single use of the result of this PHI node. */
if (!single_imm_use (result, &imm_use, &use_stmt)
- || TREE_CODE (use_stmt) != PHI_NODE
- || bb_for_stmt (use_stmt) != dest
- || PHI_ARG_DEF (use_stmt, dest_idx) != result)
+ || gimple_code (use_stmt) != GIMPLE_PHI
+ || gimple_bb (use_stmt) != dest
+ || gimple_phi_arg_def (use_stmt, dest_idx) != result)
break;
}
/* If the loop above iterated through all the PHI nodes
in BB, then we can merge the PHIs from BB into DEST. */
- if (!phi)
+ if (gsi_end_p (gsi))
*current++ = bb;
}
}
diff --git a/gcc/tree-chrec.c b/gcc/tree-chrec.c
index 295fb7920c9..89e96fd53b6 100644
--- a/gcc/tree-chrec.c
+++ b/gcc/tree-chrec.c
@@ -343,9 +343,9 @@ chrec_fold_plus (tree type,
return chrec_fold_automatically_generated_operands (op0, op1);
if (integer_zerop (op0))
- return chrec_convert (type, op1, NULL_TREE);
+ return chrec_convert (type, op1, NULL);
if (integer_zerop (op1))
- return chrec_convert (type, op0, NULL_TREE);
+ return chrec_convert (type, op0, NULL);
if (POINTER_TYPE_P (type))
code = POINTER_PLUS_EXPR;
@@ -577,7 +577,7 @@ chrec_apply (unsigned var,
if (evolution_function_is_affine_p (chrec))
{
/* "{a, +, b} (x)" -> "a + b*x". */
- x = chrec_convert_rhs (type, x, NULL_TREE);
+ x = chrec_convert_rhs (type, x, NULL);
res = chrec_fold_multiply (TREE_TYPE (x), CHREC_RIGHT (chrec), x);
if (!integer_zerop (CHREC_LEFT (chrec)))
res = chrec_fold_plus (type, CHREC_LEFT (chrec), res);
@@ -1115,7 +1115,7 @@ avoid_arithmetics_in_type_p (const_tree type)
return false;
}
-static tree chrec_convert_1 (tree, tree, tree, bool);
+static tree chrec_convert_1 (tree, tree, gimple, bool);
/* Converts BASE and STEP of affine scev to TYPE. LOOP is the loop whose iv
the scev corresponds to. AT_STMT is the statement at that the scev is
@@ -1127,7 +1127,7 @@ static tree chrec_convert_1 (tree, tree, tree, bool);
bool
convert_affine_scev (struct loop *loop, tree type,
- tree *base, tree *step, tree at_stmt,
+ tree *base, tree *step, gimple at_stmt,
bool use_overflow_semantics)
{
tree ct = TREE_TYPE (*step);
@@ -1228,7 +1228,7 @@ convert_affine_scev (struct loop *loop, tree type,
/* Convert CHREC for the right hand side of a CREC.
The increment for a pointer type is always sizetype. */
tree
-chrec_convert_rhs (tree type, tree chrec, tree at_stmt)
+chrec_convert_rhs (tree type, tree chrec, gimple at_stmt)
{
if (POINTER_TYPE_P (type))
type = sizetype;
@@ -1260,7 +1260,7 @@ chrec_convert_rhs (tree type, tree chrec, tree at_stmt)
*/
tree
-chrec_convert (tree type, tree chrec, tree at_stmt)
+chrec_convert (tree type, tree chrec, gimple at_stmt)
{
return chrec_convert_1 (type, chrec, at_stmt, true);
}
@@ -1278,7 +1278,7 @@ chrec_convert (tree type, tree chrec, tree at_stmt)
tests, but also to enforce that the result follows them. */
static tree
-chrec_convert_1 (tree type, tree chrec, tree at_stmt,
+chrec_convert_1 (tree type, tree chrec, gimple at_stmt,
bool use_overflow_semantics)
{
tree ct, res;
@@ -1352,10 +1352,10 @@ chrec_convert_aggressive (tree type, tree chrec)
right = CHREC_RIGHT (chrec);
lc = chrec_convert_aggressive (type, left);
if (!lc)
- lc = chrec_convert (type, left, NULL_TREE);
+ lc = chrec_convert (type, left, NULL);
rc = chrec_convert_aggressive (rtype, right);
if (!rc)
- rc = chrec_convert (rtype, right, NULL_TREE);
+ rc = chrec_convert (rtype, right, NULL);
return build_polynomial_chrec (CHREC_VARIABLE (chrec), lc, rc);
}
diff --git a/gcc/tree-chrec.h b/gcc/tree-chrec.h
index 7f240c6c739..9000fb7dab4 100644
--- a/gcc/tree-chrec.h
+++ b/gcc/tree-chrec.h
@@ -57,8 +57,8 @@ tree_is_chrec (const_tree expr)
extern tree chrec_fold_plus (tree, tree, tree);
extern tree chrec_fold_minus (tree, tree, tree);
extern tree chrec_fold_multiply (tree, tree, tree);
-extern tree chrec_convert (tree, tree, tree);
-extern tree chrec_convert_rhs (tree, tree, tree);
+extern tree chrec_convert (tree, tree, gimple);
+extern tree chrec_convert_rhs (tree, tree, gimple);
extern tree chrec_convert_aggressive (tree, tree);
/* Operations. */
diff --git a/gcc/tree-complex.c b/gcc/tree-complex.c
index 0fc1cc5f305..bbf4c494218 100644
--- a/gcc/tree-complex.c
+++ b/gcc/tree-complex.c
@@ -26,7 +26,7 @@ along with GCC; see the file COPYING3. If not see
#include "real.h"
#include "flags.h"
#include "tree-flow.h"
-#include "tree-gimple.h"
+#include "gimple.h"
#include "tree-iterator.h"
#include "tree-pass.h"
#include "tree-ssa-propagate.h"
@@ -104,16 +104,37 @@ some_nonzerop (tree t)
return !zerop;
}
-/* Compute a lattice value from T. It may be a gimple_val, or, as a
- special exception, a COMPLEX_EXPR. */
+
+/* Compute a lattice value from the components of a complex type REAL
+ and IMAG. */
static complex_lattice_t
-find_lattice_value (tree t)
+find_lattice_value_parts (tree real, tree imag)
{
- tree real, imag;
int r, i;
complex_lattice_t ret;
+ r = some_nonzerop (real);
+ i = some_nonzerop (imag);
+ ret = r * ONLY_REAL + i * ONLY_IMAG;
+
+ /* ??? On occasion we could do better than mapping 0+0i to real, but we
+ certainly don't want to leave it UNINITIALIZED, which eventually gets
+ mapped to VARYING. */
+ if (ret == UNINITIALIZED)
+ ret = ONLY_REAL;
+
+ return ret;
+}
+
+
+/* Compute a lattice value from gimple_val T. */
+
+static complex_lattice_t
+find_lattice_value (tree t)
+{
+ tree real, imag;
+
switch (TREE_CODE (t))
{
case SSA_NAME:
@@ -125,26 +146,11 @@ find_lattice_value (tree t)
imag = TREE_IMAGPART (t);
break;
- case COMPLEX_EXPR:
- real = TREE_OPERAND (t, 0);
- imag = TREE_OPERAND (t, 1);
- break;
-
default:
gcc_unreachable ();
}
- r = some_nonzerop (real);
- i = some_nonzerop (imag);
- ret = r*ONLY_REAL + i*ONLY_IMAG;
-
- /* ??? On occasion we could do better than mapping 0+0i to real, but we
- certainly don't want to leave it UNINITIALIZED, which eventually gets
- mapped to VARYING. */
- if (ret == UNINITIALIZED)
- ret = ONLY_REAL;
-
- return ret;
+ return find_lattice_value_parts (real, imag);
}
/* Determine if LHS is something for which we're interested in seeing
@@ -171,66 +177,72 @@ init_parameter_lattice_values (void)
SSA_NAME_VERSION (ssa_name), VARYING);
}
-/* Initialize DONT_SIMULATE_AGAIN for each stmt and phi. Return false if
- we found no statements we want to simulate, and thus there's nothing for
- the entire pass to do. */
+/* Initialize simulation state for each statement. Return false if we
+ found no statements we want to simulate, and thus there's nothing
+ for the entire pass to do. */
static bool
init_dont_simulate_again (void)
{
basic_block bb;
- block_stmt_iterator bsi;
- tree phi;
+ gimple_stmt_iterator gsi;
+ gimple phi;
bool saw_a_complex_op = false;
FOR_EACH_BB (bb)
{
- for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
- DONT_SIMULATE_AGAIN (phi) = !is_complex_reg (PHI_RESULT (phi));
+ for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+ {
+ phi = gsi_stmt (gsi);
+ prop_set_simulate_again (phi,
+ is_complex_reg (gimple_phi_result (phi)));
+ }
- for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
- tree orig_stmt, stmt, rhs = NULL;
- bool dsa;
+ gimple stmt;
+ tree op0, op1;
+ bool sim_again_p;
- orig_stmt = stmt = bsi_stmt (bsi);
+ stmt = gsi_stmt (gsi);
+ op0 = op1 = NULL_TREE;
/* Most control-altering statements must be initially
simulated, else we won't cover the entire cfg. */
- dsa = !stmt_ends_bb_p (stmt);
+ sim_again_p = stmt_ends_bb_p (stmt);
- switch (TREE_CODE (stmt))
+ switch (gimple_code (stmt))
{
- case RETURN_EXPR:
- /* We don't care what the lattice value of <retval> is,
- since it's never used as an input to another computation. */
- dsa = true;
- stmt = TREE_OPERAND (stmt, 0);
- if (!stmt || TREE_CODE (stmt) != GIMPLE_MODIFY_STMT)
- break;
- /* FALLTHRU */
+ case GIMPLE_CALL:
+ if (gimple_call_lhs (stmt))
+ sim_again_p = is_complex_reg (gimple_call_lhs (stmt));
+ break;
- case GIMPLE_MODIFY_STMT:
- dsa = !is_complex_reg (GIMPLE_STMT_OPERAND (stmt, 0));
- rhs = GIMPLE_STMT_OPERAND (stmt, 1);
+ case GIMPLE_ASSIGN:
+ sim_again_p = is_complex_reg (gimple_assign_lhs (stmt));
+ if (gimple_assign_rhs_code (stmt) == REALPART_EXPR
+ || gimple_assign_rhs_code (stmt) == IMAGPART_EXPR)
+ op0 = TREE_OPERAND (gimple_assign_rhs1 (stmt), 0);
+ else
+ op0 = gimple_assign_rhs1 (stmt);
+ if (gimple_num_ops (stmt) > 2)
+ op1 = gimple_assign_rhs2 (stmt);
break;
- case COND_EXPR:
- rhs = TREE_OPERAND (stmt, 0);
+ case GIMPLE_COND:
+ op0 = gimple_cond_lhs (stmt);
+ op1 = gimple_cond_rhs (stmt);
break;
default:
break;
}
- if (rhs)
- switch (TREE_CODE (rhs))
+ if (op0 || op1)
+ switch (gimple_expr_code (stmt))
{
case EQ_EXPR:
case NE_EXPR:
- rhs = TREE_OPERAND (rhs, 0);
- /* FALLTHRU */
-
case PLUS_EXPR:
case MINUS_EXPR:
case MULT_EXPR:
@@ -239,20 +251,25 @@ init_dont_simulate_again (void)
case FLOOR_DIV_EXPR:
case ROUND_DIV_EXPR:
case RDIV_EXPR:
+ if (TREE_CODE (TREE_TYPE (op0)) == COMPLEX_TYPE
+ || TREE_CODE (TREE_TYPE (op1)) == COMPLEX_TYPE)
+ saw_a_complex_op = true;
+ break;
+
case NEGATE_EXPR:
case CONJ_EXPR:
- if (TREE_CODE (TREE_TYPE (rhs)) == COMPLEX_TYPE)
+ if (TREE_CODE (TREE_TYPE (op0)) == COMPLEX_TYPE)
saw_a_complex_op = true;
break;
case REALPART_EXPR:
case IMAGPART_EXPR:
/* The total store transformation performed during
- gimplification creates such uninitialized loads
- and we need to lower the statement to be able
- to fix things up. */
- if (TREE_CODE (TREE_OPERAND (rhs, 0)) == SSA_NAME
- && ssa_undefined_value_p (TREE_OPERAND (rhs, 0)))
+ gimplification creates such uninitialized loads
+ and we need to lower the statement to be able
+ to fix things up. */
+ if (TREE_CODE (op0) == SSA_NAME
+ && ssa_undefined_value_p (op0))
saw_a_complex_op = true;
break;
@@ -260,7 +277,7 @@ init_dont_simulate_again (void)
break;
}
- DONT_SIMULATE_AGAIN (orig_stmt) = dsa;
+ prop_set_simulate_again (stmt, sim_again_p);
}
}
@@ -271,19 +288,18 @@ init_dont_simulate_again (void)
/* Evaluate statement STMT against the complex lattice defined above. */
static enum ssa_prop_result
-complex_visit_stmt (tree stmt, edge *taken_edge_p ATTRIBUTE_UNUSED,
+complex_visit_stmt (gimple stmt, edge *taken_edge_p ATTRIBUTE_UNUSED,
tree *result_p)
{
complex_lattice_t new_l, old_l, op1_l, op2_l;
unsigned int ver;
- tree lhs, rhs;
+ tree lhs;
- if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT)
+ lhs = gimple_get_lhs (stmt);
+ /* Skip anything but GIMPLE_ASSIGN and GIMPLE_CALL with a lhs. */
+ if (!lhs)
return SSA_PROP_VARYING;
- lhs = GIMPLE_STMT_OPERAND (stmt, 0);
- rhs = GIMPLE_STMT_OPERAND (stmt, 1);
-
/* These conditions should be satisfied due to the initial filter
set up in init_dont_simulate_again. */
gcc_assert (TREE_CODE (lhs) == SSA_NAME);
@@ -293,18 +309,22 @@ complex_visit_stmt (tree stmt, edge *taken_edge_p ATTRIBUTE_UNUSED,
ver = SSA_NAME_VERSION (lhs);
old_l = VEC_index (complex_lattice_t, complex_lattice_values, ver);
- switch (TREE_CODE (rhs))
+ switch (gimple_expr_code (stmt))
{
case SSA_NAME:
- case COMPLEX_EXPR:
case COMPLEX_CST:
- new_l = find_lattice_value (rhs);
+ new_l = find_lattice_value (gimple_assign_rhs1 (stmt));
+ break;
+
+ case COMPLEX_EXPR:
+ new_l = find_lattice_value_parts (gimple_assign_rhs1 (stmt),
+ gimple_assign_rhs2 (stmt));
break;
case PLUS_EXPR:
case MINUS_EXPR:
- op1_l = find_lattice_value (TREE_OPERAND (rhs, 0));
- op2_l = find_lattice_value (TREE_OPERAND (rhs, 1));
+ op1_l = find_lattice_value (gimple_assign_rhs1 (stmt));
+ op2_l = find_lattice_value (gimple_assign_rhs2 (stmt));
/* We've set up the lattice values such that IOR neatly
models addition. */
@@ -317,8 +337,8 @@ complex_visit_stmt (tree stmt, edge *taken_edge_p ATTRIBUTE_UNUSED,
case CEIL_DIV_EXPR:
case FLOOR_DIV_EXPR:
case ROUND_DIV_EXPR:
- op1_l = find_lattice_value (TREE_OPERAND (rhs, 0));
- op2_l = find_lattice_value (TREE_OPERAND (rhs, 1));
+ op1_l = find_lattice_value (gimple_assign_rhs1 (stmt));
+ op2_l = find_lattice_value (gimple_assign_rhs2 (stmt));
/* Obviously, if either varies, so does the result. */
if (op1_l == VARYING || op2_l == VARYING)
@@ -344,7 +364,7 @@ complex_visit_stmt (tree stmt, edge *taken_edge_p ATTRIBUTE_UNUSED,
case NEGATE_EXPR:
case CONJ_EXPR:
- new_l = find_lattice_value (TREE_OPERAND (rhs, 0));
+ new_l = find_lattice_value (gimple_assign_rhs1 (stmt));
break;
default:
@@ -363,14 +383,14 @@ complex_visit_stmt (tree stmt, edge *taken_edge_p ATTRIBUTE_UNUSED,
/* Evaluate a PHI node against the complex lattice defined above. */
static enum ssa_prop_result
-complex_visit_phi (tree phi)
+complex_visit_phi (gimple phi)
{
complex_lattice_t new_l, old_l;
unsigned int ver;
tree lhs;
int i;
- lhs = PHI_RESULT (phi);
+ lhs = gimple_phi_result (phi);
/* This condition should be satisfied due to the initial filter
set up in init_dont_simulate_again. */
@@ -378,8 +398,8 @@ complex_visit_phi (tree phi)
/* We've set up the lattice values such that IOR neatly models PHI meet. */
new_l = UNINITIALIZED;
- for (i = PHI_NUM_ARGS (phi) - 1; i >= 0; --i)
- new_l |= find_lattice_value (PHI_ARG_DEF (phi, i));
+ for (i = gimple_phi_num_args (phi) - 1; i >= 0; --i)
+ new_l |= find_lattice_value (gimple_phi_arg_def (phi, i));
ver = SSA_NAME_VERSION (lhs);
old_l = VEC_index (complex_lattice_t, complex_lattice_values, ver);
@@ -475,7 +495,7 @@ get_component_ssa_name (tree ssa_name, bool imag_p)
SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ret)
= SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ssa_name);
if (TREE_CODE (SSA_NAME_VAR (ssa_name)) == VAR_DECL
- && IS_EMPTY_STMT (SSA_NAME_DEF_STMT (ssa_name)))
+ && gimple_nop_p (SSA_NAME_DEF_STMT (ssa_name)))
{
SSA_NAME_DEF_STMT (ret) = SSA_NAME_DEF_STMT (ssa_name);
set_default_def (SSA_NAME_VAR (ret), ret);
@@ -487,15 +507,17 @@ get_component_ssa_name (tree ssa_name, bool imag_p)
return ret;
}
-/* Set a value for a complex component of SSA_NAME, return a STMT_LIST of
- stuff that needs doing. */
+/* Set a value for a complex component of SSA_NAME, return a
+ gimple_seq of stuff that needs doing. */
-static tree
+static gimple_seq
set_component_ssa_name (tree ssa_name, bool imag_p, tree value)
{
complex_lattice_t lattice = find_lattice_value (ssa_name);
size_t ssa_name_index;
- tree comp, list, last;
+ tree comp;
+ gimple last;
+ gimple_seq list;
/* We know the value must be zero, else there's a bug in our lattice
analysis. But the value may well be a variable known to contain
@@ -542,22 +564,21 @@ set_component_ssa_name (tree ssa_name, bool imag_p, tree value)
comp = get_component_ssa_name (ssa_name, imag_p);
/* Do all the work to assign VALUE to COMP. */
+ list = NULL;
value = force_gimple_operand (value, &list, false, NULL);
- last = build_gimple_modify_stmt (comp, value);
- append_to_statement_list (last, &list);
-
- gcc_assert (SSA_NAME_DEF_STMT (comp) == NULL);
- SSA_NAME_DEF_STMT (comp) = last;
+ last = gimple_build_assign (comp, value);
+ gimple_seq_add_stmt (&list, last);
+ gcc_assert (SSA_NAME_DEF_STMT (comp) == last);
return list;
}
/* Extract the real or imaginary part of a complex variable or constant.
Make sure that it's a proper gimple_val and gimplify it if not.
- Emit any new code before BSI. */
+ Emit any new code before gsi. */
static tree
-extract_component (block_stmt_iterator *bsi, tree t, bool imagpart_p,
+extract_component (gimple_stmt_iterator *gsi, tree t, bool imagpart_p,
bool gimple_p)
{
switch (TREE_CODE (t))
@@ -566,7 +587,7 @@ extract_component (block_stmt_iterator *bsi, tree t, bool imagpart_p,
return imagpart_p ? TREE_IMAGPART (t) : TREE_REALPART (t);
case COMPLEX_EXPR:
- return TREE_OPERAND (t, imagpart_p);
+ gcc_unreachable ();
case VAR_DECL:
case RESULT_DECL:
@@ -581,7 +602,8 @@ extract_component (block_stmt_iterator *bsi, tree t, bool imagpart_p,
inner_type, unshare_expr (t));
if (gimple_p)
- t = gimplify_val (bsi, inner_type, t);
+ t = force_gimple_operand_gsi (gsi, t, true, NULL, true,
+ GSI_SAME_STMT);
return t;
}
@@ -597,53 +619,53 @@ extract_component (block_stmt_iterator *bsi, tree t, bool imagpart_p,
/* Update the complex components of the ssa name on the lhs of STMT. */
static void
-update_complex_components (block_stmt_iterator *bsi, tree stmt, tree r, tree i)
+update_complex_components (gimple_stmt_iterator *gsi, gimple stmt, tree r,
+ tree i)
{
- tree lhs = GIMPLE_STMT_OPERAND (stmt, 0);
- tree list;
+ tree lhs;
+ gimple_seq list;
+
+ lhs = gimple_get_lhs (stmt);
list = set_component_ssa_name (lhs, false, r);
if (list)
- bsi_insert_after (bsi, list, BSI_CONTINUE_LINKING);
+ gsi_insert_seq_after (gsi, list, GSI_CONTINUE_LINKING);
list = set_component_ssa_name (lhs, true, i);
if (list)
- bsi_insert_after (bsi, list, BSI_CONTINUE_LINKING);
+ gsi_insert_seq_after (gsi, list, GSI_CONTINUE_LINKING);
}
static void
update_complex_components_on_edge (edge e, tree lhs, tree r, tree i)
{
- tree list;
+ gimple_seq list;
list = set_component_ssa_name (lhs, false, r);
if (list)
- bsi_insert_on_edge (e, list);
+ gsi_insert_seq_on_edge (e, list);
list = set_component_ssa_name (lhs, true, i);
if (list)
- bsi_insert_on_edge (e, list);
+ gsi_insert_seq_on_edge (e, list);
}
+
/* Update an assignment to a complex variable in place. */
static void
-update_complex_assignment (block_stmt_iterator *bsi, tree r, tree i)
+update_complex_assignment (gimple_stmt_iterator *gsi, tree r, tree i)
{
- tree stmt, mod;
- tree type;
-
- mod = stmt = bsi_stmt (*bsi);
- if (TREE_CODE (stmt) == RETURN_EXPR)
- mod = TREE_OPERAND (mod, 0);
- else if (gimple_in_ssa_p (cfun))
- update_complex_components (bsi, stmt, r, i);
-
- type = TREE_TYPE (GIMPLE_STMT_OPERAND (mod, 1));
- GIMPLE_STMT_OPERAND (mod, 1) = build2 (COMPLEX_EXPR, type, r, i);
- update_stmt (stmt);
+ gimple_stmt_iterator orig_si = *gsi;
+
+ if (gimple_in_ssa_p (cfun))
+ update_complex_components (gsi, gsi_stmt (*gsi), r, i);
+
+ gimple_assign_set_rhs_with_ops (&orig_si, COMPLEX_EXPR, r, i);
+ update_stmt (gsi_stmt (orig_si));
}
+
/* Generate code at the entry point of the function to initialize the
component variables for a complex parameter. */
@@ -678,49 +700,54 @@ update_parameter_components (void)
static void
update_phi_components (basic_block bb)
{
- tree phi;
+ gimple_stmt_iterator gsi;
- for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
- if (is_complex_reg (PHI_RESULT (phi)))
- {
- tree lr, li, pr = NULL, pi = NULL;
- unsigned int i, n;
+ for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+ {
+ gimple phi = gsi_stmt (gsi);
- lr = get_component_ssa_name (PHI_RESULT (phi), false);
- if (TREE_CODE (lr) == SSA_NAME)
- {
- pr = create_phi_node (lr, bb);
- SSA_NAME_DEF_STMT (lr) = pr;
- }
+ if (is_complex_reg (gimple_phi_result (phi)))
+ {
+ tree lr, li;
+ gimple pr = NULL, pi = NULL;
+ unsigned int i, n;
- li = get_component_ssa_name (PHI_RESULT (phi), true);
- if (TREE_CODE (li) == SSA_NAME)
- {
- pi = create_phi_node (li, bb);
- SSA_NAME_DEF_STMT (li) = pi;
- }
-
- for (i = 0, n = PHI_NUM_ARGS (phi); i < n; ++i)
- {
- tree comp, arg = PHI_ARG_DEF (phi, i);
- if (pr)
- {
- comp = extract_component (NULL, arg, false, false);
- SET_PHI_ARG_DEF (pr, i, comp);
- }
- if (pi)
- {
- comp = extract_component (NULL, arg, true, false);
- SET_PHI_ARG_DEF (pi, i, comp);
- }
- }
- }
+ lr = get_component_ssa_name (gimple_phi_result (phi), false);
+ if (TREE_CODE (lr) == SSA_NAME)
+ {
+ pr = create_phi_node (lr, bb);
+ SSA_NAME_DEF_STMT (lr) = pr;
+ }
+
+ li = get_component_ssa_name (gimple_phi_result (phi), true);
+ if (TREE_CODE (li) == SSA_NAME)
+ {
+ pi = create_phi_node (li, bb);
+ SSA_NAME_DEF_STMT (li) = pi;
+ }
+
+ for (i = 0, n = gimple_phi_num_args (phi); i < n; ++i)
+ {
+ tree comp, arg = gimple_phi_arg_def (phi, i);
+ if (pr)
+ {
+ comp = extract_component (NULL, arg, false, false);
+ SET_PHI_ARG_DEF (pr, i, comp);
+ }
+ if (pi)
+ {
+ comp = extract_component (NULL, arg, true, false);
+ SET_PHI_ARG_DEF (pi, i, comp);
+ }
+ }
+ }
+ }
}
/* Mark each virtual op in STMT for ssa update. */
static void
-update_all_vops (tree stmt)
+update_all_vops (gimple stmt)
{
ssa_op_iter iter;
tree sym;
@@ -733,18 +760,35 @@ update_all_vops (tree stmt)
}
}
+
/* Expand a complex move to scalars. */
static void
-expand_complex_move (block_stmt_iterator *bsi, tree stmt, tree type,
- tree lhs, tree rhs)
+expand_complex_move (gimple_stmt_iterator *gsi, tree type)
{
tree inner_type = TREE_TYPE (type);
- tree r, i;
+ tree r, i, lhs, rhs;
+ gimple stmt = gsi_stmt (*gsi);
+
+ if (is_gimple_assign (stmt))
+ {
+ lhs = gimple_assign_lhs (stmt);
+ if (gimple_num_ops (stmt) == 2)
+ rhs = gimple_assign_rhs1 (stmt);
+ else
+ rhs = NULL_TREE;
+ }
+ else if (is_gimple_call (stmt))
+ {
+ lhs = gimple_call_lhs (stmt);
+ rhs = NULL_TREE;
+ }
+ else
+ gcc_unreachable ();
if (TREE_CODE (lhs) == SSA_NAME)
{
- if (is_ctrl_altering_stmt (bsi_stmt (*bsi)))
+ if (is_ctrl_altering_stmt (stmt))
{
edge_iterator ei;
edge e;
@@ -752,7 +796,7 @@ expand_complex_move (block_stmt_iterator *bsi, tree stmt, tree type,
/* The value is not assigned on the exception edges, so we need not
concern ourselves there. We do need to update on the fallthru
edge. Find it. */
- FOR_EACH_EDGE (e, ei, bsi->bb->succs)
+ FOR_EACH_EDGE (e, ei, gsi_bb (*gsi)->succs)
if (e->flags & EDGE_FALLTHRU)
goto found_fallthru;
gcc_unreachable ();
@@ -762,47 +806,57 @@ expand_complex_move (block_stmt_iterator *bsi, tree stmt, tree type,
i = build1 (IMAGPART_EXPR, inner_type, lhs);
update_complex_components_on_edge (e, lhs, r, i);
}
- else if (TREE_CODE (rhs) == CALL_EXPR || TREE_SIDE_EFFECTS (rhs)
- || TREE_CODE (rhs) == PAREN_EXPR)
+ else if (is_gimple_call (stmt)
+ || gimple_has_side_effects (stmt)
+ || gimple_assign_rhs_code (stmt) == PAREN_EXPR)
{
r = build1 (REALPART_EXPR, inner_type, lhs);
i = build1 (IMAGPART_EXPR, inner_type, lhs);
- update_complex_components (bsi, stmt, r, i);
+ update_complex_components (gsi, stmt, r, i);
}
else
{
- update_all_vops (bsi_stmt (*bsi));
- r = extract_component (bsi, rhs, 0, true);
- i = extract_component (bsi, rhs, 1, true);
- update_complex_assignment (bsi, r, i);
+ update_all_vops (stmt);
+ if (gimple_assign_rhs_code (stmt) != COMPLEX_EXPR)
+ {
+ r = extract_component (gsi, rhs, 0, true);
+ i = extract_component (gsi, rhs, 1, true);
+ }
+ else
+ {
+ r = gimple_assign_rhs1 (stmt);
+ i = gimple_assign_rhs2 (stmt);
+ }
+ update_complex_assignment (gsi, r, i);
}
}
- else if (TREE_CODE (rhs) == SSA_NAME && !TREE_SIDE_EFFECTS (lhs))
+ else if (rhs && TREE_CODE (rhs) == SSA_NAME && !TREE_SIDE_EFFECTS (lhs))
{
tree x;
+ gimple t;
- r = extract_component (bsi, rhs, 0, false);
- i = extract_component (bsi, rhs, 1, false);
+ r = extract_component (gsi, rhs, 0, false);
+ i = extract_component (gsi, rhs, 1, false);
x = build1 (REALPART_EXPR, inner_type, unshare_expr (lhs));
- x = build_gimple_modify_stmt (x, r);
- bsi_insert_before (bsi, x, BSI_SAME_STMT);
+ t = gimple_build_assign (x, r);
+ gsi_insert_before (gsi, t, GSI_SAME_STMT);
- if (stmt == bsi_stmt (*bsi))
+ if (stmt == gsi_stmt (*gsi))
{
x = build1 (IMAGPART_EXPR, inner_type, unshare_expr (lhs));
- GIMPLE_STMT_OPERAND (stmt, 0) = x;
- GIMPLE_STMT_OPERAND (stmt, 1) = i;
+ gimple_assign_set_lhs (stmt, x);
+ gimple_assign_set_rhs1 (stmt, i);
}
else
{
x = build1 (IMAGPART_EXPR, inner_type, unshare_expr (lhs));
- x = build_gimple_modify_stmt (x, i);
- bsi_insert_before (bsi, x, BSI_SAME_STMT);
+ t = gimple_build_assign (x, i);
+ gsi_insert_before (gsi, t, GSI_SAME_STMT);
- stmt = bsi_stmt (*bsi);
- gcc_assert (TREE_CODE (stmt) == RETURN_EXPR);
- GIMPLE_STMT_OPERAND (stmt, 0) = lhs;
+ stmt = gsi_stmt (*gsi);
+ gcc_assert (gimple_code (stmt) == GIMPLE_RETURN);
+ gimple_return_set_retval (stmt, lhs);
}
update_all_vops (stmt);
@@ -816,7 +870,7 @@ expand_complex_move (block_stmt_iterator *bsi, tree stmt, tree type,
*/
static void
-expand_complex_addition (block_stmt_iterator *bsi, tree inner_type,
+expand_complex_addition (gimple_stmt_iterator *gsi, tree inner_type,
tree ar, tree ai, tree br, tree bi,
enum tree_code code,
complex_lattice_t al, complex_lattice_t bl)
@@ -826,21 +880,21 @@ expand_complex_addition (block_stmt_iterator *bsi, tree inner_type,
switch (PAIR (al, bl))
{
case PAIR (ONLY_REAL, ONLY_REAL):
- rr = gimplify_build2 (bsi, code, inner_type, ar, br);
+ rr = gimplify_build2 (gsi, code, inner_type, ar, br);
ri = ai;
break;
case PAIR (ONLY_REAL, ONLY_IMAG):
rr = ar;
if (code == MINUS_EXPR)
- ri = gimplify_build2 (bsi, MINUS_EXPR, inner_type, ai, bi);
+ ri = gimplify_build2 (gsi, MINUS_EXPR, inner_type, ai, bi);
else
ri = bi;
break;
case PAIR (ONLY_IMAG, ONLY_REAL):
if (code == MINUS_EXPR)
- rr = gimplify_build2 (bsi, MINUS_EXPR, inner_type, ar, br);
+ rr = gimplify_build2 (gsi, MINUS_EXPR, inner_type, ar, br);
else
rr = br;
ri = ai;
@@ -848,23 +902,23 @@ expand_complex_addition (block_stmt_iterator *bsi, tree inner_type,
case PAIR (ONLY_IMAG, ONLY_IMAG):
rr = ar;
- ri = gimplify_build2 (bsi, code, inner_type, ai, bi);
+ ri = gimplify_build2 (gsi, code, inner_type, ai, bi);
break;
case PAIR (VARYING, ONLY_REAL):
- rr = gimplify_build2 (bsi, code, inner_type, ar, br);
+ rr = gimplify_build2 (gsi, code, inner_type, ar, br);
ri = ai;
break;
case PAIR (VARYING, ONLY_IMAG):
rr = ar;
- ri = gimplify_build2 (bsi, code, inner_type, ai, bi);
+ ri = gimplify_build2 (gsi, code, inner_type, ai, bi);
break;
case PAIR (ONLY_REAL, VARYING):
if (code == MINUS_EXPR)
goto general;
- rr = gimplify_build2 (bsi, code, inner_type, ar, br);
+ rr = gimplify_build2 (gsi, code, inner_type, ar, br);
ri = bi;
break;
@@ -872,38 +926,41 @@ expand_complex_addition (block_stmt_iterator *bsi, tree inner_type,
if (code == MINUS_EXPR)
goto general;
rr = br;
- ri = gimplify_build2 (bsi, code, inner_type, ai, bi);
+ ri = gimplify_build2 (gsi, code, inner_type, ai, bi);
break;
case PAIR (VARYING, VARYING):
general:
- rr = gimplify_build2 (bsi, code, inner_type, ar, br);
- ri = gimplify_build2 (bsi, code, inner_type, ai, bi);
+ rr = gimplify_build2 (gsi, code, inner_type, ar, br);
+ ri = gimplify_build2 (gsi, code, inner_type, ai, bi);
break;
default:
gcc_unreachable ();
}
- update_complex_assignment (bsi, rr, ri);
+ update_complex_assignment (gsi, rr, ri);
}
/* Expand a complex multiplication or division to a libcall to the c99
compliant routines. */
static void
-expand_complex_libcall (block_stmt_iterator *bsi, tree ar, tree ai,
+expand_complex_libcall (gimple_stmt_iterator *gsi, tree ar, tree ai,
tree br, tree bi, enum tree_code code)
{
enum machine_mode mode;
enum built_in_function bcode;
- tree fn, stmt, type;
+ tree fn, type, lhs;
+ gimple stmt;
- stmt = bsi_stmt (*bsi);
- type = TREE_TYPE (GIMPLE_STMT_OPERAND (stmt, 1));
+ stmt = gsi_stmt (*gsi);
+ lhs = gimple_assign_lhs (stmt);
+ type = TREE_TYPE (lhs);
mode = TYPE_MODE (type);
gcc_assert (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT);
+
if (code == MULT_EXPR)
bcode = BUILT_IN_COMPLEX_MUL_MIN + mode - MIN_MODE_COMPLEX_FLOAT;
else if (code == RDIV_EXPR)
@@ -912,16 +969,18 @@ expand_complex_libcall (block_stmt_iterator *bsi, tree ar, tree ai,
gcc_unreachable ();
fn = built_in_decls[bcode];
- GIMPLE_STMT_OPERAND (stmt, 1) = build_call_expr (fn, 4, ar, ai, br, bi);
+ stmt = gimple_build_call (fn, 4, ar, ai, br, bi);
+ gimple_call_set_lhs (stmt, lhs);
update_stmt (stmt);
+ gsi_replace (gsi, stmt, true);
if (gimple_in_ssa_p (cfun))
{
- tree lhs = GIMPLE_STMT_OPERAND (stmt, 0);
type = TREE_TYPE (type);
- update_complex_components (bsi, stmt,
+ update_complex_components (gsi, stmt,
build1 (REALPART_EXPR, type, lhs),
build1 (IMAGPART_EXPR, type, lhs));
+ SSA_NAME_DEF_STMT (lhs) = stmt;
}
}
@@ -930,7 +989,7 @@ expand_complex_libcall (block_stmt_iterator *bsi, tree ar, tree ai,
*/
static void
-expand_complex_multiplication (block_stmt_iterator *bsi, tree inner_type,
+expand_complex_multiplication (gimple_stmt_iterator *gsi, tree inner_type,
tree ar, tree ai, tree br, tree bi,
complex_lattice_t al, complex_lattice_t bl)
{
@@ -947,7 +1006,7 @@ expand_complex_multiplication (block_stmt_iterator *bsi, tree inner_type,
switch (PAIR (al, bl))
{
case PAIR (ONLY_REAL, ONLY_REAL):
- rr = gimplify_build2 (bsi, MULT_EXPR, inner_type, ar, br);
+ rr = gimplify_build2 (gsi, MULT_EXPR, inner_type, ar, br);
ri = ai;
break;
@@ -957,49 +1016,49 @@ expand_complex_multiplication (block_stmt_iterator *bsi, tree inner_type,
&& REAL_VALUES_IDENTICAL (TREE_REAL_CST (ai), dconst1))
ri = br;
else
- ri = gimplify_build2 (bsi, MULT_EXPR, inner_type, ai, br);
+ ri = gimplify_build2 (gsi, MULT_EXPR, inner_type, ai, br);
break;
case PAIR (ONLY_IMAG, ONLY_IMAG):
- rr = gimplify_build2 (bsi, MULT_EXPR, inner_type, ai, bi);
- rr = gimplify_build1 (bsi, NEGATE_EXPR, inner_type, rr);
+ rr = gimplify_build2 (gsi, MULT_EXPR, inner_type, ai, bi);
+ rr = gimplify_build1 (gsi, NEGATE_EXPR, inner_type, rr);
ri = ar;
break;
case PAIR (VARYING, ONLY_REAL):
- rr = gimplify_build2 (bsi, MULT_EXPR, inner_type, ar, br);
- ri = gimplify_build2 (bsi, MULT_EXPR, inner_type, ai, br);
+ rr = gimplify_build2 (gsi, MULT_EXPR, inner_type, ar, br);
+ ri = gimplify_build2 (gsi, MULT_EXPR, inner_type, ai, br);
break;
case PAIR (VARYING, ONLY_IMAG):
- rr = gimplify_build2 (bsi, MULT_EXPR, inner_type, ai, bi);
- rr = gimplify_build1 (bsi, NEGATE_EXPR, inner_type, rr);
- ri = gimplify_build2 (bsi, MULT_EXPR, inner_type, ar, bi);
+ rr = gimplify_build2 (gsi, MULT_EXPR, inner_type, ai, bi);
+ rr = gimplify_build1 (gsi, NEGATE_EXPR, inner_type, rr);
+ ri = gimplify_build2 (gsi, MULT_EXPR, inner_type, ar, bi);
break;
case PAIR (VARYING, VARYING):
if (flag_complex_method == 2 && SCALAR_FLOAT_TYPE_P (inner_type))
{
- expand_complex_libcall (bsi, ar, ai, br, bi, MULT_EXPR);
+ expand_complex_libcall (gsi, ar, ai, br, bi, MULT_EXPR);
return;
}
else
{
tree t1, t2, t3, t4;
- t1 = gimplify_build2 (bsi, MULT_EXPR, inner_type, ar, br);
- t2 = gimplify_build2 (bsi, MULT_EXPR, inner_type, ai, bi);
- t3 = gimplify_build2 (bsi, MULT_EXPR, inner_type, ar, bi);
+ t1 = gimplify_build2 (gsi, MULT_EXPR, inner_type, ar, br);
+ t2 = gimplify_build2 (gsi, MULT_EXPR, inner_type, ai, bi);
+ t3 = gimplify_build2 (gsi, MULT_EXPR, inner_type, ar, bi);
/* Avoid expanding redundant multiplication for the common
case of squaring a complex number. */
if (ar == br && ai == bi)
t4 = t3;
else
- t4 = gimplify_build2 (bsi, MULT_EXPR, inner_type, ai, br);
+ t4 = gimplify_build2 (gsi, MULT_EXPR, inner_type, ai, br);
- rr = gimplify_build2 (bsi, MINUS_EXPR, inner_type, t1, t2);
- ri = gimplify_build2 (bsi, PLUS_EXPR, inner_type, t3, t4);
+ rr = gimplify_build2 (gsi, MINUS_EXPR, inner_type, t1, t2);
+ ri = gimplify_build2 (gsi, PLUS_EXPR, inner_type, t3, t4);
}
break;
@@ -1007,7 +1066,7 @@ expand_complex_multiplication (block_stmt_iterator *bsi, tree inner_type,
gcc_unreachable ();
}
- update_complex_assignment (bsi, rr, ri);
+ update_complex_assignment (gsi, rr, ri);
}
/* Expand complex division to scalars, straightforward algorithm.
@@ -1016,43 +1075,44 @@ expand_complex_multiplication (block_stmt_iterator *bsi, tree inner_type,
*/
static void
-expand_complex_div_straight (block_stmt_iterator *bsi, tree inner_type,
+expand_complex_div_straight (gimple_stmt_iterator *gsi, tree inner_type,
tree ar, tree ai, tree br, tree bi,
enum tree_code code)
{
tree rr, ri, div, t1, t2, t3;
- t1 = gimplify_build2 (bsi, MULT_EXPR, inner_type, br, br);
- t2 = gimplify_build2 (bsi, MULT_EXPR, inner_type, bi, bi);
- div = gimplify_build2 (bsi, PLUS_EXPR, inner_type, t1, t2);
+ t1 = gimplify_build2 (gsi, MULT_EXPR, inner_type, br, br);
+ t2 = gimplify_build2 (gsi, MULT_EXPR, inner_type, bi, bi);
+ div = gimplify_build2 (gsi, PLUS_EXPR, inner_type, t1, t2);
- t1 = gimplify_build2 (bsi, MULT_EXPR, inner_type, ar, br);
- t2 = gimplify_build2 (bsi, MULT_EXPR, inner_type, ai, bi);
- t3 = gimplify_build2 (bsi, PLUS_EXPR, inner_type, t1, t2);
- rr = gimplify_build2 (bsi, code, inner_type, t3, div);
+ t1 = gimplify_build2 (gsi, MULT_EXPR, inner_type, ar, br);
+ t2 = gimplify_build2 (gsi, MULT_EXPR, inner_type, ai, bi);
+ t3 = gimplify_build2 (gsi, PLUS_EXPR, inner_type, t1, t2);
+ rr = gimplify_build2 (gsi, code, inner_type, t3, div);
- t1 = gimplify_build2 (bsi, MULT_EXPR, inner_type, ai, br);
- t2 = gimplify_build2 (bsi, MULT_EXPR, inner_type, ar, bi);
- t3 = gimplify_build2 (bsi, MINUS_EXPR, inner_type, t1, t2);
- ri = gimplify_build2 (bsi, code, inner_type, t3, div);
+ t1 = gimplify_build2 (gsi, MULT_EXPR, inner_type, ai, br);
+ t2 = gimplify_build2 (gsi, MULT_EXPR, inner_type, ar, bi);
+ t3 = gimplify_build2 (gsi, MINUS_EXPR, inner_type, t1, t2);
+ ri = gimplify_build2 (gsi, code, inner_type, t3, div);
- update_complex_assignment (bsi, rr, ri);
+ update_complex_assignment (gsi, rr, ri);
}
/* Expand complex division to scalars, modified algorithm to minimize
overflow with wide input ranges. */
static void
-expand_complex_div_wide (block_stmt_iterator *bsi, tree inner_type,
+expand_complex_div_wide (gimple_stmt_iterator *gsi, tree inner_type,
tree ar, tree ai, tree br, tree bi,
enum tree_code code)
{
tree rr, ri, ratio, div, t1, t2, tr, ti, compare;
basic_block bb_cond, bb_true, bb_false, bb_join;
+ gimple stmt;
/* Examine |br| < |bi|, and branch. */
- t1 = gimplify_build1 (bsi, ABS_EXPR, inner_type, br);
- t2 = gimplify_build1 (bsi, ABS_EXPR, inner_type, bi);
+ t1 = gimplify_build1 (gsi, ABS_EXPR, inner_type, br);
+ t2 = gimplify_build1 (gsi, ABS_EXPR, inner_type, bi);
compare = fold_build2 (LT_EXPR, boolean_type_node, t1, t2);
STRIP_NOPS (compare);
@@ -1061,20 +1121,25 @@ expand_complex_div_wide (block_stmt_iterator *bsi, tree inner_type,
if (!TREE_CONSTANT (compare))
{
edge e;
+ gimple stmt;
tree cond, tmp;
tmp = create_tmp_var (boolean_type_node, NULL);
- cond = build_gimple_modify_stmt (tmp, compare);
+ stmt = gimple_build_assign (tmp, compare);
if (gimple_in_ssa_p (cfun))
- tmp = make_ssa_name (tmp, cond);
- GIMPLE_STMT_OPERAND (cond, 0) = tmp;
- bsi_insert_before (bsi, cond, BSI_SAME_STMT);
+ {
+ tmp = make_ssa_name (tmp, stmt);
+ gimple_assign_set_lhs (stmt, tmp);
+ }
+
+ gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
- cond = build3 (COND_EXPR, void_type_node, tmp, NULL_TREE, NULL_TREE);
- bsi_insert_before (bsi, cond, BSI_SAME_STMT);
+ cond = fold_build2 (EQ_EXPR, boolean_type_node, tmp, boolean_true_node);
+ stmt = gimple_build_cond_from_tree (cond, NULL_TREE, NULL_TREE);
+ gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
/* Split the original block, and create the TRUE and FALSE blocks. */
- e = split_block (bsi->bb, cond);
+ e = split_block (gsi_bb (*gsi), stmt);
bb_cond = e->src;
bb_join = e->dest;
bb_true = create_empty_bb (bb_cond);
@@ -1110,31 +1175,31 @@ expand_complex_div_wide (block_stmt_iterator *bsi, tree inner_type,
{
if (bb_true)
{
- *bsi = bsi_last (bb_true);
- bsi_insert_after (bsi, build_empty_stmt (), BSI_NEW_STMT);
+ *gsi = gsi_last_bb (bb_true);
+ gsi_insert_after (gsi, gimple_build_nop (), GSI_NEW_STMT);
}
- ratio = gimplify_build2 (bsi, code, inner_type, br, bi);
+ ratio = gimplify_build2 (gsi, code, inner_type, br, bi);
- t1 = gimplify_build2 (bsi, MULT_EXPR, inner_type, br, ratio);
- div = gimplify_build2 (bsi, PLUS_EXPR, inner_type, t1, bi);
+ t1 = gimplify_build2 (gsi, MULT_EXPR, inner_type, br, ratio);
+ div = gimplify_build2 (gsi, PLUS_EXPR, inner_type, t1, bi);
- t1 = gimplify_build2 (bsi, MULT_EXPR, inner_type, ar, ratio);
- tr = gimplify_build2 (bsi, PLUS_EXPR, inner_type, t1, ai);
+ t1 = gimplify_build2 (gsi, MULT_EXPR, inner_type, ar, ratio);
+ tr = gimplify_build2 (gsi, PLUS_EXPR, inner_type, t1, ai);
- t1 = gimplify_build2 (bsi, MULT_EXPR, inner_type, ai, ratio);
- ti = gimplify_build2 (bsi, MINUS_EXPR, inner_type, t1, ar);
+ t1 = gimplify_build2 (gsi, MULT_EXPR, inner_type, ai, ratio);
+ ti = gimplify_build2 (gsi, MINUS_EXPR, inner_type, t1, ar);
- tr = gimplify_build2 (bsi, code, inner_type, tr, div);
- ti = gimplify_build2 (bsi, code, inner_type, ti, div);
+ tr = gimplify_build2 (gsi, code, inner_type, tr, div);
+ ti = gimplify_build2 (gsi, code, inner_type, ti, div);
if (bb_true)
{
- t1 = build_gimple_modify_stmt (rr, tr);
- bsi_insert_before (bsi, t1, BSI_SAME_STMT);
- t1 = build_gimple_modify_stmt (ri, ti);
- bsi_insert_before (bsi, t1, BSI_SAME_STMT);
- bsi_remove (bsi, true);
+ stmt = gimple_build_assign (rr, tr);
+ gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
+ stmt = gimple_build_assign (ri, ti);
+ gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
+ gsi_remove (gsi, true);
}
}
@@ -1149,46 +1214,46 @@ expand_complex_div_wide (block_stmt_iterator *bsi, tree inner_type,
{
if (bb_false)
{
- *bsi = bsi_last (bb_false);
- bsi_insert_after (bsi, build_empty_stmt (), BSI_NEW_STMT);
+ *gsi = gsi_last_bb (bb_false);
+ gsi_insert_after (gsi, gimple_build_nop (), GSI_NEW_STMT);
}
- ratio = gimplify_build2 (bsi, code, inner_type, bi, br);
+ ratio = gimplify_build2 (gsi, code, inner_type, bi, br);
- t1 = gimplify_build2 (bsi, MULT_EXPR, inner_type, bi, ratio);
- div = gimplify_build2 (bsi, PLUS_EXPR, inner_type, t1, br);
+ t1 = gimplify_build2 (gsi, MULT_EXPR, inner_type, bi, ratio);
+ div = gimplify_build2 (gsi, PLUS_EXPR, inner_type, t1, br);
- t1 = gimplify_build2 (bsi, MULT_EXPR, inner_type, ai, ratio);
- tr = gimplify_build2 (bsi, PLUS_EXPR, inner_type, t1, ar);
+ t1 = gimplify_build2 (gsi, MULT_EXPR, inner_type, ai, ratio);
+ tr = gimplify_build2 (gsi, PLUS_EXPR, inner_type, t1, ar);
- t1 = gimplify_build2 (bsi, MULT_EXPR, inner_type, ar, ratio);
- ti = gimplify_build2 (bsi, MINUS_EXPR, inner_type, ai, t1);
+ t1 = gimplify_build2 (gsi, MULT_EXPR, inner_type, ar, ratio);
+ ti = gimplify_build2 (gsi, MINUS_EXPR, inner_type, ai, t1);
- tr = gimplify_build2 (bsi, code, inner_type, tr, div);
- ti = gimplify_build2 (bsi, code, inner_type, ti, div);
+ tr = gimplify_build2 (gsi, code, inner_type, tr, div);
+ ti = gimplify_build2 (gsi, code, inner_type, ti, div);
if (bb_false)
{
- t1 = build_gimple_modify_stmt (rr, tr);
- bsi_insert_before (bsi, t1, BSI_SAME_STMT);
- t1 = build_gimple_modify_stmt (ri, ti);
- bsi_insert_before (bsi, t1, BSI_SAME_STMT);
- bsi_remove (bsi, true);
+ stmt = gimple_build_assign (rr, tr);
+ gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
+ stmt = gimple_build_assign (ri, ti);
+ gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
+ gsi_remove (gsi, true);
}
}
if (bb_join)
- *bsi = bsi_start (bb_join);
+ *gsi = gsi_start_bb (bb_join);
else
rr = tr, ri = ti;
- update_complex_assignment (bsi, rr, ri);
+ update_complex_assignment (gsi, rr, ri);
}
/* Expand complex division to scalars. */
static void
-expand_complex_division (block_stmt_iterator *bsi, tree inner_type,
+expand_complex_division (gimple_stmt_iterator *gsi, tree inner_type,
tree ar, tree ai, tree br, tree bi,
enum tree_code code,
complex_lattice_t al, complex_lattice_t bl)
@@ -1198,35 +1263,35 @@ expand_complex_division (block_stmt_iterator *bsi, tree inner_type,
switch (PAIR (al, bl))
{
case PAIR (ONLY_REAL, ONLY_REAL):
- rr = gimplify_build2 (bsi, code, inner_type, ar, br);
+ rr = gimplify_build2 (gsi, code, inner_type, ar, br);
ri = ai;
break;
case PAIR (ONLY_REAL, ONLY_IMAG):
rr = ai;
- ri = gimplify_build2 (bsi, code, inner_type, ar, bi);
- ri = gimplify_build1 (bsi, NEGATE_EXPR, inner_type, ri);
+ ri = gimplify_build2 (gsi, code, inner_type, ar, bi);
+ ri = gimplify_build1 (gsi, NEGATE_EXPR, inner_type, ri);
break;
case PAIR (ONLY_IMAG, ONLY_REAL):
rr = ar;
- ri = gimplify_build2 (bsi, code, inner_type, ai, br);
+ ri = gimplify_build2 (gsi, code, inner_type, ai, br);
break;
case PAIR (ONLY_IMAG, ONLY_IMAG):
- rr = gimplify_build2 (bsi, code, inner_type, ai, bi);
+ rr = gimplify_build2 (gsi, code, inner_type, ai, bi);
ri = ar;
break;
case PAIR (VARYING, ONLY_REAL):
- rr = gimplify_build2 (bsi, code, inner_type, ar, br);
- ri = gimplify_build2 (bsi, code, inner_type, ai, br);
+ rr = gimplify_build2 (gsi, code, inner_type, ar, br);
+ ri = gimplify_build2 (gsi, code, inner_type, ai, br);
break;
case PAIR (VARYING, ONLY_IMAG):
- rr = gimplify_build2 (bsi, code, inner_type, ai, bi);
- ri = gimplify_build2 (bsi, code, inner_type, ar, bi);
- ri = gimplify_build1 (bsi, NEGATE_EXPR, inner_type, ri);
+ rr = gimplify_build2 (gsi, code, inner_type, ai, bi);
+ ri = gimplify_build2 (gsi, code, inner_type, ar, bi);
+ ri = gimplify_build1 (gsi, NEGATE_EXPR, inner_type, ri);
case PAIR (ONLY_REAL, VARYING):
case PAIR (ONLY_IMAG, VARYING):
@@ -1235,20 +1300,20 @@ expand_complex_division (block_stmt_iterator *bsi, tree inner_type,
{
case 0:
/* straightforward implementation of complex divide acceptable. */
- expand_complex_div_straight (bsi, inner_type, ar, ai, br, bi, code);
+ expand_complex_div_straight (gsi, inner_type, ar, ai, br, bi, code);
break;
case 2:
if (SCALAR_FLOAT_TYPE_P (inner_type))
{
- expand_complex_libcall (bsi, ar, ai, br, bi, code);
+ expand_complex_libcall (gsi, ar, ai, br, bi, code);
break;
}
/* FALLTHRU */
case 1:
/* wide ranges of inputs must work for complex divide. */
- expand_complex_div_wide (bsi, inner_type, ar, ai, br, bi, code);
+ expand_complex_div_wide (gsi, inner_type, ar, ai, br, bi, code);
break;
default:
@@ -1260,7 +1325,7 @@ expand_complex_division (block_stmt_iterator *bsi, tree inner_type,
gcc_unreachable ();
}
- update_complex_assignment (bsi, rr, ri);
+ update_complex_assignment (gsi, rr, ri);
}
/* Expand complex negation to scalars:
@@ -1268,15 +1333,15 @@ expand_complex_division (block_stmt_iterator *bsi, tree inner_type,
*/
static void
-expand_complex_negation (block_stmt_iterator *bsi, tree inner_type,
+expand_complex_negation (gimple_stmt_iterator *gsi, tree inner_type,
tree ar, tree ai)
{
tree rr, ri;
- rr = gimplify_build1 (bsi, NEGATE_EXPR, inner_type, ar);
- ri = gimplify_build1 (bsi, NEGATE_EXPR, inner_type, ai);
+ rr = gimplify_build1 (gsi, NEGATE_EXPR, inner_type, ar);
+ ri = gimplify_build1 (gsi, NEGATE_EXPR, inner_type, ai);
- update_complex_assignment (bsi, rr, ri);
+ update_complex_assignment (gsi, rr, ri);
}
/* Expand complex conjugate to scalars:
@@ -1284,44 +1349,52 @@ expand_complex_negation (block_stmt_iterator *bsi, tree inner_type,
*/
static void
-expand_complex_conjugate (block_stmt_iterator *bsi, tree inner_type,
+expand_complex_conjugate (gimple_stmt_iterator *gsi, tree inner_type,
tree ar, tree ai)
{
tree ri;
- ri = gimplify_build1 (bsi, NEGATE_EXPR, inner_type, ai);
+ ri = gimplify_build1 (gsi, NEGATE_EXPR, inner_type, ai);
- update_complex_assignment (bsi, ar, ri);
+ update_complex_assignment (gsi, ar, ri);
}
/* Expand complex comparison (EQ or NE only). */
static void
-expand_complex_comparison (block_stmt_iterator *bsi, tree ar, tree ai,
+expand_complex_comparison (gimple_stmt_iterator *gsi, tree ar, tree ai,
tree br, tree bi, enum tree_code code)
{
- tree cr, ci, cc, stmt, expr, type;
+ tree cr, ci, cc, type;
+ gimple stmt;
- cr = gimplify_build2 (bsi, code, boolean_type_node, ar, br);
- ci = gimplify_build2 (bsi, code, boolean_type_node, ai, bi);
- cc = gimplify_build2 (bsi,
+ cr = gimplify_build2 (gsi, code, boolean_type_node, ar, br);
+ ci = gimplify_build2 (gsi, code, boolean_type_node, ai, bi);
+ cc = gimplify_build2 (gsi,
(code == EQ_EXPR ? TRUTH_AND_EXPR : TRUTH_OR_EXPR),
boolean_type_node, cr, ci);
- stmt = expr = bsi_stmt (*bsi);
+ stmt = gsi_stmt (*gsi);
- switch (TREE_CODE (stmt))
+ switch (gimple_code (stmt))
{
- case RETURN_EXPR:
- expr = TREE_OPERAND (stmt, 0);
- /* FALLTHRU */
- case GIMPLE_MODIFY_STMT:
- type = TREE_TYPE (GIMPLE_STMT_OPERAND (expr, 1));
- GIMPLE_STMT_OPERAND (expr, 1) = fold_convert (type, cc);
+ case GIMPLE_RETURN:
+ type = TREE_TYPE (gimple_return_retval (stmt));
+ gimple_return_set_retval (stmt, fold_convert (type, cc));
break;
- case COND_EXPR:
- TREE_OPERAND (stmt, 0) = cc;
+
+ case GIMPLE_ASSIGN:
+ type = TREE_TYPE (gimple_assign_lhs (stmt));
+ gimple_assign_set_rhs_from_tree (gsi, fold_convert (type, cc));
+ stmt = gsi_stmt (*gsi);
break;
+
+ case GIMPLE_COND:
+ gimple_cond_set_code (stmt, EQ_EXPR);
+ gimple_cond_set_lhs (stmt, cc);
+ gimple_cond_set_rhs (stmt, boolean_true_node);
+ break;
+
default:
gcc_unreachable ();
}
@@ -1329,41 +1402,24 @@ expand_complex_comparison (block_stmt_iterator *bsi, tree ar, tree ai,
update_stmt (stmt);
}
+
/* Process one statement. If we identify a complex operation, expand it. */
static void
-expand_complex_operations_1 (block_stmt_iterator *bsi)
+expand_complex_operations_1 (gimple_stmt_iterator *gsi)
{
- tree stmt = bsi_stmt (*bsi);
- tree rhs, type, inner_type;
+ gimple stmt = gsi_stmt (*gsi);
+ tree type, inner_type, lhs;
tree ac, ar, ai, bc, br, bi;
complex_lattice_t al, bl;
enum tree_code code;
- switch (TREE_CODE (stmt))
- {
- case RETURN_EXPR:
- stmt = TREE_OPERAND (stmt, 0);
- if (!stmt)
- return;
- if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT)
- return;
- /* FALLTHRU */
-
- case GIMPLE_MODIFY_STMT:
- rhs = GIMPLE_STMT_OPERAND (stmt, 1);
- break;
+ lhs = gimple_get_lhs (stmt);
+ if (!lhs && gimple_code (stmt) != GIMPLE_COND)
+ return;
- case COND_EXPR:
- rhs = TREE_OPERAND (stmt, 0);
- break;
-
- default:
- return;
- }
-
- type = TREE_TYPE (rhs);
- code = TREE_CODE (rhs);
+ type = TREE_TYPE (gimple_op (stmt, 0));
+ code = gimple_expr_code (stmt);
/* Initial filter for operations we handle. */
switch (code)
@@ -1385,32 +1441,36 @@ expand_complex_operations_1 (block_stmt_iterator *bsi)
case EQ_EXPR:
case NE_EXPR:
- inner_type = TREE_TYPE (TREE_OPERAND (rhs, 1));
+ /* Note, both GIMPLE_ASSIGN and GIMPLE_COND may have an EQ_EXPR
+ subocde, so we need to access the operands using gimple_op. */
+ inner_type = TREE_TYPE (gimple_op (stmt, 1));
if (TREE_CODE (inner_type) != COMPLEX_TYPE)
return;
break;
default:
{
- tree lhs, rhs;
+ tree rhs;
- /* COND_EXPR may also fallthru here, but we do not need to do anything
- with it. */
- if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT)
+ /* GIMPLE_COND may also fallthru here, but we do not need to
+ do anything with it. */
+ if (gimple_code (stmt) == GIMPLE_COND)
return;
- lhs = GIMPLE_STMT_OPERAND (stmt, 0);
- rhs = GIMPLE_STMT_OPERAND (stmt, 1);
-
if (TREE_CODE (type) == COMPLEX_TYPE)
- expand_complex_move (bsi, stmt, type, lhs, rhs);
- else if ((TREE_CODE (rhs) == REALPART_EXPR
- || TREE_CODE (rhs) == IMAGPART_EXPR)
- && TREE_CODE (TREE_OPERAND (rhs, 0)) == SSA_NAME)
+ expand_complex_move (gsi, type);
+ else if (is_gimple_assign (stmt)
+ && (gimple_assign_rhs_code (stmt) == REALPART_EXPR
+ || gimple_assign_rhs_code (stmt) == IMAGPART_EXPR)
+ && TREE_CODE (lhs) == SSA_NAME)
{
- GENERIC_TREE_OPERAND (stmt, 1)
- = extract_component (bsi, TREE_OPERAND (rhs, 0),
- TREE_CODE (rhs) == IMAGPART_EXPR, false);
+ rhs = gimple_assign_rhs1 (stmt);
+ rhs = extract_component (gsi, TREE_OPERAND (rhs, 0),
+ gimple_assign_rhs_code (stmt)
+ == IMAGPART_EXPR,
+ false);
+ gimple_assign_set_rhs_from_tree (gsi, rhs);
+ stmt = gsi_stmt (*gsi);
update_stmt (stmt);
}
}
@@ -1419,23 +1479,30 @@ expand_complex_operations_1 (block_stmt_iterator *bsi)
/* Extract the components of the two complex values. Make sure and
handle the common case of the same value used twice specially. */
- ac = TREE_OPERAND (rhs, 0);
- ar = extract_component (bsi, ac, 0, true);
- ai = extract_component (bsi, ac, 1, true);
-
- if (TREE_CODE_CLASS (code) == tcc_unary)
- bc = br = bi = NULL;
+ if (is_gimple_assign (stmt))
+ {
+ ac = gimple_assign_rhs1 (stmt);
+ bc = (gimple_num_ops (stmt) > 2) ? gimple_assign_rhs2 (stmt) : NULL;
+ }
+ /* GIMPLE_CALL can not get here. */
else
{
- bc = TREE_OPERAND (rhs, 1);
- if (ac == bc)
- br = ar, bi = ai;
- else
- {
- br = extract_component (bsi, bc, 0, true);
- bi = extract_component (bsi, bc, 1, true);
- }
+ ac = gimple_cond_lhs (stmt);
+ bc = gimple_cond_rhs (stmt);
+ }
+
+ ar = extract_component (gsi, ac, false, true);
+ ai = extract_component (gsi, ac, true, true);
+
+ if (ac == bc)
+ br = ar, bi = ai;
+ else if (bc)
+ {
+ br = extract_component (gsi, bc, 0, true);
+ bi = extract_component (gsi, bc, 1, true);
}
+ else
+ br = bi = NULL_TREE;
if (gimple_in_ssa_p (cfun))
{
@@ -1461,11 +1528,11 @@ expand_complex_operations_1 (block_stmt_iterator *bsi)
{
case PLUS_EXPR:
case MINUS_EXPR:
- expand_complex_addition (bsi, inner_type, ar, ai, br, bi, code, al, bl);
+ expand_complex_addition (gsi, inner_type, ar, ai, br, bi, code, al, bl);
break;
case MULT_EXPR:
- expand_complex_multiplication (bsi, inner_type, ar, ai, br, bi, al, bl);
+ expand_complex_multiplication (gsi, inner_type, ar, ai, br, bi, al, bl);
break;
case TRUNC_DIV_EXPR:
@@ -1473,20 +1540,20 @@ expand_complex_operations_1 (block_stmt_iterator *bsi)
case FLOOR_DIV_EXPR:
case ROUND_DIV_EXPR:
case RDIV_EXPR:
- expand_complex_division (bsi, inner_type, ar, ai, br, bi, code, al, bl);
+ expand_complex_division (gsi, inner_type, ar, ai, br, bi, code, al, bl);
break;
case NEGATE_EXPR:
- expand_complex_negation (bsi, inner_type, ar, ai);
+ expand_complex_negation (gsi, inner_type, ar, ai);
break;
case CONJ_EXPR:
- expand_complex_conjugate (bsi, inner_type, ar, ai);
+ expand_complex_conjugate (gsi, inner_type, ar, ai);
break;
case EQ_EXPR:
case NE_EXPR:
- expand_complex_comparison (bsi, ar, ai, br, bi, code);
+ expand_complex_comparison (gsi, ar, ai, br, bi, code);
break;
default:
@@ -1501,7 +1568,7 @@ static unsigned int
tree_lower_complex (void)
{
int old_last_basic_block;
- block_stmt_iterator bsi;
+ gimple_stmt_iterator gsi;
basic_block bb;
if (!init_dont_simulate_again ())
@@ -1529,12 +1596,13 @@ tree_lower_complex (void)
{
if (bb->index >= old_last_basic_block)
continue;
+
update_phi_components (bb);
- for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
- expand_complex_operations_1 (&bsi);
+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+ expand_complex_operations_1 (&gsi);
}
- bsi_commit_edge_inserts ();
+ gsi_commit_edge_inserts ();
htab_delete (complex_variable_components);
VEC_free (tree, heap, complex_ssa_name_components);
@@ -1571,15 +1639,16 @@ static unsigned int
tree_lower_complex_O0 (void)
{
int old_last_basic_block = last_basic_block;
- block_stmt_iterator bsi;
+ gimple_stmt_iterator gsi;
basic_block bb;
FOR_EACH_BB (bb)
{
if (bb->index >= old_last_basic_block)
continue;
- for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
- expand_complex_operations_1 (&bsi);
+
+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+ expand_complex_operations_1 (&gsi);
}
return 0;
}
diff --git a/gcc/tree-data-ref.c b/gcc/tree-data-ref.c
index c024b74e09c..1b5e92b5af3 100644
--- a/gcc/tree-data-ref.c
+++ b/gcc/tree-data-ref.c
@@ -186,7 +186,7 @@ dump_data_reference (FILE *outf,
unsigned int i;
fprintf (outf, "(Data Ref: \n stmt: ");
- print_generic_stmt (outf, DR_STMT (dr), 0);
+ print_gimple_stmt (outf, DR_STMT (dr), 0, 0);
fprintf (outf, " ref: ");
print_generic_stmt (outf, DR_REF (dr), 0);
fprintf (outf, " base_object: ");
@@ -500,68 +500,65 @@ dump_ddrs (FILE *file, VEC (ddr_p, heap) *ddrs)
fprintf (file, "\n\n");
}
-/* Expresses EXP as VAR + OFF, where off is a constant. The type of OFF
- will be ssizetype. */
+/* 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
+ constant of type ssizetype, and returns true. If we cannot do this
+ with OFF nonzero, OFF and VAR are set to NULL_TREE instead and false
+ is returned. */
-void
-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)
{
- tree type = TREE_TYPE (exp), otype;
tree var0, var1;
tree off0, off1;
- enum tree_code code;
+ enum tree_code ocode = code;
- *var = exp;
- STRIP_NOPS (exp);
- otype = TREE_TYPE (exp);
- code = TREE_CODE (exp);
+ *var = NULL_TREE;
+ *off = NULL_TREE;
switch (code)
{
case INTEGER_CST:
*var = build_int_cst (type, 0);
- *off = fold_convert (ssizetype, exp);
- return;
+ *off = fold_convert (ssizetype, op0);
+ return true;
case POINTER_PLUS_EXPR:
- code = PLUS_EXPR;
+ ocode = PLUS_EXPR;
/* FALLTHROUGH */
case PLUS_EXPR:
case MINUS_EXPR:
- split_constant_offset (TREE_OPERAND (exp, 0), &var0, &off0);
- split_constant_offset (TREE_OPERAND (exp, 1), &var1, &off1);
- *var = fold_convert (type, fold_build2 (TREE_CODE (exp), otype,
- var0, var1));
- *off = size_binop (code, off0, off1);
- return;
+ split_constant_offset (op0, &var0, &off0);
+ split_constant_offset (op1, &var1, &off1);
+ *var = fold_build2 (code, type, var0, var1);
+ *off = size_binop (ocode, off0, off1);
+ return true;
case MULT_EXPR:
- off1 = TREE_OPERAND (exp, 1);
- if (TREE_CODE (off1) != INTEGER_CST)
- break;
+ if (TREE_CODE (op1) != INTEGER_CST)
+ return false;
- split_constant_offset (TREE_OPERAND (exp, 0), &var0, &off0);
- *var = fold_convert (type, fold_build2 (MULT_EXPR, otype,
- var0, off1));
- *off = size_binop (MULT_EXPR, off0, fold_convert (ssizetype, off1));
- return;
+ split_constant_offset (op0, &var0, &off0);
+ *var = fold_build2 (MULT_EXPR, type, var0, op1);
+ *off = size_binop (MULT_EXPR, off0, fold_convert (ssizetype, op1));
+ return true;
case ADDR_EXPR:
{
- tree op, base, poffset;
+ tree base, poffset;
HOST_WIDE_INT pbitsize, pbitpos;
enum machine_mode pmode;
int punsignedp, pvolatilep;
- op = TREE_OPERAND (exp, 0);
- if (!handled_component_p (op))
- break;
+ if (!handled_component_p (op0))
+ return false;
- base = get_inner_reference (op, &pbitsize, &pbitpos, &poffset,
+ base = get_inner_reference (op0, &pbitsize, &pbitpos, &poffset,
&pmode, &punsignedp, &pvolatilep, false);
if (pbitpos % BITS_PER_UNIT != 0)
- break;
+ return false;
base = build_fold_addr_expr (base);
off0 = ssize_int (pbitpos / BITS_PER_UNIT);
@@ -595,40 +592,57 @@ split_constant_offset (tree exp, tree *var, tree *off)
while (POINTER_TYPE_P (type))
type = TREE_TYPE (type);
if (int_size_in_bytes (type) < 0)
- break;
+ return false;
*var = var0;
*off = off0;
- return;
+ return true;
}
case SSA_NAME:
{
- tree def_stmt = SSA_NAME_DEF_STMT (exp);
- if (TREE_CODE (def_stmt) == GIMPLE_MODIFY_STMT)
- {
- tree def_stmt_rhs = GIMPLE_STMT_OPERAND (def_stmt, 1);
+ gimple def_stmt = SSA_NAME_DEF_STMT (op0);
+ enum tree_code subcode;
- if (!TREE_SIDE_EFFECTS (def_stmt_rhs)
- && EXPR_P (def_stmt_rhs)
- && !REFERENCE_CLASS_P (def_stmt_rhs)
- && !get_call_expr_in (def_stmt_rhs))
- {
- split_constant_offset (def_stmt_rhs, &var0, &off0);
- var0 = fold_convert (type, var0);
- *var = var0;
- *off = off0;
- return;
- }
- }
- break;
+ if (gimple_code (def_stmt) != GIMPLE_ASSIGN)
+ return false;
+
+ var0 = gimple_assign_rhs1 (def_stmt);
+ subcode = gimple_assign_rhs_code (def_stmt);
+ var1 = gimple_assign_rhs2 (def_stmt);
+
+ return split_constant_offset_1 (type, var0, subcode, var1, var, off);
}
default:
- break;
+ return false;
}
+}
+
+/* Expresses EXP as VAR + OFF, where off is a constant. The type of OFF
+ will be ssizetype. */
+
+void
+split_constant_offset (tree exp, tree *var, tree *off)
+{
+ tree type = TREE_TYPE (exp), otype, op0, op1, e, o;
+ enum tree_code code;
+ *var = exp;
*off = ssize_int (0);
+ STRIP_NOPS (exp);
+
+ if (automatically_generated_chrec_p (exp))
+ return;
+
+ otype = TREE_TYPE (exp);
+ code = TREE_CODE (exp);
+ extract_ops_from_tree (exp, &code, &op0, &op1);
+ if (split_constant_offset_1 (otype, op0, code, op1, &e, &o))
+ {
+ *var = fold_convert (type, e);
+ *off = o;
+ }
}
/* Returns the address ADDR of an object in a canonical shape (without nop
@@ -658,7 +672,7 @@ canonicalize_base_object_address (tree addr)
void
dr_analyze_innermost (struct data_reference *dr)
{
- tree stmt = DR_STMT (dr);
+ gimple stmt = DR_STMT (dr);
struct loop *loop = loop_containing_stmt (stmt);
tree ref = DR_REF (dr);
HOST_WIDE_INT pbitsize, pbitpos;
@@ -729,7 +743,7 @@ dr_analyze_innermost (struct data_reference *dr)
static void
dr_analyze_indices (struct data_reference *dr, struct loop *nest)
{
- tree stmt = DR_STMT (dr);
+ gimple stmt = DR_STMT (dr);
struct loop *loop = loop_containing_stmt (stmt);
VEC (tree, heap) *access_fns = NULL;
tree ref = unshare_expr (DR_REF (dr)), aref = ref, op;
@@ -773,7 +787,7 @@ dr_analyze_indices (struct data_reference *dr, struct loop *nest)
static void
dr_analyze_alias (struct data_reference *dr)
{
- tree stmt = DR_STMT (dr);
+ gimple stmt = DR_STMT (dr);
tree ref = DR_REF (dr);
tree base = get_base_address (ref), addr, smt = NULL_TREE;
ssa_op_iter it;
@@ -834,7 +848,7 @@ free_data_ref (data_reference_p dr)
loop nest in that the reference should be analyzed. */
struct data_reference *
-create_data_ref (struct loop *nest, tree memref, tree stmt, bool is_read)
+create_data_ref (struct loop *nest, tree memref, gimple stmt, bool is_read)
{
struct data_reference *dr;
@@ -1537,8 +1551,8 @@ analyze_ziv_subscript (tree chrec_a,
fprintf (dump_file, "(analyze_ziv_subscript \n");
type = signed_type_for_types (TREE_TYPE (chrec_a), TREE_TYPE (chrec_b));
- chrec_a = chrec_convert (type, chrec_a, NULL_TREE);
- chrec_b = chrec_convert (type, chrec_b, NULL_TREE);
+ chrec_a = chrec_convert (type, chrec_a, NULL);
+ chrec_b = chrec_convert (type, chrec_b, NULL);
difference = chrec_fold_minus (type, chrec_a, chrec_b);
switch (TREE_CODE (difference))
@@ -1668,8 +1682,8 @@ analyze_siv_subscript_cst_affine (tree chrec_a,
tree type, difference, tmp;
type = signed_type_for_types (TREE_TYPE (chrec_a), TREE_TYPE (chrec_b));
- chrec_a = chrec_convert (type, chrec_a, NULL_TREE);
- chrec_b = chrec_convert (type, chrec_b, NULL_TREE);
+ chrec_a = chrec_convert (type, chrec_a, NULL);
+ chrec_b = chrec_convert (type, chrec_b, NULL);
difference = chrec_fold_minus (type, initial_condition (chrec_b), chrec_a);
if (!chrec_is_positive (initial_condition (difference), &value0))
@@ -1875,7 +1889,7 @@ initialize_matrix_A (lambda_matrix A, tree chrec, unsigned index, int mult)
case NOP_EXPR:
{
tree op = initialize_matrix_A (A, TREE_OPERAND (chrec, 0), index, mult);
- return chrec_convert (chrec_type (chrec), op, NULL_TREE);
+ return chrec_convert (chrec_type (chrec), op, NULL);
}
case INTEGER_CST:
@@ -2365,7 +2379,7 @@ can_use_analyze_subscript_affine_affine (tree *chrec_a, tree *chrec_b)
type = chrec_type (*chrec_a);
left_a = CHREC_LEFT (*chrec_a);
- left_b = chrec_convert (type, CHREC_LEFT (*chrec_b), NULL_TREE);
+ left_b = chrec_convert (type, CHREC_LEFT (*chrec_b), NULL);
diff = chrec_fold_minus (type, left_a, left_b);
if (!evolution_function_is_constant_p (diff))
@@ -2376,7 +2390,7 @@ can_use_analyze_subscript_affine_affine (tree *chrec_a, tree *chrec_b)
*chrec_a = build_polynomial_chrec (CHREC_VARIABLE (*chrec_a),
diff, CHREC_RIGHT (*chrec_a));
- right_b = chrec_convert (type, CHREC_RIGHT (*chrec_b), NULL_TREE);
+ right_b = chrec_convert (type, CHREC_RIGHT (*chrec_b), NULL);
*chrec_b = build_polynomial_chrec (CHREC_VARIABLE (*chrec_b),
build_int_cst (type, 0),
right_b);
@@ -2523,8 +2537,8 @@ analyze_miv_subscript (tree chrec_a,
fprintf (dump_file, "(analyze_miv_subscript \n");
type = signed_type_for_types (TREE_TYPE (chrec_a), TREE_TYPE (chrec_b));
- chrec_a = chrec_convert (type, chrec_a, NULL_TREE);
- chrec_b = chrec_convert (type, chrec_b, NULL_TREE);
+ chrec_a = chrec_convert (type, chrec_a, NULL);
+ chrec_b = chrec_convert (type, chrec_b, NULL);
difference = chrec_fold_minus (type, chrec_a, chrec_b);
if (eq_evolutions_p (chrec_a, chrec_b))
@@ -3474,8 +3488,8 @@ omega_setup_subscript (tree access_fun_a, tree access_fun_b,
int eq;
tree type = signed_type_for_types (TREE_TYPE (access_fun_a),
TREE_TYPE (access_fun_b));
- tree fun_a = chrec_convert (type, access_fun_a, NULL_TREE);
- tree fun_b = chrec_convert (type, access_fun_b, NULL_TREE);
+ tree fun_a = chrec_convert (type, access_fun_a, NULL);
+ tree fun_b = chrec_convert (type, access_fun_b, NULL);
tree difference = chrec_fold_minus (type, fun_a, fun_b);
/* When the fun_a - fun_b is not constant, the dependence is not
@@ -3835,9 +3849,9 @@ compute_affine_dependence (struct data_dependence_relation *ddr,
{
fprintf (dump_file, "(compute_affine_dependence\n");
fprintf (dump_file, " (stmt_a = \n");
- print_generic_expr (dump_file, DR_STMT (dra), 0);
+ print_gimple_stmt (dump_file, DR_STMT (dra), 0, 0);
fprintf (dump_file, ")\n (stmt_b = \n");
- print_generic_expr (dump_file, DR_STMT (drb), 0);
+ print_gimple_stmt (dump_file, DR_STMT (drb), 0, 0);
fprintf (dump_file, ")\n");
}
@@ -3988,32 +4002,32 @@ compute_all_dependences (VEC (data_reference_p, heap) *datarefs,
true if STMT clobbers memory, false otherwise. */
bool
-get_references_in_stmt (tree stmt, VEC (data_ref_loc, heap) **references)
+get_references_in_stmt (gimple stmt, VEC (data_ref_loc, heap) **references)
{
bool clobbers_memory = false;
data_ref_loc *ref;
- tree *op0, *op1, call;
+ tree *op0, *op1;
+ enum gimple_code stmt_code = gimple_code (stmt);
*references = NULL;
/* ASM_EXPR and CALL_EXPR may embed arbitrary side effects.
Calls have side-effects, except those to const or pure
functions. */
- call = get_call_expr_in (stmt);
- if ((call
- && !(call_expr_flags (call) & (ECF_CONST | ECF_PURE)))
- || (TREE_CODE (stmt) == ASM_EXPR
- && ASM_VOLATILE_P (stmt)))
+ if ((stmt_code == GIMPLE_CALL
+ && !(gimple_call_flags (stmt) & (ECF_CONST | ECF_PURE)))
+ || (stmt_code == GIMPLE_ASM
+ && gimple_asm_volatile_p (stmt)))
clobbers_memory = true;
if (ZERO_SSA_OPERANDS (stmt, SSA_OP_ALL_VIRTUALS))
return clobbers_memory;
- if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT)
+ if (stmt_code == GIMPLE_ASSIGN)
{
tree base;
- op0 = &GIMPLE_STMT_OPERAND (stmt, 0);
- op1 = &GIMPLE_STMT_OPERAND (stmt, 1);
+ op0 = gimple_assign_lhs_ptr (stmt);
+ op1 = gimple_assign_rhs1_ptr (stmt);
if (DECL_P (*op1)
|| (REFERENCE_CLASS_P (*op1)
@@ -4033,14 +4047,13 @@ get_references_in_stmt (tree stmt, VEC (data_ref_loc, heap) **references)
ref->is_read = false;
}
}
-
- if (call)
+ else if (stmt_code == GIMPLE_CALL)
{
- unsigned i, n = call_expr_nargs (call);
+ unsigned i, n = gimple_call_num_args (stmt);
for (i = 0; i < n; i++)
{
- op0 = &CALL_EXPR_ARG (call, i);
+ op0 = gimple_call_arg_ptr (stmt, i);
if (DECL_P (*op0)
|| (REFERENCE_CLASS_P (*op0) && get_base_address (*op0)))
@@ -4060,7 +4073,7 @@ get_references_in_stmt (tree stmt, VEC (data_ref_loc, heap) **references)
loop of the loop nest in that the references should be analyzed. */
static bool
-find_data_references_in_stmt (struct loop *nest, tree stmt,
+find_data_references_in_stmt (struct loop *nest, gimple stmt,
VEC (data_reference_p, heap) **datarefs)
{
unsigned i;
@@ -4110,7 +4123,7 @@ find_data_references_in_loop (struct loop *loop,
{
basic_block bb, *bbs;
unsigned int i;
- block_stmt_iterator bsi;
+ gimple_stmt_iterator bsi;
bbs = get_loop_body_in_dom_order (loop);
@@ -4118,9 +4131,9 @@ find_data_references_in_loop (struct loop *loop,
{
bb = bbs[i];
- for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
+ for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi))
{
- tree stmt = bsi_stmt (bsi);
+ gimple stmt = gsi_stmt (bsi);
if (!find_data_references_in_stmt (loop, stmt, datarefs))
{
@@ -4443,7 +4456,7 @@ dump_rdg_vertex (FILE *file, struct graph *rdg, int i)
fprintf (file, " %d", e->dest);
fprintf (file, ") \n");
- print_generic_stmt (file, RDGV_STMT (v), TDF_VOPS|TDF_MEMSYMS);
+ print_gimple_stmt (file, RDGV_STMT (v), 0, TDF_VOPS|TDF_MEMSYMS);
fprintf (file, ")\n");
}
@@ -4579,14 +4592,14 @@ dot_rdg (struct graph *rdg)
struct rdg_vertex_info GTY(())
{
- tree stmt;
+ gimple stmt;
int index;
};
/* Returns the index of STMT in RDG. */
int
-rdg_vertex_for_stmt (struct graph *rdg, tree stmt)
+rdg_vertex_for_stmt (struct graph *rdg, gimple stmt)
{
struct rdg_vertex_info rvi, *slot;
@@ -4690,12 +4703,12 @@ create_rdg_edges (struct graph *rdg, VEC (ddr_p, heap) *ddrs)
/* Build the vertices of the reduced dependence graph RDG. */
static void
-create_rdg_vertices (struct graph *rdg, VEC (tree, heap) *stmts)
+create_rdg_vertices (struct graph *rdg, VEC (gimple, heap) *stmts)
{
int i, j;
- tree stmt;
+ gimple stmt;
- for (i = 0; VEC_iterate (tree, stmts, i, stmt); i++)
+ for (i = 0; VEC_iterate (gimple, stmts, i, stmt); i++)
{
VEC (data_ref_loc, heap) *references;
data_ref_loc *ref;
@@ -4717,7 +4730,7 @@ create_rdg_vertices (struct graph *rdg, VEC (tree, heap) *stmts)
RDG_MEM_WRITE_STMT (rdg, i) = false;
RDG_MEM_READS_STMT (rdg, i) = false;
- if (TREE_CODE (stmt) == PHI_NODE)
+ if (gimple_code (stmt) == GIMPLE_PHI)
continue;
get_references_in_stmt (stmt, &references);
@@ -4738,23 +4751,26 @@ create_rdg_vertices (struct graph *rdg, VEC (tree, heap) *stmts)
identifying statements. */
static void
-stmts_from_loop (struct loop *loop, VEC (tree, heap) **stmts)
+stmts_from_loop (struct loop *loop, VEC (gimple, heap) **stmts)
{
unsigned int i;
basic_block *bbs = get_loop_body_in_dom_order (loop);
for (i = 0; i < loop->num_nodes; i++)
{
- tree phi, stmt;
basic_block bb = bbs[i];
- block_stmt_iterator bsi;
+ gimple_stmt_iterator bsi;
+ gimple stmt;
- for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
- VEC_safe_push (tree, heap, *stmts, phi);
+ for (bsi = gsi_start_phis (bb); !gsi_end_p (bsi); gsi_next (&bsi))
+ VEC_safe_push (gimple, heap, *stmts, gsi_stmt (bsi));
- for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
- if (TREE_CODE (stmt = bsi_stmt (bsi)) != LABEL_EXPR)
- VEC_safe_push (tree, heap, *stmts, stmt);
+ for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi))
+ {
+ stmt = gsi_stmt (bsi);
+ if (gimple_code (stmt) != GIMPLE_LABEL)
+ VEC_safe_push (gimple, heap, *stmts, stmt);
+ }
}
free (bbs);
@@ -4782,7 +4798,7 @@ hash_stmt_vertex_info (const void *elt)
{
const struct rdg_vertex_info *const rvi =
(const struct rdg_vertex_info *) elt;
- const_tree stmt = rvi->stmt;
+ gimple stmt = rvi->stmt;
return htab_hash_pointer (stmt);
}
@@ -4817,7 +4833,7 @@ build_rdg (struct loop *loop)
struct graph *rdg = NULL;
VEC (ddr_p, heap) *dependence_relations;
VEC (data_reference_p, heap) *datarefs;
- VEC (tree, heap) *stmts = VEC_alloc (tree, heap, nb_data_refs);
+ VEC (gimple, heap) *stmts = VEC_alloc (gimple, heap, nb_data_refs);
dependence_relations = VEC_alloc (ddr_p, heap, nb_data_refs * nb_data_refs) ;
datarefs = VEC_alloc (data_reference_p, heap, nb_data_refs);
@@ -4830,7 +4846,7 @@ build_rdg (struct loop *loop)
goto end_rdg;
stmts_from_loop (loop, &stmts);
- rdg = new_graph (VEC_length (tree, stmts));
+ rdg = new_graph (VEC_length (gimple, stmts));
rdg->indices = htab_create (nb_data_refs, hash_stmt_vertex_info,
eq_stmt_vertex_info, hash_stmt_vertex_del);
@@ -4840,7 +4856,7 @@ build_rdg (struct loop *loop)
end_rdg:
free_dependence_relations (dependence_relations);
free_data_refs (datarefs);
- VEC_free (tree, heap, stmts);
+ VEC_free (gimple, heap, stmts);
return rdg;
}
@@ -4863,7 +4879,7 @@ free_rdg (struct graph *rdg)
store to memory. */
void
-stores_from_loop (struct loop *loop, VEC (tree, heap) **stmts)
+stores_from_loop (struct loop *loop, VEC (gimple, heap) **stmts)
{
unsigned int i;
basic_block *bbs = get_loop_body_in_dom_order (loop);
@@ -4871,11 +4887,11 @@ stores_from_loop (struct loop *loop, VEC (tree, heap) **stmts)
for (i = 0; i < loop->num_nodes; i++)
{
basic_block bb = bbs[i];
- block_stmt_iterator bsi;
+ gimple_stmt_iterator bsi;
- for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
- if (!ZERO_SSA_OPERANDS (bsi_stmt (bsi), SSA_OP_VDEF))
- VEC_safe_push (tree, heap, *stmts, bsi_stmt (bsi));
+ for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi))
+ if (!ZERO_SSA_OPERANDS (gsi_stmt (bsi), SSA_OP_VDEF))
+ VEC_safe_push (gimple, heap, *stmts, gsi_stmt (bsi));
}
free (bbs);
@@ -4885,7 +4901,7 @@ stores_from_loop (struct loop *loop, VEC (tree, heap) **stmts)
address or NULL_TREE if the base is not determined. */
static inline tree
-ref_base_address (tree stmt, data_ref_loc *ref)
+ref_base_address (gimple stmt, data_ref_loc *ref)
{
tree base = NULL_TREE;
tree base_address;
@@ -4921,7 +4937,7 @@ ref_base_address (tree stmt, data_ref_loc *ref)
bool
rdg_defs_used_in_other_loops_p (struct graph *rdg, int v)
{
- tree stmt = RDG_STMT (rdg, v);
+ gimple stmt = RDG_STMT (rdg, v);
struct loop *loop = loop_containing_stmt (stmt);
use_operand_p imm_use_p;
imm_use_iterator iterator;
@@ -4949,7 +4965,7 @@ rdg_defs_used_in_other_loops_p (struct graph *rdg, int v)
ref_base_address is the same. */
bool
-have_similar_memory_accesses (tree s1, tree s2)
+have_similar_memory_accesses (gimple s1, gimple s2)
{
bool res = false;
unsigned i, j;
@@ -4983,8 +4999,8 @@ have_similar_memory_accesses (tree s1, tree s2)
static int
have_similar_memory_accesses_1 (const void *s1, const void *s2)
{
- return have_similar_memory_accesses (CONST_CAST_TREE ((const_tree)s1),
- CONST_CAST_TREE ((const_tree)s2));
+ return have_similar_memory_accesses (CONST_CAST_GIMPLE ((const_gimple) s1),
+ CONST_CAST_GIMPLE ((const_gimple) s2));
}
/* Helper function for the hashtab. */
@@ -4992,7 +5008,7 @@ have_similar_memory_accesses_1 (const void *s1, const void *s2)
static hashval_t
ref_base_address_1 (const void *s)
{
- tree stmt = CONST_CAST_TREE((const_tree)s);
+ gimple stmt = CONST_CAST_GIMPLE ((const_gimple) s);
unsigned i;
VEC (data_ref_loc, heap) *refs;
data_ref_loc *ref;
@@ -5014,21 +5030,21 @@ ref_base_address_1 (const void *s)
/* Try to remove duplicated write data references from STMTS. */
void
-remove_similar_memory_refs (VEC (tree, heap) **stmts)
+remove_similar_memory_refs (VEC (gimple, heap) **stmts)
{
unsigned i;
- tree stmt;
- htab_t seen = htab_create (VEC_length (tree, *stmts), ref_base_address_1,
+ gimple stmt;
+ htab_t seen = htab_create (VEC_length (gimple, *stmts), ref_base_address_1,
have_similar_memory_accesses_1, NULL);
- for (i = 0; VEC_iterate (tree, *stmts, i, stmt); )
+ for (i = 0; VEC_iterate (gimple, *stmts, i, stmt); )
{
void **slot;
slot = htab_find_slot (seen, stmt, INSERT);
if (*slot)
- VEC_ordered_remove (tree, *stmts, i);
+ VEC_ordered_remove (gimple, *stmts, i);
else
{
*slot = (void *) stmt;
diff --git a/gcc/tree-data-ref.h b/gcc/tree-data-ref.h
index c1672eb3d53..639a32bf82b 100644
--- a/gcc/tree-data-ref.h
+++ b/gcc/tree-data-ref.h
@@ -156,7 +156,7 @@ int access_matrix_get_index_for_parameter (tree, struct access_matrix *);
struct data_reference
{
/* A pointer to the statement that contains this DR. */
- tree stmt;
+ gimple stmt;
/* A pointer to the memory reference. */
tree ref;
@@ -368,7 +368,7 @@ typedef struct data_ref_loc_d
DEF_VEC_O (data_ref_loc);
DEF_VEC_ALLOC_O (data_ref_loc, heap);
-bool get_references_in_stmt (tree, VEC (data_ref_loc, heap) **);
+bool get_references_in_stmt (gimple, VEC (data_ref_loc, heap) **);
void dr_analyze_innermost (struct data_reference *);
extern bool compute_data_dependences_for_loop (struct loop *, bool,
VEC (data_reference_p, heap) **,
@@ -392,7 +392,7 @@ extern void free_dependence_relation (struct data_dependence_relation *);
extern void free_dependence_relations (VEC (ddr_p, heap) *);
extern void free_data_ref (data_reference_p);
extern void free_data_refs (VEC (data_reference_p, heap) *);
-struct data_reference *create_data_ref (struct loop *, tree, tree, bool);
+struct data_reference *create_data_ref (struct loop *, tree, gimple, bool);
bool find_loop_nest (struct loop *, VEC (loop_p, heap) **);
void compute_all_dependences (VEC (data_reference_p, heap) *,
VEC (ddr_p, heap) **, VEC (loop_p, heap) *, bool);
@@ -462,7 +462,7 @@ ddr_dependence_level (ddr_p ddr)
typedef struct rdg_vertex
{
/* The statement represented by this vertex. */
- tree stmt;
+ gimple stmt;
/* True when the statement contains a write to memory. */
bool has_mem_write;
@@ -485,7 +485,7 @@ void debug_rdg_component (struct graph *, int);
void dump_rdg (FILE *, struct graph *);
void debug_rdg (struct graph *);
void dot_rdg (struct graph *);
-int rdg_vertex_for_stmt (struct graph *, tree);
+int rdg_vertex_for_stmt (struct graph *, gimple);
/* Data dependence type. */
@@ -538,10 +538,10 @@ index_in_loop_nest (int var, VEC (loop_p, heap) *loop_nest)
return var_index;
}
-void stores_from_loop (struct loop *, VEC (tree, heap) **);
-void remove_similar_memory_refs (VEC (tree, heap) **);
+void stores_from_loop (struct loop *, VEC (gimple, heap) **);
+void remove_similar_memory_refs (VEC (gimple, heap) **);
bool rdg_defs_used_in_other_loops_p (struct graph *, int);
-bool have_similar_memory_accesses (tree, tree);
+bool have_similar_memory_accesses (gimple, gimple);
/* Determines whether RDG vertices V1 and V2 access to similar memory
locations, in which case they have to be in the same partition. */
diff --git a/gcc/tree-dfa.c b/gcc/tree-dfa.c
index 285af39b3ca..df0be2df134 100644
--- a/gcc/tree-dfa.c
+++ b/gcc/tree-dfa.c
@@ -39,7 +39,7 @@ along with GCC; see the file COPYING3. If not see
#include "function.h"
#include "diagnostic.h"
#include "tree-dump.h"
-#include "tree-gimple.h"
+#include "gimple.h"
#include "tree-flow.h"
#include "tree-inline.h"
#include "tree-pass.h"
@@ -52,13 +52,12 @@ along with GCC; see the file COPYING3. If not see
/* Counters used to display DFA and SSA statistics. */
struct dfa_stats_d
{
- long num_stmt_anns;
long num_var_anns;
long num_defs;
long num_uses;
long num_phis;
long num_phi_args;
- int max_num_phi_args;
+ size_t max_num_phi_args;
long num_vdefs;
long num_vuses;
};
@@ -66,7 +65,6 @@ struct dfa_stats_d
/* Local functions. */
static void collect_dfa_stats (struct dfa_stats_d *);
-static tree collect_dfa_stats_r (tree *, int *, void *);
static tree find_vars_r (tree *, int *, void *);
@@ -85,27 +83,28 @@ static unsigned int
find_referenced_vars (void)
{
basic_block bb;
- block_stmt_iterator si;
- tree phi;
+ gimple_stmt_iterator si;
FOR_EACH_BB (bb)
{
- for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
+ for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
{
- tree *stmt_p = bsi_stmt_ptr (si);
- walk_tree (stmt_p, find_vars_r, NULL, NULL);
+ size_t i;
+ gimple stmt = gsi_stmt (si);
+ for (i = 0; i < gimple_num_ops (stmt); i++)
+ walk_tree (gimple_op_ptr (stmt, i), find_vars_r, NULL, NULL);
}
- for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
+ for (si = gsi_start_phis (bb); !gsi_end_p (si); gsi_next (&si))
{
- int len = PHI_NUM_ARGS (phi);
- int i;
+ gimple phi = gsi_stmt (si);
+ size_t i, len = gimple_phi_num_args (phi);
- walk_tree (&phi, find_vars_r, NULL, NULL);
+ walk_tree (gimple_phi_result_ptr (phi), find_vars_r, NULL, NULL);
for (i = 0; i < len; i++)
{
- tree arg = PHI_ARG_DEF (phi, i);
+ tree arg = gimple_phi_arg_def (phi, i);
walk_tree (&arg, find_vars_r, NULL, NULL);
}
}
@@ -176,29 +175,6 @@ create_function_ann (tree t)
return ann;
}
-/* Create a new annotation for a statement node T. */
-
-stmt_ann_t
-create_stmt_ann (tree t)
-{
- stmt_ann_t ann;
-
- gcc_assert (is_gimple_stmt (t));
- gcc_assert (!t->base.ann || t->base.ann->common.type == STMT_ANN);
-
- ann = GGC_CNEW (struct stmt_ann_d);
-
- ann->common.type = STMT_ANN;
-
- /* Since we just created the annotation, mark the statement modified. */
- ann->modified = true;
-
- ann->uid = inc_gimple_stmt_max_uid (cfun);
- t->base.ann = (tree_ann_t) ann;
-
- return ann;
-}
-
/* Renumber all of the gimple stmt uids. */
void
@@ -209,17 +185,11 @@ renumber_gimple_stmt_uids (void)
set_gimple_stmt_max_uid (cfun, 0);
FOR_ALL_BB (bb)
{
- block_stmt_iterator bsi;
- for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
+ gimple_stmt_iterator bsi;
+ for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi))
{
- tree stmt = bsi_stmt (bsi);
- /* If the stmt has an annotation, then overwrite it, if not,
- the process of getting it will set the number
- properly. */
- if (has_stmt_ann (stmt))
- set_gimple_stmt_uid (stmt, inc_gimple_stmt_max_uid (cfun));
- else
- get_stmt_ann (stmt);
+ gimple stmt = gsi_stmt (bsi);
+ gimple_set_uid (stmt, inc_gimple_stmt_max_uid (cfun));
}
}
}
@@ -237,6 +207,7 @@ create_tree_common_ann (tree t)
ann = GGC_CNEW (struct tree_ann_common_d);
ann->type = TREE_ANN_COMMON;
+ ann->rn = -1;
t->base.ann = (tree_ann_t) ann;
return ann;
@@ -448,11 +419,6 @@ dump_dfa_stats (FILE *file)
fprintf (file, fmt_str_1, "Referenced variables", (unsigned long)num_referenced_vars,
SCALE (size), LABEL (size));
- size = dfa_stats.num_stmt_anns * sizeof (struct stmt_ann_d);
- total += size;
- fprintf (file, fmt_str_1, "Statements annotated", dfa_stats.num_stmt_anns,
- SCALE (size), LABEL (size));
-
size = dfa_stats.num_var_anns * sizeof (struct var_ann_d);
total += size;
fprintf (file, fmt_str_1, "Variables annotated", dfa_stats.num_var_anns,
@@ -478,7 +444,7 @@ dump_dfa_stats (FILE *file)
fprintf (file, fmt_str_1, "VDEF operands", dfa_stats.num_vdefs,
SCALE (size), LABEL (size));
- size = dfa_stats.num_phis * sizeof (struct tree_phi_node);
+ size = dfa_stats.num_phis * sizeof (struct gimple_statement_phi);
total += size;
fprintf (file, fmt_str_1, "PHI nodes", dfa_stats.num_phis,
SCALE (size), LABEL (size));
@@ -495,9 +461,9 @@ dump_dfa_stats (FILE *file)
fprintf (file, "\n");
if (dfa_stats.num_phis)
- fprintf (file, "Average number of arguments per PHI node: %.1f (max: %d)\n",
+ fprintf (file, "Average number of arguments per PHI node: %.1f (max: %ld)\n",
(float) dfa_stats.num_phi_args / (float) dfa_stats.num_phis,
- dfa_stats.max_num_phi_args);
+ (long) dfa_stats.max_num_phi_args);
fprintf (file, "\n");
}
@@ -516,75 +482,44 @@ debug_dfa_stats (void)
DFA_STATS_P. */
static void
-collect_dfa_stats (struct dfa_stats_d *dfa_stats_p)
+collect_dfa_stats (struct dfa_stats_d *dfa_stats_p ATTRIBUTE_UNUSED)
{
- struct pointer_set_t *pset;
basic_block bb;
- block_stmt_iterator i;
+ referenced_var_iterator vi;
+ tree var;
gcc_assert (dfa_stats_p);
memset ((void *)dfa_stats_p, 0, sizeof (struct dfa_stats_d));
- /* Walk all the trees in the function counting references. Start at
- basic block NUM_FIXED_BLOCKS, but don't stop at block boundaries. */
- pset = pointer_set_create ();
-
- for (i = bsi_start (BASIC_BLOCK (NUM_FIXED_BLOCKS));
- !bsi_end_p (i); bsi_next (&i))
- walk_tree (bsi_stmt_ptr (i), collect_dfa_stats_r, (void *) dfa_stats_p,
- pset);
-
- pointer_set_destroy (pset);
+ /* Count all the variable annotations. */
+ FOR_EACH_REFERENCED_VAR (var, vi)
+ if (var_ann (var))
+ dfa_stats_p->num_var_anns++;
+ /* Walk all the statements in the function counting references. */
FOR_EACH_BB (bb)
{
- tree phi;
- for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
+ gimple_stmt_iterator si;
+
+ for (si = gsi_start_phis (bb); !gsi_end_p (si); gsi_next (&si))
{
+ gimple phi = gsi_stmt (si);
dfa_stats_p->num_phis++;
- dfa_stats_p->num_phi_args += PHI_NUM_ARGS (phi);
- if (PHI_NUM_ARGS (phi) > dfa_stats_p->max_num_phi_args)
- dfa_stats_p->max_num_phi_args = PHI_NUM_ARGS (phi);
+ dfa_stats_p->num_phi_args += gimple_phi_num_args (phi);
+ if (gimple_phi_num_args (phi) > dfa_stats_p->max_num_phi_args)
+ dfa_stats_p->max_num_phi_args = gimple_phi_num_args (phi);
}
- }
-}
-
-/* Callback for walk_tree to collect DFA statistics for a tree and its
- children. */
-
-static tree
-collect_dfa_stats_r (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
- void *data)
-{
- tree t = *tp;
- struct dfa_stats_d *dfa_stats_p = (struct dfa_stats_d *)data;
-
- if (t->base.ann)
- {
- switch (ann_type (t->base.ann))
+ for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
{
- case STMT_ANN:
- {
- dfa_stats_p->num_stmt_anns++;
- dfa_stats_p->num_defs += NUM_SSA_OPERANDS (t, SSA_OP_DEF);
- dfa_stats_p->num_uses += NUM_SSA_OPERANDS (t, SSA_OP_USE);
- dfa_stats_p->num_vdefs += NUM_SSA_OPERANDS (t, SSA_OP_VDEF);
- dfa_stats_p->num_vuses += NUM_SSA_OPERANDS (t, SSA_OP_VUSE);
- break;
- }
-
- case VAR_ANN:
- dfa_stats_p->num_var_anns++;
- break;
-
- default:
- break;
+ gimple stmt = gsi_stmt (si);
+ dfa_stats_p->num_defs += NUM_SSA_OPERANDS (stmt, SSA_OP_DEF);
+ dfa_stats_p->num_uses += NUM_SSA_OPERANDS (stmt, SSA_OP_USE);
+ dfa_stats_p->num_vdefs += NUM_SSA_OPERANDS (stmt, SSA_OP_VDEF);
+ dfa_stats_p->num_vuses += NUM_SSA_OPERANDS (stmt, SSA_OP_VUSE);
}
}
-
- return NULL;
}
@@ -800,7 +735,7 @@ get_virtual_var (tree var)
combination push_stmt_changes/pop_stmt_changes. */
void
-mark_symbols_for_renaming (tree stmt)
+mark_symbols_for_renaming (gimple stmt)
{
tree op;
ssa_op_iter iter;
@@ -814,8 +749,9 @@ mark_symbols_for_renaming (tree stmt)
}
-/* Find all variables within the gimplified statement that were not previously
- visible to the function and add them to the referenced variables list. */
+/* Find all variables within the gimplified statement that were not
+ previously visible to the function and add them to the referenced
+ variables list. */
static tree
find_new_referenced_vars_1 (tree *tp, int *walk_subtrees,
@@ -835,10 +771,13 @@ find_new_referenced_vars_1 (tree *tp, int *walk_subtrees,
return NULL;
}
+
+/* Find any new referenced variables in STMT. */
+
void
-find_new_referenced_vars (tree *stmt_p)
+find_new_referenced_vars (gimple stmt)
{
- walk_tree (stmt_p, find_new_referenced_vars_1, NULL, NULL);
+ walk_gimple_op (stmt, find_new_referenced_vars_1, NULL);
}
@@ -1013,7 +952,7 @@ get_ref_base_and_extent (tree exp, HOST_WIDE_INT *poffset,
SSA_NAME_OCCURS_IN_ABNORMAL_PHI set, otherwise false. */
bool
-stmt_references_abnormal_ssa_name (tree stmt)
+stmt_references_abnormal_ssa_name (gimple stmt)
{
ssa_op_iter oi;
use_operand_p use_p;
@@ -1163,25 +1102,25 @@ refs_may_alias_p (tree ref1, tree ref2)
a PHI node as well. Note that if all VUSEs are default definitions
this function will return an empty statement. */
-tree
-get_single_def_stmt (tree stmt)
+gimple
+get_single_def_stmt (gimple stmt)
{
- tree def_stmt = NULL_TREE;
+ gimple def_stmt = NULL;
tree use;
ssa_op_iter iter;
FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_VIRTUAL_USES)
{
- tree tmp = SSA_NAME_DEF_STMT (use);
+ gimple tmp = SSA_NAME_DEF_STMT (use);
/* ??? This is too simplistic for multiple virtual operands
reaching different PHI nodes of the same basic blocks or for
reaching all default definitions. */
if (def_stmt
&& def_stmt != tmp
- && !(IS_EMPTY_STMT (def_stmt)
- && IS_EMPTY_STMT (tmp)))
- return NULL_TREE;
+ && !(gimple_nop_p (def_stmt)
+ && gimple_nop_p (tmp)))
+ return NULL;
def_stmt = tmp;
}
@@ -1195,25 +1134,25 @@ get_single_def_stmt (tree stmt)
from a non-backedge. Returns NULL_TREE if such statement within
the above conditions cannot be found. */
-tree
-get_single_def_stmt_from_phi (tree ref, tree phi)
+gimple
+get_single_def_stmt_from_phi (tree ref, gimple phi)
{
tree def_arg = NULL_TREE;
- int i;
+ unsigned i;
/* Find the single PHI argument that is not flowing in from a
back edge and verify that the loop-carried definitions do
not alias the reference we look for. */
- for (i = 0; i < PHI_NUM_ARGS (phi); ++i)
+ for (i = 0; i < gimple_phi_num_args (phi); ++i)
{
tree arg = PHI_ARG_DEF (phi, i);
- tree def_stmt;
+ gimple def_stmt;
- if (!(PHI_ARG_EDGE (phi, i)->flags & EDGE_DFS_BACK))
+ if (!(gimple_phi_arg_edge (phi, i)->flags & EDGE_DFS_BACK))
{
/* Multiple non-back edges? Do not try to handle this. */
if (def_arg)
- return NULL_TREE;
+ return NULL;
def_arg = arg;
continue;
}
@@ -1223,14 +1162,14 @@ get_single_def_stmt_from_phi (tree ref, tree phi)
def_stmt = SSA_NAME_DEF_STMT (arg);
do
{
- if (TREE_CODE (def_stmt) != GIMPLE_MODIFY_STMT
- || refs_may_alias_p (ref, GIMPLE_STMT_OPERAND (def_stmt, 0)))
- return NULL_TREE;
+ if (!is_gimple_assign (def_stmt)
+ || refs_may_alias_p (ref, gimple_assign_lhs (def_stmt)))
+ return NULL;
/* ??? This will only work, reaching the PHI node again if
there is a single virtual operand on def_stmt. */
def_stmt = get_single_def_stmt (def_stmt);
if (!def_stmt)
- return NULL_TREE;
+ return NULL;
}
while (def_stmt != phi);
}
@@ -1243,8 +1182,8 @@ get_single_def_stmt_from_phi (tree ref, tree phi)
Take into account only definitions that alias REF if following
back-edges when looking through a loop PHI node. */
-tree
-get_single_def_stmt_with_phi (tree ref, tree stmt)
+gimple
+get_single_def_stmt_with_phi (tree ref, gimple stmt)
{
switch (NUM_SSA_OPERANDS (stmt, SSA_OP_VIRTUAL_USES))
{
@@ -1253,11 +1192,11 @@ get_single_def_stmt_with_phi (tree ref, tree stmt)
case 1:
{
- tree def_stmt = SSA_NAME_DEF_STMT (SINGLE_SSA_TREE_OPERAND
+ gimple def_stmt = SSA_NAME_DEF_STMT (SINGLE_SSA_TREE_OPERAND
(stmt, SSA_OP_VIRTUAL_USES));
/* We can handle lookups over PHI nodes only for a single
virtual operand. */
- if (TREE_CODE (def_stmt) == PHI_NODE)
+ if (gimple_code (def_stmt) == GIMPLE_PHI)
return get_single_def_stmt_from_phi (ref, def_stmt);
return def_stmt;
}
diff --git a/gcc/tree-dump.c b/gcc/tree-dump.c
index b7363c377c0..66ea1e75840 100644
--- a/gcc/tree-dump.c
+++ b/gcc/tree-dump.c
@@ -598,11 +598,6 @@ dequeue_and_dump (dump_info_p di)
dump_child ("op 1", TREE_OPERAND (t, 1));
break;
- case GIMPLE_MODIFY_STMT:
- dump_child ("op 0", GIMPLE_STMT_OPERAND (t, 0));
- dump_child ("op 1", GIMPLE_STMT_OPERAND (t, 1));
- break;
-
case COMPONENT_REF:
dump_child ("op 0", TREE_OPERAND (t, 0));
dump_child ("op 1", TREE_OPERAND (t, 1));
@@ -814,6 +809,7 @@ static const struct dump_option_value_info dump_options[] =
{"address", TDF_ADDRESS},
{"slim", TDF_SLIM},
{"raw", TDF_RAW},
+ {"graph", TDF_GRAPH},
{"details", TDF_DETAILS},
{"stats", TDF_STATS},
{"blocks", TDF_BLOCKS},
@@ -824,7 +820,8 @@ static const struct dump_option_value_info dump_options[] =
{"memsyms", TDF_MEMSYMS},
{"verbose", TDF_VERBOSE},
{"all", ~(TDF_RAW | TDF_SLIM | TDF_LINENO | TDF_TREE | TDF_RTL | TDF_IPA
- | TDF_STMTADDR | TDF_GRAPH | TDF_DIAGNOSTIC | TDF_VERBOSE)},
+ | TDF_STMTADDR | TDF_GRAPH | TDF_DIAGNOSTIC | TDF_VERBOSE
+ | TDF_RHS_ONLY)},
{NULL, 0}
};
diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c
index 965acce7490..140cbc54953 100644
--- a/gcc/tree-eh.c
+++ b/gcc/tree-eh.c
@@ -37,9 +37,12 @@ along with GCC; see the file COPYING3. If not see
#include "langhooks.h"
#include "ggc.h"
#include "toplev.h"
-#include "pointer-set.h"
+#include "gimple.h"
+
+/* In some instances a tree and a gimple need to be stored in a same table,
+ i.e. in hash tables. This is a structure to do this. */
+typedef union {tree *tp; tree t; gimple g;} treemple;
-
/* Nonzero if we are using EH to handle cleanups. */
static int using_eh_for_cleanups_p = 0;
@@ -48,7 +51,7 @@ using_eh_for_cleanups (void)
{
using_eh_for_cleanups_p = 1;
}
-
+
/* Misc functions used in this file. */
/* Compare and hash for any structure which begins with a canonical
@@ -70,7 +73,7 @@ struct_ptr_hash (const void *a)
return (size_t)*x >> 4;
}
-
+
/* Remember and lookup EH region data for arbitrary statements.
Really this means any statement that could_throw_p. We could
stuff this information into the stmt_ann data structure, but:
@@ -84,7 +87,7 @@ struct_ptr_hash (const void *a)
of space by only allocating memory for those that can throw. */
static void
-record_stmt_eh_region (struct eh_region *region, tree t)
+record_stmt_eh_region (struct eh_region *region, gimple t)
{
if (!region)
return;
@@ -92,14 +95,17 @@ record_stmt_eh_region (struct eh_region *region, tree t)
add_stmt_to_eh_region (t, get_eh_region_number (region));
}
+
+/* Add statement T in function IFUN to EH region NUM. */
+
void
-add_stmt_to_eh_region_fn (struct function *ifun, tree t, int num)
+add_stmt_to_eh_region_fn (struct function *ifun, gimple t, int num)
{
struct throw_stmt_node *n;
void **slot;
gcc_assert (num >= 0);
- gcc_assert (TREE_CODE (t) != RESX_EXPR);
+ gcc_assert (gimple_code (t) != GIMPLE_RESX);
n = GGC_NEW (struct throw_stmt_node);
n->stmt = t;
@@ -115,14 +121,21 @@ add_stmt_to_eh_region_fn (struct function *ifun, tree t, int num)
*slot = n;
}
+
+/* Add statement T in the current function (cfun) to EH region number
+ NUM. */
+
void
-add_stmt_to_eh_region (tree t, int num)
+add_stmt_to_eh_region (gimple t, int num)
{
add_stmt_to_eh_region_fn (cfun, t, num);
}
+
+/* Remove statement T in function IFUN from the EH region holding it. */
+
bool
-remove_stmt_from_eh_region_fn (struct function *ifun, tree t)
+remove_stmt_from_eh_region_fn (struct function *ifun, gimple t)
{
struct throw_stmt_node dummy;
void **slot;
@@ -142,54 +155,98 @@ remove_stmt_from_eh_region_fn (struct function *ifun, tree t)
return false;
}
+
+/* Remove statement T in the current function (cfun) from the EH
+ region holding it. */
+
bool
-remove_stmt_from_eh_region (tree t)
+remove_stmt_from_eh_region (gimple t)
{
return remove_stmt_from_eh_region_fn (cfun, t);
}
+/* Determine if statement T is inside an EH region in function IFUN.
+ Return the EH region number if found, return -2 if IFUN does not
+ have an EH table and -1 if T could not be found in IFUN's EH region
+ table. */
+
int
-lookup_stmt_eh_region_fn (struct function *ifun, const_tree t)
+lookup_stmt_eh_region_fn (struct function *ifun, gimple t)
{
struct throw_stmt_node *p, n;
if (!get_eh_throw_stmt_table (ifun))
return -2;
- /* The CONST_CAST is okay because we don't modify n.stmt throughout
- its scope, or the scope of p. */
- n.stmt = CONST_CAST_TREE (t);
- p = (struct throw_stmt_node *) htab_find (get_eh_throw_stmt_table (ifun),
- &n);
-
+ n.stmt = t;
+ p = (struct throw_stmt_node *) htab_find (get_eh_throw_stmt_table (ifun), &n);
return (p ? p->region_nr : -1);
}
+
+/* Determine if statement T is inside an EH region in the current
+ function (cfun). Return the EH region number if found, return -2
+ if cfun does not have an EH table and -1 if T could not be found in
+ cfun's EH region table. */
+
int
-lookup_stmt_eh_region (const_tree t)
+lookup_stmt_eh_region (gimple t)
{
/* We can get called from initialized data when -fnon-call-exceptions
is on; prevent crash. */
if (!cfun)
return -1;
+
return lookup_stmt_eh_region_fn (cfun, t);
}
-
-/* First pass of EH node decomposition. Build up a tree of TRY_FINALLY_EXPR
+
+/* Determine if expression T is inside an EH region in the current
+ function (cfun). Return the EH region number if found, return -2
+ if IFUN does not have an EH table and -1 if T could not be found in
+ IFUN's EH region table. */
+
+int
+lookup_expr_eh_region (tree t)
+{
+ /* We can get called from initialized data when -fnon-call-exceptions
+ is on; prevent crash. */
+ if (!cfun)
+ return -1;
+
+ if (!get_eh_throw_stmt_table (cfun))
+ return -2;
+
+ if (t && EXPR_P (t))
+ {
+ tree_ann_common_t ann = tree_common_ann (t);
+ if (ann)
+ return (int) ann->rn;
+ }
+
+ return -1;
+}
+
+
+/* First pass of EH node decomposition. Build up a tree of GIMPLE_TRY_FINALLY
nodes and LABEL_DECL nodes. We will use this during the second phase to
determine if a goto leaves the body of a TRY_FINALLY_EXPR node. */
struct finally_tree_node
{
- tree child, parent;
+ /* When storing a GIMPLE_TRY, we have to record a gimple. However
+ when deciding whether a GOTO to a certain LABEL_DECL (which is a
+ tree) leaves the TRY block, its necessary to record a tree in
+ this field. Thus a treemple is used. */
+ treemple child;
+ gimple parent;
};
/* Note that this table is *not* marked GTY. It is short-lived. */
static htab_t finally_tree;
static void
-record_in_finally_tree (tree child, tree parent)
+record_in_finally_tree (treemple child, gimple parent)
{
struct finally_tree_node *n;
void **slot;
@@ -204,40 +261,53 @@ record_in_finally_tree (tree child, tree parent)
}
static void
-collect_finally_tree (tree t, tree region)
+collect_finally_tree (gimple stmt, gimple region);
+
+/* Go through the gimple sequence. Works with collect_finally_tree to
+ record all GIMPLE_LABEL and GIMPLE_TRY statements. */
+
+static void
+collect_finally_tree_1 (gimple_seq seq, gimple region)
{
- tailrecurse:
- switch (TREE_CODE (t))
- {
- case LABEL_EXPR:
- record_in_finally_tree (LABEL_EXPR_LABEL (t), region);
- break;
+ gimple_stmt_iterator gsi;
- case TRY_FINALLY_EXPR:
- record_in_finally_tree (t, region);
- collect_finally_tree (TREE_OPERAND (t, 0), t);
- t = TREE_OPERAND (t, 1);
- goto tailrecurse;
+ for (gsi = gsi_start (seq); !gsi_end_p (gsi); gsi_next (&gsi))
+ collect_finally_tree (gsi_stmt (gsi), region);
+}
- case TRY_CATCH_EXPR:
- collect_finally_tree (TREE_OPERAND (t, 0), region);
- t = TREE_OPERAND (t, 1);
- goto tailrecurse;
+static void
+collect_finally_tree (gimple stmt, gimple region)
+{
+ treemple temp;
+
+ switch (gimple_code (stmt))
+ {
+ case GIMPLE_LABEL:
+ temp.t = gimple_label_label (stmt);
+ record_in_finally_tree (temp, region);
+ break;
- case CATCH_EXPR:
- t = CATCH_BODY (t);
- goto tailrecurse;
+ case GIMPLE_TRY:
+ if (gimple_try_kind (stmt) == GIMPLE_TRY_FINALLY)
+ {
+ temp.g = stmt;
+ record_in_finally_tree (temp, region);
+ collect_finally_tree_1 (gimple_try_eval (stmt), stmt);
+ collect_finally_tree_1 (gimple_try_cleanup (stmt), region);
+ }
+ else if (gimple_try_kind (stmt) == GIMPLE_TRY_CATCH)
+ {
+ collect_finally_tree_1 (gimple_try_eval (stmt), region);
+ collect_finally_tree_1 (gimple_try_cleanup (stmt), region);
+ }
+ break;
- case EH_FILTER_EXPR:
- t = EH_FILTER_FAILURE (t);
- goto tailrecurse;
+ case GIMPLE_CATCH:
+ collect_finally_tree_1 (gimple_catch_handler (stmt), region);
+ break;
- case STATEMENT_LIST:
- {
- tree_stmt_iterator i;
- for (i = tsi_start (t); !tsi_end_p (i); tsi_next (&i))
- collect_finally_tree (tsi_stmt (i), region);
- }
+ case GIMPLE_EH_FILTER:
+ collect_finally_tree_1 (gimple_eh_filter_failure (stmt), region);
break;
default:
@@ -247,11 +317,12 @@ collect_finally_tree (tree t, tree region)
}
}
+
/* Use the finally tree to determine if a jump from START to TARGET
would leave the try_finally node that START lives in. */
static bool
-outside_finally_tree (tree start, tree target)
+outside_finally_tree (treemple start, gimple target)
{
struct finally_tree_node n, *p;
@@ -261,15 +332,15 @@ outside_finally_tree (tree start, tree target)
p = (struct finally_tree_node *) htab_find (finally_tree, &n);
if (!p)
return true;
- start = p->parent;
+ start.g = p->parent;
}
- while (start != target);
+ while (start.g != target);
return false;
}
-
-/* Second pass of EH node decomposition. Actually transform the TRY_FINALLY
- and TRY_CATCH nodes into a set of gotos, magic labels, and eh regions.
+
+/* Second pass of EH node decomposition. Actually transform the GIMPLE_TRY
+ nodes into a set of gotos, magic labels, and eh regions.
The eh region creation is straight-forward, but frobbing all the gotos
and such into shape isn't. */
@@ -291,12 +362,15 @@ struct leh_state
struct leh_tf_state
{
- /* Pointer to the TRY_FINALLY node under discussion. The try_finally_expr
- is the original TRY_FINALLY_EXPR. We need to retain this so that
- outside_finally_tree can reliably reference the tree used in the
- collect_finally_tree data structures. */
- tree try_finally_expr;
- tree *top_p;
+ /* Pointer to the GIMPLE_TRY_FINALLY node under discussion. The
+ try_finally_expr is the original GIMPLE_TRY_FINALLY. We need to retain
+ this so that outside_finally_tree can reliably reference the tree used
+ in the collect_finally_tree data structures. */
+ gimple try_finally_expr;
+ gimple top_p;
+ /* While lowering a top_p usually it is expanded into multiple statements,
+ thus we need the following field to store them. */
+ gimple_seq top_p_seq;
/* The state outside this try_finally node. */
struct leh_state *outer;
@@ -304,13 +378,22 @@ struct leh_tf_state
/* The exception region created for it. */
struct eh_region *region;
- /* The GOTO_QUEUE is is an array of GOTO_EXPR and RETURN_EXPR statements
- that are seen to escape this TRY_FINALLY_EXPR node. */
+ /* The GOTO_QUEUE is is an array of GIMPLE_GOTO and GIMPLE_RETURN statements
+ that are seen to escape this GIMPLE_TRY_FINALLY node.
+ The idea is to record a gimple statement for everything except for
+ the conditionals, which get their labels recorded. Since labels are of
+ type 'tree', we need this node to store both gimple and tree objects.
+ REPL_STMT is the sequence used to replace the goto/return statement.
+ CONT_STMT is used to store the statement that allows the return/goto to
+ jump to the original destination. */
struct goto_queue_node {
- tree stmt;
- tree repl_stmt;
- tree cont_stmt;
+ treemple stmt;
+ gimple_seq repl_stmt;
+ gimple cont_stmt;
int index;
+ /* this is used when index >= 0 to indicate that stmt is a label(as
+ opposed to a goto stmt) */
+ int is_label;
} *goto_queue;
size_t goto_queue_size;
size_t goto_queue_active;
@@ -334,7 +417,7 @@ struct leh_tf_state
Cleared if the fallthru is converted to a goto. */
bool may_fallthru;
- /* True if any entry in goto_queue is a RETURN_EXPR. */
+ /* True if any entry in goto_queue is a GIMPLE_RETURN. */
bool may_return;
/* True if the finally block can receive an exception edge.
@@ -342,16 +425,17 @@ struct leh_tf_state
bool may_throw;
};
-static void lower_eh_filter (struct leh_state *, tree *);
-static void lower_eh_constructs_1 (struct leh_state *, tree *);
+static gimple_seq lower_eh_filter (struct leh_state *, gimple);
/* Search for STMT in the goto queue. Return the replacement,
or null if the statement isn't in the queue. */
#define LARGE_GOTO_QUEUE 20
-static tree
-find_goto_replacement (struct leh_tf_state *tf, tree stmt)
+static void lower_eh_constructs_1 (struct leh_state *state, gimple_seq seq);
+
+static gimple_seq
+find_goto_replacement (struct leh_tf_state *tf, treemple stmt)
{
unsigned int i;
void **slot;
@@ -359,7 +443,7 @@ find_goto_replacement (struct leh_tf_state *tf, tree stmt)
if (tf->goto_queue_active < LARGE_GOTO_QUEUE)
{
for (i = 0; i < tf->goto_queue_active; i++)
- if (tf->goto_queue[i].stmt == stmt)
+ if ( tf->goto_queue[i].stmt.g == stmt.g)
return tf->goto_queue[i].repl_stmt;
return NULL;
}
@@ -372,13 +456,14 @@ find_goto_replacement (struct leh_tf_state *tf, tree stmt)
tf->goto_queue_map = pointer_map_create ();
for (i = 0; i < tf->goto_queue_active; i++)
{
- slot = pointer_map_insert (tf->goto_queue_map, tf->goto_queue[i].stmt);
+ slot = pointer_map_insert (tf->goto_queue_map,
+ tf->goto_queue[i].stmt.g);
gcc_assert (*slot == NULL);
- *slot = (void *) &tf->goto_queue[i];
+ *slot = &tf->goto_queue[i];
}
}
- slot = pointer_map_contains (tf->goto_queue_map, stmt);
+ slot = pointer_map_contains (tf->goto_queue_map, stmt.g);
if (slot != NULL)
return (((struct goto_queue_node *) *slot)->repl_stmt);
@@ -386,91 +471,98 @@ find_goto_replacement (struct leh_tf_state *tf, tree stmt)
}
/* A subroutine of replace_goto_queue_1. Handles the sub-clauses of a
- lowered COND_EXPR. If, by chance, the replacement is a simple goto,
+ lowered GIMPLE_COND. If, by chance, the replacement is a simple goto,
then we can just splat it in, otherwise we add the new stmts immediately
- after the COND_EXPR and redirect. */
+ after the GIMPLE_COND and redirect. */
static void
replace_goto_queue_cond_clause (tree *tp, struct leh_tf_state *tf,
- tree_stmt_iterator *tsi)
+ gimple_stmt_iterator *gsi)
{
- tree new, one, label;
+ tree label;
+ gimple_seq new;
+ treemple temp;
- new = find_goto_replacement (tf, *tp);
+ temp.tp = tp;
+ new = find_goto_replacement (tf, temp);
if (!new)
return;
- one = expr_only (new);
- if (one && TREE_CODE (one) == GOTO_EXPR)
+ if (gimple_seq_singleton_p (new)
+ && gimple_code (gimple_seq_first_stmt (new)) == GIMPLE_GOTO)
{
- *tp = one;
+ *tp = gimple_goto_dest (gimple_seq_first_stmt (new));
return;
}
- label = build1 (LABEL_EXPR, void_type_node, NULL_TREE);
- *tp = build_and_jump (&LABEL_EXPR_LABEL (label));
+ label = create_artificial_label ();
+ /* Set the new label for the GIMPLE_COND */
+ *tp = label;
- tsi_link_after (tsi, label, TSI_CONTINUE_LINKING);
- tsi_link_after (tsi, new, TSI_CONTINUE_LINKING);
+ gsi_insert_after (gsi, gimple_build_label (label), GSI_CONTINUE_LINKING);
+ gsi_insert_seq_after (gsi, gimple_seq_copy (new), GSI_CONTINUE_LINKING);
}
/* The real work of replace_goto_queue. Returns with TSI updated to
point to the next statement. */
-static void replace_goto_queue_stmt_list (tree, struct leh_tf_state *);
+static void replace_goto_queue_stmt_list (gimple_seq, struct leh_tf_state *);
static void
-replace_goto_queue_1 (tree t, struct leh_tf_state *tf, tree_stmt_iterator *tsi)
+replace_goto_queue_1 (gimple stmt, struct leh_tf_state *tf,
+ gimple_stmt_iterator *gsi)
{
- switch (TREE_CODE (t))
+ gimple_seq seq;
+ treemple temp;
+ temp.g = NULL;
+
+ switch (gimple_code (stmt))
{
- case GOTO_EXPR:
- case RETURN_EXPR:
- t = find_goto_replacement (tf, t);
- if (t)
+ case GIMPLE_GOTO:
+ case GIMPLE_RETURN:
+ temp.g = stmt;
+ seq = find_goto_replacement (tf, temp);
+ if (seq)
{
- tsi_link_before (tsi, t, TSI_SAME_STMT);
- tsi_delink (tsi);
+ gsi_insert_seq_before (gsi, gimple_seq_copy (seq), GSI_SAME_STMT);
+ gsi_remove (gsi, false);
return;
}
break;
- case COND_EXPR:
- replace_goto_queue_cond_clause (&COND_EXPR_THEN (t), tf, tsi);
- replace_goto_queue_cond_clause (&COND_EXPR_ELSE (t), tf, tsi);
+ case GIMPLE_COND:
+ replace_goto_queue_cond_clause (gimple_op_ptr (stmt, 2), tf, gsi);
+ replace_goto_queue_cond_clause (gimple_op_ptr (stmt, 3), tf, gsi);
break;
- case TRY_FINALLY_EXPR:
- case TRY_CATCH_EXPR:
- replace_goto_queue_stmt_list (TREE_OPERAND (t, 0), tf);
- replace_goto_queue_stmt_list (TREE_OPERAND (t, 1), tf);
+ case GIMPLE_TRY:
+ replace_goto_queue_stmt_list (gimple_try_eval (stmt), tf);
+ replace_goto_queue_stmt_list (gimple_try_cleanup (stmt), tf);
break;
- case CATCH_EXPR:
- replace_goto_queue_stmt_list (CATCH_BODY (t), tf);
+ case GIMPLE_CATCH:
+ replace_goto_queue_stmt_list (gimple_catch_handler (stmt), tf);
break;
- case EH_FILTER_EXPR:
- replace_goto_queue_stmt_list (EH_FILTER_FAILURE (t), tf);
+ case GIMPLE_EH_FILTER:
+ replace_goto_queue_stmt_list (gimple_eh_filter_failure (stmt), tf);
break;
- case STATEMENT_LIST:
- gcc_unreachable ();
-
default:
/* These won't have gotos in them. */
break;
}
- tsi_next (tsi);
+ gsi_next (gsi);
}
-/* A subroutine of replace_goto_queue. Handles STATEMENT_LISTs. */
+/* A subroutine of replace_goto_queue. Handles GIMPLE_SEQ. */
static void
-replace_goto_queue_stmt_list (tree t, struct leh_tf_state *tf)
+replace_goto_queue_stmt_list (gimple_seq seq, struct leh_tf_state *tf)
{
- tree_stmt_iterator i = tsi_start (t);
- while (!tsi_end_p (i))
- replace_goto_queue_1 (tsi_stmt (i), tf, &i);
+ gimple_stmt_iterator gsi = gsi_start (seq);
+
+ while (!gsi_end_p (gsi))
+ replace_goto_queue_1 (gsi_stmt (gsi), tf, &gsi);
}
/* Replace all goto queue members. */
@@ -480,66 +572,21 @@ replace_goto_queue (struct leh_tf_state *tf)
{
if (tf->goto_queue_active == 0)
return;
- replace_goto_queue_stmt_list (*tf->top_p, tf);
+ replace_goto_queue_stmt_list (tf->top_p_seq, tf);
}
-/* For any GOTO_EXPR or RETURN_EXPR, decide whether it leaves a try_finally
- node, and if so record that fact in the goto queue associated with that
- try_finally node. */
+/* Add a new record to the goto queue contained in TF. NEW_STMT is the
+ data to be added, IS_LABEL indicates whether NEW_STMT is a label or
+ a gimple return. */
static void
-maybe_record_in_goto_queue (struct leh_state *state, tree stmt)
+record_in_goto_queue (struct leh_tf_state *tf,
+ treemple new_stmt,
+ int index,
+ bool is_label)
{
- struct leh_tf_state *tf = state->tf;
- struct goto_queue_node *q;
size_t active, size;
- int index;
-
- if (!tf)
- return;
-
- switch (TREE_CODE (stmt))
- {
- case GOTO_EXPR:
- {
- tree lab = GOTO_DESTINATION (stmt);
-
- /* Computed and non-local gotos do not get processed. Given
- their nature we can neither tell whether we've escaped the
- finally block nor redirect them if we knew. */
- if (TREE_CODE (lab) != LABEL_DECL)
- return;
-
- /* No need to record gotos that don't leave the try block. */
- if (! outside_finally_tree (lab, tf->try_finally_expr))
- return;
-
- if (! tf->dest_array)
- {
- tf->dest_array = VEC_alloc (tree, heap, 10);
- VEC_quick_push (tree, tf->dest_array, lab);
- index = 0;
- }
- else
- {
- int n = VEC_length (tree, tf->dest_array);
- for (index = 0; index < n; ++index)
- if (VEC_index (tree, tf->dest_array, index) == lab)
- break;
- if (index == n)
- VEC_safe_push (tree, heap, tf->dest_array, lab);
- }
- }
- break;
-
- case RETURN_EXPR:
- tf->may_return = true;
- index = -1;
- break;
-
- default:
- gcc_unreachable ();
- }
+ struct goto_queue_node *q;
gcc_assert (!tf->goto_queue_map);
@@ -557,32 +604,118 @@ maybe_record_in_goto_queue (struct leh_state *state, tree stmt)
tf->goto_queue_active = active + 1;
memset (q, 0, sizeof (*q));
- q->stmt = stmt;
+ q->stmt = new_stmt;
q->index = index;
+ q->is_label = is_label;
+}
+
+/* Record the LABEL label in the goto queue contained in TF.
+ TF is not null. */
+
+static void
+record_in_goto_queue_label (struct leh_tf_state *tf, treemple stmt, tree label)
+{
+ int index;
+ treemple temp, new_stmt;
+
+ if (!label)
+ return;
+
+ /* Computed and non-local gotos do not get processed. Given
+ their nature we can neither tell whether we've escaped the
+ finally block nor redirect them if we knew. */
+ if (TREE_CODE (label) != LABEL_DECL)
+ return;
+
+ /* No need to record gotos that don't leave the try block. */
+ temp.t = label;
+ if (!outside_finally_tree (temp, tf->try_finally_expr))
+ return;
+
+ if (! tf->dest_array)
+ {
+ tf->dest_array = VEC_alloc (tree, heap, 10);
+ VEC_quick_push (tree, tf->dest_array, label);
+ index = 0;
+ }
+ else
+ {
+ int n = VEC_length (tree, tf->dest_array);
+ for (index = 0; index < n; ++index)
+ if (VEC_index (tree, tf->dest_array, index) == label)
+ break;
+ if (index == n)
+ VEC_safe_push (tree, heap, tf->dest_array, label);
+ }
+
+ /* In the case of a GOTO we want to record the destination label,
+ since with a GIMPLE_COND we have an easy access to the then/else
+ labels. */
+ new_stmt = stmt;
+ record_in_goto_queue (tf, new_stmt, index, true);
+
+}
+
+/* For any GIMPLE_GOTO or GIMPLE_RETURN, decide whether it leaves a try_finally
+ node, and if so record that fact in the goto queue associated with that
+ try_finally node. */
+
+static void
+maybe_record_in_goto_queue (struct leh_state *state, gimple stmt)
+{
+ struct leh_tf_state *tf = state->tf;
+ treemple new_stmt;
+
+ if (!tf)
+ return;
+
+ switch (gimple_code (stmt))
+ {
+ case GIMPLE_COND:
+ new_stmt.tp = gimple_op_ptr (stmt, 2);
+ record_in_goto_queue_label (tf, new_stmt, gimple_cond_true_label (stmt));
+ new_stmt.tp = gimple_op_ptr (stmt, 3);
+ record_in_goto_queue_label (tf, new_stmt, gimple_cond_false_label (stmt));
+ break;
+ case GIMPLE_GOTO:
+ new_stmt.g = stmt;
+ record_in_goto_queue_label (tf, new_stmt, gimple_goto_dest (stmt));
+ break;
+
+ case GIMPLE_RETURN:
+ tf->may_return = true;
+ new_stmt.g = stmt;
+ record_in_goto_queue (tf, new_stmt, -1, false);
+ break;
+
+ default:
+ gcc_unreachable ();
+ }
}
+
#ifdef ENABLE_CHECKING
-/* We do not process SWITCH_EXPRs for now. As long as the original source
+/* We do not process GIMPLE_SWITCHes for now. As long as the original source
was in fact structured, and we've not yet done jump threading, then none
- of the labels will leave outer TRY_FINALLY_EXPRs. Verify this. */
+ of the labels will leave outer GIMPLE_TRY_FINALLY nodes. Verify this. */
static void
-verify_norecord_switch_expr (struct leh_state *state, tree switch_expr)
+verify_norecord_switch_expr (struct leh_state *state, gimple switch_expr)
{
struct leh_tf_state *tf = state->tf;
size_t i, n;
- tree vec;
if (!tf)
return;
- vec = SWITCH_LABELS (switch_expr);
- n = TREE_VEC_LENGTH (vec);
+ n = gimple_switch_num_labels (switch_expr);
for (i = 0; i < n; ++i)
{
- tree lab = CASE_LABEL (TREE_VEC_ELT (vec, i));
- gcc_assert (!outside_finally_tree (lab, tf->try_finally_expr));
+ treemple temp;
+ tree lab = CASE_LABEL (gimple_switch_label (switch_expr, i));
+ temp.t = lab;
+ gcc_assert (!outside_finally_tree (temp, tf->try_finally_expr));
}
}
#else
@@ -595,14 +728,24 @@ verify_norecord_switch_expr (struct leh_state *state, tree switch_expr)
variable to be used in manipulating the value returned from the function. */
static void
-do_return_redirection (struct goto_queue_node *q, tree finlab, tree mod,
+do_return_redirection (struct goto_queue_node *q, tree finlab, gimple_seq mod,
tree *return_value_p)
{
- tree ret_expr = TREE_OPERAND (q->stmt, 0);
- tree x;
+ tree ret_expr;
+ gimple x;
+
+ /* In the case of a return, the queue node must be a gimple statement. */
+ gcc_assert (!q->is_label);
+
+ ret_expr = gimple_return_retval (q->stmt.g);
if (ret_expr)
{
+ if (!*return_value_p)
+ *return_value_p = ret_expr;
+ else
+ gcc_assert (*return_value_p == ret_expr);
+ q->cont_stmt = q->stmt.g;
/* The nasty part about redirecting the return value is that the
return value itself is to be computed before the FINALLY block
is executed. e.g.
@@ -625,78 +768,50 @@ do_return_redirection (struct goto_queue_node *q, tree finlab, tree mod,
depends, I guess, but it does make generation of the switch in
lower_try_finally_switch easier. */
- switch (TREE_CODE (ret_expr))
+ if (TREE_CODE (ret_expr) == RESULT_DECL)
{
- case RESULT_DECL:
if (!*return_value_p)
*return_value_p = ret_expr;
else
gcc_assert (*return_value_p == ret_expr);
- q->cont_stmt = q->stmt;
- break;
-
- case GIMPLE_MODIFY_STMT:
- {
- tree result = GIMPLE_STMT_OPERAND (ret_expr, 0);
- tree new, old = GIMPLE_STMT_OPERAND (ret_expr, 1);
-
- if (!*return_value_p)
- {
- if (aggregate_value_p (TREE_TYPE (result),
- TREE_TYPE (current_function_decl)))
- /* If this function returns in memory, copy the argument
- into the return slot now. Otherwise, we might need to
- worry about magic return semantics, so we need to use a
- temporary to hold the value until we're actually ready
- to return. */
- new = result;
- else
- new = create_tmp_var (TREE_TYPE (old), "rettmp");
- *return_value_p = new;
- }
- else
- new = *return_value_p;
-
- x = build_gimple_modify_stmt (new, old);
- append_to_statement_list (x, &q->repl_stmt);
-
- if (new == result)
- x = result;
- else
- x = build_gimple_modify_stmt (result, new);
- q->cont_stmt = build1 (RETURN_EXPR, void_type_node, x);
- }
-
- default:
- gcc_unreachable ();
+ q->cont_stmt = q->stmt.g;
}
+ else
+ gcc_unreachable ();
}
else
- {
/* If we don't return a value, all return statements are the same. */
- q->cont_stmt = q->stmt;
- }
+ q->cont_stmt = q->stmt.g;
+
+ if (!q->repl_stmt)
+ q->repl_stmt = gimple_seq_alloc ();
if (mod)
- append_to_statement_list (mod, &q->repl_stmt);
+ gimple_seq_add_seq (&q->repl_stmt, mod);
- x = build1 (GOTO_EXPR, void_type_node, finlab);
- append_to_statement_list (x, &q->repl_stmt);
+ x = gimple_build_goto (finlab);
+ gimple_seq_add_stmt (&q->repl_stmt, x);
}
-/* Similar, but easier, for GOTO_EXPR. */
+/* Similar, but easier, for GIMPLE_GOTO. */
static void
-do_goto_redirection (struct goto_queue_node *q, tree finlab, tree mod)
+do_goto_redirection (struct goto_queue_node *q, tree finlab, gimple_seq mod,
+ struct leh_tf_state *tf)
{
- tree x;
+ gimple x;
+
+ gcc_assert (q->is_label);
+ if (!q->repl_stmt)
+ q->repl_stmt = gimple_seq_alloc ();
+
+ q->cont_stmt = gimple_build_goto (VEC_index (tree, tf->dest_array,q->index));
- q->cont_stmt = q->stmt;
if (mod)
- append_to_statement_list (mod, &q->repl_stmt);
+ gimple_seq_add_seq (&q->repl_stmt, mod);
- x = build1 (GOTO_EXPR, void_type_node, finlab);
- append_to_statement_list (x, &q->repl_stmt);
+ x = gimple_build_goto (finlab);
+ gimple_seq_add_stmt (&q->repl_stmt, x);
}
/* We want to transform
@@ -704,56 +819,59 @@ do_goto_redirection (struct goto_queue_node *q, tree finlab, tree mod)
to
body; goto over; lab: stuff; over:
- T is a TRY_FINALLY or TRY_CATCH node. LAB is the label that
+ TP is a GIMPLE_TRY node. LAB is the label that
should be placed before the second operand, or NULL. OVER is
an existing label that should be put at the exit, or NULL. */
-static void
-frob_into_branch_around (tree *tp, tree lab, tree over)
+static gimple_seq
+frob_into_branch_around (gimple tp, tree lab, tree over)
{
- tree x, op1;
+ gimple x;
+ gimple_seq cleanup, result;
- op1 = TREE_OPERAND (*tp, 1);
- *tp = TREE_OPERAND (*tp, 0);
+ cleanup = gimple_try_cleanup (tp);
+ result = gimple_try_eval (tp);
- if (block_may_fallthru (*tp))
+ if (gimple_seq_may_fallthru (result))
{
if (!over)
over = create_artificial_label ();
- x = build1 (GOTO_EXPR, void_type_node, over);
- append_to_statement_list (x, tp);
+ x = gimple_build_goto (over);
+ gimple_seq_add_stmt (&result, x);
}
if (lab)
{
- x = build1 (LABEL_EXPR, void_type_node, lab);
- append_to_statement_list (x, tp);
+ x = gimple_build_label (lab);
+ gimple_seq_add_stmt (&result, x);
}
- append_to_statement_list (op1, tp);
+ gimple_seq_add_seq (&result, cleanup);
if (over)
{
- x = build1 (LABEL_EXPR, void_type_node, over);
- append_to_statement_list (x, tp);
+ x = gimple_build_label (over);
+ gimple_seq_add_stmt (&result, x);
}
+ return result;
}
/* A subroutine of lower_try_finally. Duplicate the tree rooted at T.
Make sure to record all new labels found. */
-static tree
-lower_try_finally_dup_block (tree t, struct leh_state *outer_state)
+static gimple_seq
+lower_try_finally_dup_block (gimple_seq seq, struct leh_state *outer_state)
{
- tree region = NULL;
+ gimple region = NULL;
+ gimple_seq new_seq;
- t = unsave_expr_now (t);
+ new_seq = copy_gimple_seq_and_replace_locals (seq);
if (outer_state->tf)
region = outer_state->tf->try_finally_expr;
- collect_finally_tree (t, region);
+ collect_finally_tree_1 (new_seq, region);
- return t;
+ return new_seq;
}
/* A subroutine of lower_try_finally. Create a fallthru label for
@@ -764,12 +882,17 @@ static tree
lower_try_finally_fallthru_label (struct leh_tf_state *tf)
{
tree label = tf->fallthru_label;
+ treemple temp;
+
if (!label)
{
label = create_artificial_label ();
tf->fallthru_label = label;
if (tf->outer->tf)
- record_in_finally_tree (label, tf->outer->tf->try_finally_expr);
+ {
+ temp.t = label;
+ record_in_finally_tree (temp, tf->outer->tf->try_finally_expr);
+ }
}
return label;
}
@@ -799,9 +922,11 @@ honor_protect_cleanup_actions (struct leh_state *outer_state,
struct leh_state *this_state,
struct leh_tf_state *tf)
{
- tree protect_cleanup_actions, finally, x;
- tree_stmt_iterator i;
+ gimple protect_cleanup_actions;
+ gimple_stmt_iterator gsi;
bool finally_may_fallthru;
+ gimple_seq finally;
+ gimple x;
/* First check for nothing to do. */
if (lang_protect_cleanup_actions)
@@ -809,7 +934,7 @@ honor_protect_cleanup_actions (struct leh_state *outer_state,
else
protect_cleanup_actions = NULL;
- finally = TREE_OPERAND (*tf->top_p, 1);
+ finally = gimple_try_cleanup (tf->top_p);
/* If the EH case of the finally block can fall through, this may be a
structure of the form
@@ -832,7 +957,7 @@ honor_protect_cleanup_actions (struct leh_state *outer_state,
be used (via fallthru from the finally) we handle the eh case here,
whether or not protect_cleanup_actions is active. */
- finally_may_fallthru = block_may_fallthru (finally);
+ finally_may_fallthru = gimple_seq_may_fallthru (finally);
if (!finally_may_fallthru && !protect_cleanup_actions)
return;
@@ -848,14 +973,15 @@ honor_protect_cleanup_actions (struct leh_state *outer_state,
cp/decl.c). Since it's logically at an outer level, we should call
terminate before we get to it, so strip it away before adding the
MUST_NOT_THROW filter. */
- i = tsi_start (finally);
- x = tsi_stmt (i);
+ gsi = gsi_start (finally);
+ x = gsi_stmt (gsi);
if (protect_cleanup_actions
- && TREE_CODE (x) == TRY_CATCH_EXPR
- && TRY_CATCH_IS_CLEANUP (x))
+ && gimple_code (x) == GIMPLE_TRY
+ && gimple_try_kind (x) == GIMPLE_TRY_CATCH
+ && gimple_try_catch_is_cleanup (x))
{
- tsi_link_before (&i, TREE_OPERAND (x, 0), TSI_SAME_STMT);
- tsi_delink (&i);
+ gsi_insert_seq_before (&gsi, gimple_try_eval (x), GSI_SAME_STMT);
+ gsi_remove (&gsi, false);
}
/* Resume execution after the exception. Adding this now lets
@@ -864,55 +990,61 @@ honor_protect_cleanup_actions (struct leh_state *outer_state,
if (finally_may_fallthru)
{
tree save_eptr, save_filt;
+ tree tmp;
save_eptr = create_tmp_var (ptr_type_node, "save_eptr");
save_filt = create_tmp_var (integer_type_node, "save_filt");
- i = tsi_start (finally);
- x = build0 (EXC_PTR_EXPR, ptr_type_node);
- x = build_gimple_modify_stmt (save_eptr, x);
- tsi_link_before (&i, x, TSI_CONTINUE_LINKING);
+ gsi = gsi_start (finally);
+ tmp = build0 (EXC_PTR_EXPR, ptr_type_node);
+ x = gimple_build_assign (save_eptr, tmp);
+ gsi_insert_before (&gsi, x, GSI_CONTINUE_LINKING);
- x = build0 (FILTER_EXPR, integer_type_node);
- x = build_gimple_modify_stmt (save_filt, x);
- tsi_link_before (&i, x, TSI_CONTINUE_LINKING);
+ tmp = build0 (FILTER_EXPR, integer_type_node);
+ x = gimple_build_assign (save_filt, tmp);
+ gsi_insert_before (&gsi, x, GSI_CONTINUE_LINKING);
- i = tsi_last (finally);
- x = build0 (EXC_PTR_EXPR, ptr_type_node);
- x = build_gimple_modify_stmt (x, save_eptr);
- tsi_link_after (&i, x, TSI_CONTINUE_LINKING);
+ gsi = gsi_last (finally);
+ tmp = build0 (EXC_PTR_EXPR, ptr_type_node);
+ x = gimple_build_assign (tmp, save_eptr);
+ gsi_insert_after (&gsi, x, GSI_CONTINUE_LINKING);
- x = build0 (FILTER_EXPR, integer_type_node);
- x = build_gimple_modify_stmt (x, save_filt);
- tsi_link_after (&i, x, TSI_CONTINUE_LINKING);
+ tmp = build0 (FILTER_EXPR, integer_type_node);
+ x = gimple_build_assign (tmp, save_filt);
+ gsi_insert_after (&gsi, x, GSI_CONTINUE_LINKING);
- x = build_resx (get_eh_region_number (tf->region));
- tsi_link_after (&i, x, TSI_CONTINUE_LINKING);
+ x = gimple_build_resx (get_eh_region_number (tf->region));
+ gsi_insert_after (&gsi, x, GSI_CONTINUE_LINKING);
}
/* Wrap the block with protect_cleanup_actions as the action. */
if (protect_cleanup_actions)
{
- x = build2 (EH_FILTER_EXPR, void_type_node, NULL, NULL);
- append_to_statement_list (protect_cleanup_actions, &EH_FILTER_FAILURE (x));
- EH_FILTER_MUST_NOT_THROW (x) = 1;
- finally = build2 (TRY_CATCH_EXPR, void_type_node, finally, x);
- lower_eh_filter (outer_state, &finally);
+ gimple_seq seq = NULL, failure = NULL;
+
+ gimple_seq_add_stmt (&failure, protect_cleanup_actions);
+ x = gimple_build_eh_filter (NULL, failure);
+ gimple_eh_filter_set_must_not_throw (x, 1);
+
+ gimple_seq_add_stmt (&seq, x);
+ x = gimple_build_try (finally, seq, GIMPLE_TRY_CATCH);
+ finally = lower_eh_filter (outer_state, x);
}
else
- lower_eh_constructs_1 (outer_state, &finally);
+ lower_eh_constructs_1 (outer_state, finally);
/* Hook this up to the end of the existing try block. If we
previously fell through the end, we'll have to branch around.
This means adding a new goto, and adding it to the queue. */
- i = tsi_last (TREE_OPERAND (*tf->top_p, 0));
+ gsi = gsi_last (gimple_try_eval (tf->top_p));
if (tf->may_fallthru)
{
- x = lower_try_finally_fallthru_label (tf);
- x = build1 (GOTO_EXPR, void_type_node, x);
- tsi_link_after (&i, x, TSI_CONTINUE_LINKING);
+ tree tmp;
+ tmp = lower_try_finally_fallthru_label (tf);
+ x = gimple_build_goto (tmp);
+ gsi_insert_after (&gsi, x, GSI_CONTINUE_LINKING);
if (this_state)
maybe_record_in_goto_queue (this_state, x);
@@ -920,9 +1052,9 @@ honor_protect_cleanup_actions (struct leh_state *outer_state,
tf->may_fallthru = false;
}
- x = build1 (LABEL_EXPR, void_type_node, tf->eh_label);
- tsi_link_after (&i, x, TSI_CONTINUE_LINKING);
- tsi_link_after (&i, finally, TSI_CONTINUE_LINKING);
+ x = gimple_build_label (tf->eh_label);
+ gsi_insert_after (&gsi, x, GSI_CONTINUE_LINKING);
+ gsi_insert_seq_after (&gsi, finally, GSI_CONTINUE_LINKING);
/* Having now been handled, EH isn't to be considered with
the rest of the outgoing edges. */
@@ -935,9 +1067,12 @@ honor_protect_cleanup_actions (struct leh_state *outer_state,
try_finally node for this special case. */
static void
-lower_try_finally_nofallthru (struct leh_state *state, struct leh_tf_state *tf)
+lower_try_finally_nofallthru (struct leh_state *state,
+ struct leh_tf_state *tf)
{
- tree x, finally, lab, return_val;
+ tree lab, return_val;
+ gimple x;
+ gimple_seq finally;
struct goto_queue_node *q, *qe;
if (tf->may_throw)
@@ -945,11 +1080,12 @@ lower_try_finally_nofallthru (struct leh_state *state, struct leh_tf_state *tf)
else
lab = create_artificial_label ();
- finally = TREE_OPERAND (*tf->top_p, 1);
- *tf->top_p = TREE_OPERAND (*tf->top_p, 0);
+ /* We expect that tf->top_p is a GIMPLE_TRY. */
+ finally = gimple_try_cleanup (tf->top_p);
+ tf->top_p_seq = gimple_try_eval (tf->top_p);
- x = build1 (LABEL_EXPR, void_type_node, lab);
- append_to_statement_list (x, tf->top_p);
+ x = gimple_build_label (lab);
+ gimple_seq_add_stmt (&tf->top_p_seq, x);
return_val = NULL;
q = tf->goto_queue;
@@ -958,12 +1094,12 @@ lower_try_finally_nofallthru (struct leh_state *state, struct leh_tf_state *tf)
if (q->index < 0)
do_return_redirection (q, lab, NULL, &return_val);
else
- do_goto_redirection (q, lab, NULL);
+ do_goto_redirection (q, lab, NULL, tf);
replace_goto_queue (tf);
- lower_eh_constructs_1 (state, &finally);
- append_to_statement_list (finally, tf->top_p);
+ lower_eh_constructs_1 (state, finally);
+ gimple_seq_add_seq (&tf->top_p_seq, finally);
}
/* A subroutine of lower_try_finally. We have determined that there is
@@ -974,26 +1110,28 @@ static void
lower_try_finally_onedest (struct leh_state *state, struct leh_tf_state *tf)
{
struct goto_queue_node *q, *qe;
- tree x, finally, finally_label;
+ gimple x;
+ gimple_seq finally;
+ tree finally_label;
- finally = TREE_OPERAND (*tf->top_p, 1);
- *tf->top_p = TREE_OPERAND (*tf->top_p, 0);
+ finally = gimple_try_cleanup (tf->top_p);
+ tf->top_p_seq = gimple_try_eval (tf->top_p);
- lower_eh_constructs_1 (state, &finally);
+ lower_eh_constructs_1 (state, finally);
if (tf->may_throw)
{
/* Only reachable via the exception edge. Add the given label to
the head of the FINALLY block. Append a RESX at the end. */
- x = build1 (LABEL_EXPR, void_type_node, tf->eh_label);
- append_to_statement_list (x, tf->top_p);
+ x = gimple_build_label (tf->eh_label);
+ gimple_seq_add_stmt (&tf->top_p_seq, x);
- append_to_statement_list (finally, tf->top_p);
+ gimple_seq_add_seq (&tf->top_p_seq, finally);
- x = build_resx (get_eh_region_number (tf->region));
+ x = gimple_build_resx (get_eh_region_number (tf->region));
- append_to_statement_list (x, tf->top_p);
+ gimple_seq_add_stmt (&tf->top_p_seq, x);
return;
}
@@ -1002,15 +1140,15 @@ lower_try_finally_onedest (struct leh_state *state, struct leh_tf_state *tf)
{
/* Only reachable via the fallthru edge. Do nothing but let
the two blocks run together; we'll fall out the bottom. */
- append_to_statement_list (finally, tf->top_p);
+ gimple_seq_add_seq (&tf->top_p_seq, finally);
return;
}
finally_label = create_artificial_label ();
- x = build1 (LABEL_EXPR, void_type_node, finally_label);
- append_to_statement_list (x, tf->top_p);
+ x = gimple_build_label (finally_label);
+ gimple_seq_add_stmt (&tf->top_p_seq, x);
- append_to_statement_list (finally, tf->top_p);
+ gimple_seq_add_seq (&tf->top_p_seq, finally);
q = tf->goto_queue;
qe = q + tf->goto_queue_active;
@@ -1027,7 +1165,7 @@ lower_try_finally_onedest (struct leh_state *state, struct leh_tf_state *tf)
{
/* Reachable by goto expressions only. Redirect them. */
for (; q < qe; ++q)
- do_goto_redirection (q, finally_label, NULL);
+ do_goto_redirection (q, finally_label, NULL, tf);
replace_goto_queue (tf);
if (VEC_index (tree, tf->dest_array, 0) == tf->fallthru_label)
@@ -1040,11 +1178,11 @@ lower_try_finally_onedest (struct leh_state *state, struct leh_tf_state *tf)
}
}
- /* Reset the locus of the goto since we're moving
- goto to a different block which might be on a different line. */
- SET_EXPR_LOCUS (tf->goto_queue[0].cont_stmt, NULL);
- append_to_statement_list (tf->goto_queue[0].cont_stmt, tf->top_p);
- maybe_record_in_goto_queue (state, tf->goto_queue[0].cont_stmt);
+ /* Place the original return/goto to the original destination
+ immediately after the finally block. */
+ x = tf->goto_queue[0].cont_stmt;
+ gimple_seq_add_stmt (&tf->top_p_seq, x);
+ maybe_record_in_goto_queue (state, x);
}
/* A subroutine of lower_try_finally. There are multiple edges incoming
@@ -1054,36 +1192,38 @@ lower_try_finally_onedest (struct leh_state *state, struct leh_tf_state *tf)
static void
lower_try_finally_copy (struct leh_state *state, struct leh_tf_state *tf)
{
- tree finally, new_stmt;
- tree x;
+ gimple_seq finally;
+ gimple_seq new_stmt;
+ gimple_seq seq;
+ gimple x;
+ tree tmp;
- finally = TREE_OPERAND (*tf->top_p, 1);
- *tf->top_p = TREE_OPERAND (*tf->top_p, 0);
-
- new_stmt = NULL_TREE;
+ finally = gimple_try_cleanup (tf->top_p);
+ tf->top_p_seq = gimple_try_eval (tf->top_p);
+ new_stmt = NULL;
if (tf->may_fallthru)
{
- x = lower_try_finally_dup_block (finally, state);
- lower_eh_constructs_1 (state, &x);
- append_to_statement_list (x, &new_stmt);
+ seq = lower_try_finally_dup_block (finally, state);
+ lower_eh_constructs_1 (state, seq);
+ gimple_seq_add_seq (&new_stmt, seq);
- x = lower_try_finally_fallthru_label (tf);
- x = build1 (GOTO_EXPR, void_type_node, x);
- append_to_statement_list (x, &new_stmt);
+ tmp = lower_try_finally_fallthru_label (tf);
+ x = gimple_build_goto (tmp);
+ gimple_seq_add_stmt (&new_stmt, x);
}
if (tf->may_throw)
{
- x = build1 (LABEL_EXPR, void_type_node, tf->eh_label);
- append_to_statement_list (x, &new_stmt);
+ x = gimple_build_label (tf->eh_label);
+ gimple_seq_add_stmt (&new_stmt, x);
- x = lower_try_finally_dup_block (finally, state);
- lower_eh_constructs_1 (state, &x);
- append_to_statement_list (x, &new_stmt);
+ seq = lower_try_finally_dup_block (finally, state);
+ lower_eh_constructs_1 (state, seq);
+ gimple_seq_add_seq (&new_stmt, seq);
- x = build_resx (get_eh_region_number (tf->region));
- append_to_statement_list (x, &new_stmt);
+ x = gimple_build_resx (get_eh_region_number (tf->region));
+ gimple_seq_add_stmt (&new_stmt, x);
}
if (tf->goto_queue)
@@ -1123,16 +1263,16 @@ lower_try_finally_copy (struct leh_state *state, struct leh_tf_state *tf)
if (index == return_index)
do_return_redirection (q, lab, NULL, &return_val);
else
- do_goto_redirection (q, lab, NULL);
+ do_goto_redirection (q, lab, NULL, tf);
- x = build1 (LABEL_EXPR, void_type_node, lab);
- append_to_statement_list (x, &new_stmt);
+ x = gimple_build_label (lab);
+ gimple_seq_add_stmt (&new_stmt, x);
- x = lower_try_finally_dup_block (finally, state);
- lower_eh_constructs_1 (state, &x);
- append_to_statement_list (x, &new_stmt);
+ seq = lower_try_finally_dup_block (finally, state);
+ lower_eh_constructs_1 (state, seq);
+ gimple_seq_add_seq (&new_stmt, seq);
- append_to_statement_list (q->cont_stmt, &new_stmt);
+ gimple_seq_add_stmt (&new_stmt, q->cont_stmt);
maybe_record_in_goto_queue (state, q->cont_stmt);
}
@@ -1150,7 +1290,7 @@ lower_try_finally_copy (struct leh_state *state, struct leh_tf_state *tf)
if (index == return_index)
do_return_redirection (q, lab, NULL, &return_val);
else
- do_goto_redirection (q, lab, NULL);
+ do_goto_redirection (q, lab, NULL, tf);
}
replace_goto_queue (tf);
@@ -1159,7 +1299,7 @@ lower_try_finally_copy (struct leh_state *state, struct leh_tf_state *tf)
/* Need to link new stmts after running replace_goto_queue due
to not wanting to process the same goto stmts twice. */
- append_to_statement_list (new_stmt, tf->top_p);
+ gimple_seq_add_seq (&tf->top_p_seq, new_stmt);
}
/* A subroutine of lower_try_finally. There are multiple edges incoming
@@ -1172,18 +1312,26 @@ lower_try_finally_switch (struct leh_state *state, struct leh_tf_state *tf)
{
struct goto_queue_node *q, *qe;
tree return_val = NULL;
- tree finally, finally_tmp, finally_label;
+ tree finally_tmp, finally_label;
int return_index, eh_index, fallthru_index;
int nlabels, ndests, j, last_case_index;
- tree case_label_vec, switch_stmt, last_case, switch_body;
- tree x;
+ tree last_case;
+ VEC (tree,heap) *case_label_vec;
+ gimple_seq switch_body;
+ gimple x;
+ tree tmp;
+ gimple switch_stmt;
+ gimple_seq finally;
+ struct pointer_map_t *cont_map = NULL;
+
+ switch_body = gimple_seq_alloc ();
/* Mash the TRY block to the head of the chain. */
- finally = TREE_OPERAND (*tf->top_p, 1);
- *tf->top_p = TREE_OPERAND (*tf->top_p, 0);
+ finally = gimple_try_cleanup (tf->top_p);
+ tf->top_p_seq = gimple_try_eval (tf->top_p);
/* Lower the finally block itself. */
- lower_eh_constructs_1 (state, &finally);
+ lower_eh_constructs_1 (state, finally);
/* Prepare for switch statement generation. */
nlabels = VEC_length (tree, tf->dest_array);
@@ -1195,10 +1343,10 @@ lower_try_finally_switch (struct leh_state *state, struct leh_tf_state *tf)
finally_tmp = create_tmp_var (integer_type_node, "finally_tmp");
finally_label = create_artificial_label ();
- case_label_vec = make_tree_vec (ndests);
- switch_stmt = build3 (SWITCH_EXPR, integer_type_node, finally_tmp,
- NULL_TREE, case_label_vec);
- switch_body = NULL;
+ /* We use VEC_quick_push on case_label_vec throughout this function,
+ since we know the size in advance and allocate precisely as muce
+ space as needed. */
+ case_label_vec = VEC_alloc (tree, heap, ndests);
last_case = NULL;
last_case_index = 0;
@@ -1208,117 +1356,137 @@ lower_try_finally_switch (struct leh_state *state, struct leh_tf_state *tf)
if (tf->may_fallthru)
{
- x = build_gimple_modify_stmt (finally_tmp,
- build_int_cst (integer_type_node,
- fallthru_index));
- append_to_statement_list (x, tf->top_p);
+ x = gimple_build_assign (finally_tmp, build_int_cst (integer_type_node,
+ fallthru_index));
+ gimple_seq_add_stmt (&tf->top_p_seq, x);
if (tf->may_throw)
{
- x = build1 (GOTO_EXPR, void_type_node, finally_label);
- append_to_statement_list (x, tf->top_p);
+ x = gimple_build_goto (finally_label);
+ gimple_seq_add_stmt (&tf->top_p_seq, x);
}
last_case = build3 (CASE_LABEL_EXPR, void_type_node,
build_int_cst (NULL_TREE, fallthru_index), NULL,
create_artificial_label ());
- TREE_VEC_ELT (case_label_vec, last_case_index) = last_case;
+ VEC_quick_push (tree, case_label_vec, last_case);
last_case_index++;
- x = build1 (LABEL_EXPR, void_type_node, CASE_LABEL (last_case));
- append_to_statement_list (x, &switch_body);
+ x = gimple_build_label (CASE_LABEL (last_case));
+ gimple_seq_add_stmt (&switch_body, x);
- x = lower_try_finally_fallthru_label (tf);
- x = build1 (GOTO_EXPR, void_type_node, x);
- append_to_statement_list (x, &switch_body);
+ tmp = lower_try_finally_fallthru_label (tf);
+ x = gimple_build_goto (tmp);
+ gimple_seq_add_stmt (&switch_body, x);
}
if (tf->may_throw)
{
- x = build1 (LABEL_EXPR, void_type_node, tf->eh_label);
- append_to_statement_list (x, tf->top_p);
+ x = gimple_build_label (tf->eh_label);
+ gimple_seq_add_stmt (&tf->top_p_seq, x);
- x = build_gimple_modify_stmt (finally_tmp,
- build_int_cst (integer_type_node,
- eh_index));
- append_to_statement_list (x, tf->top_p);
+ x = gimple_build_assign (finally_tmp, build_int_cst (integer_type_node,
+ eh_index));
+ gimple_seq_add_stmt (&tf->top_p_seq, x);
last_case = build3 (CASE_LABEL_EXPR, void_type_node,
build_int_cst (NULL_TREE, eh_index), NULL,
create_artificial_label ());
- TREE_VEC_ELT (case_label_vec, last_case_index) = last_case;
+ VEC_quick_push (tree, case_label_vec, last_case);
last_case_index++;
- x = build1 (LABEL_EXPR, void_type_node, CASE_LABEL (last_case));
- append_to_statement_list (x, &switch_body);
- x = build_resx (get_eh_region_number (tf->region));
- append_to_statement_list (x, &switch_body);
+ x = gimple_build_label (CASE_LABEL (last_case));
+ gimple_seq_add_stmt (&switch_body, x);
+ x = gimple_build_resx (get_eh_region_number (tf->region));
+ gimple_seq_add_stmt (&switch_body, x);
}
- x = build1 (LABEL_EXPR, void_type_node, finally_label);
- append_to_statement_list (x, tf->top_p);
+ x = gimple_build_label (finally_label);
+ gimple_seq_add_stmt (&tf->top_p_seq, x);
- append_to_statement_list (finally, tf->top_p);
+ gimple_seq_add_seq (&tf->top_p_seq, finally);
/* Redirect each incoming goto edge. */
q = tf->goto_queue;
qe = q + tf->goto_queue_active;
j = last_case_index + tf->may_return;
+ /* Prepare the assignments to finally_tmp that are executed upon the
+ entrance through a particular edge. */
for (; q < qe; ++q)
{
- tree mod;
- int switch_id, case_index;
+ gimple_seq mod;
+ int switch_id;
+ unsigned int case_index;
+
+ mod = gimple_seq_alloc ();
if (q->index < 0)
{
- mod = build_gimple_modify_stmt (finally_tmp,
- build_int_cst (integer_type_node,
- return_index));
+ x = gimple_build_assign (finally_tmp,
+ build_int_cst (integer_type_node,
+ return_index));
+ gimple_seq_add_stmt (&mod, x);
do_return_redirection (q, finally_label, mod, &return_val);
switch_id = return_index;
}
else
{
- mod = build_gimple_modify_stmt (finally_tmp,
- build_int_cst (integer_type_node,
- q->index));
- do_goto_redirection (q, finally_label, mod);
+ x = gimple_build_assign (finally_tmp,
+ build_int_cst (integer_type_node, q->index));
+ gimple_seq_add_stmt (&mod, x);
+ do_goto_redirection (q, finally_label, mod, tf);
switch_id = q->index;
}
case_index = j + q->index;
- if (!TREE_VEC_ELT (case_label_vec, case_index))
- TREE_VEC_ELT (case_label_vec, case_index)
- = build3 (CASE_LABEL_EXPR, void_type_node,
- build_int_cst (NULL_TREE, switch_id), NULL,
- /* We store the cont_stmt in the
- CASE_LABEL, so that we can recover it
- in the loop below. We don't create
- the new label while walking the
- goto_queue because pointers don't
- offer a stable order. */
- q->cont_stmt);
+ if (VEC_length (tree, case_label_vec) <= case_index
+ || !VEC_index (tree, case_label_vec, case_index))
+ {
+ tree case_lab;
+ void **slot;
+ case_lab = build3 (CASE_LABEL_EXPR, void_type_node,
+ build_int_cst (NULL_TREE, switch_id), NULL,
+ NULL);
+ /* We store the cont_stmt in the pointer map, so that we can recover
+ it in the loop below. We don't create the new label while
+ walking the goto_queue because pointers don't offer a stable
+ order. */
+ if (!cont_map)
+ cont_map = pointer_map_create ();
+ slot = pointer_map_insert (cont_map, case_lab);
+ *slot = q->cont_stmt;
+ VEC_quick_push (tree, case_label_vec, case_lab);
+ }
}
for (j = last_case_index; j < last_case_index + nlabels; j++)
{
tree label;
- tree cont_stmt;
+ gimple cont_stmt;
+ void **slot;
- last_case = TREE_VEC_ELT (case_label_vec, j);
+ last_case = VEC_index (tree, case_label_vec, j);
gcc_assert (last_case);
+ gcc_assert (cont_map);
- cont_stmt = CASE_LABEL (last_case);
+ slot = pointer_map_contains (cont_map, last_case);
+ /* As the comment above suggests, CASE_LABEL (last_case) was just a
+ placeholder, it does not store an actual label, yet. */
+ gcc_assert (slot);
+ cont_stmt = *(gimple *) slot;
label = create_artificial_label ();
CASE_LABEL (last_case) = label;
- x = build1 (LABEL_EXPR, void_type_node, label);
- append_to_statement_list (x, &switch_body);
- append_to_statement_list (cont_stmt, &switch_body);
+ x = gimple_build_label (label);
+ gimple_seq_add_stmt (&switch_body, x);
+ gimple_seq_add_stmt (&switch_body, cont_stmt);
maybe_record_in_goto_queue (state, cont_stmt);
}
+ if (cont_map)
+ pointer_map_destroy (cont_map);
+
replace_goto_queue (tf);
/* Make sure that the last case is the default label, as one is required.
@@ -1326,10 +1494,15 @@ lower_try_finally_switch (struct leh_state *state, struct leh_tf_state *tf)
CASE_LOW (last_case) = NULL;
sort_case_labels (case_label_vec);
- /* Need to link switch_stmt after running replace_goto_queue due
- to not wanting to process the same goto stmts twice. */
- append_to_statement_list (switch_stmt, tf->top_p);
- append_to_statement_list (switch_body, tf->top_p);
+ /* Build the switch statement, setting last_case to be the default
+ label. */
+ switch_stmt = gimple_build_switch_vec (finally_tmp, last_case,
+ case_label_vec);
+
+ /* Need to link SWITCH_STMT after running replace_goto_queue
+ due to not wanting to process the same goto stmts twice. */
+ gimple_seq_add_stmt (&tf->top_p_seq, switch_stmt);
+ gimple_seq_add_seq (&tf->top_p_seq, switch_body);
}
/* Decide whether or not we are going to duplicate the finally block.
@@ -1347,7 +1520,7 @@ lower_try_finally_switch (struct leh_state *state, struct leh_tf_state *tf)
the estimate of the size of the switch machinery we'd have to add. */
static bool
-decide_copy_try_finally (int ndests, tree finally)
+decide_copy_try_finally (int ndests, gimple_seq finally)
{
int f_estimate, sw_estimate;
@@ -1355,7 +1528,7 @@ decide_copy_try_finally (int ndests, tree finally)
return false;
/* Finally estimate N times, plus N gotos. */
- f_estimate = estimate_num_insns (finally, &eni_size_weights);
+ f_estimate = count_insns_seq (finally, &eni_size_weights);
f_estimate = (f_estimate + 1) * ndests;
/* Switch statement (cost 10), N variable assignments, N gotos. */
@@ -1372,13 +1545,14 @@ decide_copy_try_finally (int ndests, tree finally)
return f_estimate < 40 || f_estimate * 2 < sw_estimate * 3;
}
-/* A subroutine of lower_eh_constructs_1. Lower a TRY_FINALLY_EXPR nodes
+
+/* A subroutine of lower_eh_constructs_1. Lower a GIMPLE_TRY_FINALLY nodes
to a sequence of labels and blocks, plus the exception region trees
that record all the magic. This is complicated by the need to
arrange for the FINALLY block to be executed on all exits. */
-static void
-lower_try_finally (struct leh_state *state, tree *tp)
+static gimple_seq
+lower_try_finally (struct leh_state *state, gimple tp)
{
struct leh_tf_state this_tf;
struct leh_state this_state;
@@ -1387,7 +1561,7 @@ lower_try_finally (struct leh_state *state, tree *tp)
/* Process the try block. */
memset (&this_tf, 0, sizeof (this_tf));
- this_tf.try_finally_expr = *tp;
+ this_tf.try_finally_expr = tp;
this_tf.top_p = tp;
this_tf.outer = state;
if (using_eh_for_cleanups_p)
@@ -1400,10 +1574,10 @@ lower_try_finally (struct leh_state *state, tree *tp)
this_state.prev_try = state->prev_try;
this_state.tf = &this_tf;
- lower_eh_constructs_1 (&this_state, &TREE_OPERAND (*tp, 0));
+ lower_eh_constructs_1 (&this_state, gimple_try_eval(tp));
/* Determine if the try block is escaped through the bottom. */
- this_tf.may_fallthru = block_may_fallthru (TREE_OPERAND (*tp, 0));
+ this_tf.may_fallthru = gimple_seq_may_fallthru (gimple_try_eval (tp));
/* Determine if any exceptions are possible within the try block. */
if (using_eh_for_cleanups_p)
@@ -1426,19 +1600,20 @@ lower_try_finally (struct leh_state *state, tree *tp)
/* If the FINALLY block is not reachable, dike it out. */
if (ndests == 0)
- *tp = TREE_OPERAND (*tp, 0);
-
+ {
+ gimple_seq_add_seq (&this_tf.top_p_seq, gimple_try_eval (tp));
+ gimple_try_set_cleanup (tp, NULL);
+ }
/* If the finally block doesn't fall through, then any destination
we might try to impose there isn't reached either. There may be
some minor amount of cleanup and redirection still needed. */
- else if (!block_may_fallthru (TREE_OPERAND (*tp, 1)))
+ else if (!gimple_seq_may_fallthru (gimple_try_cleanup (tp)))
lower_try_finally_nofallthru (state, &this_tf);
/* We can easily special-case redirection to a single destination. */
else if (ndests == 1)
lower_try_finally_onedest (state, &this_tf);
-
- else if (decide_copy_try_finally (ndests, TREE_OPERAND (*tp, 1)))
+ else if (decide_copy_try_finally (ndests, gimple_try_cleanup (tp)))
lower_try_finally_copy (state, &this_tf);
else
lower_try_finally_switch (state, &this_tf);
@@ -1447,8 +1622,9 @@ lower_try_finally (struct leh_state *state, tree *tp)
block, do so. */
if (this_tf.fallthru_label)
{
- tree x = build1 (LABEL_EXPR, void_type_node, this_tf.fallthru_label);
- append_to_statement_list (x, tp);
+ /* This must be reached only if ndests == 0. */
+ gimple x = gimple_build_label (this_tf.fallthru_label);
+ gimple_seq_add_stmt (&this_tf.top_p_seq, x);
}
VEC_free (tree, heap, this_tf.dest_array);
@@ -1456,18 +1632,20 @@ lower_try_finally (struct leh_state *state, tree *tp)
free (this_tf.goto_queue);
if (this_tf.goto_queue_map)
pointer_map_destroy (this_tf.goto_queue_map);
+
+ return this_tf.top_p_seq;
}
-/* A subroutine of lower_eh_constructs_1. Lower a TRY_CATCH_EXPR with a
- list of CATCH_EXPR nodes to a sequence of labels and blocks, plus the
- exception region trees that record all the magic. */
+/* A subroutine of lower_eh_constructs_1. Lower a GIMPLE_TRY_CATCH with a
+ list of GIMPLE_CATCH to a sequence of labels and blocks, plus the
+ exception region trees that records all the magic. */
-static void
-lower_catch (struct leh_state *state, tree *tp)
+static gimple_seq
+lower_catch (struct leh_state *state, gimple tp)
{
struct eh_region *try_region;
struct leh_state this_state;
- tree_stmt_iterator i;
+ gimple_stmt_iterator gsi;
tree out_label;
try_region = gen_eh_region_try (state->cur_region);
@@ -1475,118 +1653,121 @@ lower_catch (struct leh_state *state, tree *tp)
this_state.prev_try = try_region;
this_state.tf = state->tf;
- lower_eh_constructs_1 (&this_state, &TREE_OPERAND (*tp, 0));
+ lower_eh_constructs_1 (&this_state, gimple_try_eval (tp));
if (!get_eh_region_may_contain_throw (try_region))
{
- *tp = TREE_OPERAND (*tp, 0);
- return;
+ return gimple_try_eval (tp);
}
out_label = NULL;
- for (i = tsi_start (TREE_OPERAND (*tp, 1)); !tsi_end_p (i); )
+ for (gsi = gsi_start (gimple_try_cleanup (tp)); !gsi_end_p (gsi); )
{
struct eh_region *catch_region;
- tree catch, x, eh_label;
+ tree eh_label;
+ gimple x, catch;
- catch = tsi_stmt (i);
- catch_region = gen_eh_region_catch (try_region, CATCH_TYPES (catch));
+ catch = gsi_stmt (gsi);
+ catch_region = gen_eh_region_catch (try_region,
+ gimple_catch_types (catch));
this_state.cur_region = catch_region;
this_state.prev_try = state->prev_try;
- lower_eh_constructs_1 (&this_state, &CATCH_BODY (catch));
+ lower_eh_constructs_1 (&this_state, gimple_catch_handler (catch));
eh_label = create_artificial_label ();
set_eh_region_tree_label (catch_region, eh_label);
- x = build1 (LABEL_EXPR, void_type_node, eh_label);
- tsi_link_before (&i, x, TSI_SAME_STMT);
+ x = gimple_build_label (eh_label);
+ gsi_insert_before (&gsi, x, GSI_SAME_STMT);
- if (block_may_fallthru (CATCH_BODY (catch)))
+ if (gimple_seq_may_fallthru (gimple_catch_handler (catch)))
{
if (!out_label)
out_label = create_artificial_label ();
- x = build1 (GOTO_EXPR, void_type_node, out_label);
- append_to_statement_list (x, &CATCH_BODY (catch));
+ x = gimple_build_goto (out_label);
+ gimple_seq_add_stmt (gimple_catch_handler_ptr (catch), x);
}
- tsi_link_before (&i, CATCH_BODY (catch), TSI_SAME_STMT);
- tsi_delink (&i);
+ gsi_insert_seq_before (&gsi, gimple_catch_handler (catch),
+ GSI_SAME_STMT);
+ gsi_remove (&gsi, false);
}
- frob_into_branch_around (tp, NULL, out_label);
+ return frob_into_branch_around (tp, NULL, out_label);
}
-/* A subroutine of lower_eh_constructs_1. Lower a TRY_CATCH_EXPR with a
- EH_FILTER_EXPR to a sequence of labels and blocks, plus the exception
+/* A subroutine of lower_eh_constructs_1. Lower a GIMPLE_TRY with a
+ GIMPLE_EH_FILTER to a sequence of labels and blocks, plus the exception
region trees that record all the magic. */
-static void
-lower_eh_filter (struct leh_state *state, tree *tp)
+static gimple_seq
+lower_eh_filter (struct leh_state *state, gimple tp)
{
struct leh_state this_state;
struct eh_region *this_region;
- tree inner = expr_first (TREE_OPERAND (*tp, 1));
+ gimple inner;
tree eh_label;
- if (EH_FILTER_MUST_NOT_THROW (inner))
+ inner = gimple_seq_first_stmt (gimple_try_cleanup (tp));
+
+ if (gimple_eh_filter_must_not_throw (inner))
this_region = gen_eh_region_must_not_throw (state->cur_region);
else
this_region = gen_eh_region_allowed (state->cur_region,
- EH_FILTER_TYPES (inner));
+ gimple_eh_filter_types (inner));
this_state = *state;
this_state.cur_region = this_region;
/* For must not throw regions any cleanup regions inside it
can't reach outer catch regions. */
- if (EH_FILTER_MUST_NOT_THROW (inner))
+ if (gimple_eh_filter_must_not_throw (inner))
this_state.prev_try = NULL;
- lower_eh_constructs_1 (&this_state, &TREE_OPERAND (*tp, 0));
+ lower_eh_constructs_1 (&this_state, gimple_try_eval (tp));
if (!get_eh_region_may_contain_throw (this_region))
{
- *tp = TREE_OPERAND (*tp, 0);
- return;
+ return gimple_try_eval (tp);
}
- lower_eh_constructs_1 (state, &EH_FILTER_FAILURE (inner));
- TREE_OPERAND (*tp, 1) = EH_FILTER_FAILURE (inner);
+ lower_eh_constructs_1 (state, gimple_eh_filter_failure (inner));
+ gimple_try_set_cleanup (tp, gimple_eh_filter_failure (inner));
eh_label = create_artificial_label ();
set_eh_region_tree_label (this_region, eh_label);
- frob_into_branch_around (tp, eh_label, NULL);
+ return frob_into_branch_around (tp, eh_label, NULL);
}
/* Implement a cleanup expression. This is similar to try-finally,
except that we only execute the cleanup block for exception edges. */
-static void
-lower_cleanup (struct leh_state *state, tree *tp)
+static gimple_seq
+lower_cleanup (struct leh_state *state, gimple tp)
{
struct leh_state this_state;
struct eh_region *this_region;
struct leh_tf_state fake_tf;
+ gimple_seq result;
/* If not using eh, then exception-only cleanups are no-ops. */
if (!flag_exceptions)
{
- *tp = TREE_OPERAND (*tp, 0);
- lower_eh_constructs_1 (state, tp);
- return;
+ result = gimple_try_eval (tp);
+ lower_eh_constructs_1 (state, result);
+ return result;
}
this_region = gen_eh_region_cleanup (state->cur_region, state->prev_try);
this_state = *state;
this_state.cur_region = this_region;
- lower_eh_constructs_1 (&this_state, &TREE_OPERAND (*tp, 0));
+ lower_eh_constructs_1 (&this_state, gimple_try_eval (tp));
if (!get_eh_region_may_contain_throw (this_region))
{
- *tp = TREE_OPERAND (*tp, 0);
- return;
+ return gimple_try_eval (tp);
}
/* Build enough of a try-finally state so that we can reuse
@@ -1595,7 +1776,7 @@ lower_cleanup (struct leh_state *state, tree *tp)
fake_tf.top_p = tp;
fake_tf.outer = state;
fake_tf.region = this_region;
- fake_tf.may_fallthru = block_may_fallthru (TREE_OPERAND (*tp, 0));
+ fake_tf.may_fallthru = gimple_seq_may_fallthru (gimple_try_eval (tp));
fake_tf.may_throw = true;
fake_tf.eh_label = create_artificial_label ();
@@ -1607,118 +1788,119 @@ lower_cleanup (struct leh_state *state, tree *tp)
{
/* In this case honor_protect_cleanup_actions had nothing to do,
and we should process this normally. */
- lower_eh_constructs_1 (state, &TREE_OPERAND (*tp, 1));
- frob_into_branch_around (tp, fake_tf.eh_label, fake_tf.fallthru_label);
+ lower_eh_constructs_1 (state, gimple_try_cleanup (tp));
+ result = frob_into_branch_around (tp, fake_tf.eh_label,
+ fake_tf.fallthru_label);
}
else
{
/* In this case honor_protect_cleanup_actions did nearly all of
the work. All we have left is to append the fallthru_label. */
- *tp = TREE_OPERAND (*tp, 0);
+ result = gimple_try_eval (tp);
if (fake_tf.fallthru_label)
{
- tree x = build1 (LABEL_EXPR, void_type_node, fake_tf.fallthru_label);
- append_to_statement_list (x, tp);
+ gimple x = gimple_build_label (fake_tf.fallthru_label);
+ gimple_seq_add_stmt (&result, x);
}
}
+ return result;
}
-/* Main loop for lowering eh constructs. */
+
+
+/* Main loop for lowering eh constructs. Also moves gsi to the next
+ statement. */
static void
-lower_eh_constructs_1 (struct leh_state *state, tree *tp)
+lower_eh_constructs_2 (struct leh_state *state, gimple_stmt_iterator *gsi)
{
- tree_stmt_iterator i;
- tree t = *tp;
+ gimple_seq replace;
+ gimple x;
+ gimple stmt = gsi_stmt (*gsi);
- switch (TREE_CODE (t))
+ switch (gimple_code (stmt))
{
- case COND_EXPR:
- lower_eh_constructs_1 (state, &COND_EXPR_THEN (t));
- lower_eh_constructs_1 (state, &COND_EXPR_ELSE (t));
- break;
-
- case CALL_EXPR:
- /* Look for things that can throw exceptions, and record them. */
- if (state->cur_region && tree_could_throw_p (t))
- {
- record_stmt_eh_region (state->cur_region, t);
- note_eh_region_may_contain_throw (state->cur_region);
- }
- break;
-
- case GIMPLE_MODIFY_STMT:
+ case GIMPLE_CALL:
+ case GIMPLE_ASSIGN:
/* Look for things that can throw exceptions, and record them. */
- if (state->cur_region && tree_could_throw_p (t))
+ if (state->cur_region && stmt_could_throw_p (stmt))
{
- record_stmt_eh_region (state->cur_region, t);
+ record_stmt_eh_region (state->cur_region, stmt);
note_eh_region_may_contain_throw (state->cur_region);
}
break;
- case GOTO_EXPR:
- case RETURN_EXPR:
- maybe_record_in_goto_queue (state, t);
- break;
- case SWITCH_EXPR:
- verify_norecord_switch_expr (state, t);
+ case GIMPLE_COND:
+ case GIMPLE_GOTO:
+ case GIMPLE_RETURN:
+ maybe_record_in_goto_queue (state, stmt);
break;
- case TRY_FINALLY_EXPR:
- lower_try_finally (state, tp);
+ case GIMPLE_SWITCH:
+ verify_norecord_switch_expr (state, stmt);
break;
- case TRY_CATCH_EXPR:
- i = tsi_start (TREE_OPERAND (t, 1));
- switch (TREE_CODE (tsi_stmt (i)))
- {
- case CATCH_EXPR:
- lower_catch (state, tp);
- break;
- case EH_FILTER_EXPR:
- lower_eh_filter (state, tp);
- break;
- default:
- lower_cleanup (state, tp);
- break;
- }
- break;
-
- case STATEMENT_LIST:
- for (i = tsi_start (t); !tsi_end_p (i); )
+ case GIMPLE_TRY:
+ if (gimple_try_kind (stmt) == GIMPLE_TRY_FINALLY)
+ replace = lower_try_finally (state, stmt);
+ else
{
- lower_eh_constructs_1 (state, tsi_stmt_ptr (i));
- t = tsi_stmt (i);
- if (TREE_CODE (t) == STATEMENT_LIST)
+ x = gimple_seq_first_stmt (gimple_try_cleanup (stmt));
+ switch (gimple_code (x))
{
- tsi_link_before (&i, t, TSI_SAME_STMT);
- tsi_delink (&i);
+ case GIMPLE_CATCH:
+ replace = lower_catch (state, stmt);
+ break;
+ case GIMPLE_EH_FILTER:
+ replace = lower_eh_filter (state, stmt);
+ break;
+ default:
+ replace = lower_cleanup (state, stmt);
+ break;
}
- else
- tsi_next (&i);
}
- break;
+
+ /* Remove the old stmt and insert the transformed sequence
+ instead. */
+ gsi_insert_seq_before (gsi, replace, GSI_SAME_STMT);
+ gsi_remove (gsi, true);
+
+ /* Return since we don't want gsi_next () */
+ return;
default:
/* A type, a decl, or some kind of statement that we're not
interested in. Don't walk them. */
break;
}
+
+ gsi_next (gsi);
+}
+
+/* A helper to unwrap a gimple_seq and feed stmts to lower_eh_constructs_2. */
+
+static void
+lower_eh_constructs_1 (struct leh_state *state, gimple_seq seq)
+{
+ gimple_stmt_iterator gsi;
+ for (gsi = gsi_start (seq); !gsi_end_p (gsi);)
+ lower_eh_constructs_2 (state, &gsi);
}
static unsigned int
lower_eh_constructs (void)
{
struct leh_state null_state;
- tree *tp = &DECL_SAVED_TREE (current_function_decl);
+
+ gimple_seq bodyp = gimple_body (current_function_decl);
finally_tree = htab_create (31, struct_ptr_hash, struct_ptr_eq, free);
- collect_finally_tree (*tp, NULL);
+ collect_finally_tree_1 (bodyp, NULL);
memset (&null_state, 0, sizeof (null_state));
- lower_eh_constructs_1 (&null_state, tp);
+ lower_eh_constructs_1 (&null_state, bodyp);
htab_delete (finally_tree);
@@ -1751,27 +1933,28 @@ struct gimple_opt_pass pass_lower_eh =
static void
make_eh_edge (struct eh_region *region, void *data)
{
- tree stmt, lab;
+ gimple stmt;
+ tree lab;
basic_block src, dst;
- stmt = (tree) data;
+ stmt = (gimple) data;
lab = get_eh_region_tree_label (region);
- src = bb_for_stmt (stmt);
+ src = gimple_bb (stmt);
dst = label_to_block (lab);
make_edge (src, dst, EDGE_ABNORMAL | EDGE_EH);
}
void
-make_eh_edges (tree stmt)
+make_eh_edges (gimple stmt)
{
int region_nr;
bool is_resx;
- if (TREE_CODE (stmt) == RESX_EXPR)
+ if (gimple_code (stmt) == GIMPLE_RESX)
{
- region_nr = TREE_INT_CST_LOW (TREE_OPERAND (stmt, 0));
+ region_nr = gimple_resx_region (stmt);
is_resx = true;
}
else
@@ -1789,17 +1972,19 @@ static bool mark_eh_edge_found_error;
/* Mark edge make_eh_edge would create for given region by setting it aux
field, output error if something goes wrong. */
+
static void
mark_eh_edge (struct eh_region *region, void *data)
{
- tree stmt, lab;
+ gimple stmt;
+ tree lab;
basic_block src, dst;
edge e;
- stmt = (tree) data;
+ stmt = (gimple) data;
lab = get_eh_region_tree_label (region);
- src = bb_for_stmt (stmt);
+ src = gimple_bb (stmt);
dst = label_to_block (lab);
e = find_edge (src, dst);
@@ -1823,23 +2008,24 @@ mark_eh_edge (struct eh_region *region, void *data)
e->aux = (void *)1;
}
-/* Verify that BB containing stmt as last stmt has precisely the edges
- make_eh_edges would create. */
+/* Verify that BB containing STMT as the last statement, has precisely the
+ edges that make_eh_edges would create. */
+
bool
-verify_eh_edges (tree stmt)
+verify_eh_edges (gimple stmt)
{
int region_nr;
bool is_resx;
- basic_block bb = bb_for_stmt (stmt);
+ basic_block bb = gimple_bb (stmt);
edge_iterator ei;
edge e;
FOR_EACH_EDGE (e, ei, bb->succs)
gcc_assert (!e->aux);
mark_eh_edge_found_error = false;
- if (TREE_CODE (stmt) == RESX_EXPR)
+ if (gimple_code (stmt) == GIMPLE_RESX)
{
- region_nr = TREE_INT_CST_LOW (TREE_OPERAND (stmt, 0));
+ region_nr = gimple_resx_region (stmt);
is_resx = true;
}
else
@@ -1855,7 +2041,7 @@ verify_eh_edges (tree stmt)
}
return false;
}
- if (!tree_could_throw_p (stmt))
+ if (!stmt_could_throw_p (stmt))
{
error ("BB %i last statement has incorrectly set region", bb->index);
return true;
@@ -1874,42 +2060,151 @@ verify_eh_edges (tree stmt)
}
e->aux = NULL;
}
+
return mark_eh_edge_found_error;
}
-/* Return true if the expr can trap, as in dereferencing an invalid pointer
+/* Helper function for operation_could_trap_p and stmt_could_throw_p. */
+
+static bool
+operation_could_trap_helper_p (enum tree_code op,
+ bool fp_operation,
+ bool honor_trapv,
+ bool honor_nans,
+ bool honor_snans,
+ tree divisor,
+ bool *handled)
+{
+ *handled = true;
+ switch (op)
+ {
+ case TRUNC_DIV_EXPR:
+ case CEIL_DIV_EXPR:
+ case FLOOR_DIV_EXPR:
+ case ROUND_DIV_EXPR:
+ case EXACT_DIV_EXPR:
+ case CEIL_MOD_EXPR:
+ case FLOOR_MOD_EXPR:
+ case ROUND_MOD_EXPR:
+ case TRUNC_MOD_EXPR:
+ case RDIV_EXPR:
+ if (honor_snans || honor_trapv)
+ return true;
+ if (fp_operation)
+ return flag_trapping_math;
+ if (!TREE_CONSTANT (divisor) || integer_zerop (divisor))
+ return true;
+ return false;
+
+ case LT_EXPR:
+ case LE_EXPR:
+ case GT_EXPR:
+ case GE_EXPR:
+ case LTGT_EXPR:
+ /* Some floating point comparisons may trap. */
+ return honor_nans;
+
+ case EQ_EXPR:
+ case NE_EXPR:
+ case UNORDERED_EXPR:
+ case ORDERED_EXPR:
+ case UNLT_EXPR:
+ case UNLE_EXPR:
+ case UNGT_EXPR:
+ case UNGE_EXPR:
+ case UNEQ_EXPR:
+ return honor_snans;
+
+ case CONVERT_EXPR:
+ case FIX_TRUNC_EXPR:
+ /* Conversion of floating point might trap. */
+ return honor_nans;
+
+ case NEGATE_EXPR:
+ case ABS_EXPR:
+ case CONJ_EXPR:
+ /* These operations don't trap with floating point. */
+ if (honor_trapv)
+ return true;
+ return false;
+
+ case PLUS_EXPR:
+ case MINUS_EXPR:
+ case MULT_EXPR:
+ /* Any floating arithmetic may trap. */
+ if (fp_operation && flag_trapping_math)
+ return true;
+ if (honor_trapv)
+ return true;
+ return false;
+
+ default:
+ /* Any floating arithmetic may trap. */
+ if (fp_operation && flag_trapping_math)
+ return true;
+
+ *handled = false;
+ return false;
+ }
+}
+
+/* Return true if operation OP may trap. FP_OPERATION is true if OP is applied
+ on floating-point values. HONOR_TRAPV is true if OP is applied on integer
+ type operands that may trap. If OP is a division operator, DIVISOR contains
+ the value of the divisor. */
+
+bool
+operation_could_trap_p (enum tree_code op, bool fp_operation, bool honor_trapv,
+ tree divisor)
+{
+ bool honor_nans = (fp_operation && flag_trapping_math
+ && !flag_finite_math_only);
+ bool honor_snans = fp_operation && flag_signaling_nans != 0;
+ bool handled;
+
+ if (TREE_CODE_CLASS (op) != tcc_comparison
+ && TREE_CODE_CLASS (op) != tcc_unary
+ && TREE_CODE_CLASS (op) != tcc_binary)
+ return false;
+
+ return operation_could_trap_helper_p (op, fp_operation, honor_trapv,
+ honor_nans, honor_snans, divisor,
+ &handled);
+}
+
+/* Return true if EXPR can trap, as in dereferencing an invalid pointer
location or floating point arithmetic. C.f. the rtl version, may_trap_p.
This routine expects only GIMPLE lhs or rhs input. */
bool
tree_could_trap_p (tree expr)
{
- enum tree_code code = TREE_CODE (expr);
- bool honor_nans = false;
- bool honor_snans = false;
+ enum tree_code code;
bool fp_operation = false;
bool honor_trapv = false;
- tree t, base;
+ tree t, base, div = NULL_TREE;
- if (TREE_CODE_CLASS (code) == tcc_comparison
- || TREE_CODE_CLASS (code) == tcc_unary
- || TREE_CODE_CLASS (code) == tcc_binary)
+ if (!expr)
+ return false;
+
+ code = TREE_CODE (expr);
+ t = TREE_TYPE (expr);
+
+ if (t)
{
- t = TREE_TYPE (expr);
if (COMPARISON_CLASS_P (expr))
fp_operation = FLOAT_TYPE_P (TREE_TYPE (TREE_OPERAND (expr, 0)));
else
fp_operation = FLOAT_TYPE_P (t);
- if (fp_operation)
- {
- honor_nans = flag_trapping_math && !flag_finite_math_only;
- honor_snans = flag_signaling_nans != 0;
- }
- else if (INTEGRAL_TYPE_P (t) && TYPE_OVERFLOW_TRAPS (t))
- honor_trapv = true;
+ honor_trapv = INTEGRAL_TYPE_P (t) && TYPE_OVERFLOW_TRAPS (t);
}
+ if (TREE_CODE_CLASS (code) == tcc_binary)
+ div = TREE_OPERAND (expr, 1);
+ if (operation_could_trap_p (code, fp_operation, honor_trapv, div))
+ return true;
+
restart:
switch (code)
{
@@ -1958,93 +2253,126 @@ tree_could_trap_p (tree expr)
case ASM_EXPR:
return TREE_THIS_VOLATILE (expr);
- case TRUNC_DIV_EXPR:
- case CEIL_DIV_EXPR:
- case FLOOR_DIV_EXPR:
- case ROUND_DIV_EXPR:
- case EXACT_DIV_EXPR:
- case CEIL_MOD_EXPR:
- case FLOOR_MOD_EXPR:
- case ROUND_MOD_EXPR:
- case TRUNC_MOD_EXPR:
- case RDIV_EXPR:
- if (honor_snans || honor_trapv)
+
+ case CALL_EXPR:
+ t = get_callee_fndecl (expr);
+ /* Assume that calls to weak functions may trap. */
+ if (!t || !DECL_P (t) || DECL_WEAK (t))
return true;
- if (fp_operation)
- return flag_trapping_math;
- t = TREE_OPERAND (expr, 1);
- if (!TREE_CONSTANT (t) || integer_zerop (t))
- return true;
return false;
- case LT_EXPR:
- case LE_EXPR:
- case GT_EXPR:
- case GE_EXPR:
- case LTGT_EXPR:
- /* Some floating point comparisons may trap. */
- return honor_nans;
+ default:
+ return false;
+ }
+}
- case EQ_EXPR:
- case NE_EXPR:
- case UNORDERED_EXPR:
- case ORDERED_EXPR:
- case UNLT_EXPR:
- case UNLE_EXPR:
- case UNGT_EXPR:
- case UNGE_EXPR:
- case UNEQ_EXPR:
- return honor_snans;
- case CONVERT_EXPR:
- case FIX_TRUNC_EXPR:
- /* Conversion of floating point might trap. */
- return honor_nans;
+/* Helper for stmt_could_throw_p. Return true if STMT (assumed to be a
+ an assignment or a conditional) may throw. */
- case NEGATE_EXPR:
- case ABS_EXPR:
- case CONJ_EXPR:
- /* These operations don't trap with floating point. */
- if (honor_trapv)
- return true;
- return false;
+static bool
+stmt_could_throw_1_p (gimple stmt)
+{
+ enum tree_code code = gimple_expr_code (stmt);
+ bool honor_nans = false;
+ bool honor_snans = false;
+ bool fp_operation = false;
+ bool honor_trapv = false;
+ tree t;
+ size_t i;
+ bool handled, ret;
- case PLUS_EXPR:
- case MINUS_EXPR:
- case MULT_EXPR:
- /* Any floating arithmetic may trap. */
- if (fp_operation && flag_trapping_math)
- return true;
- if (honor_trapv)
- return true;
- return false;
+ if (TREE_CODE_CLASS (code) == tcc_comparison
+ || TREE_CODE_CLASS (code) == tcc_unary
+ || TREE_CODE_CLASS (code) == tcc_binary)
+ {
+ t = gimple_expr_type (stmt);
+ fp_operation = FLOAT_TYPE_P (t);
+ if (fp_operation)
+ {
+ honor_nans = flag_trapping_math && !flag_finite_math_only;
+ honor_snans = flag_signaling_nans != 0;
+ }
+ else if (INTEGRAL_TYPE_P (t) && TYPE_OVERFLOW_TRAPS (t))
+ honor_trapv = true;
+ }
+
+ /* Check if the main expression may trap. */
+ t = is_gimple_assign (stmt) ? gimple_assign_rhs2 (stmt) : NULL;
+ ret = operation_could_trap_helper_p (code, fp_operation, honor_trapv,
+ honor_nans, honor_snans, t,
+ &handled);
+ if (handled)
+ return ret;
+
+ /* If the expression does not trap, see if any of the individual operands may
+ trap. */
+ for (i = 0; i < gimple_num_ops (stmt); i++)
+ if (tree_could_trap_p (gimple_op (stmt, i)))
+ return true;
+
+ return false;
+}
+
+
+/* Return true if statement STMT could throw an exception. */
+
+bool
+stmt_could_throw_p (gimple stmt)
+{
+ enum gimple_code code;
+
+ if (!flag_exceptions)
+ return false;
+
+ /* The only statements that can throw an exception are assignments,
+ conditionals, calls and asms. */
+ code = gimple_code (stmt);
+ if (code != GIMPLE_ASSIGN
+ && code != GIMPLE_COND
+ && code != GIMPLE_CALL
+ && code != GIMPLE_ASM)
+ return false;
+
+ /* If exceptions can only be thrown by function calls and STMT is not a
+ GIMPLE_CALL, the statement cannot throw. */
+ if (!flag_non_call_exceptions && code != GIMPLE_CALL)
+ return false;
+
+ if (code == GIMPLE_ASSIGN || code == GIMPLE_COND)
+ return stmt_could_throw_1_p (stmt);
+ else if (is_gimple_call (stmt))
+ {
+ tree t = gimple_call_fndecl (stmt);
- case CALL_EXPR:
- t = get_callee_fndecl (expr);
/* Assume that calls to weak functions may trap. */
if (!t || !DECL_P (t) || DECL_WEAK (t))
return true;
- return false;
- default:
- /* Any floating arithmetic may trap. */
- if (fp_operation && flag_trapping_math)
- return true;
- return false;
+ return (gimple_call_flags (stmt) & ECF_NOTHROW) == 0;
}
+ else if (gimple_code (stmt) == GIMPLE_ASM)
+ return (gimple_asm_volatile_p (stmt));
+ else
+ gcc_unreachable ();
+
+ return false;
}
+
+/* Return true if expression T could throw an exception. */
+
bool
tree_could_throw_p (tree t)
{
if (!flag_exceptions)
return false;
- if (TREE_CODE (t) == GIMPLE_MODIFY_STMT)
+ if (TREE_CODE (t) == MODIFY_EXPR)
{
if (flag_non_call_exceptions
- && tree_could_trap_p (GIMPLE_STMT_OPERAND (t, 0)))
+ && tree_could_trap_p (TREE_OPERAND (t, 0)))
return true;
- t = GIMPLE_STMT_OPERAND (t, 1);
+ t = TREE_OPERAND (t, 1);
}
if (TREE_CODE (t) == WITH_SIZE_EXPR)
@@ -2056,36 +2384,30 @@ tree_could_throw_p (tree t)
return false;
}
+
+/* Return true if STMT can throw an exception that is caught within
+ the current function (CFUN). */
+
bool
-tree_can_throw_internal (const_tree stmt)
+stmt_can_throw_internal (gimple stmt)
{
int region_nr;
bool is_resx = false;
- if (TREE_CODE (stmt) == RESX_EXPR)
- region_nr = TREE_INT_CST_LOW (TREE_OPERAND (stmt, 0)), is_resx = true;
+ if (gimple_code (stmt) == GIMPLE_RESX)
+ {
+ region_nr = gimple_resx_region (stmt);
+ is_resx = true;
+ }
else
region_nr = lookup_stmt_eh_region (stmt);
+
if (region_nr < 0)
return false;
+
return can_throw_internal_1 (region_nr, is_resx);
}
-bool
-tree_can_throw_external (tree stmt)
-{
- int region_nr;
- bool is_resx = false;
-
- if (TREE_CODE (stmt) == RESX_EXPR)
- region_nr = TREE_INT_CST_LOW (TREE_OPERAND (stmt, 0)), is_resx = true;
- else
- region_nr = lookup_stmt_eh_region (stmt);
- if (region_nr < 0)
- return tree_could_throw_p (stmt);
- else
- return can_throw_external_1 (region_nr, is_resx);
-}
/* Given a statement OLD_STMT and a new statement NEW_STMT that has replaced
OLD_STMT in the function, remove OLD_STMT from the EH table and put NEW_STMT
@@ -2093,13 +2415,13 @@ tree_can_throw_external (tree stmt)
done that my require an EH edge purge. */
bool
-maybe_clean_or_replace_eh_stmt (tree old_stmt, tree new_stmt)
+maybe_clean_or_replace_eh_stmt (gimple old_stmt, gimple new_stmt)
{
int region_nr = lookup_stmt_eh_region (old_stmt);
if (region_nr >= 0)
{
- bool new_stmt_could_throw = tree_could_throw_p (new_stmt);
+ bool new_stmt_could_throw = stmt_could_throw_p (new_stmt);
if (new_stmt == old_stmt && new_stmt_could_throw)
return false;
@@ -2117,38 +2439,42 @@ maybe_clean_or_replace_eh_stmt (tree old_stmt, tree new_stmt)
return false;
}
-/* Returns TRUE if oneh and twoh are exception handlers (op 1 of
- TRY_CATCH_EXPR or TRY_FINALLY_EXPR that are similar enough to be
- considered the same. Currently this only handles handlers consisting of
- a single call, as that's the important case for C++: a destructor call
- for a particular object showing up in multiple handlers. */
+/* Returns TRUE if oneh and twoh are exception handlers (gimple_try_cleanup of
+ GIMPLE_TRY) that are similar enough to be considered the same. Currently
+ this only handles handlers consisting of a single call, as that's the
+ important case for C++: a destructor call for a particular object showing
+ up in multiple handlers. */
static bool
-same_handler_p (tree oneh, tree twoh)
+same_handler_p (gimple_seq oneh, gimple_seq twoh)
{
- tree_stmt_iterator i;
- tree ones, twos;
- int ai;
+ gimple_stmt_iterator gsi;
+ gimple ones, twos;
+ unsigned int ai;
- i = tsi_start (oneh);
- if (!tsi_one_before_end_p (i))
+ gsi = gsi_start (oneh);
+ if (!gsi_one_before_end_p (gsi))
return false;
- ones = tsi_stmt (i);
+ ones = gsi_stmt (gsi);
- i = tsi_start (twoh);
- if (!tsi_one_before_end_p (i))
+ gsi = gsi_start (twoh);
+ if (!gsi_one_before_end_p (gsi))
return false;
- twos = tsi_stmt (i);
-
- if (TREE_CODE (ones) != CALL_EXPR
- || TREE_CODE (twos) != CALL_EXPR
- || !operand_equal_p (CALL_EXPR_FN (ones), CALL_EXPR_FN (twos), 0)
- || call_expr_nargs (ones) != call_expr_nargs (twos))
+ twos = gsi_stmt (gsi);
+
+ if (!is_gimple_call (ones)
+ || !is_gimple_call (twos)
+ || gimple_call_lhs (ones)
+ || gimple_call_lhs (twos)
+ || gimple_call_chain (ones)
+ || gimple_call_chain (twos)
+ || !operand_equal_p (gimple_call_fn (ones), gimple_call_fn (twos), 0)
+ || gimple_call_num_args (ones) != gimple_call_num_args (twos))
return false;
- for (ai = 0; ai < call_expr_nargs (ones); ++ai)
- if (!operand_equal_p (CALL_EXPR_ARG (ones, ai),
- CALL_EXPR_ARG (twos, ai), 0))
+ for (ai = 0; ai < gimple_call_num_args (ones); ++ai)
+ if (!operand_equal_p (gimple_call_arg (ones, ai),
+ gimple_call_arg (twos, ai), 0))
return false;
return true;
@@ -2165,27 +2491,29 @@ same_handler_p (tree oneh, tree twoh)
temporary used in the initializer for A. */
static void
-optimize_double_finally (tree one, tree two)
+optimize_double_finally (gimple one, gimple two)
{
- tree oneh;
- tree_stmt_iterator i;
+ gimple oneh;
+ gimple_stmt_iterator gsi;
- i = tsi_start (TREE_OPERAND (one, 1));
- if (!tsi_one_before_end_p (i))
+ gsi = gsi_start (gimple_try_cleanup (one));
+ if (!gsi_one_before_end_p (gsi))
return;
- oneh = tsi_stmt (i);
- if (TREE_CODE (oneh) != TRY_CATCH_EXPR)
+ oneh = gsi_stmt (gsi);
+ if (gimple_code (oneh) != GIMPLE_TRY
+ || gimple_try_kind (oneh) != GIMPLE_TRY_CATCH)
return;
- if (same_handler_p (TREE_OPERAND (oneh, 1), TREE_OPERAND (two, 1)))
+ if (same_handler_p (gimple_try_cleanup (oneh), gimple_try_cleanup (two)))
{
- tree b = TREE_OPERAND (oneh, 0);
- TREE_OPERAND (one, 1) = b;
- TREE_SET_CODE (one, TRY_CATCH_EXPR);
+ gimple_seq seq = gimple_try_eval (oneh);
- i = tsi_start (TREE_OPERAND (two, 0));
- tsi_link_before (&i, unsave_expr_now (b), TSI_SAME_STMT);
+ gimple_try_set_cleanup (one, seq);
+ gimple_try_set_kind (one, GIMPLE_TRY_CATCH);
+ seq = copy_gimple_seq_and_replace_locals (seq);
+ gimple_seq_add_seq (&seq, gimple_try_eval (two));
+ gimple_try_set_eval (two, seq);
}
}
@@ -2193,60 +2521,55 @@ optimize_double_finally (tree one, tree two)
flow has been lowered but EH structures haven't. */
static void
-refactor_eh_r (tree t)
+refactor_eh_r (gimple_seq seq)
{
- tailrecurse:
- switch (TREE_CODE (t))
- {
- case TRY_FINALLY_EXPR:
- case TRY_CATCH_EXPR:
- refactor_eh_r (TREE_OPERAND (t, 0));
- t = TREE_OPERAND (t, 1);
- goto tailrecurse;
+ gimple_stmt_iterator gsi;
+ gimple one, two;
- case CATCH_EXPR:
- t = CATCH_BODY (t);
- goto tailrecurse;
-
- case EH_FILTER_EXPR:
- t = EH_FILTER_FAILURE (t);
- goto tailrecurse;
-
- case STATEMENT_LIST:
- {
- tree_stmt_iterator i;
- tree one = NULL_TREE, two = NULL_TREE;
- /* Try to refactor double try/finally. */
- for (i = tsi_start (t); !tsi_end_p (i); tsi_next (&i))
- {
- one = two;
- two = tsi_stmt (i);
- if (one && two
- && TREE_CODE (one) == TRY_FINALLY_EXPR
- && TREE_CODE (two) == TRY_FINALLY_EXPR)
- optimize_double_finally (one, two);
- if (one)
- refactor_eh_r (one);
- }
- if (two)
+ one = NULL;
+ two = NULL;
+ gsi = gsi_start (seq);
+ while (1)
+ {
+ one = two;
+ if (gsi_end_p (gsi))
+ two = NULL;
+ else
+ two = gsi_stmt (gsi);
+ if (one
+ && two
+ && gimple_code (one) == GIMPLE_TRY
+ && gimple_code (two) == GIMPLE_TRY
+ && gimple_try_kind (one) == GIMPLE_TRY_FINALLY
+ && gimple_try_kind (two) == GIMPLE_TRY_FINALLY)
+ optimize_double_finally (one, two);
+ if (one)
+ switch (gimple_code (one))
{
- t = two;
- goto tailrecurse;
+ case GIMPLE_TRY:
+ refactor_eh_r (gimple_try_eval (one));
+ refactor_eh_r (gimple_try_cleanup (one));
+ break;
+ case GIMPLE_CATCH:
+ refactor_eh_r (gimple_catch_handler (one));
+ break;
+ case GIMPLE_EH_FILTER:
+ refactor_eh_r (gimple_eh_filter_failure (one));
+ break;
+ default:
+ break;
}
- }
- break;
-
- default:
- /* A type, a decl, or some kind of statement that we're not
- interested in. Don't walk them. */
- break;
+ if (two)
+ gsi_next (&gsi);
+ else
+ break;
}
}
static unsigned
refactor_eh (void)
{
- refactor_eh_r (DECL_SAVED_TREE (current_function_decl));
+ refactor_eh_r (gimple_body (current_function_decl));
return 0;
}
diff --git a/gcc/tree-flow-inline.h b/gcc/tree-flow-inline.h
index bff697db5ae..eefc983190e 100644
--- a/gcc/tree-flow-inline.h
+++ b/gcc/tree-flow-inline.h
@@ -235,52 +235,6 @@ get_function_ann (tree var)
return (ann) ? ann : create_function_ann (var);
}
-/* Return true if T has a statement annotation attached to it. */
-
-static inline bool
-has_stmt_ann (tree t)
-{
-#ifdef ENABLE_CHECKING
- gcc_assert (is_gimple_stmt (t));
-#endif
- return t->base.ann && t->base.ann->common.type == STMT_ANN;
-}
-
-/* Return the statement annotation for T, which must be a statement
- node. Return NULL if the statement annotation doesn't exist. */
-static inline stmt_ann_t
-stmt_ann (tree t)
-{
-#ifdef ENABLE_CHECKING
- gcc_assert (is_gimple_stmt (t));
-#endif
- gcc_assert (!t->base.ann || t->base.ann->common.type == STMT_ANN);
- return (stmt_ann_t) t->base.ann;
-}
-
-/* Return the statement annotation for T, which must be a statement
- node. Create the statement annotation if it doesn't exist. */
-static inline stmt_ann_t
-get_stmt_ann (tree stmt)
-{
- stmt_ann_t ann = stmt_ann (stmt);
- return (ann) ? ann : create_stmt_ann (stmt);
-}
-
-/* Set the uid of all non phi function statements. */
-static inline void
-set_gimple_stmt_uid (tree stmt, unsigned int uid)
-{
- get_stmt_ann (stmt)->uid = uid;
-}
-
-/* Get the uid of all non phi function statements. */
-static inline unsigned int
-gimple_stmt_uid (tree stmt)
-{
- return get_stmt_ann (stmt)->uid;
-}
-
/* Get the number of the next statement uid to be allocated. */
static inline unsigned int
gimple_stmt_max_uid (struct function *fn)
@@ -309,19 +263,6 @@ ann_type (tree_ann_t ann)
return ann->common.type;
}
-/* Return the basic block for statement T. */
-static inline basic_block
-bb_for_stmt (tree t)
-{
- stmt_ann_t ann;
-
- if (TREE_CODE (t) == PHI_NODE)
- return PHI_BB (t);
-
- ann = stmt_ann (t);
- return ann ? ann->bb : NULL;
-}
-
/* Return the may_aliases bitmap for variable VAR, or NULL if it has
no may aliases. */
static inline bitmap
@@ -333,71 +274,18 @@ may_aliases (const_tree var)
/* Return the line number for EXPR, or return -1 if we have no line
number information for it. */
static inline int
-get_lineno (const_tree expr)
+get_lineno (const_gimple stmt)
{
- if (expr == NULL_TREE)
- return -1;
-
- if (TREE_CODE (expr) == COMPOUND_EXPR)
- expr = TREE_OPERAND (expr, 0);
+ location_t loc;
- if (! EXPR_HAS_LOCATION (expr))
+ if (!stmt)
return -1;
- return EXPR_LINENO (expr);
-}
-
-/* Return true if T is a noreturn call. */
-static inline bool
-noreturn_call_p (tree t)
-{
- tree call = get_call_expr_in (t);
- return call != 0 && (call_expr_flags (call) & ECF_NORETURN) != 0;
-}
-
-/* Mark statement T as modified. */
-static inline void
-mark_stmt_modified (tree t)
-{
- stmt_ann_t ann;
- if (TREE_CODE (t) == PHI_NODE)
- return;
-
- ann = stmt_ann (t);
- if (ann == NULL)
- ann = create_stmt_ann (t);
- else if (noreturn_call_p (t) && cfun->gimple_df)
- VEC_safe_push (tree, gc, MODIFIED_NORETURN_CALLS (cfun), t);
- ann->modified = 1;
-}
-
-/* Mark statement T as modified, and update it. */
-static inline void
-update_stmt (tree t)
-{
- if (TREE_CODE (t) == PHI_NODE)
- return;
- mark_stmt_modified (t);
- update_stmt_operands (t);
-}
-
-static inline void
-update_stmt_if_modified (tree t)
-{
- if (stmt_modified_p (t))
- update_stmt_operands (t);
-}
-
-/* Return true if T is marked as modified, false otherwise. */
-static inline bool
-stmt_modified_p (tree t)
-{
- stmt_ann_t ann = stmt_ann (t);
+ loc = gimple_location (stmt);
+ if (loc != UNKNOWN_LOCATION)
+ return -1;
- /* Note that if the statement doesn't yet have an annotation, we consider it
- modified. This will force the next call to update_stmt_operands to scan
- the statement. */
- return ann ? ann->modified : true;
+ return LOCATION_LINE (loc);
}
/* Delink an immediate_uses node from its chain. */
@@ -457,13 +345,13 @@ set_ssa_use_from_ptr (use_operand_p use, tree val)
/* Link ssa_imm_use node LINKNODE into the chain for DEF, with use occurring
in STMT. */
static inline void
-link_imm_use_stmt (ssa_use_operand_t *linknode, tree def, tree stmt)
+link_imm_use_stmt (ssa_use_operand_t *linknode, tree def, gimple stmt)
{
if (stmt)
link_imm_use (linknode, def);
else
link_imm_use (linknode, NULL);
- linknode->stmt = stmt;
+ linknode->loc.stmt = stmt;
}
/* Relink a new node in place of an old node in the list. */
@@ -486,13 +374,14 @@ relink_imm_use (ssa_use_operand_t *node, ssa_use_operand_t *old)
/* Relink ssa_imm_use node LINKNODE into the chain for OLD, with use occurring
in STMT. */
static inline void
-relink_imm_use_stmt (ssa_use_operand_t *linknode, ssa_use_operand_t *old, tree stmt)
+relink_imm_use_stmt (ssa_use_operand_t *linknode, ssa_use_operand_t *old,
+ gimple stmt)
{
if (stmt)
relink_imm_use (linknode, old);
else
link_imm_use (linknode, NULL);
- linknode->stmt = stmt;
+ linknode->loc.stmt = stmt;
}
@@ -562,17 +451,17 @@ has_single_use (const_tree var)
/* If VAR has only a single immediate use, return true, and set USE_P and STMT
to the use pointer and stmt of occurrence. */
static inline bool
-single_imm_use (const_tree var, use_operand_p *use_p, tree *stmt)
+single_imm_use (const_tree var, use_operand_p *use_p, gimple *stmt)
{
const ssa_use_operand_t *const ptr = &(SSA_NAME_IMM_USE_NODE (var));
if (ptr != ptr->next && ptr == ptr->next->next)
{
*use_p = ptr->next;
- *stmt = ptr->next->stmt;
+ *stmt = ptr->next->loc.stmt;
return true;
}
*use_p = NULL_USE_OPERAND_P;
- *stmt = NULL_TREE;
+ *stmt = NULL;
return false;
}
@@ -590,75 +479,76 @@ num_imm_uses (const_tree var)
return num;
}
-/* Return the tree pointer to by USE. */
+/* Return the tree pointed-to by USE. */
static inline tree
get_use_from_ptr (use_operand_p use)
{
return *(use->use);
}
-/* Return the tree pointer to by DEF. */
+/* Return the tree pointed-to by DEF. */
static inline tree
get_def_from_ptr (def_operand_p def)
{
return *def;
}
-/* Return a def_operand_p pointer for the result of PHI. */
-static inline def_operand_p
-get_phi_result_ptr (tree phi)
+/* Return a use_operand_p pointer for argument I of PHI node GS. */
+
+static inline use_operand_p
+gimple_phi_arg_imm_use_ptr (gimple gs, int i)
{
- return &(PHI_RESULT_TREE (phi));
+ return &gimple_phi_arg (gs, i)->imm_use;
}
-/* Return a use_operand_p pointer for argument I of phinode PHI. */
-static inline use_operand_p
-get_phi_arg_def_ptr (tree phi, int i)
+/* Return the tree operand for argument I of PHI node GS. */
+
+static inline tree
+gimple_phi_arg_def (gimple gs, size_t index)
{
- return &(PHI_ARG_IMM_USE_NODE (phi,i));
+ struct phi_arg_d *pd = gimple_phi_arg (gs, index);
+ return get_use_from_ptr (&pd->imm_use);
}
+/* Return a pointer to the tree operand for argument I of PHI node GS. */
-/* Return the bitmap of addresses taken by STMT, or NULL if it takes
- no addresses. */
-static inline bitmap
-addresses_taken (tree stmt)
+static inline tree *
+gimple_phi_arg_def_ptr (gimple gs, size_t index)
+{
+ return &gimple_phi_arg (gs, index)->def;
+}
+
+/* Return the edge associated with argument I of phi node GS. */
+
+static inline edge
+gimple_phi_arg_edge (gimple gs, size_t i)
{
- stmt_ann_t ann = stmt_ann (stmt);
- return ann ? ann->addresses_taken : NULL;
+ return EDGE_PRED (gimple_bb (gs), i);
}
/* Return the PHI nodes for basic block BB, or NULL if there are no
PHI nodes. */
-static inline tree
+static inline gimple_seq
phi_nodes (const_basic_block bb)
{
gcc_assert (!(bb->flags & BB_RTL));
- if (!bb->il.tree)
+ if (!bb->il.gimple)
return NULL;
- return bb->il.tree->phi_nodes;
+ return bb->il.gimple->phi_nodes;
}
-/* Return pointer to the list of PHI nodes for basic block BB. */
-
-static inline tree *
-phi_nodes_ptr (basic_block bb)
-{
- gcc_assert (!(bb->flags & BB_RTL));
- return &bb->il.tree->phi_nodes;
-}
-
-/* Set list of phi nodes of a basic block BB to L. */
+/* Set PHI nodes of a basic block BB to SEQ. */
static inline void
-set_phi_nodes (basic_block bb, tree l)
+set_phi_nodes (basic_block bb, gimple_seq seq)
{
- tree phi;
+ gimple_stmt_iterator i;
gcc_assert (!(bb->flags & BB_RTL));
- bb->il.tree->phi_nodes = l;
- for (phi = l; phi; phi = PHI_CHAIN (phi))
- set_bb_for_stmt (phi, bb);
+ bb->il.gimple->phi_nodes = seq;
+ if (seq)
+ for (i = gsi_start (seq); !gsi_end_p (i); gsi_next (&i))
+ gimple_set_bb (gsi_stmt (i), bb);
}
/* Return the phi argument which contains the specified use. */
@@ -667,18 +557,18 @@ static inline int
phi_arg_index_from_use (use_operand_p use)
{
struct phi_arg_d *element, *root;
- int index;
- tree phi;
+ size_t index;
+ gimple phi;
/* Since the use is the first thing in a PHI argument element, we can
calculate its index based on casting it to an argument, and performing
pointer arithmetic. */
phi = USE_STMT (use);
- gcc_assert (TREE_CODE (phi) == PHI_NODE);
+ gcc_assert (gimple_code (phi) == GIMPLE_PHI);
element = (struct phi_arg_d *)use;
- root = &(PHI_ARG_ELT (phi, 0));
+ root = gimple_phi_arg (phi, 0);
index = element - root;
#ifdef ENABLE_CHECKING
@@ -686,7 +576,7 @@ phi_arg_index_from_use (use_operand_p use)
then imm_use is likely not the first element in phi_arg_d. */
gcc_assert (
(((char *)element - (char *)root) % sizeof (struct phi_arg_d)) == 0);
- gcc_assert (index >= 0 && index < PHI_ARG_CAPACITY (phi));
+ gcc_assert (index < gimple_phi_capacity (phi));
#endif
return index;
@@ -728,121 +618,13 @@ phi_ssa_name_p (const_tree t)
return false;
}
-/* ----------------------------------------------------------------------- */
-
-/* Returns the list of statements in BB. */
-
-static inline tree
-bb_stmt_list (const_basic_block bb)
-{
- gcc_assert (!(bb->flags & BB_RTL));
- return bb->il.tree->stmt_list;
-}
-
-/* Sets the list of statements in BB to LIST. */
-
-static inline void
-set_bb_stmt_list (basic_block bb, tree list)
-{
- gcc_assert (!(bb->flags & BB_RTL));
- bb->il.tree->stmt_list = list;
-}
-
-/* Return a block_stmt_iterator that points to beginning of basic
- block BB. */
-static inline block_stmt_iterator
-bsi_start (basic_block bb)
-{
- block_stmt_iterator bsi;
- if (bb->index < NUM_FIXED_BLOCKS)
- {
- bsi.tsi.ptr = NULL;
- bsi.tsi.container = NULL;
- }
- else
- bsi.tsi = tsi_start (bb_stmt_list (bb));
- bsi.bb = bb;
- return bsi;
-}
-
-/* Return a block statement iterator that points to the first non-label
- statement in block BB. */
-
-static inline block_stmt_iterator
-bsi_after_labels (basic_block bb)
-{
- block_stmt_iterator bsi = bsi_start (bb);
-
- while (!bsi_end_p (bsi) && TREE_CODE (bsi_stmt (bsi)) == LABEL_EXPR)
- bsi_next (&bsi);
-
- return bsi;
-}
-
-/* Return a block statement iterator that points to the end of basic
- block BB. */
-static inline block_stmt_iterator
-bsi_last (basic_block bb)
-{
- block_stmt_iterator bsi;
-
- if (bb->index < NUM_FIXED_BLOCKS)
- {
- bsi.tsi.ptr = NULL;
- bsi.tsi.container = NULL;
- }
- else
- bsi.tsi = tsi_last (bb_stmt_list (bb));
- bsi.bb = bb;
- return bsi;
-}
-
-/* Return true if block statement iterator I has reached the end of
- the basic block. */
-static inline bool
-bsi_end_p (block_stmt_iterator i)
-{
- return tsi_end_p (i.tsi);
-}
-
-/* Modify block statement iterator I so that it is at the next
- statement in the basic block. */
-static inline void
-bsi_next (block_stmt_iterator *i)
-{
- tsi_next (&i->tsi);
-}
-
-/* Modify block statement iterator I so that it is at the previous
- statement in the basic block. */
-static inline void
-bsi_prev (block_stmt_iterator *i)
-{
- tsi_prev (&i->tsi);
-}
-
-/* Return the statement that block statement iterator I is currently
- at. */
-static inline tree
-bsi_stmt (block_stmt_iterator i)
-{
- return tsi_stmt (i.tsi);
-}
-
-/* Return a pointer to the statement that block statement iterator I
- is currently at. */
-static inline tree *
-bsi_stmt_ptr (block_stmt_iterator i)
-{
- return tsi_stmt_ptr (i.tsi);
-}
/* Returns the loop of the statement STMT. */
static inline struct loop *
-loop_containing_stmt (tree stmt)
+loop_containing_stmt (gimple stmt)
{
- basic_block bb = bb_for_stmt (stmt);
+ basic_block bb = gimple_bb (stmt);
if (!bb)
return NULL;
@@ -881,7 +663,15 @@ factoring_name_p (const_tree name)
return TREE_CODE (SSA_NAME_VAR (name)) == MEMORY_PARTITION_TAG;
}
-/* Return true if VAR is a clobbered by function calls. */
+/* Return true if VAR is used by function calls. */
+static inline bool
+is_call_used (const_tree var)
+{
+ return (var_ann (var)->call_clobbered
+ || bitmap_bit_p (gimple_call_used_vars (cfun), DECL_UID (var)));
+}
+
+/* Return true if VAR is clobbered by function calls. */
static inline bool
is_call_clobbered (const_tree var)
{
@@ -1075,7 +865,7 @@ clear_and_done_ssa_iter (ssa_op_iter *ptr)
ptr->iter_type = ssa_op_iter_none;
ptr->phi_i = 0;
ptr->num_phi = 0;
- ptr->phi_stmt = NULL_TREE;
+ ptr->phi_stmt = NULL;
ptr->done = true;
ptr->vuse_index = 0;
ptr->mayuse_index = 0;
@@ -1083,22 +873,18 @@ clear_and_done_ssa_iter (ssa_op_iter *ptr)
/* Initialize the iterator PTR to the virtual defs in STMT. */
static inline void
-op_iter_init (ssa_op_iter *ptr, tree stmt, int flags)
+op_iter_init (ssa_op_iter *ptr, gimple stmt, int flags)
{
-#ifdef ENABLE_CHECKING
- gcc_assert (stmt_ann (stmt));
-#endif
-
- ptr->defs = (flags & SSA_OP_DEF) ? DEF_OPS (stmt) : NULL;
- ptr->uses = (flags & SSA_OP_USE) ? USE_OPS (stmt) : NULL;
- ptr->vuses = (flags & SSA_OP_VUSE) ? VUSE_OPS (stmt) : NULL;
- ptr->vdefs = (flags & SSA_OP_VDEF) ? VDEF_OPS (stmt) : NULL;
- ptr->mayuses = (flags & SSA_OP_VMAYUSE) ? VDEF_OPS (stmt) : NULL;
+ ptr->defs = (flags & SSA_OP_DEF) ? gimple_def_ops (stmt) : NULL;
+ ptr->uses = (flags & SSA_OP_USE) ? gimple_use_ops (stmt) : NULL;
+ ptr->vuses = (flags & SSA_OP_VUSE) ? gimple_vuse_ops (stmt) : NULL;
+ ptr->vdefs = (flags & SSA_OP_VDEF) ? gimple_vdef_ops (stmt) : NULL;
+ ptr->mayuses = (flags & SSA_OP_VMAYUSE) ? gimple_vdef_ops (stmt) : NULL;
ptr->done = false;
ptr->phi_i = 0;
ptr->num_phi = 0;
- ptr->phi_stmt = NULL_TREE;
+ ptr->phi_stmt = NULL;
ptr->vuse_index = 0;
ptr->mayuse_index = 0;
}
@@ -1106,7 +892,7 @@ op_iter_init (ssa_op_iter *ptr, tree stmt, int flags)
/* Initialize iterator PTR to the use operands in STMT based on FLAGS. Return
the first use. */
static inline use_operand_p
-op_iter_init_use (ssa_op_iter *ptr, tree stmt, int flags)
+op_iter_init_use (ssa_op_iter *ptr, gimple stmt, int flags)
{
gcc_assert ((flags & SSA_OP_ALL_DEFS) == 0);
op_iter_init (ptr, stmt, flags);
@@ -1117,7 +903,7 @@ op_iter_init_use (ssa_op_iter *ptr, tree stmt, int flags)
/* Initialize iterator PTR to the def operands in STMT based on FLAGS. Return
the first def. */
static inline def_operand_p
-op_iter_init_def (ssa_op_iter *ptr, tree stmt, int flags)
+op_iter_init_def (ssa_op_iter *ptr, gimple stmt, int flags)
{
gcc_assert ((flags & SSA_OP_ALL_USES) == 0);
op_iter_init (ptr, stmt, flags);
@@ -1128,7 +914,7 @@ op_iter_init_def (ssa_op_iter *ptr, tree stmt, int flags)
/* Initialize iterator PTR to the operands in STMT based on FLAGS. Return
the first operand as a tree. */
static inline tree
-op_iter_init_tree (ssa_op_iter *ptr, tree stmt, int flags)
+op_iter_init_tree (ssa_op_iter *ptr, gimple stmt, int flags)
{
op_iter_init (ptr, stmt, flags);
ptr->iter_type = ssa_op_iter_tree;
@@ -1177,10 +963,10 @@ op_iter_next_mustdef (use_operand_p *use, def_operand_p *def,
/* Initialize iterator PTR to the operands in STMT. Return the first operands
in USE and DEF. */
static inline void
-op_iter_init_vdef (ssa_op_iter *ptr, tree stmt, vuse_vec_p *use,
+op_iter_init_vdef (ssa_op_iter *ptr, gimple stmt, vuse_vec_p *use,
def_operand_p *def)
{
- gcc_assert (TREE_CODE (stmt) != PHI_NODE);
+ gcc_assert (gimple_code (stmt) != GIMPLE_PHI);
op_iter_init (ptr, stmt, SSA_OP_VMAYUSE);
ptr->iter_type = ssa_op_iter_vdef;
@@ -1191,7 +977,7 @@ op_iter_init_vdef (ssa_op_iter *ptr, tree stmt, vuse_vec_p *use,
/* If there is a single operand in STMT matching FLAGS, return it. Otherwise
return NULL. */
static inline tree
-single_ssa_tree_operand (tree stmt, int flags)
+single_ssa_tree_operand (gimple stmt, int flags)
{
tree var;
ssa_op_iter iter;
@@ -1209,7 +995,7 @@ single_ssa_tree_operand (tree stmt, int flags)
/* If there is a single operand in STMT matching FLAGS, return it. Otherwise
return NULL. */
static inline use_operand_p
-single_ssa_use_operand (tree stmt, int flags)
+single_ssa_use_operand (gimple stmt, int flags)
{
use_operand_p var;
ssa_op_iter iter;
@@ -1228,7 +1014,7 @@ single_ssa_use_operand (tree stmt, int flags)
/* If there is a single operand in STMT matching FLAGS, return it. Otherwise
return NULL. */
static inline def_operand_p
-single_ssa_def_operand (tree stmt, int flags)
+single_ssa_def_operand (gimple stmt, int flags)
{
def_operand_p var;
ssa_op_iter iter;
@@ -1246,7 +1032,7 @@ single_ssa_def_operand (tree stmt, int flags)
/* Return true if there are zero operands in STMT matching the type
given in FLAGS. */
static inline bool
-zero_ssa_operands (tree stmt, int flags)
+zero_ssa_operands (gimple stmt, int flags)
{
ssa_op_iter iter;
@@ -1257,7 +1043,7 @@ zero_ssa_operands (tree stmt, int flags)
/* Return the number of operands matching FLAGS in STMT. */
static inline int
-num_ssa_operands (tree stmt, int flags)
+num_ssa_operands (gimple stmt, int flags)
{
ssa_op_iter iter;
tree t;
@@ -1271,7 +1057,7 @@ num_ssa_operands (tree stmt, int flags)
/* Delink all immediate_use information for STMT. */
static inline void
-delink_stmt_imm_use (tree stmt)
+delink_stmt_imm_use (gimple stmt)
{
ssa_op_iter iter;
use_operand_p use_p;
@@ -1285,7 +1071,7 @@ delink_stmt_imm_use (tree stmt)
/* This routine will compare all the operands matching FLAGS in STMT1 to those
in STMT2. TRUE is returned if they are the same. STMTs can be NULL. */
static inline bool
-compare_ssa_operands_equal (tree stmt1, tree stmt2, int flags)
+compare_ssa_operands_equal (gimple stmt1, gimple stmt2, int flags)
{
ssa_op_iter iter1, iter2;
tree op1 = NULL_TREE;
@@ -1295,8 +1081,8 @@ compare_ssa_operands_equal (tree stmt1, tree stmt2, int flags)
if (stmt1 == stmt2)
return true;
- look1 = stmt1 && stmt_ann (stmt1);
- look2 = stmt2 && stmt_ann (stmt2);
+ look1 = stmt1 != NULL;
+ look2 = stmt2 != NULL;
if (look1)
{
@@ -1331,7 +1117,7 @@ compare_ssa_operands_equal (tree stmt1, tree stmt2, int flags)
/* If there is a single DEF in the PHI node which matches FLAG, return it.
Otherwise return NULL_DEF_OPERAND_P. */
static inline tree
-single_phi_def (tree stmt, int flags)
+single_phi_def (gimple stmt, int flags)
{
tree def = PHI_RESULT (stmt);
if ((flags & SSA_OP_DEF) && is_gimple_reg (def))
@@ -1344,9 +1130,9 @@ single_phi_def (tree stmt, int flags)
/* Initialize the iterator PTR for uses matching FLAGS in PHI. FLAGS should
be either SSA_OP_USES or SSA_OP_VIRTUAL_USES. */
static inline use_operand_p
-op_iter_init_phiuse (ssa_op_iter *ptr, tree phi, int flags)
+op_iter_init_phiuse (ssa_op_iter *ptr, gimple phi, int flags)
{
- tree phi_def = PHI_RESULT (phi);
+ tree phi_def = gimple_phi_result (phi);
int comp;
clear_and_done_ssa_iter (ptr);
@@ -1364,7 +1150,7 @@ op_iter_init_phiuse (ssa_op_iter *ptr, tree phi, int flags)
}
ptr->phi_stmt = phi;
- ptr->num_phi = PHI_NUM_ARGS (phi);
+ ptr->num_phi = gimple_phi_num_args (phi);
ptr->iter_type = ssa_op_iter_use;
return op_iter_next_use (ptr);
}
@@ -1373,7 +1159,7 @@ op_iter_init_phiuse (ssa_op_iter *ptr, tree phi, int flags)
/* Start an iterator for a PHI definition. */
static inline def_operand_p
-op_iter_init_phidef (ssa_op_iter *ptr, tree phi, int flags)
+op_iter_init_phidef (ssa_op_iter *ptr, gimple phi, int flags)
{
tree phi_def = PHI_RESULT (phi);
int comp;
@@ -1453,7 +1239,7 @@ link_use_stmts_after (use_operand_p head, imm_use_iterator *imm)
{
use_operand_p use_p;
use_operand_p last_p = head;
- tree head_stmt = USE_STMT (head);
+ gimple head_stmt = USE_STMT (head);
tree use = USE_FROM_PTR (head);
ssa_op_iter op_iter;
int flag;
@@ -1461,7 +1247,7 @@ link_use_stmts_after (use_operand_p head, imm_use_iterator *imm)
/* Only look at virtual or real uses, depending on the type of HEAD. */
flag = (is_gimple_reg (use) ? SSA_OP_USE : SSA_OP_VIRTUAL_USES);
- if (TREE_CODE (head_stmt) == PHI_NODE)
+ if (gimple_code (head_stmt) == GIMPLE_PHI)
{
FOR_EACH_PHI_ARG (use_p, head_stmt, op_iter, flag)
if (USE_FROM_PTR (use_p) == use)
@@ -1480,7 +1266,7 @@ link_use_stmts_after (use_operand_p head, imm_use_iterator *imm)
}
/* Initialize IMM to traverse over uses of VAR. Return the first statement. */
-static inline tree
+static inline gimple
first_imm_use_stmt (imm_use_iterator *imm, tree var)
{
gcc_assert (TREE_CODE (var) == SSA_NAME);
@@ -1494,11 +1280,11 @@ first_imm_use_stmt (imm_use_iterator *imm, tree var)
stmt and use, which indicates a marker node. */
imm->iter_node.prev = NULL_USE_OPERAND_P;
imm->iter_node.next = NULL_USE_OPERAND_P;
- imm->iter_node.stmt = NULL_TREE;
+ imm->iter_node.loc.stmt = NULL;
imm->iter_node.use = NULL_USE_OPERAND_P;
if (end_imm_use_stmt_p (imm))
- return NULL_TREE;
+ return NULL;
link_use_stmts_after (imm->imm_use, imm);
@@ -1507,7 +1293,7 @@ first_imm_use_stmt (imm_use_iterator *imm, tree var)
/* Bump IMM to the next stmt which has a use of var. */
-static inline tree
+static inline gimple
next_imm_use_stmt (imm_use_iterator *imm)
{
imm->imm_use = imm->iter_node.next;
@@ -1515,7 +1301,7 @@ next_imm_use_stmt (imm_use_iterator *imm)
{
if (imm->iter_node.prev != NULL)
delink_imm_use (&imm->iter_node);
- return NULL_TREE;
+ return NULL;
}
link_use_stmts_after (imm->imm_use, imm);
@@ -1651,34 +1437,6 @@ set_symbol_mem_tag (tree sym, tree tag)
get_var_ann (sym)->symbol_mem_tag = tag;
}
-/* Get the value handle of EXPR. This is the only correct way to get
- the value handle for a "thing". If EXPR does not have a value
- handle associated, it returns NULL_TREE.
- NB: If EXPR is min_invariant, this function is *required* to return
- EXPR. */
-
-static inline tree
-get_value_handle (tree expr)
-{
- if (TREE_CODE (expr) == SSA_NAME)
- return SSA_NAME_VALUE (expr);
- else if (DECL_P (expr) || TREE_CODE (expr) == TREE_LIST
- || TREE_CODE (expr) == CONSTRUCTOR)
- {
- tree_ann_common_t ann = tree_common_ann (expr);
- return ((ann) ? ann->value_handle : NULL_TREE);
- }
- else if (is_gimple_min_invariant (expr))
- return expr;
- else if (EXPR_P (expr))
- {
- tree_ann_common_t ann = tree_common_ann (expr);
- return ((ann) ? ann->value_handle : NULL_TREE);
- }
- else
- gcc_unreachable ();
-}
-
/* Accessor to tree-ssa-operands.c caches. */
static inline struct ssa_operands *
gimple_ssa_operands (const struct function *fun)
@@ -1714,7 +1472,7 @@ redirect_edge_var_map_result (edge_var_map *v)
in function cfun. */
static inline tree
-make_ssa_name (tree var, tree stmt)
+make_ssa_name (tree var, gimple stmt)
{
return make_ssa_name_fn (cfun, var, stmt);
}
diff --git a/gcc/tree-flow.h b/gcc/tree-flow.h
index 5479c3342c7..96c4795fef0 100644
--- a/gcc/tree-flow.h
+++ b/gcc/tree-flow.h
@@ -26,7 +26,7 @@ along with GCC; see the file COPYING3. If not see
#include "hard-reg-set.h"
#include "basic-block.h"
#include "hashtab.h"
-#include "tree-gimple.h"
+#include "gimple.h"
#include "tree-ssa-operands.h"
#include "cgraph.h"
#include "ipa-reference.h"
@@ -141,12 +141,12 @@ struct gimple_df GTY(())
/* Array of all variables referenced in the function. */
htab_t GTY((param_is (union tree_node))) referenced_vars;
- /* A list of all the noreturn calls passed to modify_stmt.
+ /* A vector of all the noreturn calls passed to modify_stmt.
cleanup_control_flow uses it to detect cases where a mid-block
indirect call has been turned into a noreturn call. When this
happens, all the instructions after the call are no longer
reachable and must be deleted as dead. */
- VEC(tree,gc) *modified_noreturn_calls;
+ VEC(gimple,gc) *modified_noreturn_calls;
/* Array of all SSA_NAMEs used in the function. */
VEC(tree,gc) *ssa_names;
@@ -268,19 +268,27 @@ struct ptr_info_def GTY(())
/*---------------------------------------------------------------------------
Tree annotations stored in tree_base.ann
---------------------------------------------------------------------------*/
-enum tree_ann_type { TREE_ANN_COMMON, VAR_ANN, FUNCTION_ANN, STMT_ANN };
+enum tree_ann_type { TREE_ANN_COMMON, VAR_ANN, FUNCTION_ANN };
struct tree_ann_common_d GTY(())
{
/* Annotation type. */
enum tree_ann_type type;
- /* Auxiliary info specific to a pass. At all times, this
- should either point to valid data or be NULL. */
+ /* Record EH region number into a statement tree created during RTL
+ expansion (see gimple_to_tree). */
+ int rn;
+
+ /* Auxiliary info specific to a pass. At all times, this
+ should either point to valid data or be NULL. */
PTR GTY ((skip (""))) aux;
/* The value handle for this expression. Used by GVN-PRE. */
tree GTY((skip)) value_handle;
+
+ /* Pointer to original GIMPLE statement. Used during RTL expansion
+ (see gimple_to_tree). */
+ gimple stmt;
};
/* It is advantageous to avoid things like life analysis for variables which
@@ -417,6 +425,42 @@ struct function_ann_d GTY(())
ipa_reference_vars_info_t GTY ((skip)) reference_vars_info;
};
+
+/* Immediate use lists are used to directly access all uses for an SSA
+ name and get pointers to the statement for each use.
+
+ The structure ssa_use_operand_d consists of PREV and NEXT pointers
+ to maintain the list. A USE pointer, which points to address where
+ the use is located and a LOC pointer which can point to the
+ statement where the use is located, or, in the case of the root
+ node, it points to the SSA name itself.
+
+ The list is anchored by an occurrence of ssa_operand_d *in* the
+ ssa_name node itself (named 'imm_uses'). This node is uniquely
+ identified by having a NULL USE pointer. and the LOC pointer
+ pointing back to the ssa_name node itself. This node forms the
+ base for a circular list, and initially this is the only node in
+ the list.
+
+ Fast iteration allows each use to be examined, but does not allow
+ any modifications to the uses or stmts.
+
+ Normal iteration allows insertion, deletion, and modification. the
+ iterator manages this by inserting a marker node into the list
+ immediately before the node currently being examined in the list.
+ this marker node is uniquely identified by having null stmt *and* a
+ null use pointer.
+
+ When iterating to the next use, the iteration routines check to see
+ if the node after the marker has changed. if it has, then the node
+ following the marker is now the next one to be visited. if not, the
+ marker node is moved past that node in the list (visualize it as
+ bumping the marker node through the list). this continues until
+ the marker node is moved to the original anchor position. the
+ marker node is then removed from the list.
+
+ If iteration is halted early, the marker node must be removed from
+ the list before continuing. */
typedef struct immediate_use_iterator_d
{
/* This is the current use the iterator is processing. */
@@ -476,50 +520,16 @@ typedef struct immediate_use_iterator_d
-struct stmt_ann_d GTY(())
-{
- struct tree_ann_common_d common;
-
- /* Basic block that contains this statement. */
- basic_block bb;
-
- /* Operand cache for stmt. */
- struct stmt_operands_d GTY ((skip (""))) operands;
-
- /* Set of variables that have had their address taken in the statement. */
- bitmap addresses_taken;
-
- /* Unique identifier for this statement. These ID's are to be
- created by each pass on an as-needed basis in any order
- convenient for the pass which needs statement UIDs. This field
- should only be accessed thru set_gimple_stmt_uid and
- gimple_stmt_uid functions. */
- unsigned int uid;
-
- /* Nonzero if the statement references memory (at least one of its
- expressions contains a non-register operand). */
- unsigned references_memory : 1;
-
- /* Nonzero if the statement has been modified (meaning that the operands
- need to be scanned again). */
- unsigned modified : 1;
-
- /* Nonzero if the statement makes references to volatile storage. */
- unsigned has_volatile_ops : 1;
-};
-
union tree_ann_d GTY((desc ("ann_type ((tree_ann_t)&%h)")))
{
struct tree_ann_common_d GTY((tag ("TREE_ANN_COMMON"))) common;
struct var_ann_d GTY((tag ("VAR_ANN"))) vdecl;
struct function_ann_d GTY((tag ("FUNCTION_ANN"))) fdecl;
- struct stmt_ann_d GTY((tag ("STMT_ANN"))) stmt;
};
typedef union tree_ann_d *tree_ann_t;
typedef struct var_ann_d *var_ann_t;
typedef struct function_ann_d *function_ann_t;
-typedef struct stmt_ann_d *stmt_ann_t;
typedef struct tree_ann_common_d *tree_ann_common_t;
static inline tree_ann_common_t tree_common_ann (const_tree);
@@ -528,18 +538,10 @@ static inline var_ann_t var_ann (const_tree);
static inline var_ann_t get_var_ann (tree);
static inline function_ann_t function_ann (const_tree);
static inline function_ann_t get_function_ann (tree);
-static inline stmt_ann_t stmt_ann (tree);
-static inline bool has_stmt_ann (tree);
-static inline stmt_ann_t get_stmt_ann (tree);
static inline enum tree_ann_type ann_type (tree_ann_t);
-static inline basic_block bb_for_stmt (tree);
-extern void set_bb_for_stmt (tree, basic_block);
-static inline bool noreturn_call_p (tree);
-static inline void update_stmt (tree);
-static inline bool stmt_modified_p (tree);
+static inline void update_stmt (gimple);
static inline bitmap may_aliases (const_tree);
-static inline int get_lineno (const_tree);
-static inline bitmap addresses_taken (tree);
+static inline int get_lineno (const_gimple);
/*---------------------------------------------------------------------------
Structure representing predictions in tree level.
@@ -553,8 +555,8 @@ struct edge_prediction GTY((chain_next ("%h.ep_next")))
};
/* Accessors for basic block annotations. */
-static inline tree phi_nodes (const_basic_block);
-static inline void set_phi_nodes (basic_block, tree);
+static inline gimple_seq phi_nodes (const_basic_block);
+static inline void set_phi_nodes (basic_block, gimple_seq);
/*---------------------------------------------------------------------------
Global declarations
@@ -627,48 +629,6 @@ extern bool referenced_var_check_and_insert (tree);
#define PERCENT(x,y) ((float)(x) * 100.0 / (float)(y))
/*---------------------------------------------------------------------------
- Block iterators
----------------------------------------------------------------------------*/
-
-typedef struct {
- tree_stmt_iterator tsi;
- basic_block bb;
-} block_stmt_iterator;
-
-static inline block_stmt_iterator bsi_start (basic_block);
-static inline block_stmt_iterator bsi_last (basic_block);
-static inline block_stmt_iterator bsi_after_labels (basic_block);
-block_stmt_iterator bsi_for_stmt (tree);
-static inline bool bsi_end_p (block_stmt_iterator);
-static inline void bsi_next (block_stmt_iterator *);
-static inline void bsi_prev (block_stmt_iterator *);
-static inline tree bsi_stmt (block_stmt_iterator);
-static inline tree * bsi_stmt_ptr (block_stmt_iterator);
-
-extern void bsi_remove (block_stmt_iterator *, bool);
-extern void bsi_move_before (block_stmt_iterator *, block_stmt_iterator *);
-extern void bsi_move_after (block_stmt_iterator *, block_stmt_iterator *);
-extern void bsi_move_to_bb_end (block_stmt_iterator *, basic_block);
-
-enum bsi_iterator_update
-{
- /* Note that these are intentionally in the same order as TSI_FOO. They
- mean exactly the same as their TSI_* counterparts. */
- BSI_NEW_STMT,
- BSI_SAME_STMT,
- BSI_CHAIN_START,
- BSI_CHAIN_END,
- BSI_CONTINUE_LINKING
-};
-
-extern void bsi_insert_before (block_stmt_iterator *, tree,
- enum bsi_iterator_update);
-extern void bsi_insert_after (block_stmt_iterator *, tree,
- enum bsi_iterator_update);
-
-extern void bsi_replace (const block_stmt_iterator *, tree, bool);
-
-/*---------------------------------------------------------------------------
OpenMP Region Tree
---------------------------------------------------------------------------*/
@@ -702,7 +662,7 @@ struct omp_region
tree ws_args;
/* The code for the omp directive of this region. */
- enum tree_code type;
+ enum gimple_code type;
/* Schedule kind, only used for OMP_FOR type regions. */
enum omp_clause_schedule_kind sched_kind;
@@ -712,7 +672,7 @@ struct omp_region
};
extern struct omp_region *root_omp_region;
-extern struct omp_region *new_omp_region (basic_block, enum tree_code,
+extern struct omp_region *new_omp_region (basic_block, enum gimple_code,
struct omp_region *);
extern void free_omp_regions (void);
void omp_expand_local (basic_block);
@@ -725,20 +685,20 @@ tree copy_var_decl (tree, tree, tree);
/* In tree-cfg.c */
/* Location to track pending stmt for edge insertion. */
-#define PENDING_STMT(e) ((e)->insns.t)
+#define PENDING_STMT(e) ((e)->insns.g)
extern void delete_tree_cfg_annotations (void);
-extern bool stmt_ends_bb_p (const_tree);
-extern bool is_ctrl_stmt (const_tree);
-extern bool is_ctrl_altering_stmt (const_tree);
-extern bool simple_goto_p (const_tree);
-extern bool tree_can_make_abnormal_goto (const_tree);
+extern bool stmt_ends_bb_p (gimple);
+extern bool is_ctrl_stmt (gimple);
+extern bool is_ctrl_altering_stmt (gimple);
+extern bool simple_goto_p (gimple);
+extern bool stmt_can_make_abnormal_goto (gimple);
extern basic_block single_noncomplex_succ (basic_block bb);
-extern void tree_dump_bb (basic_block, FILE *, int);
-extern void debug_tree_bb (basic_block);
-extern basic_block debug_tree_bb_n (int);
-extern void dump_tree_cfg (FILE *, int);
-extern void debug_tree_cfg (int);
+extern void gimple_dump_bb (basic_block, FILE *, int, int);
+extern void gimple_debug_bb (basic_block);
+extern basic_block gimple_debug_bb_n (int);
+extern void gimple_dump_cfg (FILE *, int);
+extern void gimple_debug_cfg (int);
extern void dump_cfg_stats (FILE *);
extern void dot_cfg (void);
extern void debug_cfg_stats (void);
@@ -749,40 +709,35 @@ extern void print_loops (FILE *, int);
extern void print_loops_bb (FILE *, basic_block, int, int);
extern void cleanup_dead_labels (void);
extern void group_case_labels (void);
-extern tree first_stmt (basic_block);
-extern tree last_stmt (basic_block);
-extern tree last_and_only_stmt (basic_block);
+extern gimple first_stmt (basic_block);
+extern gimple last_stmt (basic_block);
+extern gimple last_and_only_stmt (basic_block);
extern edge find_taken_edge (basic_block, tree);
extern basic_block label_to_block_fn (struct function *, tree);
#define label_to_block(t) (label_to_block_fn (cfun, t))
-extern void bsi_insert_on_edge (edge, tree);
-extern basic_block bsi_insert_on_edge_immediate (edge, tree);
-extern void bsi_commit_one_edge_insert (edge, basic_block *);
-extern void bsi_commit_edge_inserts (void);
-extern void notice_special_calls (tree);
+extern void notice_special_calls (gimple);
extern void clear_special_calls (void);
extern void verify_stmts (void);
extern void verify_gimple (void);
-extern void verify_gimple_1 (tree);
-extern tree tree_block_label (basic_block);
+extern void verify_types_in_gimple_seq (gimple_seq);
+extern tree gimple_block_label (basic_block);
extern void extract_true_false_edges_from_block (basic_block, edge *, edge *);
-extern bool tree_duplicate_sese_region (edge, edge, basic_block *, unsigned,
+extern bool gimple_duplicate_sese_region (edge, edge, basic_block *, unsigned,
basic_block *);
-extern bool tree_duplicate_sese_tail (edge, edge, basic_block *, unsigned,
+extern bool gimple_duplicate_sese_tail (edge, edge, basic_block *, unsigned,
basic_block *);
extern void gather_blocks_in_sese_region (basic_block entry, basic_block exit,
VEC(basic_block,heap) **bbs_p);
extern void add_phi_args_after_copy_bb (basic_block);
extern void add_phi_args_after_copy (basic_block *, unsigned, edge);
-extern bool tree_purge_dead_abnormal_call_edges (basic_block);
-extern bool tree_purge_dead_eh_edges (basic_block);
-extern bool tree_purge_all_dead_eh_edges (const_bitmap);
-extern tree gimplify_val (block_stmt_iterator *, tree, tree);
-extern tree gimplify_build1 (block_stmt_iterator *, enum tree_code,
+extern bool gimple_purge_dead_abnormal_call_edges (basic_block);
+extern bool gimple_purge_dead_eh_edges (basic_block);
+extern bool gimple_purge_all_dead_eh_edges (const_bitmap);
+extern tree gimplify_build1 (gimple_stmt_iterator *, enum tree_code,
tree, tree);
-extern tree gimplify_build2 (block_stmt_iterator *, enum tree_code,
+extern tree gimplify_build2 (gimple_stmt_iterator *, enum tree_code,
tree, tree, tree);
-extern tree gimplify_build3 (block_stmt_iterator *, enum tree_code,
+extern tree gimplify_build3 (gimple_stmt_iterator *, enum tree_code,
tree, tree, tree, tree);
extern void init_empty_tree_cfg (void);
extern void init_empty_tree_cfg_for_function (struct function *);
@@ -807,7 +762,6 @@ extern const char *op_symbol_code (enum tree_code);
/* In tree-dfa.c */
extern var_ann_t create_var_ann (tree);
extern function_ann_t create_function_ann (tree);
-extern stmt_ann_t create_stmt_ann (tree);
extern void renumber_gimple_stmt_uids (void);
extern tree_ann_common_t create_tree_common_ann (tree);
extern void dump_dfa_stats (FILE *);
@@ -819,27 +773,26 @@ extern void debug_variable (tree);
extern tree get_virtual_var (tree);
extern void add_referenced_var (tree);
extern void remove_referenced_var (tree);
-extern void mark_symbols_for_renaming (tree);
-extern void find_new_referenced_vars (tree *);
+extern void mark_symbols_for_renaming (gimple);
+extern void find_new_referenced_vars (gimple);
extern tree make_rename_temp (tree, const char *);
extern void set_default_def (tree, tree);
extern tree gimple_default_def (struct function *, tree);
-extern bool stmt_references_abnormal_ssa_name (tree);
+extern bool stmt_references_abnormal_ssa_name (gimple);
extern bool refs_may_alias_p (tree, tree);
-extern tree get_single_def_stmt (tree);
-extern tree get_single_def_stmt_from_phi (tree, tree);
-extern tree get_single_def_stmt_with_phi (tree, tree);
+extern gimple get_single_def_stmt (gimple);
+extern gimple get_single_def_stmt_from_phi (tree, gimple);
+extern gimple get_single_def_stmt_with_phi (tree, gimple);
/* In tree-phinodes.c */
extern void reserve_phi_args_for_new_edge (basic_block);
-extern tree create_phi_node (tree, basic_block);
-extern void add_phi_arg (tree, tree, edge);
+extern gimple create_phi_node (tree, basic_block);
+extern void add_phi_arg (gimple, tree, edge);
extern void remove_phi_args (edge);
-extern void remove_phi_node (tree, tree, bool);
-extern tree phi_reverse (tree);
+extern void remove_phi_node (gimple_stmt_iterator *, bool);
extern void init_phinodes (void);
extern void fini_phinodes (void);
-extern void release_phi_node (tree);
+extern void release_phi_node (gimple);
#ifdef GATHER_STATISTICS
extern void phinodes_print_statistics (void);
#endif
@@ -848,6 +801,8 @@ extern void phinodes_print_statistics (void);
extern void record_vars_into (tree, tree);
extern void record_vars (tree);
extern bool block_may_fallthru (const_tree);
+extern bool gimple_seq_may_fallthru (gimple_seq);
+extern bool gimple_stmt_may_fallthru (gimple);
/* In tree-ssa-alias.c */
extern unsigned int compute_may_aliases (void);
@@ -864,7 +819,7 @@ extern bool may_alias_p (tree, alias_set_type, tree, alias_set_type, bool);
extern struct ptr_info_def *get_ptr_info (tree);
extern bool may_point_to_global_var (tree);
extern void new_type_alias (tree, tree, tree);
-extern void count_uses_and_derefs (tree, tree, unsigned *, unsigned *,
+extern void count_uses_and_derefs (tree, gimple, unsigned *, unsigned *,
unsigned *);
static inline bool ref_contains_array_ref (const_tree);
static inline bool array_ref_contains_indirect_ref (const_tree);
@@ -881,7 +836,7 @@ extern void debug_all_mem_sym_stats (void);
/* Call-back function for walk_use_def_chains(). At each reaching
definition, a function with this prototype is called. */
-typedef bool (*walk_use_def_chains_fn) (tree, tree, void *);
+typedef bool (*walk_use_def_chains_fn) (tree, gimple, void *);
/* In tree-ssa-alias-warnings.c */
extern void strict_aliasing_warning_backend (void);
@@ -918,7 +873,6 @@ extern bool types_compatible_p (tree, tree);
extern void verify_ssa (bool);
extern void delete_tree_ssa (void);
extern void walk_use_def_chains (tree, walk_use_def_chains_fn, void *, bool);
-extern bool stmt_references_memory_p (tree);
extern bool ssa_undefined_value_p (tree);
@@ -926,14 +880,13 @@ extern bool ssa_undefined_value_p (tree);
void update_ssa (unsigned);
void delete_update_ssa (void);
void register_new_name_mapping (tree, tree);
-tree create_new_def_for (tree, tree, def_operand_p);
+tree create_new_def_for (tree, gimple, def_operand_p);
bool need_ssa_update_p (void);
bool name_mappings_registered_p (void);
bool name_registered_for_update_p (tree);
bitmap ssa_names_to_replace (void);
void release_ssa_name_after_update_ssa (tree);
void compute_global_livein (bitmap, bitmap);
-tree duplicate_ssa_name (tree, tree);
void mark_sym_for_renaming (tree);
void mark_set_for_renaming (bitmap);
tree get_current_def (tree);
@@ -942,11 +895,11 @@ void set_current_def (tree, tree);
/* In tree-ssanames.c */
extern void init_ssanames (struct function *, int);
extern void fini_ssanames (void);
-extern tree make_ssa_name_fn (struct function *, tree, tree);
-extern tree duplicate_ssa_name (tree, tree);
+extern tree make_ssa_name_fn (struct function *, tree, gimple);
+extern tree duplicate_ssa_name (tree, gimple);
extern void duplicate_ssa_name_ptr_info (tree, struct ptr_info_def *);
extern void release_ssa_name (tree);
-extern void release_defs (tree);
+extern void release_defs (gimple);
extern void replace_ssa_name_symbol (tree, tree);
#ifdef GATHER_STATISTICS
@@ -954,14 +907,14 @@ extern void ssanames_print_statistics (void);
#endif
/* In tree-ssa-ccp.c */
-bool fold_stmt (tree *);
-bool fold_stmt_inplace (tree);
+bool fold_stmt (gimple_stmt_iterator *);
+bool fold_stmt_inplace (gimple);
tree get_symbol_constant_value (tree);
tree fold_const_aggregate_ref (tree);
/* In tree-vrp.c */
-tree vrp_evaluate_conditional (enum tree_code, tree, tree, tree);
-void simplify_stmt_using_ranges (tree);
+tree vrp_evaluate_conditional (enum tree_code, tree, tree, gimple);
+void simplify_stmt_using_ranges (gimple);
/* In tree-ssa-dom.c */
extern void dump_dominator_optimization_stats (FILE *);
@@ -972,8 +925,10 @@ int loop_depth_of_name (tree);
extern void merge_alias_info (tree, tree);
extern void propagate_value (use_operand_p, tree);
extern void propagate_tree_value (tree *, tree);
+extern void propagate_tree_value_into_stmt (gimple_stmt_iterator *, tree);
extern void replace_exp (use_operand_p, tree);
extern bool may_propagate_copy (tree, tree);
+extern bool may_propagate_copy_into_stmt (gimple, tree);
extern bool may_propagate_copy_into_asm (tree);
/* Affine iv. */
@@ -1046,8 +1001,8 @@ tree find_loop_niter (struct loop *, edge *);
tree loop_niter_by_eval (struct loop *, edge);
tree find_loop_niter_by_eval (struct loop *, edge *);
void estimate_numbers_of_iterations (void);
-bool scev_probably_wraps_p (tree, tree, tree, struct loop *, bool);
-bool convert_affine_scev (struct loop *, tree, tree *, tree *, tree, bool);
+bool scev_probably_wraps_p (tree, tree, gimple, struct loop *, bool);
+bool convert_affine_scev (struct loop *, tree, tree *, tree *, gimple, bool);
bool nowrap_type_p (tree);
enum ev_direction {EV_DIR_GROWS, EV_DIR_DECREASES, EV_DIR_UNKNOWN};
@@ -1058,14 +1013,14 @@ void free_numbers_of_iterations_estimates_loop (struct loop *);
void rewrite_into_loop_closed_ssa (bitmap, unsigned);
void verify_loop_closed_ssa (void);
bool for_each_index (tree *, bool (*) (tree, tree *, void *), void *);
-void create_iv (tree, tree, tree, struct loop *, block_stmt_iterator *, bool,
+void create_iv (tree, tree, tree, struct loop *, gimple_stmt_iterator *, bool,
tree *, tree *);
basic_block split_loop_exit_edge (edge);
-void standard_iv_increment_position (struct loop *, block_stmt_iterator *,
+void standard_iv_increment_position (struct loop *, gimple_stmt_iterator *,
bool *);
basic_block ip_end_pos (struct loop *);
basic_block ip_normal_pos (struct loop *);
-bool tree_duplicate_loop_to_header_edge (struct loop *, edge,
+bool gimple_duplicate_loop_to_header_edge (struct loop *, edge,
unsigned int, sbitmap,
edge, VEC (edge, heap) **,
int);
@@ -1085,13 +1040,13 @@ void tree_transform_and_unroll_loop (struct loop *, unsigned,
edge, struct tree_niter_desc *,
transform_callback, void *);
bool contains_abnormal_ssa_name_p (tree);
-bool stmt_dominates_stmt_p (tree, tree);
-void mark_virtual_ops_for_renaming (tree);
+bool stmt_dominates_stmt_p (gimple, gimple);
+void mark_virtual_ops_for_renaming (gimple);
/* In tree-ssa-threadedge.c */
extern bool potentially_threadable_block (basic_block);
-extern void thread_across_edge (tree, edge, bool,
- VEC(tree, heap) **, tree (*) (tree, tree));
+extern void thread_across_edge (gimple, edge, bool,
+ VEC(tree, heap) **, tree (*) (gimple, gimple));
/* In tree-ssa-loop-im.c */
/* The possibilities of statement movement. */
@@ -1103,7 +1058,7 @@ enum move_pos
become executed -- memory accesses, ... */
MOVE_POSSIBLE /* Unlimited movement. */
};
-extern enum move_pos movement_possibility (tree);
+extern enum move_pos movement_possibility (gimple);
char *get_lsm_tmp_name (tree, unsigned);
/* In tree-flow-inline.h */
@@ -1113,45 +1068,52 @@ static inline void set_is_used (tree);
static inline bool unmodifiable_var_p (const_tree);
/* In tree-eh.c */
-extern void make_eh_edges (tree);
+extern void make_eh_edges (gimple);
extern bool tree_could_trap_p (tree);
+extern bool operation_could_trap_p (enum tree_code, bool, bool, tree);
+extern bool stmt_could_throw_p (gimple);
extern bool tree_could_throw_p (tree);
-extern bool tree_can_throw_internal (const_tree);
-extern bool tree_can_throw_external (tree);
-extern int lookup_stmt_eh_region (const_tree);
-extern void add_stmt_to_eh_region (tree, int);
-extern bool remove_stmt_from_eh_region (tree);
-extern bool maybe_clean_or_replace_eh_stmt (tree, tree);
+extern bool stmt_can_throw_internal (gimple);
+extern void add_stmt_to_eh_region (gimple, int);
+extern bool remove_stmt_from_eh_region (gimple);
+extern bool maybe_clean_or_replace_eh_stmt (gimple, gimple);
+extern void add_stmt_to_eh_region_fn (struct function *, gimple, int);
+extern bool remove_stmt_from_eh_region_fn (struct function *, gimple);
+extern int lookup_stmt_eh_region_fn (struct function *, gimple);
+extern int lookup_expr_eh_region (tree);
+extern int lookup_stmt_eh_region (gimple);
+extern bool verify_eh_edges (gimple);
+
/* In tree-ssa-pre.c */
-void add_to_value (tree, tree);
-void debug_value_expressions (tree);
-void print_value_expressions (FILE *, tree);
+struct pre_expr_d;
+void add_to_value (unsigned int, struct pre_expr_d *);
+void debug_value_expressions (unsigned int);
+void print_value_expressions (FILE *, unsigned int);
/* In tree-vn.c */
tree make_value_handle (tree);
void set_value_handle (tree, tree);
bool expressions_equal_p (tree, tree);
-static inline tree get_value_handle (tree);
void sort_vuses (VEC (tree, gc) *);
void sort_vuses_heap (VEC (tree, heap) *);
tree vn_lookup_or_add (tree);
-tree vn_lookup_or_add_with_stmt (tree, tree);
+tree vn_lookup_or_add_with_stmt (tree, gimple);
tree vn_lookup_or_add_with_vuses (tree, VEC (tree, gc) *);
void vn_add (tree, tree);
void vn_add_with_vuses (tree, tree, VEC (tree, gc) *);
-tree vn_lookup_with_stmt (tree, tree);
+tree vn_lookup_with_stmt (tree, gimple);
tree vn_lookup (tree);
tree vn_lookup_with_vuses (tree, VEC (tree, gc) *);
/* In tree-ssa-sink.c */
-bool is_hidden_global_store (tree);
+bool is_hidden_global_store (gimple);
/* In tree-sra.c */
-void insert_edge_copies (tree, basic_block);
-void sra_insert_before (block_stmt_iterator *, tree);
-void sra_insert_after (block_stmt_iterator *, tree);
+void insert_edge_copies_seq (gimple_seq, basic_block);
+void sra_insert_before (gimple_stmt_iterator *, gimple_seq);
+void sra_insert_after (gimple_stmt_iterator *, gimple_seq);
void sra_init_cache (void);
bool sra_type_can_be_decomposed_p (tree);
@@ -1163,6 +1125,7 @@ extern void tree_check_data_deps (void);
/* In tree-ssa-loop-ivopts.c */
bool expr_invariant_in_loop_p (struct loop *, tree);
+bool stmt_invariant_in_loop_p (struct loop *, gimple);
bool multiplier_allowed_in_address_p (HOST_WIDE_INT, enum machine_mode);
unsigned multiply_by_cost (HOST_WIDE_INT, enum machine_mode);
@@ -1171,9 +1134,9 @@ extern bool thread_through_all_blocks (bool);
extern void register_jump_thread (edge, edge);
/* In gimplify.c */
-tree force_gimple_operand (tree, tree *, bool, tree);
-tree force_gimple_operand_bsi (block_stmt_iterator *, tree, bool, tree,
- bool, enum bsi_iterator_update);
+tree force_gimple_operand (tree, gimple_seq *, bool, tree);
+tree force_gimple_operand_gsi (gimple_stmt_iterator *, tree, bool, tree,
+ bool, enum gsi_iterator_update);
tree gimple_fold_indirect_ref (tree);
/* In tree-ssa-structalias.c */
@@ -1194,7 +1157,7 @@ struct mem_address
};
struct affine_tree_combination;
-tree create_mem_ref (block_stmt_iterator *, tree,
+tree create_mem_ref (gimple_stmt_iterator *, tree,
struct affine_tree_combination *);
rtx addr_for_mem_ref (struct mem_address *, bool);
void get_address_description (tree, struct mem_address *);
@@ -1206,7 +1169,7 @@ unsigned int execute_fixup_cfg (void);
#include "tree-flow-inline.h"
-void swap_tree_operands (tree, tree *, tree *);
+void swap_tree_operands (gimple, tree *, tree *);
int least_common_multiple (int, int);
diff --git a/gcc/tree-gimple.c b/gcc/tree-gimple.c
deleted file mode 100644
index 8b05f93d505..00000000000
--- a/gcc/tree-gimple.c
+++ /dev/null
@@ -1,653 +0,0 @@
-/* Functions to analyze and validate GIMPLE trees.
- Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007
- Free Software Foundation, Inc.
- Contributed by Diego Novillo <dnovillo@redhat.com>
- Rewritten by Jason Merrill <jason@redhat.com>
-
-This file is part of GCC.
-
-GCC is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 3, or (at your option)
-any later version.
-
-GCC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING3. If not see
-<http://www.gnu.org/licenses/>. */
-
-#include "config.h"
-#include "system.h"
-#include "coretypes.h"
-#include "ggc.h"
-#include "tm.h"
-#include "tree.h"
-#include "tree-gimple.h"
-#include "tree-flow.h"
-#include "output.h"
-#include "rtl.h"
-#include "expr.h"
-#include "bitmap.h"
-
-/* For the definitive definition of GIMPLE, see doc/tree-ssa.texi. */
-
-/* Validation of GIMPLE expressions. */
-
-/* Return true if T is a GIMPLE RHS for an assignment to a temporary. */
-
-bool
-is_gimple_formal_tmp_rhs (tree t)
-{
- enum tree_code code = TREE_CODE (t);
-
- switch (TREE_CODE_CLASS (code))
- {
- case tcc_unary:
- case tcc_binary:
- case tcc_comparison:
- return true;
-
- default:
- break;
- }
-
- switch (code)
- {
- case TRUTH_NOT_EXPR:
- case TRUTH_AND_EXPR:
- case TRUTH_OR_EXPR:
- case TRUTH_XOR_EXPR:
- case COND_EXPR:
- case ADDR_EXPR:
- case CALL_EXPR:
- case CONSTRUCTOR:
- case COMPLEX_EXPR:
- case INTEGER_CST:
- case REAL_CST:
- case FIXED_CST:
- case STRING_CST:
- case COMPLEX_CST:
- case VECTOR_CST:
- case OBJ_TYPE_REF:
- case ASSERT_EXPR:
- return true;
-
- default:
- break;
- }
-
- return is_gimple_lvalue (t) || is_gimple_val (t);
-}
-
-/* Returns true iff T is a valid RHS for an assignment to a renamed
- user -- or front-end generated artificial -- variable. */
-
-bool
-is_gimple_reg_rhs (tree t)
-{
- /* If the RHS of the GIMPLE_MODIFY_STMT may throw or make a nonlocal goto
- and the LHS is a user variable, then we need to introduce a formal
- temporary. This way the optimizers can determine that the user
- variable is only modified if evaluation of the RHS does not throw.
-
- Don't force a temp of a non-renamable type; the copy could be
- arbitrarily expensive. Instead we will generate a VDEF for
- the assignment. */
-
- if (is_gimple_reg_type (TREE_TYPE (t))
- && ((TREE_CODE (t) == CALL_EXPR && TREE_SIDE_EFFECTS (t))
- || tree_could_throw_p (t)))
- return false;
-
- return is_gimple_formal_tmp_rhs (t);
-}
-
-/* Returns true iff T is a valid RHS for an assignment to an un-renamed
- LHS, or for a call argument. */
-
-bool
-is_gimple_mem_rhs (tree t)
-{
- /* If we're dealing with a renamable type, either source or dest must be
- a renamed variable. */
- if (is_gimple_reg_type (TREE_TYPE (t)))
- return is_gimple_val (t);
- else
- return is_gimple_formal_tmp_rhs (t);
-}
-
-/* Returns the appropriate RHS predicate for this LHS. */
-
-gimple_predicate
-rhs_predicate_for (tree lhs)
-{
- if (is_gimple_formal_tmp_var (lhs))
- return is_gimple_formal_tmp_rhs;
- else if (is_gimple_reg (lhs))
- return is_gimple_reg_rhs;
- else
- return is_gimple_mem_rhs;
-}
-
-/* Return true if T is a valid LHS for a GIMPLE assignment expression. */
-
-bool
-is_gimple_lvalue (tree t)
-{
- return (is_gimple_addressable (t)
- || TREE_CODE (t) == WITH_SIZE_EXPR
- /* These are complex lvalues, but don't have addresses, so they
- go here. */
- || TREE_CODE (t) == BIT_FIELD_REF);
-}
-
-/* Return true if T is a GIMPLE condition. */
-
-bool
-is_gimple_condexpr (tree t)
-{
- return (is_gimple_val (t) || (COMPARISON_CLASS_P (t)
- && !tree_could_trap_p (t)
- && is_gimple_val (TREE_OPERAND (t, 0))
- && is_gimple_val (TREE_OPERAND (t, 1))));
-}
-
-/* Return true if T is something whose address can be taken. */
-
-bool
-is_gimple_addressable (tree t)
-{
- return (is_gimple_id (t) || handled_component_p (t)
- || INDIRECT_REF_P (t));
-}
-
-/* Return true if T is a valid gimple constant. */
-
-bool
-is_gimple_constant (const_tree t)
-{
- switch (TREE_CODE (t))
- {
- case INTEGER_CST:
- case REAL_CST:
- case FIXED_CST:
- case STRING_CST:
- case COMPLEX_CST:
- case VECTOR_CST:
- return true;
-
- /* Vector constant constructors are gimple invariant. */
- case CONSTRUCTOR:
- if (TREE_TYPE (t) && TREE_CODE (TREE_TYPE (t)) == VECTOR_TYPE)
- return TREE_CONSTANT (t);
- else
- return false;
-
- default:
- return false;
- }
-}
-
-/* Return true if T is a gimple address. */
-
-bool
-is_gimple_address (const_tree t)
-{
- tree op;
-
- if (TREE_CODE (t) != ADDR_EXPR)
- return false;
-
- op = TREE_OPERAND (t, 0);
- while (handled_component_p (op))
- {
- if ((TREE_CODE (op) == ARRAY_REF
- || TREE_CODE (op) == ARRAY_RANGE_REF)
- && !is_gimple_val (TREE_OPERAND (op, 1)))
- return false;
-
- op = TREE_OPERAND (op, 0);
- }
-
- if (CONSTANT_CLASS_P (op) || INDIRECT_REF_P (op))
- return true;
-
- switch (TREE_CODE (op))
- {
- case PARM_DECL:
- case RESULT_DECL:
- case LABEL_DECL:
- case FUNCTION_DECL:
- case VAR_DECL:
- case CONST_DECL:
- return true;
-
- default:
- return false;
- }
-}
-
-/* Return true if T is a gimple invariant address. */
-
-bool
-is_gimple_invariant_address (const_tree t)
-{
- tree op;
-
- if (TREE_CODE (t) != ADDR_EXPR)
- return false;
-
- op = TREE_OPERAND (t, 0);
- while (handled_component_p (op))
- {
- switch (TREE_CODE (op))
- {
- case ARRAY_REF:
- case ARRAY_RANGE_REF:
- if (!is_gimple_constant (TREE_OPERAND (op, 1))
- || TREE_OPERAND (op, 2) != NULL_TREE
- || TREE_OPERAND (op, 3) != NULL_TREE)
- return false;
- break;
-
- case COMPONENT_REF:
- if (TREE_OPERAND (op, 2) != NULL_TREE)
- return false;
- break;
-
- default:;
- }
- op = TREE_OPERAND (op, 0);
- }
-
- return CONSTANT_CLASS_P (op) || decl_address_invariant_p (op);
-}
-
-/* Return true if T is a GIMPLE minimal invariant. It's a restricted
- form of function invariant. */
-
-bool
-is_gimple_min_invariant (const_tree t)
-{
- if (TREE_CODE (t) == ADDR_EXPR)
- return is_gimple_invariant_address (t);
-
- return is_gimple_constant (t);
-}
-
-/* Return true if T looks like a valid GIMPLE statement. */
-
-bool
-is_gimple_stmt (tree t)
-{
- const enum tree_code code = TREE_CODE (t);
-
- switch (code)
- {
- case NOP_EXPR:
- /* The only valid NOP_EXPR is the empty statement. */
- return IS_EMPTY_STMT (t);
-
- case BIND_EXPR:
- case COND_EXPR:
- /* These are only valid if they're void. */
- return TREE_TYPE (t) == NULL || VOID_TYPE_P (TREE_TYPE (t));
-
- case SWITCH_EXPR:
- case GOTO_EXPR:
- case RETURN_EXPR:
- case LABEL_EXPR:
- case CASE_LABEL_EXPR:
- case TRY_CATCH_EXPR:
- case TRY_FINALLY_EXPR:
- case EH_FILTER_EXPR:
- case CATCH_EXPR:
- case CHANGE_DYNAMIC_TYPE_EXPR:
- case ASM_EXPR:
- case RESX_EXPR:
- case PHI_NODE:
- case STATEMENT_LIST:
- case OMP_PARALLEL:
- case OMP_FOR:
- case OMP_SECTIONS:
- case OMP_SECTIONS_SWITCH:
- case OMP_SECTION:
- case OMP_SINGLE:
- case OMP_MASTER:
- case OMP_ORDERED:
- case OMP_CRITICAL:
- case OMP_RETURN:
- case OMP_CONTINUE:
- case OMP_TASK:
- case OMP_ATOMIC_LOAD:
- case OMP_ATOMIC_STORE:
- /* These are always void. */
- return true;
-
- case CALL_EXPR:
- case GIMPLE_MODIFY_STMT:
- case PREDICT_EXPR:
- /* These are valid regardless of their type. */
- return true;
-
- default:
- return false;
- }
-}
-
-/* Return true if T is a variable. */
-
-bool
-is_gimple_variable (tree t)
-{
- return (TREE_CODE (t) == VAR_DECL
- || TREE_CODE (t) == PARM_DECL
- || TREE_CODE (t) == RESULT_DECL
- || TREE_CODE (t) == SSA_NAME);
-}
-
-/* Return true if T is a GIMPLE identifier (something with an address). */
-
-bool
-is_gimple_id (tree t)
-{
- return (is_gimple_variable (t)
- || TREE_CODE (t) == FUNCTION_DECL
- || TREE_CODE (t) == LABEL_DECL
- || TREE_CODE (t) == CONST_DECL
- /* Allow string constants, since they are addressable. */
- || TREE_CODE (t) == STRING_CST);
-}
-
-/* Return true if TYPE is a suitable type for a scalar register variable. */
-
-bool
-is_gimple_reg_type (tree type)
-{
- /* In addition to aggregate types, we also exclude complex types if not
- optimizing because they can be subject to partial stores in GNU C by
- means of the __real__ and __imag__ operators and we cannot promote
- them to total stores (see gimplify_modify_expr_complex_part). */
- return !(AGGREGATE_TYPE_P (type)
- || (TREE_CODE (type) == COMPLEX_TYPE && !optimize));
-
-}
-
-/* Return true if T is a non-aggregate register variable. */
-
-bool
-is_gimple_reg (tree t)
-{
- if (TREE_CODE (t) == SSA_NAME)
- t = SSA_NAME_VAR (t);
-
- if (MTAG_P (t))
- return false;
-
- if (!is_gimple_variable (t))
- return false;
-
- if (!is_gimple_reg_type (TREE_TYPE (t)))
- return false;
-
- /* A volatile decl is not acceptable because we can't reuse it as
- needed. We need to copy it into a temp first. */
- if (TREE_THIS_VOLATILE (t))
- return false;
-
- /* We define "registers" as things that can be renamed as needed,
- which with our infrastructure does not apply to memory. */
- if (needs_to_live_in_memory (t))
- return false;
-
- /* Hard register variables are an interesting case. For those that
- are call-clobbered, we don't know where all the calls are, since
- we don't (want to) take into account which operations will turn
- into libcalls at the rtl level. For those that are call-saved,
- we don't currently model the fact that calls may in fact change
- global hard registers, nor do we examine ASM_CLOBBERS at the tree
- level, and so miss variable changes that might imply. All around,
- it seems safest to not do too much optimization with these at the
- tree level at all. We'll have to rely on the rtl optimizers to
- clean this up, as there we've got all the appropriate bits exposed. */
- if (TREE_CODE (t) == VAR_DECL && DECL_HARD_REGISTER (t))
- return false;
-
- /* Complex and vector values must have been put into SSA-like form.
- That is, no assignments to the individual components. */
- if (TREE_CODE (TREE_TYPE (t)) == COMPLEX_TYPE
- || TREE_CODE (TREE_TYPE (t)) == VECTOR_TYPE)
- return DECL_GIMPLE_REG_P (t);
-
- return true;
-}
-
-
-/* Returns true if T is a GIMPLE formal temporary variable. */
-
-bool
-is_gimple_formal_tmp_var (tree t)
-{
- if (TREE_CODE (t) == SSA_NAME)
- return true;
-
- return TREE_CODE (t) == VAR_DECL && DECL_GIMPLE_FORMAL_TEMP_P (t);
-}
-
-/* Returns true if T is a GIMPLE formal temporary register variable. */
-
-bool
-is_gimple_formal_tmp_reg (tree t)
-{
- /* The intent of this is to get hold of a value that won't change.
- An SSA_NAME qualifies no matter if its of a user variable or not. */
- if (TREE_CODE (t) == SSA_NAME)
- return true;
-
- /* We don't know the lifetime characteristics of user variables. */
- if (!is_gimple_formal_tmp_var (t))
- return false;
-
- /* Finally, it must be capable of being placed in a register. */
- return is_gimple_reg (t);
-}
-
-/* Return true if T is a GIMPLE variable whose address is not needed. */
-
-bool
-is_gimple_non_addressable (tree t)
-{
- if (TREE_CODE (t) == SSA_NAME)
- t = SSA_NAME_VAR (t);
-
- return (is_gimple_variable (t) && ! needs_to_live_in_memory (t));
-}
-
-/* Return true if T is a GIMPLE rvalue, i.e. an identifier or a constant. */
-
-bool
-is_gimple_val (tree t)
-{
- /* Make loads from volatiles and memory vars explicit. */
- if (is_gimple_variable (t)
- && is_gimple_reg_type (TREE_TYPE (t))
- && !is_gimple_reg (t))
- return false;
-
- /* FIXME make these decls. That can happen only when we expose the
- entire landing-pad construct at the tree level. */
- if (TREE_CODE (t) == EXC_PTR_EXPR || TREE_CODE (t) == FILTER_EXPR)
- return true;
-
- return (is_gimple_variable (t) || is_gimple_min_invariant (t));
-}
-
-/* Similarly, but accept hard registers as inputs to asm statements. */
-
-bool
-is_gimple_asm_val (tree t)
-{
- if (TREE_CODE (t) == VAR_DECL && DECL_HARD_REGISTER (t))
- return true;
-
- return is_gimple_val (t);
-}
-
-/* Return true if T is a GIMPLE minimal lvalue. */
-
-bool
-is_gimple_min_lval (tree t)
-{
- return (is_gimple_id (t)
- || TREE_CODE (t) == INDIRECT_REF);
-}
-
-/* Return true if T is a typecast operation. */
-
-bool
-is_gimple_cast (tree t)
-{
- return (CONVERT_EXPR_P (t)
- || TREE_CODE (t) == FIX_TRUNC_EXPR);
-}
-
-/* Return true if T is a valid function operand of a CALL_EXPR. */
-
-bool
-is_gimple_call_addr (tree t)
-{
- return (TREE_CODE (t) == OBJ_TYPE_REF
- || is_gimple_val (t));
-}
-
-/* If T makes a function call, return the corresponding CALL_EXPR operand.
- Otherwise, return NULL_TREE. */
-
-tree
-get_call_expr_in (tree t)
-{
- /* FIXME tuples: delete the assertion below when conversion complete. */
- gcc_assert (TREE_CODE (t) != MODIFY_EXPR);
- if (TREE_CODE (t) == GIMPLE_MODIFY_STMT)
- t = GIMPLE_STMT_OPERAND (t, 1);
- if (TREE_CODE (t) == WITH_SIZE_EXPR)
- t = TREE_OPERAND (t, 0);
- if (TREE_CODE (t) == CALL_EXPR)
- return t;
- return NULL_TREE;
-}
-
-/* Given a memory reference expression T, return its base address.
- The base address of a memory reference expression is the main
- object being referenced. For instance, the base address for
- 'array[i].fld[j]' is 'array'. You can think of this as stripping
- away the offset part from a memory address.
-
- This function calls handled_component_p to strip away all the inner
- parts of the memory reference until it reaches the base object. */
-
-tree
-get_base_address (tree t)
-{
- while (handled_component_p (t))
- t = TREE_OPERAND (t, 0);
-
- if (SSA_VAR_P (t)
- || TREE_CODE (t) == STRING_CST
- || TREE_CODE (t) == CONSTRUCTOR
- || INDIRECT_REF_P (t))
- return t;
- else
- return NULL_TREE;
-}
-
-void
-recalculate_side_effects (tree t)
-{
- enum tree_code code = TREE_CODE (t);
- int len = TREE_OPERAND_LENGTH (t);
- int i;
-
- switch (TREE_CODE_CLASS (code))
- {
- case tcc_expression:
- switch (code)
- {
- case INIT_EXPR:
- case GIMPLE_MODIFY_STMT:
- case VA_ARG_EXPR:
- case PREDECREMENT_EXPR:
- case PREINCREMENT_EXPR:
- case POSTDECREMENT_EXPR:
- case POSTINCREMENT_EXPR:
- /* All of these have side-effects, no matter what their
- operands are. */
- return;
-
- default:
- break;
- }
- /* Fall through. */
-
- case tcc_comparison: /* a comparison expression */
- case tcc_unary: /* a unary arithmetic expression */
- case tcc_binary: /* a binary arithmetic expression */
- case tcc_reference: /* a reference */
- case tcc_vl_exp: /* a function call */
- TREE_SIDE_EFFECTS (t) = TREE_THIS_VOLATILE (t);
- for (i = 0; i < len; ++i)
- {
- tree op = TREE_OPERAND (t, i);
- if (op && TREE_SIDE_EFFECTS (op))
- TREE_SIDE_EFFECTS (t) = 1;
- }
- break;
-
- default:
- /* Can never be used with non-expressions. */
- gcc_unreachable ();
- }
-}
-
-/* Canonicalize a tree T for use in a COND_EXPR as conditional. Returns
- a canonicalized tree that is valid for a COND_EXPR or NULL_TREE, if
- we failed to create one. */
-
-tree
-canonicalize_cond_expr_cond (tree t)
-{
- /* For (bool)x use x != 0. */
- if (TREE_CODE (t) == NOP_EXPR
- && TREE_TYPE (t) == boolean_type_node)
- {
- tree top0 = TREE_OPERAND (t, 0);
- t = build2 (NE_EXPR, TREE_TYPE (t),
- top0, build_int_cst (TREE_TYPE (top0), 0));
- }
- /* For !x use x == 0. */
- else if (TREE_CODE (t) == TRUTH_NOT_EXPR)
- {
- tree top0 = TREE_OPERAND (t, 0);
- t = build2 (EQ_EXPR, TREE_TYPE (t),
- top0, build_int_cst (TREE_TYPE (top0), 0));
- }
- /* For cmp ? 1 : 0 use cmp. */
- else if (TREE_CODE (t) == COND_EXPR
- && COMPARISON_CLASS_P (TREE_OPERAND (t, 0))
- && integer_onep (TREE_OPERAND (t, 1))
- && integer_zerop (TREE_OPERAND (t, 2)))
- {
- tree top0 = TREE_OPERAND (t, 0);
- t = build2 (TREE_CODE (top0), TREE_TYPE (t),
- TREE_OPERAND (top0, 0), TREE_OPERAND (top0, 1));
- }
-
- if (is_gimple_condexpr (t))
- return t;
-
- return NULL_TREE;
-}
diff --git a/gcc/tree-gimple.h b/gcc/tree-gimple.h
deleted file mode 100644
index 3864d5d9d3e..00000000000
--- a/gcc/tree-gimple.h
+++ /dev/null
@@ -1,215 +0,0 @@
-/* Functions to analyze and validate GIMPLE trees.
- Copyright (C) 2002, 2003, 2005, 2007 Free Software Foundation, Inc.
- Contributed by Diego Novillo <dnovillo@redhat.com>
-
-This file is part of GCC.
-
-GCC is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 3, or (at your option)
-any later version.
-
-GCC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING3. If not see
-<http://www.gnu.org/licenses/>. */
-
-#ifndef _TREE_SIMPLE_H
-#define _TREE_SIMPLE_H 1
-
-
-#include "tree-iterator.h"
-
-extern tree create_tmp_var_raw (tree, const char *);
-extern tree create_tmp_var_name (const char *);
-extern tree create_tmp_var (tree, const char *);
-extern tree get_initialized_tmp_var (tree, tree *, tree *);
-extern tree get_formal_tmp_var (tree, tree *);
-
-extern void declare_vars (tree, tree, bool);
-
-extern void annotate_all_with_locus (tree *, location_t);
-
-/* Validation of GIMPLE expressions. Note that these predicates only check
- the basic form of the expression, they don't recurse to make sure that
- underlying nodes are also of the right form. */
-
-typedef bool (*gimple_predicate)(tree);
-
-/* Returns true iff T is a valid GIMPLE statement. */
-extern bool is_gimple_stmt (tree);
-
-/* Returns true iff TYPE is a valid type for a scalar register variable. */
-extern bool is_gimple_reg_type (tree);
-/* Returns true iff T is a scalar register variable. */
-extern bool is_gimple_reg (tree);
-/* Returns true if T is a GIMPLE temporary variable, false otherwise. */
-extern bool is_gimple_formal_tmp_var (tree);
-/* Returns true if T is a GIMPLE temporary register variable. */
-extern bool is_gimple_formal_tmp_reg (tree);
-/* Returns true iff T is any sort of variable. */
-extern bool is_gimple_variable (tree);
-/* Returns true iff T is any sort of symbol. */
-extern bool is_gimple_id (tree);
-/* Returns true iff T is a variable or an INDIRECT_REF (of a variable). */
-extern bool is_gimple_min_lval (tree);
-/* Returns true iff T is something whose address can be taken. */
-extern bool is_gimple_addressable (tree);
-/* Returns true iff T is any valid GIMPLE lvalue. */
-extern bool is_gimple_lvalue (tree);
-
-/* Returns true iff T is a GIMPLE address. */
-bool is_gimple_address (const_tree);
-/* Returns true iff T is a GIMPLE invariant address. */
-bool is_gimple_invariant_address (const_tree);
-/* Returns true iff T is a valid GIMPLE constant. */
-bool is_gimple_constant (const_tree);
-/* Returns true iff T is a GIMPLE restricted function invariant. */
-extern bool is_gimple_min_invariant (const_tree);
-/* Returns true iff T is a GIMPLE rvalue. */
-extern bool is_gimple_val (tree);
-/* Returns true iff T is a GIMPLE asm statement input. */
-extern bool is_gimple_asm_val (tree);
-/* Returns true iff T is a valid rhs for a MODIFY_EXPR where the LHS is a
- GIMPLE temporary, a renamed user variable, or something else,
- respectively. */
-extern bool is_gimple_formal_tmp_rhs (tree);
-extern bool is_gimple_reg_rhs (tree);
-extern bool is_gimple_mem_rhs (tree);
-/* Returns the appropriate one of the above three predicates for the LHS
- T. */
-extern gimple_predicate rhs_predicate_for (tree);
-
-/* Returns true iff T is a valid if-statement condition. */
-extern bool is_gimple_condexpr (tree);
-
-/* Returns true iff T is a type conversion. */
-extern bool is_gimple_cast (tree);
-/* Returns true iff T is a variable that does not need to live in memory. */
-extern bool is_gimple_non_addressable (tree t);
-
-/* Returns true iff T is a valid call address expression. */
-extern bool is_gimple_call_addr (tree);
-/* If T makes a function call, returns the CALL_EXPR operand. */
-extern tree get_call_expr_in (tree t);
-/* Returns true iff T contains a CALL_EXPR not suitable for inlining. */
-#define CALL_STMT_CANNOT_INLINE_P(T) \
- CALL_CANNOT_INLINE_P (get_call_expr_in (T))
-
-extern void recalculate_side_effects (tree);
-
-/* FIXME we should deduce this from the predicate. */
-typedef enum fallback_t {
- fb_none = 0,
- fb_rvalue = 1,
- fb_lvalue = 2,
- fb_mayfail = 4,
- fb_either= fb_rvalue | fb_lvalue
-} fallback_t;
-
-enum gimplify_status {
- GS_ERROR = -2, /* Something Bad Seen. */
- GS_UNHANDLED = -1, /* A langhook result for "I dunno". */
- GS_OK = 0, /* We did something, maybe more to do. */
- GS_ALL_DONE = 1 /* The expression is fully gimplified. */
-};
-
-extern enum gimplify_status gimplify_expr (tree *, tree *, tree *,
- bool (*) (tree), fallback_t);
-extern void gimplify_type_sizes (tree, tree *);
-extern void gimplify_one_sizepos (tree *, tree *);
-extern void gimplify_stmt (tree *);
-extern void gimplify_to_stmt_list (tree *);
-extern void gimplify_body (tree *, tree, bool);
-extern void push_gimplify_context (void);
-extern void pop_gimplify_context (tree);
-extern void gimplify_and_add (tree, tree *);
-
-/* Miscellaneous helpers. */
-extern void gimple_add_tmp_var (tree);
-extern tree gimple_current_bind_expr (void);
-extern tree voidify_wrapper_expr (tree, tree);
-extern tree gimple_build_eh_filter (tree, tree, tree);
-extern tree build_and_jump (tree *);
-extern tree alloc_stmt_list (void);
-extern void free_stmt_list (tree);
-extern tree force_labels_r (tree *, int *, void *);
-extern enum gimplify_status gimplify_va_arg_expr (tree *, tree *, tree *);
-struct gimplify_omp_ctx;
-extern void omp_firstprivatize_variable (struct gimplify_omp_ctx *, tree);
-extern tree gimple_boolify (tree);
-extern tree canonicalize_cond_expr_cond (tree);
-
-/* In omp-low.c. */
-extern void diagnose_omp_structured_block_errors (tree);
-extern tree omp_reduction_init (tree, tree);
-
-/* In tree-nested.c. */
-extern void lower_nested_functions (tree);
-extern void insert_field_into_struct (tree, tree);
-
-/* Convenience routines to walk all statements of a gimple function.
- The difference between these walkers and the generic walk_tree is
- that walk_stmt provides context information to the callback
- routine to know whether it is currently on the LHS or RHS of an
- assignment (IS_LHS) or contexts where only GIMPLE values are
- allowed (VAL_ONLY).
-
- This is useful in walkers that need to re-write sub-expressions
- inside statements while making sure the result is still in GIMPLE
- form.
-
- Note that this is useful exclusively before the code is converted
- into SSA form. Once the program is in SSA form, the standard
- operand interface should be used to analyze/modify statements. */
-
-struct walk_stmt_info
-{
- /* For each statement, we invoke CALLBACK via walk_tree. The passed
- data is a walk_stmt_info structure. */
- walk_tree_fn callback;
-
- /* Points to the current statement being walked. */
- tree_stmt_iterator tsi;
-
- /* Additional data that CALLBACK may want to carry through the
- recursion. */
- void *info;
-
- /* Indicates whether the *TP being examined may be replaced
- with something that matches is_gimple_val (if true) or something
- slightly more complicated (if false). "Something" technically
- means the common subset of is_gimple_lvalue and is_gimple_rhs,
- but we never try to form anything more complicated than that, so
- we don't bother checking.
-
- Also note that CALLBACK should update this flag while walking the
- sub-expressions of a statement. For instance, when walking the
- statement 'foo (&var)', the flag VAL_ONLY will initially be set
- to true, however, when walking &var, the operand of that
- ADDR_EXPR does not need to be a GIMPLE value. */
- bool val_only;
-
- /* True if we are currently walking the LHS of an assignment. */
- bool is_lhs;
-
- /* Optional. Set to true by CALLBACK if it made any changes. */
- bool changed;
-
- /* True if we're interested in seeing BIND_EXPRs. */
- bool want_bind_expr;
-
- /* True if we're interested in seeing RETURN_EXPRs. */
- bool want_return_expr;
-
- /* True if we're interested in location information. */
- bool want_locations;
-};
-
-void walk_stmts (struct walk_stmt_info *, tree *);
-
-#endif /* _TREE_SIMPLE_H */
diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c
index 78b29a4a64b..d21bb9d49d1 100644
--- a/gcc/tree-if-conv.c
+++ b/gcc/tree-if-conv.c
@@ -100,31 +100,33 @@ along with GCC; see the file COPYING3. If not see
#include "tree-pass.h"
#include "target.h"
+
/* local function prototypes */
static unsigned int main_tree_if_conversion (void);
-static tree tree_if_convert_stmt (struct loop *loop, tree, tree,
- block_stmt_iterator *);
-static void tree_if_convert_cond_expr (struct loop *, tree, tree,
- block_stmt_iterator *);
-static bool if_convertible_phi_p (struct loop *, basic_block, tree);
-static bool if_convertible_gimple_modify_stmt_p (struct loop *, basic_block,
- tree);
-static bool if_convertible_stmt_p (struct loop *, basic_block, tree);
+static tree tree_if_convert_stmt (struct loop *loop, gimple, tree,
+ gimple_stmt_iterator *);
+static void tree_if_convert_cond_stmt (struct loop *, gimple, tree,
+ gimple_stmt_iterator *);
+static bool if_convertible_phi_p (struct loop *, basic_block, gimple);
+static bool if_convertible_gimple_assign_stmt_p (struct loop *, basic_block,
+ gimple);
+static bool if_convertible_stmt_p (struct loop *, basic_block, gimple);
static bool if_convertible_bb_p (struct loop *, basic_block, basic_block);
static bool if_convertible_loop_p (struct loop *, bool);
static void add_to_predicate_list (basic_block, tree);
static tree add_to_dst_predicate_list (struct loop * loop, edge,
tree, tree,
- block_stmt_iterator *);
+ gimple_stmt_iterator *);
static void clean_predicate_lists (struct loop *loop);
static basic_block find_phi_replacement_condition (struct loop *loop,
basic_block, tree *,
- block_stmt_iterator *);
-static void replace_phi_with_cond_gimple_modify_stmt (tree, tree, basic_block,
- block_stmt_iterator *);
+ gimple_stmt_iterator *);
+static void replace_phi_with_cond_gimple_assign_stmt (gimple, tree,
+ basic_block,
+ gimple_stmt_iterator *);
static void process_phi_nodes (struct loop *);
static void combine_blocks (struct loop *);
-static tree ifc_temp_var (tree, tree);
+static gimple ifc_temp_var (tree, tree);
static bool pred_blocks_visited_p (basic_block, bitmap *);
static basic_block * get_loop_body_in_if_conv_order (const struct loop *loop);
static bool bb_with_exit_edge_p (struct loop *, basic_block);
@@ -143,7 +145,7 @@ static bool
tree_if_conversion (struct loop *loop, bool for_vectorizer)
{
basic_block bb;
- block_stmt_iterator itr;
+ gimple_stmt_iterator itr;
unsigned int i;
ifc_bbs = NULL;
@@ -176,12 +178,12 @@ tree_if_conversion (struct loop *loop, bool for_vectorizer)
/* Process all statements in this basic block.
Remove conditional expression, if any, and annotate
destination basic block(s) appropriately. */
- for (itr = bsi_start (bb); !bsi_end_p (itr); /* empty */)
+ for (itr = gsi_start_bb (bb); !gsi_end_p (itr); /* empty */)
{
- tree t = bsi_stmt (itr);
+ gimple t = gsi_stmt (itr);
cond = tree_if_convert_stmt (loop, t, cond, &itr);
- if (!bsi_end_p (itr))
- bsi_next (&itr);
+ if (!gsi_end_p (itr))
+ gsi_next (&itr);
}
/* If current bb has only one successor, then consider it as an
@@ -214,41 +216,41 @@ tree_if_conversion (struct loop *loop, bool for_vectorizer)
}
/* if-convert stmt T which is part of LOOP.
- If T is a GIMPLE_MODIFY_STMT than it is converted into conditional modify
+ If T is a GIMPLE_ASSIGN then it is converted into conditional modify
expression using COND. For conditional expressions, add condition in the
destination basic block's predicate list and remove conditional
expression itself. BSI is the iterator used to traverse statements of
loop. It is used here when it is required to delete current statement. */
static tree
-tree_if_convert_stmt (struct loop * loop, tree t, tree cond,
- block_stmt_iterator *bsi)
+tree_if_convert_stmt (struct loop * loop, gimple t, tree cond,
+ gimple_stmt_iterator *gsi)
{
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "------if-convert stmt\n");
- print_generic_stmt (dump_file, t, TDF_SLIM);
+ print_gimple_stmt (dump_file, t, 0, TDF_SLIM);
print_generic_stmt (dump_file, cond, TDF_SLIM);
}
- switch (TREE_CODE (t))
+ switch (gimple_code (t))
{
/* Labels are harmless here. */
- case LABEL_EXPR:
+ case GIMPLE_LABEL:
break;
- case GIMPLE_MODIFY_STMT:
- /* This GIMPLE_MODIFY_STMT is killing previous value of LHS. Appropriate
+ case GIMPLE_ASSIGN:
+ /* This GIMPLE_ASSIGN is killing previous value of LHS. Appropriate
value will be selected by PHI node based on condition. It is possible
that before this transformation, PHI nodes was selecting default
value and now it will use this new value. This is OK because it does
not change validity the program. */
break;
- case COND_EXPR:
+ case GIMPLE_COND:
/* Update destination blocks' predicate list and remove this
condition expression. */
- tree_if_convert_cond_expr (loop, t, cond, bsi);
+ tree_if_convert_cond_stmt (loop, t, cond, gsi);
cond = NULL_TREE;
break;
@@ -258,41 +260,41 @@ tree_if_convert_stmt (struct loop * loop, tree t, tree cond,
return cond;
}
-/* STMT is COND_EXPR. Update two destination's predicate list.
+/* STMT is a GIMPLE_COND. Update two destination's predicate list.
Remove COND_EXPR, if it is not the loop exit condition. Otherwise
- update loop exit condition appropriately. BSI is the iterator
+ update loop exit condition appropriately. GSI is the iterator
used to traverse statement list. STMT is part of loop LOOP. */
static void
-tree_if_convert_cond_expr (struct loop *loop, tree stmt, tree cond,
- block_stmt_iterator *bsi)
+tree_if_convert_cond_stmt (struct loop *loop, gimple stmt, tree cond,
+ gimple_stmt_iterator *gsi)
{
tree c, c2;
edge true_edge, false_edge;
- gcc_assert (TREE_CODE (stmt) == COND_EXPR);
+ gcc_assert (gimple_code (stmt) == GIMPLE_COND);
- c = COND_EXPR_COND (stmt);
+ c = fold_build2 (gimple_cond_code (stmt), boolean_type_node,
+ gimple_cond_lhs (stmt), gimple_cond_rhs (stmt));
- extract_true_false_edges_from_block (bb_for_stmt (stmt),
+ extract_true_false_edges_from_block (gimple_bb (stmt),
&true_edge, &false_edge);
/* Add new condition into destination's predicate list. */
- /* If 'c' is true then TRUE_EDGE is taken. */
- add_to_dst_predicate_list (loop, true_edge, cond,
- unshare_expr (c), bsi);
+ /* If C is true then TRUE_EDGE is taken. */
+ add_to_dst_predicate_list (loop, true_edge, cond, c, gsi);
/* If 'c' is false then FALSE_EDGE is taken. */
c2 = invert_truthvalue (unshare_expr (c));
- add_to_dst_predicate_list (loop, false_edge, cond, c2, bsi);
+ add_to_dst_predicate_list (loop, false_edge, cond, c2, gsi);
/* Now this conditional statement is redundant. Remove it.
But, do not remove exit condition! Update exit condition
using new condition. */
- if (!bb_with_exit_edge_p (loop, bb_for_stmt (stmt)))
+ if (!bb_with_exit_edge_p (loop, gimple_bb (stmt)))
{
- bsi_remove (bsi, true);
+ gsi_remove (gsi, true);
cond = NULL_TREE;
}
return;
@@ -306,22 +308,22 @@ tree_if_convert_cond_expr (struct loop *loop, tree stmt, tree cond,
- Virtual PHI on BB other than header. */
static bool
-if_convertible_phi_p (struct loop *loop, basic_block bb, tree phi)
+if_convertible_phi_p (struct loop *loop, basic_block bb, gimple phi)
{
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "-------------------------\n");
- print_generic_stmt (dump_file, phi, TDF_SLIM);
+ print_gimple_stmt (dump_file, phi, 0, TDF_SLIM);
}
- if (bb != loop->header && PHI_NUM_ARGS (phi) != 2)
+ if (bb != loop->header && gimple_phi_num_args (phi) != 2)
{
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, "More than two phi node args.\n");
return false;
}
- if (!is_gimple_reg (SSA_NAME_VAR (PHI_RESULT (phi))))
+ if (!is_gimple_reg (SSA_NAME_VAR (gimple_phi_result (phi))))
{
imm_use_iterator imm_iter;
use_operand_p use_p;
@@ -332,9 +334,9 @@ if_convertible_phi_p (struct loop *loop, basic_block bb, tree phi)
fprintf (dump_file, "Virtual phi not on loop header.\n");
return false;
}
- FOR_EACH_IMM_USE_FAST (use_p, imm_iter, PHI_RESULT (phi))
+ FOR_EACH_IMM_USE_FAST (use_p, imm_iter, gimple_phi_result (phi))
{
- if (TREE_CODE (USE_STMT (use_p)) == PHI_NODE)
+ if (gimple_code (USE_STMT (use_p)) == GIMPLE_PHI)
{
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, "Difficult to handle this virtual phi.\n");
@@ -346,37 +348,36 @@ if_convertible_phi_p (struct loop *loop, basic_block bb, tree phi)
return true;
}
-/* Return true, if M_EXPR is if-convertible.
- GIMPLE_MODIFY_STMT is not if-convertible if,
+/* Return true, if STMT is if-convertible.
+ GIMPLE_ASSIGN statement is not if-convertible if,
- It is not movable.
- It could trap.
- LHS is not var decl.
- GIMPLE_MODIFY_STMT is part of block BB, which is inside loop LOOP.
-*/
+ GIMPLE_ASSIGN is part of block BB, which is inside loop LOOP. */
static bool
-if_convertible_gimple_modify_stmt_p (struct loop *loop, basic_block bb,
- tree m_expr)
+if_convertible_gimple_assign_stmt_p (struct loop *loop, basic_block bb,
+ gimple stmt)
{
- tree lhs, rhs;
+ tree lhs;
- if (TREE_CODE (m_expr) != GIMPLE_MODIFY_STMT)
+ if (!is_gimple_assign (stmt))
return false;
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "-------------------------\n");
- print_generic_stmt (dump_file, m_expr, TDF_SLIM);
+ print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
}
- lhs = GIMPLE_STMT_OPERAND (m_expr, 0);
- rhs = GIMPLE_STMT_OPERAND (m_expr, 1);
+ lhs = gimple_assign_lhs (stmt);
/* Some of these constrains might be too conservative. */
- if (stmt_ends_bb_p (m_expr) || stmt_ann (m_expr)->has_volatile_ops
+ if (stmt_ends_bb_p (stmt)
+ || gimple_has_volatile_ops (stmt)
|| (TREE_CODE (lhs) == SSA_NAME
&& SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs))
- || TREE_SIDE_EFFECTS (rhs))
+ || gimple_has_side_effects (stmt))
{
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, "stmt not suitable for ifcvt\n");
@@ -385,57 +386,49 @@ if_convertible_gimple_modify_stmt_p (struct loop *loop, basic_block bb,
/* See if it needs speculative loading or not. */
if (bb != loop->header
- && tree_could_trap_p (GIMPLE_STMT_OPERAND (m_expr, 1)))
+ && gimple_assign_rhs_could_trap_p (stmt))
{
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, "tree could trap...\n");
return false;
}
- if (TREE_CODE (GIMPLE_STMT_OPERAND (m_expr, 1)) == CALL_EXPR)
- {
- if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file, "CALL_EXPR \n");
- return false;
- }
-
- if (TREE_CODE (GIMPLE_STMT_OPERAND (m_expr, 0)) != SSA_NAME
+ if (TREE_CODE (lhs) != SSA_NAME
&& bb != loop->header
&& !bb_with_exit_edge_p (loop, bb))
{
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "LHS is not var\n");
- print_generic_stmt (dump_file, m_expr, TDF_SLIM);
+ print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
}
return false;
}
-
return true;
}
/* Return true, iff STMT is if-convertible.
Statement is if-convertible if,
- - It is if-convertible GIMPLE_MODIFY_STMT
- - IT is LABEL_EXPR or COND_EXPR.
+ - It is if-convertible GIMPLE_ASSGIN
+ - It is GIMPLE_LABEL or GIMPLE_COND.
STMT is inside block BB, which is inside loop LOOP. */
static bool
-if_convertible_stmt_p (struct loop *loop, basic_block bb, tree stmt)
+if_convertible_stmt_p (struct loop *loop, basic_block bb, gimple stmt)
{
- switch (TREE_CODE (stmt))
+ switch (gimple_code (stmt))
{
- case LABEL_EXPR:
+ case GIMPLE_LABEL:
break;
- case GIMPLE_MODIFY_STMT:
+ case GIMPLE_ASSIGN:
- if (!if_convertible_gimple_modify_stmt_p (loop, bb, stmt))
+ if (!if_convertible_gimple_assign_stmt_p (loop, bb, stmt))
return false;
break;
- case COND_EXPR:
+ case GIMPLE_COND:
break;
default:
@@ -443,7 +436,7 @@ if_convertible_stmt_p (struct loop *loop, basic_block bb, tree stmt)
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "don't know what to do\n");
- print_generic_stmt (dump_file, stmt, TDF_SLIM);
+ print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
}
return false;
break;
@@ -521,9 +514,8 @@ if_convertible_bb_p (struct loop *loop, basic_block bb, basic_block exit_bb)
static bool
if_convertible_loop_p (struct loop *loop, bool for_vectorizer ATTRIBUTE_UNUSED)
{
- tree phi;
basic_block bb;
- block_stmt_iterator itr;
+ gimple_stmt_iterator itr;
unsigned int i;
edge e;
edge_iterator ei;
@@ -584,22 +576,22 @@ if_convertible_loop_p (struct loop *loop, bool for_vectorizer ATTRIBUTE_UNUSED)
return false;
/* Check statements. */
- for (itr = bsi_start (bb); !bsi_end_p (itr); bsi_next (&itr))
- if (!if_convertible_stmt_p (loop, bb, bsi_stmt (itr)))
+ for (itr = gsi_start_bb (bb); !gsi_end_p (itr); gsi_next (&itr))
+ if (!if_convertible_stmt_p (loop, bb, gsi_stmt (itr)))
return false;
/* ??? Check data dependency for vectorizer. */
/* What about phi nodes ? */
- phi = phi_nodes (bb);
+ itr = gsi_start_phis (bb);
/* Clear aux field of incoming edges to a bb with a phi node. */
- if (phi)
+ if (!gsi_end_p (itr))
FOR_EACH_EDGE (e, ei, bb->preds)
e->aux = NULL;
/* Check statements. */
- for (; phi; phi = PHI_CHAIN (phi))
- if (!if_convertible_phi_p (loop, bb, phi))
+ for (; !gsi_end_p (itr); gsi_next (&itr))
+ if (!if_convertible_phi_p (loop, bb, gsi_stmt (itr)))
return false;
if (bb_with_exit_edge_p (loop, bb))
@@ -637,7 +629,7 @@ add_to_predicate_list (basic_block bb, tree new_cond)
static tree
add_to_dst_predicate_list (struct loop * loop, edge e,
tree prev_cond, tree cond,
- block_stmt_iterator *bsi)
+ gimple_stmt_iterator *gsi)
{
tree new_cond = NULL_TREE;
@@ -649,13 +641,13 @@ add_to_dst_predicate_list (struct loop * loop, edge e,
else
{
tree tmp;
- tree tmp_stmt = NULL_TREE;
+ gimple tmp_stmt = NULL;
- prev_cond = force_gimple_operand_bsi (bsi, unshare_expr (prev_cond),
- true, NULL, true, BSI_SAME_STMT);
+ prev_cond = force_gimple_operand_gsi (gsi, unshare_expr (prev_cond),
+ true, NULL, true, GSI_SAME_STMT);
- cond = force_gimple_operand_bsi (bsi, unshare_expr (cond),
- true, NULL, true, BSI_SAME_STMT);
+ cond = force_gimple_operand_gsi (gsi, unshare_expr (cond),
+ true, NULL, true, GSI_SAME_STMT);
/* Add the condition to aux field of the edge. In case edge
destination is a PHI node, this condition will be ANDed with
@@ -666,8 +658,8 @@ add_to_dst_predicate_list (struct loop * loop, edge e,
tmp = build2 (TRUTH_AND_EXPR, boolean_type_node,
unshare_expr (prev_cond), cond);
tmp_stmt = ifc_temp_var (boolean_type_node, tmp);
- bsi_insert_before (bsi, tmp_stmt, BSI_SAME_STMT);
- new_cond = GIMPLE_STMT_OPERAND (tmp_stmt, 0);
+ gsi_insert_before (gsi, tmp_stmt, GSI_SAME_STMT);
+ new_cond = gimple_assign_lhs (tmp_stmt);
}
add_to_predicate_list (e->dest, new_cond);
return new_cond;
@@ -703,7 +695,7 @@ clean_predicate_lists (struct loop *loop)
static basic_block
find_phi_replacement_condition (struct loop *loop,
basic_block bb, tree *cond,
- block_stmt_iterator *bsi)
+ gimple_stmt_iterator *gsi)
{
edge first_edge, second_edge;
tree tmp_cond;
@@ -788,16 +780,16 @@ find_phi_replacement_condition (struct loop *loop,
condition in vector compare operation. Using gimple value allows
compiler to emit vector compare and select RTL without exposing
compare's result. */
- *cond = force_gimple_operand_bsi (bsi, unshare_expr (*cond),
+ *cond = force_gimple_operand_gsi (gsi, unshare_expr (*cond),
false, NULL_TREE,
- true, BSI_SAME_STMT);
+ true, GSI_SAME_STMT);
if (!is_gimple_reg (*cond) && !is_gimple_condexpr (*cond))
{
- tree new_stmt;
+ gimple new_stmt;
new_stmt = ifc_temp_var (TREE_TYPE (*cond), unshare_expr (*cond));
- bsi_insert_before (bsi, new_stmt, BSI_SAME_STMT);
- *cond = GIMPLE_STMT_OPERAND (new_stmt, 0);
+ gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT);
+ *cond = gimple_assign_lhs (new_stmt);
}
gcc_assert (*cond);
@@ -817,33 +809,33 @@ find_phi_replacement_condition (struct loop *loop,
*/
static void
-replace_phi_with_cond_gimple_modify_stmt (tree phi, tree cond,
+replace_phi_with_cond_gimple_assign_stmt (gimple phi, tree cond,
basic_block true_bb,
- block_stmt_iterator *bsi)
+ gimple_stmt_iterator *gsi)
{
- tree new_stmt;
+ gimple new_stmt;
basic_block bb;
tree rhs;
tree arg_0, arg_1;
- gcc_assert (TREE_CODE (phi) == PHI_NODE);
+ gcc_assert (gimple_code (phi) == GIMPLE_PHI);
/* If this is not filtered earlier, then now it is too late. */
- gcc_assert (PHI_NUM_ARGS (phi) == 2);
+ gcc_assert (gimple_phi_num_args (phi) == 2);
/* Find basic block and initialize iterator. */
- bb = bb_for_stmt (phi);
+ bb = gimple_bb (phi);
/* Use condition that is not TRUTH_NOT_EXPR in conditional modify expr. */
if (EDGE_PRED (bb, 1)->src == true_bb)
{
- arg_0 = PHI_ARG_DEF (phi, 1);
- arg_1 = PHI_ARG_DEF (phi, 0);
+ arg_0 = gimple_phi_arg_def (phi, 1);
+ arg_1 = gimple_phi_arg_def (phi, 0);
}
else
{
- arg_0 = PHI_ARG_DEF (phi, 0);
- arg_1 = PHI_ARG_DEF (phi, 1);
+ arg_0 = gimple_phi_arg_def (phi, 0);
+ arg_1 = gimple_phi_arg_def (phi, 1);
}
/* Build new RHS using selected condition and arguments. */
@@ -851,20 +843,20 @@ replace_phi_with_cond_gimple_modify_stmt (tree phi, tree cond,
unshare_expr (cond), unshare_expr (arg_0),
unshare_expr (arg_1));
- /* Create new MODIFY expression using RHS. */
- new_stmt = build_gimple_modify_stmt (unshare_expr (PHI_RESULT (phi)), rhs);
+ /* Create new GIMPLE_ASSIGN statement using RHS. */
+ new_stmt = gimple_build_assign (unshare_expr (PHI_RESULT (phi)), rhs);
/* Make new statement definition of the original phi result. */
- SSA_NAME_DEF_STMT (PHI_RESULT (phi)) = new_stmt;
+ SSA_NAME_DEF_STMT (gimple_phi_result (phi)) = new_stmt;
/* Insert using iterator. */
- bsi_insert_before (bsi, new_stmt, BSI_SAME_STMT);
+ gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT);
update_stmt (new_stmt);
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "new phi replacement stmt\n");
- print_generic_stmt (dump_file, new_stmt, TDF_SLIM);
+ print_gimple_stmt (dump_file, new_stmt, 0, TDF_SLIM);
}
}
@@ -881,30 +873,31 @@ process_phi_nodes (struct loop *loop)
/* Replace phi nodes with cond. modify expr. */
for (i = 1; i < orig_loop_num_nodes; i++)
{
- tree phi, cond = NULL_TREE;
- block_stmt_iterator bsi;
+ gimple phi;
+ tree cond = NULL_TREE;
+ gimple_stmt_iterator gsi, phi_gsi;
basic_block true_bb = NULL;
bb = ifc_bbs[i];
if (bb == loop->header)
continue;
- phi = phi_nodes (bb);
- bsi = bsi_after_labels (bb);
+ phi_gsi = gsi_start_phis (bb);
+ gsi = gsi_after_labels (bb);
/* BB has two predecessors. Using predecessor's aux field, set
appropriate condition for the PHI node replacement. */
- if (phi)
- true_bb = find_phi_replacement_condition (loop, bb, &cond, &bsi);
+ if (!gsi_end_p (phi_gsi))
+ true_bb = find_phi_replacement_condition (loop, bb, &cond, &gsi);
- while (phi)
+ while (!gsi_end_p (phi_gsi))
{
- tree next = PHI_CHAIN (phi);
- replace_phi_with_cond_gimple_modify_stmt (phi, cond, true_bb, &bsi);
+ phi = gsi_stmt (phi_gsi);
+ replace_phi_with_cond_gimple_assign_stmt (phi, cond, true_bb, &gsi);
release_phi_node (phi);
- phi = next;
+ gsi_next (&phi_gsi);
}
- set_phi_nodes (bb, NULL_TREE);
+ set_phi_nodes (bb, NULL);
}
return;
}
@@ -978,8 +971,8 @@ combine_blocks (struct loop *loop)
merge_target_bb = loop->header;
for (i = 1; i < orig_loop_num_nodes; i++)
{
- block_stmt_iterator bsi;
- tree_stmt_iterator last;
+ gimple_stmt_iterator gsi;
+ gimple_stmt_iterator last;
bb = ifc_bbs[i];
@@ -987,21 +980,21 @@ combine_blocks (struct loop *loop)
continue;
/* Remove labels and make stmts member of loop->header. */
- for (bsi = bsi_start (bb); !bsi_end_p (bsi); )
+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); )
{
- if (TREE_CODE (bsi_stmt (bsi)) == LABEL_EXPR)
- bsi_remove (&bsi, true);
+ if (gimple_code (gsi_stmt (gsi)) == GIMPLE_LABEL)
+ gsi_remove (&gsi, true);
else
{
- set_bb_for_stmt (bsi_stmt (bsi), merge_target_bb);
- bsi_next (&bsi);
+ gimple_set_bb (gsi_stmt (gsi), merge_target_bb);
+ gsi_next (&gsi);
}
}
/* Update stmt list. */
- last = tsi_last (bb_stmt_list (merge_target_bb));
- tsi_link_after (&last, bb_stmt_list (bb), TSI_NEW_STMT);
- set_bb_stmt_list (bb, alloc_stmt_list());
+ last = gsi_last_bb (merge_target_bb);
+ gsi_insert_seq_after (&last, bb_seq (bb), GSI_NEW_STMT);
+ set_bb_seq (bb, NULL);
delete_basic_block (bb);
}
@@ -1015,30 +1008,29 @@ combine_blocks (struct loop *loop)
merge_blocks (loop->header, exit_bb);
}
-/* Make new temp variable of type TYPE. Add GIMPLE_MODIFY_STMT to assign EXP
+/* Make a new temp variable of type TYPE. Add GIMPLE_ASSIGN to assign EXP
to the new variable. */
-static tree
+static gimple
ifc_temp_var (tree type, tree exp)
{
const char *name = "_ifc_";
- tree var, stmt, new_name;
-
- if (is_gimple_reg (exp))
- return exp;
+ tree var, new_name;
+ gimple stmt;
/* Create new temporary variable. */
var = create_tmp_var (type, name);
add_referenced_var (var);
/* Build new statement to assign EXP to new variable. */
- stmt = build_gimple_modify_stmt (var, exp);
+ stmt = gimple_build_assign (var, exp);
/* Get SSA name for the new variable and set make new statement
its definition statement. */
new_name = make_ssa_name (var, stmt);
- GIMPLE_STMT_OPERAND (stmt, 0) = new_name;
+ gimple_assign_set_lhs (stmt, new_name);
SSA_NAME_DEF_STMT (new_name) = stmt;
+ update_stmt (stmt);
return stmt;
}
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index 0f1a8bd1720..511270bffb3 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -56,13 +56,13 @@ along with GCC; see the file COPYING3. If not see
/* I'm not real happy about this, but we need to handle gimple and
non-gimple trees. */
-#include "tree-gimple.h"
+#include "gimple.h"
/* Inlining, Cloning, Versioning, Parallelization
Inlining: a function body is duplicated, but the PARM_DECLs are
remapped into VAR_DECLs, and non-void RETURN_EXPRs become
- GIMPLE_MODIFY_STMTs that store to a dedicated returned-value variable.
+ MODIFY_EXPRs that store to a dedicated returned-value variable.
The duplicated eh_region info of the copy will later be appended
to the info for the caller; the eh_region info in copied throwing
statements and RESX_EXPRs is adjusted accordingly.
@@ -88,14 +88,7 @@ along with GCC; see the file COPYING3. If not see
updated to point into the new body. (Note that the original
callgraph node and edge list will not be altered.)
- See the CALL_EXPR handling case in copy_body_r (). */
-
-/* 0 if we should not perform inlining.
- 1 if we should expand functions calls inline at the tree level.
- 2 if we should consider *all* functions to be inline
- candidates. */
-
-int flag_inline_trees = 0;
+ See the CALL_EXPR handling case in copy_tree_body_r (). */
/* To Do:
@@ -140,6 +133,7 @@ static void add_lexical_block (tree current_block, tree new_block);
static tree copy_decl_to_var (tree, copy_body_data *);
static tree copy_result_decl_to_var (tree, copy_body_data *);
static tree copy_decl_maybe_to_var (tree, copy_body_data *);
+static gimple remap_gimple_stmt (gimple, copy_body_data *);
/* Insert a tree->tree mapping for ID. Despite the name suggests
that the trees should be variables, it is used for more than that. */
@@ -172,6 +166,7 @@ remap_ssa_name (tree name, copy_body_data *id)
/* Do not set DEF_STMT yet as statement is not copied yet. We do that
in copy_bb. */
new = remap_decl (SSA_NAME_VAR (name), id);
+
/* We might've substituted constant or another SSA_NAME for
the variable.
@@ -187,36 +182,37 @@ remap_ssa_name (tree name, copy_body_data *id)
SSA_NAME_OCCURS_IN_ABNORMAL_PHI (new)
= SSA_NAME_OCCURS_IN_ABNORMAL_PHI (name);
TREE_TYPE (new) = TREE_TYPE (SSA_NAME_VAR (new));
- if (IS_EMPTY_STMT (SSA_NAME_DEF_STMT (name)))
+ if (gimple_nop_p (SSA_NAME_DEF_STMT (name)))
{
/* By inlining function having uninitialized variable, we might
extend the lifetime (variable might get reused). This cause
ICE in the case we end up extending lifetime of SSA name across
abnormal edge, but also increase register pressure.
- We simply initialize all uninitialized vars by 0 except for case
- we are inlining to very first BB. We can avoid this for all
- BBs that are not withing strongly connected regions of the CFG,
- but this is bit expensive to test.
- */
- if (id->entry_bb && is_gimple_reg (SSA_NAME_VAR (name))
+ We simply initialize all uninitialized vars by 0 except
+ for case we are inlining to very first BB. We can avoid
+ this for all BBs that are not inside strongly connected
+ regions of the CFG, but this is expensive to test. */
+ if (id->entry_bb
+ && is_gimple_reg (SSA_NAME_VAR (name))
&& TREE_CODE (SSA_NAME_VAR (name)) != PARM_DECL
&& (id->entry_bb != EDGE_SUCC (ENTRY_BLOCK_PTR, 0)->dest
|| EDGE_COUNT (id->entry_bb->preds) != 1))
{
- block_stmt_iterator bsi = bsi_last (id->entry_bb);
- tree init_stmt
- = build_gimple_modify_stmt (new,
- fold_convert (TREE_TYPE (new),
+ gimple_stmt_iterator gsi = gsi_last_bb (id->entry_bb);
+ gimple init_stmt;
+
+ init_stmt = gimple_build_assign (new,
+ fold_convert (TREE_TYPE (new),
integer_zero_node));
- bsi_insert_after (&bsi, init_stmt, BSI_NEW_STMT);
- SSA_NAME_DEF_STMT (new) = init_stmt;
+ gsi_insert_after (&gsi, init_stmt, GSI_NEW_STMT);
SSA_NAME_IS_DEFAULT_DEF (new) = 0;
}
else
{
- SSA_NAME_DEF_STMT (new) = build_empty_stmt ();
- if (gimple_default_def (id->src_cfun, SSA_NAME_VAR (name)) == name)
+ SSA_NAME_DEF_STMT (new) = gimple_build_nop ();
+ if (gimple_default_def (id->src_cfun, SSA_NAME_VAR (name))
+ == name)
set_default_def (SSA_NAME_VAR (new), new);
}
}
@@ -262,15 +258,15 @@ remap_decl (tree decl, copy_body_data *id)
DECL_ORIGINAL_TYPE (t) = remap_type (DECL_ORIGINAL_TYPE (t), id);
/* Remap sizes as necessary. */
- walk_tree (&DECL_SIZE (t), copy_body_r, id, NULL);
- walk_tree (&DECL_SIZE_UNIT (t), copy_body_r, id, NULL);
+ walk_tree (&DECL_SIZE (t), copy_tree_body_r, id, NULL);
+ walk_tree (&DECL_SIZE_UNIT (t), copy_tree_body_r, id, NULL);
/* If fields, do likewise for offset and qualifier. */
if (TREE_CODE (t) == FIELD_DECL)
{
- walk_tree (&DECL_FIELD_OFFSET (t), copy_body_r, id, NULL);
+ walk_tree (&DECL_FIELD_OFFSET (t), copy_tree_body_r, id, NULL);
if (TREE_CODE (DECL_CONTEXT (t)) == QUAL_UNION_TYPE)
- walk_tree (&DECL_QUALIFIER (t), copy_body_r, id, NULL);
+ walk_tree (&DECL_QUALIFIER (t), copy_tree_body_r, id, NULL);
}
if (cfun && gimple_in_ssa_p (cfun)
@@ -285,7 +281,7 @@ remap_decl (tree decl, copy_body_data *id)
/* Watch out RESULT_DECLs whose SSA names map directly
to them. */
if (TREE_CODE (map) == SSA_NAME
- && IS_EMPTY_STMT (SSA_NAME_DEF_STMT (map)))
+ && gimple_nop_p (SSA_NAME_DEF_STMT (map)))
set_default_def (t, map);
}
add_referenced_var (t);
@@ -357,16 +353,16 @@ remap_type_1 (tree type, copy_body_data *id)
case BOOLEAN_TYPE:
t = TYPE_MIN_VALUE (new);
if (t && TREE_CODE (t) != INTEGER_CST)
- walk_tree (&TYPE_MIN_VALUE (new), copy_body_r, id, NULL);
+ walk_tree (&TYPE_MIN_VALUE (new), copy_tree_body_r, id, NULL);
t = TYPE_MAX_VALUE (new);
if (t && TREE_CODE (t) != INTEGER_CST)
- walk_tree (&TYPE_MAX_VALUE (new), copy_body_r, id, NULL);
+ walk_tree (&TYPE_MAX_VALUE (new), copy_tree_body_r, id, NULL);
return new;
case FUNCTION_TYPE:
TREE_TYPE (new) = remap_type (TREE_TYPE (new), id);
- walk_tree (&TYPE_ARG_TYPES (new), copy_body_r, id, NULL);
+ walk_tree (&TYPE_ARG_TYPES (new), copy_tree_body_r, id, NULL);
return new;
case ARRAY_TYPE:
@@ -397,8 +393,8 @@ remap_type_1 (tree type, copy_body_data *id)
gcc_unreachable ();
}
- walk_tree (&TYPE_SIZE (new), copy_body_r, id, NULL);
- walk_tree (&TYPE_SIZE_UNIT (new), copy_body_r, id, NULL);
+ walk_tree (&TYPE_SIZE (new), copy_tree_body_r, id, NULL);
+ walk_tree (&TYPE_SIZE_UNIT (new), copy_tree_body_r, id, NULL);
return new;
}
@@ -442,9 +438,10 @@ remap_decls (tree decls, copy_body_data *id)
{
tree new_var;
- /* We can not chain the local static declarations into the local_decls
- as we can't duplicate them or break one decl rule. Go ahead and link
- them into local_decls. */
+ /* We cannot chain the local static declarations into the local_decls
+ as we can't duplicate them or break one decl rule. Go ahead
+ and link them into local_decls. */
+
if (!auto_var_in_fn_p (old_var, id->src_fn)
&& !DECL_EXTERNAL (old_var))
{
@@ -456,7 +453,7 @@ remap_decls (tree decls, copy_body_data *id)
/* Remap the variable. */
new_var = remap_decl (old_var, id);
- /* If we didn't remap this variable, so we can't mess with its
+ /* If we didn't remap this variable, we can't mess with its
TREE_CHAIN. If we remapped this variable to the return slot, it's
already declared somewhere else, so don't declare it here. */
if (!new_var || new_var == id->retvar)
@@ -552,11 +549,234 @@ copy_bind_expr (tree *tp, int *walk_subtrees, copy_body_data *id)
BIND_EXPR_VARS (*tp) = remap_decls (BIND_EXPR_VARS (*tp), id);
}
-/* Called from copy_body_id via walk_tree. DATA is really an
+
+/* Create a new gimple_seq by remapping all the statements in BODY
+ using the inlining information in ID. */
+
+gimple_seq
+remap_gimple_seq (gimple_seq body, copy_body_data *id)
+{
+ gimple_stmt_iterator si;
+ gimple_seq new_body = NULL;
+
+ for (si = gsi_start (body); !gsi_end_p (si); gsi_next (&si))
+ {
+ gimple new_stmt = remap_gimple_stmt (gsi_stmt (si), id);
+ gimple_seq_add_stmt (&new_body, new_stmt);
+ }
+
+ return new_body;
+}
+
+
+/* Copy a GIMPLE_BIND statement STMT, remapping all the symbols in its
+ block using the mapping information in ID. */
+
+static gimple
+copy_gimple_bind (gimple stmt, copy_body_data *id)
+{
+ gimple new_bind;
+ tree new_block, new_vars;
+ gimple_seq body, new_body;
+
+ /* Copy the statement. Note that we purposely don't use copy_stmt
+ here because we need to remap statements as we copy. */
+ body = gimple_bind_body (stmt);
+ new_body = remap_gimple_seq (body, id);
+
+ new_block = gimple_bind_block (stmt);
+ if (new_block)
+ remap_block (&new_block, id);
+
+ /* This will remap a lot of the same decls again, but this should be
+ harmless. */
+ new_vars = gimple_bind_vars (stmt);
+ if (new_vars)
+ new_vars = remap_decls (new_vars, id);
+
+ new_bind = gimple_build_bind (new_vars, new_body, new_block);
+
+ return new_bind;
+}
+
+
+/* Remap the GIMPLE operand pointed to by *TP. DATA is really a
+ 'struct walk_stmt_info *'. DATA->INFO is a 'copy_body_data *'.
+ WALK_SUBTREES is used to indicate walk_gimple_op whether to keep
+ recursing into the children nodes of *TP. */
+
+static tree
+remap_gimple_op_r (tree *tp, int *walk_subtrees, void *data)
+{
+ struct walk_stmt_info *wi_p = (struct walk_stmt_info *) data;
+ copy_body_data *id = (copy_body_data *) wi_p->info;
+ tree fn = id->src_fn;
+
+ if (TREE_CODE (*tp) == SSA_NAME)
+ {
+ *tp = remap_ssa_name (*tp, id);
+ *walk_subtrees = 0;
+ return NULL;
+ }
+ else if (auto_var_in_fn_p (*tp, fn))
+ {
+ /* Local variables and labels need to be replaced by equivalent
+ variables. We don't want to copy static variables; there's
+ only one of those, no matter how many times we inline the
+ containing function. Similarly for globals from an outer
+ function. */
+ tree new_decl;
+
+ /* Remap the declaration. */
+ new_decl = remap_decl (*tp, id);
+ gcc_assert (new_decl);
+ /* Replace this variable with the copy. */
+ STRIP_TYPE_NOPS (new_decl);
+ *tp = new_decl;
+ *walk_subtrees = 0;
+ }
+ else if (TREE_CODE (*tp) == STATEMENT_LIST)
+ gcc_unreachable ();
+ else if (TREE_CODE (*tp) == SAVE_EXPR)
+ gcc_unreachable ();
+ else if (TREE_CODE (*tp) == LABEL_DECL
+ && (!DECL_CONTEXT (*tp)
+ || decl_function_context (*tp) == id->src_fn))
+ /* These may need to be remapped for EH handling. */
+ *tp = remap_decl (*tp, id);
+ else if (TYPE_P (*tp))
+ /* Types may need remapping as well. */
+ *tp = remap_type (*tp, id);
+ else if (CONSTANT_CLASS_P (*tp))
+ {
+ /* If this is a constant, we have to copy the node iff the type
+ will be remapped. copy_tree_r will not copy a constant. */
+ tree new_type = remap_type (TREE_TYPE (*tp), id);
+
+ if (new_type == TREE_TYPE (*tp))
+ *walk_subtrees = 0;
+
+ else if (TREE_CODE (*tp) == INTEGER_CST)
+ *tp = build_int_cst_wide (new_type, TREE_INT_CST_LOW (*tp),
+ TREE_INT_CST_HIGH (*tp));
+ else
+ {
+ *tp = copy_node (*tp);
+ TREE_TYPE (*tp) = new_type;
+ }
+ }
+ else
+ {
+ /* Otherwise, just copy the node. Note that copy_tree_r already
+ knows not to copy VAR_DECLs, etc., so this is safe. */
+ if (TREE_CODE (*tp) == INDIRECT_REF)
+ {
+ /* Get rid of *& from inline substitutions that can happen when a
+ pointer argument is an ADDR_EXPR. */
+ tree decl = TREE_OPERAND (*tp, 0);
+ tree *n;
+
+ n = (tree *) pointer_map_contains (id->decl_map, decl);
+ if (n)
+ {
+ tree type, new, old;
+
+ /* If we happen to get an ADDR_EXPR in n->value, strip
+ it manually here as we'll eventually get ADDR_EXPRs
+ which lie about their types pointed to. In this case
+ build_fold_indirect_ref wouldn't strip the
+ INDIRECT_REF, but we absolutely rely on that. As
+ fold_indirect_ref does other useful transformations,
+ try that first, though. */
+ type = TREE_TYPE (TREE_TYPE (*n));
+ new = unshare_expr (*n);
+ old = *tp;
+ *tp = gimple_fold_indirect_ref (new);
+ if (!*tp)
+ {
+ if (TREE_CODE (new) == ADDR_EXPR)
+ {
+ *tp = fold_indirect_ref_1 (type, new);
+ /* ??? We should either assert here or build
+ a VIEW_CONVERT_EXPR instead of blindly leaking
+ incompatible types to our IL. */
+ if (! *tp)
+ *tp = TREE_OPERAND (new, 0);
+ }
+ else
+ {
+ *tp = build1 (INDIRECT_REF, type, new);
+ TREE_THIS_VOLATILE (*tp) = TREE_THIS_VOLATILE (old);
+ }
+ }
+ *walk_subtrees = 0;
+ return NULL;
+ }
+ }
+
+ /* Here is the "usual case". Copy this tree node, and then
+ tweak some special cases. */
+ copy_tree_r (tp, walk_subtrees, NULL);
+
+ /* Global variables we haven't seen yet need to go into referenced
+ vars. If not referenced from types only. */
+ if (gimple_in_ssa_p (cfun)
+ && TREE_CODE (*tp) == VAR_DECL
+ && id->remapping_type_depth == 0)
+ add_referenced_var (*tp);
+
+ /* We should never have TREE_BLOCK set on non-statements. */
+ if (EXPR_P (*tp))
+ gcc_assert (!TREE_BLOCK (*tp));
+
+ if (TREE_CODE (*tp) != OMP_CLAUSE)
+ TREE_TYPE (*tp) = remap_type (TREE_TYPE (*tp), id);
+
+ if (TREE_CODE (*tp) == TARGET_EXPR && TREE_OPERAND (*tp, 3))
+ {
+ /* The copied TARGET_EXPR has never been expanded, even if the
+ original node was expanded already. */
+ TREE_OPERAND (*tp, 1) = TREE_OPERAND (*tp, 3);
+ TREE_OPERAND (*tp, 3) = NULL_TREE;
+ }
+ else if (TREE_CODE (*tp) == ADDR_EXPR)
+ {
+ /* Variable substitution need not be simple. In particular,
+ the INDIRECT_REF substitution above. Make sure that
+ TREE_CONSTANT and friends are up-to-date. But make sure
+ to not improperly set TREE_BLOCK on some sub-expressions. */
+ int invariant = is_gimple_min_invariant (*tp);
+ tree block = id->block;
+ id->block = NULL_TREE;
+ walk_tree (&TREE_OPERAND (*tp, 0), copy_tree_body_r, id, NULL);
+ id->block = block;
+
+ /* Handle the case where we substituted an INDIRECT_REF
+ into the operand of the ADDR_EXPR. */
+ if (TREE_CODE (TREE_OPERAND (*tp, 0)) == INDIRECT_REF)
+ *tp = TREE_OPERAND (TREE_OPERAND (*tp, 0), 0);
+ else
+ recompute_tree_invariant_for_addr_expr (*tp);
+
+ /* If this used to be invariant, but is not any longer,
+ then regimplification is probably needed. */
+ if (invariant && !is_gimple_min_invariant (*tp))
+ id->regimplify = true;
+
+ *walk_subtrees = 0;
+ }
+ }
+
+ /* Keep iterating. */
+ return NULL_TREE;
+}
+
+
+/* Called from copy_body_id via walk_tree. DATA is really a
`copy_body_data *'. */
tree
-copy_body_r (tree *tp, int *walk_subtrees, void *data)
+copy_tree_body_r (tree *tp, int *walk_subtrees, void *data)
{
copy_body_data *id = (copy_body_data *) data;
tree fn = id->src_fn;
@@ -569,7 +789,7 @@ copy_body_r (tree *tp, int *walk_subtrees, void *data)
duplicated and/or tweaked. */
/* When requested, RETURN_EXPRs should be transformed to just the
- contained GIMPLE_MODIFY_STMT. The branch semantics of the return will
+ contained MODIFY_EXPR. The branch semantics of the return will
be handled elsewhere by manipulating the CFG rather than a statement. */
if (TREE_CODE (*tp) == RETURN_EXPR && id->transform_return_to_modify)
{
@@ -580,10 +800,10 @@ copy_body_r (tree *tp, int *walk_subtrees, void *data)
If the "assignment" is just the result decl, the result
decl has already been set (e.g. a recent "foo (&result_decl,
...)"); just toss the entire RETURN_EXPR. */
- if (assignment && TREE_CODE (assignment) == GIMPLE_MODIFY_STMT)
+ if (assignment && TREE_CODE (assignment) == MODIFY_EXPR)
{
/* Replace the RETURN_EXPR with (a copy of) the
- GIMPLE_MODIFY_STMT hanging underneath. */
+ MODIFY_EXPR hanging underneath. */
*tp = copy_node (assignment);
}
else /* Else the RETURN_EXPR returns no value. */
@@ -656,14 +876,14 @@ copy_body_r (tree *tp, int *walk_subtrees, void *data)
/* Here we handle trees that are not completely rewritten.
First we detect some inlining-induced bogosities for
discarding. */
- if (TREE_CODE (*tp) == GIMPLE_MODIFY_STMT
- && GIMPLE_STMT_OPERAND (*tp, 0) == GIMPLE_STMT_OPERAND (*tp, 1)
- && (auto_var_in_fn_p (GIMPLE_STMT_OPERAND (*tp, 0), fn)))
+ if (TREE_CODE (*tp) == MODIFY_EXPR
+ && TREE_OPERAND (*tp, 0) == TREE_OPERAND (*tp, 1)
+ && (auto_var_in_fn_p (TREE_OPERAND (*tp, 0), fn)))
{
/* Some assignments VAR = VAR; don't generate any rtl code
and thus don't count as variable modification. Avoid
keeping bogosities like 0 = 0. */
- tree decl = GIMPLE_STMT_OPERAND (*tp, 0), value;
+ tree decl = TREE_OPERAND (*tp, 0), value;
tree *n;
n = (tree *) pointer_map_contains (id->decl_map, decl);
@@ -674,7 +894,7 @@ copy_body_r (tree *tp, int *walk_subtrees, void *data)
if (TREE_CONSTANT (value) || TREE_READONLY (value))
{
*tp = build_empty_stmt ();
- return copy_body_r (tp, walk_subtrees, data);
+ return copy_tree_body_r (tp, walk_subtrees, data);
}
}
}
@@ -729,14 +949,15 @@ copy_body_r (tree *tp, int *walk_subtrees, void *data)
/* Global variables we haven't seen yet needs to go into referenced
vars. If not referenced from types only. */
- if (gimple_in_ssa_p (cfun) && TREE_CODE (*tp) == VAR_DECL
+ if (gimple_in_ssa_p (cfun)
+ && TREE_CODE (*tp) == VAR_DECL
&& id->remapping_type_depth == 0)
add_referenced_var (*tp);
/* If EXPR has block defined, map it to newly constructed block.
When inlining we want EXPRs without block appear in the block
of function call. */
- if (EXPR_P (*tp) || GIMPLE_STMT_P (*tp))
+ if (EXPR_P (*tp))
{
new_block = id->block;
if (TREE_BLOCK (*tp))
@@ -752,11 +973,11 @@ copy_body_r (tree *tp, int *walk_subtrees, void *data)
if (TREE_CODE (*tp) == RESX_EXPR && id->eh_region_offset)
TREE_OPERAND (*tp, 0) =
- build_int_cst
- (NULL_TREE,
- id->eh_region_offset + TREE_INT_CST_LOW (TREE_OPERAND (*tp, 0)));
+ build_int_cst (NULL_TREE,
+ id->eh_region_offset
+ + TREE_INT_CST_LOW (TREE_OPERAND (*tp, 0)));
- if (!GIMPLE_TUPLE_P (*tp) && TREE_CODE (*tp) != OMP_CLAUSE)
+ if (TREE_CODE (*tp) != OMP_CLAUSE)
TREE_TYPE (*tp) = remap_type (TREE_TYPE (*tp), id);
/* The copied TARGET_EXPR has never been expanded, even if the
@@ -773,17 +994,20 @@ copy_body_r (tree *tp, int *walk_subtrees, void *data)
else if (TREE_CODE (*tp) == ADDR_EXPR)
{
int invariant = is_gimple_min_invariant (*tp);
- walk_tree (&TREE_OPERAND (*tp, 0), copy_body_r, id, NULL);
+ walk_tree (&TREE_OPERAND (*tp, 0), copy_tree_body_r, id, NULL);
+
/* Handle the case where we substituted an INDIRECT_REF
into the operand of the ADDR_EXPR. */
if (TREE_CODE (TREE_OPERAND (*tp, 0)) == INDIRECT_REF)
*tp = TREE_OPERAND (TREE_OPERAND (*tp, 0), 0);
else
recompute_tree_invariant_for_addr_expr (*tp);
+
/* If this used to be invariant, but is not any longer,
then regimplification is probably needed. */
if (invariant && !is_gimple_min_invariant (*tp))
id->regimplify = true;
+
*walk_subtrees = 0;
}
}
@@ -792,6 +1016,209 @@ copy_body_r (tree *tp, int *walk_subtrees, void *data)
return NULL_TREE;
}
+
+/* Helper for copy_bb. Remap statement STMT using the inlining
+ information in ID. Return the new statement copy. */
+
+static gimple
+remap_gimple_stmt (gimple stmt, copy_body_data *id)
+{
+ gimple copy = NULL;
+ struct walk_stmt_info wi;
+ tree new_block;
+
+ /* Begin by recognizing trees that we'll completely rewrite for the
+ inlining context. Our output for these trees is completely
+ different from out input (e.g. RETURN_EXPR is deleted, and morphs
+ into an edge). Further down, we'll handle trees that get
+ duplicated and/or tweaked. */
+
+ /* When requested, GIMPLE_RETURNs should be transformed to just the
+ contained GIMPLE_ASSIGN. The branch semantics of the return will
+ be handled elsewhere by manipulating the CFG rather than the
+ statement. */
+ if (gimple_code (stmt) == GIMPLE_RETURN && id->transform_return_to_modify)
+ {
+ tree retval = gimple_return_retval (stmt);
+
+ /* If we're returning something, just turn that into an
+ assignment into the equivalent of the original RESULT_DECL.
+ If RETVAL is just the result decl, the result decl has
+ already been set (e.g. a recent "foo (&result_decl, ...)");
+ just toss the entire GIMPLE_RETURN. */
+ if (retval && TREE_CODE (retval) != RESULT_DECL)
+ copy = gimple_build_assign (id->retvar, retval);
+ else
+ return gimple_build_nop ();
+ }
+ else if (gimple_has_substatements (stmt))
+ {
+ gimple_seq s1, s2;
+
+ /* When cloning bodies from the C++ front end, we will be handed bodies
+ in High GIMPLE form. Handle here all the High GIMPLE statements that
+ have embedded statements. */
+ switch (gimple_code (stmt))
+ {
+ case GIMPLE_BIND:
+ copy = copy_gimple_bind (stmt, id);
+ break;
+
+ case GIMPLE_CATCH:
+ s1 = remap_gimple_seq (gimple_catch_handler (stmt), id);
+ copy = gimple_build_catch (gimple_catch_types (stmt), s1);
+ break;
+
+ case GIMPLE_EH_FILTER:
+ s1 = remap_gimple_seq (gimple_eh_filter_failure (stmt), id);
+ copy = gimple_build_eh_filter (gimple_eh_filter_types (stmt), s1);
+ break;
+
+ case GIMPLE_TRY:
+ s1 = remap_gimple_seq (gimple_try_eval (stmt), id);
+ s2 = remap_gimple_seq (gimple_try_cleanup (stmt), id);
+ copy = gimple_build_try (s1, s2, gimple_try_kind (stmt));
+ break;
+
+ case GIMPLE_WITH_CLEANUP_EXPR:
+ s1 = remap_gimple_seq (gimple_wce_cleanup (stmt), id);
+ copy = gimple_build_wce (s1);
+ break;
+
+ case GIMPLE_OMP_PARALLEL:
+ s1 = remap_gimple_seq (gimple_omp_body (stmt), id);
+ copy = gimple_build_omp_parallel
+ (s1,
+ gimple_omp_parallel_clauses (stmt),
+ gimple_omp_parallel_child_fn (stmt),
+ gimple_omp_parallel_data_arg (stmt));
+ break;
+
+ case GIMPLE_OMP_TASK:
+ s1 = remap_gimple_seq (gimple_omp_body (stmt), id);
+ copy = gimple_build_omp_task
+ (s1,
+ gimple_omp_task_clauses (stmt),
+ gimple_omp_task_child_fn (stmt),
+ gimple_omp_task_data_arg (stmt),
+ gimple_omp_task_copy_fn (stmt),
+ gimple_omp_task_arg_size (stmt),
+ gimple_omp_task_arg_align (stmt));
+ break;
+
+ case GIMPLE_OMP_FOR:
+ s1 = remap_gimple_seq (gimple_omp_body (stmt), id);
+ s2 = remap_gimple_seq (gimple_omp_for_pre_body (stmt), id);
+ copy = gimple_build_omp_for (s1, gimple_omp_for_clauses (stmt),
+ gimple_omp_for_collapse (stmt), s2);
+ {
+ size_t i;
+ for (i = 0; i < gimple_omp_for_collapse (stmt); i++)
+ {
+ gimple_omp_for_set_index (copy, i,
+ gimple_omp_for_index (stmt, i));
+ gimple_omp_for_set_initial (copy, i,
+ gimple_omp_for_initial (stmt, i));
+ gimple_omp_for_set_final (copy, i,
+ gimple_omp_for_final (stmt, i));
+ gimple_omp_for_set_incr (copy, i,
+ gimple_omp_for_incr (stmt, i));
+ gimple_omp_for_set_cond (copy, i,
+ gimple_omp_for_cond (stmt, i));
+ }
+ }
+ break;
+
+ case GIMPLE_OMP_MASTER:
+ s1 = remap_gimple_seq (gimple_omp_body (stmt), id);
+ copy = gimple_build_omp_master (s1);
+ break;
+
+ case GIMPLE_OMP_ORDERED:
+ s1 = remap_gimple_seq (gimple_omp_body (stmt), id);
+ copy = gimple_build_omp_ordered (s1);
+ break;
+
+ case GIMPLE_OMP_SECTION:
+ s1 = remap_gimple_seq (gimple_omp_body (stmt), id);
+ copy = gimple_build_omp_section (s1);
+ break;
+
+ case GIMPLE_OMP_SECTIONS:
+ s1 = remap_gimple_seq (gimple_omp_body (stmt), id);
+ copy = gimple_build_omp_sections
+ (s1, gimple_omp_sections_clauses (stmt));
+ break;
+
+ case GIMPLE_OMP_SINGLE:
+ s1 = remap_gimple_seq (gimple_omp_body (stmt), id);
+ copy = gimple_build_omp_single
+ (s1, gimple_omp_single_clauses (stmt));
+ break;
+
+ default:
+ gcc_unreachable ();
+ }
+ }
+ else
+ {
+ if (gimple_assign_copy_p (stmt)
+ && gimple_assign_lhs (stmt) == gimple_assign_rhs1 (stmt)
+ && auto_var_in_fn_p (gimple_assign_lhs (stmt), id->src_fn))
+ {
+ /* Here we handle statements that are not completely rewritten.
+ First we detect some inlining-induced bogosities for
+ discarding. */
+
+ /* Some assignments VAR = VAR; don't generate any rtl code
+ and thus don't count as variable modification. Avoid
+ keeping bogosities like 0 = 0. */
+ tree decl = gimple_assign_lhs (stmt), value;
+ tree *n;
+
+ n = (tree *) pointer_map_contains (id->decl_map, decl);
+ if (n)
+ {
+ value = *n;
+ STRIP_TYPE_NOPS (value);
+ if (TREE_CONSTANT (value) || TREE_READONLY (value))
+ return gimple_build_nop ();
+ }
+ }
+
+ /* Create a new deep copy of the statement. */
+ copy = gimple_copy (stmt);
+ }
+
+ /* If STMT has a block defined, map it to the newly constructed
+ block. When inlining we want statements without a block to
+ appear in the block of the function call. */
+ new_block = id->block;
+ if (gimple_block (copy))
+ {
+ tree *n;
+ n = (tree *) pointer_map_contains (id->decl_map, gimple_block (copy));
+ gcc_assert (n);
+ new_block = *n;
+ }
+
+ gimple_set_block (copy, new_block);
+
+ /* Remap all the operands in COPY. */
+ memset (&wi, 0, sizeof (wi));
+ wi.info = id;
+ walk_gimple_op (copy, remap_gimple_op_r, &wi);
+
+ /* We have to handle EH region remapping of GIMPLE_RESX specially because
+ the region number is not an operand. */
+ if (gimple_code (stmt) == GIMPLE_RESX && id->eh_region_offset)
+ {
+ gimple_resx_set_region (copy, gimple_resx_region (stmt) + id->eh_region_offset);
+ }
+ return copy;
+}
+
+
/* Copy basic block, scale profile accordingly. Edges will be taken care of
later */
@@ -799,8 +1226,9 @@ static basic_block
copy_bb (copy_body_data *id, basic_block bb, int frequency_scale,
gcov_type count_scale)
{
- block_stmt_iterator bsi, copy_bsi;
+ gimple_stmt_iterator gsi, copy_gsi;
basic_block copy_basic_block;
+ tree decl;
/* create_basic_block() will append every new block to
basic_block_info automatically. */
@@ -808,237 +1236,227 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale,
(basic_block) bb->prev_bb->aux);
copy_basic_block->count = bb->count * count_scale / REG_BR_PROB_BASE;
- /* We are going to rebuild frequencies from scratch. These values have just
- small importance to drive canonicalize_loop_headers. */
+ /* We are going to rebuild frequencies from scratch. These values
+ have just small importance to drive canonicalize_loop_headers. */
copy_basic_block->frequency = ((gcov_type)bb->frequency
- * frequency_scale / REG_BR_PROB_BASE);
+ * frequency_scale / REG_BR_PROB_BASE);
+
if (copy_basic_block->frequency > BB_FREQ_MAX)
copy_basic_block->frequency = BB_FREQ_MAX;
- copy_bsi = bsi_start (copy_basic_block);
- for (bsi = bsi_start (bb);
- !bsi_end_p (bsi); bsi_next (&bsi))
+ copy_gsi = gsi_start_bb (copy_basic_block);
+
+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
- tree stmt = bsi_stmt (bsi);
- tree orig_stmt = stmt;
+ gimple stmt = gsi_stmt (gsi);
+ gimple orig_stmt = stmt;
id->regimplify = false;
- walk_tree (&stmt, copy_body_r, id, NULL);
-
- /* RETURN_EXPR might be removed,
- this is signalled by making stmt pointer NULL. */
- if (stmt)
+ stmt = remap_gimple_stmt (stmt, id);
+ if (gimple_nop_p (stmt))
+ continue;
+
+ gimple_duplicate_stmt_histograms (cfun, stmt, id->src_cfun, orig_stmt);
+
+ /* With return slot optimization we can end up with
+ non-gimple (foo *)&this->m, fix that here. */
+ if ((is_gimple_assign (stmt)
+ && gimple_assign_rhs_code (stmt) == NOP_EXPR
+ && !is_gimple_val (gimple_assign_rhs1 (stmt)))
+ || id->regimplify)
{
- tree call, decl;
-
- gimple_duplicate_stmt_histograms (cfun, stmt, id->src_cfun, orig_stmt);
+ tree new_rhs;
+ new_rhs = force_gimple_operand_gsi (&copy_gsi,
+ gimple_assign_rhs1 (stmt),
+ true, NULL, true, GSI_SAME_STMT);
+ gimple_assign_set_rhs1 (stmt, new_rhs);
+ }
+ else if (id->regimplify)
+ gimple_regimplify_operands (stmt, &copy_gsi);
- /* With return slot optimization we can end up with
- non-gimple (foo *)&this->m, fix that here. */
- if ((TREE_CODE (stmt) == GIMPLE_MODIFY_STMT
- && TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 1)) == NOP_EXPR
- && !is_gimple_val (TREE_OPERAND (GIMPLE_STMT_OPERAND (stmt, 1), 0)))
- || id->regimplify)
- gimplify_stmt (&stmt);
+ gsi_insert_after (&copy_gsi, stmt, GSI_NEW_STMT);
- bsi_insert_after (&copy_bsi, stmt, BSI_NEW_STMT);
+ /* Process the new statement. The call to gimple_regimplify_operands
+ possibly turned the statement into multiple statements, we
+ need to process all of them. */
+ while (!gsi_end_p (copy_gsi))
+ {
+ if (is_gimple_call (stmt)
+ && gimple_call_va_arg_pack_p (stmt)
+ && id->gimple_call)
+ {
+ /* __builtin_va_arg_pack () should be replaced by
+ all arguments corresponding to ... in the caller. */
+ tree p;
+ gimple new_call;
+ VEC(tree, heap) *argarray;
+ size_t nargs = gimple_call_num_args (id->gimple_call);
+ size_t n;
+
+ for (p = DECL_ARGUMENTS (id->src_fn); p; p = TREE_CHAIN (p))
+ nargs--;
+
+ /* Create the new array of arguments. */
+ n = nargs + gimple_call_num_args (stmt);
+ argarray = VEC_alloc (tree, heap, n);
+ VEC_safe_grow (tree, heap, argarray, n);
+
+ /* Copy all the arguments before '...' */
+ memcpy (VEC_address (tree, argarray),
+ gimple_call_arg_ptr (stmt, 0),
+ gimple_call_num_args (stmt) * sizeof (tree));
+
+ /* Append the arguments passed in '...' */
+ memcpy (VEC_address(tree, argarray) + gimple_call_num_args (stmt),
+ gimple_call_arg_ptr (id->gimple_call, 0)
+ + (gimple_call_num_args (id->gimple_call) - nargs),
+ nargs * sizeof (tree));
+
+ new_call = gimple_build_call_vec (gimple_call_fn (stmt),
+ argarray);
+
+ VEC_free (tree, heap, argarray);
+
+ /* Copy all GIMPLE_CALL flags, location and block, except
+ GF_CALL_VA_ARG_PACK. */
+ gimple_call_copy_flags (new_call, stmt);
+ gimple_call_set_va_arg_pack (new_call, false);
+ gimple_set_location (new_call, gimple_location (stmt));
+ gimple_set_block (new_call, gimple_block (stmt));
+ gimple_call_set_lhs (new_call, gimple_call_lhs (stmt));
+
+ gsi_replace (&copy_gsi, new_call, false);
+ stmt = new_call;
+ }
+ else if (is_gimple_call (stmt)
+ && id->gimple_call
+ && (decl = gimple_call_fndecl (stmt))
+ && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL
+ && DECL_FUNCTION_CODE (decl) == BUILT_IN_VA_ARG_PACK_LEN)
+ {
+ /* __builtin_va_arg_pack_len () should be replaced by
+ the number of anonymous arguments. */
+ size_t nargs = gimple_call_num_args (id->gimple_call);
+ tree count, p;
+ gimple new_stmt;
+
+ for (p = DECL_ARGUMENTS (id->src_fn); p; p = TREE_CHAIN (p))
+ nargs--;
+
+ count = build_int_cst (integer_type_node, nargs);
+ new_stmt = gimple_build_assign (gimple_call_lhs (stmt), count);
+ gsi_replace (&copy_gsi, new_stmt, false);
+ stmt = new_stmt;
+ }
- /* Process new statement. gimplify_stmt possibly turned statement
- into multiple statements, we need to process all of them. */
- while (!bsi_end_p (copy_bsi))
+ /* Statements produced by inlining can be unfolded, especially
+ when we constant propagated some operands. We can't fold
+ them right now for two reasons:
+ 1) folding require SSA_NAME_DEF_STMTs to be correct
+ 2) we can't change function calls to builtins.
+ So we just mark statement for later folding. We mark
+ all new statements, instead just statements that has changed
+ by some nontrivial substitution so even statements made
+ foldable indirectly are updated. If this turns out to be
+ expensive, copy_body can be told to watch for nontrivial
+ changes. */
+ if (id->statements_to_fold)
+ pointer_set_insert (id->statements_to_fold, stmt);
+
+ /* We're duplicating a CALL_EXPR. Find any corresponding
+ callgraph edges and update or duplicate them. */
+ if (is_gimple_call (stmt))
{
- tree *stmtp = bsi_stmt_ptr (copy_bsi);
- tree stmt = *stmtp;
- call = get_call_expr_in (stmt);
+ struct cgraph_node *node;
+ struct cgraph_edge *edge;
- if (call && CALL_EXPR_VA_ARG_PACK (call) && id->call_expr)
+ switch (id->transform_call_graph_edges)
{
- /* __builtin_va_arg_pack () should be replaced by
- all arguments corresponding to ... in the caller. */
- tree p, *argarray, new_call, *call_ptr;
- int nargs = call_expr_nargs (id->call_expr);
-
- for (p = DECL_ARGUMENTS (id->src_fn); p; p = TREE_CHAIN (p))
- nargs--;
-
- argarray = (tree *) alloca ((nargs + call_expr_nargs (call))
- * sizeof (tree));
-
- memcpy (argarray, CALL_EXPR_ARGP (call),
- call_expr_nargs (call) * sizeof (*argarray));
- memcpy (argarray + call_expr_nargs (call),
- CALL_EXPR_ARGP (id->call_expr)
- + (call_expr_nargs (id->call_expr) - nargs),
- nargs * sizeof (*argarray));
-
- new_call = build_call_array (TREE_TYPE (call),
- CALL_EXPR_FN (call),
- nargs + call_expr_nargs (call),
- argarray);
- /* Copy all CALL_EXPR flags, locus and block, except
- CALL_EXPR_VA_ARG_PACK flag. */
- CALL_EXPR_STATIC_CHAIN (new_call)
- = CALL_EXPR_STATIC_CHAIN (call);
- CALL_EXPR_TAILCALL (new_call) = CALL_EXPR_TAILCALL (call);
- CALL_EXPR_RETURN_SLOT_OPT (new_call)
- = CALL_EXPR_RETURN_SLOT_OPT (call);
- CALL_FROM_THUNK_P (new_call) = CALL_FROM_THUNK_P (call);
- CALL_CANNOT_INLINE_P (new_call)
- = CALL_CANNOT_INLINE_P (call);
- TREE_NOTHROW (new_call) = TREE_NOTHROW (call);
- SET_EXPR_LOCUS (new_call, EXPR_LOCUS (call));
- TREE_BLOCK (new_call) = TREE_BLOCK (call);
-
- call_ptr = stmtp;
- if (TREE_CODE (*call_ptr) == GIMPLE_MODIFY_STMT)
- call_ptr = &GIMPLE_STMT_OPERAND (*call_ptr, 1);
- if (TREE_CODE (*call_ptr) == WITH_SIZE_EXPR)
- call_ptr = &TREE_OPERAND (*call_ptr, 0);
- gcc_assert (*call_ptr == call);
- if (call_ptr == stmtp)
- {
- bsi_replace (&copy_bsi, new_call, true);
- stmtp = bsi_stmt_ptr (copy_bsi);
- stmt = *stmtp;
- }
- else
- {
- *call_ptr = new_call;
- stmt = *stmtp;
- update_stmt (stmt);
- }
- }
- else if (call
- && id->call_expr
- && (decl = get_callee_fndecl (call))
- && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL
- && DECL_FUNCTION_CODE (decl)
- == BUILT_IN_VA_ARG_PACK_LEN)
- {
- /* __builtin_va_arg_pack_len () should be replaced by
- the number of anonymous arguments. */
- int nargs = call_expr_nargs (id->call_expr);
- tree count, *call_ptr, p;
-
- for (p = DECL_ARGUMENTS (id->src_fn); p; p = TREE_CHAIN (p))
- nargs--;
-
- count = build_int_cst (integer_type_node, nargs);
- call_ptr = stmtp;
- if (TREE_CODE (*call_ptr) == GIMPLE_MODIFY_STMT)
- call_ptr = &GIMPLE_STMT_OPERAND (*call_ptr, 1);
- if (TREE_CODE (*call_ptr) == WITH_SIZE_EXPR)
- call_ptr = &TREE_OPERAND (*call_ptr, 0);
- gcc_assert (*call_ptr == call && call_ptr != stmtp);
- *call_ptr = count;
- stmt = *stmtp;
- update_stmt (stmt);
- call = NULL_TREE;
+ case CB_CGE_DUPLICATE:
+ edge = cgraph_edge (id->src_node, orig_stmt);
+ if (edge)
+ cgraph_clone_edge (edge, id->dst_node, stmt,
+ REG_BR_PROB_BASE, 1,
+ edge->frequency, true);
+ break;
+
+ case CB_CGE_MOVE_CLONES:
+ for (node = id->dst_node->next_clone;
+ node;
+ node = node->next_clone)
+ {
+ edge = cgraph_edge (node, orig_stmt);
+ if (edge)
+ cgraph_set_call_stmt (edge, stmt);
+ }
+ /* FALLTHRU */
+
+ case CB_CGE_MOVE:
+ edge = cgraph_edge (id->dst_node, orig_stmt);
+ if (edge)
+ cgraph_set_call_stmt (edge, stmt);
+ break;
+
+ default:
+ gcc_unreachable ();
}
+ }
- /* Statements produced by inlining can be unfolded, especially
- when we constant propagated some operands. We can't fold
- them right now for two reasons:
- 1) folding require SSA_NAME_DEF_STMTs to be correct
- 2) we can't change function calls to builtins.
- So we just mark statement for later folding. We mark
- all new statements, instead just statements that has changed
- by some nontrivial substitution so even statements made
- foldable indirectly are updated. If this turns out to be
- expensive, copy_body can be told to watch for nontrivial
- changes. */
- if (id->statements_to_fold)
- pointer_set_insert (id->statements_to_fold, stmt);
- /* We're duplicating a CALL_EXPR. Find any corresponding
- callgraph edges and update or duplicate them. */
- if (call && (decl = get_callee_fndecl (call)))
- {
- struct cgraph_node *node;
- struct cgraph_edge *edge;
-
- switch (id->transform_call_graph_edges)
- {
- case CB_CGE_DUPLICATE:
- edge = cgraph_edge (id->src_node, orig_stmt);
- if (edge)
- cgraph_clone_edge (edge, id->dst_node, stmt,
- REG_BR_PROB_BASE, 1, edge->frequency, true);
- break;
-
- case CB_CGE_MOVE_CLONES:
- for (node = id->dst_node->next_clone;
- node;
- node = node->next_clone)
- {
- edge = cgraph_edge (node, orig_stmt);
- gcc_assert (edge);
- cgraph_set_call_stmt (edge, stmt);
- }
- /* FALLTHRU */
-
- case CB_CGE_MOVE:
- edge = cgraph_edge (id->dst_node, orig_stmt);
- if (edge)
- cgraph_set_call_stmt (edge, stmt);
- break;
-
- default:
- gcc_unreachable ();
- }
- }
- /* If you think we can abort here, you are wrong.
- There is no region 0 in tree land. */
- gcc_assert (lookup_stmt_eh_region_fn (id->src_cfun, orig_stmt)
- != 0);
-
- if (tree_could_throw_p (stmt)
- /* When we are cloning for inlining, we are supposed to
- construct a clone that calls precisely the same functions
- as original. However IPA optimizers might've proved
- earlier some function calls as non-trapping that might
- render some basic blocks dead that might become
- unreachable.
-
- We can't update SSA with unreachable blocks in CFG and thus
- we prevent the scenario by preserving even the "dead" eh
- edges until the point they are later removed by
- fixup_cfg pass. */
- || (id->transform_call_graph_edges == CB_CGE_MOVE_CLONES
- && lookup_stmt_eh_region_fn (id->src_cfun, orig_stmt) > 0))
- {
- int region = lookup_stmt_eh_region_fn (id->src_cfun, orig_stmt);
- /* Add an entry for the copied tree in the EH hashtable.
- When cloning or versioning, use the hashtable in
- cfun, and just copy the EH number. When inlining, use the
- hashtable in the caller, and adjust the region number. */
- if (region > 0)
- add_stmt_to_eh_region (stmt, region + id->eh_region_offset);
-
- /* If this tree doesn't have a region associated with it,
- and there is a "current region,"
- then associate this tree with the current region
- and add edges associated with this region. */
- if ((lookup_stmt_eh_region_fn (id->src_cfun,
- orig_stmt) <= 0
- && id->eh_region > 0)
- && tree_could_throw_p (stmt))
- add_stmt_to_eh_region (stmt, id->eh_region);
- }
- if (gimple_in_ssa_p (cfun))
- {
- ssa_op_iter i;
- tree def;
+ /* If you think we can abort here, you are wrong.
+ There is no region 0 in gimple. */
+ gcc_assert (lookup_stmt_eh_region_fn (id->src_cfun, orig_stmt) != 0);
+
+ if (stmt_could_throw_p (stmt)
+ /* When we are cloning for inlining, we are supposed to
+ construct a clone that calls precisely the same functions
+ as original. However IPA optimizers might've proved
+ earlier some function calls as non-trapping that might
+ render some basic blocks dead that might become
+ unreachable.
+
+ We can't update SSA with unreachable blocks in CFG and thus
+ we prevent the scenario by preserving even the "dead" eh
+ edges until the point they are later removed by
+ fixup_cfg pass. */
+ || (id->transform_call_graph_edges == CB_CGE_MOVE_CLONES
+ && lookup_stmt_eh_region_fn (id->src_cfun, orig_stmt) > 0))
+ {
+ int region = lookup_stmt_eh_region_fn (id->src_cfun, orig_stmt);
+
+ /* Add an entry for the copied tree in the EH hashtable.
+ When cloning or versioning, use the hashtable in
+ cfun, and just copy the EH number. When inlining, use the
+ hashtable in the caller, and adjust the region number. */
+ if (region > 0)
+ add_stmt_to_eh_region (stmt, region + id->eh_region_offset);
+
+ /* If this tree doesn't have a region associated with it,
+ and there is a "current region,"
+ then associate this tree with the current region
+ and add edges associated with this region. */
+ if (lookup_stmt_eh_region_fn (id->src_cfun, orig_stmt) <= 0
+ && id->eh_region > 0
+ && stmt_could_throw_p (stmt))
+ add_stmt_to_eh_region (stmt, id->eh_region);
+ }
- find_new_referenced_vars (bsi_stmt_ptr (copy_bsi));
- FOR_EACH_SSA_TREE_OPERAND (def, stmt, i, SSA_OP_DEF)
- if (TREE_CODE (def) == SSA_NAME)
- SSA_NAME_DEF_STMT (def) = stmt;
- }
- bsi_next (&copy_bsi);
+ if (gimple_in_ssa_p (cfun))
+ {
+ ssa_op_iter i;
+ tree def;
+
+ find_new_referenced_vars (gsi_stmt (copy_gsi));
+ FOR_EACH_SSA_TREE_OPERAND (def, stmt, i, SSA_OP_DEF)
+ if (TREE_CODE (def) == SSA_NAME)
+ SSA_NAME_DEF_STMT (def) = stmt;
}
- copy_bsi = bsi_last (copy_basic_block);
+
+ gsi_next (&copy_gsi);
}
+
+ copy_gsi = gsi_last_bb (copy_basic_block);
}
+
return copy_basic_block;
}
@@ -1071,27 +1489,31 @@ update_ssa_across_abnormal_edges (basic_block bb, basic_block ret_bb,
if (!e->dest->aux
|| ((basic_block)e->dest->aux)->index == ENTRY_BLOCK)
{
- tree phi;
+ gimple phi;
+ gimple_stmt_iterator si;
gcc_assert (e->flags & EDGE_ABNORMAL);
+
if (!nonlocal_goto)
gcc_assert (e->flags & EDGE_EH);
+
if (!can_throw)
gcc_assert (!(e->flags & EDGE_EH));
- for (phi = phi_nodes (e->dest); phi; phi = PHI_CHAIN (phi))
+
+ for (si = gsi_start_phis (e->dest); !gsi_end_p (si); gsi_next (&si))
{
edge re;
+ phi = gsi_stmt (si);
+
/* There shouldn't be any PHI nodes in the ENTRY_BLOCK. */
gcc_assert (!e->dest->aux);
- gcc_assert (SSA_NAME_OCCURS_IN_ABNORMAL_PHI
- (PHI_RESULT (phi)));
+ gcc_assert (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (PHI_RESULT (phi)));
if (!is_gimple_reg (PHI_RESULT (phi)))
{
- mark_sym_for_renaming
- (SSA_NAME_VAR (PHI_RESULT (phi)));
+ mark_sym_for_renaming (SSA_NAME_VAR (PHI_RESULT (phi)));
continue;
}
@@ -1106,16 +1528,18 @@ update_ssa_across_abnormal_edges (basic_block bb, basic_block ret_bb,
}
}
+
/* Copy edges from BB into its copy constructed earlier, scale profile
accordingly. Edges will be taken care of later. Assume aux
pointers to point to the copies of each BB. */
+
static void
copy_edges_for_bb (basic_block bb, gcov_type count_scale, basic_block ret_bb)
{
basic_block new_bb = (basic_block) bb->aux;
edge_iterator ei;
edge old_edge;
- block_stmt_iterator bsi;
+ gimple_stmt_iterator si;
int flags;
/* Use the indices from the original blocks to create edges for the
@@ -1139,17 +1563,18 @@ copy_edges_for_bb (basic_block bb, gcov_type count_scale, basic_block ret_bb)
if (bb->index == ENTRY_BLOCK || bb->index == EXIT_BLOCK)
return;
- for (bsi = bsi_start (new_bb); !bsi_end_p (bsi);)
+ for (si = gsi_start_bb (new_bb); !gsi_end_p (si);)
{
- tree copy_stmt;
+ gimple copy_stmt;
bool can_throw, nonlocal_goto;
- copy_stmt = bsi_stmt (bsi);
+ copy_stmt = gsi_stmt (si);
update_stmt (copy_stmt);
if (gimple_in_ssa_p (cfun))
mark_symbols_for_renaming (copy_stmt);
+
/* Do this before the possible split_block. */
- bsi_next (&bsi);
+ gsi_next (&si);
/* If this tree could throw an exception, there are two
cases where we need to add abnormal edge(s): the
@@ -1162,13 +1587,12 @@ copy_edges_for_bb (basic_block bb, gcov_type count_scale, basic_block ret_bb)
propagation can change an INDIRECT_REF which throws
into a COMPONENT_REF which doesn't. If the copy
can throw, the original could also throw. */
-
- can_throw = tree_can_throw_internal (copy_stmt);
- nonlocal_goto = tree_can_make_abnormal_goto (copy_stmt);
+ can_throw = stmt_can_throw_internal (copy_stmt);
+ nonlocal_goto = stmt_can_make_abnormal_goto (copy_stmt);
if (can_throw || nonlocal_goto)
{
- if (!bsi_end_p (bsi))
+ if (!gsi_end_p (si))
/* Note that bb's predecessor edges aren't necessarily
right at this point; split_block doesn't care. */
{
@@ -1176,7 +1600,7 @@ copy_edges_for_bb (basic_block bb, gcov_type count_scale, basic_block ret_bb)
new_bb = e->dest;
new_bb->aux = e->src->aux;
- bsi = bsi_start (new_bb);
+ si = gsi_start_bb (new_bb);
}
}
@@ -1184,11 +1608,11 @@ copy_edges_for_bb (basic_block bb, gcov_type count_scale, basic_block ret_bb)
make_eh_edges (copy_stmt);
if (nonlocal_goto)
- make_abnormal_goto_edges (bb_for_stmt (copy_stmt), true);
+ make_abnormal_goto_edges (gimple_bb (copy_stmt), true);
if ((can_throw || nonlocal_goto)
&& gimple_in_ssa_p (cfun))
- update_ssa_across_abnormal_edges (bb_for_stmt (copy_stmt), ret_bb,
+ update_ssa_across_abnormal_edges (gimple_bb (copy_stmt), ret_bb,
can_throw, nonlocal_goto);
}
}
@@ -1203,27 +1627,33 @@ copy_phis_for_bb (basic_block bb, copy_body_data *id)
{
basic_block const new_bb = (basic_block) bb->aux;
edge_iterator ei;
- tree phi;
+ gimple phi;
+ gimple_stmt_iterator si;
- for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
+ for (si = gsi_start (phi_nodes (bb)); !gsi_end_p (si); gsi_next (&si))
{
- tree res = PHI_RESULT (phi);
- tree new_res = res;
- tree new_phi;
+ tree res, new_res;
+ gimple new_phi;
edge new_edge;
+ phi = gsi_stmt (si);
+ res = PHI_RESULT (phi);
+ new_res = res;
if (is_gimple_reg (res))
{
- walk_tree (&new_res, copy_body_r, id, NULL);
+ walk_tree (&new_res, copy_tree_body_r, id, NULL);
SSA_NAME_DEF_STMT (new_res)
= new_phi = create_phi_node (new_res, new_bb);
FOR_EACH_EDGE (new_edge, ei, new_bb->preds)
{
- edge const old_edge = find_edge ((basic_block) new_edge->src->aux, bb);
+ edge const old_edge
+ = find_edge ((basic_block) new_edge->src->aux, bb);
tree arg = PHI_ARG_DEF_FROM_EDGE (phi, old_edge);
tree new_arg = arg;
-
- walk_tree (&new_arg, copy_body_r, id, NULL);
+ tree block = id->block;
+ id->block = NULL_TREE;
+ walk_tree (&new_arg, copy_tree_body_r, id, NULL);
+ id->block = block;
gcc_assert (new_arg);
/* With return slot optimization we can end up with
non-gimple (foo *)&this->m, fix that here. */
@@ -1231,10 +1661,9 @@ copy_phis_for_bb (basic_block bb, copy_body_data *id)
&& TREE_CODE (new_arg) != FUNCTION_DECL
&& !is_gimple_val (new_arg))
{
- tree stmts = NULL_TREE;
- new_arg = force_gimple_operand (new_arg, &stmts,
- true, NULL);
- bsi_insert_on_edge_immediate (new_edge, stmts);
+ gimple_seq stmts = NULL;
+ new_arg = force_gimple_operand (new_arg, &stmts, true, NULL);
+ gsi_insert_seq_on_edge_immediate (new_edge, stmts);
}
add_phi_arg (new_phi, new_arg, new_edge);
}
@@ -1242,7 +1671,9 @@ copy_phis_for_bb (basic_block bb, copy_body_data *id)
}
}
+
/* Wrapper for remap_decl so it can be used as a callback. */
+
static tree
remap_decl_1 (tree decl, void *data)
{
@@ -1275,7 +1706,7 @@ initialize_cfun (tree new_fndecl, tree callee_fndecl, gcov_type count,
frequency_scale = count_scale;
/* Register specific tree functions. */
- tree_register_cfg_hooks ();
+ gimple_register_cfg_hooks ();
*new_cfun = *DECL_STRUCT_FUNCTION (callee_fndecl);
new_cfun->funcdef_no = get_next_funcdef_no ();
VALUE_HISTOGRAMS (new_cfun) = NULL;
@@ -1340,7 +1771,7 @@ copy_cfg_body (copy_body_data * id, gcov_type count, int frequency,
frequency_scale = count_scale;
/* Register specific tree functions. */
- tree_register_cfg_hooks ();
+ gimple_register_cfg_hooks ();
/* Must have a CFG here at this point. */
gcc_assert (ENTRY_BLOCK_PTR_FOR_FUNCTION
@@ -1348,7 +1779,6 @@ copy_cfg_body (copy_body_data * id, gcov_type count, int frequency,
cfun_to_copy = id->src_cfun = DECL_STRUCT_FUNCTION (callee_fndecl);
-
ENTRY_BLOCK_PTR_FOR_FUNCTION (cfun_to_copy)->aux = entry_block_map;
EXIT_BLOCK_PTR_FOR_FUNCTION (cfun_to_copy)->aux = exit_block_map;
entry_block_map->aux = ENTRY_BLOCK_PTR_FOR_FUNCTION (cfun_to_copy);
@@ -1361,6 +1791,7 @@ copy_cfg_body (copy_body_data * id, gcov_type count, int frequency,
= duplicate_eh_regions (cfun_to_copy, remap_decl_1, id,
0, id->eh_region);
}
+
/* Use aux pointers to map the original blocks to copy. */
FOR_EACH_BB_FN (bb, cfun_to_copy)
{
@@ -1370,17 +1801,21 @@ copy_cfg_body (copy_body_data * id, gcov_type count, int frequency,
}
last = last_basic_block;
+
/* Now that we've duplicated the blocks, duplicate their edges. */
FOR_ALL_BB_FN (bb, cfun_to_copy)
copy_edges_for_bb (bb, count_scale, exit_block_map);
+
if (gimple_in_ssa_p (cfun))
FOR_ALL_BB_FN (bb, cfun_to_copy)
copy_phis_for_bb (bb, id);
+
FOR_ALL_BB_FN (bb, cfun_to_copy)
{
((basic_block)bb->aux)->aux = NULL;
bb->aux = NULL;
}
+
/* Zero out AUX fields of newly created block during EH edge
insertion. */
for (; last < last_basic_block; last++)
@@ -1391,21 +1826,6 @@ copy_cfg_body (copy_body_data * id, gcov_type count, int frequency,
return new_fndecl;
}
-/* Make a copy of the body of FN so that it can be inserted inline in
- another function. */
-
-tree
-copy_generic_body (copy_body_data *id)
-{
- tree body;
- tree fndecl = id->src_fn;
-
- body = DECL_SAVED_TREE (fndecl);
- walk_tree (&body, copy_body_r, id, NULL);
-
- return body;
-}
-
static tree
copy_body (copy_body_data *id, gcov_type count, int frequency,
basic_block entry_block_map, basic_block exit_block_map)
@@ -1440,7 +1860,7 @@ static void
setup_one_parameter (copy_body_data *id, tree p, tree value, tree fn,
basic_block bb, tree *vars)
{
- tree init_stmt;
+ gimple init_stmt;
tree var;
tree rhs = value;
tree def = (gimple_in_ssa_p (cfun)
@@ -1556,7 +1976,7 @@ setup_one_parameter (copy_body_data *id, tree p, tree value, tree fn,
the argument to the proper type in case it was promoted. */
if (value)
{
- block_stmt_iterator bsi = bsi_last (bb);
+ gimple_stmt_iterator si = gsi_last_bb (bb);
if (rhs == error_mark_node)
{
@@ -1566,21 +1986,20 @@ setup_one_parameter (copy_body_data *id, tree p, tree value, tree fn,
STRIP_USELESS_TYPE_CONVERSION (rhs);
- /* We want to use GIMPLE_MODIFY_STMT, not INIT_EXPR here so that we
+ /* We want to use MODIFY_EXPR, not INIT_EXPR here so that we
keep our trees in gimple form. */
if (def && gimple_in_ssa_p (cfun) && is_gimple_reg (p))
{
def = remap_ssa_name (def, id);
- init_stmt = build_gimple_modify_stmt (def, rhs);
- SSA_NAME_DEF_STMT (def) = init_stmt;
+ init_stmt = gimple_build_assign (def, rhs);
SSA_NAME_IS_DEFAULT_DEF (def) = 0;
set_default_def (var, NULL);
}
else
- init_stmt = build_gimple_modify_stmt (var, rhs);
+ init_stmt = gimple_build_assign (var, rhs);
/* If we did not create a gimple value and we did not create a gimple
- cast of a gimple value, then we will need to gimplify INIT_STMTS
+ cast of a gimple value, then we will need to gimplify INIT_STMT
at the end. Note that is_gimple_cast only checks the outer
tree code, not its operand. Thus the explicit check that its
operand is a gimple value. */
@@ -1589,53 +2008,67 @@ setup_one_parameter (copy_body_data *id, tree p, tree value, tree fn,
|| !is_gimple_val (TREE_OPERAND (rhs, 0))))
|| !is_gimple_reg (var))
{
- tree_stmt_iterator i;
+ gimple_stmt_iterator i;
+ gimple_seq seq = gimple_seq_alloc ();
+ struct gimplify_ctx gctx;
+
+ push_gimplify_context (&gctx);
+
+ i = gsi_start (seq);
+ gimple_regimplify_operands (init_stmt, &i);
- push_gimplify_context ();
- gimplify_stmt (&init_stmt);
if (gimple_in_ssa_p (cfun)
- && init_stmt && TREE_CODE (init_stmt) == STATEMENT_LIST)
+ && init_stmt
+ && !gimple_seq_empty_p (seq))
{
/* The replacement can expose previously unreferenced
variables. */
- for (i = tsi_start (init_stmt); !tsi_end_p (i); tsi_next (&i))
- find_new_referenced_vars (tsi_stmt_ptr (i));
+ for (i = gsi_start (seq); !gsi_end_p (i); gsi_next (&i))
+ find_new_referenced_vars (gsi_stmt (i));
+
+ /* Insert the gimplified sequence needed for INIT_STMT
+ after SI. INIT_STMT will be inserted after SEQ. */
+ gsi_insert_seq_after (&si, seq, GSI_NEW_STMT);
}
+
pop_gimplify_context (NULL);
}
/* If VAR represents a zero-sized variable, it's possible that the
assignment statement may result in no gimple statements. */
if (init_stmt)
- bsi_insert_after (&bsi, init_stmt, BSI_NEW_STMT);
+ gsi_insert_after (&si, init_stmt, GSI_NEW_STMT);
+
if (gimple_in_ssa_p (cfun))
- for (;!bsi_end_p (bsi); bsi_next (&bsi))
- mark_symbols_for_renaming (bsi_stmt (bsi));
+ for (;!gsi_end_p (si); gsi_next (&si))
+ mark_symbols_for_renaming (gsi_stmt (si));
}
}
/* Generate code to initialize the parameters of the function at the
- top of the stack in ID from the CALL_EXPR EXP. */
+ top of the stack in ID from the GIMPLE_CALL STMT. */
static void
-initialize_inlined_parameters (copy_body_data *id, tree exp,
+initialize_inlined_parameters (copy_body_data *id, gimple stmt,
tree fn, basic_block bb)
{
tree parms;
- tree a;
+ size_t i;
tree p;
tree vars = NULL_TREE;
- call_expr_arg_iterator iter;
- tree static_chain = CALL_EXPR_STATIC_CHAIN (exp);
+ tree static_chain = gimple_call_chain (stmt);
/* Figure out what the parameters are. */
parms = DECL_ARGUMENTS (fn);
/* Loop through the parameter declarations, replacing each with an
equivalent VAR_DECL, appropriately initialized. */
- for (p = parms, a = first_call_expr_arg (exp, &iter); p;
- a = next_call_expr_arg (&iter), p = TREE_CHAIN (p))
- setup_one_parameter (id, p, a, fn, bb, &vars);
+ for (p = parms, i = 0; p; p = TREE_CHAIN (p), i++)
+ {
+ tree val;
+ val = i < gimple_call_num_args (stmt) ? gimple_call_arg (stmt, i) : NULL;
+ setup_one_parameter (id, p, val, fn, bb, &vars);
+ }
/* Initialize the static chain. */
p = DECL_STRUCT_FUNCTION (fn)->static_chain_decl;
@@ -1651,6 +2084,7 @@ initialize_inlined_parameters (copy_body_data *id, tree exp,
declare_inline_vars (id->block, vars);
}
+
/* Declare a return variable to replace the RESULT_DECL for the
function we are calling. An appropriate DECL_STMT is returned.
The USE_STMT is filled to contain a use of the declaration to
@@ -1658,7 +2092,7 @@ initialize_inlined_parameters (copy_body_data *id, tree exp,
RETURN_SLOT, if non-null is place where to store the result. It
is set only for CALL_EXPR_RETURN_SLOT_OPT. MODIFY_DEST, if non-null,
- was the LHS of the GIMPLE_MODIFY_STMT to which this call is the RHS.
+ was the LHS of the MODIFY_EXPR to which this call is the RHS.
The return value is a (possibly null) value that is the result of the
function as seen by the callee. *USE_P is a (possibly null) value that
@@ -1838,37 +2272,89 @@ declare_return_variable (copy_body_data *id, tree return_slot, tree modify_dest,
bool
tree_inlinable_function_p (tree fn)
{
- return inlinable_function_p (fn);
+ bool ret = inlinable_function_p (fn);
+
+ if (getenv ("TUPLES_INLINE"))
+ fprintf (stderr, "Function %s is %sinlinable\n", get_name (fn),
+ ret ? "" : "not ");
+
+ return ret;
}
static const char *inline_forbidden_reason;
+/* A callback for walk_gimple_seq to handle tree operands. Returns
+ NULL_TREE if a function can be inlined, otherwise sets the reason
+ why not and returns a tree representing the offending operand. */
+
static tree
-inline_forbidden_p_1 (tree *nodep, int *walk_subtrees ATTRIBUTE_UNUSED,
- void *fnp)
+inline_forbidden_p_op (tree *nodep, int *walk_subtrees ATTRIBUTE_UNUSED,
+ void *fnp ATTRIBUTE_UNUSED)
{
tree node = *nodep;
- tree fn = (tree) fnp;
tree t;
- switch (TREE_CODE (node))
+ if (TREE_CODE (node) == RECORD_TYPE || TREE_CODE (node) == UNION_TYPE)
+ {
+ /* We cannot inline a function of the form
+
+ void F (int i) { struct S { int ar[i]; } s; }
+
+ Attempting to do so produces a catch-22.
+ If walk_tree examines the TYPE_FIELDS chain of RECORD_TYPE/
+ UNION_TYPE nodes, then it goes into infinite recursion on a
+ structure containing a pointer to its own type. If it doesn't,
+ then the type node for S doesn't get adjusted properly when
+ F is inlined.
+
+ ??? This is likely no longer true, but it's too late in the 4.0
+ cycle to try to find out. This should be checked for 4.1. */
+ for (t = TYPE_FIELDS (node); t; t = TREE_CHAIN (t))
+ if (variably_modified_type_p (TREE_TYPE (t), NULL))
+ {
+ inline_forbidden_reason
+ = G_("function %q+F can never be inlined "
+ "because it uses variable sized variables");
+ return node;
+ }
+ }
+
+ return NULL_TREE;
+}
+
+
+/* A callback for walk_gimple_seq to handle statements. Returns
+ non-NULL iff a function can not be inlined. Also sets the reason
+ why. */
+
+static tree
+inline_forbidden_p_stmt (gimple_stmt_iterator *gsi, bool *handled_ops_p,
+ struct walk_stmt_info *wip)
+{
+ tree fn = (tree) wip->info;
+ tree t;
+ gimple stmt = gsi_stmt (*gsi);
+
+ switch (gimple_code (stmt))
{
- case CALL_EXPR:
+ case GIMPLE_CALL:
/* Refuse to inline alloca call unless user explicitly forced so as
this may change program's memory overhead drastically when the
function using alloca is called in loop. In GCC present in
SPEC2000 inlining into schedule_block cause it to require 2GB of
RAM instead of 256MB. */
- if (alloca_call_p (node)
+ if (gimple_alloca_call_p (stmt)
&& !lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn)))
{
inline_forbidden_reason
= G_("function %q+F can never be inlined because it uses "
"alloca (override using the always_inline attribute)");
- return node;
+ *handled_ops_p = true;
+ return fn;
}
- t = get_callee_fndecl (node);
- if (! t)
+
+ t = gimple_call_fndecl (stmt);
+ if (t == NULL_TREE)
break;
/* We cannot inline functions that call setjmp. */
@@ -1876,7 +2362,8 @@ inline_forbidden_p_1 (tree *nodep, int *walk_subtrees ATTRIBUTE_UNUSED,
{
inline_forbidden_reason
= G_("function %q+F can never be inlined because it uses setjmp");
- return node;
+ *handled_ops_p = true;
+ return t;
}
if (DECL_BUILT_IN_CLASS (t) == BUILT_IN_NORMAL)
@@ -1890,7 +2377,8 @@ inline_forbidden_p_1 (tree *nodep, int *walk_subtrees ATTRIBUTE_UNUSED,
inline_forbidden_reason
= G_("function %q+F can never be inlined because it "
"uses variable argument lists");
- return node;
+ *handled_ops_p = true;
+ return t;
case BUILT_IN_LONGJMP:
/* We can't inline functions that call __builtin_longjmp at
@@ -1901,14 +2389,16 @@ inline_forbidden_p_1 (tree *nodep, int *walk_subtrees ATTRIBUTE_UNUSED,
inline_forbidden_reason
= G_("function %q+F can never be inlined because "
"it uses setjmp-longjmp exception handling");
- return node;
+ *handled_ops_p = true;
+ return t;
case BUILT_IN_NONLOCAL_GOTO:
/* Similarly. */
inline_forbidden_reason
= G_("function %q+F can never be inlined because "
"it uses non-local goto");
- return node;
+ *handled_ops_p = true;
+ return t;
case BUILT_IN_RETURN:
case BUILT_IN_APPLY_ARGS:
@@ -1919,15 +2409,16 @@ inline_forbidden_p_1 (tree *nodep, int *walk_subtrees ATTRIBUTE_UNUSED,
inline_forbidden_reason
= G_("function %q+F can never be inlined because "
"it uses __builtin_return or __builtin_apply_args");
- return node;
+ *handled_ops_p = true;
+ return t;
default:
break;
}
break;
- case GOTO_EXPR:
- t = TREE_OPERAND (node, 0);
+ case GIMPLE_GOTO:
+ t = gimple_goto_dest (stmt);
/* We will not inline a function which uses computed goto. The
addresses of its local labels, which may be tucked into
@@ -1938,12 +2429,13 @@ inline_forbidden_p_1 (tree *nodep, int *walk_subtrees ATTRIBUTE_UNUSED,
inline_forbidden_reason
= G_("function %q+F can never be inlined "
"because it contains a computed goto");
- return node;
+ *handled_ops_p = true;
+ return t;
}
break;
- case LABEL_EXPR:
- t = TREE_OPERAND (node, 0);
+ case GIMPLE_LABEL:
+ t = gimple_label_label (stmt);
if (DECL_NONLOCAL (t))
{
/* We cannot inline a function that receives a non-local goto
@@ -1952,41 +2444,20 @@ inline_forbidden_p_1 (tree *nodep, int *walk_subtrees ATTRIBUTE_UNUSED,
inline_forbidden_reason
= G_("function %q+F can never be inlined "
"because it receives a non-local goto");
- return node;
+ *handled_ops_p = true;
+ return t;
}
break;
- case RECORD_TYPE:
- case UNION_TYPE:
- /* We cannot inline a function of the form
-
- void F (int i) { struct S { int ar[i]; } s; }
-
- Attempting to do so produces a catch-22.
- If walk_tree examines the TYPE_FIELDS chain of RECORD_TYPE/
- UNION_TYPE nodes, then it goes into infinite recursion on a
- structure containing a pointer to its own type. If it doesn't,
- then the type node for S doesn't get adjusted properly when
- F is inlined.
-
- ??? This is likely no longer true, but it's too late in the 4.0
- cycle to try to find out. This should be checked for 4.1. */
- for (t = TYPE_FIELDS (node); t; t = TREE_CHAIN (t))
- if (variably_modified_type_p (TREE_TYPE (t), NULL))
- {
- inline_forbidden_reason
- = G_("function %q+F can never be inlined "
- "because it uses variable sized variables");
- return node;
- }
-
default:
break;
}
+ *handled_ops_p = false;
return NULL_TREE;
}
+
static tree
inline_forbidden_p_2 (tree *nodep, int *walk_subtrees,
void *fnp)
@@ -2008,25 +2479,35 @@ inline_forbidden_p_2 (tree *nodep, int *walk_subtrees,
return NULL_TREE;
}
-/* Return subexpression representing possible alloca call, if any. */
-static tree
+/* Return true if FNDECL is a function that cannot be inlined into
+ another one. */
+
+static bool
inline_forbidden_p (tree fndecl)
{
location_t saved_loc = input_location;
- block_stmt_iterator bsi;
- basic_block bb;
- tree ret = NULL_TREE;
struct function *fun = DECL_STRUCT_FUNCTION (fndecl);
tree step;
+ struct walk_stmt_info wi;
+ struct pointer_set_t *visited_nodes;
+ basic_block bb;
+ bool forbidden_p = false;
+
+ visited_nodes = pointer_set_create ();
+ memset (&wi, 0, sizeof (wi));
+ wi.info = (void *) fndecl;
+ wi.pset = visited_nodes;
FOR_EACH_BB_FN (bb, fun)
- for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
- {
- ret = walk_tree_without_duplicates (bsi_stmt_ptr (bsi),
- inline_forbidden_p_1, fndecl);
- if (ret)
- goto egress;
- }
+ {
+ gimple ret;
+ gimple_seq seq = bb_seq (bb);
+ ret = walk_gimple_seq (seq, inline_forbidden_p_stmt,
+ inline_forbidden_p_op, &wi);
+ forbidden_p = (ret != NULL);
+ if (forbidden_p)
+ goto egress;
+ }
for (step = fun->local_decls; step; step = TREE_CHAIN (step))
{
@@ -2035,15 +2516,20 @@ inline_forbidden_p (tree fndecl)
&& TREE_STATIC (decl)
&& !DECL_EXTERNAL (decl)
&& DECL_INITIAL (decl))
- ret = walk_tree_without_duplicates (&DECL_INITIAL (decl),
- inline_forbidden_p_2, fndecl);
- if (ret)
- goto egress;
+ {
+ tree ret;
+ ret = walk_tree_without_duplicates (&DECL_INITIAL (decl),
+ inline_forbidden_p_2, fndecl);
+ forbidden_p = (ret != NULL);
+ if (forbidden_p)
+ goto egress;
+ }
}
egress:
+ pointer_set_destroy (visited_nodes);
input_location = saved_loc;
- return ret;
+ return forbidden_p;
}
/* Returns nonzero if FN is a function that does not have any
@@ -2063,7 +2549,6 @@ inlinable_function_p (tree fn)
/* We only warn for functions declared `inline' by the user. */
do_warning = (warn_inline
- && DECL_INLINE (fn)
&& DECL_DECLARED_INLINE_P (fn)
&& !DECL_IN_SYSTEM_HEADER (fn));
@@ -2095,27 +2580,9 @@ inlinable_function_p (tree fn)
/* If we don't have the function body available, we can't inline it.
However, this should not be recorded since we also get here for
forward declared inline functions. Therefore, return at once. */
- if (!DECL_SAVED_TREE (fn))
+ if (!gimple_body (fn))
return false;
- /* If we're not inlining at all, then we cannot inline this function. */
- else if (!flag_inline_trees)
- inlinable = false;
-
- /* Only try to inline functions if DECL_INLINE is set. This should be
- true for all functions declared `inline', and for all other functions
- as well with -finline-functions.
-
- Don't think of disregarding DECL_INLINE when flag_inline_trees == 2;
- it's the front-end that must set DECL_INLINE in this case, because
- dwarf2out loses if a function that does not have DECL_INLINE set is
- inlined anyway. That is why we have both DECL_INLINE and
- DECL_DECLARED_INLINE_P. */
- /* FIXME: When flag_inline_trees dies, the check for flag_unit_at_a_time
- here should be redundant. */
- else if (!DECL_INLINE (fn) && !flag_unit_at_a_time)
- inlinable = false;
-
else if (inline_forbidden_p (fn))
{
/* See if we should warn about uninlinable functions. Previously,
@@ -2156,151 +2623,21 @@ estimate_move_cost (tree type)
return ((size + MOVE_MAX_PIECES - 1) / MOVE_MAX_PIECES);
}
-/* Arguments for estimate_num_insns_1. */
+/* Returns cost of operation CODE, according to WEIGHTS */
-struct eni_data
+static int
+estimate_operator_cost (enum tree_code code, eni_weights *weights)
{
- /* Used to return the number of insns. */
- int count;
-
- /* Weights of various constructs. */
- eni_weights *weights;
-};
-
-/* Used by estimate_num_insns. Estimate number of instructions seen
- by given statement. */
-
-static tree
-estimate_num_insns_1 (tree *tp, int *walk_subtrees, void *data)
-{
- struct eni_data *const d = (struct eni_data *) data;
- tree x = *tp;
- unsigned cost;
-
- if (IS_TYPE_OR_DECL_P (x))
+ switch (code)
{
- *walk_subtrees = 0;
- return NULL;
- }
- /* Assume that constants and references counts nothing. These should
- be majorized by amount of operations among them we count later
- and are common target of CSE and similar optimizations. */
- else if (CONSTANT_CLASS_P (x) || REFERENCE_CLASS_P (x))
- return NULL;
-
- switch (TREE_CODE (x))
- {
- /* Containers have no cost. */
- case TREE_LIST:
- case TREE_VEC:
- case BLOCK:
- case COMPONENT_REF:
- case BIT_FIELD_REF:
- case INDIRECT_REF:
- case ALIGN_INDIRECT_REF:
- case MISALIGNED_INDIRECT_REF:
- case ARRAY_REF:
- case ARRAY_RANGE_REF:
- case OBJ_TYPE_REF:
- case EXC_PTR_EXPR: /* ??? */
- case FILTER_EXPR: /* ??? */
- case COMPOUND_EXPR:
- case BIND_EXPR:
- case WITH_CLEANUP_EXPR:
- case PAREN_EXPR:
- CASE_CONVERT:
- case VIEW_CONVERT_EXPR:
- case SAVE_EXPR:
- case ADDR_EXPR:
- case COMPLEX_EXPR:
+ /* These are "free" conversions, or their presumed cost
+ is folded into other operations. */
case RANGE_EXPR:
- case CASE_LABEL_EXPR:
- case SSA_NAME:
- case CATCH_EXPR:
- case EH_FILTER_EXPR:
- case STATEMENT_LIST:
- case ERROR_MARK:
- case FDESC_EXPR:
- case VA_ARG_EXPR:
- case TRY_CATCH_EXPR:
- case TRY_FINALLY_EXPR:
- case LABEL_EXPR:
- case GOTO_EXPR:
- case RETURN_EXPR:
- case EXIT_EXPR:
- case LOOP_EXPR:
- case PHI_NODE:
- case WITH_SIZE_EXPR:
- case OMP_CLAUSE:
- case OMP_RETURN:
- case OMP_CONTINUE:
- case OMP_SECTIONS_SWITCH:
- case OMP_ATOMIC_STORE:
- break;
-
- /* We don't account constants for now. Assume that the cost is amortized
- by operations that do use them. We may re-consider this decision once
- we are able to optimize the tree before estimating its size and break
- out static initializers. */
- case IDENTIFIER_NODE:
- case INTEGER_CST:
- case REAL_CST:
- case FIXED_CST:
- case COMPLEX_CST:
- case VECTOR_CST:
- case STRING_CST:
- case PREDICT_EXPR:
- *walk_subtrees = 0;
- return NULL;
-
- /* CHANGE_DYNAMIC_TYPE_EXPR explicitly expands to nothing. */
- case CHANGE_DYNAMIC_TYPE_EXPR:
- *walk_subtrees = 0;
- return NULL;
-
- /* Try to estimate the cost of assignments. We have three cases to
- deal with:
- 1) Simple assignments to registers;
- 2) Stores to things that must live in memory. This includes
- "normal" stores to scalars, but also assignments of large
- structures, or constructors of big arrays;
- 3) TARGET_EXPRs.
-
- Let us look at the first two cases, assuming we have "a = b + C":
- <GIMPLE_MODIFY_STMT <var_decl "a">
- <plus_expr <var_decl "b"> <constant C>>
- If "a" is a GIMPLE register, the assignment to it is free on almost
- any target, because "a" usually ends up in a real register. Hence
- the only cost of this expression comes from the PLUS_EXPR, and we
- can ignore the GIMPLE_MODIFY_STMT.
- If "a" is not a GIMPLE register, the assignment to "a" will most
- likely be a real store, so the cost of the GIMPLE_MODIFY_STMT is the cost
- of moving something into "a", which we compute using the function
- estimate_move_cost.
-
- The third case deals with TARGET_EXPRs, for which the semantics are
- that a temporary is assigned, unless the TARGET_EXPR itself is being
- assigned to something else. In the latter case we do not need the
- temporary. E.g. in:
- <GIMPLE_MODIFY_STMT <var_decl "a"> <target_expr>>, the
- GIMPLE_MODIFY_STMT is free. */
- case INIT_EXPR:
- case GIMPLE_MODIFY_STMT:
- /* Is the right and side a TARGET_EXPR? */
- if (TREE_CODE (GENERIC_TREE_OPERAND (x, 1)) == TARGET_EXPR)
- break;
- /* ... fall through ... */
-
- case TARGET_EXPR:
- x = GENERIC_TREE_OPERAND (x, 0);
- /* Is this an assignments to a register? */
- if (is_gimple_reg (x))
- break;
- /* Otherwise it's a store, so fall through to compute the move cost. */
-
- case CONSTRUCTOR:
- d->count += estimate_move_cost (TREE_TYPE (x));
- break;
+ case CONVERT_EXPR:
+ case COMPLEX_EXPR:
+ case PAREN_EXPR:
+ case NOP_EXPR:
+ return 0;
/* Assign cost of 1 to usual operations.
??? We may consider mapping RTL costs to this. */
@@ -2363,15 +2700,15 @@ estimate_num_insns_1 (tree *tp, int *walk_subtrees, void *data)
case POSTDECREMENT_EXPR:
case POSTINCREMENT_EXPR:
- case ASM_EXPR:
-
case REALIGN_LOAD_EXPR:
case REDUC_MAX_EXPR:
case REDUC_MIN_EXPR:
case REDUC_PLUS_EXPR:
case WIDEN_SUM_EXPR:
- case DOT_PROD_EXPR:
+ case WIDEN_MULT_EXPR:
+ case DOT_PROD_EXPR:
+
case VEC_WIDEN_MULT_HI_EXPR:
case VEC_WIDEN_MULT_LO_EXPR:
case VEC_UNPACK_HI_EXPR:
@@ -2381,26 +2718,12 @@ estimate_num_insns_1 (tree *tp, int *walk_subtrees, void *data)
case VEC_PACK_TRUNC_EXPR:
case VEC_PACK_SAT_EXPR:
case VEC_PACK_FIX_TRUNC_EXPR:
-
- case WIDEN_MULT_EXPR:
-
case VEC_EXTRACT_EVEN_EXPR:
case VEC_EXTRACT_ODD_EXPR:
case VEC_INTERLEAVE_HIGH_EXPR:
case VEC_INTERLEAVE_LOW_EXPR:
- case RESX_EXPR:
- d->count += 1;
- break;
-
- case SWITCH_EXPR:
- /* Take into account cost of the switch + guess 2 conditional jumps for
- each case label.
-
- TODO: once the switch expansion logic is sufficiently separated, we can
- do better job on estimating cost of the switch. */
- d->count += TREE_VEC_LENGTH (SWITCH_LABELS (x)) * 2;
- break;
+ return 1;
/* Few special cases of expensive operations. This is useful
to avoid inlining on functions having too many of these. */
@@ -2414,34 +2737,115 @@ estimate_num_insns_1 (tree *tp, int *walk_subtrees, void *data)
case FLOOR_MOD_EXPR:
case ROUND_MOD_EXPR:
case RDIV_EXPR:
- d->count += d->weights->div_mod_cost;
+ return weights->div_mod_cost;
+
+ default:
+ /* We expect a copy assignment with no operator. */
+ gcc_assert (get_gimple_rhs_class (code) == GIMPLE_SINGLE_RHS);
+ return 0;
+ }
+}
+
+
+/* Estimate number of instructions that will be created by expanding
+ the statements in the statement sequence STMTS.
+ WEIGHTS contains weights attributed to various constructs. */
+
+static
+int estimate_num_insns_seq (gimple_seq stmts, eni_weights *weights)
+{
+ int cost;
+ gimple_stmt_iterator gsi;
+
+ cost = 0;
+ for (gsi = gsi_start (stmts); !gsi_end_p (gsi); gsi_next (&gsi))
+ cost += estimate_num_insns (gsi_stmt (gsi), weights);
+
+ return cost;
+}
+
+
+/* Estimate number of instructions that will be created by expanding STMT.
+ WEIGHTS contains weights attributed to various constructs. */
+
+int
+estimate_num_insns (gimple stmt, eni_weights *weights)
+{
+ unsigned cost, i;
+ enum gimple_code code = gimple_code (stmt);
+ tree lhs;
+
+ switch (code)
+ {
+ case GIMPLE_ASSIGN:
+ /* Try to estimate the cost of assignments. We have three cases to
+ deal with:
+ 1) Simple assignments to registers;
+ 2) Stores to things that must live in memory. This includes
+ "normal" stores to scalars, but also assignments of large
+ structures, or constructors of big arrays;
+
+ Let us look at the first two cases, assuming we have "a = b + C":
+ <GIMPLE_ASSIGN <var_decl "a">
+ <plus_expr <var_decl "b"> <constant C>>
+ If "a" is a GIMPLE register, the assignment to it is free on almost
+ any target, because "a" usually ends up in a real register. Hence
+ the only cost of this expression comes from the PLUS_EXPR, and we
+ can ignore the GIMPLE_ASSIGN.
+ If "a" is not a GIMPLE register, the assignment to "a" will most
+ likely be a real store, so the cost of the GIMPLE_ASSIGN is the cost
+ of moving something into "a", which we compute using the function
+ estimate_move_cost. */
+ lhs = gimple_assign_lhs (stmt);
+ if (is_gimple_reg (lhs))
+ cost = 0;
+ else
+ cost = estimate_move_cost (TREE_TYPE (lhs));
+
+ cost += estimate_operator_cost (gimple_assign_rhs_code (stmt), weights);
+ break;
+
+ case GIMPLE_COND:
+ cost = 1 + estimate_operator_cost (gimple_cond_code (stmt), weights);
+ break;
+
+ case GIMPLE_SWITCH:
+ /* Take into account cost of the switch + guess 2 conditional jumps for
+ each case label.
+
+ TODO: once the switch expansion logic is sufficiently separated, we can
+ do better job on estimating cost of the switch. */
+ cost = gimple_switch_num_labels (stmt) * 2;
break;
- case CALL_EXPR:
+
+ case GIMPLE_CALL:
{
- tree decl = get_callee_fndecl (x);
- tree addr = CALL_EXPR_FN (x);
+ tree decl = gimple_call_fndecl (stmt);
+ tree addr = gimple_call_fn (stmt);
tree funtype = TREE_TYPE (addr);
- gcc_assert (POINTER_TYPE_P (funtype));
- funtype = TREE_TYPE (funtype);
+ if (POINTER_TYPE_P (funtype))
+ funtype = TREE_TYPE (funtype);
if (decl && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_MD)
- cost = d->weights->target_builtin_call_cost;
+ cost = weights->target_builtin_call_cost;
else
- cost = d->weights->call_cost;
+ cost = weights->call_cost;
if (decl && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL)
switch (DECL_FUNCTION_CODE (decl))
{
case BUILT_IN_CONSTANT_P:
- *walk_subtrees = 0;
- return NULL_TREE;
+ return 0;
case BUILT_IN_EXPECT:
- return NULL_TREE;
+ cost = 0;
+ break;
+
/* Prefetch instruction is not expensive. */
case BUILT_IN_PREFETCH:
- cost = 1;
+ cost = weights->target_builtin_call_cost;
break;
+
default:
break;
}
@@ -2449,96 +2853,117 @@ estimate_num_insns_1 (tree *tp, int *walk_subtrees, void *data)
if (decl)
funtype = TREE_TYPE (decl);
- /* Our cost must be kept in sync with cgraph_estimate_size_after_inlining
- that does use function declaration to figure out the arguments.
-
- When we deal with function with no body nor prototype, base estimates on
- actual parameters of the call expression. Otherwise use either the actual
- arguments types or function declaration for more precise answer. */
+ /* Our cost must be kept in sync with
+ cgraph_estimate_size_after_inlining that does use function
+ declaration to figure out the arguments. */
if (decl && DECL_ARGUMENTS (decl))
{
tree arg;
for (arg = DECL_ARGUMENTS (decl); arg; arg = TREE_CHAIN (arg))
- d->count += estimate_move_cost (TREE_TYPE (arg));
+ cost += estimate_move_cost (TREE_TYPE (arg));
}
else if (funtype && prototype_p (funtype))
{
tree t;
for (t = TYPE_ARG_TYPES (funtype); t; t = TREE_CHAIN (t))
- d->count += estimate_move_cost (TREE_VALUE (t));
+ cost += estimate_move_cost (TREE_VALUE (t));
}
else
{
- tree a;
- call_expr_arg_iterator iter;
- FOR_EACH_CALL_EXPR_ARG (a, iter, x)
- d->count += estimate_move_cost (TREE_TYPE (a));
+ for (i = 0; i < gimple_call_num_args (stmt); i++)
+ {
+ tree arg = gimple_call_arg (stmt, i);
+ cost += estimate_move_cost (TREE_TYPE (arg));
+ }
}
- d->count += cost;
break;
}
- case OMP_PARALLEL:
- case OMP_TASK:
- case OMP_FOR:
- case OMP_SECTIONS:
- case OMP_SINGLE:
- case OMP_SECTION:
- case OMP_MASTER:
- case OMP_ORDERED:
- case OMP_CRITICAL:
- case OMP_ATOMIC:
- case OMP_ATOMIC_LOAD:
- /* OpenMP directives are generally very expensive. */
- d->count += d->weights->omp_cost;
- break;
+ case GIMPLE_GOTO:
+ case GIMPLE_LABEL:
+ case GIMPLE_NOP:
+ case GIMPLE_PHI:
+ case GIMPLE_RETURN:
+ case GIMPLE_CHANGE_DYNAMIC_TYPE:
+ case GIMPLE_PREDICT:
+ return 0;
+
+ case GIMPLE_ASM:
+ case GIMPLE_RESX:
+ return 1;
+
+ case GIMPLE_BIND:
+ return estimate_num_insns_seq (gimple_bind_body (stmt), weights);
+
+ case GIMPLE_EH_FILTER:
+ return estimate_num_insns_seq (gimple_eh_filter_failure (stmt), weights);
+
+ case GIMPLE_CATCH:
+ return estimate_num_insns_seq (gimple_catch_handler (stmt), weights);
+
+ case GIMPLE_TRY:
+ return (estimate_num_insns_seq (gimple_try_eval (stmt), weights)
+ + estimate_num_insns_seq (gimple_try_cleanup (stmt), weights));
+
+ /* OpenMP directives are generally very expensive. */
+
+ case GIMPLE_OMP_RETURN:
+ case GIMPLE_OMP_SECTIONS_SWITCH:
+ case GIMPLE_OMP_ATOMIC_STORE:
+ case GIMPLE_OMP_CONTINUE:
+ /* ...except these, which are cheap. */
+ return 0;
+
+ case GIMPLE_OMP_ATOMIC_LOAD:
+ return weights->omp_cost;
+
+ case GIMPLE_OMP_FOR:
+ return (weights->omp_cost
+ + estimate_num_insns_seq (gimple_omp_body (stmt), weights)
+ + estimate_num_insns_seq (gimple_omp_for_pre_body (stmt), weights));
+
+ case GIMPLE_OMP_PARALLEL:
+ case GIMPLE_OMP_TASK:
+ case GIMPLE_OMP_CRITICAL:
+ case GIMPLE_OMP_MASTER:
+ case GIMPLE_OMP_ORDERED:
+ case GIMPLE_OMP_SECTION:
+ case GIMPLE_OMP_SECTIONS:
+ case GIMPLE_OMP_SINGLE:
+ return (weights->omp_cost
+ + estimate_num_insns_seq (gimple_omp_body (stmt), weights));
default:
gcc_unreachable ();
}
- return NULL;
+
+ return cost;
}
-/* Estimate number of instructions that will be created by expanding EXPR.
- WEIGHTS contains weights attributed to various constructs. */
+/* Estimate number of instructions that will be created by expanding
+ function FNDECL. WEIGHTS contains weights attributed to various
+ constructs. */
int
-estimate_num_insns (tree expr, eni_weights *weights)
+estimate_num_insns_fn (tree fndecl, eni_weights *weights)
{
- struct pointer_set_t *visited_nodes;
+ struct function *my_function = DECL_STRUCT_FUNCTION (fndecl);
+ gimple_stmt_iterator bsi;
basic_block bb;
- block_stmt_iterator bsi;
- struct function *my_function;
- struct eni_data data;
-
- data.count = 0;
- data.weights = weights;
+ int n = 0;
- /* If we're given an entire function, walk the CFG. */
- if (TREE_CODE (expr) == FUNCTION_DECL)
+ gcc_assert (my_function && my_function->cfg);
+ FOR_EACH_BB_FN (bb, my_function)
{
- my_function = DECL_STRUCT_FUNCTION (expr);
- gcc_assert (my_function && my_function->cfg);
- visited_nodes = pointer_set_create ();
- FOR_EACH_BB_FN (bb, my_function)
- {
- for (bsi = bsi_start (bb);
- !bsi_end_p (bsi);
- bsi_next (&bsi))
- {
- walk_tree (bsi_stmt_ptr (bsi), estimate_num_insns_1,
- &data, visited_nodes);
- }
- }
- pointer_set_destroy (visited_nodes);
+ for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi))
+ n += estimate_num_insns (gsi_stmt (bsi), weights);
}
- else
- walk_tree_without_duplicates (&expr, estimate_num_insns_1, &data);
- return data.count;
+ return n;
}
+
/* Initializes weights used by estimate_num_insns. */
void
@@ -2564,7 +2989,22 @@ init_inline_once (void)
eni_time_weights.omp_cost = 40;
}
+/* Estimate the number of instructions in a gimple_seq. */
+
+int
+count_insns_seq (gimple_seq seq, eni_weights *weights)
+{
+ gimple_stmt_iterator gsi;
+ int n = 0;
+ for (gsi = gsi_start (seq); !gsi_end_p (gsi); gsi_next (&gsi))
+ n += estimate_num_insns (gsi_stmt (gsi), weights);
+
+ return n;
+}
+
+
/* Install new lexical TREE_BLOCK underneath 'current_block'. */
+
static void
add_lexical_block (tree current_block, tree new_block)
{
@@ -2579,13 +3019,25 @@ add_lexical_block (tree current_block, tree new_block)
BLOCK_SUPERCONTEXT (new_block) = current_block;
}
-/* If *TP is a CALL_EXPR, replace it with its inline expansion. */
+/* Fetch callee declaration from the call graph edge going from NODE and
+ associated with STMR call statement. Return NULL_TREE if not found. */
+static tree
+get_indirect_callee_fndecl (struct cgraph_node *node, gimple stmt)
+{
+ struct cgraph_edge *cs;
+
+ cs = cgraph_edge (node, stmt);
+ if (cs)
+ return cs->callee->decl;
+
+ return NULL_TREE;
+}
+
+/* If STMT is a GIMPLE_CALL, replace it with its inline expansion. */
static bool
-expand_call_inline (basic_block bb, tree stmt, tree *tp, void *data)
+expand_call_inline (basic_block bb, gimple stmt, copy_body_data *id)
{
- copy_body_data *id;
- tree t;
tree retvar, use_retvar;
tree fn;
struct pointer_map_t *st;
@@ -2596,45 +3048,45 @@ expand_call_inline (basic_block bb, tree stmt, tree *tp, void *data)
const char *reason;
basic_block return_block;
edge e;
- block_stmt_iterator bsi, stmt_bsi;
+ gimple_stmt_iterator gsi, stmt_gsi;
bool successfully_inlined = FALSE;
bool purge_dead_abnormal_edges;
tree t_step;
tree var;
- /* See what we've got. */
- id = (copy_body_data *) data;
- t = *tp;
-
/* Set input_location here so we get the right instantiation context
if we call instantiate_decl from inlinable_function_p. */
saved_location = input_location;
- if (EXPR_HAS_LOCATION (t))
- input_location = EXPR_LOCATION (t);
+ if (gimple_has_location (stmt))
+ input_location = gimple_location (stmt);
/* From here on, we're only interested in CALL_EXPRs. */
- if (TREE_CODE (t) != CALL_EXPR)
+ if (gimple_code (stmt) != GIMPLE_CALL)
goto egress;
/* First, see if we can figure out what function is being called.
If we cannot, then there is no hope of inlining the function. */
- fn = get_callee_fndecl (t);
+ fn = gimple_call_fndecl (stmt);
if (!fn)
- goto egress;
+ {
+ fn = get_indirect_callee_fndecl (id->dst_node, stmt);
+ if (!fn)
+ goto egress;
+ }
/* Turn forward declarations into real ones. */
fn = cgraph_node (fn)->decl;
- /* If fn is a declaration of a function in a nested scope that was
+ /* If FN is a declaration of a function in a nested scope that was
globally declared inline, we don't set its DECL_INITIAL.
However, we can't blindly follow DECL_ABSTRACT_ORIGIN because the
C++ front-end uses it for cdtors to refer to their internal
declarations, that are not real functions. Fortunately those
don't have trees to be saved, so we can tell by checking their
- DECL_SAVED_TREE. */
- if (! DECL_INITIAL (fn)
+ gimple_body. */
+ if (!DECL_INITIAL (fn)
&& DECL_ABSTRACT_ORIGIN (fn)
- && DECL_SAVED_TREE (DECL_ABSTRACT_ORIGIN (fn)))
+ && gimple_body (DECL_ABSTRACT_ORIGIN (fn)))
fn = DECL_ABSTRACT_ORIGIN (fn);
/* Objective C and fortran still calls tree_rest_of_compilation directly.
@@ -2654,7 +3106,7 @@ expand_call_inline (basic_block bb, tree stmt, tree *tp, void *data)
where previous inlining turned indirect call into direct call by
constant propagating arguments. In all other cases we hit a bug
(incorrect node sharing is most common reason for missing edges. */
- gcc_assert (dest->needed || !flag_unit_at_a_time);
+ gcc_assert (dest->needed);
cgraph_create_edge (id->dst_node, dest, stmt,
bb->count, CGRAPH_FREQ_BASE,
bb->loop_depth)->inline_failed
@@ -2671,9 +3123,15 @@ expand_call_inline (basic_block bb, tree stmt, tree *tp, void *data)
inlining. */
if (!cgraph_inline_p (cg_edge, &reason))
{
+ /* If this call was originally indirect, we do not want to emit any
+ inlining related warnings or sorry messages because there are no
+ guarantees regarding those. */
+ if (cg_edge->indirect_call)
+ goto egress;
+
if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn))
/* Avoid warnings during early inline pass. */
- && (!flag_unit_at_a_time || cgraph_global_info_ready))
+ && cgraph_global_info_ready)
{
sorry ("inlining failed in call to %q+F: %s", fn, reason);
sorry ("called from here");
@@ -2683,7 +3141,7 @@ expand_call_inline (basic_block bb, tree stmt, tree *tp, void *data)
&& strlen (reason)
&& !lookup_attribute ("noinline", DECL_ATTRIBUTES (fn))
/* Avoid warnings during early inline pass. */
- && (!flag_unit_at_a_time || cgraph_global_info_ready))
+ && cgraph_global_info_ready)
{
warning (OPT_Winline, "inlining failed in call to %q+F: %s",
fn, reason);
@@ -2701,7 +3159,7 @@ expand_call_inline (basic_block bb, tree stmt, tree *tp, void *data)
/* We will be inlining this callee. */
id->eh_region = lookup_stmt_eh_region (stmt);
- /* Split the block holding the CALL_EXPR. */
+ /* Split the block holding the GIMPLE_CALL. */
e = split_block (bb, stmt);
bb = e->src;
return_block = e->dest;
@@ -2710,26 +3168,26 @@ expand_call_inline (basic_block bb, tree stmt, tree *tp, void *data)
/* split_block splits after the statement; work around this by
moving the call into the second block manually. Not pretty,
but seems easier than doing the CFG manipulation by hand
- when the CALL_EXPR is in the last statement of BB. */
- stmt_bsi = bsi_last (bb);
- bsi_remove (&stmt_bsi, false);
+ when the GIMPLE_CALL is in the last statement of BB. */
+ stmt_gsi = gsi_last_bb (bb);
+ gsi_remove (&stmt_gsi, false);
- /* If the CALL_EXPR was in the last statement of BB, it may have
+ /* If the GIMPLE_CALL was in the last statement of BB, it may have
been the source of abnormal edges. In this case, schedule
the removal of dead abnormal edges. */
- bsi = bsi_start (return_block);
- if (bsi_end_p (bsi))
+ gsi = gsi_start_bb (return_block);
+ if (gsi_end_p (gsi))
{
- bsi_insert_after (&bsi, stmt, BSI_NEW_STMT);
+ gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
purge_dead_abnormal_edges = true;
}
else
{
- bsi_insert_before (&bsi, stmt, BSI_NEW_STMT);
+ gsi_insert_before (&gsi, stmt, GSI_NEW_STMT);
purge_dead_abnormal_edges = false;
}
- stmt_bsi = bsi_start (return_block);
+ stmt_gsi = gsi_start_bb (return_block);
/* Build a block containing code to initialize the arguments, the
actual inline expansion of the body, and a label for the return
@@ -2738,7 +3196,7 @@ expand_call_inline (basic_block bb, tree stmt, tree *tp, void *data)
id->block = make_node (BLOCK);
BLOCK_ABSTRACT_ORIGIN (id->block) = fn;
BLOCK_SOURCE_LOCATION (id->block) = input_location;
- add_lexical_block (TREE_BLOCK (stmt), id->block);
+ add_lexical_block (gimple_block (stmt), id->block);
/* Local declarations will be replaced by their equivalents in this
map. */
@@ -2749,27 +3207,26 @@ expand_call_inline (basic_block bb, tree stmt, tree *tp, void *data)
id->src_fn = fn;
id->src_node = cg_edge->callee;
id->src_cfun = DECL_STRUCT_FUNCTION (fn);
- id->call_expr = t;
+ id->gimple_call = stmt;
gcc_assert (!id->src_cfun->after_inlining);
id->entry_bb = bb;
- initialize_inlined_parameters (id, t, fn, bb);
+ initialize_inlined_parameters (id, stmt, fn, bb);
if (DECL_INITIAL (fn))
add_lexical_block (id->block, remap_blocks (DECL_INITIAL (fn), id));
/* Return statements in the function body will be replaced by jumps
to the RET_LABEL. */
-
gcc_assert (DECL_INITIAL (fn));
gcc_assert (TREE_CODE (DECL_INITIAL (fn)) == BLOCK);
- /* Find the lhs to which the result of this call is assigned. */
+ /* Find the LHS to which the result of this call is assigned. */
return_slot = NULL;
- if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT)
+ if (gimple_call_lhs (stmt))
{
- modify_dest = GIMPLE_STMT_OPERAND (stmt, 0);
+ modify_dest = gimple_call_lhs (stmt);
/* The function which we are inlining might not return a value,
in which case we should issue a warning that the function
@@ -2779,7 +3236,8 @@ expand_call_inline (basic_block bb, tree stmt, tree *tp, void *data)
uninitialized variable. */
if (DECL_P (modify_dest))
TREE_NO_WARNING (modify_dest) = 1;
- if (CALL_EXPR_RETURN_SLOT_OPT (t))
+
+ if (gimple_call_return_slot_opt_p (stmt))
{
return_slot = modify_dest;
modify_dest = NULL;
@@ -2800,8 +3258,7 @@ expand_call_inline (basic_block bb, tree stmt, tree *tp, void *data)
}
/* Declare the return variable for the function. */
- retvar = declare_return_variable (id, return_slot,
- modify_dest, &use_retvar);
+ retvar = declare_return_variable (id, return_slot, modify_dest, &use_retvar);
if (DECL_IS_OPERATOR_NEW (fn))
{
@@ -2835,56 +3292,65 @@ expand_call_inline (basic_block bb, tree stmt, tree *tp, void *data)
id->decl_map = st;
/* If the inlined function returns a result that we care about,
- clobber the CALL_EXPR with a reference to the return variable. */
- if (use_retvar && (TREE_CODE (bsi_stmt (stmt_bsi)) != CALL_EXPR))
+ substitute the GIMPLE_CALL with an assignment of the return
+ variable to the LHS of the call. That is, if STMT was
+ 'a = foo (...)', substitute the call with 'a = USE_RETVAR'. */
+ if (use_retvar && gimple_call_lhs (stmt))
{
- *tp = use_retvar;
+ gimple old_stmt = stmt;
+ stmt = gimple_build_assign (gimple_call_lhs (stmt), use_retvar);
+ gsi_replace (&stmt_gsi, stmt, false);
if (gimple_in_ssa_p (cfun))
{
update_stmt (stmt);
mark_symbols_for_renaming (stmt);
}
- maybe_clean_or_replace_eh_stmt (stmt, stmt);
+ maybe_clean_or_replace_eh_stmt (old_stmt, stmt);
}
else
- /* We're modifying a TSI owned by gimple_expand_calls_inline();
- tsi_delink() will leave the iterator in a sane state. */
{
- /* Handle case of inlining function that miss return statement so
- return value becomes undefined. */
- if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT
- && TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 0)) == SSA_NAME)
+ /* Handle the case of inlining a function with no return
+ statement, which causes the return value to become undefined. */
+ if (gimple_call_lhs (stmt)
+ && TREE_CODE (gimple_call_lhs (stmt)) == SSA_NAME)
{
- tree name = GIMPLE_STMT_OPERAND (stmt, 0);
- tree var = SSA_NAME_VAR (GIMPLE_STMT_OPERAND (stmt, 0));
+ tree name = gimple_call_lhs (stmt);
+ tree var = SSA_NAME_VAR (name);
tree def = gimple_default_def (cfun, var);
- /* If the variable is used undefined, make this name undefined via
- move. */
if (def)
{
- GIMPLE_STMT_OPERAND (stmt, 1) = def;
+ /* If the variable is used undefined, make this name
+ undefined via a move. */
+ stmt = gimple_build_assign (gimple_call_lhs (stmt), def);
+ gsi_replace (&stmt_gsi, stmt, true);
update_stmt (stmt);
}
- /* Otherwise make this variable undefined. */
else
{
- bsi_remove (&stmt_bsi, true);
+ /* Otherwise make this variable undefined. */
+ gsi_remove (&stmt_gsi, true);
set_default_def (var, name);
- SSA_NAME_DEF_STMT (name) = build_empty_stmt ();
+ SSA_NAME_DEF_STMT (name) = gimple_build_nop ();
}
}
else
- bsi_remove (&stmt_bsi, true);
+ gsi_remove (&stmt_gsi, true);
}
if (purge_dead_abnormal_edges)
- tree_purge_dead_abnormal_call_edges (return_block);
+ gimple_purge_dead_abnormal_call_edges (return_block);
/* If the value of the new expression is ignored, that's OK. We
don't warn about this for CALL_EXPRs, so we shouldn't warn about
the equivalent inlined version either. */
- TREE_USED (*tp) = 1;
+ if (is_gimple_assign (stmt))
+ {
+ gcc_assert (gimple_assign_single_p (stmt)
+ || gimple_assign_rhs_code (stmt) == NOP_EXPR
+ || gimple_assign_rhs_code (stmt) == CONVERT_EXPR);
+ TREE_USED (gimple_assign_rhs1 (stmt)) = 1;
+ }
/* Output the inlining info for this abstract function, since it has been
inlined. If we don't do this now, we can lose the information about the
@@ -2905,58 +3371,58 @@ expand_call_inline (basic_block bb, tree stmt, tree *tp, void *data)
/* Expand call statements reachable from STMT_P.
We can only have CALL_EXPRs as the "toplevel" tree code or nested
- in a GIMPLE_MODIFY_STMT. See tree-gimple.c:get_call_expr_in(). We can
+ in a MODIFY_EXPR. See tree-gimple.c:get_call_expr_in(). We can
unfortunately not use that function here because we need a pointer
to the CALL_EXPR, not the tree itself. */
static bool
gimple_expand_calls_inline (basic_block bb, copy_body_data *id)
{
- block_stmt_iterator bsi;
+ gimple_stmt_iterator gsi;
- /* Register specific tree functions. */
- tree_register_cfg_hooks ();
- for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
- tree *expr_p = bsi_stmt_ptr (bsi);
- tree stmt = *expr_p;
+ gimple stmt = gsi_stmt (gsi);
- if (TREE_CODE (*expr_p) == GIMPLE_MODIFY_STMT)
- expr_p = &GIMPLE_STMT_OPERAND (*expr_p, 1);
- if (TREE_CODE (*expr_p) == WITH_SIZE_EXPR)
- expr_p = &TREE_OPERAND (*expr_p, 0);
- if (TREE_CODE (*expr_p) == CALL_EXPR)
- if (expand_call_inline (bb, stmt, expr_p, id))
- return true;
+ if (is_gimple_call (stmt)
+ && expand_call_inline (bb, stmt, id))
+ return true;
}
+
return false;
}
+
/* Walk all basic blocks created after FIRST and try to fold every statement
in the STATEMENTS pointer set. */
+
static void
fold_marked_statements (int first, struct pointer_set_t *statements)
{
- for (;first < n_basic_blocks;first++)
+ for (; first < n_basic_blocks; first++)
if (BASIC_BLOCK (first))
{
- block_stmt_iterator bsi;
- for (bsi = bsi_start (BASIC_BLOCK (first));
- !bsi_end_p (bsi); bsi_next (&bsi))
- if (pointer_set_contains (statements, bsi_stmt (bsi)))
+ gimple_stmt_iterator gsi;
+
+ for (gsi = gsi_start_bb (BASIC_BLOCK (first));
+ !gsi_end_p (gsi);
+ gsi_next (&gsi))
+ if (pointer_set_contains (statements, gsi_stmt (gsi)))
{
- tree old_stmt = bsi_stmt (bsi);
- tree old_call = get_call_expr_in (old_stmt);
+ gimple old_stmt = gsi_stmt (gsi);
- if (fold_stmt (bsi_stmt_ptr (bsi)))
+ if (fold_stmt (&gsi))
{
- update_stmt (bsi_stmt (bsi));
- if (old_call)
- cgraph_update_edges_for_call_stmt (old_stmt, old_call,
- bsi_stmt (bsi));
- if (maybe_clean_or_replace_eh_stmt (old_stmt,
- bsi_stmt (bsi)))
- tree_purge_dead_eh_edges (BASIC_BLOCK (first));
+ /* Re-read the statement from GSI as fold_stmt() may
+ have changed it. */
+ gimple new_stmt = gsi_stmt (gsi);
+ update_stmt (new_stmt);
+
+ if (is_gimple_call (old_stmt))
+ cgraph_update_edges_for_call_stmt (old_stmt, new_stmt);
+
+ if (maybe_clean_or_replace_eh_stmt (old_stmt, new_stmt))
+ gimple_purge_dead_eh_edges (BASIC_BLOCK (first));
}
}
}
@@ -2986,6 +3452,8 @@ optimize_inline_calls (tree fn)
tree prev_fn;
basic_block bb;
int last = n_basic_blocks;
+ struct gimplify_ctx gctx;
+
/* There is no point in performing inlining if errors have already
occurred -- and we might crash if we try to inline invalid
code. */
@@ -3012,12 +3480,15 @@ optimize_inline_calls (tree fn)
id.transform_lang_insert_block = NULL;
id.statements_to_fold = pointer_set_create ();
- push_gimplify_context ();
+ push_gimplify_context (&gctx);
/* We make no attempts to keep dominance info up-to-date. */
free_dominance_info (CDI_DOMINATORS);
free_dominance_info (CDI_POST_DOMINATORS);
+ /* Register specific gimple functions. */
+ gimple_register_cfg_hooks ();
+
/* Reach the trees by walking over the CFG, and note the
enclosing basic-blocks in the call edges. */
/* We walk the blocks going forward, because inlined function bodies
@@ -3055,11 +3526,13 @@ optimize_inline_calls (tree fn)
cgraph_node_remove_callees (id.dst_node);
fold_cond_expr_cond ();
+
/* It would be nice to check SSA/CFG/statement consistency here, but it is
not possible yet - the IPA passes might make various functions to not
throw and they don't care to proactively update local EH info. This is
done later in fixup_cfg pass that also execute the verification. */
- return (TODO_update_ssa | TODO_cleanup_cfg
+ return (TODO_update_ssa
+ | TODO_cleanup_cfg
| (gimple_in_ssa_p (cfun) ? TODO_remove_unused_locals : 0)
| (profile_status != PROFILE_ABSENT ? TODO_rebuild_frequencies : 0));
}
@@ -3074,7 +3547,6 @@ copy_tree_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
/* We make copies of most nodes. */
if (IS_EXPR_CODE_CLASS (cl)
- || IS_GIMPLE_STMT_CODE_CLASS (cl)
|| code == TREE_LIST
|| code == TREE_VEC
|| code == TYPE_DECL
@@ -3084,8 +3556,7 @@ copy_tree_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
here. */
tree chain = NULL_TREE, new;
- if (!GIMPLE_TUPLE_P (*tp))
- chain = TREE_CHAIN (*tp);
+ chain = TREE_CHAIN (*tp);
/* Copy the node. */
new = copy_node (*tp);
@@ -3245,7 +3716,7 @@ unsave_r (tree *tp, int *walk_subtrees, void *data)
}
else if (TREE_CODE (*tp) == STATEMENT_LIST)
- copy_statement_list (tp);
+ gcc_unreachable ();
else if (TREE_CODE (*tp) == BIND_EXPR)
copy_bind_expr (tp, walk_subtrees, id);
else if (TREE_CODE (*tp) == SAVE_EXPR)
@@ -3298,6 +3769,162 @@ unsave_expr_now (tree expr)
return expr;
}
+/* Called via walk_gimple_seq. If *GSIP points to a GIMPLE_LABEL for a local
+ label, copies the declaration and enters it in the splay_tree in DATA (which
+ is really a 'copy_body_data *'. */
+
+static tree
+mark_local_labels_stmt (gimple_stmt_iterator *gsip,
+ bool *handled_ops_p ATTRIBUTE_UNUSED,
+ struct walk_stmt_info *wi)
+{
+ copy_body_data *id = (copy_body_data *) wi->info;
+ gimple stmt = gsi_stmt (*gsip);
+
+ if (gimple_code (stmt) == GIMPLE_LABEL)
+ {
+ tree decl = gimple_label_label (stmt);
+
+ /* Copy the decl and remember the copy. */
+ insert_decl_map (id, decl, id->copy_decl (decl, id));
+ }
+
+ return NULL_TREE;
+}
+
+
+/* Called via walk_gimple_seq by copy_gimple_seq_and_replace_local.
+ Using the splay_tree pointed to by ST (which is really a `splay_tree'),
+ remaps all local declarations to appropriate replacements in gimple
+ operands. */
+
+static tree
+replace_locals_op (tree *tp, int *walk_subtrees, void *data)
+{
+ struct walk_stmt_info *wi = (struct walk_stmt_info*) data;
+ copy_body_data *id = (copy_body_data *) wi->info;
+ struct pointer_map_t *st = id->decl_map;
+ tree *n;
+ tree expr = *tp;
+
+ /* Only a local declaration (variable or label). */
+ if ((TREE_CODE (expr) == VAR_DECL
+ && !TREE_STATIC (expr))
+ || TREE_CODE (expr) == LABEL_DECL)
+ {
+ /* Lookup the declaration. */
+ n = (tree *) pointer_map_contains (st, expr);
+
+ /* If it's there, remap it. */
+ if (n)
+ *tp = *n;
+ *walk_subtrees = 0;
+ }
+ else if (TREE_CODE (expr) == STATEMENT_LIST
+ || TREE_CODE (expr) == BIND_EXPR
+ || TREE_CODE (expr) == SAVE_EXPR)
+ gcc_unreachable ();
+ else if (TREE_CODE (expr) == TARGET_EXPR)
+ {
+ /* Don't mess with a TARGET_EXPR that hasn't been expanded.
+ It's OK for this to happen if it was part of a subtree that
+ isn't immediately expanded, such as operand 2 of another
+ TARGET_EXPR. */
+ if (!TREE_OPERAND (expr, 1))
+ {
+ TREE_OPERAND (expr, 1) = TREE_OPERAND (expr, 3);
+ TREE_OPERAND (expr, 3) = NULL_TREE;
+ }
+ }
+
+ /* Keep iterating. */
+ return NULL_TREE;
+}
+
+
+/* Called via walk_gimple_seq by copy_gimple_seq_and_replace_local.
+ Using the splay_tree pointed to by ST (which is really a `splay_tree'),
+ remaps all local declarations to appropriate replacements in gimple
+ statements. */
+
+static tree
+replace_locals_stmt (gimple_stmt_iterator *gsip,
+ bool *handled_ops_p ATTRIBUTE_UNUSED,
+ struct walk_stmt_info *wi)
+{
+ copy_body_data *id = (copy_body_data *) wi->info;
+ gimple stmt = gsi_stmt (*gsip);
+
+ if (gimple_code (stmt) == GIMPLE_BIND)
+ {
+ tree block = gimple_bind_block (stmt);
+
+ if (block)
+ {
+ remap_block (&block, id);
+ gimple_bind_set_block (stmt, block);
+ }
+
+ /* This will remap a lot of the same decls again, but this should be
+ harmless. */
+ if (gimple_bind_vars (stmt))
+ gimple_bind_set_vars (stmt, remap_decls (gimple_bind_vars (stmt), id));
+ }
+
+ /* Keep iterating. */
+ return NULL_TREE;
+}
+
+
+/* Copies everything in SEQ and replaces variables and labels local to
+ current_function_decl. */
+
+gimple_seq
+copy_gimple_seq_and_replace_locals (gimple_seq seq)
+{
+ copy_body_data id;
+ struct walk_stmt_info wi;
+ struct pointer_set_t *visited;
+ gimple_seq copy;
+
+ /* There's nothing to do for NULL_TREE. */
+ if (seq == NULL)
+ return seq;
+
+ /* Set up ID. */
+ memset (&id, 0, sizeof (id));
+ id.src_fn = current_function_decl;
+ id.dst_fn = current_function_decl;
+ id.decl_map = pointer_map_create ();
+
+ id.copy_decl = copy_decl_no_change;
+ id.transform_call_graph_edges = CB_CGE_DUPLICATE;
+ id.transform_new_cfg = false;
+ id.transform_return_to_modify = false;
+ id.transform_lang_insert_block = NULL;
+
+ /* Walk the tree once to find local labels. */
+ memset (&wi, 0, sizeof (wi));
+ visited = pointer_set_create ();
+ wi.info = &id;
+ wi.pset = visited;
+ walk_gimple_seq (seq, mark_local_labels_stmt, NULL, &wi);
+ pointer_set_destroy (visited);
+
+ copy = gimple_seq_copy (seq);
+
+ /* Walk the copy, remapping decls. */
+ memset (&wi, 0, sizeof (wi));
+ wi.info = &id;
+ walk_gimple_seq (copy, replace_locals_stmt, replace_locals_op, &wi);
+
+ /* Clean up. */
+ pointer_map_destroy (id.decl_map);
+
+ return copy;
+}
+
+
/* Allow someone to determine if SEARCH is a child of TOP from gdb. */
static tree
@@ -3334,7 +3961,6 @@ declare_inline_vars (tree block, tree vars)
BLOCK_VARS (block) = chainon (BLOCK_VARS (block), vars);
}
-
/* Copy NODE (which must be a DECL). The DECL originally was in the FROM_FN,
but now it will be in the TO_FN. PARM_TO_VAR means enable PARM_DECL to
VAR_DECL translation. */
@@ -3427,7 +4053,6 @@ copy_result_decl_to_var (tree decl, copy_body_data *id)
return copy_decl_for_dup_finish (id, decl, copy);
}
-
tree
copy_decl_no_change (tree decl, copy_body_data *id)
{
@@ -3589,7 +4214,8 @@ tree_function_versioning (tree old_decl, tree new_decl, varray_type tree_map,
if (tree_map)
for (i = 0; i < VARRAY_ACTIVE_SIZE (tree_map); i++)
{
- replace_info = (struct ipa_replace_map *) VARRAY_GENERIC_PTR (tree_map, i);
+ replace_info
+ = (struct ipa_replace_map *) VARRAY_GENERIC_PTR (tree_map, i);
if (replace_info->replace_p)
insert_decl_map (&id, replace_info->old_tree,
replace_info->new_tree);
@@ -3680,3 +4306,34 @@ build_duplicate_type (tree type)
return type;
}
+
+/* Return whether it is safe to inline a function because it used different
+ target specific options or different optimization options. */
+bool
+tree_can_inline_p (tree caller, tree callee)
+{
+ /* Don't inline a function with a higher optimization level than the
+ caller, or with different space constraints (hot/cold functions). */
+ tree caller_tree = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (caller);
+ tree callee_tree = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (callee);
+
+ if (caller_tree != callee_tree)
+ {
+ struct cl_optimization *caller_opt
+ = TREE_OPTIMIZATION ((caller_tree)
+ ? caller_tree
+ : optimization_default_node);
+
+ struct cl_optimization *callee_opt
+ = TREE_OPTIMIZATION ((callee_tree)
+ ? callee_tree
+ : optimization_default_node);
+
+ if ((caller_opt->optimize > callee_opt->optimize)
+ || (caller_opt->optimize_size != callee_opt->optimize_size))
+ return false;
+ }
+
+ /* Allow the backend to decide if inlining is ok. */
+ return targetm.target_option.can_inline_p (caller, callee);
+}
diff --git a/gcc/tree-inline.h b/gcc/tree-inline.h
index a69afd00f99..e590e1465a7 100644
--- a/gcc/tree-inline.h
+++ b/gcc/tree-inline.h
@@ -32,13 +32,17 @@ typedef struct copy_body_data
/* FUNCTION_DECL for function being inlined, or in general the
source function providing the original trees. */
tree src_fn;
+
/* FUNCTION_DECL for function being inlined into, or in general
the destination function receiving the new trees. */
tree dst_fn;
+
/* Callgraph node of the source function. */
struct cgraph_node *src_node;
+
/* Callgraph node of the destination function. */
struct cgraph_node *dst_node;
+
/* struct function for function being inlined. Usually this is the same
as DECL_STRUCT_FUNCTION (src_fn), but can be different if saved_cfg
and saved_eh are in use. */
@@ -46,6 +50,7 @@ typedef struct copy_body_data
/* The VAR_DECL for the return value. */
tree retvar;
+
/* The map from local declarations in the inlined function to
equivalents in the function into which it is being inlined. */
struct pointer_map_t *decl_map;
@@ -56,12 +61,13 @@ typedef struct copy_body_data
/* Current BLOCK. */
tree block;
- /* CALL_EXPR if va arg parameter packs should be expanded or NULL
+ /* GIMPLE_CALL if va arg parameter packs should be expanded or NULL
is not. */
- tree call_expr;
+ gimple gimple_call;
/* Exception region the inlined call lie in. */
int eh_region;
+
/* Take region number in the function being copied, add this value and
get eh region number of the duplicate in the function we inline into. */
int eh_region_offset;
@@ -137,30 +143,27 @@ extern eni_weights eni_time_weights;
/* Function prototypes. */
-extern tree copy_body_r (tree *, int *, void *);
+extern tree copy_tree_body_r (tree *, int *, void *);
extern void insert_decl_map (copy_body_data *, tree, tree);
unsigned int optimize_inline_calls (tree);
bool tree_inlinable_function_p (tree);
tree copy_tree_r (tree *, int *, void *);
-tree copy_generic_body (copy_body_data *id);
tree copy_decl_no_change (tree decl, copy_body_data *id);
void save_body (tree, tree *, tree *);
int estimate_move_cost (tree type);
-int estimate_num_insns (tree expr, eni_weights *);
+int estimate_num_insns (gimple, eni_weights *);
+int estimate_num_insns_fn (tree, eni_weights *);
+int count_insns_seq (gimple_seq, eni_weights *);
bool tree_versionable_function_p (tree);
void tree_function_versioning (tree, tree, varray_type, bool);
+bool tree_can_inline_p (tree, tree);
+extern gimple_seq remap_gimple_seq (gimple_seq, copy_body_data *);
extern tree remap_decl (tree decl, copy_body_data *id);
extern tree remap_type (tree type, copy_body_data *id);
+extern gimple_seq copy_gimple_seq_and_replace_locals (gimple_seq seq);
extern HOST_WIDE_INT estimated_stack_frame_size (void);
-/* 0 if we should not perform inlining.
- 1 if we should expand functions calls inline at the tree level.
- 2 if we should consider *all* functions to be inline
- candidates. */
-
-extern int flag_inline_trees;
-
#endif /* GCC_TREE_INLINE_H */
diff --git a/gcc/tree-into-ssa.c b/gcc/tree-into-ssa.c
index c9e99efa9d1..fb61731893a 100644
--- a/gcc/tree-into-ssa.c
+++ b/gcc/tree-into-ssa.c
@@ -36,7 +36,7 @@ along with GCC; see the file COPYING3. If not see
#include "diagnostic.h"
#include "bitmap.h"
#include "tree-flow.h"
-#include "tree-gimple.h"
+#include "gimple.h"
#include "tree-inline.h"
#include "varray.h"
#include "timevar.h"
@@ -49,6 +49,7 @@ along with GCC; see the file COPYING3. If not see
#include "params.h"
#include "vecprim.h"
+
/* This file builds the SSA form for a function as described in:
R. Cytron, J. Ferrante, B. Rosen, M. Wegman, and K. Zadeck. Efficiently
Computing Static Single Assignment Form and the Control Dependence
@@ -102,6 +103,7 @@ static htab_t def_blocks;
associated with the current block. */
static VEC(tree,heap) *block_defs_stack;
+
/* Set of existing SSA names being replaced by update_ssa. */
static sbitmap old_ssa_names;
@@ -110,6 +112,7 @@ static sbitmap old_ssa_names;
the operations done on them are presence tests. */
static sbitmap new_ssa_names;
+
/* Symbols whose SSA form needs to be updated or created for the first
time. */
static bitmap syms_to_rename;
@@ -129,11 +132,11 @@ static bitmap names_to_release;
/* For each block, the PHI nodes that need to be rewritten are stored into
these vectors. */
-typedef VEC(tree, heap) *tree_vec;
-DEF_VEC_P (tree_vec);
-DEF_VEC_ALLOC_P (tree_vec, heap);
+typedef VEC(gimple, heap) *gimple_vec;
+DEF_VEC_P (gimple_vec);
+DEF_VEC_ALLOC_P (gimple_vec, heap);
-static VEC(tree_vec, heap) *phis_to_rewrite;
+static VEC(gimple_vec, heap) *phis_to_rewrite;
/* The bitmap of non-NULL elements of PHIS_TO_REWRITE. */
static bitmap blocks_with_phis_to_rewrite;
@@ -152,6 +155,7 @@ struct repl_map_d
bitmap set;
};
+
/* NEW -> OLD_SET replacement table. If we are replacing several
existing SSA names O_1, O_2, ..., O_j with a new name N_i,
then REPL_TBL[N_i] = { O_1, O_2, ..., O_j }. */
@@ -239,19 +243,6 @@ enum rewrite_mode {
};
-/* Use TREE_VISITED to keep track of which statements we want to
- rename. When renaming a subset of the variables, not all
- statements will be processed. This is decided in mark_def_sites. */
-#define REWRITE_THIS_STMT(T) TREE_VISITED (T)
-
-/* Use the unsigned flag to keep track of which statements we want to
- visit when marking new definition sites. This is slightly
- different than REWRITE_THIS_STMT: it's used by update_ssa to
- distinguish statements that need to have both uses and defs
- processed from those that only need to have their defs processed.
- Statements that define new SSA names only need to have their defs
- registered, but they don't need to have their uses renamed. */
-#define REGISTER_DEFS_IN_THIS_STMT(T) (T)->base.unsigned_flag
/* Prototypes for debugging functions. */
@@ -271,6 +262,50 @@ extern void debug_defs_stack (int);
extern void dump_currdefs (FILE *);
extern void debug_currdefs (void);
+/* Return true if STMT needs to be rewritten. When renaming a subset
+ of the variables, not all statements will be processed. This is
+ decided in mark_def_sites. */
+
+static inline bool
+rewrite_uses_p (gimple stmt)
+{
+ return gimple_visited_p (stmt);
+}
+
+
+/* Set the rewrite marker on STMT to the value given by REWRITE_P. */
+
+static inline void
+set_rewrite_uses (gimple stmt, bool rewrite_p)
+{
+ gimple_set_visited (stmt, rewrite_p);
+}
+
+
+/* Return true if the DEFs created by statement STMT should be
+ registered when marking new definition sites. This is slightly
+ different than rewrite_uses_p: it's used by update_ssa to
+ distinguish statements that need to have both uses and defs
+ processed from those that only need to have their defs processed.
+ Statements that define new SSA names only need to have their defs
+ registered, but they don't need to have their uses renamed. */
+
+static inline bool
+register_defs_p (gimple stmt)
+{
+ return gimple_plf (stmt, GF_PLF_1) != 0;
+}
+
+
+/* If REGISTER_DEFS_P is true, mark STMT to have its DEFs registered. */
+
+static inline void
+set_register_defs (gimple stmt, bool register_defs_p)
+{
+ gimple_set_plf (stmt, GF_PLF_1, register_defs_p);
+}
+
+
/* Get the information associated with NAME. */
static inline ssa_name_info_p
@@ -371,7 +406,7 @@ set_current_def (tree var, tree def)
for LIVEIN). */
void
-compute_global_livein (bitmap livein, bitmap def_blocks)
+compute_global_livein (bitmap livein ATTRIBUTE_UNUSED, bitmap def_blocks ATTRIBUTE_UNUSED)
{
basic_block bb, *worklist, *tos;
unsigned i;
@@ -419,24 +454,26 @@ compute_global_livein (bitmap livein, bitmap def_blocks)
static void
initialize_flags_in_bb (basic_block bb)
{
- tree phi, stmt;
- block_stmt_iterator bsi;
+ gimple stmt;
+ gimple_stmt_iterator gsi;
- for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
+ for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
- REWRITE_THIS_STMT (phi) = 0;
- REGISTER_DEFS_IN_THIS_STMT (phi) = 0;
+ gimple phi = gsi_stmt (gsi);
+ set_rewrite_uses (phi, false);
+ set_register_defs (phi, false);
}
- for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
- stmt = bsi_stmt (bsi);
+ stmt = gsi_stmt (gsi);
+
/* We are going to use the operand cache API, such as
SET_USE, SET_DEF, and FOR_EACH_IMM_USE_FAST. The operand
cache for each statement should be up-to-date. */
- gcc_assert (!stmt_modified_p (stmt));
- REWRITE_THIS_STMT (stmt) = 0;
- REGISTER_DEFS_IN_THIS_STMT (stmt) = 0;
+ gcc_assert (!gimple_modified_p (stmt));
+ set_rewrite_uses (stmt, false);
+ set_register_defs (stmt, false);
}
}
@@ -724,23 +761,26 @@ add_new_name_mapping (tree new, tree old)
static void
mark_def_sites (struct dom_walk_data *walk_data, basic_block bb,
- block_stmt_iterator bsi)
+ gimple_stmt_iterator gsi)
{
struct mark_def_sites_global_data *gd;
bitmap kills;
- tree stmt, def;
+ tree def;
+ gimple stmt;
use_operand_p use_p;
ssa_op_iter iter;
- stmt = bsi_stmt (bsi);
- update_stmt_if_modified (stmt);
+ /* Since this is the first time that we rewrite the program into SSA
+ form, force an operand scan on every statement. */
+ stmt = gsi_stmt (gsi);
+ update_stmt (stmt);
gd = (struct mark_def_sites_global_data *) walk_data->global_data;
kills = gd->kills;
gcc_assert (blocks_to_update == NULL);
- REGISTER_DEFS_IN_THIS_STMT (stmt) = 0;
- REWRITE_THIS_STMT (stmt) = 0;
+ set_register_defs (stmt, false);
+ set_rewrite_uses (stmt, false);
/* If a variable is used before being set, then the variable is live
across a block boundary, so mark it live-on-entry to BB. */
@@ -750,7 +790,7 @@ mark_def_sites (struct dom_walk_data *walk_data, basic_block bb,
gcc_assert (DECL_P (sym));
if (!bitmap_bit_p (kills, DECL_UID (sym)))
set_livein_block (sym, bb);
- REWRITE_THIS_STMT (stmt) = 1;
+ set_rewrite_uses (stmt, true);
}
/* Now process the defs. Mark BB as the definition block and add
@@ -760,12 +800,12 @@ mark_def_sites (struct dom_walk_data *walk_data, basic_block bb,
gcc_assert (DECL_P (def));
set_def_block (def, bb, false);
bitmap_set_bit (kills, DECL_UID (def));
- REGISTER_DEFS_IN_THIS_STMT (stmt) = 1;
+ set_register_defs (stmt, true);
}
/* If we found the statement interesting then also mark the block BB
as interesting. */
- if (REWRITE_THIS_STMT (stmt) || REGISTER_DEFS_IN_THIS_STMT (stmt))
+ if (rewrite_uses_p (stmt) || register_defs_p (stmt))
SET_BIT (gd->interesting_blocks, bb->index);
}
@@ -1007,7 +1047,7 @@ get_default_def_for (tree sym)
if (ddef == NULL_TREE)
{
- ddef = make_ssa_name (sym, build_empty_stmt ());
+ ddef = make_ssa_name (sym, gimple_build_nop ());
set_default_def (sym, ddef);
}
@@ -1018,30 +1058,30 @@ get_default_def_for (tree sym)
/* Marks phi node PHI in basic block BB for rewrite. */
static void
-mark_phi_for_rewrite (basic_block bb, tree phi)
+mark_phi_for_rewrite (basic_block bb, gimple phi)
{
- tree_vec phis;
+ gimple_vec phis;
unsigned i, idx = bb->index;
- if (REWRITE_THIS_STMT (phi))
+ if (rewrite_uses_p (phi))
return;
- REWRITE_THIS_STMT (phi) = 1;
+ set_rewrite_uses (phi, true);
if (!blocks_with_phis_to_rewrite)
return;
bitmap_set_bit (blocks_with_phis_to_rewrite, idx);
- VEC_reserve (tree_vec, heap, phis_to_rewrite, last_basic_block + 1);
- for (i = VEC_length (tree_vec, phis_to_rewrite); i <= idx; i++)
- VEC_quick_push (tree_vec, phis_to_rewrite, NULL);
+ VEC_reserve (gimple_vec, heap, phis_to_rewrite, last_basic_block + 1);
+ for (i = VEC_length (gimple_vec, phis_to_rewrite); i <= idx; i++)
+ VEC_quick_push (gimple_vec, phis_to_rewrite, NULL);
- phis = VEC_index (tree_vec, phis_to_rewrite, idx);
+ phis = VEC_index (gimple_vec, phis_to_rewrite, idx);
if (!phis)
- phis = VEC_alloc (tree, heap, 10);
+ phis = VEC_alloc (gimple, heap, 10);
- VEC_safe_push (tree, heap, phis, phi);
- VEC_replace (tree_vec, phis_to_rewrite, idx, phis);
+ VEC_safe_push (gimple, heap, phis, phi);
+ VEC_replace (gimple_vec, phis_to_rewrite, idx, phis);
}
@@ -1060,7 +1100,7 @@ insert_phi_nodes_for (tree var, bitmap phi_insertion_points, bool update_p)
{
unsigned bb_index;
edge e;
- tree phi;
+ gimple phi;
basic_block bb;
bitmap_iterator bi;
struct def_blocks_d *def_map;
@@ -1082,7 +1122,7 @@ insert_phi_nodes_for (tree var, bitmap phi_insertion_points, bool update_p)
if (update_p)
mark_block_for_update (bb);
- phi = NULL_TREE;
+ phi = NULL;
if (TREE_CODE (var) == SSA_NAME)
{
@@ -1097,7 +1137,7 @@ insert_phi_nodes_for (tree var, bitmap phi_insertion_points, bool update_p)
phi = create_phi_node (var, bb);
new_lhs = duplicate_ssa_name (var, phi);
- SET_PHI_RESULT (phi, new_lhs);
+ gimple_phi_set_result (phi, new_lhs);
add_new_name_mapping (new_lhs, var);
/* Add VAR to every argument slot of PHI. We need VAR in
@@ -1116,7 +1156,7 @@ insert_phi_nodes_for (tree var, bitmap phi_insertion_points, bool update_p)
}
/* Mark this PHI node as interesting for update_ssa. */
- REGISTER_DEFS_IN_THIS_STMT (phi) = 1;
+ set_register_defs (phi, true);
mark_phi_for_rewrite (bb, phi);
}
}
@@ -1231,7 +1271,8 @@ static void
rewrite_initialize_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
basic_block bb)
{
- tree phi;
+ gimple phi;
+ gimple_stmt_iterator gsi;
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, "\n\nRenaming block #%d\n\n", bb->index);
@@ -1242,9 +1283,12 @@ rewrite_initialize_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
/* Step 1. Register new definitions for every PHI node in the block.
Conceptually, all the PHI nodes are executed in parallel and each PHI
node introduces a new version for the associated variable. */
- for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
+ for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
- tree result = PHI_RESULT (phi);
+ tree result;
+
+ phi = gsi_stmt (gsi);
+ result = gimple_phi_result (phi);
gcc_assert (is_gimple_reg (result));
register_new_def (result, SSA_NAME_VAR (result));
}
@@ -1283,30 +1327,30 @@ get_reaching_def (tree var)
static void
rewrite_stmt (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
- basic_block bb ATTRIBUTE_UNUSED, block_stmt_iterator si)
+ basic_block bb ATTRIBUTE_UNUSED, gimple_stmt_iterator si)
{
- tree stmt;
+ gimple stmt;
use_operand_p use_p;
def_operand_p def_p;
ssa_op_iter iter;
- stmt = bsi_stmt (si);
+ stmt = gsi_stmt (si);
/* If mark_def_sites decided that we don't need to rewrite this
statement, ignore it. */
gcc_assert (blocks_to_update == NULL);
- if (!REWRITE_THIS_STMT (stmt) && !REGISTER_DEFS_IN_THIS_STMT (stmt))
+ if (!rewrite_uses_p (stmt) && !register_defs_p (stmt))
return;
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "Renaming statement ");
- print_generic_stmt (dump_file, stmt, TDF_SLIM);
+ print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
fprintf (dump_file, "\n");
}
/* Step 1. Rewrite USES in the statement. */
- if (REWRITE_THIS_STMT (stmt))
+ if (rewrite_uses_p (stmt))
FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE)
{
tree var = USE_FROM_PTR (use_p);
@@ -1315,7 +1359,7 @@ rewrite_stmt (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
}
/* Step 2. Register the statement's DEF operands. */
- if (REGISTER_DEFS_IN_THIS_STMT (stmt))
+ if (register_defs_p (stmt))
FOR_EACH_SSA_DEF_OPERAND (def_p, stmt, iter, SSA_OP_DEF)
{
tree var = DEF_FROM_PTR (def_p);
@@ -1340,12 +1384,15 @@ rewrite_add_phi_arguments (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
FOR_EACH_EDGE (e, ei, bb->succs)
{
- tree phi;
+ gimple phi;
+ gimple_stmt_iterator gsi;
- for (phi = phi_nodes (e->dest); phi; phi = PHI_CHAIN (phi))
+ for (gsi = gsi_start_phis (e->dest); !gsi_end_p (gsi);
+ gsi_next (&gsi))
{
tree currdef;
- currdef = get_reaching_def (SSA_NAME_VAR (PHI_RESULT (phi)));
+ phi = gsi_stmt (gsi);
+ currdef = get_reaching_def (SSA_NAME_VAR (gimple_phi_result (phi)));
add_phi_arg (phi, currdef, e);
}
}
@@ -1721,8 +1768,8 @@ rewrite_update_init_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
{
edge e;
edge_iterator ei;
- tree phi;
bool is_abnormal_phi;
+ gimple_stmt_iterator gsi;
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, "\n\nRegistering new PHI nodes in block #%d\n\n",
@@ -1749,14 +1796,15 @@ rewrite_update_init_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
register it as a new definition for its corresponding name. Also
register definitions for names whose underlying symbols are
marked for renaming. */
- for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
+ for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
tree lhs, lhs_sym;
+ gimple phi = gsi_stmt (gsi);
- if (!REGISTER_DEFS_IN_THIS_STMT (phi))
+ if (!register_defs_p (phi))
continue;
- lhs = PHI_RESULT (phi);
+ lhs = gimple_phi_result (phi);
lhs_sym = SSA_NAME_VAR (lhs);
if (symbol_marked_for_renaming (lhs_sym))
@@ -1834,7 +1882,7 @@ maybe_replace_use (use_operand_p use_p)
DEF_P. */
static inline void
-maybe_register_def (def_operand_p def_p, tree stmt)
+maybe_register_def (def_operand_p def_p, gimple stmt)
{
tree def = DEF_FROM_PTR (def_p);
tree sym = DECL_P (def) ? def : SSA_NAME_VAR (def);
@@ -1876,33 +1924,31 @@ maybe_register_def (def_operand_p def_p, tree stmt)
static void
rewrite_update_stmt (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
basic_block bb ATTRIBUTE_UNUSED,
- block_stmt_iterator si)
+ gimple_stmt_iterator si)
{
- stmt_ann_t ann;
- tree stmt;
+ gimple stmt;
use_operand_p use_p;
def_operand_p def_p;
ssa_op_iter iter;
- stmt = bsi_stmt (si);
- ann = stmt_ann (stmt);
+ stmt = gsi_stmt (si);
gcc_assert (bitmap_bit_p (blocks_to_update, bb->index));
/* Only update marked statements. */
- if (!REWRITE_THIS_STMT (stmt) && !REGISTER_DEFS_IN_THIS_STMT (stmt))
+ if (!rewrite_uses_p (stmt) && !register_defs_p (stmt))
return;
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "Updating SSA information for statement ");
- print_generic_stmt (dump_file, stmt, TDF_SLIM);
+ print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
fprintf (dump_file, "\n");
}
/* Rewrite USES included in OLD_SSA_NAMES and USES whose underlying
symbol is marked for renaming. */
- if (REWRITE_THIS_STMT (stmt))
+ if (rewrite_uses_p (stmt))
{
FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE)
maybe_replace_use (use_p);
@@ -1915,7 +1961,7 @@ rewrite_update_stmt (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
/* Register definitions of names in NEW_SSA_NAMES and OLD_SSA_NAMES.
Also register definitions for names whose underlying symbol is
marked for renaming. */
- if (REGISTER_DEFS_IN_THIS_STMT (stmt))
+ if (register_defs_p (stmt))
{
FOR_EACH_SSA_DEF_OPERAND (def_p, stmt, iter, SSA_OP_DEF)
maybe_register_def (def_p, stmt);
@@ -1942,19 +1988,19 @@ rewrite_update_phi_arguments (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
FOR_EACH_EDGE (e, ei, bb->succs)
{
- tree phi;
- tree_vec phis;
+ gimple phi;
+ gimple_vec phis;
if (!bitmap_bit_p (blocks_with_phis_to_rewrite, e->dest->index))
continue;
- phis = VEC_index (tree_vec, phis_to_rewrite, e->dest->index);
- for (i = 0; VEC_iterate (tree, phis, i, phi); i++)
+ phis = VEC_index (gimple_vec, phis_to_rewrite, e->dest->index);
+ for (i = 0; VEC_iterate (gimple, phis, i, phi); i++)
{
tree arg, lhs_sym;
use_operand_p arg_p;
- gcc_assert (REWRITE_THIS_STMT (phi));
+ gcc_assert (rewrite_uses_p (phi));
arg_p = PHI_ARG_DEF_PTR_FROM_EDGE (phi, e);
arg = USE_FROM_PTR (arg_p);
@@ -1962,7 +2008,7 @@ rewrite_update_phi_arguments (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
if (arg && !DECL_P (arg) && TREE_CODE (arg) != SSA_NAME)
continue;
- lhs_sym = SSA_NAME_VAR (PHI_RESULT (phi));
+ lhs_sym = SSA_NAME_VAR (gimple_phi_result (phi));
if (arg == NULL_TREE)
{
@@ -2168,7 +2214,6 @@ fini_ssa_renamer (void)
cfun->gimple_df->in_ssa_p = true;
}
-
/* Main entry point into the SSA builder. The renaming process
proceeds in four main phases:
@@ -2264,14 +2309,14 @@ struct gimple_opt_pass pass_build_ssa =
renamer. BLOCKS is the set of blocks that need updating. */
static void
-mark_def_interesting (tree var, tree stmt, basic_block bb, bool insert_phi_p)
+mark_def_interesting (tree var, gimple stmt, basic_block bb, bool insert_phi_p)
{
gcc_assert (bitmap_bit_p (blocks_to_update, bb->index));
- REGISTER_DEFS_IN_THIS_STMT (stmt) = 1;
+ set_register_defs (stmt, true);
if (insert_phi_p)
{
- bool is_phi_p = TREE_CODE (stmt) == PHI_NODE;
+ bool is_phi_p = gimple_code (stmt) == GIMPLE_PHI;
set_def_block (var, bb, is_phi_p);
@@ -2295,17 +2340,17 @@ mark_def_interesting (tree var, tree stmt, basic_block bb, bool insert_phi_p)
nodes. */
static inline void
-mark_use_interesting (tree var, tree stmt, basic_block bb, bool insert_phi_p)
+mark_use_interesting (tree var, gimple stmt, basic_block bb, bool insert_phi_p)
{
- basic_block def_bb = bb_for_stmt (stmt);
+ basic_block def_bb = gimple_bb (stmt);
mark_block_for_update (def_bb);
mark_block_for_update (bb);
- if (TREE_CODE (stmt) == PHI_NODE)
+ if (gimple_code (stmt) == GIMPLE_PHI)
mark_phi_for_rewrite (def_bb, stmt);
else
- REWRITE_THIS_STMT (stmt) = 1;
+ set_rewrite_uses (stmt, true);
/* If VAR has not been defined in BB, then it is live-on-entry
to BB. Note that we cannot just use the block holding VAR's
@@ -2340,8 +2385,7 @@ static void
prepare_block_for_update (basic_block bb, bool insert_phi_p)
{
basic_block son;
- block_stmt_iterator si;
- tree phi;
+ gimple_stmt_iterator si;
edge e;
edge_iterator ei;
@@ -2349,14 +2393,16 @@ prepare_block_for_update (basic_block bb, bool insert_phi_p)
/* Process PHI nodes marking interesting those that define or use
the symbols that we are interested in. */
- for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
+ for (si = gsi_start_phis (bb); !gsi_end_p (si); gsi_next (&si))
{
- tree lhs_sym, lhs = PHI_RESULT (phi);
+ gimple phi = gsi_stmt (si);
+ tree lhs_sym, lhs = gimple_phi_result (phi);
lhs_sym = DECL_P (lhs) ? lhs : SSA_NAME_VAR (lhs);
if (!symbol_marked_for_renaming (lhs_sym))
continue;
+
mark_def_interesting (lhs_sym, phi, bb, insert_phi_p);
/* Mark the uses in phi nodes as interesting. It would be more correct
@@ -2367,20 +2413,18 @@ prepare_block_for_update (basic_block bb, bool insert_phi_p)
block that also contains its definition, and thus insert a few more
phi nodes for it. */
FOR_EACH_EDGE (e, ei, bb->preds)
- {
- mark_use_interesting (lhs_sym, phi, e->src, insert_phi_p);
- }
+ mark_use_interesting (lhs_sym, phi, e->src, insert_phi_p);
}
/* Process the statements. */
- for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
+ for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
{
- tree stmt;
+ gimple stmt;
ssa_op_iter i;
use_operand_p use_p;
def_operand_p def_p;
- stmt = bsi_stmt (si);
+ stmt = gsi_stmt (si);
FOR_EACH_SSA_USE_OPERAND (use_p, stmt, i, SSA_OP_ALL_USES)
{
@@ -2419,13 +2463,13 @@ prepare_use_sites_for (tree name, bool insert_phi_p)
FOR_EACH_IMM_USE_FAST (use_p, iter, name)
{
- tree stmt = USE_STMT (use_p);
- basic_block bb = bb_for_stmt (stmt);
+ gimple stmt = USE_STMT (use_p);
+ basic_block bb = gimple_bb (stmt);
- if (TREE_CODE (stmt) == PHI_NODE)
+ if (gimple_code (stmt) == GIMPLE_PHI)
{
int ix = PHI_ARG_INDEX_FROM_USE (use_p);
- edge e = PHI_ARG_EDGE (stmt, ix);
+ edge e = gimple_phi_arg_edge (stmt, ix);
mark_use_interesting (name, stmt, e->src, insert_phi_p);
}
else
@@ -2445,14 +2489,14 @@ prepare_use_sites_for (tree name, bool insert_phi_p)
static void
prepare_def_site_for (tree name, bool insert_phi_p)
{
- tree stmt;
+ gimple stmt;
basic_block bb;
gcc_assert (names_to_release == NULL
|| !bitmap_bit_p (names_to_release, SSA_NAME_VERSION (name)));
stmt = SSA_NAME_DEF_STMT (name);
- bb = bb_for_stmt (stmt);
+ bb = gimple_bb (stmt);
if (bb)
{
gcc_assert (bb->index < last_basic_block);
@@ -2659,10 +2703,10 @@ delete_update_ssa (void)
if (blocks_with_phis_to_rewrite)
EXECUTE_IF_SET_IN_BITMAP (blocks_with_phis_to_rewrite, 0, i, bi)
{
- tree_vec phis = VEC_index (tree_vec, phis_to_rewrite, i);
+ gimple_vec phis = VEC_index (gimple_vec, phis_to_rewrite, i);
- VEC_free (tree, heap, phis);
- VEC_replace (tree_vec, phis_to_rewrite, i, NULL);
+ VEC_free (gimple, heap, phis);
+ VEC_replace (gimple_vec, phis_to_rewrite, i, NULL);
}
BITMAP_FREE (blocks_with_phis_to_rewrite);
@@ -2676,17 +2720,17 @@ delete_update_ssa (void)
update_ssa's tables. */
tree
-create_new_def_for (tree old_name, tree stmt, def_operand_p def)
+create_new_def_for (tree old_name, gimple stmt, def_operand_p def)
{
tree new_name = duplicate_ssa_name (old_name, stmt);
SET_DEF (def, new_name);
- if (TREE_CODE (stmt) == PHI_NODE)
+ if (gimple_code (stmt) == GIMPLE_PHI)
{
edge e;
edge_iterator ei;
- basic_block bb = bb_for_stmt (stmt);
+ basic_block bb = gimple_bb (stmt);
/* If needed, mark NEW_NAME as occurring in an abnormal PHI node. */
FOR_EACH_EDGE (e, ei, bb->preds)
@@ -2713,7 +2757,7 @@ create_new_def_for (tree old_name, tree stmt, def_operand_p def)
update_ssa. */
void
-register_new_name_mapping (tree new, tree old)
+register_new_name_mapping (tree new ATTRIBUTE_UNUSED, tree old ATTRIBUTE_UNUSED)
{
if (need_to_initialize_update_ssa_p)
init_update_ssa ();
@@ -2779,7 +2823,7 @@ name_mappings_registered_p (void)
/* Return true if name N has been registered in the replacement table. */
bool
-name_registered_for_update_p (tree n)
+name_registered_for_update_p (tree n ATTRIBUTE_UNUSED)
{
if (!need_ssa_update_p ())
return false;
@@ -3079,7 +3123,7 @@ update_ssa (unsigned update_flags)
blocks_with_phis_to_rewrite = BITMAP_ALLOC (NULL);
if (!phis_to_rewrite)
- phis_to_rewrite = VEC_alloc (tree_vec, heap, last_basic_block);
+ phis_to_rewrite = VEC_alloc (gimple_vec, heap, last_basic_block);
blocks_to_update = BITMAP_ALLOC (NULL);
/* Ensure that the dominance information is up-to-date. */
diff --git a/gcc/tree-iterator.c b/gcc/tree-iterator.c
index 9816f249e1b..d8c151a9f54 100644
--- a/gcc/tree-iterator.c
+++ b/gcc/tree-iterator.c
@@ -22,7 +22,7 @@ along with GCC; see the file COPYING3. If not see
#include "system.h"
#include "coretypes.h"
#include "tree.h"
-#include "tree-gimple.h"
+#include "gimple.h"
#include "tree-iterator.h"
#include "ggc.h"
diff --git a/gcc/tree-loop-distribution.c b/gcc/tree-loop-distribution.c
index d15ab80377f..d86391e2af3 100644
--- a/gcc/tree-loop-distribution.c
+++ b/gcc/tree-loop-distribution.c
@@ -84,22 +84,25 @@ static void
update_phis_for_loop_copy (struct loop *orig_loop, struct loop *new_loop)
{
tree new_ssa_name;
- tree phi_new, phi_orig;
+ gimple_stmt_iterator si_new, si_orig;
edge orig_loop_latch = loop_latch_edge (orig_loop);
edge orig_entry_e = loop_preheader_edge (orig_loop);
edge new_loop_entry_e = loop_preheader_edge (new_loop);
/* Scan the phis in the headers of the old and new loops
(they are organized in exactly the same order). */
-
- for (phi_new = phi_nodes (new_loop->header),
- phi_orig = phi_nodes (orig_loop->header);
- phi_new && phi_orig;
- phi_new = PHI_CHAIN (phi_new), phi_orig = PHI_CHAIN (phi_orig))
+ for (si_new = gsi_start_phis (new_loop->header),
+ si_orig = gsi_start_phis (orig_loop->header);
+ !gsi_end_p (si_new) && !gsi_end_p (si_orig);
+ gsi_next (&si_new), gsi_next (&si_orig))
{
+ tree def;
+ gimple phi_new = gsi_stmt (si_new);
+ gimple phi_orig = gsi_stmt (si_orig);
+
/* Add the first phi argument for the phi in NEW_LOOP (the one
associated with the entry of NEW_LOOP) */
- tree def = PHI_ARG_DEF_FROM_EDGE (phi_orig, orig_entry_e);
+ def = PHI_ARG_DEF_FROM_EDGE (phi_orig, orig_entry_e);
add_phi_arg (phi_new, def, new_loop_entry_e);
/* Add the second phi argument for the phi in NEW_LOOP (the one
@@ -171,7 +174,7 @@ static bool
generate_loops_for_partition (struct loop *loop, bitmap partition, bool copy_p)
{
unsigned i, x;
- block_stmt_iterator bsi;
+ gimple_stmt_iterator bsi;
basic_block *bbs;
if (copy_p)
@@ -192,27 +195,19 @@ generate_loops_for_partition (struct loop *loop, bitmap partition, bool copy_p)
for (x = 0, i = 0; i < loop->num_nodes; i++)
{
basic_block bb = bbs[i];
- tree phi, prev = NULL_TREE, next;
- for (phi = phi_nodes (bb); phi;)
+ for (bsi = gsi_start_phis (bb); !gsi_end_p (bsi);)
if (!bitmap_bit_p (partition, x++))
- {
- next = PHI_CHAIN (phi);
- remove_phi_node (phi, prev, true);
- phi = next;
- }
+ remove_phi_node (&bsi, true);
else
- {
- prev = phi;
- phi = PHI_CHAIN (phi);
- }
+ gsi_next (&bsi);
- for (bsi = bsi_start (bb); !bsi_end_p (bsi);)
- if (TREE_CODE (bsi_stmt (bsi)) != LABEL_EXPR
+ for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi);)
+ if (gimple_code (gsi_stmt (bsi)) != GIMPLE_LABEL
&& !bitmap_bit_p (partition, x++))
- bsi_remove (&bsi, false);
+ gsi_remove (&bsi, false);
else
- bsi_next (&bsi);
+ gsi_next (&bsi);
mark_virtual_ops_in_bb (bb);
}
@@ -224,22 +219,22 @@ generate_loops_for_partition (struct loop *loop, bitmap partition, bool copy_p)
/* Generate a call to memset. Return true when the operation succeeded. */
static bool
-generate_memset_zero (tree stmt, tree op0, tree nb_iter,
- block_stmt_iterator bsi)
+generate_memset_zero (gimple stmt, tree op0, tree nb_iter,
+ gimple_stmt_iterator bsi)
{
- tree s, t, stmts, nb_bytes, addr_base;
+ tree t, nb_bytes, addr_base;
bool res = false;
- tree stmt_list = NULL_TREE;
- tree args [3];
- tree fn_call, mem, fndecl, fntype, fn;
- tree_stmt_iterator i;
+ gimple_seq stmts = NULL, stmt_list = NULL;
+ gimple fn_call;
+ tree mem, fndecl, fntype, fn;
+ gimple_stmt_iterator i;
ssa_op_iter iter;
struct data_reference *dr = XCNEW (struct data_reference);
nb_bytes = fold_build2 (MULT_EXPR, TREE_TYPE (nb_iter),
nb_iter, TYPE_SIZE_UNIT (TREE_TYPE (op0)));
nb_bytes = force_gimple_operand (nb_bytes, &stmts, true, NULL);
- append_to_statement_list_force (stmts, &stmt_list);
+ gimple_seq_add_seq (&stmt_list, stmts);
DR_STMT (dr) = stmt;
DR_REF (dr) = op0;
@@ -261,7 +256,7 @@ generate_memset_zero (tree stmt, tree op0, tree nb_iter,
addr_base = size_binop (PLUS_EXPR, DR_OFFSET (dr), DR_INIT (dr));
addr_base = fold_build2 (MINUS_EXPR, sizetype, addr_base, nb_bytes);
addr_base = force_gimple_operand (addr_base, &stmts, true, NULL);
- append_to_statement_list_force (stmts, &stmt_list);
+ gimple_seq_add_seq (&stmt_list, stmts);
addr_base = fold_build2 (POINTER_PLUS_EXPR,
TREE_TYPE (DR_BASE_ADDRESS (dr)),
@@ -271,23 +266,18 @@ generate_memset_zero (tree stmt, tree op0, tree nb_iter,
goto end;
mem = force_gimple_operand (addr_base, &stmts, true, NULL);
- append_to_statement_list_force (stmts, &stmt_list);
-
+ gimple_seq_add_seq (&stmt_list, stmts);
fndecl = implicit_built_in_decls [BUILT_IN_MEMSET];
fntype = TREE_TYPE (fndecl);
fn = build1 (ADDR_EXPR, build_pointer_type (fntype), fndecl);
- args[0] = mem;
- args[1] = integer_zero_node;
- args[2] = nb_bytes;
-
- fn_call = build_call_array (fntype, fn, 3, args);
- append_to_statement_list_force (fn_call, &stmt_list);
+ fn_call = gimple_build_call (fn, 3, mem, integer_zero_node, nb_bytes);
+ gimple_seq_add_stmt (&stmt_list, fn_call);
- for (i = tsi_start (stmt_list); !tsi_end_p (i); tsi_next (&i))
+ for (i = gsi_start (stmt_list); !gsi_end_p (i); gsi_next (&i))
{
- s = tsi_stmt (i);
+ gimple s = gsi_stmt (i);
update_stmt_if_modified (s);
FOR_EACH_SSA_TREE_OPERAND (t, s, iter, SSA_OP_VIRTUAL_DEFS)
@@ -303,6 +293,7 @@ generate_memset_zero (tree stmt, tree op0, tree nb_iter,
{
if (TREE_CODE (t) == SSA_NAME)
{
+ gimple s;
imm_use_iterator imm_iter;
FOR_EACH_IMM_USE_STMT (s, imm_iter, t)
@@ -313,7 +304,7 @@ generate_memset_zero (tree stmt, tree op0, tree nb_iter,
mark_sym_for_renaming (t);
}
- bsi_insert_after (&bsi, stmt_list, BSI_CONTINUE_LINKING);
+ gsi_insert_seq_after (&bsi, stmt_list, GSI_CONTINUE_LINKING);
res = true;
if (dump_file && (dump_flags & TDF_DETAILS))
@@ -334,9 +325,9 @@ generate_builtin (struct loop *loop, bitmap partition, bool copy_p)
bool res = false;
unsigned i, x = 0;
basic_block *bbs;
- tree write = NULL_TREE;
+ gimple write = NULL;
tree op0, op1;
- block_stmt_iterator bsi;
+ gimple_stmt_iterator bsi;
tree nb_iter = number_of_exit_cond_executions (loop);
if (!nb_iter || nb_iter == chrec_dont_know)
@@ -347,18 +338,17 @@ generate_builtin (struct loop *loop, bitmap partition, bool copy_p)
for (i = 0; i < loop->num_nodes; i++)
{
basic_block bb = bbs[i];
- tree phi;
- for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
+ for (bsi = gsi_start_phis (bb); !gsi_end_p (bsi); gsi_next (&bsi))
x++;
- for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
+ for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi))
{
- tree stmt = bsi_stmt (bsi);
+ gimple stmt = gsi_stmt (bsi);
if (bitmap_bit_p (partition, x++)
- && TREE_CODE (stmt) == GIMPLE_MODIFY_STMT
- && !is_gimple_reg (GIMPLE_STMT_OPERAND (stmt, 0)))
+ && is_gimple_assign (stmt)
+ && !is_gimple_reg (gimple_assign_lhs (stmt)))
{
/* Don't generate the builtins when there are more than
one memory write. */
@@ -373,17 +363,18 @@ generate_builtin (struct loop *loop, bitmap partition, bool copy_p)
if (!write)
goto end;
- op0 = GIMPLE_STMT_OPERAND (write, 0);
- op1 = GIMPLE_STMT_OPERAND (write, 1);
+ op0 = gimple_assign_lhs (write);
+ op1 = gimple_assign_rhs1 (write);
if (!(TREE_CODE (op0) == ARRAY_REF
|| TREE_CODE (op0) == INDIRECT_REF))
goto end;
/* The new statements will be placed before LOOP. */
- bsi = bsi_last (loop_preheader_edge (loop)->src);
+ bsi = gsi_last_bb (loop_preheader_edge (loop)->src);
- if (integer_zerop (op1) || real_zerop (op1))
+ if (gimple_assign_rhs_code (write) == INTEGER_CST
+ && (integer_zerop (op1) || real_zerop (op1)))
res = generate_memset_zero (write, op0, nb_iter, bsi);
/* If this is the last partition for which we generate code, we have
@@ -557,7 +548,7 @@ rdg_flag_uses (struct graph *rdg, int u, bitmap partition, bitmap loops,
ssa_op_iter iter;
use_operand_p use_p;
struct vertex *x = &(rdg->vertices[u]);
- tree stmt = RDGV_STMT (x);
+ gimple stmt = RDGV_STMT (x);
struct graph_edge *anti_dep = has_anti_dependence (x);
/* Keep in the same partition the destination of an antidependence,
@@ -572,7 +563,7 @@ rdg_flag_uses (struct graph *rdg, int u, bitmap partition, bitmap loops,
processed, part_has_writes);
}
- if (TREE_CODE (stmt) != PHI_NODE)
+ if (gimple_code (stmt) != GIMPLE_PHI)
{
FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_VIRTUAL_USES)
{
@@ -580,7 +571,7 @@ rdg_flag_uses (struct graph *rdg, int u, bitmap partition, bitmap loops,
if (TREE_CODE (use) == SSA_NAME)
{
- tree def_stmt = SSA_NAME_DEF_STMT (use);
+ gimple def_stmt = SSA_NAME_DEF_STMT (use);
int v = rdg_vertex_for_stmt (rdg, def_stmt);
if (v >= 0
@@ -591,10 +582,9 @@ rdg_flag_uses (struct graph *rdg, int u, bitmap partition, bitmap loops,
}
}
- if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT
- && has_upstream_mem_writes (u))
+ if (is_gimple_assign (stmt) && has_upstream_mem_writes (u))
{
- tree op0 = GIMPLE_STMT_OPERAND (stmt, 0);
+ tree op0 = gimple_assign_lhs (stmt);
/* Scalar channels don't have enough space for transmitting data
between tasks, unless we add more storage by privatizing. */
@@ -667,7 +657,7 @@ rdg_flag_vertex_and_dependent (struct graph *rdg, int v, bitmap partition,
blocks of LOOP. */
static void
-collect_condition_stmts (struct loop *loop, VEC (tree, heap) **conds)
+collect_condition_stmts (struct loop *loop, VEC (gimple, heap) **conds)
{
unsigned i;
edge e;
@@ -675,10 +665,10 @@ collect_condition_stmts (struct loop *loop, VEC (tree, heap) **conds)
for (i = 0; VEC_iterate (edge, exits, i, e); i++)
{
- tree cond = last_stmt (e->src);
+ gimple cond = last_stmt (e->src);
if (cond)
- VEC_safe_push (tree, heap, *conds, cond);
+ VEC_safe_push (gimple, heap, *conds, cond);
}
VEC_free (edge, heap, exits);
@@ -694,14 +684,14 @@ rdg_flag_loop_exits (struct graph *rdg, bitmap loops, bitmap partition,
{
unsigned i;
bitmap_iterator bi;
- VEC (tree, heap) *conds = VEC_alloc (tree, heap, 3);
+ VEC (gimple, heap) *conds = VEC_alloc (gimple, heap, 3);
EXECUTE_IF_SET_IN_BITMAP (loops, 0, i, bi)
collect_condition_stmts (get_loop (i), &conds);
- while (!VEC_empty (tree, conds))
+ while (!VEC_empty (gimple, conds))
{
- tree cond = VEC_pop (tree, conds);
+ gimple cond = VEC_pop (gimple, conds);
int v = rdg_vertex_for_stmt (rdg, cond);
bitmap new_loops = BITMAP_ALLOC (NULL);
@@ -1050,11 +1040,11 @@ ldist_gen (struct loop *loop, struct graph *rdg,
Returns the number of distributed loops. */
static int
-distribute_loop (struct loop *loop, VEC (tree, heap) *stmts)
+distribute_loop (struct loop *loop, VEC (gimple, heap) *stmts)
{
bool res = false;
struct graph *rdg;
- tree s;
+ gimple s;
unsigned i;
VEC (int, heap) *vertices;
@@ -1085,7 +1075,7 @@ distribute_loop (struct loop *loop, VEC (tree, heap) *stmts)
if (dump_file && (dump_flags & TDF_DETAILS))
dump_rdg (dump_file, rdg);
- for (i = 0; VEC_iterate (tree, stmts, i, s); i++)
+ for (i = 0; VEC_iterate (gimple, stmts, i, s); i++)
{
int v = rdg_vertex_for_stmt (rdg, s);
@@ -1117,7 +1107,7 @@ tree_loop_distribution (void)
FOR_EACH_LOOP (li, loop, 0)
{
- VEC (tree, heap) *work_list = VEC_alloc (tree, heap, 3);
+ VEC (gimple, heap) *work_list = VEC_alloc (gimple, heap, 3);
/* With the following working list, we're asking distribute_loop
to separate the stores of the loop: when dependences allow,
@@ -1143,7 +1133,7 @@ tree_loop_distribution (void)
verify_loop_structure ();
- VEC_free (tree, heap, work_list);
+ VEC_free (gimple, heap, work_list);
}
return 0;
diff --git a/gcc/tree-loop-linear.c b/gcc/tree-loop-linear.c
index f58bd11b7fb..66d25ec1beb 100644
--- a/gcc/tree-loop-linear.c
+++ b/gcc/tree-loop-linear.c
@@ -89,13 +89,13 @@ along with GCC; see the file COPYING3. If not see
*/
static void
-gather_interchange_stats (VEC (ddr_p, heap) *dependence_relations,
- VEC (data_reference_p, heap) *datarefs,
- struct loop *loop,
- struct loop *first_loop,
- unsigned int *dependence_steps,
- unsigned int *nb_deps_not_carried_by_loop,
- double_int *access_strides)
+gather_interchange_stats (VEC (ddr_p, heap) *dependence_relations ATTRIBUTE_UNUSED,
+ VEC (data_reference_p, heap) *datarefs ATTRIBUTE_UNUSED,
+ struct loop *loop ATTRIBUTE_UNUSED,
+ struct loop *first_loop ATTRIBUTE_UNUSED,
+ unsigned int *dependence_steps ATTRIBUTE_UNUSED,
+ unsigned int *nb_deps_not_carried_by_loop ATTRIBUTE_UNUSED,
+ double_int *access_strides ATTRIBUTE_UNUSED)
{
unsigned int i, j;
struct data_dependence_relation *ddr;
@@ -135,7 +135,7 @@ gather_interchange_stats (VEC (ddr_p, heap) *dependence_relations,
{
unsigned int it;
tree ref = DR_REF (dr);
- tree stmt = DR_STMT (dr);
+ gimple stmt = DR_STMT (dr);
struct loop *stmt_loop = loop_containing_stmt (stmt);
struct loop *inner_loop = first_loop->inner;
@@ -319,9 +319,9 @@ linear_transform_loops (void)
VEC(tree,heap) *oldivs = NULL;
VEC(tree,heap) *invariants = NULL;
VEC(tree,heap) *lambda_parameters = NULL;
- VEC(tree,heap) *remove_ivs = VEC_alloc (tree, heap, 3);
+ VEC(gimple,heap) *remove_ivs = VEC_alloc (gimple, heap, 3);
struct loop *loop_nest;
- tree oldiv_stmt;
+ gimple oldiv_stmt;
unsigned i;
FOR_EACH_LOOP (li, loop_nest, 0)
@@ -412,12 +412,12 @@ linear_transform_loops (void)
free_data_refs (datarefs);
}
- for (i = 0; VEC_iterate (tree, remove_ivs, i, oldiv_stmt); i++)
+ for (i = 0; VEC_iterate (gimple, remove_ivs, i, oldiv_stmt); i++)
remove_iv (oldiv_stmt);
VEC_free (tree, heap, oldivs);
VEC_free (tree, heap, invariants);
- VEC_free (tree, heap, remove_ivs);
+ VEC_free (gimple, heap, remove_ivs);
scev_reset ();
if (modified)
diff --git a/gcc/tree-mudflap.c b/gcc/tree-mudflap.c
index b5e8984a4df..7d15077073b 100644
--- a/gcc/tree-mudflap.c
+++ b/gcc/tree-mudflap.c
@@ -33,7 +33,8 @@ along with GCC; see the file COPYING3. If not see
#include "flags.h"
#include "function.h"
#include "tree-inline.h"
-#include "tree-gimple.h"
+#include "gimple.h"
+#include "tree-iterator.h"
#include "tree-flow.h"
#include "tree-mudflap.h"
#include "tree-dump.h"
@@ -45,6 +46,7 @@ along with GCC; see the file COPYING3. If not see
#include "ggc.h"
#include "cgraph.h"
#include "toplev.h"
+#include "gimple.h"
/* Internal function decls */
@@ -64,9 +66,10 @@ static void mf_xform_derefs (void);
static unsigned int execute_mudflap_function_ops (void);
/* Addressable variables instrumentation. */
-static void mf_xform_decls (tree, tree);
-static tree mx_xfn_xform_decls (tree *, int *, void *);
-static void mx_register_decls (tree, tree *);
+static void mf_xform_decls (gimple_seq, tree);
+static tree mx_xfn_xform_decls (gimple_stmt_iterator *, bool *,
+ struct walk_stmt_info *);
+static gimple_seq mx_register_decls (tree, gimple_seq, location_t);
static unsigned int execute_mudflap_function_decls (void);
@@ -421,13 +424,15 @@ mudflap_init (void)
static unsigned int
execute_mudflap_function_ops (void)
{
+ struct gimplify_ctx gctx;
+
/* Don't instrument functions such as the synthetic constructor
built during mudflap_finish_file. */
if (mf_marked_p (current_function_decl) ||
DECL_ARTIFICIAL (current_function_decl))
return 0;
- push_gimplify_context ();
+ push_gimplify_context (&gctx);
/* In multithreaded mode, don't cache the lookup cache parameters. */
if (! flag_mudflap_threads)
@@ -449,8 +454,8 @@ execute_mudflap_function_ops (void)
static void
mf_decl_cache_locals (void)
{
- tree t, shift_init_stmts, mask_init_stmts;
- tree_stmt_iterator tsi;
+ gimple g;
+ gimple_seq seq = gimple_seq_alloc ();
/* Build the cache vars. */
mf_cache_shift_decl_l
@@ -463,28 +468,17 @@ mf_decl_cache_locals (void)
/* Build initialization nodes for the cache vars. We just load the
globals into the cache variables. */
- t = build_gimple_modify_stmt (mf_cache_shift_decl_l, mf_cache_shift_decl);
- SET_EXPR_LOCATION (t, DECL_SOURCE_LOCATION (current_function_decl));
- gimplify_to_stmt_list (&t);
- shift_init_stmts = t;
-
- t = build_gimple_modify_stmt (mf_cache_mask_decl_l, mf_cache_mask_decl);
- SET_EXPR_LOCATION (t, DECL_SOURCE_LOCATION (current_function_decl));
- gimplify_to_stmt_list (&t);
- mask_init_stmts = t;
-
- /* Anticipating multiple entry points, we insert the cache vars
- initializers in each successor of the ENTRY_BLOCK_PTR. */
- for (tsi = tsi_start (shift_init_stmts);
- ! tsi_end_p (tsi);
- tsi_next (&tsi))
- insert_edge_copies (tsi_stmt (tsi), ENTRY_BLOCK_PTR);
-
- for (tsi = tsi_start (mask_init_stmts);
- ! tsi_end_p (tsi);
- tsi_next (&tsi))
- insert_edge_copies (tsi_stmt (tsi), ENTRY_BLOCK_PTR);
- bsi_commit_edge_inserts ();
+ g = gimple_build_assign (mf_cache_shift_decl_l, mf_cache_shift_decl);
+ gimple_set_location (g, DECL_SOURCE_LOCATION (current_function_decl));
+ gimple_seq_add_stmt (&seq, g);
+
+ g = gimple_build_assign (mf_cache_mask_decl_l, mf_cache_mask_decl);
+ gimple_set_location (g, DECL_SOURCE_LOCATION (current_function_decl));
+ gimple_seq_add_stmt (&seq, g);
+
+ insert_edge_copies_seq (seq, ENTRY_BLOCK_PTR);
+
+ gsi_commit_edge_inserts ();
}
@@ -498,27 +492,28 @@ mf_decl_clear_locals (void)
static void
mf_build_check_statement_for (tree base, tree limit,
- block_stmt_iterator *instr_bsi,
- location_t *locus, tree dirflag)
+ gimple_stmt_iterator *instr_gsi,
+ location_t location, tree dirflag)
{
- tree_stmt_iterator head, tsi;
- block_stmt_iterator bsi;
+ gimple_stmt_iterator gsi;
basic_block cond_bb, then_bb, join_bb;
edge e;
tree cond, t, u, v;
tree mf_base;
tree mf_elem;
tree mf_limit;
+ gimple g;
+ gimple_seq seq;
/* We first need to split the current basic block, and start altering
the CFG. This allows us to insert the statements we're about to
construct into the right basic blocks. */
- cond_bb = bb_for_stmt (bsi_stmt (*instr_bsi));
- bsi = *instr_bsi;
- bsi_prev (&bsi);
- if (! bsi_end_p (bsi))
- e = split_block (cond_bb, bsi_stmt (bsi));
+ cond_bb = gimple_bb (gsi_stmt (*instr_gsi));
+ gsi = *instr_gsi;
+ gsi_prev (&gsi);
+ if (! gsi_end_p (gsi))
+ e = split_block (cond_bb, gsi_stmt (gsi));
else
e = split_block_after_labels (cond_bb);
cond_bb = e->src;
@@ -556,21 +551,19 @@ mf_build_check_statement_for (tree base, tree limit,
mf_limit = create_tmp_var (mf_uintptr_type, "__mf_limit");
/* Build: __mf_base = (uintptr_t) <base address expression>. */
- t = build_gimple_modify_stmt (mf_base,
- fold_convert (mf_uintptr_type,
- unshare_expr (base)));
- SET_EXPR_LOCUS (t, locus);
- gimplify_to_stmt_list (&t);
- head = tsi_start (t);
- tsi = tsi_last (t);
+ seq = gimple_seq_alloc ();
+ t = fold_convert (mf_uintptr_type, unshare_expr (base));
+ gimplify_expr (&t, &seq, &seq, is_gimple_reg_rhs, fb_rvalue);
+ g = gimple_build_assign (mf_base, t);
+ gimple_set_location (g, location);
+ gimple_seq_add_stmt (&seq, g);
/* Build: __mf_limit = (uintptr_t) <limit address expression>. */
- t = build_gimple_modify_stmt (mf_limit,
- fold_convert (mf_uintptr_type,
- unshare_expr (limit)));
- SET_EXPR_LOCUS (t, locus);
- gimplify_to_stmt_list (&t);
- tsi_link_after (&tsi, t, TSI_CONTINUE_LINKING);
+ t = fold_convert (mf_uintptr_type, unshare_expr (limit));
+ gimplify_expr (&t, &seq, &seq, is_gimple_reg_rhs, fb_rvalue);
+ g = gimple_build_assign (mf_limit, t);
+ gimple_set_location (g, location);
+ gimple_seq_add_stmt (&seq, g);
/* Build: __mf_elem = &__mf_lookup_cache [(__mf_base >> __mf_shift)
& __mf_mask]. */
@@ -584,10 +577,10 @@ mf_build_check_statement_for (tree base, tree limit,
TREE_TYPE (TREE_TYPE (mf_cache_array_decl)),
mf_cache_array_decl, t, NULL_TREE, NULL_TREE);
t = build1 (ADDR_EXPR, mf_cache_structptr_type, t);
- t = build_gimple_modify_stmt (mf_elem, t);
- SET_EXPR_LOCUS (t, locus);
- gimplify_to_stmt_list (&t);
- tsi_link_after (&tsi, t, TSI_CONTINUE_LINKING);
+ gimplify_expr (&t, &seq, &seq, is_gimple_reg_rhs, fb_rvalue);
+ g = gimple_build_assign (mf_elem, t);
+ gimple_set_location (g, location);
+ gimple_seq_add_stmt (&seq, g);
/* Quick validity check.
@@ -629,16 +622,18 @@ mf_build_check_statement_for (tree base, tree limit,
result of the evaluation of 't' in a temporary variable which we
can use as the condition for the conditional jump. */
t = build2 (TRUTH_OR_EXPR, boolean_type_node, t, u);
+ gimplify_expr (&t, &seq, &seq, is_gimple_reg_rhs, fb_rvalue);
cond = create_tmp_var (boolean_type_node, "__mf_unlikely_cond");
- t = build_gimple_modify_stmt (cond, t);
- gimplify_to_stmt_list (&t);
- tsi_link_after (&tsi, t, TSI_CONTINUE_LINKING);
+ g = gimple_build_assign (cond, t);
+ gimple_set_location (g, location);
+ gimple_seq_add_stmt (&seq, g);
/* Build the conditional jump. 'cond' is just a temporary so we can
simply build a void COND_EXPR. We do need labels in both arms though. */
- t = build3 (COND_EXPR, void_type_node, cond, NULL_TREE, NULL_TREE);
- SET_EXPR_LOCUS (t, locus);
- tsi_link_after (&tsi, t, TSI_CONTINUE_LINKING);
+ g = gimple_build_cond (NE_EXPR, cond, integer_zero_node, NULL_TREE,
+ NULL_TREE);
+ gimple_set_location (g, location);
+ gimple_seq_add_stmt (&seq, g);
/* At this point, after so much hard work, we have only constructed
the conditional jump,
@@ -651,9 +646,8 @@ mf_build_check_statement_for (tree base, tree limit,
We can insert this now in the current basic block, i.e. the one that
the statement we're instrumenting was originally in. */
- bsi = bsi_last (cond_bb);
- for (tsi = head; ! tsi_end_p (tsi); tsi_next (&tsi))
- bsi_insert_after (&bsi, tsi_stmt (tsi), BSI_CONTINUE_LINKING);
+ gsi = gsi_last_bb (cond_bb);
+ gsi_insert_seq_after (&gsi, seq, GSI_CONTINUE_LINKING);
/* Now build up the body of the cache-miss handling:
@@ -662,33 +656,31 @@ mf_build_check_statement_for (tree base, tree limit,
This is the body of the conditional. */
- u = mf_file_function_line_tree (locus == NULL ? UNKNOWN_LOCATION : *locus);
+ seq = gimple_seq_alloc ();
+ /* u is a string, so it is already a gimple value. */
+ u = mf_file_function_line_tree (location);
/* NB: we pass the overall [base..limit] range to mf_check. */
v = fold_build2 (PLUS_EXPR, integer_type_node,
fold_build2 (MINUS_EXPR, mf_uintptr_type, mf_limit, mf_base),
integer_one_node);
- t = build_call_expr (mf_check_fndecl, 4, mf_base, v, dirflag, u);
- gimplify_to_stmt_list (&t);
- head = tsi_start (t);
- tsi = tsi_last (t);
+ gimplify_expr (&v, &seq, &seq, is_gimple_mem_rhs, fb_rvalue);
+ g = gimple_build_call (mf_check_fndecl, 4, mf_base, v, dirflag, u);
+ gimple_seq_add_stmt (&seq, g);
if (! flag_mudflap_threads)
{
- t = build_gimple_modify_stmt (mf_cache_shift_decl_l,
- mf_cache_shift_decl);
- tsi_link_after (&tsi, t, TSI_CONTINUE_LINKING);
+ g = gimple_build_assign (mf_cache_shift_decl_l, mf_cache_shift_decl);
+ gimple_seq_add_stmt (&seq, g);
- t = build_gimple_modify_stmt (mf_cache_mask_decl_l,
- mf_cache_mask_decl);
- tsi_link_after (&tsi, t, TSI_CONTINUE_LINKING);
+ g = gimple_build_assign (mf_cache_mask_decl_l, mf_cache_mask_decl);
+ gimple_seq_add_stmt (&seq, g);
}
/* Insert the check code in the THEN block. */
- bsi = bsi_start (then_bb);
- for (tsi = head; ! tsi_end_p (tsi); tsi_next (&tsi))
- bsi_insert_after (&bsi, tsi_stmt (tsi), BSI_CONTINUE_LINKING);
+ gsi = gsi_start_bb (then_bb);
+ gsi_insert_seq_after (&gsi, seq, GSI_CONTINUE_LINKING);
- *instr_bsi = bsi_start (join_bb);
+ *instr_gsi = gsi_start_bb (join_bb);
}
@@ -715,8 +707,8 @@ mf_decl_eligible_p (tree decl)
static void
-mf_xform_derefs_1 (block_stmt_iterator *iter, tree *tp,
- location_t *locus, tree dirflag)
+mf_xform_derefs_1 (gimple_stmt_iterator *iter, tree *tp,
+ location_t location, tree dirflag)
{
tree type, base, limit, addr, size, t;
@@ -896,44 +888,45 @@ mf_xform_derefs_1 (block_stmt_iterator *iter, tree *tp,
return;
}
- mf_build_check_statement_for (base, limit, iter, locus, dirflag);
+ mf_build_check_statement_for (base, limit, iter, location, dirflag);
}
static void
mf_xform_derefs (void)
{
basic_block bb, next;
- block_stmt_iterator i;
+ gimple_stmt_iterator i;
int saved_last_basic_block = last_basic_block;
+ enum gimple_rhs_class class;
bb = ENTRY_BLOCK_PTR ->next_bb;
do
{
next = bb->next_bb;
- for (i = bsi_start (bb); !bsi_end_p (i); bsi_next (&i))
+ for (i = gsi_start_bb (bb); !gsi_end_p (i); gsi_next (&i))
{
- tree s = bsi_stmt (i);
+ gimple s = gsi_stmt (i);
/* Only a few GIMPLE statements can reference memory. */
- switch (TREE_CODE (s))
+ switch (gimple_code (s))
{
- case GIMPLE_MODIFY_STMT:
- mf_xform_derefs_1 (&i, &GIMPLE_STMT_OPERAND (s, 0),
- EXPR_LOCUS (s), integer_one_node);
- mf_xform_derefs_1 (&i, &GIMPLE_STMT_OPERAND (s, 1),
- EXPR_LOCUS (s), integer_zero_node);
+ case GIMPLE_ASSIGN:
+ mf_xform_derefs_1 (&i, gimple_assign_lhs_ptr (s),
+ gimple_location (s), integer_one_node);
+ mf_xform_derefs_1 (&i, gimple_assign_rhs1_ptr (s),
+ gimple_location (s), integer_zero_node);
+ class = get_gimple_rhs_class (gimple_assign_rhs_code (s));
+ if (class == GIMPLE_BINARY_RHS)
+ mf_xform_derefs_1 (&i, gimple_assign_rhs2_ptr (s),
+ gimple_location (s), integer_zero_node);
break;
- case RETURN_EXPR:
- if (TREE_OPERAND (s, 0) != NULL_TREE)
+ case GIMPLE_RETURN:
+ if (gimple_return_retval (s) != NULL_TREE)
{
- if (TREE_CODE (TREE_OPERAND (s, 0)) == GIMPLE_MODIFY_STMT)
- mf_xform_derefs_1 (&i, &GIMPLE_STMT_OPERAND
- (TREE_OPERAND (s, 0), 1),
- EXPR_LOCUS (s), integer_zero_node);
- else
- mf_xform_derefs_1 (&i, &TREE_OPERAND (s, 0), EXPR_LOCUS (s),
- integer_zero_node);
+ mf_xform_derefs_1 (&i, gimple_return_retval_ptr (s),
+ gimple_location (s),
+ integer_zero_node);
}
break;
@@ -958,15 +951,17 @@ mf_xform_derefs (void)
static unsigned int
execute_mudflap_function_decls (void)
{
+ struct gimplify_ctx gctx;
+
/* Don't instrument functions such as the synthetic constructor
built during mudflap_finish_file. */
if (mf_marked_p (current_function_decl) ||
DECL_ARTIFICIAL (current_function_decl))
return 0;
- push_gimplify_context ();
+ push_gimplify_context (&gctx);
- mf_xform_decls (DECL_SAVED_TREE (current_function_decl),
+ mf_xform_decls (gimple_body (current_function_decl),
DECL_ARGUMENTS (current_function_decl));
pop_gimplify_context (NULL);
@@ -984,12 +979,13 @@ struct mf_xform_decls_data
/* Synthesize a CALL_EXPR and a TRY_FINALLY_EXPR, for this chain of
_DECLs if appropriate. Arrange to call the __mf_register function
- now, and the __mf_unregister function later for each. */
-static void
-mx_register_decls (tree decl, tree *stmt_list)
+ now, and the __mf_unregister function later for each. Return the
+ gimple sequence after synthesis. */
+gimple_seq
+mx_register_decls (tree decl, gimple_seq seq, location_t location)
{
- tree finally_stmts = NULL_TREE;
- tree_stmt_iterator initially_stmts = tsi_start (*stmt_list);
+ gimple_seq finally_stmts = NULL;
+ gimple_stmt_iterator initially_stmts = gsi_start (seq);
while (decl != NULL_TREE)
{
@@ -1001,46 +997,46 @@ mx_register_decls (tree decl, tree *stmt_list)
&& ! TREE_STATIC (decl))
{
tree size = NULL_TREE, variable_name;
- tree unregister_fncall, unregister_fncall_param;
- tree register_fncall, register_fncall_param;
+ gimple unregister_fncall, register_fncall;
+ tree unregister_fncall_param, register_fncall_param;
+ /* Variable-sized objects should have sizes already been
+ gimplified when we got here. */
size = convert (size_type_node, TYPE_SIZE_UNIT (TREE_TYPE (decl)));
-
+ gcc_assert (is_gimple_val (size));
+
unregister_fncall_param =
- convert (ptr_type_node,
- mf_mark (build1 (ADDR_EXPR,
- build_pointer_type (TREE_TYPE (decl)),
- decl)));
+ mf_mark (build1 (ADDR_EXPR,
+ build_pointer_type (TREE_TYPE (decl)),
+ decl));
/* __mf_unregister (&VARIABLE, sizeof (VARIABLE), __MF_TYPE_STACK) */
- unregister_fncall = build_call_expr (mf_unregister_fndecl, 3,
- unregister_fncall_param,
- size,
- build_int_cst (NULL_TREE, 3));
+ unregister_fncall = gimple_build_call (mf_unregister_fndecl, 3,
+ unregister_fncall_param,
+ size,
+ build_int_cst (NULL_TREE, 3));
variable_name = mf_varname_tree (decl);
register_fncall_param =
- convert (ptr_type_node,
- mf_mark (build1 (ADDR_EXPR,
- build_pointer_type (TREE_TYPE (decl)),
- decl)));
+ mf_mark (build1 (ADDR_EXPR,
+ build_pointer_type (TREE_TYPE (decl)),
+ decl));
/* __mf_register (&VARIABLE, sizeof (VARIABLE), __MF_TYPE_STACK,
"name") */
- register_fncall = build_call_expr (mf_register_fndecl, 4,
- register_fncall_param,
- size,
- build_int_cst (NULL_TREE, 3),
- variable_name);
-
+ register_fncall = gimple_build_call (mf_register_fndecl, 4,
+ register_fncall_param,
+ size,
+ build_int_cst (NULL_TREE, 3),
+ variable_name);
+
/* Accumulate the two calls. */
- /* ??? Set EXPR_LOCATION. */
- gimplify_stmt (&register_fncall);
- gimplify_stmt (&unregister_fncall);
+ gimple_set_location (register_fncall, location);
+ gimple_set_location (unregister_fncall, location);
/* Add the __mf_register call at the current appending point. */
- if (tsi_end_p (initially_stmts))
+ if (gsi_end_p (initially_stmts))
{
if (!DECL_ARTIFICIAL (decl))
warning (OPT_Wmudflap,
@@ -1049,11 +1045,11 @@ mx_register_decls (tree decl, tree *stmt_list)
}
else
{
- tsi_link_before (&initially_stmts, register_fncall,
- TSI_SAME_STMT);
+ gsi_insert_before (&initially_stmts, register_fncall,
+ GSI_SAME_STMT);
/* Accumulate the FINALLY piece. */
- append_to_statement_list (unregister_fncall, &finally_stmts);
+ gimple_seq_add_stmt (&finally_stmts, unregister_fncall);
}
mf_mark (decl);
}
@@ -1062,39 +1058,46 @@ mx_register_decls (tree decl, tree *stmt_list)
}
/* Actually, (initially_stmts!=NULL) <=> (finally_stmts!=NULL) */
- if (finally_stmts != NULL_TREE)
+ if (finally_stmts != NULL)
{
- tree t = build2 (TRY_FINALLY_EXPR, void_type_node,
- *stmt_list, finally_stmts);
- *stmt_list = NULL;
- append_to_statement_list (t, stmt_list);
+ gimple stmt = gimple_build_try (seq, finally_stmts, GIMPLE_TRY_FINALLY);
+ gimple_seq new_seq = gimple_seq_alloc ();
+
+ gimple_seq_add_stmt (&new_seq, stmt);
+ return new_seq;
}
+ else
+ return seq;
}
/* Process every variable mentioned in BIND_EXPRs. */
static tree
-mx_xfn_xform_decls (tree *t, int *continue_p, void *data)
+mx_xfn_xform_decls (gimple_stmt_iterator *gsi,
+ bool *handled_operands_p ATTRIBUTE_UNUSED,
+ struct walk_stmt_info *wi)
{
- struct mf_xform_decls_data* d = (struct mf_xform_decls_data*) data;
+ struct mf_xform_decls_data *d = (struct mf_xform_decls_data *) wi->info;
+ gimple stmt = gsi_stmt (*gsi);
- if (*t == NULL_TREE || *t == error_mark_node)
+ switch (gimple_code (stmt))
{
- *continue_p = 0;
- return NULL_TREE;
- }
-
- *continue_p = 1;
-
- switch (TREE_CODE (*t))
- {
- case BIND_EXPR:
+ case GIMPLE_BIND:
{
/* Process function parameters now (but only once). */
- mx_register_decls (d->param_decls, &BIND_EXPR_BODY (*t));
- d->param_decls = NULL_TREE;
+ if (d->param_decls)
+ {
+ gimple_bind_set_body (stmt,
+ mx_register_decls (d->param_decls,
+ gimple_bind_body (stmt),
+ gimple_location (stmt)));
+ d->param_decls = NULL_TREE;
+ }
- mx_register_decls (BIND_EXPR_VARS (*t), &BIND_EXPR_BODY (*t));
+ gimple_bind_set_body (stmt,
+ mx_register_decls (gimple_bind_vars (stmt),
+ gimple_bind_body (stmt),
+ gimple_location (stmt)));
}
break;
@@ -1114,11 +1117,18 @@ mx_xfn_xform_decls (tree *t, int *continue_p, void *data)
*/
static void
-mf_xform_decls (tree fnbody, tree fnparams)
+mf_xform_decls (gimple_seq fnbody, tree fnparams)
{
struct mf_xform_decls_data d;
+ struct walk_stmt_info wi;
+ struct pointer_set_t *pset = pointer_set_create ();
+
d.param_decls = fnparams;
- walk_tree_without_duplicates (&fnbody, mx_xfn_xform_decls, &d);
+ memset (&wi, 0, sizeof (wi));
+ wi.info = (void*) &d;
+ wi.pset = pset;
+ walk_gimple_seq (fnbody, mx_xfn_xform_decls, NULL, &wi);
+ pointer_set_destroy (pset);
}
diff --git a/gcc/tree-nested.c b/gcc/tree-nested.c
index 225605071cc..8f4ab047ae9 100644
--- a/gcc/tree-nested.c
+++ b/gcc/tree-nested.c
@@ -1,4 +1,4 @@
-/* Nested function decomposition for trees.
+/* Nested function decomposition for GIMPLE.
Copyright (C) 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
This file is part of GCC.
@@ -15,7 +15,7 @@
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/>. */
+ <http://www.gnu.org/licenses/>. */
#include "config.h"
#include "system.h"
@@ -27,7 +27,7 @@
#include "function.h"
#include "tree-dump.h"
#include "tree-inline.h"
-#include "tree-gimple.h"
+#include "gimple.h"
#include "tree-iterator.h"
#include "tree-flow.h"
#include "cgraph.h"
@@ -355,46 +355,70 @@ get_chain_field (struct nesting_info *info)
return field;
}
+/* Initialize a new temporary with the GIMPLE_CALL STMT. */
+
+static tree
+init_tmp_var_with_call (struct nesting_info *info, gimple_stmt_iterator *gsi,
+ gimple call)
+{
+ tree t;
+
+ t = create_tmp_var_for (info, TREE_TYPE (TREE_TYPE (gimple_call_fn (call))),
+ NULL);
+ gimple_call_set_lhs (call, t);
+ if (! gsi_end_p (*gsi))
+ gimple_set_location (call, gimple_location (gsi_stmt (*gsi)));
+ gsi_insert_before (gsi, call, GSI_SAME_STMT);
+
+ return t;
+}
+
+
/* Copy EXP into a temporary. Allocate the temporary in the context of
- INFO and insert the initialization statement before TSI. */
+ INFO and insert the initialization statement before GSI. */
static tree
-init_tmp_var (struct nesting_info *info, tree exp, tree_stmt_iterator *tsi)
+init_tmp_var (struct nesting_info *info, tree exp, gimple_stmt_iterator *gsi)
{
- tree t, stmt;
+ tree t;
+ gimple stmt;
t = create_tmp_var_for (info, TREE_TYPE (exp), NULL);
- stmt = build_gimple_modify_stmt (t, exp);
- SET_EXPR_LOCUS (stmt, EXPR_LOCUS (tsi_stmt (*tsi)));
- tsi_link_before (tsi, stmt, TSI_SAME_STMT);
+ stmt = gimple_build_assign (t, exp);
+ if (! gsi_end_p (*gsi))
+ gimple_set_location (stmt, gimple_location (gsi_stmt (*gsi)));
+ gsi_insert_before_without_update (gsi, stmt, GSI_SAME_STMT);
return t;
}
+
/* Similarly, but only do so to force EXP to satisfy is_gimple_val. */
static tree
-tsi_gimplify_val (struct nesting_info *info, tree exp, tree_stmt_iterator *tsi)
+gsi_gimplify_val (struct nesting_info *info, tree exp,
+ gimple_stmt_iterator *gsi)
{
if (is_gimple_val (exp))
return exp;
else
- return init_tmp_var (info, exp, tsi);
+ return init_tmp_var (info, exp, gsi);
}
/* Similarly, but copy from the temporary and insert the statement
after the iterator. */
static tree
-save_tmp_var (struct nesting_info *info, tree exp,
- tree_stmt_iterator *tsi)
+save_tmp_var (struct nesting_info *info, tree exp, gimple_stmt_iterator *gsi)
{
- tree t, stmt;
+ tree t;
+ gimple stmt;
t = create_tmp_var_for (info, TREE_TYPE (exp), NULL);
- stmt = build_gimple_modify_stmt (exp, t);
- SET_EXPR_LOCUS (stmt, EXPR_LOCUS (tsi_stmt (*tsi)));
- tsi_link_after (tsi, stmt, TSI_SAME_STMT);
+ stmt = gimple_build_assign (exp, t);
+ if (! gsi_end_p (*gsi))
+ gimple_set_location (stmt, gimple_location (gsi_stmt (*gsi)));
+ gsi_insert_after_without_update (gsi, stmt, GSI_SAME_STMT);
return t;
}
@@ -512,236 +536,102 @@ get_nl_goto_field (struct nesting_info *info)
return field;
}
-
-/* Helper function for walk_stmts. Walk output operands of an ASM_EXPR. */
-
-static void
-walk_asm_expr (struct walk_stmt_info *wi, tree stmt)
-{
- int noutputs = list_length (ASM_OUTPUTS (stmt));
- const char **oconstraints
- = (const char **) alloca ((noutputs) * sizeof (const char *));
- int i;
- tree link;
- const char *constraint;
- bool allows_mem, allows_reg, is_inout;
-
- wi->is_lhs = true;
- for (i=0, link = ASM_OUTPUTS (stmt); link; ++i, link = TREE_CHAIN (link))
- {
- constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
- oconstraints[i] = constraint;
- parse_output_constraint (&constraint, i, 0, 0, &allows_mem,
- &allows_reg, &is_inout);
-
- wi->val_only = (allows_reg || !allows_mem);
- walk_tree (&TREE_VALUE (link), wi->callback, wi, NULL);
- }
-
- for (link = ASM_INPUTS (stmt); link; link = TREE_CHAIN (link))
- {
- constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
- parse_input_constraint (&constraint, 0, 0, noutputs, 0,
- oconstraints, &allows_mem, &allows_reg);
-
- wi->val_only = (allows_reg || !allows_mem);
- /* Although input "m" is not really a LHS, we need a lvalue. */
- wi->is_lhs = !wi->val_only;
- walk_tree (&TREE_VALUE (link), wi->callback, wi, NULL);
- }
-
- wi->is_lhs = false;
- wi->val_only = true;
-}
-
-/* Iterate over all sub-statements of *TP calling walk_tree with
- WI->CALLBACK for every sub-expression in each statement found. */
-
-void
-walk_stmts (struct walk_stmt_info *wi, tree *tp)
-{
- tree t = *tp;
- int walk_subtrees;
-
- if (!t)
- return;
- if (wi->want_locations && EXPR_HAS_LOCATION (t))
- input_location = EXPR_LOCATION (t);
-
- switch (TREE_CODE (t))
- {
- case STATEMENT_LIST:
- {
- tree_stmt_iterator i;
- for (i = tsi_start (t); !tsi_end_p (i); tsi_next (&i))
- {
- wi->tsi = i;
- walk_stmts (wi, tsi_stmt_ptr (i));
- }
- }
- break;
-
- case COND_EXPR:
- walk_tree (&COND_EXPR_COND (t), wi->callback, wi, NULL);
- walk_stmts (wi, &COND_EXPR_THEN (t));
- walk_stmts (wi, &COND_EXPR_ELSE (t));
- break;
- case CATCH_EXPR:
- walk_stmts (wi, &CATCH_BODY (t));
- break;
- case EH_FILTER_EXPR:
- walk_stmts (wi, &EH_FILTER_FAILURE (t));
- break;
- case TRY_CATCH_EXPR:
- case TRY_FINALLY_EXPR:
- walk_stmts (wi, &TREE_OPERAND (t, 0));
- walk_stmts (wi, &TREE_OPERAND (t, 1));
- break;
-
- case BIND_EXPR:
- if (wi->want_bind_expr)
- {
- walk_subtrees = 1;
- wi->callback (tp, &walk_subtrees, wi);
- if (!walk_subtrees)
- break;
- }
- walk_stmts (wi, &BIND_EXPR_BODY (t));
- break;
-
- case RETURN_EXPR:
- if (wi->want_return_expr)
- {
- walk_subtrees = 1;
- wi->callback (tp, &walk_subtrees, wi);
- if (!walk_subtrees)
- break;
- }
- walk_stmts (wi, &TREE_OPERAND (t, 0));
- break;
-
- case GIMPLE_MODIFY_STMT:
- /* A formal temporary lhs may use a COMPONENT_REF rhs. */
- wi->val_only = !is_gimple_formal_tmp_var (GIMPLE_STMT_OPERAND (t, 0));
- walk_tree (&GIMPLE_STMT_OPERAND (t, 1), wi->callback, wi, NULL);
-
- /* If the rhs is appropriate for a memory, we may use a
- COMPONENT_REF on the lhs. */
- wi->val_only = !is_gimple_mem_rhs (GIMPLE_STMT_OPERAND (t, 1));
- wi->is_lhs = true;
- walk_tree (&GIMPLE_STMT_OPERAND (t, 0), wi->callback, wi, NULL);
-
- wi->val_only = true;
- wi->is_lhs = false;
- break;
-
- case ASM_EXPR:
- walk_asm_expr (wi, *tp);
- break;
-
- default:
- wi->val_only = true;
- walk_tree (tp, wi->callback, wi, NULL);
- break;
- }
-}
-
-/* Invoke CALLBACK on all statements of *STMT_P. */
+/* Invoke CALLBACK on all statements of GIMPLE sequence SEQ. */
static void
-walk_body (walk_tree_fn callback, struct nesting_info *info, tree *stmt_p)
+walk_body (walk_stmt_fn callback_stmt, walk_tree_fn callback_op,
+ struct nesting_info *info, gimple_seq seq)
{
struct walk_stmt_info wi;
memset (&wi, 0, sizeof (wi));
- wi.callback = callback;
wi.info = info;
wi.val_only = true;
-
- walk_stmts (&wi, stmt_p);
+ walk_gimple_seq (seq, callback_stmt, callback_op, &wi);
}
-/* Invoke CALLBACK on all statements of INFO->CONTEXT. */
+
+/* Invoke CALLBACK_STMT/CALLBACK_OP on all statements of INFO->CONTEXT. */
static inline void
-walk_function (walk_tree_fn callback, struct nesting_info *info)
+walk_function (walk_stmt_fn callback_stmt, walk_tree_fn callback_op,
+ struct nesting_info *info)
{
- walk_body (callback, info, &DECL_SAVED_TREE (info->context));
+ walk_body (callback_stmt, callback_op, info, gimple_body (info->context));
}
-/* Invoke CALLBACK on OMP_FOR init, cond, incr and pre-body. */
+/* Invoke CALLBACK on a GIMPLE_OMP_FOR's init, cond, incr and pre-body. */
static void
-walk_omp_for (walk_tree_fn callback, struct nesting_info *info, tree for_stmt)
+walk_gimple_omp_for (gimple for_stmt,
+ walk_stmt_fn callback_stmt, walk_tree_fn callback_op,
+ struct nesting_info *info)
{
struct walk_stmt_info wi;
- tree t, list = NULL, empty;
- int i;
+ gimple_seq seq;
+ tree t;
+ size_t i;
- walk_body (callback, info, &OMP_FOR_PRE_BODY (for_stmt));
+ walk_body (callback_stmt, callback_op, info, gimple_omp_for_pre_body (for_stmt));
- empty = build_empty_stmt ();
- append_to_statement_list_force (empty, &list);
+ seq = gimple_seq_alloc ();
memset (&wi, 0, sizeof (wi));
- wi.callback = callback;
wi.info = info;
- wi.tsi = tsi_last (list);
+ wi.gsi = gsi_last (seq);
- for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
+ for (i = 0; i < gimple_omp_for_collapse (for_stmt); i++)
{
- t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
- gcc_assert (TREE_CODE (t) == GIMPLE_MODIFY_STMT);
- SET_EXPR_LOCUS (empty, EXPR_LOCUS (t));
wi.val_only = false;
- walk_tree (&GIMPLE_STMT_OPERAND (t, 0), callback, &wi, NULL);
+ walk_tree (gimple_omp_for_index_ptr (for_stmt, i), callback_op,
+ &wi, NULL);
wi.val_only = true;
wi.is_lhs = false;
- walk_tree (&GIMPLE_STMT_OPERAND (t, 1), callback, &wi, NULL);
+ walk_tree (gimple_omp_for_initial_ptr (for_stmt, i), callback_op,
+ &wi, NULL);
- t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
- gcc_assert (COMPARISON_CLASS_P (t));
- SET_EXPR_LOCUS (empty, EXPR_LOCUS (t));
- wi.val_only = false;
- walk_tree (&TREE_OPERAND (t, 0), callback, &wi, NULL);
wi.val_only = true;
wi.is_lhs = false;
- walk_tree (&TREE_OPERAND (t, 1), callback, &wi, NULL);
+ walk_tree (gimple_omp_for_final_ptr (for_stmt, i), callback_op,
+ &wi, NULL);
- t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
- gcc_assert (TREE_CODE (t) == GIMPLE_MODIFY_STMT);
- SET_EXPR_LOCUS (empty, EXPR_LOCUS (t));
- wi.val_only = false;
- walk_tree (&GIMPLE_STMT_OPERAND (t, 0), callback, &wi, NULL);
- t = GIMPLE_STMT_OPERAND (t, 1);
+ t = gimple_omp_for_incr (for_stmt, i);
gcc_assert (BINARY_CLASS_P (t));
wi.val_only = false;
- walk_tree (&TREE_OPERAND (t, 0), callback, &wi, NULL);
+ walk_tree (&TREE_OPERAND (t, 0), callback_op, &wi, NULL);
wi.val_only = true;
wi.is_lhs = false;
- walk_tree (&TREE_OPERAND (t, 1), callback, &wi, NULL);
+ walk_tree (&TREE_OPERAND (t, 1), callback_op, &wi, NULL);
}
- /* Remove empty statement added above from the end of statement list. */
- tsi_delink (&wi.tsi);
- append_to_statement_list (list, &OMP_FOR_PRE_BODY (for_stmt));
+ if (gimple_seq_empty_p (seq))
+ gimple_seq_free (seq);
+ else
+ {
+ gimple_seq pre_body = gimple_omp_for_pre_body (for_stmt);
+ annotate_all_with_location (seq, gimple_location (for_stmt));
+ gimple_seq_add_seq (&pre_body, seq);
+ gimple_omp_for_set_pre_body (for_stmt, pre_body);
+ }
}
/* Similarly for ROOT and all functions nested underneath, depth first. */
static void
-walk_all_functions (walk_tree_fn callback, struct nesting_info *root)
+walk_all_functions (walk_stmt_fn callback_stmt, walk_tree_fn callback_op,
+ struct nesting_info *root)
{
do
{
if (root->inner)
- walk_all_functions (callback, root->inner);
- walk_function (callback, root);
+ walk_all_functions (callback_stmt, callback_op, root->inner);
+ walk_function (callback_stmt, callback_op, root);
root = root->next;
}
while (root);
}
-
+
+
/* We have to check for a fairly pathological case. The operands of function
nested function are to be interpreted in the context of the enclosing
function. So if any are variably-sized, they will get remapped when the
@@ -817,7 +707,7 @@ create_nesting_tree (struct cgraph_node *cgn)
static tree
get_static_chain (struct nesting_info *info, tree target_context,
- tree_stmt_iterator *tsi)
+ gimple_stmt_iterator *gsi)
{
struct nesting_info *i;
tree x;
@@ -836,20 +726,21 @@ get_static_chain (struct nesting_info *info, tree target_context,
x = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (x)), x);
x = build3 (COMPONENT_REF, TREE_TYPE (field), x, field, NULL_TREE);
- x = init_tmp_var (info, x, tsi);
+ x = init_tmp_var (info, x, gsi);
}
}
return x;
}
+
/* Return an expression referencing FIELD from TARGET_CONTEXT's non-local
frame as seen from INFO->CONTEXT. Insert any necessary computations
- before TSI. */
+ before GSI. */
static tree
get_frame_field (struct nesting_info *info, tree target_context,
- tree field, tree_stmt_iterator *tsi)
+ tree field, gimple_stmt_iterator *gsi)
{
struct nesting_info *i;
tree x;
@@ -870,7 +761,7 @@ get_frame_field (struct nesting_info *info, tree target_context,
x = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (x)), x);
x = build3 (COMPONENT_REF, TREE_TYPE (field), x, field, NULL_TREE);
- x = init_tmp_var (info, x, tsi);
+ x = init_tmp_var (info, x, gsi);
}
x = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (x)), x);
@@ -880,7 +771,8 @@ get_frame_field (struct nesting_info *info, tree target_context,
return x;
}
-/* A subroutine of convert_nonlocal_reference. Create a local variable
+
+/* A subroutine of convert_nonlocal_reference_op. Create a local variable
in the nested function with DECL_VALUE_EXPR set to reference the true
variable in the parent function. This is used both for debug info
and in OpenMP lowering. */
@@ -947,7 +839,8 @@ get_nonlocal_debug_decl (struct nesting_info *info, tree decl)
return new_decl;
}
-/* Called via walk_function+walk_tree, rewrite all references to VAR
+
+/* Callback for walk_gimple_stmt, rewrite all references to VAR
and PARM_DECLs that belong to outer functions.
The rewrite will involve some number of structure accesses back up
@@ -955,16 +848,12 @@ get_nonlocal_debug_decl (struct nesting_info *info, tree decl)
be CHAIN->FOO. For two levels it'll be CHAIN->__chain->FOO. Further
indirections apply to decls for which use_pointer_in_frame is true. */
-static bool convert_nonlocal_omp_clauses (tree *, struct walk_stmt_info *);
-
static tree
-convert_nonlocal_reference (tree *tp, int *walk_subtrees, void *data)
+convert_nonlocal_reference_op (tree *tp, int *walk_subtrees, void *data)
{
struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
struct nesting_info *const info = (struct nesting_info *) wi->info;
tree t = *tp;
- tree save_local_var_chain;
- bitmap save_suppress;
*walk_subtrees = 0;
switch (TREE_CODE (t))
@@ -989,10 +878,10 @@ convert_nonlocal_reference (tree *tp, int *walk_subtrees, void *data)
for (i = info->outer; i->context != target_context; i = i->outer)
continue;
x = lookup_field_for_decl (i, t, INSERT);
- x = get_frame_field (info, target_context, x, &wi->tsi);
+ x = get_frame_field (info, target_context, x, &wi->gsi);
if (use_pointer_in_frame (t))
{
- x = init_tmp_var (info, x, &wi->tsi);
+ x = init_tmp_var (info, x, &wi->gsi);
x = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (x)), x);
}
}
@@ -1000,25 +889,15 @@ convert_nonlocal_reference (tree *tp, int *walk_subtrees, void *data)
if (wi->val_only)
{
if (wi->is_lhs)
- x = save_tmp_var (info, x, &wi->tsi);
+ x = save_tmp_var (info, x, &wi->gsi);
else
- x = init_tmp_var (info, x, &wi->tsi);
+ x = init_tmp_var (info, x, &wi->gsi);
}
*tp = x;
}
break;
- case GOTO_EXPR:
- /* Don't walk non-local gotos for now. */
- if (TREE_CODE (GOTO_DESTINATION (t)) != LABEL_DECL)
- {
- *walk_subtrees = 1;
- wi->val_only = true;
- wi->is_lhs = false;
- }
- break;
-
case LABEL_DECL:
/* We're taking the address of a label from a parent function, but
this is not itself a non-local goto. Mark the label such that it
@@ -1035,7 +914,7 @@ convert_nonlocal_reference (tree *tp, int *walk_subtrees, void *data)
wi->val_only = false;
wi->is_lhs = false;
wi->changed = false;
- walk_tree (&TREE_OPERAND (t, 0), convert_nonlocal_reference, wi, NULL);
+ walk_tree (&TREE_OPERAND (t, 0), convert_nonlocal_reference_op, wi, 0);
wi->val_only = true;
if (wi->changed)
@@ -1053,8 +932,8 @@ convert_nonlocal_reference (tree *tp, int *walk_subtrees, void *data)
where we only accept variables (and min_invariant, presumably),
then compute the address into a temporary. */
if (save_val_only)
- *tp = tsi_gimplify_val ((struct nesting_info *) wi->info,
- t, &wi->tsi);
+ *tp = gsi_gimplify_val ((struct nesting_info *) wi->info,
+ t, &wi->gsi);
}
}
break;
@@ -1073,28 +952,28 @@ convert_nonlocal_reference (tree *tp, int *walk_subtrees, void *data)
for (; handled_component_p (t); tp = &TREE_OPERAND (t, 0), t = *tp)
{
if (TREE_CODE (t) == COMPONENT_REF)
- walk_tree (&TREE_OPERAND (t, 2), convert_nonlocal_reference, wi,
+ walk_tree (&TREE_OPERAND (t, 2), convert_nonlocal_reference_op, wi,
NULL);
else if (TREE_CODE (t) == ARRAY_REF
|| TREE_CODE (t) == ARRAY_RANGE_REF)
{
- walk_tree (&TREE_OPERAND (t, 1), convert_nonlocal_reference, wi,
- NULL);
- walk_tree (&TREE_OPERAND (t, 2), convert_nonlocal_reference, wi,
- NULL);
- walk_tree (&TREE_OPERAND (t, 3), convert_nonlocal_reference, wi,
- NULL);
+ walk_tree (&TREE_OPERAND (t, 1), convert_nonlocal_reference_op,
+ wi, NULL);
+ walk_tree (&TREE_OPERAND (t, 2), convert_nonlocal_reference_op,
+ wi, NULL);
+ walk_tree (&TREE_OPERAND (t, 3), convert_nonlocal_reference_op,
+ wi, NULL);
}
else if (TREE_CODE (t) == BIT_FIELD_REF)
{
- walk_tree (&TREE_OPERAND (t, 1), convert_nonlocal_reference, wi,
- NULL);
- walk_tree (&TREE_OPERAND (t, 2), convert_nonlocal_reference, wi,
- NULL);
+ walk_tree (&TREE_OPERAND (t, 1), convert_nonlocal_reference_op,
+ wi, NULL);
+ walk_tree (&TREE_OPERAND (t, 2), convert_nonlocal_reference_op,
+ wi, NULL);
}
}
wi->val_only = false;
- walk_tree (tp, convert_nonlocal_reference, wi, NULL);
+ walk_tree (tp, convert_nonlocal_reference_op, wi, NULL);
break;
case VIEW_CONVERT_EXPR:
@@ -1104,52 +983,6 @@ convert_nonlocal_reference (tree *tp, int *walk_subtrees, void *data)
*walk_subtrees = 1;
break;
- case OMP_PARALLEL:
- case OMP_TASK:
- save_suppress = info->suppress_expansion;
- if (convert_nonlocal_omp_clauses (&OMP_TASKREG_CLAUSES (t), wi))
- {
- tree c, decl;
- decl = get_chain_decl (info);
- c = build_omp_clause (OMP_CLAUSE_FIRSTPRIVATE);
- OMP_CLAUSE_DECL (c) = decl;
- OMP_CLAUSE_CHAIN (c) = OMP_TASKREG_CLAUSES (t);
- OMP_TASKREG_CLAUSES (t) = c;
- }
-
- save_local_var_chain = info->new_local_var_chain;
- info->new_local_var_chain = NULL;
-
- walk_body (convert_nonlocal_reference, info, &OMP_TASKREG_BODY (t));
-
- if (info->new_local_var_chain)
- declare_vars (info->new_local_var_chain, OMP_TASKREG_BODY (t), false);
- info->new_local_var_chain = save_local_var_chain;
- info->suppress_expansion = save_suppress;
- break;
-
- case OMP_FOR:
- save_suppress = info->suppress_expansion;
- convert_nonlocal_omp_clauses (&OMP_FOR_CLAUSES (t), wi);
- walk_omp_for (convert_nonlocal_reference, info, t);
- walk_body (convert_nonlocal_reference, info, &OMP_FOR_BODY (t));
- info->suppress_expansion = save_suppress;
- break;
-
- case OMP_SECTIONS:
- case OMP_SINGLE:
- save_suppress = info->suppress_expansion;
- convert_nonlocal_omp_clauses (&OMP_CLAUSES (t), wi);
- walk_body (convert_nonlocal_reference, info, &OMP_BODY (t));
- info->suppress_expansion = save_suppress;
- break;
-
- case OMP_SECTION:
- case OMP_MASTER:
- case OMP_ORDERED:
- walk_body (convert_nonlocal_reference, info, &OMP_BODY (t));
- break;
-
default:
if (!IS_TYPE_OR_DECL_P (t))
{
@@ -1163,6 +996,12 @@ convert_nonlocal_reference (tree *tp, int *walk_subtrees, void *data)
return NULL_TREE;
}
+static tree convert_nonlocal_reference_stmt (gimple_stmt_iterator *, bool *,
+ struct walk_stmt_info *);
+
+/* Helper for convert_nonlocal_references, rewrite all references to VAR
+ and PARM_DECLs that belong to outer functions. */
+
static bool
convert_nonlocal_omp_clauses (tree *pclauses, struct walk_stmt_info *wi)
{
@@ -1185,7 +1024,7 @@ convert_nonlocal_omp_clauses (tree *pclauses, struct walk_stmt_info *wi)
goto do_decl_clause;
case OMP_CLAUSE_LASTPRIVATE:
- if (OMP_CLAUSE_LASTPRIVATE_STMT (clause))
+ if (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (clause))
need_stmts = true;
goto do_decl_clause;
@@ -1214,8 +1053,8 @@ convert_nonlocal_omp_clauses (tree *pclauses, struct walk_stmt_info *wi)
case OMP_CLAUSE_NUM_THREADS:
wi->val_only = true;
wi->is_lhs = false;
- convert_nonlocal_reference (&OMP_CLAUSE_OPERAND (clause, 0), &dummy,
- wi);
+ convert_nonlocal_reference_op (&OMP_CLAUSE_OPERAND (clause, 0),
+ &dummy, wi);
break;
case OMP_CLAUSE_NOWAIT:
@@ -1244,18 +1083,21 @@ convert_nonlocal_omp_clauses (tree *pclauses, struct walk_stmt_info *wi)
= DECL_CONTEXT (OMP_CLAUSE_REDUCTION_PLACEHOLDER (clause));
DECL_CONTEXT (OMP_CLAUSE_REDUCTION_PLACEHOLDER (clause))
= info->context;
- walk_body (convert_nonlocal_reference, info,
- &OMP_CLAUSE_REDUCTION_INIT (clause));
- walk_body (convert_nonlocal_reference, info,
- &OMP_CLAUSE_REDUCTION_MERGE (clause));
+ walk_body (convert_nonlocal_reference_stmt,
+ convert_nonlocal_reference_op, info,
+ OMP_CLAUSE_REDUCTION_GIMPLE_INIT (clause));
+ walk_body (convert_nonlocal_reference_stmt,
+ convert_nonlocal_reference_op, info,
+ OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (clause));
DECL_CONTEXT (OMP_CLAUSE_REDUCTION_PLACEHOLDER (clause))
= old_context;
}
break;
case OMP_CLAUSE_LASTPRIVATE:
- walk_body (convert_nonlocal_reference, info,
- &OMP_CLAUSE_LASTPRIVATE_STMT (clause));
+ walk_body (convert_nonlocal_reference_stmt,
+ convert_nonlocal_reference_op, info,
+ OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (clause));
break;
default:
@@ -1265,6 +1107,110 @@ convert_nonlocal_omp_clauses (tree *pclauses, struct walk_stmt_info *wi)
return need_chain;
}
+
+/* Callback for walk_gimple_stmt. Rewrite all references to VAR and
+ PARM_DECLs that belong to outer functions. This handles statements
+ that are not handled via the standard recursion done in
+ walk_gimple_stmt. STMT is the statement to examine, DATA is as in
+ convert_nonlocal_reference_op. Set *HANDLED_OPS_P to true if all the
+ operands of STMT have been handled by this function. */
+
+static tree
+convert_nonlocal_reference_stmt (gimple_stmt_iterator *gsi, bool *handled_ops_p,
+ struct walk_stmt_info *wi)
+{
+ struct nesting_info *info = (struct nesting_info *) wi->info;
+ tree save_local_var_chain;
+ bitmap save_suppress;
+ gimple stmt = gsi_stmt (*gsi);
+
+ switch (gimple_code (stmt))
+ {
+ case GIMPLE_GOTO:
+ /* Don't walk non-local gotos for now. */
+ if (TREE_CODE (gimple_goto_dest (stmt)) != LABEL_DECL)
+ {
+ wi->val_only = true;
+ wi->is_lhs = false;
+ *handled_ops_p = true;
+ return NULL_TREE;
+ }
+ break;
+
+ case GIMPLE_OMP_PARALLEL:
+ case GIMPLE_OMP_TASK:
+ save_suppress = info->suppress_expansion;
+ if (convert_nonlocal_omp_clauses (gimple_omp_taskreg_clauses_ptr (stmt),
+ wi))
+ {
+ tree c, decl;
+ decl = get_chain_decl (info);
+ c = build_omp_clause (OMP_CLAUSE_FIRSTPRIVATE);
+ OMP_CLAUSE_DECL (c) = decl;
+ OMP_CLAUSE_CHAIN (c) = gimple_omp_taskreg_clauses (stmt);
+ gimple_omp_taskreg_set_clauses (stmt, c);
+ }
+
+ save_local_var_chain = info->new_local_var_chain;
+ info->new_local_var_chain = NULL;
+
+ walk_body (convert_nonlocal_reference_stmt, convert_nonlocal_reference_op,
+ info, gimple_omp_body (stmt));
+
+ if (info->new_local_var_chain)
+ declare_vars (info->new_local_var_chain,
+ gimple_seq_first_stmt (gimple_omp_body (stmt)),
+ false);
+ info->new_local_var_chain = save_local_var_chain;
+ info->suppress_expansion = save_suppress;
+ break;
+
+ case GIMPLE_OMP_FOR:
+ save_suppress = info->suppress_expansion;
+ convert_nonlocal_omp_clauses (gimple_omp_for_clauses_ptr (stmt), wi);
+ walk_gimple_omp_for (stmt, convert_nonlocal_reference_stmt,
+ convert_nonlocal_reference_op, info);
+ walk_body (convert_nonlocal_reference_stmt,
+ convert_nonlocal_reference_op, info, gimple_omp_body (stmt));
+ info->suppress_expansion = save_suppress;
+ break;
+
+ case GIMPLE_OMP_SECTIONS:
+ save_suppress = info->suppress_expansion;
+ convert_nonlocal_omp_clauses (gimple_omp_sections_clauses_ptr (stmt), wi);
+ walk_body (convert_nonlocal_reference_stmt, convert_nonlocal_reference_op,
+ info, gimple_omp_body (stmt));
+ info->suppress_expansion = save_suppress;
+ break;
+
+ case GIMPLE_OMP_SINGLE:
+ save_suppress = info->suppress_expansion;
+ convert_nonlocal_omp_clauses (gimple_omp_single_clauses_ptr (stmt), wi);
+ walk_body (convert_nonlocal_reference_stmt, convert_nonlocal_reference_op,
+ info, gimple_omp_body (stmt));
+ info->suppress_expansion = save_suppress;
+ break;
+
+ case GIMPLE_OMP_SECTION:
+ case GIMPLE_OMP_MASTER:
+ case GIMPLE_OMP_ORDERED:
+ walk_body (convert_nonlocal_reference_stmt, convert_nonlocal_reference_op,
+ info, gimple_omp_body (stmt));
+ break;
+
+ default:
+ /* For every other statement that we are not interested in
+ handling here, let the walker traverse the operands. */
+ *handled_ops_p = false;
+ return NULL_TREE;
+ }
+
+ /* We have handled all of STMT operands, no need to traverse the operands. */
+ *handled_ops_p = true;
+ return NULL_TREE;
+}
+
+
/* A subroutine of convert_local_reference. Create a local variable
in the parent function with DECL_VALUE_EXPR set to reference the
field in FRAME. This is used both for debug info and in OpenMP
@@ -1309,21 +1255,20 @@ get_local_debug_decl (struct nesting_info *info, tree decl, tree field)
return new_decl;
}
-/* Called via walk_function+walk_tree, rewrite all references to VAR
+
+/* Called via walk_function+walk_gimple_stmt, rewrite all references to VAR
and PARM_DECLs that were referenced by inner nested functions.
The rewrite will be a structure reference to the local frame variable. */
static bool convert_local_omp_clauses (tree *, struct walk_stmt_info *);
static tree
-convert_local_reference (tree *tp, int *walk_subtrees, void *data)
+convert_local_reference_op (tree *tp, int *walk_subtrees, void *data)
{
struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
struct nesting_info *const info = (struct nesting_info *) wi->info;
tree t = *tp, field, x;
bool save_val_only;
- tree save_local_var_chain;
- bitmap save_suppress;
*walk_subtrees = 0;
switch (TREE_CODE (t))
@@ -1351,14 +1296,14 @@ convert_local_reference (tree *tp, int *walk_subtrees, void *data)
x = get_local_debug_decl (info, t, field);
if (!bitmap_bit_p (info->suppress_expansion, DECL_UID (t)))
- x = get_frame_field (info, info->context, field, &wi->tsi);
+ x = get_frame_field (info, info->context, field, &wi->gsi);
if (wi->val_only)
{
if (wi->is_lhs)
- x = save_tmp_var (info, x, &wi->tsi);
+ x = save_tmp_var (info, x, &wi->gsi);
else
- x = init_tmp_var (info, x, &wi->tsi);
+ x = init_tmp_var (info, x, &wi->gsi);
}
*tp = x;
@@ -1370,7 +1315,7 @@ convert_local_reference (tree *tp, int *walk_subtrees, void *data)
wi->val_only = false;
wi->is_lhs = false;
wi->changed = false;
- walk_tree (&TREE_OPERAND (t, 0), convert_local_reference, wi, NULL);
+ walk_tree (&TREE_OPERAND (t, 0), convert_local_reference_op, wi, NULL);
wi->val_only = save_val_only;
/* If we converted anything ... */
@@ -1389,7 +1334,8 @@ convert_local_reference (tree *tp, int *walk_subtrees, void *data)
/* If we are in a context where we only accept values, then
compute the address into a temporary. */
if (save_val_only)
- *tp = tsi_gimplify_val ((struct nesting_info *)wi->info, t, &wi->tsi);
+ *tp = gsi_gimplify_val ((struct nesting_info *) wi->info,
+ t, &wi->gsi);
}
break;
@@ -1408,28 +1354,28 @@ convert_local_reference (tree *tp, int *walk_subtrees, void *data)
for (; handled_component_p (t); tp = &TREE_OPERAND (t, 0), t = *tp)
{
if (TREE_CODE (t) == COMPONENT_REF)
- walk_tree (&TREE_OPERAND (t, 2), convert_local_reference, wi,
+ walk_tree (&TREE_OPERAND (t, 2), convert_local_reference_op, wi,
NULL);
else if (TREE_CODE (t) == ARRAY_REF
|| TREE_CODE (t) == ARRAY_RANGE_REF)
{
- walk_tree (&TREE_OPERAND (t, 1), convert_local_reference, wi,
+ walk_tree (&TREE_OPERAND (t, 1), convert_local_reference_op, wi,
NULL);
- walk_tree (&TREE_OPERAND (t, 2), convert_local_reference, wi,
+ walk_tree (&TREE_OPERAND (t, 2), convert_local_reference_op, wi,
NULL);
- walk_tree (&TREE_OPERAND (t, 3), convert_local_reference, wi,
+ walk_tree (&TREE_OPERAND (t, 3), convert_local_reference_op, wi,
NULL);
}
else if (TREE_CODE (t) == BIT_FIELD_REF)
{
- walk_tree (&TREE_OPERAND (t, 1), convert_local_reference, wi,
+ walk_tree (&TREE_OPERAND (t, 1), convert_local_reference_op, wi,
NULL);
- walk_tree (&TREE_OPERAND (t, 2), convert_local_reference, wi,
+ walk_tree (&TREE_OPERAND (t, 2), convert_local_reference_op, wi,
NULL);
}
}
wi->val_only = false;
- walk_tree (tp, convert_local_reference, wi, NULL);
+ walk_tree (tp, convert_local_reference_op, wi, NULL);
wi->val_only = save_val_only;
break;
@@ -1440,52 +1386,6 @@ convert_local_reference (tree *tp, int *walk_subtrees, void *data)
*walk_subtrees = 1;
break;
- case OMP_PARALLEL:
- case OMP_TASK:
- save_suppress = info->suppress_expansion;
- if (convert_local_omp_clauses (&OMP_TASKREG_CLAUSES (t), wi))
- {
- tree c;
- (void) get_frame_type (info);
- c = build_omp_clause (OMP_CLAUSE_SHARED);
- OMP_CLAUSE_DECL (c) = info->frame_decl;
- OMP_CLAUSE_CHAIN (c) = OMP_TASKREG_CLAUSES (t);
- OMP_TASKREG_CLAUSES (t) = c;
- }
-
- save_local_var_chain = info->new_local_var_chain;
- info->new_local_var_chain = NULL;
-
- walk_body (convert_local_reference, info, &OMP_TASKREG_BODY (t));
-
- if (info->new_local_var_chain)
- declare_vars (info->new_local_var_chain, OMP_TASKREG_BODY (t), false);
- info->new_local_var_chain = save_local_var_chain;
- info->suppress_expansion = save_suppress;
- break;
-
- case OMP_FOR:
- save_suppress = info->suppress_expansion;
- convert_local_omp_clauses (&OMP_FOR_CLAUSES (t), wi);
- walk_omp_for (convert_local_reference, info, t);
- walk_body (convert_local_reference, info, &OMP_FOR_BODY (t));
- info->suppress_expansion = save_suppress;
- break;
-
- case OMP_SECTIONS:
- case OMP_SINGLE:
- save_suppress = info->suppress_expansion;
- convert_local_omp_clauses (&OMP_CLAUSES (t), wi);
- walk_body (convert_local_reference, info, &OMP_BODY (t));
- info->suppress_expansion = save_suppress;
- break;
-
- case OMP_SECTION:
- case OMP_MASTER:
- case OMP_ORDERED:
- walk_body (convert_local_reference, info, &OMP_BODY (t));
- break;
-
default:
if (!IS_TYPE_OR_DECL_P (t))
{
@@ -1499,6 +1399,12 @@ convert_local_reference (tree *tp, int *walk_subtrees, void *data)
return NULL_TREE;
}
+static tree convert_local_reference_stmt (gimple_stmt_iterator *, bool *,
+ struct walk_stmt_info *);
+
+/* Helper for convert_local_reference. Convert all the references in
+ the chain of clauses at *PCLAUSES. WI is as in convert_local_reference. */
+
static bool
convert_local_omp_clauses (tree *pclauses, struct walk_stmt_info *wi)
{
@@ -1521,7 +1427,7 @@ convert_local_omp_clauses (tree *pclauses, struct walk_stmt_info *wi)
goto do_decl_clause;
case OMP_CLAUSE_LASTPRIVATE:
- if (OMP_CLAUSE_LASTPRIVATE_STMT (clause))
+ if (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (clause))
need_stmts = true;
goto do_decl_clause;
@@ -1556,7 +1462,8 @@ convert_local_omp_clauses (tree *pclauses, struct walk_stmt_info *wi)
case OMP_CLAUSE_NUM_THREADS:
wi->val_only = true;
wi->is_lhs = false;
- convert_local_reference (&OMP_CLAUSE_OPERAND (clause, 0), &dummy, wi);
+ convert_local_reference_op (&OMP_CLAUSE_OPERAND (clause, 0), &dummy,
+ wi);
break;
case OMP_CLAUSE_NOWAIT:
@@ -1585,18 +1492,21 @@ convert_local_omp_clauses (tree *pclauses, struct walk_stmt_info *wi)
= DECL_CONTEXT (OMP_CLAUSE_REDUCTION_PLACEHOLDER (clause));
DECL_CONTEXT (OMP_CLAUSE_REDUCTION_PLACEHOLDER (clause))
= info->context;
- walk_body (convert_local_reference, info,
- &OMP_CLAUSE_REDUCTION_INIT (clause));
- walk_body (convert_local_reference, info,
- &OMP_CLAUSE_REDUCTION_MERGE (clause));
+ walk_body (convert_local_reference_stmt,
+ convert_local_reference_op, info,
+ OMP_CLAUSE_REDUCTION_GIMPLE_INIT (clause));
+ walk_body (convert_local_reference_stmt,
+ convert_local_reference_op, info,
+ OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (clause));
DECL_CONTEXT (OMP_CLAUSE_REDUCTION_PLACEHOLDER (clause))
= old_context;
}
break;
case OMP_CLAUSE_LASTPRIVATE:
- walk_body (convert_local_reference, info,
- &OMP_CLAUSE_LASTPRIVATE_STMT (clause));
+ walk_body (convert_local_reference_stmt,
+ convert_local_reference_op, info,
+ OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (clause));
break;
default:
@@ -1606,27 +1516,128 @@ convert_local_omp_clauses (tree *pclauses, struct walk_stmt_info *wi)
return need_frame;
}
-/* Called via walk_function+walk_tree, rewrite all GOTO_EXPRs that
- reference labels from outer functions. The rewrite will be a
+
+/* Called via walk_function+walk_gimple_stmt, rewrite all references to VAR
+ and PARM_DECLs that were referenced by inner nested functions.
+ The rewrite will be a structure reference to the local frame variable. */
+
+static tree
+convert_local_reference_stmt (gimple_stmt_iterator *gsi, bool *handled_ops_p,
+ struct walk_stmt_info *wi)
+{
+ struct nesting_info *info = (struct nesting_info *) wi->info;
+ tree save_local_var_chain;
+ bitmap save_suppress;
+ gimple stmt = gsi_stmt (*gsi);
+
+ switch (gimple_code (stmt))
+ {
+ case GIMPLE_OMP_PARALLEL:
+ case GIMPLE_OMP_TASK:
+ save_suppress = info->suppress_expansion;
+ if (convert_local_omp_clauses (gimple_omp_taskreg_clauses_ptr (stmt),
+ wi))
+ {
+ tree c;
+ (void) get_frame_type (info);
+ c = build_omp_clause (OMP_CLAUSE_SHARED);
+ OMP_CLAUSE_DECL (c) = info->frame_decl;
+ OMP_CLAUSE_CHAIN (c) = gimple_omp_taskreg_clauses (stmt);
+ gimple_omp_taskreg_set_clauses (stmt, c);
+ }
+
+ save_local_var_chain = info->new_local_var_chain;
+ info->new_local_var_chain = NULL;
+
+ walk_body (convert_local_reference_stmt, convert_local_reference_op, info,
+ gimple_omp_body (stmt));
+
+ if (info->new_local_var_chain)
+ declare_vars (info->new_local_var_chain,
+ gimple_seq_first_stmt (gimple_omp_body (stmt)), false);
+ info->new_local_var_chain = save_local_var_chain;
+ info->suppress_expansion = save_suppress;
+ break;
+
+ case GIMPLE_OMP_FOR:
+ save_suppress = info->suppress_expansion;
+ convert_local_omp_clauses (gimple_omp_for_clauses_ptr (stmt), wi);
+ walk_gimple_omp_for (stmt, convert_local_reference_stmt,
+ convert_local_reference_op, info);
+ walk_body (convert_local_reference_stmt, convert_local_reference_op,
+ info, gimple_omp_body (stmt));
+ info->suppress_expansion = save_suppress;
+ break;
+
+ case GIMPLE_OMP_SECTIONS:
+ save_suppress = info->suppress_expansion;
+ convert_local_omp_clauses (gimple_omp_sections_clauses_ptr (stmt), wi);
+ walk_body (convert_local_reference_stmt, convert_local_reference_op,
+ info, gimple_omp_body (stmt));
+ info->suppress_expansion = save_suppress;
+ break;
+
+ case GIMPLE_OMP_SINGLE:
+ save_suppress = info->suppress_expansion;
+ convert_local_omp_clauses (gimple_omp_single_clauses_ptr (stmt), wi);
+ walk_body (convert_local_reference_stmt, convert_local_reference_op,
+ info, gimple_omp_body (stmt));
+ info->suppress_expansion = save_suppress;
+ break;
+
+ case GIMPLE_OMP_SECTION:
+ case GIMPLE_OMP_MASTER:
+ case GIMPLE_OMP_ORDERED:
+ walk_body (convert_local_reference_stmt, convert_local_reference_op,
+ info, gimple_omp_body (stmt));
+ break;
+
+ default:
+ /* For every other statement that we are not interested in
+ handling here, let the walker traverse the operands. */
+ *handled_ops_p = false;
+ return NULL_TREE;
+ }
+
+ /* Indicate that we have handled all the operands ourselves. */
+ *handled_ops_p = true;
+ return NULL_TREE;
+}
+
+
+/* Called via walk_function+walk_gimple_stmt, rewrite all GIMPLE_GOTOs
+ that reference labels from outer functions. The rewrite will be a
call to __builtin_nonlocal_goto. */
static tree
-convert_nl_goto_reference (tree *tp, int *walk_subtrees, void *data)
+convert_nl_goto_reference (gimple_stmt_iterator *gsi, bool *handled_ops_p,
+ struct walk_stmt_info *wi)
{
- struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
struct nesting_info *const info = (struct nesting_info *) wi->info, *i;
- tree t = *tp, label, new_label, target_context, x, field;
+ tree label, new_label, target_context, x, field;
void **slot;
+ gimple call;
+ gimple stmt = gsi_stmt (*gsi);
- *walk_subtrees = 0;
- if (TREE_CODE (t) != GOTO_EXPR)
- return NULL_TREE;
- label = GOTO_DESTINATION (t);
+ if (gimple_code (stmt) != GIMPLE_GOTO)
+ {
+ *handled_ops_p = false;
+ return NULL_TREE;
+ }
+
+ label = gimple_goto_dest (stmt);
if (TREE_CODE (label) != LABEL_DECL)
- return NULL_TREE;
+ {
+ *handled_ops_p = false;
+ return NULL_TREE;
+ }
+
target_context = decl_function_context (label);
if (target_context == info->context)
- return NULL_TREE;
+ {
+ *handled_ops_p = false;
+ return NULL_TREE;
+ }
for (i = info->outer; target_context != i->context; i = i->outer)
continue;
@@ -1650,69 +1661,80 @@ convert_nl_goto_reference (tree *tp, int *walk_subtrees, void *data)
/* Build: __builtin_nl_goto(new_label, &chain->nl_goto_field). */
field = get_nl_goto_field (i);
- x = get_frame_field (info, target_context, field, &wi->tsi);
+ x = get_frame_field (info, target_context, field, &wi->gsi);
x = build_addr (x, target_context);
- x = tsi_gimplify_val (info, x, &wi->tsi);
- x = build_call_expr (implicit_built_in_decls[BUILT_IN_NONLOCAL_GOTO], 2,
- build_addr (new_label, target_context), x);
-
- SET_EXPR_LOCUS (x, EXPR_LOCUS (tsi_stmt (wi->tsi)));
- *tsi_stmt_ptr (wi->tsi) = x;
+ x = gsi_gimplify_val (info, x, &wi->gsi);
+ call = gimple_build_call (implicit_built_in_decls[BUILT_IN_NONLOCAL_GOTO], 2,
+ build_addr (new_label, target_context), x);
+ gsi_replace (&wi->gsi, call, false);
+ /* We have handled all of STMT's operands, no need to keep going. */
+ *handled_ops_p = true;
return NULL_TREE;
}
-/* Called via walk_function+walk_tree, rewrite all LABEL_EXPRs that
+
+/* Called via walk_function+walk_tree, rewrite all GIMPLE_LABELs whose labels
are referenced via nonlocal goto from a nested function. The rewrite
will involve installing a newly generated DECL_NONLOCAL label, and
- (potentially) a branch around the rtl gunk that is assumed to be
+ (potentially) a branch around the rtl gunk that is assumed to be
attached to such a label. */
static tree
-convert_nl_goto_receiver (tree *tp, int *walk_subtrees, void *data)
+convert_nl_goto_receiver (gimple_stmt_iterator *gsi, bool *handled_ops_p,
+ struct walk_stmt_info *wi)
{
- struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
struct nesting_info *const info = (struct nesting_info *) wi->info;
- tree t = *tp, label, new_label, x;
- tree_stmt_iterator tmp_tsi;
+ tree label, new_label;
+ gimple_stmt_iterator tmp_gsi;
void **slot;
+ gimple stmt = gsi_stmt (*gsi);
- *walk_subtrees = 0;
- if (TREE_CODE (t) != LABEL_EXPR)
- return NULL_TREE;
- label = LABEL_EXPR_LABEL (t);
+ if (gimple_code (stmt) != GIMPLE_LABEL)
+ {
+ *handled_ops_p = false;
+ return NULL_TREE;
+ }
+
+ label = gimple_label_label (stmt);
slot = pointer_map_contains (info->var_map, label);
if (!slot)
- return NULL_TREE;
+ {
+ *handled_ops_p = false;
+ return NULL_TREE;
+ }
/* If there's any possibility that the previous statement falls through,
then we must branch around the new non-local label. */
- tmp_tsi = wi->tsi;
- tsi_prev (&tmp_tsi);
- if (tsi_end_p (tmp_tsi) || block_may_fallthru (tsi_stmt (tmp_tsi)))
+ tmp_gsi = wi->gsi;
+ gsi_prev (&tmp_gsi);
+ if (gsi_end_p (tmp_gsi) || gimple_stmt_may_fallthru (gsi_stmt (tmp_gsi)))
{
- x = build1 (GOTO_EXPR, void_type_node, label);
- tsi_link_before (&wi->tsi, x, TSI_SAME_STMT);
+ gimple stmt = gimple_build_goto (label);
+ gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
}
new_label = (tree) *slot;
- x = build1 (LABEL_EXPR, void_type_node, new_label);
- tsi_link_before (&wi->tsi, x, TSI_SAME_STMT);
+ stmt = gimple_build_label (new_label);
+ gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
+ *handled_ops_p = true;
return NULL_TREE;
}
-/* Called via walk_function+walk_tree, rewrite all references to addresses
+
+/* Called via walk_function+walk_stmt, rewrite all references to addresses
of nested functions that require the use of trampolines. The rewrite
will involve a reference a trampoline generated for the occasion. */
static tree
-convert_tramp_reference (tree *tp, int *walk_subtrees, void *data)
+convert_tramp_reference_op (tree *tp, int *walk_subtrees, void *data)
{
struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
struct nesting_info *const info = (struct nesting_info *) wi->info, *i;
- tree t = *tp, decl, target_context, x;
+ tree t = *tp, decl, target_context, x, builtin;
+ gimple call;
*walk_subtrees = 0;
switch (TREE_CODE (t))
@@ -1749,85 +1771,103 @@ convert_tramp_reference (tree *tp, int *walk_subtrees, void *data)
x = lookup_tramp_for_decl (i, decl, INSERT);
/* Compute the address of the field holding the trampoline. */
- x = get_frame_field (info, target_context, x, &wi->tsi);
+ x = get_frame_field (info, target_context, x, &wi->gsi);
x = build_addr (x, target_context);
- x = tsi_gimplify_val (info, x, &wi->tsi);
+ x = gsi_gimplify_val (info, x, &wi->gsi);
/* Do machine-specific ugliness. Normally this will involve
computing extra alignment, but it can really be anything. */
- x = build_call_expr (implicit_built_in_decls[BUILT_IN_ADJUST_TRAMPOLINE],
- 1, x);
- x = init_tmp_var (info, x, &wi->tsi);
+ builtin = implicit_built_in_decls[BUILT_IN_ADJUST_TRAMPOLINE];
+ call = gimple_build_call (builtin, 1, x);
+ x = init_tmp_var_with_call (info, &wi->gsi, call);
/* Cast back to the proper function type. */
x = build1 (NOP_EXPR, TREE_TYPE (t), x);
- x = init_tmp_var (info, x, &wi->tsi);
+ x = init_tmp_var (info, x, &wi->gsi);
*tp = x;
break;
- case CALL_EXPR:
- /* Only walk call arguments, lest we generate trampolines for
- direct calls. */
+ default:
+ if (!IS_TYPE_OR_DECL_P (t))
+ *walk_subtrees = 1;
+ break;
+ }
+
+ return NULL_TREE;
+}
+
+
+/* Called via walk_function+walk_gimple_stmt, rewrite all references
+ to addresses of nested functions that require the use of
+ trampolines. The rewrite will involve a reference a trampoline
+ generated for the occasion. */
+
+static tree
+convert_tramp_reference_stmt (gimple_stmt_iterator *gsi, bool *handled_ops_p,
+ struct walk_stmt_info *wi)
+{
+ gimple stmt = gsi_stmt (*gsi);
+
+ switch (gimple_code (stmt))
+ {
+ case GIMPLE_CALL:
{
- int nargs = call_expr_nargs (t);
- int i;
+ /* Only walk call arguments, lest we generate trampolines for
+ direct calls. */
+ unsigned long i, nargs = gimple_call_num_args (stmt);
for (i = 0; i < nargs; i++)
- walk_tree (&CALL_EXPR_ARG (t, i), convert_tramp_reference, wi, NULL);
+ walk_tree (gimple_call_arg_ptr (stmt, i), convert_tramp_reference_op,
+ wi, NULL);
+
+ *handled_ops_p = true;
+ return NULL_TREE;
}
- break;
default:
- if (!IS_TYPE_OR_DECL_P (t))
- *walk_subtrees = 1;
break;
}
+ *handled_ops_p = false;
return NULL_TREE;
}
-/* Called via walk_function+walk_tree, rewrite all CALL_EXPRs that
- reference nested functions to make sure that the static chain is
- set up properly for the call. */
+
+
+/* Called via walk_function+walk_gimple_stmt, rewrite all GIMPLE_CALLs
+ that reference nested functions to make sure that the static chain
+ is set up properly for the call. */
static tree
-convert_call_expr (tree *tp, int *walk_subtrees, void *data)
+convert_gimple_call (gimple_stmt_iterator *gsi, bool *handled_ops_p,
+ struct walk_stmt_info *wi)
{
- struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
struct nesting_info *const info = (struct nesting_info *) wi->info;
- tree t = *tp, decl, target_context;
+ tree decl, target_context;
char save_static_chain_added;
int i;
+ gimple stmt = gsi_stmt (*gsi);
- *walk_subtrees = 0;
- switch (TREE_CODE (t))
+ switch (gimple_code (stmt))
{
- case CALL_EXPR:
- decl = get_callee_fndecl (t);
- if (!decl)
+ case GIMPLE_CALL:
+ decl = gimple_call_fn (stmt);
+ if (TREE_CODE (decl) != FUNCTION_DECL)
break;
target_context = decl_function_context (decl);
if (target_context && !DECL_NO_STATIC_CHAIN (decl))
{
- CALL_EXPR_STATIC_CHAIN (t)
- = get_static_chain (info, target_context, &wi->tsi);
- info->static_chain_added
- |= (1 << (info->context != target_context));
+ gimple_call_set_chain (stmt, get_static_chain (info, target_context,
+ &wi->gsi));
+ info->static_chain_added |= (1 << (info->context != target_context));
}
break;
- case RETURN_EXPR:
- case GIMPLE_MODIFY_STMT:
- case WITH_SIZE_EXPR:
- /* Only return modify and with_size_expr may contain calls. */
- *walk_subtrees = 1;
- break;
-
- case OMP_PARALLEL:
- case OMP_TASK:
+ case GIMPLE_OMP_PARALLEL:
+ case GIMPLE_OMP_TASK:
save_static_chain_added = info->static_chain_added;
info->static_chain_added = 0;
- walk_body (convert_call_expr, info, &OMP_TASKREG_BODY (t));
+ walk_body (convert_gimple_call, NULL, info, gimple_omp_body (stmt));
for (i = 0; i < 2; i++)
{
tree c, decl;
@@ -1835,7 +1875,9 @@ convert_call_expr (tree *tp, int *walk_subtrees, void *data)
continue;
decl = i ? get_chain_decl (info) : info->frame_decl;
/* Don't add CHAIN.* or FRAME.* twice. */
- for (c = OMP_TASKREG_CLAUSES (t); c; c = OMP_CLAUSE_CHAIN (c))
+ for (c = gimple_omp_taskreg_clauses (stmt);
+ c;
+ c = OMP_CLAUSE_CHAIN (c))
if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE
|| OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED)
&& OMP_CLAUSE_DECL (c) == decl)
@@ -1845,32 +1887,37 @@ convert_call_expr (tree *tp, int *walk_subtrees, void *data)
c = build_omp_clause (i ? OMP_CLAUSE_FIRSTPRIVATE
: OMP_CLAUSE_SHARED);
OMP_CLAUSE_DECL (c) = decl;
- OMP_CLAUSE_CHAIN (c) = OMP_TASKREG_CLAUSES (t);
- OMP_TASKREG_CLAUSES (t) = c;
+ OMP_CLAUSE_CHAIN (c) = gimple_omp_taskreg_clauses (stmt);
+ gimple_omp_taskreg_set_clauses (stmt, c);
}
}
info->static_chain_added |= save_static_chain_added;
break;
- case OMP_FOR:
- walk_body (convert_call_expr, info, &OMP_FOR_PRE_BODY (t));
+ case GIMPLE_OMP_FOR:
+ walk_body (convert_gimple_call, NULL, info,
+ gimple_omp_for_pre_body (stmt));
/* FALLTHRU */
- case OMP_SECTIONS:
- case OMP_SECTION:
- case OMP_SINGLE:
- case OMP_MASTER:
- case OMP_ORDERED:
- case OMP_CRITICAL:
- walk_body (convert_call_expr, info, &OMP_BODY (t));
+ case GIMPLE_OMP_SECTIONS:
+ case GIMPLE_OMP_SECTION:
+ case GIMPLE_OMP_SINGLE:
+ case GIMPLE_OMP_MASTER:
+ case GIMPLE_OMP_ORDERED:
+ case GIMPLE_OMP_CRITICAL:
+ walk_body (convert_gimple_call, NULL, info, gimple_omp_body (stmt));
break;
default:
- break;
+ /* Keep looking for other operands. */
+ *handled_ops_p = false;
+ return NULL_TREE;
}
+ *handled_ops_p = true;
return NULL_TREE;
}
+
/* Walk the nesting tree starting with ROOT, depth first. Convert all
trampolines and call expressions. On the way back up, determine if
a nested function actually uses its static chain; if not, remember that. */
@@ -1883,8 +1930,9 @@ convert_all_function_calls (struct nesting_info *root)
if (root->inner)
convert_all_function_calls (root->inner);
- walk_function (convert_tramp_reference, root);
- walk_function (convert_call_expr, root);
+ walk_function (convert_tramp_reference_stmt, convert_tramp_reference_op,
+ root);
+ walk_function (convert_gimple_call, NULL, root);
/* If the function does not use a static chain, then remember that. */
if (root->outer && !root->chain_decl && !root->chain_field)
@@ -1905,10 +1953,13 @@ convert_all_function_calls (struct nesting_info *root)
static void
finalize_nesting_tree_1 (struct nesting_info *root)
{
- tree stmt_list = NULL;
+ gimple_seq stmt_list;
+ gimple stmt;
tree context = root->context;
struct function *sf;
+ stmt_list = NULL;
+
/* If we created a non-local frame type or decl, we need to lay them
out at this time. */
if (root->frame_type)
@@ -1943,8 +1994,8 @@ finalize_nesting_tree_1 (struct nesting_info *root)
y = build3 (COMPONENT_REF, TREE_TYPE (field),
root->frame_decl, field, NULL_TREE);
- x = build_gimple_modify_stmt (y, x);
- append_to_statement_list (x, &stmt_list);
+ stmt = gimple_build_assign (y, x);
+ gimple_seq_add_stmt (&stmt_list, stmt);
}
}
@@ -1954,8 +2005,8 @@ finalize_nesting_tree_1 (struct nesting_info *root)
{
tree x = build3 (COMPONENT_REF, TREE_TYPE (root->chain_field),
root->frame_decl, root->chain_field, NULL_TREE);
- x = build_gimple_modify_stmt (x, get_chain_decl (root));
- append_to_statement_list (x, &stmt_list);
+ stmt = gimple_build_assign (x, get_chain_decl (root));
+ gimple_seq_add_stmt (&stmt_list, stmt);
}
/* If trampolines were created, then we need to initialize them. */
@@ -1982,19 +2033,19 @@ finalize_nesting_tree_1 (struct nesting_info *root)
arg1 = build_addr (x, context);
x = implicit_built_in_decls[BUILT_IN_INIT_TRAMPOLINE];
- x = build_call_expr (x, 3, arg1, arg2, arg3);
- append_to_statement_list (x, &stmt_list);
+ stmt = gimple_build_call (x, 3, arg1, arg2, arg3);
+ gimple_seq_add_stmt (&stmt_list, stmt);
}
}
/* If we created initialization statements, insert them. */
if (stmt_list)
{
- annotate_all_with_locus (&stmt_list,
- DECL_SOURCE_LOCATION (context));
- append_to_statement_list (BIND_EXPR_BODY (DECL_SAVED_TREE (context)),
- &stmt_list);
- BIND_EXPR_BODY (DECL_SAVED_TREE (context)) = stmt_list;
+ gimple bind;
+ annotate_all_with_location (stmt_list, DECL_SOURCE_LOCATION (context));
+ bind = gimple_seq_first_stmt (gimple_body (context));
+ gimple_seq_add_seq (&stmt_list, gimple_bind_body (bind));
+ gimple_bind_set_body (bind, stmt_list);
}
/* If a chain_decl was created, then it needs to be registered with
@@ -2014,10 +2065,12 @@ finalize_nesting_tree_1 (struct nesting_info *root)
/* Make sure all new local variables get inserted into the
proper BIND_EXPR. */
if (root->new_local_var_chain)
- declare_vars (root->new_local_var_chain, DECL_SAVED_TREE (root->context),
+ declare_vars (root->new_local_var_chain,
+ gimple_seq_first_stmt (gimple_body (root->context)),
false);
if (root->debug_var_chain)
- declare_vars (root->debug_var_chain, DECL_SAVED_TREE (root->context),
+ declare_vars (root->debug_var_chain,
+ gimple_seq_first_stmt (gimple_body (root->context)),
true);
/* Dump the translated tree function. */
@@ -2101,10 +2154,14 @@ lower_nested_functions (tree fndecl)
bitmap_obstack_initialize (&nesting_info_bitmap_obstack);
root = create_nesting_tree (cgn);
- walk_all_functions (convert_nonlocal_reference, root);
- walk_all_functions (convert_local_reference, root);
- walk_all_functions (convert_nl_goto_reference, root);
- walk_all_functions (convert_nl_goto_receiver, root);
+ walk_all_functions (convert_nonlocal_reference_stmt,
+ convert_nonlocal_reference_op,
+ root);
+ walk_all_functions (convert_local_reference_stmt,
+ convert_local_reference_op,
+ root);
+ walk_all_functions (convert_nl_goto_reference, NULL, root);
+ walk_all_functions (convert_nl_goto_receiver, NULL, root);
convert_all_function_calls (root);
finalize_nesting_tree (root);
unnest_nesting_tree (root);
diff --git a/gcc/tree-nomudflap.c b/gcc/tree-nomudflap.c
index 8d1ae7519b3..8e618a100f4 100644
--- a/gcc/tree-nomudflap.c
+++ b/gcc/tree-nomudflap.c
@@ -27,7 +27,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-inline.h"
#include "c-tree.h"
#include "c-common.h"
-#include "tree-gimple.h"
+#include "gimple.h"
#include "diagnostic.h"
#include "hashtab.h"
#include "output.h"
diff --git a/gcc/tree-nrv.c b/gcc/tree-nrv.c
index 13febcaf79b..40e7508f613 100644
--- a/gcc/tree-nrv.c
+++ b/gcc/tree-nrv.c
@@ -74,7 +74,8 @@ static tree finalize_nrv_r (tree *, int *, void *);
static tree
finalize_nrv_r (tree *tp, int *walk_subtrees, void *data)
{
- struct nrv_data *dp = (struct nrv_data *)data;
+ struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
+ struct nrv_data *dp = (struct nrv_data *) wi->info;
/* No need to walk into types. */
if (TYPE_P (*tp))
@@ -107,7 +108,7 @@ tree_nrv (void)
tree result_type = TREE_TYPE (result);
tree found = NULL;
basic_block bb;
- block_stmt_iterator bsi;
+ gimple_stmt_iterator gsi;
struct nrv_data data;
/* If this function does not return an aggregate type in memory, then
@@ -123,24 +124,29 @@ tree_nrv (void)
/* Look through each block for assignments to the RESULT_DECL. */
FOR_EACH_BB (bb)
{
- for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
- tree stmt = bsi_stmt (bsi);
- tree ret_expr;
+ gimple stmt = gsi_stmt (gsi);
+ tree ret_val;
- if (TREE_CODE (stmt) == RETURN_EXPR)
+ if (gimple_code (stmt) == GIMPLE_RETURN)
{
/* In a function with an aggregate return value, the
gimplifier has changed all non-empty RETURN_EXPRs to
return the RESULT_DECL. */
- ret_expr = TREE_OPERAND (stmt, 0);
- if (ret_expr)
- gcc_assert (ret_expr == result);
+ ret_val = gimple_return_retval (stmt);
+ if (ret_val)
+ gcc_assert (ret_val == result);
}
- else if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT
- && GIMPLE_STMT_OPERAND (stmt, 0) == result)
+ else if (is_gimple_assign (stmt)
+ && gimple_assign_lhs (stmt) == result)
{
- ret_expr = GIMPLE_STMT_OPERAND (stmt, 1);
+ tree rhs;
+
+ if (!gimple_assign_copy_p (stmt))
+ return 0;
+
+ rhs = gimple_assign_rhs1 (stmt);
/* Now verify that this return statement uses the same value
as any previously encountered return statement. */
@@ -149,11 +155,11 @@ tree_nrv (void)
/* If we found a return statement using a different variable
than previous return statements, then we can not perform
NRV optimizations. */
- if (found != ret_expr)
+ if (found != rhs)
return 0;
}
else
- found = ret_expr;
+ found = rhs;
/* The returned value must be a local automatic variable of the
same type and alignment as the function's result. */
@@ -167,9 +173,9 @@ tree_nrv (void)
TREE_TYPE (found)))
return 0;
}
- else if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT)
+ else if (is_gimple_assign (stmt))
{
- tree addr = get_base_address (GIMPLE_STMT_OPERAND (stmt, 0));
+ tree addr = get_base_address (gimple_assign_lhs (stmt));
/* If there's any MODIFY of component of RESULT,
then bail out. */
if (addr && addr == result)
@@ -205,18 +211,21 @@ tree_nrv (void)
data.result = result;
FOR_EACH_BB (bb)
{
- for (bsi = bsi_start (bb); !bsi_end_p (bsi); )
+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); )
{
- tree *tp = bsi_stmt_ptr (bsi);
+ gimple stmt = gsi_stmt (gsi);
/* If this is a copy from VAR to RESULT, remove it. */
- if (TREE_CODE (*tp) == GIMPLE_MODIFY_STMT
- && GIMPLE_STMT_OPERAND (*tp, 0) == result
- && GIMPLE_STMT_OPERAND (*tp, 1) == found)
- bsi_remove (&bsi, true);
+ if (gimple_assign_copy_p (stmt)
+ && gimple_assign_lhs (stmt) == result
+ && gimple_assign_rhs1 (stmt) == found)
+ gsi_remove (&gsi, true);
else
{
- walk_tree (tp, finalize_nrv_r, &data, 0);
- bsi_next (&bsi);
+ struct walk_stmt_info wi;
+ memset (&wi, 0, sizeof (wi));
+ wi.info = &data;
+ walk_gimple_op (stmt, finalize_nrv_r, &wi);
+ gsi_next (&gsi);
}
}
}
@@ -226,12 +235,18 @@ tree_nrv (void)
return 0;
}
+static bool
+gate_pass_return_slot (void)
+{
+ return optimize > 0;
+}
+
struct gimple_opt_pass pass_nrv =
{
{
GIMPLE_PASS,
"nrv", /* name */
- NULL, /* gate */
+ gate_pass_return_slot, /* gate */
tree_nrv, /* execute */
NULL, /* sub */
NULL, /* next */
@@ -265,13 +280,13 @@ dest_safe_for_nrv_p (tree dest)
if (TREE_CODE (dest) == SSA_NAME)
dest = SSA_NAME_VAR (dest);
- if (is_call_clobbered (dest))
+ if (is_call_used (dest))
return false;
return true;
}
-/* Walk through the function looking for GIMPLE_MODIFY_STMTs with calls that
+/* Walk through the function looking for GIMPLE_ASSIGNs with calls that
return in memory on the RHS. For each of these, determine whether it is
safe to pass the address of the LHS as the return slot, and mark the
call appropriately if so.
@@ -290,21 +305,24 @@ execute_return_slot_opt (void)
FOR_EACH_BB (bb)
{
- block_stmt_iterator i;
- for (i = bsi_start (bb); !bsi_end_p (i); bsi_next (&i))
+ gimple_stmt_iterator gsi;
+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
- tree stmt = bsi_stmt (i);
- tree call;
-
- if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT
- && (call = GIMPLE_STMT_OPERAND (stmt, 1),
- TREE_CODE (call) == CALL_EXPR)
- && !CALL_EXPR_RETURN_SLOT_OPT (call)
- && aggregate_value_p (call, call))
- /* Check if the location being assigned to is
- call-clobbered. */
- CALL_EXPR_RETURN_SLOT_OPT (call) =
- dest_safe_for_nrv_p (GIMPLE_STMT_OPERAND (stmt, 0)) ? 1 : 0;
+ gimple stmt = gsi_stmt (gsi);
+ bool slot_opt_p;
+
+ if (is_gimple_call (stmt)
+ && gimple_call_lhs (stmt)
+ && !gimple_call_return_slot_opt_p (stmt)
+ && aggregate_value_p (TREE_TYPE (gimple_call_lhs (stmt)),
+ gimple_call_fndecl (stmt))
+ )
+ {
+ /* Check if the location being assigned to is
+ call-clobbered. */
+ slot_opt_p = dest_safe_for_nrv_p (gimple_call_lhs (stmt));
+ gimple_call_set_return_slot_opt (stmt, slot_opt_p);
+ }
}
}
return 0;
diff --git a/gcc/tree-object-size.c b/gcc/tree-object-size.c
index c1b3b5f1264..22c495154d4 100644
--- a/gcc/tree-object-size.c
+++ b/gcc/tree-object-size.c
@@ -43,13 +43,13 @@ static unsigned HOST_WIDE_INT unknown[4] = { -1, -1, 0, 0 };
static tree compute_object_offset (const_tree, const_tree);
static unsigned HOST_WIDE_INT addr_object_size (const_tree, int);
-static unsigned HOST_WIDE_INT alloc_object_size (const_tree, int);
-static tree pass_through_call (const_tree);
+static unsigned HOST_WIDE_INT alloc_object_size (const_gimple, int);
+static tree pass_through_call (const_gimple);
static void collect_object_sizes_for (struct object_size_info *, tree);
static void expr_object_size (struct object_size_info *, tree, tree);
static bool merge_object_sizes (struct object_size_info *, tree, tree,
unsigned HOST_WIDE_INT);
-static bool plus_expr_object_size (struct object_size_info *, tree, tree);
+static bool plus_stmt_object_size (struct object_size_info *, tree, gimple);
static bool cond_expr_object_size (struct object_size_info *, tree, tree);
static unsigned int compute_object_sizes (void);
static void init_offset_limit (void);
@@ -219,21 +219,21 @@ addr_object_size (const_tree ptr, int object_size_type)
}
-/* Compute __builtin_object_size for CALL, which is a CALL_EXPR.
+/* Compute __builtin_object_size for CALL, which is a GIMPLE_CALL.
Handles various allocation calls. OBJECT_SIZE_TYPE is the second
argument from __builtin_object_size. If unknown, return
unknown[object_size_type]. */
static unsigned HOST_WIDE_INT
-alloc_object_size (const_tree call, int object_size_type)
+alloc_object_size (const_gimple call, int object_size_type)
{
tree callee, bytes = NULL_TREE;
tree alloc_size;
int arg1 = -1, arg2 = -1;
- gcc_assert (TREE_CODE (call) == CALL_EXPR);
+ gcc_assert (is_gimple_call (call));
- callee = get_callee_fndecl (call);
+ callee = gimple_call_fndecl (call);
if (!callee)
return unknown[object_size_type];
@@ -244,7 +244,7 @@ alloc_object_size (const_tree call, int object_size_type)
arg1 = TREE_INT_CST_LOW (TREE_VALUE (p))-1;
if (TREE_CHAIN (p))
- arg2 = TREE_INT_CST_LOW (TREE_VALUE (TREE_CHAIN (p)))-1;
+ arg2 = TREE_INT_CST_LOW (TREE_VALUE (TREE_CHAIN (p)))-1;
}
if (DECL_BUILT_IN_CLASS (callee) == BUILT_IN_NORMAL)
@@ -260,19 +260,19 @@ alloc_object_size (const_tree call, int object_size_type)
break;
}
- if (arg1 < 0 || arg1 >= call_expr_nargs (call)
- || TREE_CODE (CALL_EXPR_ARG (call, arg1)) != INTEGER_CST
+ if (arg1 < 0 || arg1 >= (int)gimple_call_num_args (call)
+ || TREE_CODE (gimple_call_arg (call, arg1)) != INTEGER_CST
|| (arg2 >= 0
- && (arg2 >= call_expr_nargs (call)
- || TREE_CODE (CALL_EXPR_ARG (call, arg2)) != INTEGER_CST)))
+ && (arg2 >= (int)gimple_call_num_args (call)
+ || TREE_CODE (gimple_call_arg (call, arg2)) != INTEGER_CST)))
return unknown[object_size_type];
if (arg2 >= 0)
bytes = size_binop (MULT_EXPR,
- fold_convert (sizetype, CALL_EXPR_ARG (call, arg1)),
- fold_convert (sizetype, CALL_EXPR_ARG (call, arg2)));
+ fold_convert (sizetype, gimple_call_arg (call, arg1)),
+ fold_convert (sizetype, gimple_call_arg (call, arg2)));
else if (arg1 >= 0)
- bytes = fold_convert (sizetype, CALL_EXPR_ARG (call, arg1));
+ bytes = fold_convert (sizetype, gimple_call_arg (call, arg1));
if (bytes && host_integerp (bytes, 1))
return tree_low_cst (bytes, 1);
@@ -282,13 +282,13 @@ alloc_object_size (const_tree call, int object_size_type)
/* If object size is propagated from one of function's arguments directly
- to its return value, return that argument for CALL_EXPR CALL.
+ to its return value, return that argument for GIMPLE_CALL statement CALL.
Otherwise return NULL. */
static tree
-pass_through_call (const_tree call)
+pass_through_call (const_gimple call)
{
- tree callee = get_callee_fndecl (call);
+ tree callee = gimple_call_fndecl (call);
if (callee
&& DECL_BUILT_IN_CLASS (callee) == BUILT_IN_NORMAL)
@@ -308,8 +308,8 @@ pass_through_call (const_tree call)
case BUILT_IN_STRNCPY_CHK:
case BUILT_IN_STRCAT_CHK:
case BUILT_IN_STRNCAT_CHK:
- if (call_expr_nargs (call) >= 1)
- return CALL_EXPR_ARG (call, 0);
+ if (gimple_call_num_args (call) >= 1)
+ return gimple_call_arg (call, 0);
break;
default:
break;
@@ -332,16 +332,8 @@ compute_builtin_object_size (tree ptr, int object_size_type)
if (TREE_CODE (ptr) == ADDR_EXPR)
return addr_object_size (ptr, object_size_type);
- else if (TREE_CODE (ptr) == CALL_EXPR)
- {
- tree arg = pass_through_call (ptr);
- if (arg)
- return compute_builtin_object_size (arg, object_size_type);
- else
- return alloc_object_size (ptr, object_size_type);
- }
- else if (TREE_CODE (ptr) == SSA_NAME
+ if (TREE_CODE (ptr) == SSA_NAME
&& POINTER_TYPE_P (TREE_TYPE (ptr))
&& object_sizes[object_size_type] != NULL)
{
@@ -463,9 +455,7 @@ compute_builtin_object_size (tree ptr, int object_size_type)
return unknown[object_size_type];
}
-
-/* Compute object_sizes for PTR, defined to VALUE, which is not
- a SSA_NAME. */
+/* Compute object_sizes for PTR, defined to VALUE, which is not an SSA_NAME. */
static void
expr_object_size (struct object_size_info *osi, tree ptr, tree value)
@@ -487,8 +477,6 @@ expr_object_size (struct object_size_info *osi, tree ptr, tree value)
if (TREE_CODE (value) == ADDR_EXPR)
bytes = addr_object_size (value, object_size_type);
- else if (TREE_CODE (value) == CALL_EXPR)
- bytes = alloc_object_size (value, object_size_type);
else
bytes = unknown[object_size_type];
@@ -505,6 +493,64 @@ expr_object_size (struct object_size_info *osi, tree ptr, tree value)
}
+/* Compute object_sizes for PTR, defined to the result of a call. */
+
+static void
+call_object_size (struct object_size_info *osi, tree ptr, gimple call)
+{
+ int object_size_type = osi->object_size_type;
+ unsigned int varno = SSA_NAME_VERSION (ptr);
+ unsigned HOST_WIDE_INT bytes;
+
+ gcc_assert (is_gimple_call (call));
+
+ gcc_assert (object_sizes[object_size_type][varno]
+ != unknown[object_size_type]);
+ gcc_assert (osi->pass == 0);
+
+ bytes = alloc_object_size (call, object_size_type);
+
+ if ((object_size_type & 2) == 0)
+ {
+ if (object_sizes[object_size_type][varno] < bytes)
+ object_sizes[object_size_type][varno] = bytes;
+ }
+ else
+ {
+ if (object_sizes[object_size_type][varno] > bytes)
+ object_sizes[object_size_type][varno] = bytes;
+ }
+}
+
+
+/* Compute object_sizes for PTR, defined to an unknown value. */
+
+static void
+unknown_object_size (struct object_size_info *osi, tree ptr)
+{
+ int object_size_type = osi->object_size_type;
+ unsigned int varno = SSA_NAME_VERSION (ptr);
+ unsigned HOST_WIDE_INT bytes;
+
+ gcc_assert (object_sizes[object_size_type][varno]
+ != unknown[object_size_type]);
+ gcc_assert (osi->pass == 0);
+
+ bytes = unknown[object_size_type];
+
+ if ((object_size_type & 2) == 0)
+ {
+ if (object_sizes[object_size_type][varno] < bytes)
+ object_sizes[object_size_type][varno] = bytes;
+ }
+ else
+ {
+ if (object_sizes[object_size_type][varno] > bytes)
+ object_sizes[object_size_type][varno] = bytes;
+ }
+}
+
+
/* Merge object sizes of ORIG + OFFSET into DEST. Return true if
the object size might need reexamination later. */
@@ -552,20 +598,22 @@ merge_object_sizes (struct object_size_info *osi, tree dest, tree orig,
}
-/* Compute object_sizes for PTR, defined to VALUE, which is
- a POINTER_PLUS_EXPR. Return true if the object size might need reexamination
- later. */
+/* Compute object_sizes for VAR, defined to the result of an assignment
+ with operator POINTER_PLUS_EXPR. Return true if the object size might
+ need reexamination later. */
static bool
-plus_expr_object_size (struct object_size_info *osi, tree var, tree value)
+plus_stmt_object_size (struct object_size_info *osi, tree var, gimple stmt)
{
- tree op0 = TREE_OPERAND (value, 0);
- tree op1 = TREE_OPERAND (value, 1);
int object_size_type = osi->object_size_type;
unsigned int varno = SSA_NAME_VERSION (var);
unsigned HOST_WIDE_INT bytes;
+ tree op0, op1;
+
+ gcc_assert (gimple_assign_rhs_code (stmt) == POINTER_PLUS_EXPR);
- gcc_assert (TREE_CODE (value) == POINTER_PLUS_EXPR);
+ op0 = gimple_assign_rhs1 (stmt);
+ op1 = gimple_assign_rhs2 (stmt);
if (object_sizes[object_size_type][varno] == unknown[object_size_type])
return false;
@@ -583,6 +631,7 @@ plus_expr_object_size (struct object_size_info *osi, tree var, tree value)
{
unsigned HOST_WIDE_INT off = tree_low_cst (op1, 1);
+ /* op0 will be ADDR_EXPR here. */
bytes = compute_builtin_object_size (op0, object_size_type);
if (bytes == unknown[object_size_type])
;
@@ -611,7 +660,7 @@ plus_expr_object_size (struct object_size_info *osi, tree var, tree value)
}
-/* Compute object_sizes for PTR, defined to VALUE, which is
+/* Compute object_sizes for VAR, defined to VALUE, which is
a COND_EXPR. Return true if the object size might need reexamination
later. */
@@ -644,12 +693,11 @@ cond_expr_object_size (struct object_size_info *osi, tree var, tree value)
return reexamine;
}
-
/* Compute object sizes for VAR.
For ADDR_EXPR an object size is the number of remaining bytes
to the end of the object (where what is considered an object depends on
OSI->object_size_type).
- For allocation CALL_EXPR like malloc or calloc object size is the size
+ For allocation GIMPLE_CALL like malloc or calloc object size is the size
of the allocation.
For POINTER_PLUS_EXPR where second operand is a constant integer,
object size is object size of the first operand minus the constant.
@@ -660,7 +708,7 @@ cond_expr_object_size (struct object_size_info *osi, tree var, tree value)
unknown[object_size_type] for all objects bigger than half of the address
space, and constants less than half of the address space are considered
addition, while bigger constants subtraction.
- For a memcpy like CALL_EXPR that always returns one of its arguments, the
+ For a memcpy like GIMPLE_CALL that always returns one of its arguments, the
object size is object size of that argument.
Otherwise, object size is the maximum of object sizes of variables
that it might be set to. */
@@ -670,7 +718,7 @@ collect_object_sizes_for (struct object_size_info *osi, tree var)
{
int object_size_type = osi->object_size_type;
unsigned int varno = SSA_NAME_VERSION (var);
- tree stmt;
+ gimple stmt;
bool reexamine;
if (bitmap_bit_p (computed[object_size_type], varno))
@@ -709,51 +757,57 @@ collect_object_sizes_for (struct object_size_info *osi, tree var)
stmt = SSA_NAME_DEF_STMT (var);
reexamine = false;
- switch (TREE_CODE (stmt))
+ switch (gimple_code (stmt))
{
- case RETURN_EXPR:
- gcc_assert (TREE_CODE (TREE_OPERAND (stmt, 0)) == GIMPLE_MODIFY_STMT);
- stmt = TREE_OPERAND (stmt, 0);
- /* FALLTHRU */
-
- case GIMPLE_MODIFY_STMT:
+ case GIMPLE_ASSIGN:
{
- tree rhs = GIMPLE_STMT_OPERAND (stmt, 1), arg;
- STRIP_NOPS (rhs);
-
- if (TREE_CODE (rhs) == CALL_EXPR)
- {
- arg = pass_through_call (rhs);
- if (arg)
- rhs = arg;
- }
-
- if (TREE_CODE (rhs) == SSA_NAME
- && POINTER_TYPE_P (TREE_TYPE (rhs)))
- reexamine = merge_object_sizes (osi, var, rhs, 0);
-
- else if (TREE_CODE (rhs) == POINTER_PLUS_EXPR)
- reexamine = plus_expr_object_size (osi, var, rhs);
-
- else if (TREE_CODE (rhs) == COND_EXPR)
- reexamine = cond_expr_object_size (osi, var, rhs);
+ if (gimple_assign_rhs_code (stmt) == POINTER_PLUS_EXPR)
+ reexamine = plus_stmt_object_size (osi, var, stmt);
+ else if (gimple_assign_single_p (stmt)
+ || gimple_assign_unary_nop_p (stmt))
+ {
+ tree rhs = gimple_assign_rhs1 (stmt);
+
+ if (TREE_CODE (rhs) == SSA_NAME
+ && POINTER_TYPE_P (TREE_TYPE (rhs)))
+ reexamine = merge_object_sizes (osi, var, rhs, 0);
+ else if (TREE_CODE (rhs) == COND_EXPR)
+ reexamine = cond_expr_object_size (osi, var, rhs);
+ else
+ expr_object_size (osi, var, rhs);
+ }
+ else
+ unknown_object_size (osi, var);
+ break;
+ }
- else
- expr_object_size (osi, var, rhs);
+ case GIMPLE_CALL:
+ {
+ tree arg = pass_through_call (stmt);
+ if (arg)
+ {
+ if (TREE_CODE (arg) == SSA_NAME
+ && POINTER_TYPE_P (TREE_TYPE (arg)))
+ reexamine = merge_object_sizes (osi, var, arg, 0);
+ else if (TREE_CODE (arg) == COND_EXPR)
+ reexamine = cond_expr_object_size (osi, var, arg);
+ else
+ expr_object_size (osi, var, arg);
+ }
+ else
+ call_object_size (osi, var, stmt);
break;
}
- case ASM_EXPR:
+ case GIMPLE_ASM:
/* Pointers defined by __asm__ statements can point anywhere. */
object_sizes[object_size_type][varno] = unknown[object_size_type];
break;
- case NOP_EXPR:
+ case GIMPLE_NOP:
{
tree decl = SSA_NAME_VAR (var);
- gcc_assert (IS_EMPTY_STMT (stmt));
-
if (TREE_CODE (decl) != PARM_DECL && DECL_INITIAL (decl))
expr_object_size (osi, var, DECL_INITIAL (decl));
else
@@ -761,13 +815,13 @@ collect_object_sizes_for (struct object_size_info *osi, tree var)
}
break;
- case PHI_NODE:
+ case GIMPLE_PHI:
{
- int i;
+ unsigned i;
- for (i = 0; i < PHI_NUM_ARGS (stmt); i++)
+ for (i = 0; i < gimple_phi_num_args (stmt); i++)
{
- tree rhs = PHI_ARG_DEF (stmt, i);
+ tree rhs = gimple_phi_arg (stmt, i)->def;
if (object_sizes[object_size_type][varno]
== unknown[object_size_type])
@@ -780,6 +834,7 @@ collect_object_sizes_for (struct object_size_info *osi, tree var)
}
break;
}
+
default:
gcc_unreachable ();
}
@@ -810,7 +865,7 @@ static void
check_for_plus_in_loops_1 (struct object_size_info *osi, tree var,
unsigned int depth)
{
- tree stmt = SSA_NAME_DEF_STMT (var);
+ gimple stmt = SSA_NAME_DEF_STMT (var);
unsigned int varno = SSA_NAME_VERSION (var);
if (osi->depths[varno])
@@ -838,57 +893,61 @@ check_for_plus_in_loops_1 (struct object_size_info *osi, tree var,
osi->depths[varno] = depth;
*osi->tos++ = varno;
- switch (TREE_CODE (stmt))
+ switch (gimple_code (stmt))
{
- case RETURN_EXPR:
- gcc_assert (TREE_CODE (TREE_OPERAND (stmt, 0)) == GIMPLE_MODIFY_STMT);
- stmt = TREE_OPERAND (stmt, 0);
- /* FALLTHRU */
- case GIMPLE_MODIFY_STMT:
+ case GIMPLE_ASSIGN:
{
- tree rhs = GIMPLE_STMT_OPERAND (stmt, 1), arg;
- STRIP_NOPS (rhs);
-
- if (TREE_CODE (rhs) == CALL_EXPR)
- {
- arg = pass_through_call (rhs);
- if (arg)
- rhs = arg;
- }
-
- if (TREE_CODE (rhs) == SSA_NAME)
- check_for_plus_in_loops_1 (osi, rhs, depth);
- else if (TREE_CODE (rhs) == POINTER_PLUS_EXPR)
- {
- tree op0 = TREE_OPERAND (rhs, 0);
- tree op1 = TREE_OPERAND (rhs, 1);
- tree cst, basevar;
-
- basevar = op0;
- cst = op1;
- gcc_assert (TREE_CODE (cst) == INTEGER_CST);
+ if ((gimple_assign_single_p (stmt)
+ || gimple_assign_unary_nop_p (stmt))
+ && TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME)
+ {
+ tree rhs = gimple_assign_rhs1 (stmt);
+
+ check_for_plus_in_loops_1 (osi, rhs, depth);
+ }
+ else if (gimple_assign_rhs_code (stmt) == POINTER_PLUS_EXPR)
+ {
+ tree basevar = gimple_assign_rhs1 (stmt);
+ tree cst = gimple_assign_rhs2 (stmt);
+
+ gcc_assert (TREE_CODE (cst) == INTEGER_CST);
+
+ check_for_plus_in_loops_1 (osi, basevar,
+ depth + !integer_zerop (cst));
+ }
+ else
+ gcc_unreachable ();
+ break;
+ }
- check_for_plus_in_loops_1 (osi, basevar,
- depth + !integer_zerop (cst));
- }
- else
- gcc_unreachable ();
- break;
+ case GIMPLE_CALL:
+ {
+ tree arg = pass_through_call (stmt);
+ if (arg)
+ {
+ if (TREE_CODE (arg) == SSA_NAME)
+ check_for_plus_in_loops_1 (osi, arg, depth);
+ else
+ gcc_unreachable ();
+ }
+ break;
}
- case PHI_NODE:
+
+ case GIMPLE_PHI:
{
- int i;
+ unsigned i;
- for (i = 0; i < PHI_NUM_ARGS (stmt); i++)
+ for (i = 0; i < gimple_phi_num_args (stmt); i++)
{
- tree rhs = PHI_ARG_DEF (stmt, i);
+ tree rhs = gimple_phi_arg (stmt, i)->def;
if (TREE_CODE (rhs) == SSA_NAME)
check_for_plus_in_loops_1 (osi, rhs, depth);
}
break;
}
+
default:
gcc_unreachable ();
}
@@ -905,50 +964,29 @@ check_for_plus_in_loops_1 (struct object_size_info *osi, tree var,
static void
check_for_plus_in_loops (struct object_size_info *osi, tree var)
{
- tree stmt = SSA_NAME_DEF_STMT (var);
+ gimple stmt = SSA_NAME_DEF_STMT (var);
- switch (TREE_CODE (stmt))
- {
- case RETURN_EXPR:
- gcc_assert (TREE_CODE (TREE_OPERAND (stmt, 0)) == GIMPLE_MODIFY_STMT);
- stmt = TREE_OPERAND (stmt, 0);
- /* FALLTHRU */
-
- case GIMPLE_MODIFY_STMT:
- {
- tree rhs = GIMPLE_STMT_OPERAND (stmt, 1), arg;
- STRIP_NOPS (rhs);
-
- if (TREE_CODE (rhs) == CALL_EXPR)
- {
- arg = pass_through_call (rhs);
- if (arg)
- rhs = arg;
- }
+ /* NOTE: In the pre-tuples code, we handled a CALL_EXPR here,
+ and looked for a POINTER_PLUS_EXPR in the pass-through
+ argument, if any. In GIMPLE, however, such an expression
+ is not a valid call operand. */
- if (TREE_CODE (rhs) == POINTER_PLUS_EXPR)
- {
- tree op0 = TREE_OPERAND (rhs, 0);
- tree op1 = TREE_OPERAND (rhs, 1);
- tree cst, basevar;
-
- basevar = op0;
- cst = op1;
- gcc_assert (TREE_CODE (cst) == INTEGER_CST);
-
- if (integer_zerop (cst))
- break;
-
- osi->depths[SSA_NAME_VERSION (basevar)] = 1;
- *osi->tos++ = SSA_NAME_VERSION (basevar);
- check_for_plus_in_loops_1 (osi, var, 2);
- osi->depths[SSA_NAME_VERSION (basevar)] = 0;
- osi->tos--;
- }
- break;
- }
- default:
- break;
+ if (is_gimple_assign (stmt)
+ && gimple_assign_rhs_code (stmt) == POINTER_PLUS_EXPR)
+ {
+ tree basevar = gimple_assign_rhs1 (stmt);
+ tree cst = gimple_assign_rhs2 (stmt);
+
+ gcc_assert (TREE_CODE (cst) == INTEGER_CST);
+
+ if (integer_zerop (cst))
+ return;
+
+ osi->depths[SSA_NAME_VERSION (basevar)] = 1;
+ *osi->tos++ = SSA_NAME_VERSION (basevar);
+ check_for_plus_in_loops_1 (osi, var, 2);
+ osi->depths[SSA_NAME_VERSION (basevar)] = 0;
+ osi->tos--;
}
}
@@ -997,30 +1035,29 @@ compute_object_sizes (void)
basic_block bb;
FOR_EACH_BB (bb)
{
- block_stmt_iterator i;
- for (i = bsi_start (bb); !bsi_end_p (i); bsi_next (&i))
+ gimple_stmt_iterator i;
+ for (i = gsi_start_bb (bb); !gsi_end_p (i); gsi_next (&i))
{
- tree *stmtp = bsi_stmt_ptr (i);
- tree call = get_rhs (*stmtp);
tree callee, result;
+ gimple call = gsi_stmt (i);
- if (!call || TREE_CODE (call) != CALL_EXPR)
+ if (gimple_code (call) != GIMPLE_CALL)
continue;
- callee = get_callee_fndecl (call);
+ callee = gimple_call_fndecl (call);
if (!callee
|| DECL_BUILT_IN_CLASS (callee) != BUILT_IN_NORMAL
|| DECL_FUNCTION_CODE (callee) != BUILT_IN_OBJECT_SIZE)
continue;
init_object_sizes ();
- result = fold_call_expr (call, false);
+ result = fold_call_stmt (call, false);
if (!result)
{
- if (call_expr_nargs (call) == 2
- && POINTER_TYPE_P (TREE_TYPE (CALL_EXPR_ARG (call, 0))))
+ if (gimple_call_num_args (call) == 2
+ && POINTER_TYPE_P (TREE_TYPE (gimple_call_arg (call, 0))))
{
- tree ost = CALL_EXPR_ARG (call, 1);
+ tree ost = gimple_call_arg (call, 1);
if (host_integerp (ost, 1))
{
@@ -1042,17 +1079,19 @@ compute_object_sizes (void)
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "Simplified\n ");
- print_generic_stmt (dump_file, *stmtp, dump_flags);
+ print_gimple_stmt (dump_file, call, 0, dump_flags);
}
- if (!set_rhs (stmtp, result))
+ if (!update_call_from_tree (&i, result))
gcc_unreachable ();
- update_stmt (*stmtp);
+
+ /* NOTE: In the pre-tuples code, we called update_stmt here. This is
+ now handled by gsi_replace, called from update_call_from_tree. */
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "to\n ");
- print_generic_stmt (dump_file, *stmtp, dump_flags);
+ print_gimple_stmt (dump_file, call, 0, dump_flags);
fprintf (dump_file, "\n");
}
}
diff --git a/gcc/tree-optimize.c b/gcc/tree-optimize.c
index 35feaa1be5b..ba3d0fcc9e0 100644
--- a/gcc/tree-optimize.c
+++ b/gcc/tree-optimize.c
@@ -115,7 +115,7 @@ execute_early_local_optimizations (void)
cgraph state so newly inserted functions are also early optimized.
However we execute early local optimizations for lately inserted
functions, in that case don't reset cgraph state back to IPA_SSA. */
- if (flag_unit_at_a_time && cgraph_state < CGRAPH_STATE_IPA_SSA)
+ if (cgraph_state < CGRAPH_STATE_IPA_SSA)
cgraph_state = CGRAPH_STATE_IPA_SSA;
return 0;
}
@@ -289,7 +289,7 @@ unsigned int
execute_fixup_cfg (void)
{
basic_block bb;
- block_stmt_iterator bsi;
+ gimple_stmt_iterator gsi;
int todo = gimple_in_ssa_p (cfun) ? TODO_verify_ssa : 0;
cfun->after_inlining = true;
@@ -297,35 +297,36 @@ execute_fixup_cfg (void)
if (cfun->eh)
FOR_EACH_BB (bb)
{
- for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
- tree stmt = bsi_stmt (bsi);
- tree call = get_call_expr_in (stmt);
- tree decl = call ? get_callee_fndecl (call) : NULL;
-
- if (decl && call_expr_flags (call) & (ECF_CONST | ECF_PURE
- | ECF_LOOPING_CONST_OR_PURE)
- && TREE_SIDE_EFFECTS (call))
+ gimple stmt = gsi_stmt (gsi);
+ tree decl = is_gimple_call (stmt)
+ ? gimple_call_fndecl (stmt)
+ : NULL;
+
+ if (decl
+ && gimple_call_flags (stmt) & (ECF_CONST
+ | ECF_PURE
+ | ECF_LOOPING_CONST_OR_PURE))
{
if (gimple_in_ssa_p (cfun))
{
todo |= TODO_update_ssa | TODO_cleanup_cfg;
update_stmt (stmt);
}
- TREE_SIDE_EFFECTS (call) = 0;
}
- if (decl && TREE_NOTHROW (decl))
- TREE_NOTHROW (call) = 1;
- if (!tree_could_throw_p (stmt) && lookup_stmt_eh_region (stmt))
+
+ if (!stmt_could_throw_p (stmt) && lookup_stmt_eh_region (stmt))
remove_stmt_from_eh_region (stmt);
}
- if (tree_purge_dead_eh_edges (bb))
+
+ if (gimple_purge_dead_eh_edges (bb))
todo |= TODO_cleanup_cfg;
}
/* Dump a textual representation of the flowgraph. */
if (dump_file)
- dump_tree_cfg (dump_file, dump_flags);
+ gimple_dump_cfg (dump_file, dump_flags);
return todo;
}
@@ -341,20 +342,12 @@ execute_init_datastructures (void)
return 0;
}
-/* Gate: initialize or not the SSA datastructures. */
-
-static bool
-gate_init_datastructures (void)
-{
- return (optimize >= 1);
-}
-
struct gimple_opt_pass pass_init_datastructures =
{
{
GIMPLE_PASS,
NULL, /* name */
- gate_init_datastructures, /* gate */
+ NULL, /* gate */
execute_init_datastructures, /* execute */
NULL, /* sub */
NULL, /* next */
@@ -375,7 +368,7 @@ tree_lowering_passes (tree fn)
current_function_decl = fn;
push_cfun (DECL_STRUCT_FUNCTION (fn));
- tree_register_cfg_hooks ();
+ gimple_register_cfg_hooks ();
bitmap_obstack_initialize (NULL);
execute_pass_list (all_lowering_passes);
if (optimize && cgraph_global_info_ready)
@@ -399,7 +392,7 @@ tree_rest_of_compilation (tree fndecl)
timevar_push (TV_EXPAND);
- gcc_assert (!flag_unit_at_a_time || cgraph_global_info_ready);
+ gcc_assert (cgraph_global_info_ready);
node = cgraph_node (fndecl);
@@ -418,7 +411,7 @@ tree_rest_of_compilation (tree fndecl)
not safe to try to expand expressions involving them. */
cfun->dont_save_pending_sizes_p = 1;
- tree_register_cfg_hooks ();
+ gimple_register_cfg_hooks ();
bitmap_obstack_initialize (&reg_obstack); /* FIXME, only at RTL generation*/
/* Perform all tree transforms and optimizations. */
@@ -429,7 +422,6 @@ tree_rest_of_compilation (tree fndecl)
/* Release the default bitmap obstack. */
bitmap_obstack_release (NULL);
- DECL_SAVED_TREE (fndecl) = NULL;
set_cfun (NULL);
/* If requested, warn about function definitions where the function will
@@ -456,20 +448,17 @@ tree_rest_of_compilation (tree fndecl)
}
}
- if (!flag_inline_trees)
+ gimple_set_body (fndecl, NULL);
+ if (DECL_STRUCT_FUNCTION (fndecl) == 0
+ && !cgraph_node (fndecl)->origin)
{
- DECL_SAVED_TREE (fndecl) = NULL;
- if (DECL_STRUCT_FUNCTION (fndecl) == 0
- && !cgraph_node (fndecl)->origin)
- {
- /* Stop pointing to the local nodes about to be freed.
- But DECL_INITIAL must remain nonzero so we know this
- was an actual function definition.
- For a nested function, this is done in c_pop_function_context.
- If rest_of_compilation set this to 0, leave it 0. */
- if (DECL_INITIAL (fndecl) != 0)
- DECL_INITIAL (fndecl) = error_mark_node;
- }
+ /* Stop pointing to the local nodes about to be freed.
+ But DECL_INITIAL must remain nonzero so we know this
+ was an actual function definition.
+ For a nested function, this is done in c_pop_function_context.
+ If rest_of_compilation set this to 0, leave it 0. */
+ if (DECL_INITIAL (fndecl) != 0)
+ DECL_INITIAL (fndecl) = error_mark_node;
}
input_location = saved_loc;
diff --git a/gcc/tree-outof-ssa.c b/gcc/tree-outof-ssa.c
index 40c1d3f9c3b..58aed883007 100644
--- a/gcc/tree-outof-ssa.c
+++ b/gcc/tree-outof-ssa.c
@@ -128,6 +128,8 @@ create_temp (tree t)
set_symbol_mem_tag (tmp, symbol_mem_tag (t));
if (is_call_clobbered (t))
mark_call_clobbered (tmp, var_ann (t)->escape_mask);
+ if (bitmap_bit_p (gimple_call_used_vars (cfun), DECL_UID (t)))
+ bitmap_set_bit (gimple_call_used_vars (cfun), DECL_UID (tmp));
return tmp;
}
@@ -139,9 +141,9 @@ create_temp (tree t)
static void
insert_copy_on_edge (edge e, tree dest, tree src)
{
- tree copy;
+ gimple copy;
- copy = build_gimple_modify_stmt (dest, src);
+ copy = gimple_build_assign (dest, src);
set_is_used (dest);
if (TREE_CODE (src) == ADDR_EXPR)
@@ -155,11 +157,11 @@ insert_copy_on_edge (edge e, tree dest, tree src)
"Inserting a copy on edge BB%d->BB%d :",
e->src->index,
e->dest->index);
- print_generic_expr (dump_file, copy, dump_flags);
+ print_gimple_stmt (dump_file, copy, 0, dump_flags);
fprintf (dump_file, "\n");
}
- bsi_insert_on_edge (e, copy);
+ gsi_insert_on_edge (e, copy);
}
@@ -313,15 +315,17 @@ eliminate_name (elim_graph g, tree T)
static void
eliminate_build (elim_graph g, basic_block B)
{
- tree phi;
tree T0, Ti;
int p0, pi;
+ gimple_stmt_iterator gsi;
clear_elim_graph (g);
- for (phi = phi_nodes (B); phi; phi = PHI_CHAIN (phi))
+ for (gsi = gsi_start_phis (B); !gsi_end_p (gsi); gsi_next (&gsi))
{
- T0 = var_to_partition_to_var (g->map, PHI_RESULT (phi));
+ gimple phi = gsi_stmt (gsi);
+
+ T0 = var_to_partition_to_var (g->map, gimple_phi_result (phi));
/* Ignore results which are not in partitions. */
if (T0 == NULL_TREE)
@@ -549,7 +553,7 @@ assign_vars (var_map map)
If the stmt is changed, return true. */
static inline bool
-replace_use_variable (var_map map, use_operand_p p, tree *expr)
+replace_use_variable (var_map map, use_operand_p p, gimple *expr)
{
tree new_var;
tree var = USE_FROM_PTR (p);
@@ -560,11 +564,7 @@ replace_use_variable (var_map map, use_operand_p p, tree *expr)
int version = SSA_NAME_VERSION (var);
if (expr[version])
{
- tree new_expr = GIMPLE_STMT_OPERAND (expr[version], 1);
- SET_USE (p, new_expr);
-
- /* Clear the stmt's RHS, or GC might bite us. */
- GIMPLE_STMT_OPERAND (expr[version], 1) = NULL_TREE;
+ SET_USE (p, gimple_assign_rhs_to_tree (expr[version]));
return true;
}
}
@@ -612,20 +612,20 @@ static void
eliminate_virtual_phis (void)
{
basic_block bb;
- tree phi, next;
+ gimple_stmt_iterator gsi;
FOR_EACH_BB (bb)
{
- for (phi = phi_nodes (bb); phi; phi = next)
+ for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); )
{
- next = PHI_CHAIN (phi);
- if (!is_gimple_reg (SSA_NAME_VAR (PHI_RESULT (phi))))
+ gimple phi = gsi_stmt (gsi);
+ if (!is_gimple_reg (SSA_NAME_VAR (gimple_phi_result (phi))))
{
#ifdef ENABLE_CHECKING
- int i;
+ size_t i;
/* There should be no arguments of this PHI which are in
the partition list, or we get incorrect results. */
- for (i = 0; i < PHI_NUM_ARGS (phi); i++)
+ for (i = 0; i < gimple_phi_num_args (phi); i++)
{
tree arg = PHI_ARG_DEF (phi, i);
if (TREE_CODE (arg) == SSA_NAME
@@ -634,13 +634,15 @@ eliminate_virtual_phis (void)
fprintf (stderr, "Argument of PHI is not virtual (");
print_generic_expr (stderr, arg, TDF_SLIM);
fprintf (stderr, "), but the result is :");
- print_generic_stmt (stderr, phi, TDF_SLIM);
+ print_gimple_stmt (stderr, phi, 0, TDF_SLIM);
internal_error ("SSA corruption");
}
}
#endif
- remove_phi_node (phi, NULL_TREE, true);
+ remove_phi_node (&gsi, true);
}
+ else
+ gsi_next (&gsi);
}
}
}
@@ -653,13 +655,13 @@ eliminate_virtual_phis (void)
variable. */
static void
-rewrite_trees (var_map map, tree *values)
+rewrite_trees (var_map map, gimple *values)
{
elim_graph g;
basic_block bb;
- block_stmt_iterator si;
+ gimple_stmt_iterator gsi;
edge e;
- tree phi;
+ gimple_seq phi;
bool changed;
#ifdef ENABLE_CHECKING
@@ -668,14 +670,14 @@ rewrite_trees (var_map map, tree *values)
create incorrect code. */
FOR_EACH_BB (bb)
{
- tree phi;
- for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
+ for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
- tree T0 = var_to_partition_to_var (map, PHI_RESULT (phi));
+ gimple phi = gsi_stmt (gsi);
+ tree T0 = var_to_partition_to_var (map, gimple_phi_result (phi));
if (T0 == NULL_TREE)
{
- int i;
- for (i = 0; i < PHI_NUM_ARGS (phi); i++)
+ size_t i;
+ for (i = 0; i < gimple_phi_num_args (phi); i++)
{
tree arg = PHI_ARG_DEF (phi, i);
@@ -685,7 +687,7 @@ rewrite_trees (var_map map, tree *values)
fprintf (stderr, "Argument of PHI is in a partition :(");
print_generic_expr (stderr, arg, TDF_SLIM);
fprintf (stderr, "), but the result is not :");
- print_generic_stmt (stderr, phi, TDF_SLIM);
+ print_gimple_stmt (stderr, phi, 0, TDF_SLIM);
internal_error ("SSA corruption");
}
}
@@ -699,21 +701,18 @@ rewrite_trees (var_map map, tree *values)
g->map = map;
FOR_EACH_BB (bb)
{
- for (si = bsi_start (bb); !bsi_end_p (si); )
+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); )
{
- tree stmt = bsi_stmt (si);
+ gimple stmt = gsi_stmt (gsi);
use_operand_p use_p, copy_use_p;
def_operand_p def_p;
bool remove = false, is_copy = false;
int num_uses = 0;
- stmt_ann_t ann;
ssa_op_iter iter;
- ann = stmt_ann (stmt);
changed = false;
- if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT
- && (TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 1)) == SSA_NAME))
+ if (gimple_assign_copy_p (stmt))
is_copy = true;
copy_use_p = NULL_USE_OPERAND_P;
@@ -757,13 +756,13 @@ rewrite_trees (var_map map, tree *values)
/* Remove any stmts marked for removal. */
if (remove)
- bsi_remove (&si, true);
+ gsi_remove (&gsi, true);
else
{
if (changed)
if (maybe_clean_or_replace_eh_stmt (stmt, stmt))
- tree_purge_dead_eh_edges (bb);
- bsi_next (&si);
+ gimple_purge_dead_eh_edges (bb);
+ gsi_next (&gsi);
}
}
@@ -782,7 +781,7 @@ rewrite_trees (var_map map, tree *values)
/* These are the local work structures used to determine the best place to
insert the copies that were placed on edges by the SSA->normal pass.. */
static VEC(edge,heap) *edge_leader;
-static VEC(tree,heap) *stmt_list;
+static VEC(gimple_seq,heap) *stmt_list;
static bitmap leader_has_match = NULL;
static edge leader_match = NULL;
@@ -801,22 +800,19 @@ same_stmt_list_p (edge e)
/* Return TRUE if S1 and S2 are equivalent copies. */
static inline bool
-identical_copies_p (const_tree s1, const_tree s2)
+identical_copies_p (const_gimple s1, const_gimple s2)
{
#ifdef ENABLE_CHECKING
- gcc_assert (TREE_CODE (s1) == GIMPLE_MODIFY_STMT);
- gcc_assert (TREE_CODE (s2) == GIMPLE_MODIFY_STMT);
- gcc_assert (DECL_P (GIMPLE_STMT_OPERAND (s1, 0)));
- gcc_assert (DECL_P (GIMPLE_STMT_OPERAND (s2, 0)));
+ gcc_assert (is_gimple_assign (s1));
+ gcc_assert (is_gimple_assign (s2));
+ gcc_assert (DECL_P (gimple_assign_lhs (s1)));
+ gcc_assert (DECL_P (gimple_assign_lhs (s2)));
#endif
- if (GIMPLE_STMT_OPERAND (s1, 0) != GIMPLE_STMT_OPERAND (s2, 0))
+ if (gimple_assign_lhs (s1) != gimple_assign_lhs (s2))
return false;
- s1 = GIMPLE_STMT_OPERAND (s1, 1);
- s2 = GIMPLE_STMT_OPERAND (s2, 1);
-
- if (s1 != s2)
+ if (gimple_assign_rhs1 (s1) != gimple_assign_rhs1 (s2))
return false;
return true;
@@ -829,22 +825,19 @@ identical_copies_p (const_tree s1, const_tree s2)
static inline bool
identical_stmt_lists_p (const_edge e1, const_edge e2)
{
- tree t1 = PENDING_STMT (e1);
- tree t2 = PENDING_STMT (e2);
- tree_stmt_iterator tsi1, tsi2;
+ gimple_seq t1 = PENDING_STMT (e1);
+ gimple_seq t2 = PENDING_STMT (e2);
+ gimple_stmt_iterator gsi1, gsi2;
- gcc_assert (TREE_CODE (t1) == STATEMENT_LIST);
- gcc_assert (TREE_CODE (t2) == STATEMENT_LIST);
-
- for (tsi1 = tsi_start (t1), tsi2 = tsi_start (t2);
- !tsi_end_p (tsi1) && !tsi_end_p (tsi2);
- tsi_next (&tsi1), tsi_next (&tsi2))
+ for (gsi1 = gsi_start (t1), gsi2 = gsi_start (t2);
+ !gsi_end_p (gsi1) && !gsi_end_p (gsi2);
+ gsi_next (&gsi1), gsi_next (&gsi2))
{
- if (!identical_copies_p (tsi_stmt (tsi1), tsi_stmt (tsi2)))
+ if (!identical_copies_p (gsi_stmt (gsi1), gsi_stmt (gsi2)))
break;
}
- if (!tsi_end_p (tsi1) || ! tsi_end_p (tsi2))
+ if (!gsi_end_p (gsi1) || !gsi_end_p (gsi2))
return false;
return true;
@@ -857,7 +850,7 @@ static void
init_analyze_edges_for_bb (void)
{
edge_leader = VEC_alloc (edge, heap, 25);
- stmt_list = VEC_alloc (tree, heap, 25);
+ stmt_list = VEC_alloc (gimple_seq, heap, 25);
leader_has_match = BITMAP_ALLOC (NULL);
}
@@ -868,7 +861,7 @@ static void
fini_analyze_edges_for_bb (void)
{
VEC_free (edge, heap, edge_leader);
- VEC_free (tree, heap, stmt_list);
+ VEC_free (gimple_seq, heap, stmt_list);
BITMAP_FREE (leader_has_match);
}
@@ -900,13 +893,14 @@ contains_tree_r (tree * tp, int *walk_subtrees, void *data)
static bool
process_single_block_loop_latch (edge single_edge)
{
- tree stmts;
+ gimple_seq stmts;
basic_block b_exit, b_pheader, b_loop = single_edge->src;
edge_iterator ei;
edge e;
- block_stmt_iterator bsi, bsi_exit;
- tree_stmt_iterator tsi;
- tree expr, stmt;
+ gimple_stmt_iterator gsi, gsi_exit;
+ gimple_stmt_iterator tsi;
+ tree expr;
+ gimple stmt;
unsigned int count = 0;
if (single_edge == NULL || (single_edge->dest != single_edge->src)
@@ -939,29 +933,31 @@ process_single_block_loop_latch (edge single_edge)
if (b_exit == b_pheader || b_exit == b_loop || b_pheader == b_loop)
return false;
- bsi_exit = bsi_after_labels (b_exit);
+ gsi_exit = gsi_after_labels (b_exit);
/* Get the last stmt in the loop body. */
- bsi = bsi_last (single_edge->src);
- stmt = bsi_stmt (bsi);
+ gsi = gsi_last_bb (single_edge->src);
+ stmt = gsi_stmt (gsi);
- if (TREE_CODE (stmt) != COND_EXPR)
+ if (gimple_code (stmt) != GIMPLE_COND)
return false;
- expr = COND_EXPR_COND (stmt);
+
+ expr = build2 (gimple_cond_code (stmt), boolean_type_node,
+ gimple_cond_lhs (stmt), gimple_cond_rhs (stmt));
/* Iterate over the insns on the latch and count them. */
- for (tsi = tsi_start (stmts); !tsi_end_p (tsi); tsi_next (&tsi))
+ for (tsi = gsi_start (stmts); !gsi_end_p (tsi); gsi_next (&tsi))
{
- tree stmt1 = tsi_stmt (tsi);
+ gimple stmt1 = gsi_stmt (tsi);
tree var;
count++;
/* Check that the condition does not contain any new definition
created in the latch as the stmts from the latch intended
to precede it. */
- if (TREE_CODE (stmt1) != GIMPLE_MODIFY_STMT)
+ if (gimple_code (stmt1) != GIMPLE_ASSIGN)
return false;
- var = GIMPLE_STMT_OPERAND (stmt1, 0);
+ var = gimple_assign_lhs (stmt1);
if (TREE_THIS_VOLATILE (var)
|| TYPE_VOLATILE (TREE_TYPE (var))
|| walk_tree (&expr, contains_tree_r, var, NULL))
@@ -997,25 +993,26 @@ process_single_block_loop_latch (edge single_edge)
var = tmp_var;
...
*/
- for (tsi = tsi_start (stmts); !tsi_end_p (tsi); tsi_next (&tsi))
+ for (tsi = gsi_start (stmts); !gsi_end_p (tsi); gsi_next (&tsi))
{
- tree stmt1 = tsi_stmt (tsi);
- tree var, tmp_var, copy;
+ gimple stmt1 = gsi_stmt (tsi);
+ tree var, tmp_var;
+ gimple copy;
/* Create a new variable to load back the value of var in case
we exit the loop. */
- var = GIMPLE_STMT_OPERAND (stmt1, 0);
+ var = gimple_assign_lhs (stmt1);
tmp_var = create_temp (var);
- copy = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (tmp_var), tmp_var, var);
+ copy = gimple_build_assign (tmp_var, var);
set_is_used (tmp_var);
- bsi_insert_before (&bsi, copy, BSI_SAME_STMT);
- copy = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (tmp_var), var, tmp_var);
- bsi_insert_before (&bsi_exit, copy, BSI_SAME_STMT);
+ gsi_insert_before (&gsi, copy, GSI_SAME_STMT);
+ copy = gimple_build_assign (var, tmp_var);
+ gsi_insert_before (&gsi_exit, copy, GSI_SAME_STMT);
}
PENDING_STMT (single_edge) = 0;
/* Insert the new stmts to the loop body. */
- bsi_insert_before (&bsi, stmts, BSI_NEW_STMT);
+ gsi_insert_seq_before (&gsi, stmts, GSI_NEW_STMT);
if (dump_file)
fprintf (dump_file,
@@ -1036,8 +1033,8 @@ analyze_edges_for_bb (basic_block bb)
int count;
unsigned int x;
bool have_opportunity;
- block_stmt_iterator bsi;
- tree stmt;
+ gimple_stmt_iterator gsi;
+ gimple stmt;
edge single_edge = NULL;
bool is_label;
edge leader;
@@ -1059,7 +1056,7 @@ analyze_edges_for_bb (basic_block bb)
{
FOR_EACH_EDGE (e, ei, bb->preds)
if (PENDING_STMT (e))
- bsi_commit_one_edge_insert (e, NULL);
+ gsi_commit_one_edge_insert (e, NULL);
return;
}
@@ -1072,18 +1069,19 @@ analyze_edges_for_bb (basic_block bb)
gcc_assert (!(e->flags & EDGE_ABNORMAL));
if (e->flags & EDGE_FALLTHRU)
{
- bsi = bsi_start (e->src);
- if (!bsi_end_p (bsi))
+ gsi = gsi_start_bb (e->src);
+ if (!gsi_end_p (gsi))
{
- stmt = bsi_stmt (bsi);
- bsi_next (&bsi);
- gcc_assert (stmt != NULL_TREE);
- is_label = (TREE_CODE (stmt) == LABEL_EXPR);
+ stmt = gsi_stmt (gsi);
+ gsi_next (&gsi);
+ gcc_assert (stmt != NULL);
+ is_label = (gimple_code (stmt) == GIMPLE_LABEL);
/* Punt if it has non-label stmts, or isn't local. */
- if (!is_label || DECL_NONLOCAL (TREE_OPERAND (stmt, 0))
- || !bsi_end_p (bsi))
+ if (!is_label
+ || DECL_NONLOCAL (gimple_label_label (stmt))
+ || !gsi_end_p (gsi))
{
- bsi_commit_one_edge_insert (e, NULL);
+ gsi_commit_one_edge_insert (e, NULL);
continue;
}
}
@@ -1101,7 +1099,7 @@ analyze_edges_for_bb (basic_block bb)
/* Add stmts to the edge unless processed specially as a
single-block loop latch edge. */
if (!process_single_block_loop_latch (single_edge))
- bsi_commit_one_edge_insert (single_edge, NULL);
+ gsi_commit_one_edge_insert (single_edge, NULL);
}
return;
}
@@ -1109,7 +1107,7 @@ analyze_edges_for_bb (basic_block bb)
/* Ensure that we have empty worklists. */
#ifdef ENABLE_CHECKING
gcc_assert (VEC_length (edge, edge_leader) == 0);
- gcc_assert (VEC_length (tree, stmt_list) == 0);
+ gcc_assert (VEC_length (gimple_seq, stmt_list) == 0);
gcc_assert (bitmap_empty_p (leader_has_match));
#endif
@@ -1142,7 +1140,7 @@ analyze_edges_for_bb (basic_block bb)
if (!found)
{
VEC_safe_push (edge, heap, edge_leader, e);
- VEC_safe_push (tree, heap, stmt_list, PENDING_STMT (e));
+ VEC_safe_push (gimple_seq, heap, stmt_list, PENDING_STMT (e));
}
}
}
@@ -1151,9 +1149,9 @@ analyze_edges_for_bb (basic_block bb)
if (!have_opportunity)
{
for (x = 0; VEC_iterate (edge, edge_leader, x, leader); x++)
- bsi_commit_one_edge_insert (leader, NULL);
+ gsi_commit_one_edge_insert (leader, NULL);
VEC_truncate (edge, edge_leader, 0);
- VEC_truncate (tree, stmt_list, 0);
+ VEC_truncate (gimple_seq, stmt_list, 0);
bitmap_clear (leader_has_match);
return;
}
@@ -1168,8 +1166,8 @@ analyze_edges_for_bb (basic_block bb)
if (bitmap_bit_p (leader_has_match, x))
{
edge new_edge;
- block_stmt_iterator bsi;
- tree curr_stmt_list;
+ gimple_stmt_iterator gsi;
+ gimple_seq curr_stmt_list;
leader_match = leader;
@@ -1179,7 +1177,7 @@ analyze_edges_for_bb (basic_block bb)
and use the saved stmt list. */
PENDING_STMT (leader) = NULL;
leader->aux = leader;
- curr_stmt_list = VEC_index (tree, stmt_list, x);
+ curr_stmt_list = VEC_index (gimple_seq, stmt_list, x);
new_edge = make_forwarder_block (leader->dest, same_stmt_list_p,
NULL);
@@ -1189,7 +1187,7 @@ analyze_edges_for_bb (basic_block bb)
fprintf (dump_file, "Splitting BB %d for Common stmt list. ",
leader->dest->index);
fprintf (dump_file, "Original block is now BB%d.\n", bb->index);
- print_generic_stmt (dump_file, curr_stmt_list, TDF_VOPS);
+ print_gimple_seq (dump_file, curr_stmt_list, 0, TDF_VOPS);
}
FOR_EACH_EDGE (e, ei, new_edge->src->preds)
@@ -1200,22 +1198,22 @@ analyze_edges_for_bb (basic_block bb)
e->src->index, e->dest->index);
}
- bsi = bsi_last (leader->dest);
- bsi_insert_after (&bsi, curr_stmt_list, BSI_NEW_STMT);
+ gsi = gsi_last_bb (leader->dest);
+ gsi_insert_seq_after (&gsi, curr_stmt_list, GSI_NEW_STMT);
leader_match = NULL;
/* We should never get a new block now. */
}
else
{
- PENDING_STMT (leader) = VEC_index (tree, stmt_list, x);
- bsi_commit_one_edge_insert (leader, NULL);
+ PENDING_STMT (leader) = VEC_index (gimple_seq, stmt_list, x);
+ gsi_commit_one_edge_insert (leader, NULL);
}
/* Clear the working data structures. */
VEC_truncate (edge, edge_leader, 0);
- VEC_truncate (tree, stmt_list, 0);
+ VEC_truncate (gimple_seq, stmt_list, 0);
bitmap_clear (leader_has_match);
}
@@ -1295,9 +1293,9 @@ static void
remove_ssa_form (bool perform_ter)
{
basic_block bb;
- tree phi, next;
- tree *values = NULL;
+ gimple *values = NULL;
var_map map;
+ gimple_stmt_iterator gsi;
map = coalesce_ssa_name ();
@@ -1334,13 +1332,8 @@ remove_ssa_form (bool perform_ter)
/* Remove PHI nodes which have been translated back to real variables. */
FOR_EACH_BB (bb)
- {
- for (phi = phi_nodes (bb); phi; phi = next)
- {
- next = PHI_CHAIN (phi);
- remove_phi_node (phi, NULL_TREE, true);
- }
- }
+ for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi);)
+ remove_phi_node (&gsi, true);
/* If any copies were inserted on edges, analyze and insert them now. */
perform_edge_inserts ();
@@ -1362,25 +1355,25 @@ static void
insert_backedge_copies (void)
{
basic_block bb;
+ gimple_stmt_iterator gsi;
FOR_EACH_BB (bb)
{
- tree phi;
-
- for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
+ for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
- tree result = PHI_RESULT (phi);
+ gimple phi = gsi_stmt (gsi);
+ tree result = gimple_phi_result (phi);
tree result_var;
- int i;
+ size_t i;
if (!is_gimple_reg (result))
continue;
result_var = SSA_NAME_VAR (result);
- for (i = 0; i < PHI_NUM_ARGS (phi); i++)
+ for (i = 0; i < gimple_phi_num_args (phi); i++)
{
- tree arg = PHI_ARG_DEF (phi, i);
- edge e = PHI_ARG_EDGE (phi, i);
+ tree arg = gimple_phi_arg_def (phi, i);
+ edge e = gimple_phi_arg_edge (phi, i);
/* If the argument is not an SSA_NAME, then we will need a
constant initialization. If the argument is an SSA_NAME with
@@ -1390,12 +1383,13 @@ insert_backedge_copies (void)
&& (TREE_CODE (arg) != SSA_NAME
|| SSA_NAME_VAR (arg) != result_var))
{
- tree stmt, name, last = NULL;
- block_stmt_iterator bsi;
+ tree name;
+ gimple stmt, last = NULL;
+ gimple_stmt_iterator gsi2;
- bsi = bsi_last (PHI_ARG_EDGE (phi, i)->src);
- if (!bsi_end_p (bsi))
- last = bsi_stmt (bsi);
+ gsi2 = gsi_last_bb (gimple_phi_arg_edge (phi, i)->src);
+ if (!gsi_end_p (gsi2))
+ last = gsi_stmt (gsi2);
/* In theory the only way we ought to get back to the
start of a loop should be with a COND_EXPR or GOTO_EXPR.
@@ -1416,17 +1410,17 @@ insert_backedge_copies (void)
/* Create a new instance of the underlying variable of the
PHI result. */
- stmt = build_gimple_modify_stmt (NULL_TREE,
- PHI_ARG_DEF (phi, i));
+ stmt = gimple_build_assign (result_var,
+ gimple_phi_arg_def (phi, i));
name = make_ssa_name (result_var, stmt);
- GIMPLE_STMT_OPERAND (stmt, 0) = name;
+ gimple_assign_set_lhs (stmt, name);
/* Insert the new statement into the block and update
the PHI node. */
if (last && stmt_ends_bb_p (last))
- bsi_insert_before (&bsi, stmt, BSI_NEW_STMT);
+ gsi_insert_before (&gsi2, stmt, GSI_NEW_STMT);
else
- bsi_insert_after (&bsi, stmt, BSI_NEW_STMT);
+ gsi_insert_after (&gsi2, stmt, GSI_NEW_STMT);
SET_PHI_ARG_DEF (phi, i, name);
}
}
@@ -1452,12 +1446,12 @@ rewrite_out_of_ssa (void)
eliminate_virtual_phis ();
if (dump_file && (dump_flags & TDF_DETAILS))
- dump_tree_cfg (dump_file, dump_flags & ~TDF_DETAILS);
+ gimple_dump_cfg (dump_file, dump_flags & ~TDF_DETAILS);
remove_ssa_form (flag_tree_ter && !flag_mudflap);
if (dump_file && (dump_flags & TDF_DETAILS))
- dump_tree_cfg (dump_file, dump_flags & ~TDF_DETAILS);
+ gimple_dump_cfg (dump_file, dump_flags & ~TDF_DETAILS);
cfun->gimple_df->in_ssa_p = false;
return 0;
diff --git a/gcc/tree-parloops.c b/gcc/tree-parloops.c
index be0fd9cbac4..f2b8d042ef5 100644
--- a/gcc/tree-parloops.c
+++ b/gcc/tree-parloops.c
@@ -41,14 +41,14 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
The implementation is straightforward -- for each loop we test whether its
iterations are independent, and if it is the case (and some additional
conditions regarding profitability and correctness are satisfied), we
- add OMP_PARALLEL and OMP_FOR codes and let omp expansion machinery do
- its job.
+ add GIMPLE_OMP_PARALLEL and GIMPLE_OMP_FOR codes and let omp expansion
+ machinery do its job.
The most of the complexity is in bringing the code into shape expected
by the omp expanders:
- -- for OMP_FOR, ensuring that the loop has only one induction variable
- and that the exit test is at the start of the loop body
- -- for OMP_PARALLEL, replacing the references to local addressable
+ -- for GIMPLE_OMP_FOR, ensuring that the loop has only one induction
+ variable and that the exit test is at the start of the loop body
+ -- for GIMPLE_OMP_PARALLEL, replacing the references to local addressable
variables by accesses through pointers, and breaking up ssa chains
by storing the values incoming to the parallelized loop to a structure
passed to the new function as an argument (something similar is done
@@ -122,11 +122,11 @@ parloop
sum.27_11 = D.1827_8 + sum.27_29;
- OMP_CONTINUE
+ GIMPLE_OMP_CONTINUE
# Adding this reduction phi is done at create_phi_for_local_result() #
# sum.27_56 = PHI <sum.27_11, 0>
- OMP_RETURN
+ GIMPLE_OMP_RETURN
# Creating the atomic operation is done at
create_call_for_reduction_1() #
@@ -136,7 +136,7 @@ parloop
D.1840_60 = sum.27_56 + D.1839_59;
#pragma omp atomic_store (D.1840_60);
- OMP_RETURN
+ GIMPLE_OMP_RETURN
# collecting the result after the join of the threads is done at
create_loads_for_reductions().
@@ -166,15 +166,15 @@ parloop
reduction in the current loop. */
struct reduction_info
{
- tree reduc_stmt; /* reduction statement. */
- tree reduc_phi; /* The phi node defining the reduction. */
- enum tree_code reduction_code; /* code for the reduction operation. */
- tree keep_res; /* The PHI_RESULT of this phi is the resulting value
+ gimple reduc_stmt; /* reduction statement. */
+ gimple reduc_phi; /* The phi node defining the reduction. */
+ enum tree_code reduction_code;/* code for the reduction operation. */
+ gimple keep_res; /* The PHI_RESULT of this phi is the resulting value
of the reduction variable when existing the loop. */
tree initial_value; /* The initial value of the reduction var before entering the loop. */
tree field; /* the name of the field in the parloop data structure intended for reduction. */
tree init; /* reduction initialization value. */
- tree new_phi; /* (helper field) Newly created phi node whose result
+ gimple new_phi; /* (helper field) Newly created phi node whose result
will be passed to the atomic operation. Represents
the local result each thread computed for the reduction
operation. */
@@ -200,7 +200,7 @@ reduction_info_hash (const void *aa)
}
static struct reduction_info *
-reduction_phi (htab_t reduction_list, tree phi)
+reduction_phi (htab_t reduction_list, gimple phi)
{
struct reduction_info tmpred, *red;
@@ -249,14 +249,15 @@ name_to_copy_elt_hash (const void *aa)
reductions are found, they are inserted to the REDUCTION_LIST. */
static bool
-loop_parallel_p (struct loop *loop, htab_t reduction_list, struct tree_niter_desc *niter)
+loop_parallel_p (struct loop *loop, htab_t reduction_list,
+ struct tree_niter_desc *niter)
{
edge exit = single_dom_exit (loop);
VEC (ddr_p, heap) * dependence_relations;
- VEC (data_reference_p, heap) * datarefs;
+ VEC (data_reference_p, heap) *datarefs;
lambda_trans_matrix trans;
bool ret = false;
- tree phi;
+ gimple_stmt_iterator gsi;
loop_vec_info simple_loop_info;
/* Only consider innermost loops with just one exit. The innermost-loop
@@ -279,9 +280,10 @@ loop_parallel_p (struct loop *loop, htab_t reduction_list, struct tree_niter_des
simple_loop_info = vect_analyze_loop_form (loop);
- for (phi = phi_nodes (loop->header); phi; phi = PHI_CHAIN (phi))
+ for (gsi = gsi_start_phis (loop->header); !gsi_end_p (gsi); gsi_next (&gsi))
{
- tree reduc_stmt = NULL, operation;
+ gimple phi = gsi_stmt (gsi);
+ gimple reduc_stmt = NULL;
/* ??? TODO: Change this into a generic function that
recognizes reductions. */
@@ -302,7 +304,7 @@ loop_parallel_p (struct loop *loop, htab_t reduction_list, struct tree_niter_des
{
fprintf (dump_file,
"Detected reduction. reduction stmt is: \n");
- print_generic_stmt (dump_file, reduc_stmt, 0);
+ print_gimple_stmt (dump_file, reduc_stmt, 0, 0);
fprintf (dump_file, "\n");
}
@@ -310,8 +312,7 @@ loop_parallel_p (struct loop *loop, htab_t reduction_list, struct tree_niter_des
new_reduction->reduc_stmt = reduc_stmt;
new_reduction->reduc_phi = phi;
- operation = GIMPLE_STMT_OPERAND (reduc_stmt, 1);
- new_reduction->reduction_code = TREE_CODE (operation);
+ new_reduction->reduction_code = gimple_assign_rhs_code (reduc_stmt);
slot = htab_find_slot (reduction_list, new_reduction, INSERT);
*slot = new_reduction;
}
@@ -320,13 +321,13 @@ loop_parallel_p (struct loop *loop, htab_t reduction_list, struct tree_niter_des
/* Get rid of the information created by the vectorizer functions. */
destroy_loop_vec_info (simple_loop_info, true);
- for (phi = phi_nodes (exit->dest); phi; phi = PHI_CHAIN (phi))
+ for (gsi = gsi_start_phis (exit->dest); !gsi_end_p (gsi); gsi_next (&gsi))
{
+ gimple phi = gsi_stmt (gsi);
struct reduction_info *red;
imm_use_iterator imm_iter;
use_operand_p use_p;
- tree reduc_phi;
-
+ gimple reduc_phi;
tree val = PHI_ARG_DEF_FROM_EDGE (phi, exit);
if (is_gimple_reg (val))
@@ -334,7 +335,7 @@ loop_parallel_p (struct loop *loop, htab_t reduction_list, struct tree_niter_des
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "phi is ");
- print_generic_expr (dump_file, phi, 0);
+ print_gimple_stmt (dump_file, phi, 0, 0);
fprintf (dump_file, "arg of phi to exit: value ");
print_generic_expr (dump_file, val, 0);
fprintf (dump_file, " used outside loop\n");
@@ -351,7 +352,7 @@ loop_parallel_p (struct loop *loop, htab_t reduction_list, struct tree_niter_des
reduc_phi = NULL;
FOR_EACH_IMM_USE_FAST (use_p, imm_iter, val)
{
- if (flow_bb_inside_loop_p (loop, bb_for_stmt (USE_STMT (use_p))))
+ if (flow_bb_inside_loop_p (loop, gimple_bb (USE_STMT (use_p))))
{
reduc_phi = USE_STMT (use_p);
break;
@@ -368,9 +369,9 @@ loop_parallel_p (struct loop *loop, htab_t reduction_list, struct tree_niter_des
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "reduction phi is ");
- print_generic_expr (dump_file, red->reduc_phi, 0);
+ print_gimple_stmt (dump_file, red->reduc_phi, 0, 0);
fprintf (dump_file, "reduction stmt is ");
- print_generic_expr (dump_file, red->reduc_stmt, 0);
+ print_gimple_stmt (dump_file, red->reduc_stmt, 0, 0);
}
}
@@ -378,8 +379,9 @@ loop_parallel_p (struct loop *loop, htab_t reduction_list, struct tree_niter_des
/* The iterations of the loop may communicate only through bivs whose
iteration space can be distributed efficiently. */
- for (phi = phi_nodes (loop->header); phi; phi = PHI_CHAIN (phi))
+ for (gsi = gsi_start_phis (loop->header); !gsi_end_p (gsi); gsi_next (&gsi))
{
+ gimple phi = gsi_stmt (gsi);
tree def = PHI_RESULT (phi);
affine_iv iv;
@@ -465,7 +467,9 @@ take_address_of (tree obj, tree type, edge entry, htab_t decl_address)
int uid;
void **dslot;
struct int_tree_map ielt, *nielt;
- tree *var_p, name, bvar, stmt, addr;
+ tree *var_p, name, bvar, addr;
+ gimple stmt;
+ gimple_seq stmts;
/* Since the address of OBJ is invariant, the trees may be shared.
Avoid rewriting unrelated parts of the code. */
@@ -483,10 +487,10 @@ take_address_of (tree obj, tree type, edge entry, htab_t decl_address)
addr = build_addr (*var_p, current_function_decl);
bvar = create_tmp_var (TREE_TYPE (addr), get_name (*var_p));
add_referenced_var (bvar);
- stmt = build_gimple_modify_stmt (bvar, addr);
+ stmt = gimple_build_assign (bvar, addr);
name = make_ssa_name (bvar, stmt);
- GIMPLE_STMT_OPERAND (stmt, 0) = name;
- bsi_insert_on_edge_immediate (entry, stmt);
+ gimple_assign_set_lhs (stmt, name);
+ gsi_insert_on_edge_immediate (entry, stmt);
nielt = XNEW (struct int_tree_map);
nielt->uid = uid;
@@ -500,17 +504,17 @@ take_address_of (tree obj, tree type, edge entry, htab_t decl_address)
{
*var_p = build1 (INDIRECT_REF, TREE_TYPE (*var_p), name);
name = force_gimple_operand (build_addr (obj, current_function_decl),
- &stmt, true, NULL_TREE);
- if (stmt)
- bsi_insert_on_edge_immediate (entry, stmt);
+ &stmts, true, NULL_TREE);
+ if (!gimple_seq_empty_p (stmts))
+ gsi_insert_seq_on_edge_immediate (entry, stmts);
}
if (TREE_TYPE (name) != type)
{
- name = force_gimple_operand (fold_convert (type, name), &stmt, true,
+ name = force_gimple_operand (fold_convert (type, name), &stmts, true,
NULL_TREE);
- if (stmt)
- bsi_insert_on_edge_immediate (entry, stmt);
+ if (!gimple_seq_empty_p (stmts))
+ gsi_insert_seq_on_edge_immediate (entry, stmts);
}
return name;
@@ -543,8 +547,7 @@ initialize_reductions (void **slot, void *data)
c = build_omp_clause (OMP_CLAUSE_REDUCTION);
OMP_CLAUSE_REDUCTION_CODE (c) = reduc->reduction_code;
- OMP_CLAUSE_DECL (c) =
- SSA_NAME_VAR (GIMPLE_STMT_OPERAND (reduc->reduc_stmt, 0));
+ OMP_CLAUSE_DECL (c) = SSA_NAME_VAR (gimple_assign_lhs (reduc->reduc_stmt));
init = omp_reduction_init (c, TREE_TYPE (bvar));
reduc->init = init;
@@ -569,6 +572,7 @@ initialize_reductions (void **slot, void *data)
struct elv_data
{
+ struct walk_stmt_info info;
edge entry;
htab_t decl_address;
bool changed;
@@ -632,7 +636,7 @@ eliminate_local_variables_1 (tree *tp, int *walk_subtrees, void *data)
return NULL_TREE;
}
- if (!EXPR_P (t) && !GIMPLE_STMT_P (t))
+ if (!EXPR_P (t))
*walk_subtrees = 0;
return NULL_TREE;
@@ -644,16 +648,17 @@ eliminate_local_variables_1 (tree *tp, int *walk_subtrees, void *data)
already. */
static void
-eliminate_local_variables_stmt (edge entry, tree stmt,
+eliminate_local_variables_stmt (edge entry, gimple stmt,
htab_t decl_address)
{
struct elv_data dta;
+ memset (&dta.info, '\0', sizeof (dta.info));
dta.entry = entry;
dta.decl_address = decl_address;
dta.changed = false;
- walk_tree (&stmt, eliminate_local_variables_1, &dta, NULL);
+ walk_gimple_op (stmt, eliminate_local_variables_1, &dta.info);
if (dta.changed)
update_stmt (stmt);
@@ -676,7 +681,7 @@ eliminate_local_variables (edge entry, edge exit)
basic_block bb;
VEC (basic_block, heap) *body = VEC_alloc (basic_block, heap, 3);
unsigned i;
- block_stmt_iterator bsi;
+ gimple_stmt_iterator gsi;
htab_t decl_address = htab_create (10, int_tree_map_hash, int_tree_map_eq,
free);
basic_block entry_bb = entry->src;
@@ -686,8 +691,8 @@ eliminate_local_variables (edge entry, edge exit)
for (i = 0; VEC_iterate (basic_block, body, i, bb); i++)
if (bb != entry_bb && bb != exit_bb)
- for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
- eliminate_local_variables_stmt (entry, bsi_stmt (bsi),
+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+ eliminate_local_variables_stmt (entry, gsi_stmt (gsi),
decl_address);
htab_delete (decl_address);
@@ -703,14 +708,13 @@ expr_invariant_in_region_p (edge entry, edge exit, tree expr)
basic_block entry_bb = entry->src;
basic_block exit_bb = exit->dest;
basic_block def_bb;
- unsigned i, len;
if (is_gimple_min_invariant (expr))
return true;
if (TREE_CODE (expr) == SSA_NAME)
{
- def_bb = bb_for_stmt (SSA_NAME_DEF_STMT (expr));
+ def_bb = gimple_bb (SSA_NAME_DEF_STMT (expr));
if (def_bb
&& dominated_by_p (CDI_DOMINATORS, def_bb, entry_bb)
&& !dominated_by_p (CDI_DOMINATORS, def_bb, exit_bb))
@@ -719,15 +723,7 @@ expr_invariant_in_region_p (edge entry, edge exit, tree expr)
return true;
}
- if (!EXPR_P (expr) && !GIMPLE_STMT_P (expr))
- return false;
-
- len = TREE_OPERAND_LENGTH (expr);
- for (i = 0; i < len; i++)
- if (!expr_invariant_in_region_p (entry, exit, TREE_OPERAND (expr, i)))
- return false;
-
- return true;
+ return false;
}
/* If COPY_NAME_P is true, creates and returns a duplicate of NAME.
@@ -788,7 +784,7 @@ separate_decls_in_region_name (tree name,
if (copy_name_p)
{
- copy = duplicate_ssa_name (name, NULL_TREE);
+ copy = duplicate_ssa_name (name, NULL);
nelt = XNEW (struct name_to_copy_elt);
nelt->version = idx;
nelt->new_name = copy;
@@ -813,7 +809,7 @@ separate_decls_in_region_name (tree name,
replacement decls are stored in DECL_COPIES. */
static void
-separate_decls_in_region_stmt (edge entry, edge exit, tree stmt,
+separate_decls_in_region_stmt (edge entry, edge exit, gimple stmt,
htab_t name_copies, htab_t decl_copies)
{
use_operand_p use;
@@ -855,7 +851,7 @@ add_field_for_reduction (void **slot, void *data)
struct reduction_info *const red = (struct reduction_info *) *slot;
tree const type = (tree) data;
- tree var = SSA_NAME_VAR (GIMPLE_STMT_OPERAND (red->reduc_stmt, 0));
+ tree var = SSA_NAME_VAR (gimple_assign_lhs (red->reduc_stmt));
tree field = build_decl (FIELD_DECL, DECL_NAME (var), TREE_TYPE (var));
insert_field_into_struct (type, field);
@@ -896,13 +892,13 @@ create_phi_for_local_result (void **slot, void *data)
struct reduction_info *const reduc = (struct reduction_info *) *slot;
const struct loop *const loop = (const struct loop *) data;
edge e;
- tree new_phi;
+ gimple new_phi;
basic_block store_bb;
tree local_res;
/* STORE_BB is the block where the phi
should be stored. It is the destination of the loop exit.
- (Find the fallthru edge from OMP_CONTINUE). */
+ (Find the fallthru edge from GIMPLE_OMP_CONTINUE). */
store_bb = FALLTHRU_EDGE (loop->latch)->dest;
/* STORE_BB has two predecessors. One coming from the loop
@@ -914,11 +910,13 @@ create_phi_for_local_result (void **slot, void *data)
e = EDGE_PRED (store_bb, 1);
else
e = EDGE_PRED (store_bb, 0);
- local_res = make_ssa_name (SSA_NAME_VAR (GIMPLE_STMT_OPERAND (reduc->reduc_stmt, 0)), NULL_TREE);
+ local_res
+ = make_ssa_name (SSA_NAME_VAR (gimple_assign_lhs (reduc->reduc_stmt)),
+ NULL);
new_phi = create_phi_node (local_res, store_bb);
SSA_NAME_DEF_STMT (local_res) = new_phi;
add_phi_arg (new_phi, reduc->init, e);
- add_phi_arg (new_phi, GIMPLE_STMT_OPERAND (reduc->reduc_stmt, 0),
+ add_phi_arg (new_phi, gimple_assign_lhs (reduc->reduc_stmt),
FALLTHRU_EDGE (loop->latch));
reduc->new_phi = new_phi;
@@ -944,7 +942,7 @@ create_call_for_reduction_1 (void **slot, void *data)
{
struct reduction_info *const reduc = (struct reduction_info *) *slot;
struct clsn_data *const clsn_data = (struct clsn_data *) data;
- block_stmt_iterator bsi;
+ gimple_stmt_iterator gsi;
tree type = TREE_TYPE (PHI_RESULT (reduc->reduc_phi));
tree struct_type = TREE_TYPE (TREE_TYPE (clsn_data->load));
tree load_struct;
@@ -952,7 +950,8 @@ create_call_for_reduction_1 (void **slot, void *data)
basic_block new_bb;
edge e;
tree t, addr, addr_type, ref, x;
- tree tmp_load, load, name;
+ tree tmp_load, name;
+ gimple load;
load_struct = fold_build1 (INDIRECT_REF, struct_type, clsn_data->load);
t = build3 (COMPONENT_REF, type, load_struct, reduc->field, NULL_TREE);
@@ -969,27 +968,23 @@ create_call_for_reduction_1 (void **slot, void *data)
tmp_load = create_tmp_var (TREE_TYPE (TREE_TYPE (addr)), NULL);
add_referenced_var (tmp_load);
tmp_load = make_ssa_name (tmp_load, NULL);
- load = build2 (OMP_ATOMIC_LOAD, void_type_node, tmp_load, addr);
+ load = gimple_build_omp_atomic_load (tmp_load, addr);
SSA_NAME_DEF_STMT (tmp_load) = load;
- bsi = bsi_start (new_bb);
- bsi_insert_after (&bsi, load, BSI_NEW_STMT);
+ gsi = gsi_start_bb (new_bb);
+ gsi_insert_after (&gsi, load, GSI_NEW_STMT);
e = split_block (new_bb, load);
new_bb = e->dest;
- bsi = bsi_start (new_bb);
+ gsi = gsi_start_bb (new_bb);
ref = tmp_load;
- x =
- fold_build2 (reduc->reduction_code,
- TREE_TYPE (PHI_RESULT (reduc->new_phi)), ref,
- PHI_RESULT (reduc->new_phi));
-
- name =
- force_gimple_operand_bsi (&bsi, x, true, NULL_TREE, true,
- BSI_CONTINUE_LINKING);
+ x = fold_build2 (reduc->reduction_code,
+ TREE_TYPE (PHI_RESULT (reduc->new_phi)), ref,
+ PHI_RESULT (reduc->new_phi));
- x = build1 (OMP_ATOMIC_STORE, void_type_node, name);
+ name = force_gimple_operand_gsi (&gsi, x, true, NULL_TREE, true,
+ GSI_CONTINUE_LINKING);
- bsi_insert_after (&bsi, x, BSI_NEW_STMT);
+ gsi_insert_after (&gsi, gimple_build_omp_atomic_store (name), GSI_NEW_STMT);
return 1;
}
@@ -1002,7 +997,7 @@ create_call_for_reduction (struct loop *loop, htab_t reduction_list,
struct clsn_data *ld_st_data)
{
htab_traverse (reduction_list, create_phi_for_local_result, loop);
- /* Find the fallthru edge from OMP_CONTINUE. */
+ /* Find the fallthru edge from GIMPLE_OMP_CONTINUE. */
ld_st_data->load_bb = FALLTHRU_EDGE (loop->latch)->dest;
htab_traverse (reduction_list, create_call_for_reduction_1, ld_st_data);
}
@@ -1015,30 +1010,34 @@ create_loads_for_reductions (void **slot, void *data)
{
struct reduction_info *const red = (struct reduction_info *) *slot;
struct clsn_data *const clsn_data = (struct clsn_data *) data;
- tree stmt;
- block_stmt_iterator bsi;
- tree type = TREE_TYPE (GIMPLE_STMT_OPERAND (red->reduc_stmt, 0));
+ gimple stmt;
+ gimple_stmt_iterator gsi;
+ tree type = TREE_TYPE (gimple_assign_lhs (red->reduc_stmt));
tree struct_type = TREE_TYPE (TREE_TYPE (clsn_data->load));
tree load_struct;
tree name;
tree x;
- bsi = bsi_after_labels (clsn_data->load_bb);
+ gsi = gsi_after_labels (clsn_data->load_bb);
load_struct = fold_build1 (INDIRECT_REF, struct_type, clsn_data->load);
load_struct = build3 (COMPONENT_REF, type, load_struct, red->field,
NULL_TREE);
x = load_struct;
name = PHI_RESULT (red->keep_res);
- stmt = build_gimple_modify_stmt (name, x);
- GIMPLE_STMT_OPERAND (stmt, 0) = name;
+ stmt = gimple_build_assign (name, x);
SSA_NAME_DEF_STMT (name) = stmt;
- bsi_insert_after (&bsi, stmt, BSI_NEW_STMT);
+ gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
- remove_phi_node (red->keep_res, NULL_TREE, false);
-
- return 1;
+ for (gsi = gsi_start_phis (gimple_bb (red->keep_res));
+ !gsi_end_p (gsi); gsi_next (&gsi))
+ if (gsi_stmt (gsi) == red->keep_res)
+ {
+ remove_phi_node (&gsi, false);
+ return 1;
+ }
+ gcc_unreachable ();
}
/* Load the reduction result that was stored in LD_ST_DATA.
@@ -1048,18 +1047,16 @@ static void
create_final_loads_for_reduction (htab_t reduction_list,
struct clsn_data *ld_st_data)
{
- block_stmt_iterator bsi;
+ gimple_stmt_iterator gsi;
tree t;
+ gimple stmt;
- bsi = bsi_after_labels (ld_st_data->load_bb);
+ gsi = gsi_after_labels (ld_st_data->load_bb);
t = build_fold_addr_expr (ld_st_data->store);
- t =
- build_gimple_modify_stmt (ld_st_data->load,
- build_fold_addr_expr (ld_st_data->store));
+ stmt = gimple_build_assign (ld_st_data->load, t);
- bsi_insert_before (&bsi, t, BSI_NEW_STMT);
- SSA_NAME_DEF_STMT (ld_st_data->load) = t;
- GIMPLE_STMT_OPERAND (t, 0) = ld_st_data->load;
+ gsi_insert_before (&gsi, stmt, GSI_NEW_STMT);
+ SSA_NAME_DEF_STMT (ld_st_data->load) = stmt;
htab_traverse (reduction_list, create_loads_for_reductions, ld_st_data);
@@ -1076,18 +1073,16 @@ create_stores_for_reduction (void **slot, void *data)
{
struct reduction_info *const red = (struct reduction_info *) *slot;
struct clsn_data *const clsn_data = (struct clsn_data *) data;
- tree stmt;
- block_stmt_iterator bsi;
- tree type = TREE_TYPE (GIMPLE_STMT_OPERAND (red->reduc_stmt, 0));
-
- bsi = bsi_last (clsn_data->store_bb);
- stmt =
- build_gimple_modify_stmt (build3
- (COMPONENT_REF, type, clsn_data->store,
- red->field, NULL_TREE),
- red->initial_value);
+ tree t;
+ gimple stmt;
+ gimple_stmt_iterator gsi;
+ tree type = TREE_TYPE (gimple_assign_lhs (red->reduc_stmt));
+
+ gsi = gsi_last_bb (clsn_data->store_bb);
+ t = build3 (COMPONENT_REF, type, clsn_data->store, red->field, NULL_TREE);
+ stmt = gimple_build_assign (t, red->initial_value);
mark_virtual_ops_for_renaming (stmt);
- bsi_insert_after (&bsi, stmt, BSI_NEW_STMT);
+ gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
return 1;
}
@@ -1101,28 +1096,25 @@ create_loads_and_stores_for_name (void **slot, void *data)
{
struct name_to_copy_elt *const elt = (struct name_to_copy_elt *) *slot;
struct clsn_data *const clsn_data = (struct clsn_data *) data;
- tree stmt;
- block_stmt_iterator bsi;
+ tree t;
+ gimple stmt;
+ gimple_stmt_iterator gsi;
tree type = TREE_TYPE (elt->new_name);
tree struct_type = TREE_TYPE (TREE_TYPE (clsn_data->load));
tree load_struct;
- bsi = bsi_last (clsn_data->store_bb);
- stmt =
- build_gimple_modify_stmt (build3
- (COMPONENT_REF, type, clsn_data->store,
- elt->field, NULL_TREE),
- ssa_name (elt->version));
+ gsi = gsi_last_bb (clsn_data->store_bb);
+ t = build3 (COMPONENT_REF, type, clsn_data->store, elt->field, NULL_TREE);
+ stmt = gimple_build_assign (t, ssa_name (elt->version));
mark_virtual_ops_for_renaming (stmt);
- bsi_insert_after (&bsi, stmt, BSI_NEW_STMT);
+ gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
- bsi = bsi_last (clsn_data->load_bb);
+ gsi = gsi_last_bb (clsn_data->load_bb);
load_struct = fold_build1 (INDIRECT_REF, struct_type, clsn_data->load);
- stmt = build_gimple_modify_stmt (elt->new_name,
- build3 (COMPONENT_REF, type, load_struct,
- elt->field, NULL_TREE));
+ t = build3 (COMPONENT_REF, type, load_struct, elt->field, NULL_TREE);
+ stmt = gimple_build_assign (elt->new_name, t);
SSA_NAME_DEF_STMT (elt->new_name) = stmt;
- bsi_insert_after (&bsi, stmt, BSI_NEW_STMT);
+ gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
return 1;
}
@@ -1174,27 +1166,27 @@ separate_decls_in_region (edge entry, edge exit, htab_t reduction_list,
htab_t decl_copies = htab_create (10, int_tree_map_hash, int_tree_map_eq,
free);
unsigned i;
- tree phi, type, type_name, nvar;
- block_stmt_iterator bsi;
+ tree type, type_name, nvar;
+ gimple_stmt_iterator gsi;
struct clsn_data clsn_data;
VEC (basic_block, heap) *body = VEC_alloc (basic_block, heap, 3);
basic_block bb;
basic_block entry_bb = bb1;
basic_block exit_bb = exit->dest;
- entry = single_succ_edge(entry_bb);
+ entry = single_succ_edge (entry_bb);
gather_blocks_in_sese_region (entry_bb, exit_bb, &body);
for (i = 0; VEC_iterate (basic_block, body, i, bb); i++)
{
if (bb != entry_bb && bb != exit_bb)
{
- for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
- separate_decls_in_region_stmt (entry, exit, phi, name_copies,
- decl_copies);
-
- for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
- separate_decls_in_region_stmt (entry, exit, bsi_stmt (bsi),
+ for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+ separate_decls_in_region_stmt (entry, exit, gsi_stmt (gsi),
+ name_copies, decl_copies);
+
+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+ separate_decls_in_region_stmt (entry, exit, gsi_stmt (gsi),
name_copies, decl_copies);
}
}
@@ -1230,7 +1222,7 @@ separate_decls_in_region (edge entry, edge exit, htab_t reduction_list,
add_referenced_var (*arg_struct);
nvar = create_tmp_var (build_pointer_type (type), ".paral_data_load");
add_referenced_var (nvar);
- *new_arg_struct = make_ssa_name (nvar, NULL_TREE);
+ *new_arg_struct = make_ssa_name (nvar, NULL);
ld_st_data->store = *arg_struct;
ld_st_data->load = *new_arg_struct;
@@ -1246,7 +1238,7 @@ separate_decls_in_region (edge entry, edge exit, htab_t reduction_list,
{
htab_traverse (reduction_list, create_stores_for_reduction,
ld_st_data);
- clsn_data.load = make_ssa_name (nvar, NULL_TREE);
+ clsn_data.load = make_ssa_name (nvar, NULL);
clsn_data.load_bb = exit->dest;
clsn_data.store = ld_st_data->store;
create_final_loads_for_reduction (reduction_list, &clsn_data);
@@ -1338,15 +1330,18 @@ static void
canonicalize_loop_ivs (struct loop *loop, htab_t reduction_list, tree nit)
{
unsigned precision = TYPE_PRECISION (TREE_TYPE (nit));
- tree phi, prev, res, type, var_before, val, atype, mtype, t, next;
- block_stmt_iterator bsi;
+ tree res, type, var_before, val, atype, mtype;
+ gimple_stmt_iterator gsi, psi;
+ gimple phi, stmt;
bool ok;
affine_iv iv;
edge exit = single_dom_exit (loop);
struct reduction_info *red;
- for (phi = phi_nodes (loop->header); phi; phi = PHI_CHAIN (phi))
+ for (psi = gsi_start_phis (loop->header);
+ !gsi_end_p (psi); gsi_next (&psi))
{
+ phi = gsi_stmt (psi);
res = PHI_RESULT (phi);
if (is_gimple_reg (res) && TYPE_PRECISION (TREE_TYPE (res)) > precision)
@@ -1355,20 +1350,19 @@ canonicalize_loop_ivs (struct loop *loop, htab_t reduction_list, tree nit)
type = lang_hooks.types.type_for_size (precision, 1);
- bsi = bsi_last (loop->latch);
+ gsi = gsi_last_bb (loop->latch);
create_iv (build_int_cst_type (type, 0), build_int_cst (type, 1), NULL_TREE,
- loop, &bsi, true, &var_before, NULL);
+ loop, &gsi, true, &var_before, NULL);
- bsi = bsi_after_labels (loop->header);
- prev = NULL;
- for (phi = phi_nodes (loop->header); phi; phi = next)
+ gsi = gsi_after_labels (loop->header);
+ for (psi = gsi_start_phis (loop->header); !gsi_end_p (psi); )
{
- next = PHI_CHAIN (phi);
+ phi = gsi_stmt (psi);
res = PHI_RESULT (phi);
if (!is_gimple_reg (res) || res == var_before)
{
- prev = phi;
+ gsi_next (&psi);
continue;
}
@@ -1377,12 +1371,12 @@ canonicalize_loop_ivs (struct loop *loop, htab_t reduction_list, tree nit)
/* We preserve the reduction phi nodes. */
if (!ok && red)
{
- prev = phi;
+ gsi_next (&psi);
continue;
}
else
gcc_assert (ok);
- remove_phi_node (phi, prev, false);
+ remove_phi_node (&psi, false);
atype = TREE_TYPE (res);
mtype = POINTER_TYPE_P (atype) ? sizetype : atype;
@@ -1391,14 +1385,14 @@ canonicalize_loop_ivs (struct loop *loop, htab_t reduction_list, tree nit)
val = fold_build2 (POINTER_TYPE_P (atype)
? POINTER_PLUS_EXPR : PLUS_EXPR,
atype, unshare_expr (iv.base), val);
- val = force_gimple_operand_bsi (&bsi, val, false, NULL_TREE, true,
- BSI_SAME_STMT);
- t = build_gimple_modify_stmt (res, val);
- bsi_insert_before (&bsi, t, BSI_SAME_STMT);
- SSA_NAME_DEF_STMT (res) = t;
+ val = force_gimple_operand_gsi (&gsi, val, false, NULL_TREE, true,
+ GSI_SAME_STMT);
+ stmt = gimple_build_assign (res, val);
+ gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
+ SSA_NAME_DEF_STMT (res) = stmt;
}
- t = last_stmt (exit->src);
+ stmt = last_stmt (exit->src);
/* Make the loop exit if the control condition is not satisfied. */
if (exit->flags & EDGE_TRUE_VALUE)
{
@@ -1408,7 +1402,9 @@ canonicalize_loop_ivs (struct loop *loop, htab_t reduction_list, tree nit)
te->flags = EDGE_FALSE_VALUE;
fe->flags = EDGE_TRUE_VALUE;
}
- COND_EXPR_COND (t) = build2 (LT_EXPR, boolean_type_node, var_before, nit);
+ gimple_cond_set_code (stmt, LT_EXPR);
+ gimple_cond_set_lhs (stmt, var_before);
+ gimple_cond_set_rhs (stmt, nit);
}
/* Moves the exit condition of LOOP to the beginning of its header, and
@@ -1430,22 +1426,23 @@ transform_to_exit_first_loop (struct loop *loop, htab_t reduction_list, tree nit
unsigned n;
bool ok;
edge exit = single_dom_exit (loop), hpred;
- tree phi, nphi, cond, control, control_name, res, t, cond_stmt;
- block_stmt_iterator bsi;
+ tree control, control_name, res, t;
+ gimple phi, nphi, cond_stmt, stmt;
+ gimple_stmt_iterator gsi;
split_block_after_labels (loop->header);
orig_header = single_succ (loop->header);
hpred = single_succ_edge (loop->header);
cond_stmt = last_stmt (exit->src);
- cond = COND_EXPR_COND (cond_stmt);
- control = TREE_OPERAND (cond, 0);
- gcc_assert (TREE_OPERAND (cond, 1) == nit);
+ control = gimple_cond_lhs (cond_stmt);
+ gcc_assert (gimple_cond_rhs (cond_stmt) == nit);
/* Make sure that we have phi nodes on exit for all loop header phis
(create_parallel_loop requires that). */
- for (phi = phi_nodes (loop->header); phi; phi = PHI_CHAIN (phi))
+ for (gsi = gsi_start_phis (loop->header); !gsi_end_p (gsi); gsi_next (&gsi))
{
+ phi = gsi_stmt (gsi);
res = PHI_RESULT (phi);
t = make_ssa_name (SSA_NAME_VAR (res), phi);
SET_PHI_RESULT (phi, t);
@@ -1456,7 +1453,7 @@ transform_to_exit_first_loop (struct loop *loop, htab_t reduction_list, tree nit
if (res == control)
{
- TREE_OPERAND (cond, 0) = t;
+ gimple_cond_set_lhs (cond_stmt, t);
update_stmt (cond_stmt);
control = t;
}
@@ -1466,22 +1463,26 @@ transform_to_exit_first_loop (struct loop *loop, htab_t reduction_list, tree nit
for (n = 0; bbs[n] != exit->src; n++)
continue;
nbbs = XNEWVEC (basic_block, n);
- ok = tree_duplicate_sese_tail (single_succ_edge (loop->header), exit,
- bbs + 1, n, nbbs);
+ ok = gimple_duplicate_sese_tail (single_succ_edge (loop->header), exit,
+ bbs + 1, n, nbbs);
gcc_assert (ok);
free (bbs);
ex_bb = nbbs[0];
free (nbbs);
/* Other than reductions, the only gimple reg that should be copied
- out of the loop is the control variable. */
+ out of the loop is the control variable. */
control_name = NULL_TREE;
- for (phi = phi_nodes (ex_bb); phi; phi = PHI_CHAIN (phi))
+ for (gsi = gsi_start_phis (ex_bb); !gsi_end_p (gsi); )
{
+ phi = gsi_stmt (gsi);
res = PHI_RESULT (phi);
if (!is_gimple_reg (res))
- continue;
+ {
+ gsi_next (&gsi);
+ continue;
+ }
/* Check if it is a part of reduction. If it is,
keep the phi at the reduction's keep_res field. The
@@ -1498,93 +1499,95 @@ transform_to_exit_first_loop (struct loop *loop, htab_t reduction_list, tree nit
red = reduction_phi (reduction_list, SSA_NAME_DEF_STMT (val));
if (red)
- red->keep_res = phi;
+ {
+ red->keep_res = phi;
+ gsi_next (&gsi);
+ continue;
+ }
}
- else
- gcc_assert (control_name == NULL_TREE
- && SSA_NAME_VAR (res) == SSA_NAME_VAR (control));
+ gcc_assert (control_name == NULL_TREE
+ && SSA_NAME_VAR (res) == SSA_NAME_VAR (control));
control_name = res;
+ remove_phi_node (&gsi, false);
}
gcc_assert (control_name != NULL_TREE);
- phi = SSA_NAME_DEF_STMT (control_name);
- remove_phi_node (phi, NULL_TREE, false);
/* Initialize the control variable to NIT. */
- bsi = bsi_after_labels (ex_bb);
- nit = force_gimple_operand_bsi (&bsi,
+ gsi = gsi_after_labels (ex_bb);
+ nit = force_gimple_operand_gsi (&gsi,
fold_convert (TREE_TYPE (control_name), nit),
- false, NULL_TREE, false, BSI_SAME_STMT);
- t = build_gimple_modify_stmt (control_name, nit);
- bsi_insert_before (&bsi, t, BSI_NEW_STMT);
- SSA_NAME_DEF_STMT (control_name) = t;
+ false, NULL_TREE, false, GSI_SAME_STMT);
+ stmt = gimple_build_assign (control_name, nit);
+ gsi_insert_before (&gsi, stmt, GSI_NEW_STMT);
+ SSA_NAME_DEF_STMT (control_name) = stmt;
}
/* Create the parallel constructs for LOOP as described in gen_parallel_loop.
- LOOP_FN and DATA are the arguments of OMP_PARALLEL.
+ LOOP_FN and DATA are the arguments of GIMPLE_OMP_PARALLEL.
NEW_DATA is the variable that should be initialized from the argument
of LOOP_FN. N_THREADS is the requested number of threads. Returns the
- basic block containing OMP_PARALLEL tree. */
+ basic block containing GIMPLE_OMP_PARALLEL tree. */
static basic_block
create_parallel_loop (struct loop *loop, tree loop_fn, tree data,
tree new_data, unsigned n_threads)
{
- block_stmt_iterator bsi;
+ gimple_stmt_iterator gsi;
basic_block bb, paral_bb, for_bb, ex_bb;
- tree t, param, res, for_stmt;
- tree cvar, cvar_init, initvar, cvar_next, cvar_base, cond, phi, type;
+ tree t, param, res;
+ gimple stmt, for_stmt, phi, cond_stmt;
+ tree cvar, cvar_init, initvar, cvar_next, cvar_base, type;
edge exit, nexit, guard, end, e;
- /* Prepare the OMP_PARALLEL statement. */
+ /* Prepare the GIMPLE_OMP_PARALLEL statement. */
bb = loop_preheader_edge (loop)->src;
paral_bb = single_pred (bb);
- bsi = bsi_last (paral_bb);
+ gsi = gsi_last_bb (paral_bb);
t = build_omp_clause (OMP_CLAUSE_NUM_THREADS);
OMP_CLAUSE_NUM_THREADS_EXPR (t)
= build_int_cst (integer_type_node, n_threads);
- t = build4 (OMP_PARALLEL, void_type_node, NULL_TREE, t, loop_fn, data);
+ stmt = gimple_build_omp_parallel (NULL, t, loop_fn, data);
- bsi_insert_after (&bsi, t, BSI_NEW_STMT);
+ gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
/* Initialize NEW_DATA. */
if (data)
{
- bsi = bsi_after_labels (bb);
-
- param = make_ssa_name (DECL_ARGUMENTS (loop_fn), NULL_TREE);
- t = build_gimple_modify_stmt (param, build_fold_addr_expr (data));
- bsi_insert_before (&bsi, t, BSI_SAME_STMT);
- SSA_NAME_DEF_STMT (param) = t;
-
- t = build_gimple_modify_stmt (new_data,
- fold_convert (TREE_TYPE (new_data),
- param));
- bsi_insert_before (&bsi, t, BSI_SAME_STMT);
- SSA_NAME_DEF_STMT (new_data) = t;
+ gsi = gsi_after_labels (bb);
+
+ param = make_ssa_name (DECL_ARGUMENTS (loop_fn), NULL);
+ stmt = gimple_build_assign (param, build_fold_addr_expr (data));
+ gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
+ SSA_NAME_DEF_STMT (param) = stmt;
+
+ stmt = gimple_build_assign (new_data,
+ fold_convert (TREE_TYPE (new_data), param));
+ gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
+ SSA_NAME_DEF_STMT (new_data) = stmt;
}
- /* Emit OMP_RETURN for OMP_PARALLEL. */
+ /* Emit GIMPLE_OMP_RETURN for GIMPLE_OMP_PARALLEL. */
bb = split_loop_exit_edge (single_dom_exit (loop));
- bsi = bsi_last (bb);
- bsi_insert_after (&bsi, make_node (OMP_RETURN), BSI_NEW_STMT);
+ gsi = gsi_last_bb (bb);
+ gsi_insert_after (&gsi, gimple_build_omp_return (false), GSI_NEW_STMT);
- /* Extract data for OMP_FOR. */
+ /* Extract data for GIMPLE_OMP_FOR. */
gcc_assert (loop->header == single_dom_exit (loop)->src);
- cond = COND_EXPR_COND (last_stmt (loop->header));
+ cond_stmt = last_stmt (loop->header);
- cvar = TREE_OPERAND (cond, 0);
+ cvar = gimple_cond_lhs (cond_stmt);
cvar_base = SSA_NAME_VAR (cvar);
phi = SSA_NAME_DEF_STMT (cvar);
cvar_init = PHI_ARG_DEF_FROM_EDGE (phi, loop_preheader_edge (loop));
- initvar = make_ssa_name (cvar_base, NULL_TREE);
+ initvar = make_ssa_name (cvar_base, NULL);
SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (phi, loop_preheader_edge (loop)),
initvar);
cvar_next = PHI_ARG_DEF_FROM_EDGE (phi, loop_latch_edge (loop));
- bsi = bsi_last (loop->latch);
- gcc_assert (bsi_stmt (bsi) == SSA_NAME_DEF_STMT (cvar_next));
- bsi_remove (&bsi, true);
+ gsi = gsi_last_bb (loop->latch);
+ gcc_assert (gsi_stmt (gsi) == SSA_NAME_DEF_STMT (cvar_next));
+ gsi_remove (&gsi, true);
/* Prepare cfg. */
for_bb = split_edge (loop_preheader_edge (loop));
@@ -1595,56 +1598,48 @@ create_parallel_loop (struct loop *loop, tree loop_fn, tree data,
guard = make_edge (for_bb, ex_bb, 0);
single_succ_edge (loop->latch)->flags = 0;
end = make_edge (loop->latch, ex_bb, EDGE_FALLTHRU);
- for (phi = phi_nodes (ex_bb); phi; phi = PHI_CHAIN (phi))
+ for (gsi = gsi_start_phis (ex_bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
+ phi = gsi_stmt (gsi);
res = PHI_RESULT (phi);
- gcc_assert (!is_gimple_reg (phi));
- t = SSA_NAME_DEF_STMT (PHI_ARG_DEF_FROM_EDGE (phi, exit));
- add_phi_arg (phi, PHI_ARG_DEF_FROM_EDGE (t, loop_preheader_edge (loop)),
+ stmt = SSA_NAME_DEF_STMT (PHI_ARG_DEF_FROM_EDGE (phi, exit));
+ add_phi_arg (phi,
+ PHI_ARG_DEF_FROM_EDGE (stmt, loop_preheader_edge (loop)),
guard);
- add_phi_arg (phi, PHI_ARG_DEF_FROM_EDGE (t, loop_latch_edge (loop)),
+ add_phi_arg (phi, PHI_ARG_DEF_FROM_EDGE (stmt, loop_latch_edge (loop)),
end);
}
e = redirect_edge_and_branch (exit, nexit->dest);
PENDING_STMT (e) = NULL;
- /* Emit OMP_FOR. */
- TREE_OPERAND (cond, 0) = cvar_base;
+ /* Emit GIMPLE_OMP_FOR. */
+ gimple_cond_set_lhs (cond_stmt, cvar_base);
type = TREE_TYPE (cvar);
t = build_omp_clause (OMP_CLAUSE_SCHEDULE);
OMP_CLAUSE_SCHEDULE_KIND (t) = OMP_CLAUSE_SCHEDULE_STATIC;
- for_stmt = make_node (OMP_FOR);
- TREE_TYPE (for_stmt) = void_type_node;
- OMP_FOR_CLAUSES (for_stmt) = t;
- OMP_FOR_INIT (for_stmt) = make_tree_vec (1);
- TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), 0)
- = build_gimple_modify_stmt (initvar, cvar_init);
- OMP_FOR_COND (for_stmt) = make_tree_vec (1);
- TREE_VEC_ELT (OMP_FOR_COND (for_stmt), 0) = cond;
- OMP_FOR_INCR (for_stmt) = make_tree_vec (2);
- TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), 0)
- = build_gimple_modify_stmt (cvar_base,
- build2 (PLUS_EXPR, type, cvar_base,
- build_int_cst (type, 1)));
- OMP_FOR_BODY (for_stmt) = NULL_TREE;
- OMP_FOR_PRE_BODY (for_stmt) = NULL_TREE;
-
- bsi = bsi_last (for_bb);
- bsi_insert_after (&bsi, for_stmt, BSI_NEW_STMT);
+ for_stmt = gimple_build_omp_for (NULL, t, 1, NULL);
+ gimple_omp_for_set_index (for_stmt, 0, initvar);
+ gimple_omp_for_set_initial (for_stmt, 0, cvar_init);
+ gimple_omp_for_set_final (for_stmt, 0, gimple_cond_rhs (cond_stmt));
+ gimple_omp_for_set_cond (for_stmt, 0, gimple_cond_code (cond_stmt));
+ gimple_omp_for_set_incr (for_stmt, 0, build2 (PLUS_EXPR, type,
+ cvar_base,
+ build_int_cst (type, 1)));
+
+ gsi = gsi_last_bb (for_bb);
+ gsi_insert_after (&gsi, for_stmt, GSI_NEW_STMT);
SSA_NAME_DEF_STMT (initvar) = for_stmt;
- /* Emit OMP_CONTINUE. */
- bsi = bsi_last (loop->latch);
- t = build2 (OMP_CONTINUE, void_type_node, cvar_next, cvar);
- bsi_insert_after (&bsi, t, BSI_NEW_STMT);
- SSA_NAME_DEF_STMT (cvar_next) = t;
+ /* Emit GIMPLE_OMP_CONTINUE. */
+ gsi = gsi_last_bb (loop->latch);
+ stmt = gimple_build_omp_continue (cvar_next, cvar);
+ gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
+ SSA_NAME_DEF_STMT (cvar_next) = stmt;
- /* Emit OMP_RETURN for OMP_FOR. */
- bsi = bsi_last (ex_bb);
- t = make_node (OMP_RETURN);
- OMP_RETURN_NOWAIT (t) = 1;
- bsi_insert_after (&bsi, t, BSI_NEW_STMT);
+ /* Emit GIMPLE_OMP_RETURN for GIMPLE_OMP_FOR. */
+ gsi = gsi_last_bb (ex_bb);
+ gsi_insert_after (&gsi, gimple_build_omp_return (true), GSI_NEW_STMT);
return paral_bb;
}
@@ -1660,7 +1655,8 @@ gen_parallel_loop (struct loop *loop, htab_t reduction_list,
struct loop *nloop;
loop_iterator li;
tree many_iterations_cond, type, nit;
- tree stmts, arg_struct, new_arg_struct;
+ tree arg_struct, new_arg_struct;
+ gimple_seq stmts;
basic_block parallel_head;
edge entry, exit;
struct clsn_data clsn_data;
@@ -1690,14 +1686,14 @@ gen_parallel_loop (struct loop *loop, htab_t reduction_list,
BODY1;
store all local loop-invariant variables used in body of the loop to DATA.
- OMP_PARALLEL (OMP_CLAUSE_NUM_THREADS (N_THREADS), LOOPFN, DATA);
+ GIMPLE_OMP_PARALLEL (OMP_CLAUSE_NUM_THREADS (N_THREADS), LOOPFN, DATA);
load the variables from DATA.
- OMP_FOR (IV = INIT; COND; IV += STEP) (OMP_CLAUSE_SCHEDULE (static))
+ GIMPLE_OMP_FOR (IV = INIT; COND; IV += STEP) (OMP_CLAUSE_SCHEDULE (static))
BODY2;
BODY1;
- OMP_CONTINUE;
- OMP_RETURN -- OMP_FOR
- OMP_RETURN -- OMP_PARALLEL
+ GIMPLE_OMP_CONTINUE;
+ GIMPLE_OMP_RETURN -- GIMPLE_OMP_FOR
+ GIMPLE_OMP_RETURN -- GIMPLE_OMP_PARALLEL
goto end;
original:
@@ -1723,7 +1719,7 @@ gen_parallel_loop (struct loop *loop, htab_t reduction_list,
nit = force_gimple_operand (unshare_expr (niter->niter), &stmts, true,
NULL_TREE);
if (stmts)
- bsi_insert_on_edge_immediate (loop_preheader_edge (loop), stmts);
+ gsi_insert_seq_on_edge_immediate (loop_preheader_edge (loop), stmts);
many_iterations_cond =
fold_build2 (GE_EXPR, boolean_type_node,
@@ -1735,14 +1731,14 @@ gen_parallel_loop (struct loop *loop, htab_t reduction_list,
many_iterations_cond
= force_gimple_operand (many_iterations_cond, &stmts, false, NULL_TREE);
if (stmts)
- bsi_insert_on_edge_immediate (loop_preheader_edge (loop), stmts);
+ gsi_insert_seq_on_edge_immediate (loop_preheader_edge (loop), stmts);
if (!is_gimple_condexpr (many_iterations_cond))
{
many_iterations_cond
= force_gimple_operand (many_iterations_cond, &stmts,
true, NULL_TREE);
if (stmts)
- bsi_insert_on_edge_immediate (loop_preheader_edge (loop), stmts);
+ gsi_insert_seq_on_edge_immediate (loop_preheader_edge (loop), stmts);
}
initialize_original_copy_tables ();
@@ -1803,16 +1799,16 @@ gen_parallel_loop (struct loop *loop, htab_t reduction_list,
/* Returns true when LOOP contains vector phi nodes. */
static bool
-loop_has_vector_phi_nodes (struct loop *loop)
+loop_has_vector_phi_nodes (struct loop *loop ATTRIBUTE_UNUSED)
{
unsigned i;
basic_block *bbs = get_loop_body_in_dom_order (loop);
+ gimple_stmt_iterator gsi;
bool res = true;
- tree phi;
for (i = 0; i < loop->num_nodes; i++)
- for (phi = phi_nodes (bbs[i]); phi; phi = PHI_CHAIN (phi))
- if (TREE_CODE (TREE_TYPE (PHI_RESULT (phi))) == VECTOR_TYPE)
+ for (gsi = gsi_start_phis (bbs[i]); !gsi_end_p (gsi); gsi_next (&gsi))
+ if (TREE_CODE (TREE_TYPE (PHI_RESULT (gsi_stmt (gsi)))) == VECTOR_TYPE)
goto end;
res = false;
@@ -1841,6 +1837,7 @@ parallelize_loops (void)
reduction_list = htab_create (10, reduction_info_hash,
reduction_info_eq, free);
+ init_stmt_vec_info_vec ();
FOR_EACH_LOOP (li, loop, 0)
{
@@ -1865,6 +1862,7 @@ parallelize_loops (void)
verify_loop_closed_ssa ();
}
+ free_stmt_vec_info_vec ();
htab_delete (reduction_list);
return changed;
}
diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h
index aca2b56decb..50bd40d1b1d 100644
--- a/gcc/tree-pass.h
+++ b/gcc/tree-pass.h
@@ -72,7 +72,9 @@ enum tree_dump_index
#define TDF_DIAGNOSTIC (1 << 15) /* A dump to be put in a diagnostic
message. */
#define TDF_VERBOSE (1 << 16) /* A dump that uses the full tree
- dumper to print stmts. */
+ dumper to print stmts. */
+#define TDF_RHS_ONLY (1 << 17) /* a flag to only print the RHS of
+ a gimple stmt. */
extern char *get_dump_file_name (enum tree_dump_index);
extern int dump_enabled_p (enum tree_dump_index);
@@ -505,7 +507,6 @@ extern struct rtl_opt_pass pass_final;
extern struct rtl_opt_pass pass_rtl_seqabstr;
extern struct gimple_opt_pass pass_release_ssa_names;
extern struct gimple_opt_pass pass_early_inline;
-extern struct gimple_opt_pass pass_O0_always_inline;
extern struct gimple_opt_pass pass_inline_parameters;
extern struct gimple_opt_pass pass_all_early_optimizations;
extern struct gimple_opt_pass pass_update_address_taken;
diff --git a/gcc/tree-phinodes.c b/gcc/tree-phinodes.c
index 9d20b0e64c9..511e84bf9b9 100644
--- a/gcc/tree-phinodes.c
+++ b/gcc/tree-phinodes.c
@@ -28,6 +28,7 @@ along with GCC; see the file COPYING3. If not see
#include "basic-block.h"
#include "tree-flow.h"
#include "toplev.h"
+#include "gimple.h"
/* Rewriting a function into SSA form can create a huge number of PHIs
many of which may be thrown away shortly after their creation if jumps
@@ -76,11 +77,10 @@ along with GCC; see the file COPYING3. If not see
the -2 on all the calculations below. */
#define NUM_BUCKETS 10
-static GTY ((deletable (""))) tree free_phinodes[NUM_BUCKETS - 2];
+static GTY ((deletable (""))) VEC(gimple,gc) *free_phinodes[NUM_BUCKETS - 2];
static unsigned long free_phinode_count;
static int ideal_phi_node_len (int);
-static void resize_phi_node (tree *, int);
#ifdef GATHER_STATISTICS
unsigned int phi_nodes_reused;
@@ -126,13 +126,13 @@ phinodes_print_statistics (void)
happens to contain a PHI node with LEN arguments or more, return
that one. */
-static inline tree
-allocate_phi_node (int len)
+static inline gimple
+allocate_phi_node (size_t len)
{
- tree phi;
- int bucket = NUM_BUCKETS - 2;
- int size = (sizeof (struct tree_phi_node)
- + (len - 1) * sizeof (struct phi_arg_d));
+ gimple phi;
+ size_t bucket = NUM_BUCKETS - 2;
+ size_t size = sizeof (struct gimple_statement_phi)
+ + (len - 1) * sizeof (struct phi_arg_d);
if (free_phinode_count)
for (bucket = len - 2; bucket < NUM_BUCKETS - 2; bucket++)
@@ -141,22 +141,27 @@ allocate_phi_node (int len)
/* If our free list has an element, then use it. */
if (bucket < NUM_BUCKETS - 2
- && PHI_ARG_CAPACITY (free_phinodes[bucket]) >= len)
+ && gimple_phi_capacity (VEC_index (gimple, free_phinodes[bucket], 0))
+ >= len)
{
free_phinode_count--;
- phi = free_phinodes[bucket];
- free_phinodes[bucket] = PHI_CHAIN (free_phinodes[bucket]);
+ phi = VEC_pop (gimple, free_phinodes[bucket]);
+ if (VEC_empty (gimple, free_phinodes[bucket]))
+ VEC_free (gimple, gc, free_phinodes[bucket]);
#ifdef GATHER_STATISTICS
phi_nodes_reused++;
#endif
}
else
{
- phi = (tree) ggc_alloc (size);
+ phi = (gimple) ggc_alloc (size);
#ifdef GATHER_STATISTICS
phi_nodes_created++;
- tree_node_counts[(int) phi_kind]++;
- tree_node_sizes[(int) phi_kind] += size;
+ {
+ enum gimple_alloc_kind kind = gimple_alloc_kind (GIMPLE_PHI);
+ gimple_alloc_counts[(int) kind]++;
+ gimple_alloc_sizes[(int) kind] += size;
+ }
#endif
}
@@ -184,7 +189,8 @@ ideal_phi_node_len (int len)
len = 2;
/* Compute the number of bytes of the original request. */
- size = sizeof (struct tree_phi_node) + (len - 1) * sizeof (struct phi_arg_d);
+ size = sizeof (struct gimple_statement_phi)
+ + (len - 1) * sizeof (struct phi_arg_d);
/* Round it up to the next power of two. */
log2 = ceil_log2 (size);
@@ -199,10 +205,10 @@ ideal_phi_node_len (int len)
/* Return a PHI node with LEN argument slots for variable VAR. */
-static tree
+static gimple
make_phi_node (tree var, int len)
{
- tree phi;
+ gimple phi;
int capacity, i;
capacity = ideal_phi_node_len (len);
@@ -212,24 +218,25 @@ make_phi_node (tree var, int len)
/* We need to clear the entire PHI node, including the argument
portion, because we represent a "missing PHI argument" by placing
NULL_TREE in PHI_ARG_DEF. */
- memset (phi, 0, (sizeof (struct tree_phi_node) - sizeof (struct phi_arg_d)
+ memset (phi, 0, (sizeof (struct gimple_statement_phi)
+ - sizeof (struct phi_arg_d)
+ sizeof (struct phi_arg_d) * len));
- TREE_SET_CODE (phi, PHI_NODE);
- PHI_NUM_ARGS (phi) = len;
- PHI_ARG_CAPACITY (phi) = capacity;
+ phi->gsbase.code = GIMPLE_PHI;
+ phi->gimple_phi.nargs = len;
+ phi->gimple_phi.capacity = capacity;
if (TREE_CODE (var) == SSA_NAME)
- SET_PHI_RESULT (phi, var);
+ gimple_phi_set_result (phi, var);
else
- SET_PHI_RESULT (phi, make_ssa_name (var, phi));
+ gimple_phi_set_result (phi, make_ssa_name (var, phi));
for (i = 0; i < capacity; i++)
{
use_operand_p imm;
- imm = &(PHI_ARG_IMM_USE_NODE (phi, i));
- imm->use = &(PHI_ARG_DEF_TREE (phi, i));
+ imm = gimple_phi_arg_imm_use_ptr (phi, i);
+ imm->use = gimple_phi_arg_def_ptr (phi, i);
imm->prev = NULL;
imm->next = NULL;
- imm->stmt = phi;
+ imm->loc.stmt = phi;
}
return phi;
@@ -238,66 +245,66 @@ make_phi_node (tree var, int len)
/* We no longer need PHI, release it so that it may be reused. */
void
-release_phi_node (tree phi)
+release_phi_node (gimple phi)
{
- int bucket;
- int len = PHI_ARG_CAPACITY (phi);
- int x;
+ size_t bucket;
+ size_t len = gimple_phi_capacity (phi);
+ size_t x;
- for (x = 0; x < PHI_NUM_ARGS (phi); x++)
+ for (x = 0; x < gimple_phi_num_args (phi); x++)
{
use_operand_p imm;
- imm = &(PHI_ARG_IMM_USE_NODE (phi, x));
+ imm = gimple_phi_arg_imm_use_ptr (phi, x);
delink_imm_use (imm);
}
bucket = len > NUM_BUCKETS - 1 ? NUM_BUCKETS - 1 : len;
bucket -= 2;
- PHI_CHAIN (phi) = free_phinodes[bucket];
- free_phinodes[bucket] = phi;
+ VEC_safe_push (gimple, gc, free_phinodes[bucket], phi);
free_phinode_count++;
}
+
/* Resize an existing PHI node. The only way is up. Return the
possibly relocated phi. */
static void
-resize_phi_node (tree *phi, int len)
+resize_phi_node (gimple *phi, size_t len)
{
- int old_size, i;
- tree new_phi;
+ size_t old_size, i;
+ gimple new_phi;
- gcc_assert (len > PHI_ARG_CAPACITY (*phi));
+ gcc_assert (len > gimple_phi_capacity (*phi));
/* The garbage collector will not look at the PHI node beyond the
first PHI_NUM_ARGS elements. Therefore, all we have to copy is a
portion of the PHI node currently in use. */
- old_size = (sizeof (struct tree_phi_node)
- + (PHI_NUM_ARGS (*phi) - 1) * sizeof (struct phi_arg_d));
+ old_size = sizeof (struct gimple_statement_phi)
+ + (gimple_phi_num_args (*phi) - 1) * sizeof (struct phi_arg_d);
new_phi = allocate_phi_node (len);
memcpy (new_phi, *phi, old_size);
- for (i = 0; i < PHI_NUM_ARGS (new_phi); i++)
+ for (i = 0; i < gimple_phi_num_args (new_phi); i++)
{
use_operand_p imm, old_imm;
- imm = &(PHI_ARG_IMM_USE_NODE (new_phi, i));
- old_imm = &(PHI_ARG_IMM_USE_NODE (*phi, i));
- imm->use = &(PHI_ARG_DEF_TREE (new_phi, i));
+ imm = gimple_phi_arg_imm_use_ptr (new_phi, i);
+ old_imm = gimple_phi_arg_imm_use_ptr (*phi, i);
+ imm->use = gimple_phi_arg_def_ptr (new_phi, i);
relink_imm_use_stmt (imm, old_imm, new_phi);
}
- PHI_ARG_CAPACITY (new_phi) = len;
+ new_phi->gimple_phi.capacity = len;
- for (i = PHI_NUM_ARGS (new_phi); i < len; i++)
+ for (i = gimple_phi_num_args (new_phi); i < len; i++)
{
use_operand_p imm;
- imm = &(PHI_ARG_IMM_USE_NODE (new_phi, i));
- imm->use = &(PHI_ARG_DEF_TREE (new_phi, i));
+ imm = gimple_phi_arg_imm_use_ptr (new_phi, i);
+ imm->use = gimple_phi_arg_def_ptr (new_phi, i);
imm->prev = NULL;
imm->next = NULL;
- imm->stmt = new_phi;
+ imm->loc.stmt = new_phi;
}
*phi = new_phi;
@@ -308,22 +315,22 @@ resize_phi_node (tree *phi, int len)
void
reserve_phi_args_for_new_edge (basic_block bb)
{
- tree *loc;
- int len = EDGE_COUNT (bb->preds);
- int cap = ideal_phi_node_len (len + 4);
+ size_t len = EDGE_COUNT (bb->preds);
+ size_t cap = ideal_phi_node_len (len + 4);
+ gimple_stmt_iterator gsi;
- for (loc = phi_nodes_ptr (bb);
- *loc;
- loc = &PHI_CHAIN (*loc))
+ for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
- if (len > PHI_ARG_CAPACITY (*loc))
+ gimple *loc = gsi_stmt_ptr (&gsi);
+
+ if (len > gimple_phi_capacity (*loc))
{
- tree old_phi = *loc;
+ gimple old_phi = *loc;
resize_phi_node (loc, cap);
- /* The result of the phi is defined by this phi node. */
- SSA_NAME_DEF_STMT (PHI_RESULT (*loc)) = *loc;
+ /* The result of the PHI is defined by this PHI node. */
+ SSA_NAME_DEF_STMT (gimple_phi_result (*loc)) = *loc;
release_phi_node (old_phi);
}
@@ -337,26 +344,28 @@ reserve_phi_args_for_new_edge (basic_block bb)
batch. */
SET_PHI_ARG_DEF (*loc, len - 1, NULL_TREE);
- PHI_NUM_ARGS (*loc)++;
+ (*loc)->gimple_phi.nargs++;
}
}
/* Create a new PHI node for variable VAR at basic block BB. */
-tree
+gimple
create_phi_node (tree var, basic_block bb)
{
- tree phi;
-
- phi = make_phi_node (var, EDGE_COUNT (bb->preds));
+ gimple_stmt_iterator gsi;
+ gimple phi = make_phi_node (var, EDGE_COUNT (bb->preds));
/* Add the new PHI node to the list of PHI nodes for block BB. */
- PHI_CHAIN (phi) = phi_nodes (bb);
- set_phi_nodes (bb, phi);
+ if (phi_nodes (bb) == NULL)
+ set_phi_nodes (bb, gimple_seq_alloc ());
+
+ gsi = gsi_last (phi_nodes (bb));
+ gsi_insert_after (&gsi, phi, GSI_NEW_STMT);
/* Associate BB to the PHI node. */
- set_bb_for_stmt (phi, bb);
+ gimple_set_bb (phi, bb);
return phi;
}
@@ -369,19 +378,19 @@ create_phi_node (tree var, basic_block bb)
PHI points to the reallocated phi node when we return. */
void
-add_phi_arg (tree phi, tree def, edge e)
+add_phi_arg (gimple phi, tree def, edge e)
{
basic_block bb = e->dest;
- gcc_assert (bb == bb_for_stmt (phi));
+ gcc_assert (bb == gimple_bb (phi));
/* We resize PHI nodes upon edge creation. We should always have
enough room at this point. */
- gcc_assert (PHI_NUM_ARGS (phi) <= PHI_ARG_CAPACITY (phi));
+ gcc_assert (gimple_phi_num_args (phi) <= gimple_phi_capacity (phi));
/* We resize PHI nodes upon edge creation. We should always have
enough room at this point. */
- gcc_assert (e->dest_idx < (unsigned int) PHI_NUM_ARGS (phi));
+ gcc_assert (e->dest_idx < gimple_phi_num_args (phi));
/* Copy propagation needs to know what object occur in abnormal
PHI nodes. This is a convenient place to record such information. */
@@ -401,22 +410,22 @@ add_phi_arg (tree phi, tree def, edge e)
is consistent with how we remove an edge from the edge vector. */
static void
-remove_phi_arg_num (tree phi, int i)
+remove_phi_arg_num (gimple phi, int i)
{
- int num_elem = PHI_NUM_ARGS (phi);
+ int num_elem = gimple_phi_num_args (phi);
gcc_assert (i < num_elem);
/* Delink the item which is being removed. */
- delink_imm_use (&(PHI_ARG_IMM_USE_NODE (phi, i)));
+ delink_imm_use (gimple_phi_arg_imm_use_ptr (phi, i));
/* If it is not the last element, move the last element
to the element we want to delete, resetting all the links. */
if (i != num_elem - 1)
{
use_operand_p old_p, new_p;
- old_p = &PHI_ARG_IMM_USE_NODE (phi, num_elem - 1);
- new_p = &PHI_ARG_IMM_USE_NODE (phi, i);
+ old_p = gimple_phi_arg_imm_use_ptr (phi, num_elem - 1);
+ new_p = gimple_phi_arg_imm_use_ptr (phi, i);
/* Set use on new node, and link into last element's place. */
*(new_p->use) = *(old_p->use);
relink_imm_use (new_p, old_p);
@@ -425,7 +434,7 @@ remove_phi_arg_num (tree phi, int i)
/* Shrink the vector and return. Note that we do not have to clear
PHI_ARG_DEF because the garbage collector will not look at those
elements beyond the first PHI_NUM_ARGS elements of the array. */
- PHI_NUM_ARGS (phi)--;
+ phi->gimple_phi.nargs--;
}
@@ -434,60 +443,29 @@ remove_phi_arg_num (tree phi, int i)
void
remove_phi_args (edge e)
{
- tree phi;
+ gimple_stmt_iterator gsi;
- for (phi = phi_nodes (e->dest); phi; phi = PHI_CHAIN (phi))
- remove_phi_arg_num (phi, e->dest_idx);
+ for (gsi = gsi_start_phis (e->dest); !gsi_end_p (gsi); gsi_next (&gsi))
+ remove_phi_arg_num (gsi_stmt (gsi), e->dest_idx);
}
-/* Remove PHI node PHI from basic block BB. If PREV is non-NULL, it is
- used as the node immediately before PHI in the linked list. If
- RELEASE_LHS_P is true, the LHS of this PHI node is released into
- the free pool of SSA names. */
+/* Remove the PHI node pointed-to by iterator GSI from basic block BB. After
+ removal, iterator GSI is updated to point to the next PHI node in the
+ sequence. If RELEASE_LHS_P is true, the LHS of this PHI node is released
+ into the free pool of SSA names. */
void
-remove_phi_node (tree phi, tree prev, bool release_lhs_p)
+remove_phi_node (gimple_stmt_iterator *gsi, bool release_lhs_p)
{
- tree *loc;
-
- if (prev)
- {
- loc = &PHI_CHAIN (prev);
- }
- else
- {
- for (loc = phi_nodes_ptr (bb_for_stmt (phi));
- *loc != phi;
- loc = &PHI_CHAIN (*loc))
- ;
- }
-
- /* Remove PHI from the chain. */
- *loc = PHI_CHAIN (phi);
+ gimple phi = gsi_stmt (*gsi);
+ gsi_remove (gsi, false);
/* If we are deleting the PHI node, then we should release the
SSA_NAME node so that it can be reused. */
release_phi_node (phi);
if (release_lhs_p)
- release_ssa_name (PHI_RESULT (phi));
-}
-
-
-/* Reverse the order of PHI nodes in the chain PHI.
- Return the new head of the chain (old last PHI node). */
-
-tree
-phi_reverse (tree phi)
-{
- tree prev = NULL_TREE, next;
- for (; phi; phi = next)
- {
- next = PHI_CHAIN (phi);
- PHI_CHAIN (phi) = prev;
- prev = phi;
- }
- return prev;
+ release_ssa_name (gimple_phi_result (phi));
}
#include "gt-tree-phinodes.h"
diff --git a/gcc/tree-predcom.c b/gcc/tree-predcom.c
index 32d7fbe00ca..63911b3dbe5 100644
--- a/gcc/tree-predcom.c
+++ b/gcc/tree-predcom.c
@@ -207,7 +207,8 @@ along with GCC; see the file COPYING3. If not see
#define MAX_DISTANCE (target_avail_regs < 16 ? 4 : 8)
-/* Data references. */
+/* Data references (or phi nodes that carry data reference values across
+ loop iterations). */
typedef struct dref
{
@@ -215,7 +216,12 @@ typedef struct dref
struct data_reference *ref;
/* The statement in that the reference appears. */
- tree stmt;
+ gimple stmt;
+
+ /* In case that STMT is a phi node, this field is set to the SSA name
+ defined by it in replace_phis_by_defined_names (in order to avoid
+ pointing to phi node that got reallocated in the meantime). */
+ tree name_defined_by_phi;
/* Distance of the reference from the root of the chain (in number of
iterations of the loop). */
@@ -349,12 +355,12 @@ dump_dref (FILE *file, dref ref)
}
else
{
- if (TREE_CODE (ref->stmt) == PHI_NODE)
+ if (gimple_code (ref->stmt) == GIMPLE_PHI)
fprintf (file, " looparound ref\n");
else
fprintf (file, " combination ref\n");
fprintf (file, " in statement ");
- print_generic_expr (file, ref->stmt, TDF_SLIM);
+ print_gimple_stmt (file, ref->stmt, 0, TDF_SLIM);
fprintf (file, "\n");
fprintf (file, " distance %u\n", ref->distance);
}
@@ -777,7 +783,7 @@ split_data_refs_to_components (struct loop *loop,
dataref->always_accessed
= dominated_by_p (CDI_DOMINATORS, last_always_executed,
- bb_for_stmt (dataref->stmt));
+ gimple_bb (dataref->stmt));
dataref->pos = VEC_length (dref, comp->refs);
VEC_quick_push (dref, comp->refs, dataref);
}
@@ -813,7 +819,7 @@ suitable_component_p (struct loop *loop, struct component *comp)
for (i = 0; VEC_iterate (dref, comp->refs, i, a); i++)
{
- ba = bb_for_stmt (a->stmt);
+ ba = gimple_bb (a->stmt);
if (!just_once_each_iteration_p (loop, ba))
return false;
@@ -989,12 +995,12 @@ name_for_ref (dref ref)
{
tree name;
- if (TREE_CODE (ref->stmt) == GIMPLE_MODIFY_STMT)
+ if (is_gimple_assign (ref->stmt))
{
if (!ref->ref || DR_IS_READ (ref->ref))
- name = GIMPLE_STMT_OPERAND (ref->stmt, 0);
+ name = gimple_assign_lhs (ref->stmt);
else
- name = GIMPLE_STMT_OPERAND (ref->stmt, 1);
+ name = gimple_assign_rhs1 (ref->stmt);
}
else
name = PHI_RESULT (ref->stmt);
@@ -1052,44 +1058,49 @@ valid_initializer_p (struct data_reference *ref,
iteration), returns the phi node. Otherwise, NULL_TREE is returned. ROOT
is the root of the current chain. */
-static tree
+static gimple
find_looparound_phi (struct loop *loop, dref ref, dref root)
{
- tree name, phi, init, init_stmt, init_ref;
+ tree name, init, init_ref;
+ gimple phi = NULL, init_stmt;
edge latch = loop_latch_edge (loop);
struct data_reference init_dr;
+ gimple_stmt_iterator psi;
- if (TREE_CODE (ref->stmt) == GIMPLE_MODIFY_STMT)
+ if (is_gimple_assign (ref->stmt))
{
if (DR_IS_READ (ref->ref))
- name = GIMPLE_STMT_OPERAND (ref->stmt, 0);
+ name = gimple_assign_lhs (ref->stmt);
else
- name = GIMPLE_STMT_OPERAND (ref->stmt, 1);
+ name = gimple_assign_rhs1 (ref->stmt);
}
else
name = PHI_RESULT (ref->stmt);
if (!name)
- return NULL_TREE;
+ return NULL;
- for (phi = phi_nodes (loop->header); phi; phi = PHI_CHAIN (phi))
- if (PHI_ARG_DEF_FROM_EDGE (phi, latch) == name)
- break;
+ for (psi = gsi_start_phis (loop->header); !gsi_end_p (psi); gsi_next (&psi))
+ {
+ phi = gsi_stmt (psi);
+ if (PHI_ARG_DEF_FROM_EDGE (phi, latch) == name)
+ break;
+ }
- if (!phi)
- return NULL_TREE;
+ if (gsi_end_p (psi))
+ return NULL;
init = PHI_ARG_DEF_FROM_EDGE (phi, loop_preheader_edge (loop));
if (TREE_CODE (init) != SSA_NAME)
- return NULL_TREE;
+ return NULL;
init_stmt = SSA_NAME_DEF_STMT (init);
- if (TREE_CODE (init_stmt) != GIMPLE_MODIFY_STMT)
- return NULL_TREE;
- gcc_assert (GIMPLE_STMT_OPERAND (init_stmt, 0) == init);
+ if (gimple_code (init_stmt) != GIMPLE_ASSIGN)
+ return NULL;
+ gcc_assert (gimple_assign_lhs (init_stmt) == init);
- init_ref = GIMPLE_STMT_OPERAND (init_stmt, 1);
+ init_ref = gimple_assign_rhs1 (init_stmt);
if (!REFERENCE_CLASS_P (init_ref)
&& !DECL_P (init_ref))
- return NULL_TREE;
+ return NULL;
/* Analyze the behavior of INIT_REF with respect to LOOP (innermost
loop enclosing PHI). */
@@ -1099,7 +1110,7 @@ find_looparound_phi (struct loop *loop, dref ref, dref root)
dr_analyze_innermost (&init_dr);
if (!valid_initializer_p (&init_dr, ref->distance + 1, root->ref))
- return NULL_TREE;
+ return NULL;
return phi;
}
@@ -1107,7 +1118,7 @@ find_looparound_phi (struct loop *loop, dref ref, dref root)
/* Adds a reference for the looparound copy of REF in PHI to CHAIN. */
static void
-insert_looparound_copy (chain_p chain, dref ref, tree phi)
+insert_looparound_copy (chain_p chain, dref ref, gimple phi)
{
dref nw = XCNEW (struct dref), aref;
unsigned i;
@@ -1138,7 +1149,7 @@ add_looparound_copies (struct loop *loop, chain_p chain)
{
unsigned i;
dref ref, root = get_chain_root (chain);
- tree phi;
+ gimple phi;
for (i = 0; VEC_iterate (dref, chain->refs, i, ref); i++)
{
@@ -1218,69 +1229,85 @@ determine_roots (struct loop *loop,
is in the lhs of STMT, false if it is in rhs. */
static void
-replace_ref_with (tree stmt, tree new, bool set, bool in_lhs)
+replace_ref_with (gimple stmt, tree new, bool set, bool in_lhs)
{
- tree val, new_stmt;
- block_stmt_iterator bsi;
+ tree val;
+ gimple new_stmt;
+ gimple_stmt_iterator bsi, psi;
- if (TREE_CODE (stmt) == PHI_NODE)
+ if (gimple_code (stmt) == GIMPLE_PHI)
{
gcc_assert (!in_lhs && !set);
val = PHI_RESULT (stmt);
- bsi = bsi_after_labels (bb_for_stmt (stmt));
- remove_phi_node (stmt, NULL_TREE, false);
+ bsi = gsi_after_labels (gimple_bb (stmt));
+ psi = gsi_for_stmt (stmt);
+ remove_phi_node (&psi, false);
- /* Turn the phi node into GIMPLE_MODIFY_STMT. */
- new_stmt = build_gimple_modify_stmt (val, new);
- SSA_NAME_DEF_STMT (val) = new_stmt;
- bsi_insert_before (&bsi, new_stmt, BSI_NEW_STMT);
+ /* Turn the phi node into GIMPLE_ASSIGN. */
+ new_stmt = gimple_build_assign (val, new);
+ gsi_insert_before (&bsi, new_stmt, GSI_NEW_STMT);
return;
}
/* Since the reference is of gimple_reg type, it should only
appear as lhs or rhs of modify statement. */
- gcc_assert (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT);
+ gcc_assert (is_gimple_assign (stmt));
+
+ bsi = gsi_for_stmt (stmt);
/* If we do not need to initialize NEW, just replace the use of OLD. */
if (!set)
{
gcc_assert (!in_lhs);
- GIMPLE_STMT_OPERAND (stmt, 1) = new;
+ gimple_assign_set_rhs_from_tree (&bsi, new);
+ stmt = gsi_stmt (bsi);
update_stmt (stmt);
return;
}
- bsi = bsi_for_stmt (stmt);
if (in_lhs)
{
- val = GIMPLE_STMT_OPERAND (stmt, 1);
+ /* We have statement
+
+ OLD = VAL
- /* OLD = VAL
-
- is transformed to
+ If OLD is a memory reference, then VAL is gimple_val, and we transform
+ this to
OLD = VAL
NEW = VAL
- (since the reference is of gimple_reg type, VAL is either gimple
- invariant or ssa name). */
+ Otherwise, we are replacing a combination chain,
+ VAL is the expression that performs the combination, and OLD is an
+ SSA name. In this case, we transform the assignment to
+
+ OLD = VAL
+ NEW = OLD
+
+ */
+
+ val = gimple_assign_lhs (stmt);
+ if (TREE_CODE (val) != SSA_NAME)
+ {
+ gcc_assert (gimple_assign_copy_p (stmt));
+ val = gimple_assign_rhs1 (stmt);
+ }
}
else
{
- val = GIMPLE_STMT_OPERAND (stmt, 0);
-
/* VAL = OLD
is transformed to
VAL = OLD
NEW = VAL */
+
+ val = gimple_assign_lhs (stmt);
}
- new_stmt = build_gimple_modify_stmt (new, unshare_expr (val));
- bsi_insert_after (&bsi, new_stmt, BSI_NEW_STMT);
- SSA_NAME_DEF_STMT (new) = new_stmt;
+ new_stmt = gimple_build_assign (new, unshare_expr (val));
+ gsi_insert_after (&bsi, new_stmt, GSI_NEW_STMT);
}
/* Returns the reference to the address of REF in the ITER-th iteration of
@@ -1388,12 +1415,12 @@ get_init_expr (chain_p chain, unsigned index)
/* Marks all virtual operands of statement STMT for renaming. */
void
-mark_virtual_ops_for_renaming (tree stmt)
+mark_virtual_ops_for_renaming (gimple stmt)
{
ssa_op_iter iter;
tree var;
- if (TREE_CODE (stmt) == PHI_NODE)
+ if (gimple_code (stmt) == GIMPLE_PHI)
{
var = PHI_RESULT (stmt);
if (is_gimple_reg (var))
@@ -1418,12 +1445,12 @@ mark_virtual_ops_for_renaming (tree stmt)
/* Calls mark_virtual_ops_for_renaming for all members of LIST. */
static void
-mark_virtual_ops_for_renaming_list (tree list)
+mark_virtual_ops_for_renaming_list (gimple_seq list)
{
- tree_stmt_iterator tsi;
+ gimple_stmt_iterator gsi;
- for (tsi = tsi_start (list); !tsi_end_p (tsi); tsi_next (&tsi))
- mark_virtual_ops_for_renaming (tsi_stmt (tsi));
+ for (gsi = gsi_start (list); !gsi_end_p (gsi); gsi_next (&gsi))
+ mark_virtual_ops_for_renaming (gsi_stmt (gsi));
}
/* Returns a new temporary variable used for the I-th variable carrying
@@ -1457,8 +1484,9 @@ initialize_root_vars (struct loop *loop, chain_p chain, bitmap tmp_vars)
unsigned n = chain->length;
dref root = get_chain_root (chain);
bool reuse_first = !chain->has_max_use_after;
- tree ref, init, var, next, stmts;
- tree phi;
+ tree ref, init, var, next;
+ gimple phi;
+ gimple_seq stmts;
edge entry = loop_preheader_edge (loop), latch = loop_latch_edge (loop);
/* If N == 0, then all the references are within the single iteration. And
@@ -1468,7 +1496,7 @@ initialize_root_vars (struct loop *loop, chain_p chain, bitmap tmp_vars)
chain->vars = VEC_alloc (tree, heap, n + 1);
if (chain->type == CT_COMBINATION)
- ref = GIMPLE_STMT_OPERAND (root->stmt, 0);
+ ref = gimple_assign_lhs (root->stmt);
else
ref = DR_REF (root->ref);
@@ -1481,7 +1509,7 @@ initialize_root_vars (struct loop *loop, chain_p chain, bitmap tmp_vars)
VEC_quick_push (tree, chain->vars, VEC_index (tree, chain->vars, 0));
for (i = 0; VEC_iterate (tree, chain->vars, i, var); i++)
- VEC_replace (tree, chain->vars, i, make_ssa_name (var, NULL_TREE));
+ VEC_replace (tree, chain->vars, i, make_ssa_name (var, NULL));
for (i = 0; i < n; i++)
{
@@ -1493,7 +1521,7 @@ initialize_root_vars (struct loop *loop, chain_p chain, bitmap tmp_vars)
if (stmts)
{
mark_virtual_ops_for_renaming_list (stmts);
- bsi_insert_on_edge_immediate (entry, stmts);
+ gsi_insert_seq_on_edge_immediate (entry, stmts);
}
phi = create_phi_node (var, loop->header);
@@ -1533,8 +1561,9 @@ initialize_root_vars_lm (struct loop *loop, dref root, bool written,
bitmap tmp_vars)
{
unsigned i;
- tree ref = DR_REF (root->ref), init, var, next, stmts;
- tree phi;
+ tree ref = DR_REF (root->ref), init, var, next;
+ gimple_seq stmts;
+ gimple phi;
edge entry = loop_preheader_edge (loop), latch = loop_latch_edge (loop);
/* Find the initializer for the variable, and check that it cannot
@@ -1548,7 +1577,7 @@ initialize_root_vars_lm (struct loop *loop, dref root, bool written,
VEC_quick_push (tree, *vars, VEC_index (tree, *vars, 0));
for (i = 0; VEC_iterate (tree, *vars, i, var); i++)
- VEC_replace (tree, *vars, i, make_ssa_name (var, NULL_TREE));
+ VEC_replace (tree, *vars, i, make_ssa_name (var, NULL));
var = VEC_index (tree, *vars, 0);
@@ -1556,7 +1585,7 @@ initialize_root_vars_lm (struct loop *loop, dref root, bool written,
if (stmts)
{
mark_virtual_ops_for_renaming_list (stmts);
- bsi_insert_on_edge_immediate (entry, stmts);
+ gsi_insert_seq_on_edge_immediate (entry, stmts);
}
if (written)
@@ -1569,10 +1598,9 @@ initialize_root_vars_lm (struct loop *loop, dref root, bool written,
}
else
{
- init = build_gimple_modify_stmt (var, init);
- SSA_NAME_DEF_STMT (var) = init;
- mark_virtual_ops_for_renaming (init);
- bsi_insert_on_edge_immediate (entry, init);
+ gimple init_stmt = gimple_build_assign (var, init);
+ mark_virtual_ops_for_renaming (init_stmt);
+ gsi_insert_on_edge_immediate (entry, init_stmt);
}
}
@@ -1613,7 +1641,7 @@ execute_load_motion (struct loop *loop, chain_p chain, bitmap tmp_vars)
if (n_writes)
{
var = VEC_index (tree, vars, 0);
- var = make_ssa_name (SSA_NAME_VAR (var), NULL_TREE);
+ var = make_ssa_name (SSA_NAME_VAR (var), NULL);
VEC_replace (tree, vars, 0, var);
}
else
@@ -1629,20 +1657,20 @@ execute_load_motion (struct loop *loop, chain_p chain, bitmap tmp_vars)
/* Returns the single statement in that NAME is used, excepting
the looparound phi nodes contained in one of the chains. If there is no
- such statement, or more statements, NULL_TREE is returned. */
+ such statement, or more statements, NULL is returned. */
-static tree
+static gimple
single_nonlooparound_use (tree name)
{
use_operand_p use;
imm_use_iterator it;
- tree stmt, ret = NULL_TREE;
+ gimple stmt, ret = NULL;
FOR_EACH_IMM_USE_FAST (use, it, name)
{
stmt = USE_STMT (use);
- if (TREE_CODE (stmt) == PHI_NODE)
+ if (gimple_code (stmt) == GIMPLE_PHI)
{
/* Ignore uses in looparound phi nodes. Uses in other phi nodes
could not be processed anyway, so just fail for them. */
@@ -1650,10 +1678,10 @@ single_nonlooparound_use (tree name)
SSA_NAME_VERSION (PHI_RESULT (stmt))))
continue;
- return NULL_TREE;
+ return NULL;
}
- else if (ret != NULL_TREE)
- return NULL_TREE;
+ else if (ret != NULL)
+ return NULL;
else
ret = stmt;
}
@@ -1665,19 +1693,22 @@ single_nonlooparound_use (tree name)
used. */
static void
-remove_stmt (tree stmt)
+remove_stmt (gimple stmt)
{
- tree next, name;
+ tree name;
+ gimple next;
+ gimple_stmt_iterator psi;
- if (TREE_CODE (stmt) == PHI_NODE)
+ if (gimple_code (stmt) == GIMPLE_PHI)
{
name = PHI_RESULT (stmt);
next = single_nonlooparound_use (name);
- remove_phi_node (stmt, NULL_TREE, true);
+ psi = gsi_for_stmt (stmt);
+ remove_phi_node (&psi, true);
if (!next
- || TREE_CODE (next) != GIMPLE_MODIFY_STMT
- || GIMPLE_STMT_OPERAND (next, 1) != name)
+ || !gimple_assign_copy_p (next)
+ || gimple_assign_rhs1 (next) != name)
return;
stmt = next;
@@ -1685,21 +1716,21 @@ remove_stmt (tree stmt)
while (1)
{
- block_stmt_iterator bsi;
+ gimple_stmt_iterator bsi;
- bsi = bsi_for_stmt (stmt);
+ bsi = gsi_for_stmt (stmt);
- name = GIMPLE_STMT_OPERAND (stmt, 0);
+ name = gimple_assign_lhs (stmt);
gcc_assert (TREE_CODE (name) == SSA_NAME);
next = single_nonlooparound_use (name);
mark_virtual_ops_for_renaming (stmt);
- bsi_remove (&bsi, true);
+ gsi_remove (&bsi, true);
if (!next
- || TREE_CODE (next) != GIMPLE_MODIFY_STMT
- || GIMPLE_STMT_OPERAND (next, 1) != name)
+ || !gimple_assign_copy_p (next)
+ || gimple_assign_rhs1 (next) != name)
return;
stmt = next;
@@ -1794,7 +1825,7 @@ execute_pred_commoning (struct loop *loop, VEC (chain_p, heap) *chains,
}
/* For each reference in CHAINS, if its defining statement is
- ssa name, set it to phi node that defines it. */
+ phi node, record the ssa name that is defined by it. */
static void
replace_phis_by_defined_names (VEC (chain_p, heap) *chains)
@@ -1806,14 +1837,16 @@ replace_phis_by_defined_names (VEC (chain_p, heap) *chains)
for (i = 0; VEC_iterate (chain_p, chains, i, chain); i++)
for (j = 0; VEC_iterate (dref, chain->refs, j, a); j++)
{
- gcc_assert (TREE_CODE (a->stmt) != SSA_NAME);
- if (TREE_CODE (a->stmt) == PHI_NODE)
- a->stmt = PHI_RESULT (a->stmt);
+ if (gimple_code (a->stmt) == GIMPLE_PHI)
+ {
+ a->name_defined_by_phi = PHI_RESULT (a->stmt);
+ a->stmt = NULL;
+ }
}
}
-/* For each reference in CHAINS, if its defining statement is
- phi node, set it to the ssa name that is defined by it. */
+/* For each reference in CHAINS, if name_defined_by_phi is not
+ NULL, use it to set the stmt field. */
static void
replace_names_by_phis (VEC (chain_p, heap) *chains)
@@ -1824,10 +1857,11 @@ replace_names_by_phis (VEC (chain_p, heap) *chains)
for (i = 0; VEC_iterate (chain_p, chains, i, chain); i++)
for (j = 0; VEC_iterate (dref, chain->refs, j, a); j++)
- if (TREE_CODE (a->stmt) == SSA_NAME)
+ if (a->stmt == NULL)
{
- a->stmt = SSA_NAME_DEF_STMT (a->stmt);
- gcc_assert (TREE_CODE (a->stmt) == PHI_NODE);
+ a->stmt = SSA_NAME_DEF_STMT (a->name_defined_by_phi);
+ gcc_assert (gimple_code (a->stmt) == GIMPLE_PHI);
+ a->name_defined_by_phi = NULL_TREE;
}
}
@@ -1896,7 +1930,7 @@ should_unroll_loop_p (struct loop *loop, unsigned factor,
static void
base_names_in_chain_on (struct loop *loop, tree name, tree var)
{
- tree stmt, phi;
+ gimple stmt, phi;
imm_use_iterator iter;
edge e;
@@ -1907,8 +1941,8 @@ base_names_in_chain_on (struct loop *loop, tree name, tree var)
phi = NULL;
FOR_EACH_IMM_USE_STMT (stmt, iter, name)
{
- if (TREE_CODE (stmt) == PHI_NODE
- && flow_bb_inside_loop_p (loop, bb_for_stmt (stmt)))
+ if (gimple_code (stmt) == GIMPLE_PHI
+ && flow_bb_inside_loop_p (loop, gimple_bb (stmt)))
{
phi = stmt;
BREAK_FROM_IMM_USE_STMT (iter);
@@ -1917,10 +1951,10 @@ base_names_in_chain_on (struct loop *loop, tree name, tree var)
if (!phi)
return;
- if (bb_for_stmt (phi) == loop->header)
+ if (gimple_bb (phi) == loop->header)
e = loop_latch_edge (loop);
else
- e = single_pred_edge (bb_for_stmt (stmt));
+ e = single_pred_edge (gimple_bb (stmt));
name = PHI_RESULT (phi);
SSA_NAME_VAR (name) = var;
@@ -1936,11 +1970,14 @@ static void
eliminate_temp_copies (struct loop *loop, bitmap tmp_vars)
{
edge e;
- tree phi, name, use, var, stmt;
+ gimple phi, stmt;
+ tree name, use, var;
+ gimple_stmt_iterator psi;
e = loop_latch_edge (loop);
- for (phi = phi_nodes (loop->header); phi; phi = PHI_CHAIN (phi))
+ for (psi = gsi_start_phis (loop->header); !gsi_end_p (psi); gsi_next (&psi))
{
+ phi = gsi_stmt (psi);
name = PHI_RESULT (phi);
var = SSA_NAME_VAR (name);
if (!bitmap_bit_p (tmp_vars, DECL_UID (var)))
@@ -1950,15 +1987,15 @@ eliminate_temp_copies (struct loop *loop, bitmap tmp_vars)
/* Base all the ssa names in the ud and du chain of NAME on VAR. */
stmt = SSA_NAME_DEF_STMT (use);
- while (TREE_CODE (stmt) == PHI_NODE
+ while (gimple_code (stmt) == GIMPLE_PHI
/* In case we could not unroll the loop enough to eliminate
all copies, we may reach the loop header before the defining
statement (in that case, some register copies will be present
in loop latch in the final code, corresponding to the newly
created looparound phi nodes). */
- && bb_for_stmt (stmt) != loop->header)
+ && gimple_bb (stmt) != loop->header)
{
- gcc_assert (single_pred_p (bb_for_stmt (stmt)));
+ gcc_assert (single_pred_p (gimple_bb (stmt)));
use = PHI_ARG_DEF (stmt, 0);
stmt = SSA_NAME_DEF_STMT (use);
}
@@ -1980,38 +2017,40 @@ chain_can_be_combined_p (chain_p chain)
statements, NAME is replaced with the actual name used in the returned
statement. */
-static tree
+static gimple
find_use_stmt (tree *name)
{
- tree stmt, rhs, lhs;
+ gimple stmt;
+ tree rhs, lhs;
/* Skip over assignments. */
while (1)
{
stmt = single_nonlooparound_use (*name);
if (!stmt)
- return NULL_TREE;
+ return NULL;
- if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT)
- return NULL_TREE;
+ if (gimple_code (stmt) != GIMPLE_ASSIGN)
+ return NULL;
- lhs = GIMPLE_STMT_OPERAND (stmt, 0);
+ lhs = gimple_assign_lhs (stmt);
if (TREE_CODE (lhs) != SSA_NAME)
- return NULL_TREE;
+ return NULL;
- rhs = GIMPLE_STMT_OPERAND (stmt, 1);
- if (rhs != *name)
- break;
+ if (gimple_assign_copy_p (stmt))
+ {
+ rhs = gimple_assign_rhs1 (stmt);
+ if (rhs != *name)
+ return NULL;
- *name = lhs;
+ *name = lhs;
+ }
+ else if (get_gimple_rhs_class (gimple_assign_rhs_code (stmt))
+ == GIMPLE_BINARY_RHS)
+ return stmt;
+ else
+ return NULL;
}
-
- if (!EXPR_P (rhs)
- || REFERENCE_CLASS_P (rhs)
- || TREE_CODE_LENGTH (TREE_CODE (rhs)) != 2)
- return NULL_TREE;
-
- return stmt;
}
/* Returns true if we may perform reassociation for operation CODE in TYPE. */
@@ -2031,27 +2070,26 @@ may_reassociate_p (tree type, enum tree_code code)
tree of the same operations and returns its root. Distance to the root
is stored in DISTANCE. */
-static tree
-find_associative_operation_root (tree stmt, unsigned *distance)
+static gimple
+find_associative_operation_root (gimple stmt, unsigned *distance)
{
- tree rhs = GIMPLE_STMT_OPERAND (stmt, 1), lhs, next;
- enum tree_code code = TREE_CODE (rhs);
+ tree lhs;
+ gimple next;
+ enum tree_code code = gimple_assign_rhs_code (stmt);
+ tree type = TREE_TYPE (gimple_assign_lhs (stmt));
unsigned dist = 0;
- if (!may_reassociate_p (TREE_TYPE (rhs), code))
- return NULL_TREE;
+ if (!may_reassociate_p (type, code))
+ return NULL;
while (1)
{
- lhs = GIMPLE_STMT_OPERAND (stmt, 0);
+ lhs = gimple_assign_lhs (stmt);
gcc_assert (TREE_CODE (lhs) == SSA_NAME);
next = find_use_stmt (&lhs);
- if (!next)
- break;
-
- rhs = GIMPLE_STMT_OPERAND (next, 1);
- if (TREE_CODE (rhs) != code)
+ if (!next
+ || gimple_assign_rhs_code (next) != code)
break;
stmt = next;
@@ -2069,30 +2107,30 @@ find_associative_operation_root (tree stmt, unsigned *distance)
tree formed by this operation instead of the statement that uses NAME1 or
NAME2. */
-static tree
+static gimple
find_common_use_stmt (tree *name1, tree *name2)
{
- tree stmt1, stmt2;
+ gimple stmt1, stmt2;
stmt1 = find_use_stmt (name1);
if (!stmt1)
- return NULL_TREE;
+ return NULL;
stmt2 = find_use_stmt (name2);
if (!stmt2)
- return NULL_TREE;
+ return NULL;
if (stmt1 == stmt2)
return stmt1;
stmt1 = find_associative_operation_root (stmt1, NULL);
if (!stmt1)
- return NULL_TREE;
+ return NULL;
stmt2 = find_associative_operation_root (stmt2, NULL);
if (!stmt2)
- return NULL_TREE;
+ return NULL;
- return (stmt1 == stmt2 ? stmt1 : NULL_TREE);
+ return (stmt1 == stmt2 ? stmt1 : NULL);
}
/* Checks whether R1 and R2 are combined together using CODE, with the result
@@ -2106,7 +2144,8 @@ combinable_refs_p (dref r1, dref r2,
enum tree_code acode;
bool aswap;
tree atype;
- tree name1, name2, stmt, rhs;
+ tree name1, name2;
+ gimple stmt;
name1 = name_for_ref (r1);
name2 = name_for_ref (r2);
@@ -2117,11 +2156,10 @@ combinable_refs_p (dref r1, dref r2,
if (!stmt)
return false;
- rhs = GIMPLE_STMT_OPERAND (stmt, 1);
- acode = TREE_CODE (rhs);
+ acode = gimple_assign_rhs_code (stmt);
aswap = (!commutative_tree_code (acode)
- && TREE_OPERAND (rhs, 0) != name1);
- atype = TREE_TYPE (rhs);
+ && gimple_assign_rhs1 (stmt) != name1);
+ atype = TREE_TYPE (gimple_assign_lhs (stmt));
if (*code == ERROR_MARK)
{
@@ -2140,43 +2178,49 @@ combinable_refs_p (dref r1, dref r2,
an assignment of the remaining operand. */
static void
-remove_name_from_operation (tree stmt, tree op)
+remove_name_from_operation (gimple stmt, tree op)
{
- tree *rhs;
+ tree other_op;
+ gimple_stmt_iterator si;
- gcc_assert (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT);
+ gcc_assert (is_gimple_assign (stmt));
- rhs = &GIMPLE_STMT_OPERAND (stmt, 1);
- if (TREE_OPERAND (*rhs, 0) == op)
- *rhs = TREE_OPERAND (*rhs, 1);
- else if (TREE_OPERAND (*rhs, 1) == op)
- *rhs = TREE_OPERAND (*rhs, 0);
+ if (gimple_assign_rhs1 (stmt) == op)
+ other_op = gimple_assign_rhs2 (stmt);
else
- gcc_unreachable ();
+ other_op = gimple_assign_rhs1 (stmt);
+
+ si = gsi_for_stmt (stmt);
+ gimple_assign_set_rhs_from_tree (&si, other_op);
+
+ /* We should not have reallocated STMT. */
+ gcc_assert (gsi_stmt (si) == stmt);
+
update_stmt (stmt);
}
/* Reassociates the expression in that NAME1 and NAME2 are used so that they
are combined in a single statement, and returns this statement. */
-static tree
+static gimple
reassociate_to_the_same_stmt (tree name1, tree name2)
{
- tree stmt1, stmt2, root1, root2, r1, r2, s1, s2;
- tree new_stmt, tmp_stmt, new_name, tmp_name, var;
+ gimple stmt1, stmt2, root1, root2, s1, s2;
+ gimple new_stmt, tmp_stmt;
+ tree new_name, tmp_name, var, r1, r2;
unsigned dist1, dist2;
enum tree_code code;
tree type = TREE_TYPE (name1);
- block_stmt_iterator bsi;
+ gimple_stmt_iterator bsi;
stmt1 = find_use_stmt (&name1);
stmt2 = find_use_stmt (&name2);
root1 = find_associative_operation_root (stmt1, &dist1);
root2 = find_associative_operation_root (stmt2, &dist2);
- code = TREE_CODE (GIMPLE_STMT_OPERAND (stmt1, 1));
+ code = gimple_assign_rhs_code (stmt1);
gcc_assert (root1 && root2 && root1 == root2
- && code == TREE_CODE (GIMPLE_STMT_OPERAND (stmt2, 1)));
+ && code == gimple_assign_rhs_code (stmt2));
/* Find the root of the nearest expression in that both NAME1 and NAME2
are used. */
@@ -2188,22 +2232,22 @@ reassociate_to_the_same_stmt (tree name1, tree name2)
while (dist1 > dist2)
{
s1 = find_use_stmt (&r1);
- r1 = GIMPLE_STMT_OPERAND (s1, 0);
+ r1 = gimple_assign_lhs (s1);
dist1--;
}
while (dist2 > dist1)
{
s2 = find_use_stmt (&r2);
- r2 = GIMPLE_STMT_OPERAND (s2, 0);
+ r2 = gimple_assign_lhs (s2);
dist2--;
}
while (s1 != s2)
{
s1 = find_use_stmt (&r1);
- r1 = GIMPLE_STMT_OPERAND (s1, 0);
+ r1 = gimple_assign_lhs (s1);
s2 = find_use_stmt (&r2);
- r2 = GIMPLE_STMT_OPERAND (s2, 0);
+ r2 = gimple_assign_lhs (s2);
}
/* Remove NAME1 and NAME2 from the statements in that they are used
@@ -2215,24 +2259,28 @@ reassociate_to_the_same_stmt (tree name1, tree name2)
combine it with the rhs of S1. */
var = create_tmp_var (type, "predreastmp");
add_referenced_var (var);
- new_name = make_ssa_name (var, NULL_TREE);
- new_stmt = build_gimple_modify_stmt (new_name,
- fold_build2 (code, type, name1, name2));
- SSA_NAME_DEF_STMT (new_name) = new_stmt;
+ new_name = make_ssa_name (var, NULL);
+ new_stmt = gimple_build_assign_with_ops (code, new_name, name1, name2);
var = create_tmp_var (type, "predreastmp");
add_referenced_var (var);
- tmp_name = make_ssa_name (var, NULL_TREE);
- tmp_stmt = build_gimple_modify_stmt (tmp_name,
- GIMPLE_STMT_OPERAND (s1, 1));
- SSA_NAME_DEF_STMT (tmp_name) = tmp_stmt;
-
- GIMPLE_STMT_OPERAND (s1, 1) = fold_build2 (code, type, new_name, tmp_name);
+ tmp_name = make_ssa_name (var, NULL);
+
+ /* Rhs of S1 may now be either a binary expression with operation
+ CODE, or gimple_val (in case that stmt1 == s1 or stmt2 == s1,
+ so that name1 or name2 was removed from it). */
+ tmp_stmt = gimple_build_assign_with_ops (gimple_assign_rhs_code (s1),
+ tmp_name,
+ gimple_assign_rhs1 (s1),
+ gimple_assign_rhs2 (s1));
+
+ bsi = gsi_for_stmt (s1);
+ gimple_assign_set_rhs_with_ops (&bsi, code, new_name, tmp_name);
+ s1 = gsi_stmt (bsi);
update_stmt (s1);
- bsi = bsi_for_stmt (s1);
- bsi_insert_before (&bsi, new_stmt, BSI_SAME_STMT);
- bsi_insert_before (&bsi, tmp_stmt, BSI_SAME_STMT);
+ gsi_insert_before (&bsi, new_stmt, GSI_SAME_STMT);
+ gsi_insert_before (&bsi, tmp_stmt, GSI_SAME_STMT);
return new_stmt;
}
@@ -2242,10 +2290,10 @@ reassociate_to_the_same_stmt (tree name1, tree name2)
associative and commutative operation in the same expression, reassociate
the expression so that they are used in the same statement. */
-static tree
+static gimple
stmt_combining_refs (dref r1, dref r2)
{
- tree stmt1, stmt2;
+ gimple stmt1, stmt2;
tree name1 = name_for_ref (r1);
tree name2 = name_for_ref (r2);
@@ -2268,7 +2316,7 @@ combine_chains (chain_p ch1, chain_p ch2)
bool swap = false;
chain_p new_chain;
unsigned i;
- tree root_stmt;
+ gimple root_stmt;
tree rslt_type = NULL_TREE;
if (ch1 == ch2)
@@ -2399,7 +2447,8 @@ prepare_initializers_chain (struct loop *loop, chain_p chain)
{
unsigned i, n = (chain->type == CT_INVARIANT) ? 1 : chain->length;
struct data_reference *dr = get_chain_root (chain)->ref;
- tree init, stmts;
+ tree init;
+ gimple_seq stmts;
dref laref;
edge entry = loop_preheader_edge (loop);
@@ -2413,7 +2462,7 @@ prepare_initializers_chain (struct loop *loop, chain_p chain)
instead of creating our own. */
for (i = 0; VEC_iterate (dref, chain->refs, i, laref); i++)
{
- if (TREE_CODE (laref->stmt) != PHI_NODE)
+ if (gimple_code (laref->stmt) != GIMPLE_PHI)
continue;
gcc_assert (laref->distance > 0);
@@ -2437,7 +2486,7 @@ prepare_initializers_chain (struct loop *loop, chain_p chain)
if (stmts)
{
mark_virtual_ops_for_renaming_list (stmts);
- bsi_insert_on_edge_immediate (entry, stmts);
+ gsi_insert_seq_on_edge_immediate (entry, stmts);
}
set_alias_info (init, dr);
diff --git a/gcc/tree-pretty-print.c b/gcc/tree-pretty-print.c
index 2f7de8f1c7d..df055f84fe7 100644
--- a/gcc/tree-pretty-print.c
+++ b/gcc/tree-pretty-print.c
@@ -44,11 +44,8 @@ static void pretty_print_string (pretty_printer *, const char*);
static void print_call_name (pretty_printer *, const_tree);
static void newline_and_indent (pretty_printer *, int);
static void maybe_init_pretty_print (FILE *);
-static void print_declaration (pretty_printer *, tree, int, int);
static void print_struct_decl (pretty_printer *, const_tree, int, int);
static void do_niy (pretty_printer *, const_tree);
-static void dump_vops (pretty_printer *, tree, int, int);
-static void dump_generic_bb_buff (pretty_printer *, basic_block, int, int);
#define INDENT(SPACE) do { \
int i; for (i = 0; i<SPACE; i++) pp_space (buffer); } while (0)
@@ -409,7 +406,7 @@ dump_omp_clause (pretty_printer *buffer, tree clause, int spc, int flags)
/* Dump the list of OpenMP clauses. BUFFER, SPC and FLAGS are as in
dump_generic_node. */
-static void
+void
dump_omp_clauses (pretty_printer *buffer, tree clause, int spc, int flags)
{
if (clause == NULL)
@@ -427,33 +424,6 @@ dump_omp_clauses (pretty_printer *buffer, tree clause, int spc, int flags)
}
-/* Dump the set of decls SYMS. BUFFER, SPC and FLAGS are as in
- dump_generic_node. */
-
-static void
-dump_symbols (pretty_printer *buffer, bitmap syms, int flags)
-{
- unsigned i;
- bitmap_iterator bi;
-
- if (syms == NULL)
- pp_string (buffer, "NIL");
- else
- {
- pp_string (buffer, " { ");
-
- EXECUTE_IF_SET_IN_BITMAP (syms, 0, i, bi)
- {
- tree sym = referenced_var_lookup (i);
- dump_generic_node (buffer, sym, 0, flags, false);
- pp_string (buffer, " ");
- }
-
- pp_string (buffer, "}");
- }
-}
-
-
/* Dump the node NODE on the pretty_printer BUFFER, SPC spaces of
indent. FLAGS specifies details to show in the dump (see TDF_* in
tree-pass.h). If IS_STMT is true, the object printed is considered
@@ -471,18 +441,7 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
if (node == NULL_TREE)
return spc;
- is_expr = EXPR_P (node) || GIMPLE_STMT_P (node);
-
- /* We use has_stmt_ann because CALL_EXPR can be both an expression
- and a statement, and we have no guarantee that it will have a
- stmt_ann when it is used as an RHS expression. stmt_ann will assert
- if you call it on something with a non-stmt annotation attached. */
- if (TREE_CODE (node) != ERROR_MARK
- && is_gimple_stmt (node)
- && (flags & (TDF_VOPS|TDF_MEMSYMS))
- && has_stmt_ann (node)
- && TREE_CODE (node) != PHI_NODE)
- dump_vops (buffer, node, spc, flags);
+ is_expr = EXPR_P (node);
if (is_stmt && (flags & TDF_STMTADDR))
pp_printf (buffer, "<&%p> ", (void *)node);
@@ -952,16 +911,12 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
pp_character (buffer, ')');
pp_string (buffer, str);
dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
-
- if (TREE_CODE (op0) != VALUE_HANDLE)
+ op0 = component_ref_field_offset (node);
+ if (op0 && TREE_CODE (op0) != INTEGER_CST)
{
- op0 = component_ref_field_offset (node);
- if (op0 && TREE_CODE (op0) != INTEGER_CST)
- {
- pp_string (buffer, "{off: ");
+ pp_string (buffer, "{off: ");
dump_generic_node (buffer, op0, spc, flags, false);
pp_character (buffer, '}');
- }
}
break;
@@ -1099,24 +1054,16 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
break;
case MODIFY_EXPR:
- case GIMPLE_MODIFY_STMT:
case INIT_EXPR:
- dump_generic_node (buffer, GENERIC_TREE_OPERAND (node, 0), spc, flags,
+ dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags,
false);
pp_space (buffer);
pp_character (buffer, '=');
- if (TREE_CODE (node) == GIMPLE_MODIFY_STMT
+ if (TREE_CODE (node) == MODIFY_EXPR
&& MOVE_NONTEMPORAL (node))
pp_string (buffer, "{nt}");
- if (TREE_CODE (node) == GIMPLE_MODIFY_STMT)
- {
- stmt_ann_t ann;
- if ((ann = stmt_ann (node))
- && ann->has_volatile_ops)
- pp_string (buffer, "{v}");
- }
pp_space (buffer);
- dump_generic_node (buffer, GENERIC_TREE_OPERAND (node, 1), spc, flags,
+ dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags,
false);
break;
@@ -1626,9 +1573,8 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
if (op0)
{
pp_space (buffer);
- if (TREE_CODE (op0) == MODIFY_EXPR
- || TREE_CODE (op0) == GIMPLE_MODIFY_STMT)
- dump_generic_node (buffer, GENERIC_TREE_OPERAND (op0, 1),
+ if (TREE_CODE (op0) == MODIFY_EXPR)
+ dump_generic_node (buffer, TREE_OPERAND (op0, 1),
spc, flags, false);
else
dump_generic_node (buffer, op0, spc, flags, false);
@@ -1734,7 +1680,7 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
dump_generic_node (buffer, CASE_LOW (node), spc, flags, false);
}
else
- pp_string (buffer, "default ");
+ pp_string (buffer, "default");
pp_character (buffer, ':');
break;
@@ -1749,28 +1695,6 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
pp_character (buffer, ')');
break;
- case PHI_NODE:
- {
- int i;
-
- dump_generic_node (buffer, PHI_RESULT (node), spc, flags, false);
- pp_string (buffer, " = PHI <");
- for (i = 0; i < PHI_NUM_ARGS (node); i++)
- {
- dump_generic_node (buffer, PHI_ARG_DEF (node, i), spc, flags, false);
- pp_string (buffer, "(");
- pp_decimal_int (buffer, PHI_ARG_EDGE (node, i)->src->index);
- pp_string (buffer, ")");
- if (i < PHI_NUM_ARGS (node) - 1)
- pp_string (buffer, ", ");
- }
- pp_string (buffer, ">");
-
- if (stmt_references_memory_p (node) && (flags & TDF_MEMSYMS))
- dump_symbols (buffer, STORED_SYMS (node), flags);
- }
- break;
-
case SSA_NAME:
dump_generic_node (buffer, SSA_NAME_VAR (node), spc, flags, false);
pp_string (buffer, "_");
@@ -1789,10 +1713,6 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
pp_string (buffer, ">");
break;
- case VALUE_HANDLE:
- pp_printf (buffer, "VH.%d", VALUE_HANDLE_ID (node));
- break;
-
case ASSERT_EXPR:
pp_string (buffer, "ASSERT_EXPR <");
dump_generic_node (buffer, ASSERT_EXPR_VAR (node), spc, flags, false);
@@ -1852,21 +1772,6 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
case OMP_PARALLEL:
pp_string (buffer, "#pragma omp parallel");
dump_omp_clauses (buffer, OMP_PARALLEL_CLAUSES (node), spc, flags);
- if (OMP_PARALLEL_FN (node))
- {
- pp_string (buffer, " [child fn: ");
- dump_generic_node (buffer, OMP_PARALLEL_FN (node), spc, flags, false);
-
- pp_string (buffer, " (");
-
- if (OMP_PARALLEL_DATA_ARG (node))
- dump_generic_node (buffer, OMP_PARALLEL_DATA_ARG (node), spc, flags,
- false);
- else
- pp_string (buffer, "???");
-
- pp_string (buffer, ")]");
- }
dump_omp_body:
if (!(flags & TDF_SLIM) && OMP_BODY (node))
@@ -1884,28 +1789,6 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
case OMP_TASK:
pp_string (buffer, "#pragma omp task");
dump_omp_clauses (buffer, OMP_TASK_CLAUSES (node), spc, flags);
- if (OMP_TASK_FN (node))
- {
- pp_string (buffer, " [child fn: ");
- dump_generic_node (buffer, OMP_TASK_FN (node), spc, flags, false);
-
- pp_string (buffer, " (");
-
- if (OMP_TASK_DATA_ARG (node))
- dump_generic_node (buffer, OMP_TASK_DATA_ARG (node), spc, flags,
- false);
- else
- pp_string (buffer, "???");
-
- pp_character (buffer, ')');
- if (OMP_TASK_COPYFN (node))
- {
- pp_string (buffer, ", copy fn: ");
- dump_generic_node (buffer, OMP_TASK_COPYFN (node), spc,
- flags, false);
- }
- pp_character (buffer, ']');
- }
goto dump_omp_body;
case OMP_FOR:
@@ -1964,21 +1847,9 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
case OMP_SECTIONS:
pp_string (buffer, "#pragma omp sections");
- if (OMP_SECTIONS_CONTROL (node))
- {
- pp_string (buffer, " <");
- dump_generic_node (buffer, OMP_SECTIONS_CONTROL (node), spc,
- flags, false);
- pp_string (buffer, ">");
- }
dump_omp_clauses (buffer, OMP_SECTIONS_CLAUSES (node), spc, flags);
goto dump_omp_body;
- case OMP_SECTIONS_SWITCH:
- pp_string (buffer, "OMP_SECTIONS_SWITCH");
- is_expr = false;
- break;
-
case OMP_SECTION:
pp_string (buffer, "#pragma omp section");
goto dump_omp_body;
@@ -2013,44 +1884,11 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
break;
- case OMP_ATOMIC_LOAD:
- pp_string (buffer, "#pragma omp atomic_load");
- newline_and_indent (buffer, spc + 2);
- dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
- pp_space (buffer);
- pp_character (buffer, '=');
- pp_space (buffer);
- pp_character (buffer, '*');
- dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
- break;
-
- case OMP_ATOMIC_STORE:
- pp_string (buffer, "#pragma omp atomic_store (");
- dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
- pp_character (buffer, ')');
- break;
-
case OMP_SINGLE:
pp_string (buffer, "#pragma omp single");
dump_omp_clauses (buffer, OMP_SINGLE_CLAUSES (node), spc, flags);
goto dump_omp_body;
- case OMP_RETURN:
- pp_string (buffer, "OMP_RETURN");
- if (OMP_RETURN_NOWAIT (node))
- pp_string (buffer, " [nowait]");
- is_expr = false;
- break;
-
- case OMP_CONTINUE:
- pp_string (buffer, "OMP_CONTINUE <");
- dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
- pp_string (buffer, " <- ");
- dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
- pp_string (buffer, ">");
- is_expr = false;
- break;
-
case OMP_CLAUSE:
dump_omp_clause (buffer, node, spc, flags);
is_expr = false;
@@ -2245,7 +2083,7 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
/* Print the declaration of a variable. */
-static void
+void
print_declaration (pretty_printer *buffer, tree t, int spc, int flags)
{
INDENT (spc);
@@ -2423,7 +2261,6 @@ op_prio (const_tree op)
return 1;
case MODIFY_EXPR:
- case GIMPLE_MODIFY_STMT:
case INIT_EXPR:
return 2;
@@ -2557,7 +2394,6 @@ op_symbol_code (enum tree_code code)
switch (code)
{
case MODIFY_EXPR:
- case GIMPLE_MODIFY_STMT:
return "=";
case TRUTH_OR_EXPR:
@@ -2898,342 +2734,3 @@ newline_and_indent (pretty_printer *buffer, int spc)
pp_newline (buffer);
INDENT (spc);
}
-
-
-static void
-dump_vops (pretty_printer *buffer, tree stmt, int spc, int flags)
-{
- struct voptype_d *vdefs;
- struct voptype_d *vuses;
- int i, n;
-
- if (!ssa_operands_active () || !stmt_references_memory_p (stmt))
- return;
-
- /* Even if the statement doesn't have virtual operators yet, it may
- contain symbol information (this happens before aliases have been
- computed). */
- if ((flags & TDF_MEMSYMS)
- && VUSE_OPS (stmt) == NULL
- && VDEF_OPS (stmt) == NULL)
- {
- if (LOADED_SYMS (stmt))
- {
- pp_string (buffer, "# LOADS: ");
- dump_symbols (buffer, LOADED_SYMS (stmt), flags);
- newline_and_indent (buffer, spc);
- }
-
- if (STORED_SYMS (stmt))
- {
- pp_string (buffer, "# STORES: ");
- dump_symbols (buffer, STORED_SYMS (stmt), flags);
- newline_and_indent (buffer, spc);
- }
-
- return;
- }
-
- vuses = VUSE_OPS (stmt);
- while (vuses)
- {
- pp_string (buffer, "# VUSE <");
-
- n = VUSE_NUM (vuses);
- for (i = 0; i < n; i++)
- {
- dump_generic_node (buffer, VUSE_OP (vuses, i), spc + 2, flags, false);
- if (i < n - 1)
- pp_string (buffer, ", ");
- }
-
- pp_string (buffer, ">");
-
- if (flags & TDF_MEMSYMS)
- dump_symbols (buffer, LOADED_SYMS (stmt), flags);
-
- newline_and_indent (buffer, spc);
- vuses = vuses->next;
- }
-
- vdefs = VDEF_OPS (stmt);
- while (vdefs)
- {
- pp_string (buffer, "# ");
- dump_generic_node (buffer, VDEF_RESULT (vdefs), spc + 2, flags, false);
- pp_string (buffer, " = VDEF <");
-
- n = VDEF_NUM (vdefs);
- for (i = 0; i < n; i++)
- {
- dump_generic_node (buffer, VDEF_OP (vdefs, i), spc + 2, flags, 0);
- if (i < n - 1)
- pp_string (buffer, ", ");
- }
-
- pp_string (buffer, ">");
-
- if ((flags & TDF_MEMSYMS) && vdefs->next == NULL)
- dump_symbols (buffer, STORED_SYMS (stmt), flags);
-
- newline_and_indent (buffer, spc);
- vdefs = vdefs->next;
- }
-}
-
-
-/* Dumps basic block BB to FILE with details described by FLAGS and
- indented by INDENT spaces. */
-
-void
-dump_generic_bb (FILE *file, basic_block bb, int indent, int flags)
-{
- maybe_init_pretty_print (file);
- dump_generic_bb_buff (&buffer, bb, indent, flags);
- pp_flush (&buffer);
-}
-
-/* Dumps header of basic block BB to buffer BUFFER indented by INDENT
- spaces and details described by flags. */
-
-static void
-dump_bb_header (pretty_printer *buffer, basic_block bb, int indent, int flags)
-{
- edge e;
- tree stmt;
- edge_iterator ei;
-
- if (flags & TDF_BLOCKS)
- {
- INDENT (indent);
- pp_string (buffer, "# BLOCK ");
- pp_decimal_int (buffer, bb->index);
- if (bb->frequency)
- {
- pp_string (buffer, " freq:");
- pp_decimal_int (buffer, bb->frequency);
- }
- if (bb->count)
- {
- pp_string (buffer, " count:");
- pp_widest_integer (buffer, bb->count);
- }
-
- if (flags & TDF_LINENO)
- {
- block_stmt_iterator bsi;
-
- for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
- if (get_lineno (bsi_stmt (bsi)) != -1)
- {
- pp_string (buffer, ", starting at line ");
- pp_decimal_int (buffer, get_lineno (bsi_stmt (bsi)));
- break;
- }
- }
- newline_and_indent (buffer, indent);
-
- pp_string (buffer, "# PRED:");
- pp_write_text_to_stream (buffer);
- FOR_EACH_EDGE (e, ei, bb->preds)
- if (flags & TDF_SLIM)
- {
- pp_string (buffer, " ");
- if (e->src == ENTRY_BLOCK_PTR)
- pp_string (buffer, "ENTRY");
- else
- pp_decimal_int (buffer, e->src->index);
- }
- else
- dump_edge_info (buffer->buffer->stream, e, 0);
- pp_newline (buffer);
- }
- else
- {
- stmt = first_stmt (bb);
- if (!stmt || TREE_CODE (stmt) != LABEL_EXPR)
- {
- INDENT (indent - 2);
- pp_string (buffer, "<bb ");
- pp_decimal_int (buffer, bb->index);
- pp_string (buffer, ">:");
- pp_newline (buffer);
- }
- }
- pp_write_text_to_stream (buffer);
- check_bb_profile (bb, buffer->buffer->stream);
-}
-
-/* Dumps end of basic block BB to buffer BUFFER indented by INDENT
- spaces. */
-
-static void
-dump_bb_end (pretty_printer *buffer, basic_block bb, int indent, int flags)
-{
- edge e;
- edge_iterator ei;
-
- INDENT (indent);
- pp_string (buffer, "# SUCC:");
- pp_write_text_to_stream (buffer);
- FOR_EACH_EDGE (e, ei, bb->succs)
- if (flags & TDF_SLIM)
- {
- pp_string (buffer, " ");
- if (e->dest == EXIT_BLOCK_PTR)
- pp_string (buffer, "EXIT");
- else
- pp_decimal_int (buffer, e->dest->index);
- }
- else
- dump_edge_info (buffer->buffer->stream, e, 1);
- pp_newline (buffer);
-}
-
-/* Dump PHI nodes of basic block BB to BUFFER with details described
- by FLAGS and indented by INDENT spaces. */
-
-static void
-dump_phi_nodes (pretty_printer *buffer, basic_block bb, int indent, int flags)
-{
- tree phi = phi_nodes (bb);
- if (!phi)
- return;
-
- for (; phi; phi = PHI_CHAIN (phi))
- {
- if (is_gimple_reg (PHI_RESULT (phi)) || (flags & TDF_VOPS))
- {
- INDENT (indent);
- pp_string (buffer, "# ");
- dump_generic_node (buffer, phi, indent, flags, false);
- pp_newline (buffer);
- if (flags & TDF_VERBOSE)
- print_node (buffer->buffer->stream, "", phi, indent);
- }
- }
-}
-
-
-/* Dump jump to basic block BB that is represented implicitly in the cfg
- to BUFFER. */
-
-static void
-pp_cfg_jump (pretty_printer *buffer, basic_block bb)
-{
- tree stmt;
-
- stmt = first_stmt (bb);
-
- pp_string (buffer, "goto <bb ");
- pp_decimal_int (buffer, bb->index);
- pp_string (buffer, ">");
- if (stmt && TREE_CODE (stmt) == LABEL_EXPR)
- {
- pp_string (buffer, " (");
- dump_generic_node (buffer, LABEL_EXPR_LABEL (stmt), 0, 0, false);
- pp_string (buffer, ")");
- }
- pp_semicolon (buffer);
-}
-
-/* Dump edges represented implicitly in basic block BB to BUFFER, indented
- by INDENT spaces, with details given by FLAGS. */
-
-static void
-dump_implicit_edges (pretty_printer *buffer, basic_block bb, int indent,
- int flags)
-{
- edge e;
- edge_iterator ei;
- tree stmt;
-
- stmt = last_stmt (bb);
- if (stmt && TREE_CODE (stmt) == COND_EXPR)
- {
- edge true_edge, false_edge;
-
- /* When we are emitting the code or changing CFG, it is possible that
- the edges are not yet created. When we are using debug_bb in such
- a situation, we do not want it to crash. */
- if (EDGE_COUNT (bb->succs) != 2)
- return;
- extract_true_false_edges_from_block (bb, &true_edge, &false_edge);
-
- INDENT (indent + 2);
- pp_cfg_jump (buffer, true_edge->dest);
- newline_and_indent (buffer, indent);
- pp_string (buffer, "else");
- newline_and_indent (buffer, indent + 2);
- pp_cfg_jump (buffer, false_edge->dest);
- pp_newline (buffer);
- return;
- }
-
- /* If there is a fallthru edge, we may need to add an artificial goto to the
- dump. */
- FOR_EACH_EDGE (e, ei, bb->succs)
- if (e->flags & EDGE_FALLTHRU)
- break;
- if (e && e->dest != bb->next_bb)
- {
- INDENT (indent);
-
- if ((flags & TDF_LINENO) && e->goto_locus != UNKNOWN_LOCATION)
- {
- expanded_location goto_xloc;
- goto_xloc = expand_location (e->goto_locus);
- pp_character (buffer, '[');
- if (goto_xloc.file)
- {
- pp_string (buffer, goto_xloc.file);
- pp_string (buffer, " : ");
- }
- pp_decimal_int (buffer, goto_xloc.line);
- pp_string (buffer, "] ");
- }
-
- pp_cfg_jump (buffer, e->dest);
- pp_newline (buffer);
- }
-}
-
-/* Dumps basic block BB to buffer BUFFER with details described by FLAGS and
- indented by INDENT spaces. */
-
-static void
-dump_generic_bb_buff (pretty_printer *buffer, basic_block bb,
- int indent, int flags)
-{
- block_stmt_iterator bsi;
- tree stmt;
- int label_indent = indent - 2;
-
- if (label_indent < 0)
- label_indent = 0;
-
- dump_bb_header (buffer, bb, indent, flags);
-
- dump_phi_nodes (buffer, bb, indent, flags);
-
- for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
- {
- int curr_indent;
-
- stmt = bsi_stmt (bsi);
-
- curr_indent = TREE_CODE (stmt) == LABEL_EXPR ? label_indent : indent;
-
- INDENT (curr_indent);
- dump_generic_node (buffer, stmt, curr_indent, flags, true);
- pp_newline (buffer);
- dump_histograms_for_stmt (cfun, buffer->buffer->stream, stmt);
- if (flags & TDF_VERBOSE)
- print_node (buffer->buffer->stream, "", stmt, curr_indent);
- }
-
- dump_implicit_edges (buffer, bb, indent, flags);
-
- if (flags & TDF_BLOCKS)
- dump_bb_end (buffer, bb, indent, flags);
-}
diff --git a/gcc/tree-profile.c b/gcc/tree-profile.c
index 9aac154b436..20ded1b9f75 100644
--- a/gcc/tree-profile.c
+++ b/gcc/tree-profile.c
@@ -164,12 +164,13 @@ tree_init_edge_profiler (void)
/* Output instructions as GIMPLE trees to increment the edge
execution count, and insert them on E. We rely on
- bsi_insert_on_edge to preserve the order. */
+ gsi_insert_on_edge to preserve the order. */
static void
tree_gen_edge_profiler (int edgeno, edge e)
{
- tree ref, one, stmt1, stmt2, stmt3;
+ tree ref, one;
+ gimple stmt1, stmt2, stmt3;
/* We share one temporary variable declaration per function. This
gets re-set in tree_profiling. */
@@ -177,26 +178,24 @@ tree_gen_edge_profiler (int edgeno, edge e)
gcov_type_tmp_var = create_tmp_var (gcov_type_node, "PROF_edge_counter");
ref = tree_coverage_counter_ref (GCOV_COUNTER_ARCS, edgeno);
one = build_int_cst (gcov_type_node, 1);
- stmt1 = build_gimple_modify_stmt (gcov_type_tmp_var, ref);
- stmt2 = build_gimple_modify_stmt (gcov_type_tmp_var,
- build2 (PLUS_EXPR, gcov_type_node,
- gcov_type_tmp_var, one));
- stmt3 = build_gimple_modify_stmt (unshare_expr (ref), gcov_type_tmp_var);
- bsi_insert_on_edge (e, stmt1);
- bsi_insert_on_edge (e, stmt2);
- bsi_insert_on_edge (e, stmt3);
+ stmt1 = gimple_build_assign (gcov_type_tmp_var, ref);
+ stmt2 = gimple_build_assign_with_ops (PLUS_EXPR, gcov_type_tmp_var,
+ gcov_type_tmp_var, one);
+ stmt3 = gimple_build_assign (unshare_expr (ref), gcov_type_tmp_var);
+ gsi_insert_on_edge (e, stmt1);
+ gsi_insert_on_edge (e, stmt2);
+ gsi_insert_on_edge (e, stmt3);
}
-/* Emits code to get VALUE to instrument at BSI, and returns the
+/* Emits code to get VALUE to instrument at GSI, and returns the
variable containing the value. */
static tree
-prepare_instrumented_value (block_stmt_iterator *bsi,
- histogram_value value)
+prepare_instrumented_value (gimple_stmt_iterator *gsi, histogram_value value)
{
tree val = value->hvalue.value;
- return force_gimple_operand_bsi (bsi, fold_convert (gcov_type_node, val),
- true, NULL_TREE, true, BSI_SAME_STMT);
+ return force_gimple_operand_gsi (gsi, fold_convert (gcov_type_node, val),
+ true, NULL_TREE, true, GSI_SAME_STMT);
}
/* Output instructions as GIMPLE trees to increment the interval histogram
@@ -206,20 +205,23 @@ prepare_instrumented_value (block_stmt_iterator *bsi,
static void
tree_gen_interval_profiler (histogram_value value, unsigned tag, unsigned base)
{
- tree stmt = value->hvalue.stmt;
- block_stmt_iterator bsi = bsi_for_stmt (stmt);
+ gimple stmt = value->hvalue.stmt;
+ gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
tree ref = tree_coverage_counter_ref (tag, base), ref_ptr;
- tree call, val;
- tree start = build_int_cst_type (integer_type_node, value->hdata.intvl.int_start);
- tree steps = build_int_cst_type (unsigned_type_node, value->hdata.intvl.steps);
+ gimple call;
+ tree val;
+ tree start = build_int_cst_type (integer_type_node,
+ value->hdata.intvl.int_start);
+ tree steps = build_int_cst_type (unsigned_type_node,
+ value->hdata.intvl.steps);
- ref_ptr = force_gimple_operand_bsi (&bsi,
+ ref_ptr = force_gimple_operand_gsi (&gsi,
build_addr (ref, current_function_decl),
- true, NULL_TREE, true, BSI_SAME_STMT);
- val = prepare_instrumented_value (&bsi, value);
- call = build_call_expr (tree_interval_profiler_fn, 4,
- ref_ptr, val, start, steps);
- bsi_insert_before (&bsi, call, BSI_SAME_STMT);
+ true, NULL_TREE, true, GSI_SAME_STMT);
+ val = prepare_instrumented_value (&gsi, value);
+ call = gimple_build_call (tree_interval_profiler_fn, 4,
+ ref_ptr, val, start, steps);
+ gsi_insert_before (&gsi, call, GSI_SAME_STMT);
}
/* Output instructions as GIMPLE trees to increment the power of two histogram
@@ -229,16 +231,17 @@ tree_gen_interval_profiler (histogram_value value, unsigned tag, unsigned base)
static void
tree_gen_pow2_profiler (histogram_value value, unsigned tag, unsigned base)
{
- tree stmt = value->hvalue.stmt;
- block_stmt_iterator bsi = bsi_for_stmt (stmt);
+ gimple stmt = value->hvalue.stmt;
+ gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
tree ref_ptr = tree_coverage_counter_addr (tag, base);
- tree call, val;
+ gimple call;
+ tree val;
- ref_ptr = force_gimple_operand_bsi (&bsi, ref_ptr,
- true, NULL_TREE, true, BSI_SAME_STMT);
- val = prepare_instrumented_value (&bsi, value);
- call = build_call_expr (tree_pow2_profiler_fn, 2, ref_ptr, val);
- bsi_insert_before (&bsi, call, BSI_SAME_STMT);
+ ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
+ true, NULL_TREE, true, GSI_SAME_STMT);
+ val = prepare_instrumented_value (&gsi, value);
+ call = gimple_build_call (tree_pow2_profiler_fn, 2, ref_ptr, val);
+ gsi_insert_before (&gsi, call, GSI_SAME_STMT);
}
/* Output instructions as GIMPLE trees for code to find the most common value.
@@ -248,16 +251,17 @@ tree_gen_pow2_profiler (histogram_value value, unsigned tag, unsigned base)
static void
tree_gen_one_value_profiler (histogram_value value, unsigned tag, unsigned base)
{
- tree stmt = value->hvalue.stmt;
- block_stmt_iterator bsi = bsi_for_stmt (stmt);
+ gimple stmt = value->hvalue.stmt;
+ gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
tree ref_ptr = tree_coverage_counter_addr (tag, base);
- tree call, val;
+ gimple call;
+ tree val;
- ref_ptr = force_gimple_operand_bsi (&bsi, ref_ptr,
- true, NULL_TREE, true, BSI_SAME_STMT);
- val = prepare_instrumented_value (&bsi, value);
- call = build_call_expr (tree_one_value_profiler_fn, 2, ref_ptr, val);
- bsi_insert_before (&bsi, call, BSI_SAME_STMT);
+ ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
+ true, NULL_TREE, true, GSI_SAME_STMT);
+ val = prepare_instrumented_value (&gsi, value);
+ call = gimple_build_call (tree_one_value_profiler_fn, 2, ref_ptr, val);
+ gsi_insert_before (&gsi, call, GSI_SAME_STMT);
}
@@ -270,13 +274,14 @@ tree_gen_one_value_profiler (histogram_value value, unsigned tag, unsigned base)
static void
tree_gen_ic_profiler (histogram_value value, unsigned tag, unsigned base)
{
- tree tmp1, stmt1, stmt2, stmt3;
- tree stmt = value->hvalue.stmt;
- block_stmt_iterator bsi = bsi_for_stmt (stmt);
+ tree tmp1;
+ gimple stmt1, stmt2, stmt3;
+ gimple stmt = value->hvalue.stmt;
+ gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
tree ref_ptr = tree_coverage_counter_addr (tag, base);
- ref_ptr = force_gimple_operand_bsi (&bsi, ref_ptr,
- true, NULL_TREE, true, BSI_SAME_STMT);
+ ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
+ true, NULL_TREE, true, GSI_SAME_STMT);
/* Insert code:
@@ -285,13 +290,13 @@ tree_gen_ic_profiler (histogram_value value, unsigned tag, unsigned base)
*/
tmp1 = create_tmp_var (ptr_void, "PROF");
- stmt1 = build_gimple_modify_stmt (ic_gcov_type_ptr_var, ref_ptr);
- stmt2 = build_gimple_modify_stmt (tmp1, unshare_expr (value->hvalue.value));
- stmt3 = build_gimple_modify_stmt (ic_void_ptr_var, tmp1);
+ stmt1 = gimple_build_assign (ic_gcov_type_ptr_var, ref_ptr);
+ stmt2 = gimple_build_assign (tmp1, unshare_expr (value->hvalue.value));
+ stmt3 = gimple_build_assign (ic_void_ptr_var, tmp1);
- bsi_insert_before (&bsi, stmt1, BSI_SAME_STMT);
- bsi_insert_before (&bsi, stmt2, BSI_SAME_STMT);
- bsi_insert_before (&bsi, stmt3, BSI_SAME_STMT);
+ gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
+ gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
+ gsi_insert_before (&gsi, stmt3, GSI_SAME_STMT);
}
@@ -304,18 +309,15 @@ static void
tree_gen_ic_func_profiler (void)
{
struct cgraph_node * c_node = cgraph_node (current_function_decl);
- block_stmt_iterator bsi;
+ gimple_stmt_iterator gsi;
edge e;
basic_block bb;
edge_iterator ei;
- tree stmt1, stmt2;
+ gimple stmt1, stmt2;
tree tree_uid, cur_func;
- if (flag_unit_at_a_time)
- {
- if (!c_node->needed)
- return;
- }
+ if (!c_node->needed)
+ return;
tree_init_edge_profiler ();
@@ -324,30 +326,30 @@ tree_gen_ic_func_profiler (void)
tree void0;
bb = split_edge (e);
- bsi = bsi_start (bb);
+ gsi = gsi_start_bb (bb);
- cur_func = force_gimple_operand_bsi (&bsi,
+ cur_func = force_gimple_operand_gsi (&gsi,
build_addr (current_function_decl,
current_function_decl),
true, NULL_TREE,
- true, BSI_SAME_STMT);
+ true, GSI_SAME_STMT);
tree_uid = build_int_cst (gcov_type_node, c_node->pid);
- stmt1 = build_call_expr (tree_indirect_call_profiler_fn, 4,
- ic_gcov_type_ptr_var,
- tree_uid,
- cur_func,
- ic_void_ptr_var);
- bsi_insert_after (&bsi, stmt1, BSI_NEW_STMT);
+ stmt1 = gimple_build_call (tree_indirect_call_profiler_fn, 4,
+ ic_gcov_type_ptr_var,
+ tree_uid,
+ cur_func,
+ ic_void_ptr_var);
+ gsi_insert_after (&gsi, stmt1, GSI_NEW_STMT);
gcc_assert (EDGE_COUNT (bb->succs) == 1);
bb = split_edge (EDGE_I (bb->succs, 0));
- bsi = bsi_start (bb);
+ gsi = gsi_start_bb (bb);
/* Set __gcov_indirect_call_callee to 0,
so that calls from other modules won't get misattributed
to the last caller of the current callee. */
void0 = build_int_cst (build_pointer_type (void_type_node), 0);
- stmt2 = build_gimple_modify_stmt (ic_void_ptr_var, void0);
- bsi_insert_after (&bsi, stmt2, BSI_NEW_STMT);
+ stmt2 = gimple_build_assign (ic_void_ptr_var, void0);
+ gsi_insert_after (&gsi, stmt2, GSI_NEW_STMT);
}
}
@@ -357,9 +359,9 @@ tree_gen_ic_func_profiler (void)
section for counters, BASE is offset of the counter position. */
static void
-tree_gen_const_delta_profiler (histogram_value value ATTRIBUTE_UNUSED,
- unsigned tag ATTRIBUTE_UNUSED,
- unsigned base ATTRIBUTE_UNUSED)
+tree_gen_const_delta_profiler (histogram_value value ATTRIBUTE_UNUSED,
+ unsigned tag ATTRIBUTE_UNUSED,
+ unsigned base ATTRIBUTE_UNUSED)
{
/* FIXME implement this. */
#ifdef ENABLE_CHECKING
@@ -375,17 +377,18 @@ tree_gen_const_delta_profiler (histogram_value value ATTRIBUTE_UNUSED,
static void
tree_gen_average_profiler (histogram_value value, unsigned tag, unsigned base)
{
- tree stmt = value->hvalue.stmt;
- block_stmt_iterator bsi = bsi_for_stmt (stmt);
+ gimple stmt = value->hvalue.stmt;
+ gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
tree ref_ptr = tree_coverage_counter_addr (tag, base);
- tree call, val;
+ gimple call;
+ tree val;
- ref_ptr = force_gimple_operand_bsi (&bsi, ref_ptr,
+ ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
true, NULL_TREE,
- true, BSI_SAME_STMT);
- val = prepare_instrumented_value (&bsi, value);
- call = build_call_expr (tree_average_profiler_fn, 2, ref_ptr, val);
- bsi_insert_before (&bsi, call, BSI_SAME_STMT);
+ true, GSI_SAME_STMT);
+ val = prepare_instrumented_value (&gsi, value);
+ call = gimple_build_call (tree_average_profiler_fn, 2, ref_ptr, val);
+ gsi_insert_before (&gsi, call, GSI_SAME_STMT);
}
/* Output instructions as GIMPLE trees to increment the ior histogram
@@ -395,16 +398,17 @@ tree_gen_average_profiler (histogram_value value, unsigned tag, unsigned base)
static void
tree_gen_ior_profiler (histogram_value value, unsigned tag, unsigned base)
{
- tree stmt = value->hvalue.stmt;
- block_stmt_iterator bsi = bsi_for_stmt (stmt);
+ gimple stmt = value->hvalue.stmt;
+ gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
tree ref_ptr = tree_coverage_counter_addr (tag, base);
- tree call, val;
+ gimple call;
+ tree val;
- ref_ptr = force_gimple_operand_bsi (&bsi, ref_ptr,
- true, NULL_TREE, true, BSI_SAME_STMT);
- val = prepare_instrumented_value (&bsi, value);
- call = build_call_expr (tree_ior_profiler_fn, 2, ref_ptr, val);
- bsi_insert_before (&bsi, call, BSI_SAME_STMT);
+ ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
+ true, NULL_TREE, true, GSI_SAME_STMT);
+ val = prepare_instrumented_value (&gsi, value);
+ call = gimple_build_call (tree_ior_profiler_fn, 2, ref_ptr, val);
+ gsi_insert_before (&gsi, call, GSI_SAME_STMT);
}
/* Return 1 if tree-based profiling is in effect, else 0.
@@ -417,7 +421,7 @@ do_tree_profiling (void)
if (profile_arc_flag || flag_test_coverage || flag_branch_probabilities)
{
tree_register_profile_hooks ();
- tree_register_value_prof_hooks ();
+ gimple_register_value_prof_hooks ();
return true;
}
return false;
diff --git a/gcc/tree-scalar-evolution.c b/gcc/tree-scalar-evolution.c
index 57fe59b186e..67fcd08dda0 100644
--- a/gcc/tree-scalar-evolution.c
+++ b/gcc/tree-scalar-evolution.c
@@ -48,7 +48,7 @@ along with GCC; see the file COPYING3. If not see
Given a scalar variable to be analyzed, follow the SSA edge to
its definition:
- - When the definition is a GIMPLE_MODIFY_STMT: if the right hand side
+ - When the definition is a GIMPLE_ASSIGN: if the right hand side
(RHS) of the definition cannot be statically analyzed, the answer
of the analyzer is: "don't know".
Otherwise, for all the variables that are not yet analyzed in the
@@ -397,7 +397,7 @@ chrec_contains_symbols_defined_in_loop (const_tree chrec, unsigned loop_nb)
if (TREE_CODE (chrec) == SSA_NAME)
{
- tree def = SSA_NAME_DEF_STMT (chrec);
+ gimple def = SSA_NAME_DEF_STMT (chrec);
struct loop *def_loop = loop_containing_stmt (def);
struct loop *loop = get_loop (loop_nb);
@@ -421,13 +421,13 @@ chrec_contains_symbols_defined_in_loop (const_tree chrec, unsigned loop_nb)
/* Return true when PHI is a loop-phi-node. */
static bool
-loop_phi_node_p (tree phi)
+loop_phi_node_p (gimple phi)
{
/* The implementation of this function is based on the following
property: "all the loop-phi-nodes of a loop are contained in the
loop's header basic block". */
- return loop_containing_stmt (phi)->header == bb_for_stmt (phi);
+ return loop_containing_stmt (phi)->header == gimple_bb (phi);
}
/* Compute the scalar evolution for EVOLUTION_FN after crossing LOOP.
@@ -656,7 +656,7 @@ get_scalar_evolution (tree scalar)
static tree
add_to_evolution_1 (unsigned loop_nb, tree chrec_before, tree to_add,
- tree at_stmt)
+ gimple at_stmt)
{
tree type, left, right;
struct loop *loop = get_loop (loop_nb), *chloop;
@@ -853,7 +853,7 @@ add_to_evolution_1 (unsigned loop_nb, tree chrec_before, tree to_add,
static tree
add_to_evolution (unsigned loop_nb, tree chrec_before, enum tree_code code,
- tree to_add, tree at_stmt)
+ tree to_add, gimple at_stmt)
{
tree type = chrec_type (to_add);
tree res = NULL_TREE;
@@ -918,47 +918,14 @@ set_nb_iterations_in_loop (struct loop *loop,
scalar evolution analysis. For the moment, greedily select all the
loop nests we could analyze. */
-/* Return true when it is possible to analyze the condition expression
- EXPR. */
-
-static bool
-analyzable_condition (const_tree expr)
-{
- tree condition;
-
- if (TREE_CODE (expr) != COND_EXPR)
- return false;
-
- condition = TREE_OPERAND (expr, 0);
-
- switch (TREE_CODE (condition))
- {
- case SSA_NAME:
- return true;
-
- case LT_EXPR:
- case LE_EXPR:
- case GT_EXPR:
- case GE_EXPR:
- case EQ_EXPR:
- case NE_EXPR:
- return true;
-
- default:
- return false;
- }
-
- return false;
-}
-
/* For a loop with a single exit edge, return the COND_EXPR that
guards the exit edge. If the expression is too difficult to
analyze, then give up. */
-tree
+gimple
get_loop_exit_condition (const struct loop *loop)
{
- tree res = NULL_TREE;
+ gimple res = NULL;
edge exit_edge = single_exit (loop);
if (dump_file && (dump_flags & TDF_DETAILS))
@@ -966,16 +933,16 @@ get_loop_exit_condition (const struct loop *loop)
if (exit_edge)
{
- tree expr;
+ gimple stmt;
- expr = last_stmt (exit_edge->src);
- if (analyzable_condition (expr))
- res = expr;
+ stmt = last_stmt (exit_edge->src);
+ if (gimple_code (stmt) == GIMPLE_COND)
+ res = stmt;
}
if (dump_file && (dump_flags & TDF_DETAILS))
{
- print_generic_expr (dump_file, res, 0);
+ print_gimple_stmt (dump_file, res, 0, 0);
fprintf (dump_file, ")\n");
}
@@ -986,7 +953,7 @@ get_loop_exit_condition (const struct loop *loop)
static void
get_exit_conditions_rec (struct loop *loop,
- VEC(tree,heap) **exit_conditions)
+ VEC(gimple,heap) **exit_conditions)
{
if (!loop)
return;
@@ -997,10 +964,10 @@ get_exit_conditions_rec (struct loop *loop,
if (single_exit (loop))
{
- tree loop_condition = get_loop_exit_condition (loop);
+ gimple loop_condition = get_loop_exit_condition (loop);
if (loop_condition)
- VEC_safe_push (tree, heap, *exit_conditions, loop_condition);
+ VEC_safe_push (gimple, heap, *exit_conditions, loop_condition);
}
}
@@ -1008,7 +975,7 @@ get_exit_conditions_rec (struct loop *loop,
initializes the EXIT_CONDITIONS array. */
static void
-select_loops_exit_conditions (VEC(tree,heap) **exit_conditions)
+select_loops_exit_conditions (VEC(gimple,heap) **exit_conditions)
{
struct loop *function_body = current_loops->tree_root;
@@ -1025,59 +992,23 @@ typedef enum t_bool {
} t_bool;
-static t_bool follow_ssa_edge (struct loop *loop, tree, tree, tree *, int);
+static t_bool follow_ssa_edge (struct loop *loop, gimple, gimple, tree *, int);
-/* Follow the ssa edge into the right hand side RHS of an assignment.
+/* 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_in_rhs (struct loop *loop, tree at_stmt, tree rhs,
- tree halting_phi, tree *evolution_of_loop, int limit)
+follow_ssa_edge_binary (struct loop *loop, gimple at_stmt,
+ tree type, tree rhs0, enum tree_code code, tree rhs1,
+ gimple halting_phi, tree *evolution_of_loop, int limit)
{
t_bool res = t_false;
- tree rhs0, rhs1;
- tree type_rhs = TREE_TYPE (rhs);
tree evol;
- enum tree_code code;
-
- /* The RHS is one of the following cases:
- - an SSA_NAME,
- - an INTEGER_CST,
- - a PLUS_EXPR,
- - a POINTER_PLUS_EXPR,
- - a MINUS_EXPR,
- - an ASSERT_EXPR,
- - other cases are not yet handled. */
- code = TREE_CODE (rhs);
+
switch (code)
{
- case NOP_EXPR:
- /* This assignment is under the form "a_1 = (cast) rhs. */
- res = follow_ssa_edge_in_rhs (loop, at_stmt, TREE_OPERAND (rhs, 0),
- halting_phi, evolution_of_loop, limit);
- *evolution_of_loop = chrec_convert (TREE_TYPE (rhs),
- *evolution_of_loop, at_stmt);
- break;
-
- case INTEGER_CST:
- /* This assignment is under the form "a_1 = 7". */
- res = t_false;
- break;
-
- case SSA_NAME:
- /* This assignment is under the form: "a_1 = b_2". */
- res = follow_ssa_edge
- (loop, SSA_NAME_DEF_STMT (rhs), halting_phi, evolution_of_loop, limit);
- break;
-
case POINTER_PLUS_EXPR:
case PLUS_EXPR:
- /* This case is under the form "rhs0 + rhs1". */
- rhs0 = TREE_OPERAND (rhs, 0);
- rhs1 = TREE_OPERAND (rhs, 1);
- STRIP_TYPE_NOPS (rhs0);
- STRIP_TYPE_NOPS (rhs1);
-
if (TREE_CODE (rhs0) == SSA_NAME)
{
if (TREE_CODE (rhs1) == SSA_NAME)
@@ -1092,13 +1023,12 @@ follow_ssa_edge_in_rhs (struct loop *loop, tree at_stmt, tree rhs,
evol = *evolution_of_loop;
res = follow_ssa_edge
- (loop, SSA_NAME_DEF_STMT (rhs0), halting_phi,
- &evol, limit);
+ (loop, SSA_NAME_DEF_STMT (rhs0), halting_phi, &evol, limit);
if (res == t_true)
*evolution_of_loop = add_to_evolution
(loop->num,
- chrec_convert (type_rhs, evol, at_stmt),
+ chrec_convert (type, evol, at_stmt),
code, rhs1, at_stmt);
else if (res == t_false)
@@ -1110,7 +1040,7 @@ follow_ssa_edge_in_rhs (struct loop *loop, tree at_stmt, tree rhs,
if (res == t_true)
*evolution_of_loop = add_to_evolution
(loop->num,
- chrec_convert (type_rhs, *evolution_of_loop, at_stmt),
+ chrec_convert (type, *evolution_of_loop, at_stmt),
code, rhs0, at_stmt);
else if (res == t_dont_know)
@@ -1130,7 +1060,7 @@ follow_ssa_edge_in_rhs (struct loop *loop, tree at_stmt, tree rhs,
evolution_of_loop, limit);
if (res == t_true)
*evolution_of_loop = add_to_evolution
- (loop->num, chrec_convert (type_rhs, *evolution_of_loop,
+ (loop->num, chrec_convert (type, *evolution_of_loop,
at_stmt),
code, rhs1, at_stmt);
@@ -1148,7 +1078,7 @@ follow_ssa_edge_in_rhs (struct loop *loop, tree at_stmt, tree rhs,
evolution_of_loop, limit);
if (res == t_true)
*evolution_of_loop = add_to_evolution
- (loop->num, chrec_convert (type_rhs, *evolution_of_loop,
+ (loop->num, chrec_convert (type, *evolution_of_loop,
at_stmt),
code, rhs0, at_stmt);
@@ -1161,16 +1091,10 @@ follow_ssa_edge_in_rhs (struct loop *loop, tree at_stmt, tree rhs,
"a = ... + ...". */
/* And there is nothing to do. */
res = t_false;
-
break;
case MINUS_EXPR:
/* This case is under the form "opnd0 = rhs0 - rhs1". */
- rhs0 = TREE_OPERAND (rhs, 0);
- rhs1 = TREE_OPERAND (rhs, 1);
- STRIP_TYPE_NOPS (rhs0);
- STRIP_TYPE_NOPS (rhs1);
-
if (TREE_CODE (rhs0) == SSA_NAME)
{
/* Match an assignment under the form:
@@ -1186,7 +1110,7 @@ follow_ssa_edge_in_rhs (struct loop *loop, tree at_stmt, tree rhs,
evolution_of_loop, limit);
if (res == t_true)
*evolution_of_loop = add_to_evolution
- (loop->num, chrec_convert (type_rhs, *evolution_of_loop, at_stmt),
+ (loop->num, chrec_convert (type, *evolution_of_loop, at_stmt),
MINUS_EXPR, rhs1, at_stmt);
else if (res == t_dont_know)
@@ -1197,14 +1121,72 @@ follow_ssa_edge_in_rhs (struct loop *loop, tree at_stmt, tree rhs,
"a = ... - ...". */
/* And there is nothing to do. */
res = t_false;
-
break;
+
+ default:
+ res = t_false;
+ }
+
+ return res;
+}
+/* Follow the ssa edge into the expression EXPR.
+ 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,
+ gimple halting_phi, tree *evolution_of_loop, int limit)
+{
+ t_bool res = t_false;
+ tree rhs0, rhs1;
+ tree type = TREE_TYPE (expr);
+ enum tree_code code;
+
+ /* The EXPR is one of the following cases:
+ - an SSA_NAME,
+ - an INTEGER_CST,
+ - a PLUS_EXPR,
+ - a POINTER_PLUS_EXPR,
+ - a MINUS_EXPR,
+ - an ASSERT_EXPR,
+ - other cases are not yet handled. */
+ code = TREE_CODE (expr);
+ switch (code)
+ {
+ case NOP_EXPR:
+ /* This assignment is under the form "a_1 = (cast) rhs. */
+ res = follow_ssa_edge_expr (loop, at_stmt, TREE_OPERAND (expr, 0),
+ halting_phi, evolution_of_loop, limit);
+ *evolution_of_loop = chrec_convert (type, *evolution_of_loop, at_stmt);
+ break;
+
+ case INTEGER_CST:
+ /* This assignment is under the form "a_1 = 7". */
+ res = t_false;
+ break;
+
+ case SSA_NAME:
+ /* This assignment is under the form: "a_1 = b_2". */
+ res = follow_ssa_edge
+ (loop, SSA_NAME_DEF_STMT (expr), halting_phi, evolution_of_loop, limit);
+ break;
+
+ case POINTER_PLUS_EXPR:
+ case PLUS_EXPR:
+ case MINUS_EXPR:
+ /* This case is under the form "rhs0 +- rhs1". */
+ rhs0 = TREE_OPERAND (expr, 0);
+ rhs1 = TREE_OPERAND (expr, 1);
+ STRIP_TYPE_NOPS (rhs0);
+ STRIP_TYPE_NOPS (rhs1);
+ return follow_ssa_edge_binary (loop, at_stmt, type, rhs0, code, rhs1,
+ halting_phi, evolution_of_loop, limit);
+
case ASSERT_EXPR:
{
/* This assignment is of the form: "a_1 = ASSERT_EXPR <a_2, ...>"
It must be handled as a copy assignment of the form a_1 = a_2. */
- tree op0 = ASSERT_EXPR_VAR (rhs);
+ tree op0 = ASSERT_EXPR_VAR (expr);
if (TREE_CODE (op0) == SSA_NAME)
res = follow_ssa_edge (loop, SSA_NAME_DEF_STMT (op0),
halting_phi, evolution_of_loop, limit);
@@ -1222,12 +1204,37 @@ follow_ssa_edge_in_rhs (struct loop *loop, tree at_stmt, tree rhs,
return res;
}
+/* Follow the ssa edge into the right hand side of an assignment STMT.
+ Return true if the strongly connected component has been found. */
+
+static t_bool
+follow_ssa_edge_in_rhs (struct loop *loop, gimple stmt,
+ gimple halting_phi, tree *evolution_of_loop, int limit)
+{
+ tree type = TREE_TYPE (gimple_assign_lhs (stmt));
+ enum tree_code code = gimple_assign_rhs_code (stmt);
+
+ switch (get_gimple_rhs_class (code))
+ {
+ case GIMPLE_BINARY_RHS:
+ return follow_ssa_edge_binary (loop, stmt, type,
+ gimple_assign_rhs1 (stmt), code,
+ gimple_assign_rhs2 (stmt),
+ halting_phi, evolution_of_loop, limit);
+ case GIMPLE_SINGLE_RHS:
+ return follow_ssa_edge_expr (loop, stmt, gimple_assign_rhs1 (stmt),
+ halting_phi, evolution_of_loop, limit);
+ default:
+ return t_false;
+ }
+}
+
/* Checks whether the I-th argument of a PHI comes from a backedge. */
static bool
-backedge_phi_arg_p (const_tree phi, int i)
+backedge_phi_arg_p (gimple phi, int i)
{
- const_edge e = PHI_ARG_EDGE (phi, i);
+ const_edge e = gimple_phi_arg_edge (phi, i);
/* We would in fact like to test EDGE_DFS_BACK here, but we do not care
about updating it anywhere, and this should work as well most of the
@@ -1245,8 +1252,8 @@ backedge_phi_arg_p (const_tree phi, int i)
static inline t_bool
follow_ssa_edge_in_condition_phi_branch (int i,
struct loop *loop,
- tree condition_phi,
- tree halting_phi,
+ gimple condition_phi,
+ gimple halting_phi,
tree *evolution_of_branch,
tree init_cond, int limit)
{
@@ -1280,11 +1287,11 @@ follow_ssa_edge_in_condition_phi_branch (int i,
static t_bool
follow_ssa_edge_in_condition_phi (struct loop *loop,
- tree condition_phi,
- tree halting_phi,
+ gimple condition_phi,
+ gimple halting_phi,
tree *evolution_of_loop, int limit)
{
- int i;
+ int i, n;
tree init = *evolution_of_loop;
tree evolution_of_branch;
t_bool res = follow_ssa_edge_in_condition_phi_branch (0, loop, condition_phi,
@@ -1297,10 +1304,11 @@ follow_ssa_edge_in_condition_phi (struct loop *loop,
*evolution_of_loop = evolution_of_branch;
/* If the phi node is just a copy, do not increase the limit. */
- if (PHI_NUM_ARGS (condition_phi) > 1)
+ n = gimple_phi_num_args (condition_phi);
+ if (n > 1)
limit++;
- for (i = 1; i < PHI_NUM_ARGS (condition_phi); i++)
+ for (i = 1; i < n; i++)
{
/* Quickly give up when the evolution of one of the branches is
not known. */
@@ -1328,8 +1336,8 @@ follow_ssa_edge_in_condition_phi (struct loop *loop,
static t_bool
follow_ssa_edge_inner_loop_phi (struct loop *outer_loop,
- tree loop_phi_node,
- tree halting_phi,
+ gimple loop_phi_node,
+ gimple halting_phi,
tree *evolution_of_loop, int limit)
{
struct loop *loop = loop_containing_stmt (loop_phi_node);
@@ -1340,19 +1348,19 @@ follow_ssa_edge_inner_loop_phi (struct loop *outer_loop,
if (ev == PHI_RESULT (loop_phi_node))
{
t_bool res = t_false;
- int i;
+ int i, n = gimple_phi_num_args (loop_phi_node);
- for (i = 0; i < PHI_NUM_ARGS (loop_phi_node); i++)
+ for (i = 0; i < n; i++)
{
tree arg = PHI_ARG_DEF (loop_phi_node, i);
basic_block bb;
/* Follow the edges that exit the inner loop. */
- bb = PHI_ARG_EDGE (loop_phi_node, i)->src;
+ bb = gimple_phi_arg_edge (loop_phi_node, i)->src;
if (!flow_bb_inside_loop_p (loop, bb))
- res = follow_ssa_edge_in_rhs (outer_loop, loop_phi_node,
- arg, halting_phi,
- evolution_of_loop, limit);
+ res = follow_ssa_edge_expr (outer_loop, loop_phi_node,
+ arg, halting_phi,
+ evolution_of_loop, limit);
if (res == t_true)
break;
}
@@ -1366,20 +1374,20 @@ follow_ssa_edge_inner_loop_phi (struct loop *outer_loop,
/* Otherwise, compute the overall effect of the inner loop. */
ev = compute_overall_effect_of_inner_loop (loop, ev);
- return follow_ssa_edge_in_rhs (outer_loop, loop_phi_node, ev, halting_phi,
- evolution_of_loop, limit);
+ return follow_ssa_edge_expr (outer_loop, loop_phi_node, ev, halting_phi,
+ evolution_of_loop, limit);
}
/* Follow an SSA edge from a loop-phi-node to itself, constructing a
path that is analyzed on the return walk. */
static t_bool
-follow_ssa_edge (struct loop *loop, tree def, tree halting_phi,
+follow_ssa_edge (struct loop *loop, gimple def, gimple halting_phi,
tree *evolution_of_loop, int limit)
{
struct loop *def_loop;
- if (TREE_CODE (def) == NOP_EXPR)
+ if (gimple_nop_p (def))
return t_false;
/* Give up if the path is longer than the MAX that we allow. */
@@ -1388,9 +1396,9 @@ follow_ssa_edge (struct loop *loop, tree def, tree halting_phi,
def_loop = loop_containing_stmt (def);
- switch (TREE_CODE (def))
+ switch (gimple_code (def))
{
- case PHI_NODE:
+ case GIMPLE_PHI:
if (!loop_phi_node_p (def))
/* DEF is a condition-phi-node. Follow the branches, and
record their evolutions. Finally, merge the collected
@@ -1419,15 +1427,13 @@ follow_ssa_edge (struct loop *loop, tree def, tree halting_phi,
/* Outer loop. */
return t_false;
- case GIMPLE_MODIFY_STMT:
- return follow_ssa_edge_in_rhs (loop, def,
- GIMPLE_STMT_OPERAND (def, 1),
- halting_phi,
+ case GIMPLE_ASSIGN:
+ return follow_ssa_edge_in_rhs (loop, def, halting_phi,
evolution_of_loop, limit);
default:
/* At this level of abstraction, the program is just a set
- of GIMPLE_MODIFY_STMTs and PHI_NODEs. In principle there is no
+ of GIMPLE_ASSIGNs and PHI_NODEs. In principle there is no
other node to be handled. */
return t_false;
}
@@ -1439,10 +1445,10 @@ follow_ssa_edge (struct loop *loop, tree def, tree halting_phi,
function from LOOP_PHI_NODE to LOOP_PHI_NODE in the loop. */
static tree
-analyze_evolution_in_loop (tree loop_phi_node,
+analyze_evolution_in_loop (gimple loop_phi_node,
tree init_cond)
{
- int i;
+ 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);
basic_block bb;
@@ -1451,18 +1457,19 @@ analyze_evolution_in_loop (tree loop_phi_node,
{
fprintf (dump_file, "(analyze_evolution_in_loop \n");
fprintf (dump_file, " (loop_phi_node = ");
- print_generic_expr (dump_file, loop_phi_node, 0);
+ print_gimple_stmt (dump_file, loop_phi_node, 0, 0);
fprintf (dump_file, ")\n");
}
- for (i = 0; i < PHI_NUM_ARGS (loop_phi_node); i++)
+ for (i = 0; i < n; i++)
{
tree arg = PHI_ARG_DEF (loop_phi_node, i);
- tree ssa_chain, ev_fn;
+ gimple ssa_chain;
+ tree ev_fn;
t_bool res;
/* Select the edges that enter the loop body. */
- bb = PHI_ARG_EDGE (loop_phi_node, i)->src;
+ bb = gimple_phi_arg_edge (loop_phi_node, i)->src;
if (!flow_bb_inside_loop_p (loop, bb))
continue;
@@ -1509,24 +1516,25 @@ analyze_evolution_in_loop (tree loop_phi_node,
loop, and leaves this task to the on-demand tree reconstructor. */
static tree
-analyze_initial_condition (tree loop_phi_node)
+analyze_initial_condition (gimple loop_phi_node)
{
- int i;
+ int i, n;
tree init_cond = chrec_not_analyzed_yet;
- struct loop *loop = bb_for_stmt (loop_phi_node)->loop_father;
+ struct loop *loop = loop_containing_stmt (loop_phi_node);
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "(analyze_initial_condition \n");
fprintf (dump_file, " (loop_phi_node = \n");
- print_generic_expr (dump_file, loop_phi_node, 0);
+ print_gimple_stmt (dump_file, loop_phi_node, 0, 0);
fprintf (dump_file, ")\n");
}
- for (i = 0; i < PHI_NUM_ARGS (loop_phi_node); i++)
+ n = gimple_phi_num_args (loop_phi_node);
+ for (i = 0; i < n; i++)
{
tree branch = PHI_ARG_DEF (loop_phi_node, i);
- basic_block bb = PHI_ARG_EDGE (loop_phi_node, i)->src;
+ basic_block bb = gimple_phi_arg_edge (loop_phi_node, i)->src;
/* When the branch is oriented to the loop's body, it does
not contribute to the initial condition. */
@@ -1565,7 +1573,7 @@ analyze_initial_condition (tree loop_phi_node)
/* Analyze the scalar evolution for LOOP_PHI_NODE. */
static tree
-interpret_loop_phi (struct loop *loop, tree loop_phi_node)
+interpret_loop_phi (struct loop *loop, gimple loop_phi_node)
{
tree res;
struct loop *phi_loop = loop_containing_stmt (loop_phi_node);
@@ -1597,12 +1605,12 @@ interpret_loop_phi (struct loop *loop, tree loop_phi_node)
analyzed. */
static tree
-interpret_condition_phi (struct loop *loop, tree condition_phi)
+interpret_condition_phi (struct loop *loop, gimple condition_phi)
{
- int i;
+ int i, n = gimple_phi_num_args (condition_phi);
tree res = chrec_not_analyzed_yet;
- for (i = 0; i < PHI_NUM_ARGS (condition_phi); i++)
+ for (i = 0; i < n; i++)
{
tree branch_chrec;
@@ -1621,88 +1629,83 @@ interpret_condition_phi (struct loop *loop, tree condition_phi)
return res;
}
-/* Interpret the right hand side of a GIMPLE_MODIFY_STMT OPND1. If we didn't
+/* Interpret the operation RHS1 OP RHS2. If we didn't
analyze this node before, follow the definitions until ending
- either on an analyzed GIMPLE_MODIFY_STMT, or on a loop-phi-node. On the
+ either on an analyzed GIMPLE_ASSIGN, or on a loop-phi-node. On the
return path, this function propagates evolutions (ala constant copy
propagation). OPND1 is not a GIMPLE expression because we could
analyze the effect of an inner loop: see interpret_loop_phi. */
static tree
-interpret_rhs_modify_stmt (struct loop *loop, tree at_stmt,
- tree opnd1, tree type)
+interpret_rhs_expr (struct loop *loop, gimple at_stmt,
+ tree type, tree rhs1, enum tree_code code, tree rhs2)
{
- tree res, opnd10, opnd11, chrec10, chrec11;
+ tree res, chrec1, chrec2;
+
+ if (get_gimple_rhs_class (code) == GIMPLE_SINGLE_RHS)
+ {
+ if (is_gimple_min_invariant (rhs1))
+ return chrec_convert (type, rhs1, at_stmt);
+
+ if (code == SSA_NAME)
+ return chrec_convert (type, analyze_scalar_evolution (loop, rhs1),
+ at_stmt);
- if (is_gimple_min_invariant (opnd1))
- return chrec_convert (type, opnd1, at_stmt);
+ if (code == ASSERT_EXPR)
+ {
+ rhs1 = ASSERT_EXPR_VAR (rhs1);
+ return chrec_convert (type, analyze_scalar_evolution (loop, rhs1),
+ at_stmt);
+ }
+
+ return chrec_dont_know;
+ }
- switch (TREE_CODE (opnd1))
+ switch (code)
{
case POINTER_PLUS_EXPR:
- opnd10 = TREE_OPERAND (opnd1, 0);
- opnd11 = TREE_OPERAND (opnd1, 1);
- chrec10 = analyze_scalar_evolution (loop, opnd10);
- chrec11 = analyze_scalar_evolution (loop, opnd11);
- chrec10 = chrec_convert (type, chrec10, at_stmt);
- chrec11 = chrec_convert (sizetype, chrec11, at_stmt);
- res = chrec_fold_plus (type, chrec10, chrec11);
+ chrec1 = analyze_scalar_evolution (loop, rhs1);
+ chrec2 = analyze_scalar_evolution (loop, rhs2);
+ chrec1 = chrec_convert (type, chrec1, at_stmt);
+ chrec2 = chrec_convert (sizetype, chrec2, at_stmt);
+ res = chrec_fold_plus (type, chrec1, chrec2);
break;
case PLUS_EXPR:
- opnd10 = TREE_OPERAND (opnd1, 0);
- opnd11 = TREE_OPERAND (opnd1, 1);
- chrec10 = analyze_scalar_evolution (loop, opnd10);
- chrec11 = analyze_scalar_evolution (loop, opnd11);
- chrec10 = chrec_convert (type, chrec10, at_stmt);
- chrec11 = chrec_convert (type, chrec11, at_stmt);
- res = chrec_fold_plus (type, chrec10, chrec11);
+ chrec1 = analyze_scalar_evolution (loop, rhs1);
+ chrec2 = analyze_scalar_evolution (loop, rhs2);
+ chrec1 = chrec_convert (type, chrec1, at_stmt);
+ chrec2 = chrec_convert (type, chrec2, at_stmt);
+ res = chrec_fold_plus (type, chrec1, chrec2);
break;
case MINUS_EXPR:
- opnd10 = TREE_OPERAND (opnd1, 0);
- opnd11 = TREE_OPERAND (opnd1, 1);
- chrec10 = analyze_scalar_evolution (loop, opnd10);
- chrec11 = analyze_scalar_evolution (loop, opnd11);
- chrec10 = chrec_convert (type, chrec10, at_stmt);
- chrec11 = chrec_convert (type, chrec11, at_stmt);
- res = chrec_fold_minus (type, chrec10, chrec11);
+ chrec1 = analyze_scalar_evolution (loop, rhs1);
+ chrec2 = analyze_scalar_evolution (loop, rhs2);
+ chrec1 = chrec_convert (type, chrec1, at_stmt);
+ chrec2 = chrec_convert (type, chrec2, at_stmt);
+ res = chrec_fold_minus (type, chrec1, chrec2);
break;
case NEGATE_EXPR:
- opnd10 = TREE_OPERAND (opnd1, 0);
- chrec10 = analyze_scalar_evolution (loop, opnd10);
- chrec10 = chrec_convert (type, chrec10, at_stmt);
+ chrec1 = analyze_scalar_evolution (loop, rhs1);
+ chrec1 = chrec_convert (type, chrec1, at_stmt);
/* TYPE may be integer, real or complex, so use fold_convert. */
- res = chrec_fold_multiply (type, chrec10,
+ res = chrec_fold_multiply (type, chrec1,
fold_convert (type, integer_minus_one_node));
break;
case MULT_EXPR:
- opnd10 = TREE_OPERAND (opnd1, 0);
- opnd11 = TREE_OPERAND (opnd1, 1);
- chrec10 = analyze_scalar_evolution (loop, opnd10);
- chrec11 = analyze_scalar_evolution (loop, opnd11);
- chrec10 = chrec_convert (type, chrec10, at_stmt);
- chrec11 = chrec_convert (type, chrec11, at_stmt);
- res = chrec_fold_multiply (type, chrec10, chrec11);
- break;
-
- case SSA_NAME:
- res = chrec_convert (type, analyze_scalar_evolution (loop, opnd1),
- at_stmt);
- break;
-
- case ASSERT_EXPR:
- opnd10 = ASSERT_EXPR_VAR (opnd1);
- res = chrec_convert (type, analyze_scalar_evolution (loop, opnd10),
- at_stmt);
+ chrec1 = analyze_scalar_evolution (loop, rhs1);
+ chrec2 = analyze_scalar_evolution (loop, rhs2);
+ chrec1 = chrec_convert (type, chrec1, at_stmt);
+ chrec2 = chrec_convert (type, chrec2, at_stmt);
+ res = chrec_fold_multiply (type, chrec1, chrec2);
break;
CASE_CONVERT:
- opnd10 = TREE_OPERAND (opnd1, 0);
- chrec10 = analyze_scalar_evolution (loop, opnd10);
- res = chrec_convert (type, chrec10, at_stmt);
+ chrec1 = analyze_scalar_evolution (loop, rhs1);
+ res = chrec_convert (type, chrec1, at_stmt);
break;
default:
@@ -1713,6 +1716,39 @@ interpret_rhs_modify_stmt (struct loop *loop, tree at_stmt,
return res;
}
+/* Interpret the expression EXPR. */
+
+static tree
+interpret_expr (struct loop *loop, gimple at_stmt, tree expr)
+{
+ enum tree_code code;
+ tree type = TREE_TYPE (expr), op0, op1;
+
+ if (automatically_generated_chrec_p (expr))
+ return expr;
+
+ if (TREE_CODE (expr) == POLYNOMIAL_CHREC)
+ return chrec_dont_know;
+
+ extract_ops_from_tree (expr, &code, &op0, &op1);
+
+ return interpret_rhs_expr (loop, at_stmt, type,
+ op0, code, op1);
+}
+
+/* Interpret the rhs of the assignment STMT. */
+
+static tree
+interpret_gimple_assign (struct loop *loop, gimple stmt)
+{
+ tree type = TREE_TYPE (gimple_assign_lhs (stmt));
+ enum tree_code code = gimple_assign_rhs_code (stmt);
+
+ return interpret_rhs_expr (loop, stmt, type,
+ gimple_assign_rhs1 (stmt), code,
+ gimple_assign_rhs2 (stmt));
+}
+
/* This section contains all the entry points:
@@ -1744,7 +1780,8 @@ compute_scalar_evolution_in_loop (struct loop *wrto_loop,
static tree
analyze_scalar_evolution_1 (struct loop *loop, tree var, tree res)
{
- tree def, type = TREE_TYPE (var);
+ tree type = TREE_TYPE (var);
+ gimple def;
basic_block bb;
struct loop *def_loop;
@@ -1752,10 +1789,10 @@ analyze_scalar_evolution_1 (struct loop *loop, tree var, tree res)
return chrec_dont_know;
if (TREE_CODE (var) != SSA_NAME)
- return interpret_rhs_modify_stmt (loop, NULL_TREE, var, type);
+ return interpret_expr (loop, NULL, var);
def = SSA_NAME_DEF_STMT (var);
- bb = bb_for_stmt (def);
+ bb = gimple_bb (def);
def_loop = bb ? bb->loop_father : NULL;
if (bb == NULL
@@ -1783,14 +1820,13 @@ analyze_scalar_evolution_1 (struct loop *loop, tree var, tree res)
goto set_and_end;
}
- switch (TREE_CODE (def))
+ switch (gimple_code (def))
{
- case GIMPLE_MODIFY_STMT:
- res = interpret_rhs_modify_stmt (loop, def,
- GIMPLE_STMT_OPERAND (def, 1), type);
+ case GIMPLE_ASSIGN:
+ res = interpret_gimple_assign (loop, def);
break;
- case PHI_NODE:
+ case GIMPLE_PHI:
if (loop_phi_node_p (def))
res = interpret_loop_phi (loop, def);
else
@@ -1845,9 +1881,6 @@ analyze_scalar_evolution (struct loop *loop, tree var)
res = analyze_scalar_evolution_1 (loop, var, get_scalar_evolution (var));
- if (TREE_CODE (var) == SSA_NAME && res == chrec_dont_know)
- res = var;
-
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, ")\n");
@@ -1934,7 +1967,8 @@ loop_closed_phi_def (tree var)
{
struct loop *loop;
edge exit;
- tree phi;
+ gimple phi;
+ gimple_stmt_iterator psi;
if (var == NULL_TREE
|| TREE_CODE (var) != SSA_NAME)
@@ -1945,9 +1979,12 @@ loop_closed_phi_def (tree var)
if (!exit)
return NULL_TREE;
- for (phi = phi_nodes (exit->dest); phi; phi = PHI_CHAIN (phi))
- if (PHI_ARG_DEF_FROM_EDGE (phi, exit) == var)
- return PHI_RESULT (phi);
+ for (psi = gsi_start_phis (exit->dest); !gsi_end_p (psi); gsi_next (&psi))
+ {
+ phi = gsi_stmt (psi);
+ if (PHI_ARG_DEF_FROM_EDGE (phi, exit) == var)
+ return PHI_RESULT (phi);
+ }
return NULL_TREE;
}
@@ -1987,7 +2024,7 @@ instantiate_scev_1 (struct loop *instantiation_loop,
switch (TREE_CODE (chrec))
{
case SSA_NAME:
- def_bb = bb_for_stmt (SSA_NAME_DEF_STMT (chrec));
+ def_bb = gimple_bb (SSA_NAME_DEF_STMT (chrec));
/* A parameter (or loop invariant and we do not want to include
evolutions in outer loops), nothing to do. */
@@ -2073,7 +2110,7 @@ instantiate_scev_1 (struct loop *instantiation_loop,
if (CHREC_LEFT (chrec) != op0
|| CHREC_RIGHT (chrec) != op1)
{
- op1 = chrec_convert_rhs (chrec_type (op0), op1, NULL_TREE);
+ op1 = chrec_convert_rhs (chrec_type (op0), op1, NULL);
chrec = build_polynomial_chrec (CHREC_VARIABLE (chrec), op0, op1);
}
return chrec;
@@ -2095,8 +2132,8 @@ instantiate_scev_1 (struct loop *instantiation_loop,
if (TREE_OPERAND (chrec, 0) != op0
|| TREE_OPERAND (chrec, 1) != op1)
{
- op0 = chrec_convert (type, op0, NULL_TREE);
- op1 = chrec_convert_rhs (type, op1, NULL_TREE);
+ op0 = chrec_convert (type, op0, NULL);
+ op1 = chrec_convert_rhs (type, op1, NULL);
chrec = chrec_fold_plus (type, op0, op1);
}
return chrec;
@@ -2117,8 +2154,8 @@ instantiate_scev_1 (struct loop *instantiation_loop,
if (TREE_OPERAND (chrec, 0) != op0
|| TREE_OPERAND (chrec, 1) != op1)
{
- op0 = chrec_convert (type, op0, NULL_TREE);
- op1 = chrec_convert (type, op1, NULL_TREE);
+ op0 = chrec_convert (type, op0, NULL);
+ op1 = chrec_convert (type, op1, NULL);
chrec = chrec_fold_minus (type, op0, op1);
}
return chrec;
@@ -2139,8 +2176,8 @@ instantiate_scev_1 (struct loop *instantiation_loop,
if (TREE_OPERAND (chrec, 0) != op0
|| TREE_OPERAND (chrec, 1) != op1)
{
- op0 = chrec_convert (type, op0, NULL_TREE);
- op1 = chrec_convert (type, op1, NULL_TREE);
+ op0 = chrec_convert (type, op0, NULL);
+ op1 = chrec_convert (type, op1, NULL);
chrec = chrec_fold_multiply (type, op0, op1);
}
return chrec;
@@ -2168,7 +2205,7 @@ instantiate_scev_1 (struct loop *instantiation_loop,
if (fold_conversions)
return fold_convert (TREE_TYPE (chrec), op0);
- return chrec_convert (TREE_TYPE (chrec), op0, NULL_TREE);
+ return chrec_convert (TREE_TYPE (chrec), op0, NULL);
case SCEV_NOT_KNOWN:
return chrec_dont_know;
@@ -2388,14 +2425,14 @@ number_of_exit_cond_executions (struct loop *loop)
from the EXIT_CONDITIONS array. */
static void
-number_of_iterations_for_all_loops (VEC(tree,heap) **exit_conditions)
+number_of_iterations_for_all_loops (VEC(gimple,heap) **exit_conditions)
{
unsigned int i;
unsigned nb_chrec_dont_know_loops = 0;
unsigned nb_static_loops = 0;
- tree cond;
+ gimple cond;
- for (i = 0; VEC_iterate (tree, *exit_conditions, i, cond); i++)
+ for (i = 0; VEC_iterate (gimple, *exit_conditions, i, cond); i++)
{
tree res = number_of_latch_executions (loop_containing_stmt (cond));
if (chrec_contains_undetermined (res))
@@ -2540,33 +2577,37 @@ gather_chrec_stats (tree chrec, struct chrec_stats *stats)
index. This allows the parallelization of the loop. */
static void
-analyze_scalar_evolution_for_all_loop_phi_nodes (VEC(tree,heap) **exit_conditions)
+analyze_scalar_evolution_for_all_loop_phi_nodes (VEC(gimple,heap) **exit_conditions)
{
unsigned int i;
struct chrec_stats stats;
- tree cond;
+ gimple cond, phi;
+ gimple_stmt_iterator psi;
reset_chrecs_counters (&stats);
- for (i = 0; VEC_iterate (tree, *exit_conditions, i, cond); i++)
+ for (i = 0; VEC_iterate (gimple, *exit_conditions, i, cond); i++)
{
struct loop *loop;
basic_block bb;
- tree phi, chrec;
+ tree chrec;
loop = loop_containing_stmt (cond);
bb = loop->header;
- for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
- if (is_gimple_reg (PHI_RESULT (phi)))
- {
- chrec = instantiate_parameters
- (loop,
- analyze_scalar_evolution (loop, PHI_RESULT (phi)));
+ for (psi = gsi_start_phis (bb); !gsi_end_p (psi); gsi_next (&psi))
+ {
+ phi = gsi_stmt (psi);
+ if (is_gimple_reg (PHI_RESULT (phi)))
+ {
+ chrec = instantiate_parameters
+ (loop,
+ analyze_scalar_evolution (loop, PHI_RESULT (phi)));
- if (dump_file && (dump_flags & TDF_STATS))
- gather_chrec_stats (chrec, &stats);
- }
+ if (dump_file && (dump_flags & TDF_STATS))
+ gather_chrec_stats (chrec, &stats);
+ }
+ }
}
if (dump_file && (dump_flags & TDF_STATS))
@@ -2671,10 +2712,10 @@ scev_reset (void)
overflow (e.g. because it is computed in signed arithmetics). */
bool
-simple_iv (struct loop *loop, tree stmt, tree op, affine_iv *iv,
+simple_iv (struct loop *loop, gimple stmt, tree op, affine_iv *iv,
bool allow_nonconstant_step)
{
- basic_block bb = bb_for_stmt (stmt);
+ basic_block bb = gimple_bb (stmt);
tree type, ev;
bool folded_casts;
@@ -2730,16 +2771,16 @@ simple_iv (struct loop *loop, tree stmt, tree op, affine_iv *iv,
void
scev_analysis (void)
{
- VEC(tree,heap) *exit_conditions;
+ VEC(gimple,heap) *exit_conditions;
- exit_conditions = VEC_alloc (tree, heap, 37);
+ exit_conditions = VEC_alloc (gimple, heap, 37);
select_loops_exit_conditions (&exit_conditions);
if (dump_file && (dump_flags & TDF_STATS))
analyze_scalar_evolution_for_all_loop_phi_nodes (&exit_conditions);
number_of_iterations_for_all_loops (&exit_conditions);
- VEC_free (tree, heap, exit_conditions);
+ VEC_free (gimple, heap, exit_conditions);
}
/* Finalize the scalar evolution analysis. */
@@ -2765,11 +2806,13 @@ unsigned int
scev_const_prop (void)
{
basic_block bb;
- tree name, phi, next_phi, type, ev;
+ tree name, type, ev;
+ gimple phi, ass;
struct loop *loop, *ex_loop;
bitmap ssa_names_to_remove = NULL;
unsigned i;
loop_iterator li;
+ gimple_stmt_iterator psi;
if (number_of_loops () <= 1)
return 0;
@@ -2778,8 +2821,9 @@ scev_const_prop (void)
{
loop = bb->loop_father;
- for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
+ for (psi = gsi_start_phis (bb); !gsi_end_p (psi); gsi_next (&psi))
{
+ phi = gsi_stmt (psi);
name = PHI_RESULT (phi);
if (!is_gimple_reg (name))
@@ -2815,11 +2859,13 @@ scev_const_prop (void)
EXECUTE_IF_SET_IN_BITMAP (ssa_names_to_remove, 0, i, bi)
{
+ gimple_stmt_iterator psi;
name = ssa_name (i);
phi = SSA_NAME_DEF_STMT (name);
- gcc_assert (TREE_CODE (phi) == PHI_NODE);
- remove_phi_node (phi, NULL, true);
+ gcc_assert (gimple_code (phi) == GIMPLE_PHI);
+ psi = gsi_for_stmt (phi);
+ remove_phi_node (&psi, true);
}
BITMAP_FREE (ssa_names_to_remove);
@@ -2830,8 +2876,8 @@ scev_const_prop (void)
FOR_EACH_LOOP (li, loop, LI_FROM_INNERMOST)
{
edge exit;
- tree def, rslt, ass, niter;
- block_stmt_iterator bsi;
+ tree def, rslt, niter;
+ gimple_stmt_iterator bsi;
/* If we do not know exact number of iterations of the loop, we cannot
replace the final value. */
@@ -2852,22 +2898,28 @@ scev_const_prop (void)
/* Ensure that it is possible to insert new statements somewhere. */
if (!single_pred_p (exit->dest))
split_loop_exit_edge (exit);
- bsi = bsi_after_labels (exit->dest);
+ bsi = gsi_after_labels (exit->dest);
ex_loop = superloop_at_depth (loop,
loop_depth (exit->dest->loop_father) + 1);
- for (phi = phi_nodes (exit->dest); phi; phi = next_phi)
+ for (psi = gsi_start_phis (exit->dest); !gsi_end_p (psi); )
{
- next_phi = PHI_CHAIN (phi);
+ phi = gsi_stmt (psi);
rslt = PHI_RESULT (phi);
def = PHI_ARG_DEF_FROM_EDGE (phi, exit);
if (!is_gimple_reg (def))
- continue;
+ {
+ gsi_next (&psi);
+ continue;
+ }
if (!POINTER_TYPE_P (TREE_TYPE (def))
&& !INTEGRAL_TYPE_P (TREE_TYPE (def)))
- continue;
+ {
+ gsi_next (&psi);
+ continue;
+ }
def = analyze_scalar_evolution_in_loop (ex_loop, loop, def, NULL);
def = compute_overall_effect_of_inner_loop (ex_loop, def);
@@ -2877,23 +2929,20 @@ scev_const_prop (void)
of some ssa names, which may cause problems if they appear
on abnormal edges. */
|| contains_abnormal_ssa_name_p (def))
- continue;
+ {
+ gsi_next (&psi);
+ continue;
+ }
/* Eliminate the PHI node and replace it by a computation outside
the loop. */
def = unshare_expr (def);
- remove_phi_node (phi, NULL_TREE, false);
-
- ass = build_gimple_modify_stmt (rslt, NULL_TREE);
- SSA_NAME_DEF_STMT (rslt) = ass;
- {
- block_stmt_iterator dest = bsi;
- bsi_insert_before (&dest, ass, BSI_NEW_STMT);
- def = force_gimple_operand_bsi (&dest, def, false, NULL_TREE,
- true, BSI_SAME_STMT);
- }
- GIMPLE_STMT_OPERAND (ass, 1) = def;
- update_stmt (ass);
+ remove_phi_node (&psi, false);
+
+ def = force_gimple_operand_gsi (&bsi, def, false, NULL_TREE,
+ true, GSI_SAME_STMT);
+ ass = gimple_build_assign (rslt, def);
+ gsi_insert_before (&bsi, ass, GSI_SAME_STMT);
}
}
return 0;
diff --git a/gcc/tree-scalar-evolution.h b/gcc/tree-scalar-evolution.h
index 472b194d307..5d6d711afa9 100644
--- a/gcc/tree-scalar-evolution.h
+++ b/gcc/tree-scalar-evolution.h
@@ -23,7 +23,7 @@ along with GCC; see the file COPYING3. If not see
extern tree number_of_latch_executions (struct loop *);
extern tree number_of_exit_cond_executions (struct loop *);
-extern tree get_loop_exit_condition (const struct loop *);
+extern gimple get_loop_exit_condition (const struct loop *);
extern void scev_initialize (void);
extern void scev_reset (void);
@@ -35,7 +35,7 @@ extern void gather_stats_on_scev_database (void);
extern void scev_analysis (void);
unsigned int scev_const_prop (void);
-extern bool simple_iv (struct loop *, tree, tree, affine_iv *, bool);
+extern bool simple_iv (struct loop *, gimple, tree, affine_iv *, bool);
/* Analyze all the parameters of the chrec that were left under a
symbolic form. LOOP is the loop in which symbolic names have to
diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c
index 391511f56a7..5ae1c51350c 100644
--- a/gcc/tree-sra.c
+++ b/gcc/tree-sra.c
@@ -37,7 +37,7 @@ along with GCC; see the file COPYING3. If not see
#include "langhooks.h"
#include "tree-inline.h"
#include "tree-flow.h"
-#include "tree-gimple.h"
+#include "gimple.h"
#include "tree-dump.h"
#include "tree-pass.h"
#include "timevar.h"
@@ -208,8 +208,9 @@ extern void debug_sra_elt_name (struct sra_elt *);
/* Forward declarations. */
static tree generate_element_ref (struct sra_elt *);
-static tree sra_build_assignment (tree dst, tree src);
-static void mark_all_v_defs (tree list);
+static gimple_seq sra_build_assignment (tree dst, tree src);
+static void mark_all_v_defs_seq (gimple_seq);
+static void mark_all_v_defs_stmt (gimple);
/* Return true if DECL is an SRA candidate. */
@@ -308,6 +309,26 @@ sra_type_can_be_decomposed_p (tree type)
return false;
}
+/* Returns true if the TYPE is one of the available va_list types.
+ Otherwise it returns false.
+ Note, that for multiple calling conventions there can be more
+ than just one va_list type present. */
+
+static bool
+is_va_list_type (tree type)
+{
+ tree h;
+
+ if (type == NULL_TREE)
+ return false;
+ h = targetm.canonical_va_list_type (type);
+ if (h == NULL_TREE)
+ return false;
+ if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (h))
+ return true;
+ return false;
+}
+
/* Return true if DECL can be decomposed into a set of independent
(though not necessarily scalar) variables. */
@@ -360,9 +381,7 @@ decl_can_be_decomposed_p (tree var)
tree-stdarg.c, as the decomposition is truly a win. This could also
be fixed if the stdarg pass ran early, but this can't be done until
we've aliasing information early too. See PR 30791. */
- if (early_sra
- && TYPE_MAIN_VARIANT (TREE_TYPE (var))
- == TYPE_MAIN_VARIANT (va_list_type_node))
+ if (early_sra && is_va_list_type (TREE_TYPE (var)))
return false;
return true;
@@ -701,7 +720,7 @@ maybe_lookup_element_for_expr (tree expr)
references, and categorize them. */
/* A set of callbacks for phases 2 and 4. They'll be invoked for the
- various kinds of references seen. In all cases, *BSI is an iterator
+ various kinds of references seen. In all cases, *GSI is an iterator
pointing to the statement being processed. */
struct sra_walk_fns
{
@@ -711,21 +730,21 @@ struct sra_walk_fns
is a left-hand-side reference. USE_ALL is true if we saw something we
couldn't quite identify and had to force the use of the entire object. */
void (*use) (struct sra_elt *elt, tree *expr_p,
- block_stmt_iterator *bsi, bool is_output, bool use_all);
+ gimple_stmt_iterator *gsi, bool is_output, bool use_all);
/* Invoked when we have a copy between two scalarizable references. */
void (*copy) (struct sra_elt *lhs_elt, struct sra_elt *rhs_elt,
- block_stmt_iterator *bsi);
+ gimple_stmt_iterator *gsi);
/* Invoked when ELT is initialized from a constant. VALUE may be NULL,
in which case it should be treated as an empty CONSTRUCTOR. */
- void (*init) (struct sra_elt *elt, tree value, block_stmt_iterator *bsi);
+ void (*init) (struct sra_elt *elt, tree value, gimple_stmt_iterator *gsi);
/* Invoked when we have a copy between one scalarizable reference ELT
and one non-scalarizable reference OTHER without side-effects.
IS_OUTPUT is true if ELT is on the left-hand side. */
void (*ldst) (struct sra_elt *elt, tree other,
- block_stmt_iterator *bsi, bool is_output);
+ gimple_stmt_iterator *gsi, bool is_output);
/* True during phase 2, false during phase 4. */
/* ??? This is a hack. */
@@ -759,7 +778,7 @@ sra_find_candidate_decl (tree *tp, int *walk_subtrees,
If we find one, invoke FNS->USE. */
static void
-sra_walk_expr (tree *expr_p, block_stmt_iterator *bsi, bool is_output,
+sra_walk_expr (tree *expr_p, gimple_stmt_iterator *gsi, bool is_output,
const struct sra_walk_fns *fns)
{
tree expr = *expr_p;
@@ -786,7 +805,7 @@ sra_walk_expr (tree *expr_p, block_stmt_iterator *bsi, bool is_output,
if (disable_scalarization)
elt->cannot_scalarize = true;
else
- fns->use (elt, expr_p, bsi, is_output, use_all_p);
+ fns->use (elt, expr_p, gsi, is_output, use_all_p);
}
return;
@@ -863,6 +882,7 @@ sra_walk_expr (tree *expr_p, block_stmt_iterator *bsi, bool is_output,
goto use_all;
case NOP_EXPR:
+ case CONVERT_EXPR:
/* Similarly, a nop explicitly wants to look at an object in a
type other than the one we've scalarized. */
goto use_all;
@@ -898,60 +918,62 @@ sra_walk_expr (tree *expr_p, block_stmt_iterator *bsi, bool is_output,
}
}
-/* Walk a TREE_LIST of values looking for scalarizable aggregates.
+/* Walk the arguments of a GIMPLE_CALL looking for scalarizable aggregates.
If we find one, invoke FNS->USE. */
static void
-sra_walk_tree_list (tree list, block_stmt_iterator *bsi, bool is_output,
- const struct sra_walk_fns *fns)
-{
- tree op;
- for (op = list; op ; op = TREE_CHAIN (op))
- sra_walk_expr (&TREE_VALUE (op), bsi, is_output, fns);
-}
-
-/* Walk the arguments of a CALL_EXPR looking for scalarizable aggregates.
- If we find one, invoke FNS->USE. */
-
-static void
-sra_walk_call_expr (tree expr, block_stmt_iterator *bsi,
+sra_walk_gimple_call (gimple stmt, gimple_stmt_iterator *gsi,
const struct sra_walk_fns *fns)
{
int i;
- int nargs = call_expr_nargs (expr);
+ int nargs = gimple_call_num_args (stmt);
+
for (i = 0; i < nargs; i++)
- sra_walk_expr (&CALL_EXPR_ARG (expr, i), bsi, false, fns);
+ sra_walk_expr (gimple_call_arg_ptr (stmt, i), gsi, false, fns);
+
+ if (gimple_call_lhs (stmt))
+ sra_walk_expr (gimple_call_lhs_ptr (stmt), gsi, true, fns);
}
-/* Walk the inputs and outputs of an ASM_EXPR looking for scalarizable
+/* Walk the inputs and outputs of a GIMPLE_ASM looking for scalarizable
aggregates. If we find one, invoke FNS->USE. */
static void
-sra_walk_asm_expr (tree expr, block_stmt_iterator *bsi,
+sra_walk_gimple_asm (gimple stmt, gimple_stmt_iterator *gsi,
const struct sra_walk_fns *fns)
{
- sra_walk_tree_list (ASM_INPUTS (expr), bsi, false, fns);
- sra_walk_tree_list (ASM_OUTPUTS (expr), bsi, true, fns);
+ size_t i;
+ for (i = 0; i < gimple_asm_ninputs (stmt); i++)
+ sra_walk_expr (&TREE_VALUE (gimple_asm_input_op (stmt, i)), gsi, false, fns);
+ for (i = 0; i < gimple_asm_noutputs (stmt); i++)
+ sra_walk_expr (&TREE_VALUE (gimple_asm_output_op (stmt, i)), gsi, true, fns);
}
-/* Walk a GIMPLE_MODIFY_STMT and categorize the assignment appropriately. */
+/* Walk a GIMPLE_ASSIGN and categorize the assignment appropriately. */
static void
-sra_walk_gimple_modify_stmt (tree expr, block_stmt_iterator *bsi,
- const struct sra_walk_fns *fns)
+sra_walk_gimple_assign (gimple stmt, gimple_stmt_iterator *gsi,
+ const struct sra_walk_fns *fns)
{
- struct sra_elt *lhs_elt, *rhs_elt;
+ struct sra_elt *lhs_elt = NULL, *rhs_elt = NULL;
tree lhs, rhs;
- lhs = GIMPLE_STMT_OPERAND (expr, 0);
- rhs = GIMPLE_STMT_OPERAND (expr, 1);
+ /* If there is more than 1 element on the RHS, only walk the lhs. */
+ if (!gimple_assign_single_p (stmt))
+ {
+ sra_walk_expr (gimple_assign_lhs_ptr (stmt), gsi, true, fns);
+ return;
+ }
+
+ lhs = gimple_assign_lhs (stmt);
+ rhs = gimple_assign_rhs1 (stmt);
lhs_elt = maybe_lookup_element_for_expr (lhs);
rhs_elt = maybe_lookup_element_for_expr (rhs);
/* If both sides are scalarizable, this is a COPY operation. */
if (lhs_elt && rhs_elt)
{
- fns->copy (lhs_elt, rhs_elt, bsi);
+ fns->copy (lhs_elt, rhs_elt, gsi);
return;
}
@@ -959,9 +981,9 @@ sra_walk_gimple_modify_stmt (tree expr, block_stmt_iterator *bsi,
if (rhs_elt)
{
if (!rhs_elt->is_scalar && !TREE_SIDE_EFFECTS (lhs))
- fns->ldst (rhs_elt, lhs, bsi, false);
+ fns->ldst (rhs_elt, lhs, gsi, false);
else
- fns->use (rhs_elt, &GIMPLE_STMT_OPERAND (expr, 1), bsi, false, false);
+ fns->use (rhs_elt, gimple_assign_rhs1_ptr (stmt), gsi, false, false);
}
/* If it isn't scalarizable, there may be scalarizable variables within, so
@@ -970,13 +992,7 @@ sra_walk_gimple_modify_stmt (tree expr, block_stmt_iterator *bsi,
that the statements get inserted in the proper place, before any
copy-out operations. */
else
- {
- tree call = get_call_expr_in (rhs);
- if (call)
- sra_walk_call_expr (call, bsi, fns);
- else
- sra_walk_expr (&GIMPLE_STMT_OPERAND (expr, 1), bsi, false, fns);
- }
+ sra_walk_expr (gimple_assign_rhs1_ptr (stmt), gsi, false, fns);
/* Likewise, handle the LHS being scalarizable. We have cases similar
to those above, but also want to handle RHS being constant. */
@@ -987,7 +1003,7 @@ sra_walk_gimple_modify_stmt (tree expr, block_stmt_iterator *bsi,
if (TREE_CODE (rhs) == COMPLEX_EXPR
|| TREE_CODE (rhs) == COMPLEX_CST
|| TREE_CODE (rhs) == CONSTRUCTOR)
- fns->init (lhs_elt, rhs, bsi);
+ fns->init (lhs_elt, rhs, gsi);
/* If this is an assignment from read-only memory, treat this as if
we'd been passed the constructor directly. Invoke INIT. */
@@ -995,7 +1011,7 @@ sra_walk_gimple_modify_stmt (tree expr, block_stmt_iterator *bsi,
&& TREE_STATIC (rhs)
&& TREE_READONLY (rhs)
&& targetm.binds_local_p (rhs))
- fns->init (lhs_elt, DECL_INITIAL (rhs), bsi);
+ fns->init (lhs_elt, DECL_INITIAL (rhs), gsi);
/* If this is a copy from a non-scalarizable lvalue, invoke LDST.
The lvalue requirement prevents us from trying to directly scalarize
@@ -1003,19 +1019,19 @@ sra_walk_gimple_modify_stmt (tree expr, block_stmt_iterator *bsi,
the function multiple times, and other evil things. */
else if (!lhs_elt->is_scalar
&& !TREE_SIDE_EFFECTS (rhs) && is_gimple_addressable (rhs))
- fns->ldst (lhs_elt, rhs, bsi, true);
+ fns->ldst (lhs_elt, rhs, gsi, true);
/* Otherwise we're being used in some context that requires the
aggregate to be seen as a whole. Invoke USE. */
else
- fns->use (lhs_elt, &GIMPLE_STMT_OPERAND (expr, 0), bsi, true, false);
+ fns->use (lhs_elt, gimple_assign_lhs_ptr (stmt), gsi, true, false);
}
/* Similarly to above, LHS_ELT being null only means that the LHS as a
whole is not a scalarizable reference. There may be occurrences of
scalarizable variables within, which implies a USE. */
else
- sra_walk_expr (&GIMPLE_STMT_OPERAND (expr, 0), bsi, true, fns);
+ sra_walk_expr (gimple_assign_lhs_ptr (stmt), gsi, true, fns);
}
/* Entry point to the walk functions. Search the entire function,
@@ -1026,22 +1042,20 @@ static void
sra_walk_function (const struct sra_walk_fns *fns)
{
basic_block bb;
- block_stmt_iterator si, ni;
+ gimple_stmt_iterator si, ni;
/* ??? Phase 4 could derive some benefit to walking the function in
dominator tree order. */
FOR_EACH_BB (bb)
- for (si = bsi_start (bb); !bsi_end_p (si); si = ni)
+ for (si = gsi_start_bb (bb); !gsi_end_p (si); si = ni)
{
- tree stmt, t;
- stmt_ann_t ann;
+ gimple stmt;
- stmt = bsi_stmt (si);
- ann = stmt_ann (stmt);
+ stmt = gsi_stmt (si);
ni = si;
- bsi_next (&ni);
+ gsi_next (&ni);
/* If the statement has no virtual operands, then it doesn't
make any structure references that we care about. */
@@ -1049,35 +1063,28 @@ sra_walk_function (const struct sra_walk_fns *fns)
&& ZERO_SSA_OPERANDS (stmt, (SSA_OP_VIRTUAL_DEFS | SSA_OP_VUSE)))
continue;
- switch (TREE_CODE (stmt))
+ switch (gimple_code (stmt))
{
- case RETURN_EXPR:
+ case GIMPLE_RETURN:
/* If we have "return <retval>" then the return value is
already exposed for our pleasure. Walk it as a USE to
force all the components back in place for the return.
-
- If we have an embedded assignment, then <retval> is of
- a type that gets returned in registers in this ABI, and
- we do not wish to extend their lifetimes. Treat this
- as a USE of the variable on the RHS of this assignment. */
-
- t = TREE_OPERAND (stmt, 0);
- if (t == NULL_TREE)
+ */
+ if (gimple_return_retval (stmt) == NULL_TREE)
;
- else if (TREE_CODE (t) == GIMPLE_MODIFY_STMT)
- sra_walk_expr (&GIMPLE_STMT_OPERAND (t, 1), &si, false, fns);
else
- sra_walk_expr (&TREE_OPERAND (stmt, 0), &si, false, fns);
+ sra_walk_expr (gimple_return_retval_ptr (stmt), &si, false,
+ fns);
break;
- case GIMPLE_MODIFY_STMT:
- sra_walk_gimple_modify_stmt (stmt, &si, fns);
+ case GIMPLE_ASSIGN:
+ sra_walk_gimple_assign (stmt, &si, fns);
break;
- case CALL_EXPR:
- sra_walk_call_expr (stmt, &si, fns);
+ case GIMPLE_CALL:
+ sra_walk_gimple_call (stmt, &si, fns);
break;
- case ASM_EXPR:
- sra_walk_asm_expr (stmt, &si, fns);
+ case GIMPLE_ASM:
+ sra_walk_gimple_asm (stmt, &si, fns);
break;
default:
@@ -1118,7 +1125,7 @@ find_candidates_for_sra (void)
static void
scan_use (struct sra_elt *elt, tree *expr_p ATTRIBUTE_UNUSED,
- block_stmt_iterator *bsi ATTRIBUTE_UNUSED,
+ gimple_stmt_iterator *gsi ATTRIBUTE_UNUSED,
bool is_output ATTRIBUTE_UNUSED, bool use_all ATTRIBUTE_UNUSED)
{
elt->n_uses += 1;
@@ -1126,7 +1133,7 @@ scan_use (struct sra_elt *elt, tree *expr_p ATTRIBUTE_UNUSED,
static void
scan_copy (struct sra_elt *lhs_elt, struct sra_elt *rhs_elt,
- block_stmt_iterator *bsi ATTRIBUTE_UNUSED)
+ gimple_stmt_iterator *gsi ATTRIBUTE_UNUSED)
{
lhs_elt->n_copies += 1;
rhs_elt->n_copies += 1;
@@ -1134,14 +1141,14 @@ scan_copy (struct sra_elt *lhs_elt, struct sra_elt *rhs_elt,
static void
scan_init (struct sra_elt *lhs_elt, tree rhs ATTRIBUTE_UNUSED,
- block_stmt_iterator *bsi ATTRIBUTE_UNUSED)
+ gimple_stmt_iterator *gsi ATTRIBUTE_UNUSED)
{
lhs_elt->n_copies += 1;
}
static void
scan_ldst (struct sra_elt *elt, tree other ATTRIBUTE_UNUSED,
- block_stmt_iterator *bsi ATTRIBUTE_UNUSED,
+ gimple_stmt_iterator *gsi ATTRIBUTE_UNUSED,
bool is_output ATTRIBUTE_UNUSED)
{
elt->n_copies += 1;
@@ -1332,10 +1339,12 @@ instantiate_element (struct sra_elt *elt)
|| (var != elt->replacement
&& TREE_CODE (elt->replacement) == BIT_FIELD_REF))
{
- tree init = sra_build_assignment (var, fold_convert (TREE_TYPE (var),
- integer_zero_node));
- insert_edge_copies (init, ENTRY_BLOCK_PTR);
- mark_all_v_defs (init);
+ gimple_seq init = sra_build_assignment (var,
+ fold_convert (TREE_TYPE (var),
+ integer_zero_node)
+ );
+ insert_edge_copies_seq (init, ENTRY_BLOCK_PTR);
+ mark_all_v_defs_seq (init);
}
if (dump_file)
@@ -2012,7 +2021,7 @@ decide_instantiations (void)
non-scalar. */
static void
-mark_all_v_defs_1 (tree stmt)
+mark_all_v_defs_stmt (gimple stmt)
{
tree sym;
ssa_op_iter iter;
@@ -2032,18 +2041,13 @@ mark_all_v_defs_1 (tree stmt)
LIST for renaming. */
static void
-mark_all_v_defs (tree list)
+mark_all_v_defs_seq (gimple_seq seq)
{
- if (TREE_CODE (list) != STATEMENT_LIST)
- mark_all_v_defs_1 (list);
- else
- {
- tree_stmt_iterator i;
- for (i = tsi_start (list); !tsi_end_p (i); tsi_next (&i))
- mark_all_v_defs_1 (tsi_stmt (i));
- }
-}
+ gimple_stmt_iterator gsi;
+ for (gsi = gsi_start (seq); !gsi_end_p (gsi); gsi_next (&gsi))
+ mark_all_v_defs_stmt (gsi_stmt (gsi));
+}
/* Mark every replacement under ELT with TREE_NO_WARNING. */
@@ -2137,9 +2141,11 @@ scalar_bitfield_p (tree bf)
/* Create an assignment statement from SRC to DST. */
-static tree
+static gimple_seq
sra_build_assignment (tree dst, tree src)
{
+ gimple stmt;
+ gimple_seq seq = NULL;
/* Turning BIT_FIELD_REFs into bit operations enables other passes
to do a much better job at optimizing the code.
From dst = BIT_FIELD_REF <var, sz, off> we produce
@@ -2154,7 +2160,6 @@ sra_build_assignment (tree dst, tree src)
{
tree var, shift, width;
tree utype, stype, stmp, utmp, dtmp;
- tree list, stmt;
bool unsignedp = (INTEGRAL_TYPE_P (TREE_TYPE (src))
? TYPE_UNSIGNED (TREE_TYPE (src)) : true);
@@ -2187,7 +2192,6 @@ sra_build_assignment (tree dst, tree src)
else if (!TYPE_UNSIGNED (utype))
utype = unsigned_type_for (utype);
- list = NULL;
stmp = make_rename_temp (stype, "SR");
/* Convert the base var of the BIT_FIELD_REF to the scalar type
@@ -2195,22 +2199,19 @@ sra_build_assignment (tree dst, tree src)
if (!useless_type_conversion_p (stype, TREE_TYPE (var)))
{
if (INTEGRAL_TYPE_P (TREE_TYPE (var)))
- stmt = build_gimple_modify_stmt (stmp,
- fold_convert (stype, var));
+ stmt = gimple_build_assign (stmp, fold_convert (stype, var));
else
- stmt = build_gimple_modify_stmt (stmp,
- fold_build1 (VIEW_CONVERT_EXPR,
- stype, var));
- append_to_statement_list (stmt, &list);
+ stmt = gimple_build_assign (stmp, fold_build1 (VIEW_CONVERT_EXPR,
+ stype, var));
+ gimple_seq_add_stmt (&seq, stmt);
var = stmp;
}
if (!integer_zerop (shift))
{
- stmt = build_gimple_modify_stmt (stmp,
- fold_build2 (RSHIFT_EXPR, stype,
- var, shift));
- append_to_statement_list (stmt, &list);
+ stmt = gimple_build_assign (stmp, fold_build2 (RSHIFT_EXPR, stype,
+ var, shift));
+ gimple_seq_add_stmt (&seq, stmt);
var = stmp;
}
@@ -2223,10 +2224,9 @@ sra_build_assignment (tree dst, tree src)
tree mask = int_const_binop (LSHIFT_EXPR, one, width, 0);
mask = int_const_binop (MINUS_EXPR, mask, one, 0);
- stmt = build_gimple_modify_stmt (stmp,
- fold_build2 (BIT_AND_EXPR, stype,
- var, mask));
- append_to_statement_list (stmt, &list);
+ stmt = gimple_build_assign (stmp, fold_build2 (BIT_AND_EXPR, stype,
+ var, mask));
+ gimple_seq_add_stmt (&seq, stmt);
var = stmp;
}
@@ -2236,8 +2236,8 @@ sra_build_assignment (tree dst, tree src)
{
utmp = make_rename_temp (utype, "SR");
- stmt = build_gimple_modify_stmt (utmp, fold_convert (utype, var));
- append_to_statement_list (stmt, &list);
+ stmt = gimple_build_assign (utmp, fold_convert (utype, var));
+ gimple_seq_add_stmt (&seq, stmt);
var = utmp;
}
@@ -2251,19 +2251,20 @@ sra_build_assignment (tree dst, tree src)
size_binop (MINUS_EXPR, width,
bitsize_int (1)), 0);
- stmt = build_gimple_modify_stmt (utmp,
- fold_build2 (BIT_XOR_EXPR, utype,
- var, signbit));
- append_to_statement_list (stmt, &list);
+ stmt = gimple_build_assign (utmp, fold_build2 (BIT_XOR_EXPR, utype,
+ var, signbit));
+ gimple_seq_add_stmt (&seq, stmt);
- stmt = build_gimple_modify_stmt (utmp,
- fold_build2 (MINUS_EXPR, utype,
- utmp, signbit));
- append_to_statement_list (stmt, &list);
+ stmt = gimple_build_assign (utmp, fold_build2 (MINUS_EXPR, utype,
+ utmp, signbit));
+ gimple_seq_add_stmt (&seq, stmt);
var = utmp;
}
+ /* fold_build3 (BIT_FIELD_REF, ...) sometimes returns a cast. */
+ STRIP_NOPS (dst);
+
/* Finally, move and convert to the destination. */
if (!useless_type_conversion_p (TREE_TYPE (dst), TREE_TYPE (var)))
{
@@ -2277,17 +2278,23 @@ sra_build_assignment (tree dst, tree src)
if (!is_gimple_reg (dst))
{
dtmp = make_rename_temp (TREE_TYPE (dst), "SR");
- stmt = build_gimple_modify_stmt (dtmp, var);
- append_to_statement_list (stmt, &list);
+ stmt = gimple_build_assign (dtmp, var);
+ gimple_seq_add_stmt (&seq, stmt);
var = dtmp;
}
}
- stmt = build_gimple_modify_stmt (dst, var);
- append_to_statement_list (stmt, &list);
+ stmt = gimple_build_assign (dst, var);
+ gimple_seq_add_stmt (&seq, stmt);
- return list;
+ return seq;
}
+ /* fold_build3 (BIT_FIELD_REF, ...) sometimes returns a cast. */
+ if (CONVERT_EXPR_P (dst))
+ {
+ STRIP_NOPS (dst);
+ src = fold_convert (TREE_TYPE (dst), src);
+ }
/* It was hoped that we could perform some type sanity checking
here, but since front-ends can emit accesses of fields in types
different from their nominal types and copy structures containing
@@ -2298,11 +2305,13 @@ sra_build_assignment (tree dst, tree src)
So we just assume type differences at this point are ok.
The only exception we make here are pointer types, which can be different
in e.g. structurally equal, but non-identical RECORD_TYPEs. */
- if (POINTER_TYPE_P (TREE_TYPE (dst))
- && !useless_type_conversion_p (TREE_TYPE (dst), TREE_TYPE (src)))
+ else if (POINTER_TYPE_P (TREE_TYPE (dst))
+ && !useless_type_conversion_p (TREE_TYPE (dst), TREE_TYPE (src)))
src = fold_convert (TREE_TYPE (dst), src);
- return build_gimple_modify_stmt (dst, src);
+ stmt = gimple_build_assign (dst, src);
+ gimple_seq_add_stmt (&seq, stmt);
+ return seq;
}
/* BIT_FIELD_REFs must not be shared. sra_build_elt_assignment()
@@ -2312,11 +2321,12 @@ sra_build_assignment (tree dst, tree src)
/* Emit an assignment from SRC to DST, but if DST is a scalarizable
BIT_FIELD_REF, turn it into bit operations. */
-static tree
+static gimple_seq
sra_build_bf_assignment (tree dst, tree src)
{
tree var, type, utype, tmp, tmp2, tmp3;
- tree list, stmt;
+ gimple_seq seq;
+ gimple stmt;
tree cst, cst2, mask;
tree minshift, maxshift;
@@ -2328,7 +2338,7 @@ sra_build_bf_assignment (tree dst, tree src)
if (!scalar_bitfield_p (dst))
return sra_build_assignment (REPLDUP (dst), src);
- list = NULL;
+ seq = NULL;
cst = fold_convert (bitsizetype, TREE_OPERAND (dst, 2));
cst2 = size_binop (PLUS_EXPR,
@@ -2377,11 +2387,11 @@ sra_build_bf_assignment (tree dst, tree src)
tmp2 = make_rename_temp (utype, "SR");
if (INTEGRAL_TYPE_P (TREE_TYPE (var)))
- stmt = build_gimple_modify_stmt (tmp2, fold_convert (utype, tmp));
+ stmt = gimple_build_assign (tmp2, fold_convert (utype, tmp));
else
- stmt = build_gimple_modify_stmt (tmp2, fold_build1 (VIEW_CONVERT_EXPR,
- utype, tmp));
- append_to_statement_list (stmt, &list);
+ stmt = gimple_build_assign (tmp2, fold_build1 (VIEW_CONVERT_EXPR,
+ utype, tmp));
+ gimple_seq_add_stmt (&seq, stmt);
}
else
tmp2 = var;
@@ -2389,10 +2399,9 @@ sra_build_bf_assignment (tree dst, tree src)
if (!integer_zerop (mask))
{
tmp = make_rename_temp (utype, "SR");
- stmt = build_gimple_modify_stmt (tmp,
- fold_build2 (BIT_AND_EXPR, utype,
+ stmt = gimple_build_assign (tmp, fold_build2 (BIT_AND_EXPR, utype,
tmp2, mask));
- append_to_statement_list (stmt, &list);
+ gimple_seq_add_stmt (&seq, stmt);
}
else
tmp = mask;
@@ -2401,28 +2410,31 @@ sra_build_bf_assignment (tree dst, tree src)
tmp2 = src;
else if (INTEGRAL_TYPE_P (TREE_TYPE (src)))
{
+ gimple_seq tmp_seq;
tmp2 = make_rename_temp (TREE_TYPE (src), "SR");
- stmt = sra_build_assignment (tmp2, src);
- append_to_statement_list (stmt, &list);
+ tmp_seq = sra_build_assignment (tmp2, src);
+ gimple_seq_add_seq (&seq, tmp_seq);
}
else
{
+ gimple_seq tmp_seq;
tmp2 = make_rename_temp
(lang_hooks.types.type_for_size
(TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (src))),
1), "SR");
- stmt = sra_build_assignment (tmp2, fold_build1 (VIEW_CONVERT_EXPR,
+ tmp_seq = sra_build_assignment (tmp2, fold_build1 (VIEW_CONVERT_EXPR,
TREE_TYPE (tmp2), src));
- append_to_statement_list (stmt, &list);
+ gimple_seq_add_seq (&seq, tmp_seq);
}
if (!TYPE_UNSIGNED (TREE_TYPE (tmp2)))
{
+ gimple_seq tmp_seq;
tree ut = unsigned_type_for (TREE_TYPE (tmp2));
tmp3 = make_rename_temp (ut, "SR");
tmp2 = fold_convert (ut, tmp2);
- stmt = sra_build_assignment (tmp3, tmp2);
- append_to_statement_list (stmt, &list);
+ tmp_seq = sra_build_assignment (tmp3, tmp2);
+ gimple_seq_add_seq (&seq, tmp_seq);
tmp2 = fold_build1 (BIT_NOT_EXPR, utype, mask);
tmp2 = int_const_binop (RSHIFT_EXPR, tmp2, minshift, true);
@@ -2432,8 +2444,8 @@ sra_build_bf_assignment (tree dst, tree src)
if (tmp3 != tmp2)
{
tmp3 = make_rename_temp (ut, "SR");
- stmt = sra_build_assignment (tmp3, tmp2);
- append_to_statement_list (stmt, &list);
+ tmp_seq = sra_build_assignment (tmp3, tmp2);
+ gimple_seq_add_seq (&seq, tmp_seq);
}
tmp2 = tmp3;
@@ -2441,20 +2453,20 @@ sra_build_bf_assignment (tree dst, tree src)
if (TYPE_MAIN_VARIANT (TREE_TYPE (tmp2)) != TYPE_MAIN_VARIANT (utype))
{
+ gimple_seq tmp_seq;
tmp3 = make_rename_temp (utype, "SR");
tmp2 = fold_convert (utype, tmp2);
- stmt = sra_build_assignment (tmp3, tmp2);
- append_to_statement_list (stmt, &list);
+ tmp_seq = sra_build_assignment (tmp3, tmp2);
+ gimple_seq_add_seq (&seq, tmp_seq);
tmp2 = tmp3;
}
if (!integer_zerop (minshift))
{
tmp3 = make_rename_temp (utype, "SR");
- stmt = build_gimple_modify_stmt (tmp3,
- fold_build2 (LSHIFT_EXPR, utype,
- tmp2, minshift));
- append_to_statement_list (stmt, &list);
+ stmt = gimple_build_assign (tmp3, fold_build2 (LSHIFT_EXPR, utype,
+ tmp2, minshift));
+ gimple_seq_add_stmt (&seq, stmt);
tmp2 = tmp3;
}
@@ -2462,35 +2474,34 @@ sra_build_bf_assignment (tree dst, tree src)
tmp3 = make_rename_temp (utype, "SR");
else
tmp3 = var;
- stmt = build_gimple_modify_stmt (tmp3,
- fold_build2 (BIT_IOR_EXPR, utype,
- tmp, tmp2));
- append_to_statement_list (stmt, &list);
+ stmt = gimple_build_assign (tmp3, fold_build2 (BIT_IOR_EXPR, utype,
+ tmp, tmp2));
+ gimple_seq_add_stmt (&seq, stmt);
if (tmp3 != var)
{
if (TREE_TYPE (var) == type)
- stmt = build_gimple_modify_stmt (var,
- fold_convert (type, tmp3));
+ stmt = gimple_build_assign (var, fold_convert (type, tmp3));
else
- stmt = build_gimple_modify_stmt (var,
- fold_build1 (VIEW_CONVERT_EXPR,
+ stmt = gimple_build_assign (var, fold_build1 (VIEW_CONVERT_EXPR,
TREE_TYPE (var), tmp3));
- append_to_statement_list (stmt, &list);
+ gimple_seq_add_stmt (&seq, stmt);
}
- return list;
+ return seq;
}
/* Expand an assignment of SRC to the scalarized representation of
ELT. If it is a field group, try to widen the assignment to cover
the full variable. */
-static tree
+static gimple_seq
sra_build_elt_assignment (struct sra_elt *elt, tree src)
{
tree dst = elt->replacement;
- tree var, tmp, cst, cst2, list, stmt;
+ tree var, tmp, cst, cst2;
+ gimple stmt;
+ gimple_seq seq;
if (TREE_CODE (dst) != BIT_FIELD_REF
|| !elt->in_bitfld_block)
@@ -2526,7 +2537,8 @@ sra_build_elt_assignment (struct sra_elt *elt, tree src)
if (TYPE_MAIN_VARIANT (TREE_TYPE (var))
!= TYPE_MAIN_VARIANT (TREE_TYPE (src)))
{
- list = NULL;
+ gimple_seq tmp_seq;
+ seq = NULL;
if (!INTEGRAL_TYPE_P (TREE_TYPE (src)))
src = fold_build1 (VIEW_CONVERT_EXPR,
@@ -2537,15 +2549,15 @@ sra_build_elt_assignment (struct sra_elt *elt, tree src)
gcc_assert (TYPE_UNSIGNED (TREE_TYPE (src)));
tmp = make_rename_temp (TREE_TYPE (src), "SR");
- stmt = build_gimple_modify_stmt (tmp, src);
- append_to_statement_list (stmt, &list);
+ stmt = gimple_build_assign (tmp, src);
+ gimple_seq_add_stmt (&seq, stmt);
- stmt = sra_build_assignment (var,
- fold_convert (TREE_TYPE (var),
- tmp));
- append_to_statement_list (stmt, &list);
+ tmp_seq = sra_build_assignment (var,
+ fold_convert (TREE_TYPE (var),
+ tmp));
+ gimple_seq_add_seq (&seq, tmp_seq);
- return list;
+ return seq;
}
src = fold_convert (TREE_TYPE (var), src);
@@ -2568,9 +2580,10 @@ sra_build_elt_assignment (struct sra_elt *elt, tree src)
static void
generate_copy_inout (struct sra_elt *elt, bool copy_out, tree expr,
- tree *list_p)
+ gimple_seq *seq_p)
{
struct sra_elt *c;
+ gimple_seq tmp_seq;
tree t;
if (!copy_out && TREE_CODE (expr) == SSA_NAME
@@ -2584,24 +2597,25 @@ generate_copy_inout (struct sra_elt *elt, bool copy_out, tree expr,
i = c->replacement;
t = build2 (COMPLEX_EXPR, elt->type, r, i);
- t = sra_build_bf_assignment (expr, t);
- SSA_NAME_DEF_STMT (expr) = t;
- append_to_statement_list (t, list_p);
+ tmp_seq = sra_build_bf_assignment (expr, t);
+ gcc_assert (gimple_seq_singleton_p (tmp_seq));
+ SSA_NAME_DEF_STMT (expr) = gimple_seq_first_stmt (tmp_seq);
+ gimple_seq_add_seq (seq_p, tmp_seq);
}
else if (elt->replacement)
{
if (copy_out)
- t = sra_build_elt_assignment (elt, expr);
+ tmp_seq = sra_build_elt_assignment (elt, expr);
else
- t = sra_build_bf_assignment (expr, REPLDUP (elt->replacement));
- append_to_statement_list (t, list_p);
+ tmp_seq = sra_build_bf_assignment (expr, REPLDUP (elt->replacement));
+ gimple_seq_add_seq (seq_p, tmp_seq);
}
else
{
FOR_EACH_ACTUAL_CHILD (c, elt)
{
t = generate_one_element_ref (c, unshare_expr (expr));
- generate_copy_inout (c, copy_out, t, list_p);
+ generate_copy_inout (c, copy_out, t, seq_p);
}
}
}
@@ -2611,7 +2625,7 @@ generate_copy_inout (struct sra_elt *elt, bool copy_out, tree expr,
correspondence of instantiated elements. */
static void
-generate_element_copy (struct sra_elt *dst, struct sra_elt *src, tree *list_p)
+generate_element_copy (struct sra_elt *dst, struct sra_elt *src, gimple_seq *seq_p)
{
struct sra_elt *dc, *sc;
@@ -2626,7 +2640,7 @@ generate_element_copy (struct sra_elt *dst, struct sra_elt *src, tree *list_p)
{
sc = lookup_element (src, dcs->element, NULL, NO_INSERT);
gcc_assert (sc);
- generate_element_copy (dcs, sc, list_p);
+ generate_element_copy (dcs, sc, seq_p);
}
continue;
@@ -2658,17 +2672,17 @@ generate_element_copy (struct sra_elt *dst, struct sra_elt *src, tree *list_p)
sc = lookup_element (src, f, NULL, NO_INSERT);
}
- generate_element_copy (dc, sc, list_p);
+ generate_element_copy (dc, sc, seq_p);
}
if (dst->replacement)
{
- tree t;
+ gimple_seq tmp_seq;
gcc_assert (src->replacement);
- t = sra_build_elt_assignment (dst, REPLDUP (src->replacement));
- append_to_statement_list (t, list_p);
+ tmp_seq = sra_build_elt_assignment (dst, REPLDUP (src->replacement));
+ gimple_seq_add_seq (seq_p, tmp_seq);
}
}
@@ -2678,7 +2692,7 @@ generate_element_copy (struct sra_elt *dst, struct sra_elt *src, tree *list_p)
with generate_element_init. */
static void
-generate_element_zero (struct sra_elt *elt, tree *list_p)
+generate_element_zero (struct sra_elt *elt, gimple_seq *seq_p)
{
struct sra_elt *c;
@@ -2690,17 +2704,18 @@ generate_element_zero (struct sra_elt *elt, tree *list_p)
if (!elt->in_bitfld_block)
FOR_EACH_ACTUAL_CHILD (c, elt)
- generate_element_zero (c, list_p);
+ generate_element_zero (c, seq_p);
if (elt->replacement)
{
tree t;
+ gimple_seq tmp_seq;
gcc_assert (elt->is_scalar);
t = fold_convert (elt->type, integer_zero_node);
- t = sra_build_elt_assignment (elt, t);
- append_to_statement_list (t, list_p);
+ tmp_seq = sra_build_elt_assignment (elt, t);
+ gimple_seq_add_seq (seq_p, tmp_seq);
}
}
@@ -2708,11 +2723,10 @@ generate_element_zero (struct sra_elt *elt, tree *list_p)
Add the result to *LIST_P. */
static void
-generate_one_element_init (struct sra_elt *elt, tree init, tree *list_p)
+generate_one_element_init (struct sra_elt *elt, tree init, gimple_seq *seq_p)
{
- /* The replacement can be almost arbitrarily complex. Gimplify. */
- tree stmt = sra_build_elt_assignment (elt, init);
- gimplify_and_add (stmt, list_p);
+ gimple_seq tmp_seq = sra_build_elt_assignment (elt, init);
+ gimple_seq_add_seq (seq_p, tmp_seq);
}
/* Generate a set of assignment statements in *LIST_P to set all instantiated
@@ -2722,7 +2736,7 @@ generate_one_element_init (struct sra_elt *elt, tree init, tree *list_p)
handle. */
static bool
-generate_element_init_1 (struct sra_elt *elt, tree init, tree *list_p)
+generate_element_init_1 (struct sra_elt *elt, tree init, gimple_seq *seq_p)
{
bool result = true;
enum tree_code init_code;
@@ -2740,7 +2754,7 @@ generate_element_init_1 (struct sra_elt *elt, tree init, tree *list_p)
{
if (elt->replacement)
{
- generate_one_element_init (elt, init, list_p);
+ generate_one_element_init (elt, init, seq_p);
elt->visited = true;
}
return result;
@@ -2758,7 +2772,7 @@ generate_element_init_1 (struct sra_elt *elt, tree init, tree *list_p)
else
t = (init_code == COMPLEX_EXPR
? TREE_OPERAND (init, 1) : TREE_IMAGPART (init));
- result &= generate_element_init_1 (sub, t, list_p);
+ result &= generate_element_init_1 (sub, t, seq_p);
}
break;
@@ -2774,7 +2788,7 @@ generate_element_init_1 (struct sra_elt *elt, tree init, tree *list_p)
{
sub = lookup_element (elt, lower, NULL, NO_INSERT);
if (sub != NULL)
- result &= generate_element_init_1 (sub, value, list_p);
+ result &= generate_element_init_1 (sub, value, seq_p);
if (tree_int_cst_equal (lower, upper))
break;
lower = int_const_binop (PLUS_EXPR, lower,
@@ -2785,7 +2799,7 @@ generate_element_init_1 (struct sra_elt *elt, tree init, tree *list_p)
{
sub = lookup_element (elt, purpose, NULL, NO_INSERT);
if (sub != NULL)
- result &= generate_element_init_1 (sub, value, list_p);
+ result &= generate_element_init_1 (sub, value, seq_p);
}
}
break;
@@ -2802,95 +2816,86 @@ generate_element_init_1 (struct sra_elt *elt, tree init, tree *list_p)
gimplification. */
static bool
-generate_element_init (struct sra_elt *elt, tree init, tree *list_p)
+generate_element_init (struct sra_elt *elt, tree init, gimple_seq *seq_p)
{
bool ret;
+ struct gimplify_ctx gctx;
- push_gimplify_context ();
- ret = generate_element_init_1 (elt, init, list_p);
+ push_gimplify_context (&gctx);
+ ret = generate_element_init_1 (elt, init, seq_p);
pop_gimplify_context (NULL);
/* The replacement can expose previously unreferenced variables. */
- if (ret && *list_p)
+ if (ret && *seq_p)
{
- tree_stmt_iterator i;
+ gimple_stmt_iterator i;
- for (i = tsi_start (*list_p); !tsi_end_p (i); tsi_next (&i))
- find_new_referenced_vars (tsi_stmt_ptr (i));
+ for (i = gsi_start (*seq_p); !gsi_end_p (i); gsi_next (&i))
+ find_new_referenced_vars (gsi_stmt (i));
}
return ret;
}
-/* Insert STMT on all the outgoing edges out of BB. Note that if BB
- has more than one edge, STMT will be replicated for each edge. Also,
- abnormal edges will be ignored. */
+/* Insert a gimple_seq SEQ on all the outgoing edges out of BB. Note that
+ if BB has more than one edge, STMT will be replicated for each edge.
+ Also, abnormal edges will be ignored. */
void
-insert_edge_copies (tree stmt, basic_block bb)
+insert_edge_copies_seq (gimple_seq seq, basic_block bb)
{
edge e;
edge_iterator ei;
- bool first_copy;
+ unsigned n_copies = -1;
- first_copy = true;
FOR_EACH_EDGE (e, ei, bb->succs)
- {
- /* We don't need to insert copies on abnormal edges. The
- value of the scalar replacement is not guaranteed to
- be valid through an abnormal edge. */
- if (!(e->flags & EDGE_ABNORMAL))
- {
- if (first_copy)
- {
- bsi_insert_on_edge (e, stmt);
- first_copy = false;
- }
- else
- bsi_insert_on_edge (e, unsave_expr_now (stmt));
- }
- }
+ if (!(e->flags & EDGE_ABNORMAL))
+ n_copies++;
+
+ FOR_EACH_EDGE (e, ei, bb->succs)
+ if (!(e->flags & EDGE_ABNORMAL))
+ gsi_insert_seq_on_edge (e, n_copies-- > 0 ? gimple_seq_copy (seq) : seq);
}
-/* Helper function to insert LIST before BSI, and set up line number info. */
+/* Helper function to insert LIST before GSI, and set up line number info. */
void
-sra_insert_before (block_stmt_iterator *bsi, tree list)
+sra_insert_before (gimple_stmt_iterator *gsi, gimple_seq seq)
{
- tree stmt = bsi_stmt (*bsi);
+ gimple stmt = gsi_stmt (*gsi);
- if (EXPR_HAS_LOCATION (stmt))
- annotate_all_with_locus (&list, EXPR_LOCATION (stmt));
- bsi_insert_before (bsi, list, BSI_SAME_STMT);
+ if (gimple_has_location (stmt))
+ annotate_all_with_location (seq, gimple_location (stmt));
+ gsi_insert_seq_before (gsi, seq, GSI_SAME_STMT);
}
-/* Similarly, but insert after BSI. Handles insertion onto edges as well. */
+/* Similarly, but insert after GSI. Handles insertion onto edges as well. */
void
-sra_insert_after (block_stmt_iterator *bsi, tree list)
+sra_insert_after (gimple_stmt_iterator *gsi, gimple_seq seq)
{
- tree stmt = bsi_stmt (*bsi);
+ gimple stmt = gsi_stmt (*gsi);
- if (EXPR_HAS_LOCATION (stmt))
- annotate_all_with_locus (&list, EXPR_LOCATION (stmt));
+ if (gimple_has_location (stmt))
+ annotate_all_with_location (seq, gimple_location (stmt));
if (stmt_ends_bb_p (stmt))
- insert_edge_copies (list, bsi->bb);
+ insert_edge_copies_seq (seq, gsi_bb (*gsi));
else
- bsi_insert_after (bsi, list, BSI_SAME_STMT);
+ gsi_insert_seq_after (gsi, seq, GSI_SAME_STMT);
}
-/* Similarly, but replace the statement at BSI. */
+/* Similarly, but replace the statement at GSI. */
static void
-sra_replace (block_stmt_iterator *bsi, tree list)
+sra_replace (gimple_stmt_iterator *gsi, gimple_seq seq)
{
- sra_insert_before (bsi, list);
- bsi_remove (bsi, false);
- if (bsi_end_p (*bsi))
- *bsi = bsi_last (bsi->bb);
+ sra_insert_before (gsi, seq);
+ gsi_remove (gsi, false);
+ if (gsi_end_p (*gsi))
+ *gsi = gsi_last (gsi_seq (*gsi));
else
- bsi_prev (bsi);
+ gsi_prev (gsi);
}
/* Data structure that bitfield_overlaps_p fills in with information
@@ -3004,7 +3009,7 @@ bitfield_overlaps_p (tree blen, tree bpos, struct sra_elt *fld,
static void
sra_explode_bitfield_assignment (tree var, tree vpos, bool to_var,
- tree *listp, tree blen, tree bpos,
+ gimple_seq *seq_p, tree blen, tree bpos,
struct sra_elt *elt)
{
struct sra_elt *fld;
@@ -3022,7 +3027,8 @@ sra_explode_bitfield_assignment (tree var, tree vpos, bool to_var,
if (fld->replacement)
{
- tree infld, invar, st, type;
+ tree infld, invar, type;
+ gimple_seq st;
infld = fld->replacement;
@@ -3061,7 +3067,7 @@ sra_explode_bitfield_assignment (tree var, tree vpos, bool to_var,
else
st = sra_build_bf_assignment (infld, invar);
- append_to_statement_list (st, listp);
+ gimple_seq_add_seq (seq_p, st);
}
else
{
@@ -3070,7 +3076,7 @@ sra_explode_bitfield_assignment (tree var, tree vpos, bool to_var,
if (flp.overlap_pos)
sub = size_binop (PLUS_EXPR, sub, flp.overlap_pos);
- sra_explode_bitfield_assignment (var, sub, to_var, listp,
+ sra_explode_bitfield_assignment (var, sub, to_var, seq_p,
flen, fpos, fld);
}
}
@@ -3083,7 +3089,8 @@ sra_explode_bitfield_assignment (tree var, tree vpos, bool to_var,
full variable back to the scalarized variables. */
static void
-sra_sync_for_bitfield_assignment (tree *listbeforep, tree *listafterp,
+sra_sync_for_bitfield_assignment (gimple_seq *seq_before_p,
+ gimple_seq *seq_after_p,
tree blen, tree bpos,
struct sra_elt *elt)
{
@@ -3096,18 +3103,18 @@ sra_sync_for_bitfield_assignment (tree *listbeforep, tree *listafterp,
if (fld->replacement || (!flp.overlap_len && !flp.overlap_pos))
{
generate_copy_inout (fld, false, generate_element_ref (fld),
- listbeforep);
+ seq_before_p);
mark_no_warning (fld);
- if (listafterp)
+ if (seq_after_p)
generate_copy_inout (fld, true, generate_element_ref (fld),
- listafterp);
+ seq_after_p);
}
else
{
tree flen = flp.overlap_len ? flp.overlap_len : flp.field_len;
tree fpos = flp.overlap_pos ? flp.overlap_pos : bitsize_int (0);
- sra_sync_for_bitfield_assignment (listbeforep, listafterp,
+ sra_sync_for_bitfield_assignment (seq_before_p, seq_after_p,
flen, fpos, fld);
}
}
@@ -3118,10 +3125,10 @@ sra_sync_for_bitfield_assignment (tree *listbeforep, tree *listafterp,
aggregate. IS_OUTPUT is true if ELT is being modified. */
static void
-scalarize_use (struct sra_elt *elt, tree *expr_p, block_stmt_iterator *bsi,
+scalarize_use (struct sra_elt *elt, tree *expr_p, gimple_stmt_iterator *gsi,
bool is_output, bool use_all)
{
- tree stmt = bsi_stmt (*bsi);
+ gimple stmt = gsi_stmt (*gsi);
tree bfexpr;
if (elt->replacement)
@@ -3133,52 +3140,43 @@ scalarize_use (struct sra_elt *elt, tree *expr_p, block_stmt_iterator *bsi,
if (is_output
&& TREE_CODE (elt->replacement) == BIT_FIELD_REF
&& is_gimple_reg (TREE_OPERAND (elt->replacement, 0))
- && TREE_CODE (stmt) == GIMPLE_MODIFY_STMT
- && &GIMPLE_STMT_OPERAND (stmt, 0) == expr_p)
+ && is_gimple_assign (stmt)
+ && gimple_assign_lhs_ptr (stmt) == expr_p)
{
- tree newstmt = sra_build_elt_assignment
- (elt, GIMPLE_STMT_OPERAND (stmt, 1));
- if (TREE_CODE (newstmt) != STATEMENT_LIST)
- {
- tree list = NULL;
- append_to_statement_list (newstmt, &list);
- newstmt = list;
- }
- sra_replace (bsi, newstmt);
+ gimple_seq newseq;
+ /* RHS must be a single operand. */
+ gcc_assert (gimple_assign_single_p (stmt));
+ newseq = sra_build_elt_assignment (elt, gimple_assign_rhs1 (stmt));
+ sra_replace (gsi, newseq);
return;
}
else if (!is_output
&& TREE_CODE (elt->replacement) == BIT_FIELD_REF
- && TREE_CODE (stmt) == GIMPLE_MODIFY_STMT
- && &GIMPLE_STMT_OPERAND (stmt, 1) == expr_p)
+ && is_gimple_assign (stmt)
+ && gimple_assign_rhs1_ptr (stmt) == expr_p)
{
tree tmp = make_rename_temp
- (TREE_TYPE (GIMPLE_STMT_OPERAND (stmt, 0)), "SR");
- tree newstmt = sra_build_assignment (tmp, REPLDUP (elt->replacement));
+ (TREE_TYPE (gimple_assign_lhs (stmt)), "SR");
+ gimple_seq newseq = sra_build_assignment (tmp, REPLDUP (elt->replacement));
- if (TREE_CODE (newstmt) != STATEMENT_LIST)
- {
- tree list = NULL;
- append_to_statement_list (newstmt, &list);
- newstmt = list;
- }
- sra_insert_before (bsi, newstmt);
+ sra_insert_before (gsi, newseq);
replacement = tmp;
}
if (is_output)
- mark_all_v_defs (stmt);
+ mark_all_v_defs_stmt (stmt);
*expr_p = REPLDUP (replacement);
update_stmt (stmt);
}
else if (use_all && is_output
- && TREE_CODE (stmt) == GIMPLE_MODIFY_STMT
+ && is_gimple_assign (stmt)
&& TREE_CODE (bfexpr
- = GIMPLE_STMT_OPERAND (stmt, 0)) == BIT_FIELD_REF
+ = gimple_assign_lhs (stmt)) == BIT_FIELD_REF
&& &TREE_OPERAND (bfexpr, 0) == expr_p
&& INTEGRAL_TYPE_P (TREE_TYPE (bfexpr))
&& TREE_CODE (TREE_TYPE (*expr_p)) == RECORD_TYPE)
{
- tree listbefore = NULL, listafter = NULL;
+ gimple_seq seq_before = NULL;
+ gimple_seq seq_after = NULL;
tree blen = fold_convert (bitsizetype, TREE_OPERAND (bfexpr, 1));
tree bpos = fold_convert (bitsizetype, TREE_OPERAND (bfexpr, 2));
bool update = false;
@@ -3186,18 +3184,18 @@ scalarize_use (struct sra_elt *elt, tree *expr_p, block_stmt_iterator *bsi,
if (!elt->use_block_copy)
{
tree type = TREE_TYPE (bfexpr);
- tree var = make_rename_temp (type, "SR"), tmp, st, vpos;
+ tree var = make_rename_temp (type, "SR"), tmp, vpos;
+ gimple st;
- GIMPLE_STMT_OPERAND (stmt, 0) = var;
+ gimple_assign_set_lhs (stmt, var);
update = true;
if (!TYPE_UNSIGNED (type))
{
type = unsigned_type_for (type);
tmp = make_rename_temp (type, "SR");
- st = build_gimple_modify_stmt (tmp,
- fold_convert (type, var));
- append_to_statement_list (st, &listafter);
+ st = gimple_build_assign (tmp, fold_convert (type, var));
+ gimple_seq_add_stmt (&seq_after, st);
var = tmp;
}
@@ -3210,35 +3208,35 @@ scalarize_use (struct sra_elt *elt, tree *expr_p, block_stmt_iterator *bsi,
else
vpos = bitsize_int (0);
sra_explode_bitfield_assignment
- (var, vpos, false, &listafter, blen, bpos, elt);
+ (var, vpos, false, &seq_after, blen, bpos, elt);
}
else
sra_sync_for_bitfield_assignment
- (&listbefore, &listafter, blen, bpos, elt);
+ (&seq_before, &seq_after, blen, bpos, elt);
- if (listbefore)
+ if (seq_before)
{
- mark_all_v_defs (listbefore);
- sra_insert_before (bsi, listbefore);
+ mark_all_v_defs_seq (seq_before);
+ sra_insert_before (gsi, seq_before);
}
- if (listafter)
+ if (seq_after)
{
- mark_all_v_defs (listafter);
- sra_insert_after (bsi, listafter);
+ mark_all_v_defs_seq (seq_after);
+ sra_insert_after (gsi, seq_after);
}
if (update)
update_stmt (stmt);
}
else if (use_all && !is_output
- && TREE_CODE (stmt) == GIMPLE_MODIFY_STMT
+ && is_gimple_assign (stmt)
&& TREE_CODE (bfexpr
- = GIMPLE_STMT_OPERAND (stmt, 1)) == BIT_FIELD_REF
- && &TREE_OPERAND (GIMPLE_STMT_OPERAND (stmt, 1), 0) == expr_p
+ = gimple_assign_rhs1 (stmt)) == BIT_FIELD_REF
+ && &TREE_OPERAND (gimple_assign_rhs1 (stmt), 0) == expr_p
&& INTEGRAL_TYPE_P (TREE_TYPE (bfexpr))
&& TREE_CODE (TREE_TYPE (*expr_p)) == RECORD_TYPE)
{
- tree list = NULL;
+ gimple_seq seq = NULL;
tree blen = fold_convert (bitsizetype, TREE_OPERAND (bfexpr, 1));
tree bpos = fold_convert (bitsizetype, TREE_OPERAND (bfexpr, 2));
bool update = false;
@@ -3253,9 +3251,9 @@ scalarize_use (struct sra_elt *elt, tree *expr_p, block_stmt_iterator *bsi,
var = make_rename_temp (type, "SR");
- append_to_statement_list (build_gimple_modify_stmt
- (var, build_int_cst_wide (type, 0, 0)),
- &list);
+ gimple_seq_add_stmt (&seq,
+ gimple_build_assign
+ (var, build_int_cst_wide (type, 0, 0)));
/* If VAR is wider than BLEN bits, it is padded at the
most-significant end. We want to set VPOS such that
@@ -3266,19 +3264,19 @@ scalarize_use (struct sra_elt *elt, tree *expr_p, block_stmt_iterator *bsi,
else
vpos = bitsize_int (0);
sra_explode_bitfield_assignment
- (var, vpos, true, &list, blen, bpos, elt);
+ (var, vpos, true, &seq, blen, bpos, elt);
- GIMPLE_STMT_OPERAND (stmt, 1) = var;
+ gimple_assign_set_rhs1 (stmt, var);
update = true;
}
else
sra_sync_for_bitfield_assignment
- (&list, NULL, blen, bpos, elt);
+ (&seq, NULL, blen, bpos, elt);
- if (list)
+ if (seq)
{
- mark_all_v_defs (list);
- sra_insert_before (bsi, list);
+ mark_all_v_defs_seq (seq);
+ sra_insert_before (gsi, seq);
}
if (update)
@@ -3286,7 +3284,7 @@ scalarize_use (struct sra_elt *elt, tree *expr_p, block_stmt_iterator *bsi,
}
else
{
- tree list = NULL;
+ gimple_seq seq = NULL;
/* Otherwise we need some copies. If ELT is being read, then we
want to store all (modified) sub-elements back into the
@@ -3302,15 +3300,15 @@ scalarize_use (struct sra_elt *elt, tree *expr_p, block_stmt_iterator *bsi,
This optimization would be most effective if sra_walk_function
processed the blocks in dominator order. */
- generate_copy_inout (elt, is_output, generate_element_ref (elt), &list);
- if (list == NULL)
+ generate_copy_inout (elt, is_output, generate_element_ref (elt), &seq);
+ if (seq == NULL)
return;
- mark_all_v_defs (list);
+ mark_all_v_defs_seq (seq);
if (is_output)
- sra_insert_after (bsi, list);
+ sra_insert_after (gsi, seq);
else
{
- sra_insert_before (bsi, list);
+ sra_insert_before (gsi, seq);
if (use_all)
mark_no_warning (elt);
}
@@ -3322,21 +3320,24 @@ scalarize_use (struct sra_elt *elt, tree *expr_p, block_stmt_iterator *bsi,
static void
scalarize_copy (struct sra_elt *lhs_elt, struct sra_elt *rhs_elt,
- block_stmt_iterator *bsi)
+ gimple_stmt_iterator *gsi)
{
- tree list, stmt;
+ gimple_seq seq;
+ gimple stmt;
if (lhs_elt->replacement && rhs_elt->replacement)
{
/* If we have two scalar operands, modify the existing statement. */
- stmt = bsi_stmt (*bsi);
+ stmt = gsi_stmt (*gsi);
/* See the commentary in sra_walk_function concerning
RETURN_EXPR, and why we should never see one here. */
- gcc_assert (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT);
+ gcc_assert (is_gimple_assign (stmt));
+ gcc_assert (gimple_assign_copy_p (stmt));
+
- GIMPLE_STMT_OPERAND (stmt, 0) = lhs_elt->replacement;
- GIMPLE_STMT_OPERAND (stmt, 1) = REPLDUP (rhs_elt->replacement);
+ gimple_assign_set_lhs (stmt, lhs_elt->replacement);
+ gimple_assign_set_rhs1 (stmt, REPLDUP (rhs_elt->replacement));
update_stmt (stmt);
}
else if (lhs_elt->use_block_copy || rhs_elt->use_block_copy)
@@ -3349,22 +3350,22 @@ scalarize_copy (struct sra_elt *lhs_elt, struct sra_elt *rhs_elt,
would at least allow those elements that are instantiated in
both structures to be optimized well. */
- list = NULL;
+ seq = NULL;
generate_copy_inout (rhs_elt, false,
- generate_element_ref (rhs_elt), &list);
- if (list)
+ generate_element_ref (rhs_elt), &seq);
+ if (seq)
{
- mark_all_v_defs (list);
- sra_insert_before (bsi, list);
+ mark_all_v_defs_seq (seq);
+ sra_insert_before (gsi, seq);
}
- list = NULL;
+ seq = NULL;
generate_copy_inout (lhs_elt, true,
- generate_element_ref (lhs_elt), &list);
- if (list)
+ generate_element_ref (lhs_elt), &seq);
+ if (seq)
{
- mark_all_v_defs (list);
- sra_insert_after (bsi, list);
+ mark_all_v_defs_seq (seq);
+ sra_insert_after (gsi, seq);
}
}
else
@@ -3373,14 +3374,14 @@ scalarize_copy (struct sra_elt *lhs_elt, struct sra_elt *rhs_elt,
case perform pair-wise element assignments and replace the
original block copy statement. */
- stmt = bsi_stmt (*bsi);
- mark_all_v_defs (stmt);
+ stmt = gsi_stmt (*gsi);
+ mark_all_v_defs_stmt (stmt);
- list = NULL;
- generate_element_copy (lhs_elt, rhs_elt, &list);
- gcc_assert (list);
- mark_all_v_defs (list);
- sra_replace (bsi, list);
+ seq = NULL;
+ generate_element_copy (lhs_elt, rhs_elt, &seq);
+ gcc_assert (seq);
+ mark_all_v_defs_seq (seq);
+ sra_replace (gsi, seq);
}
}
@@ -3390,23 +3391,23 @@ scalarize_copy (struct sra_elt *lhs_elt, struct sra_elt *rhs_elt,
CONSTRUCTOR. */
static void
-scalarize_init (struct sra_elt *lhs_elt, tree rhs, block_stmt_iterator *bsi)
+scalarize_init (struct sra_elt *lhs_elt, tree rhs, gimple_stmt_iterator *gsi)
{
bool result = true;
- tree list = NULL, init_list = NULL;
+ gimple_seq seq = NULL, init_seq = NULL;
/* Generate initialization statements for all members extant in the RHS. */
if (rhs)
{
/* Unshare the expression just in case this is from a decl's initial. */
rhs = unshare_expr (rhs);
- result = generate_element_init (lhs_elt, rhs, &init_list);
+ result = generate_element_init (lhs_elt, rhs, &init_seq);
}
/* CONSTRUCTOR is defined such that any member not mentioned is assigned
a zero value. Initialize the rest of the instantiated elements. */
- generate_element_zero (lhs_elt, &list);
- append_to_statement_list (init_list, &list);
+ generate_element_zero (lhs_elt, &seq);
+ gimple_seq_add_seq (&seq, init_seq);
if (!result)
{
@@ -3416,11 +3417,11 @@ scalarize_init (struct sra_elt *lhs_elt, tree rhs, block_stmt_iterator *bsi)
constants. The easiest way to do this is to generate a complete
copy-out, and then follow that with the constant assignments
that we were able to build. DCE will clean things up. */
- tree list0 = NULL;
+ gimple_seq seq0 = NULL;
generate_copy_inout (lhs_elt, true, generate_element_ref (lhs_elt),
- &list0);
- append_to_statement_list (list, &list0);
- list = list0;
+ &seq0);
+ gimple_seq_add_seq (&seq0, seq);
+ seq = seq0;
}
if (lhs_elt->use_block_copy || !result)
@@ -3428,20 +3429,20 @@ scalarize_init (struct sra_elt *lhs_elt, tree rhs, block_stmt_iterator *bsi)
/* Since LHS is not fully instantiated, we must leave the structure
assignment in place. Treating this case differently from a USE
exposes constants to later optimizations. */
- if (list)
+ if (seq)
{
- mark_all_v_defs (list);
- sra_insert_after (bsi, list);
+ mark_all_v_defs_seq (seq);
+ sra_insert_after (gsi, seq);
}
}
else
{
/* The LHS is fully instantiated. The list of initializations
replaces the original structure assignment. */
- gcc_assert (list);
- mark_all_v_defs (bsi_stmt (*bsi));
- mark_all_v_defs (list);
- sra_replace (bsi, list);
+ gcc_assert (seq);
+ mark_all_v_defs_stmt (gsi_stmt (*gsi));
+ mark_all_v_defs_seq (seq);
+ sra_replace (gsi, seq);
}
}
@@ -3470,7 +3471,7 @@ mark_notrap (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
static void
scalarize_ldst (struct sra_elt *elt, tree other,
- block_stmt_iterator *bsi, bool is_output)
+ gimple_stmt_iterator *gsi, bool is_output)
{
/* Shouldn't have gotten called for a scalar. */
gcc_assert (!elt->replacement);
@@ -3479,7 +3480,7 @@ scalarize_ldst (struct sra_elt *elt, tree other,
{
/* Since ELT is not fully instantiated, we have to leave the
block copy in place. Treat this as a USE. */
- scalarize_use (elt, NULL, bsi, is_output, false);
+ scalarize_use (elt, NULL, gsi, is_output, false);
}
else
{
@@ -3487,19 +3488,21 @@ scalarize_ldst (struct sra_elt *elt, tree other,
case we can have each element stored/loaded directly to/from the
corresponding slot in OTHER. This avoids a block copy. */
- tree list = NULL, stmt = bsi_stmt (*bsi);
+ gimple_seq seq = NULL;
+ gimple stmt = gsi_stmt (*gsi);
- mark_all_v_defs (stmt);
- generate_copy_inout (elt, is_output, other, &list);
- gcc_assert (list);
- mark_all_v_defs (list);
+ mark_all_v_defs_stmt (stmt);
+ generate_copy_inout (elt, is_output, other, &seq);
+ gcc_assert (seq);
+ mark_all_v_defs_seq (seq);
/* Preserve EH semantics. */
if (stmt_ends_bb_p (stmt))
{
- tree_stmt_iterator tsi;
- tree first, blist = NULL;
- bool thr = tree_could_throw_p (stmt);
+ gimple_stmt_iterator si;
+ gimple first;
+ gimple_seq blist = NULL;
+ bool thr = stmt_could_throw_p (stmt);
/* If the last statement of this BB created an EH edge
before scalarization, we have to locate the first
@@ -3510,26 +3513,26 @@ scalarize_ldst (struct sra_elt *elt, tree other,
list will be added to normal outgoing edges of the same
BB. If they access any memory, it's the same memory, so
we can assume they won't throw. */
- tsi = tsi_start (list);
- for (first = tsi_stmt (tsi);
- thr && !tsi_end_p (tsi) && !tree_could_throw_p (first);
- first = tsi_stmt (tsi))
+ si = gsi_start (seq);
+ for (first = gsi_stmt (si);
+ thr && !gsi_end_p (si) && !stmt_could_throw_p (first);
+ first = gsi_stmt (si))
{
- tsi_delink (&tsi);
- append_to_statement_list (first, &blist);
+ gsi_remove (&si, false);
+ gimple_seq_add_stmt (&blist, first);
}
/* Extract the first remaining statement from LIST, this is
the EH statement if there is one. */
- tsi_delink (&tsi);
+ gsi_remove (&si, false);
if (blist)
- sra_insert_before (bsi, blist);
+ sra_insert_before (gsi, blist);
/* Replace the old statement with this new representative. */
- bsi_replace (bsi, first, true);
+ gsi_replace (gsi, first, true);
- if (!tsi_end_p (tsi))
+ if (!gsi_end_p (si))
{
/* If any reference would trap, then they all would. And more
to the point, the first would. Therefore none of the rest
@@ -3538,16 +3541,16 @@ scalarize_ldst (struct sra_elt *elt, tree other,
TREE_THIS_NOTRAP in all INDIRECT_REFs. */
do
{
- walk_tree (tsi_stmt_ptr (tsi), mark_notrap, NULL, NULL);
- tsi_next (&tsi);
+ walk_gimple_stmt (&si, NULL, mark_notrap, NULL);
+ gsi_next (&si);
}
- while (!tsi_end_p (tsi));
+ while (!gsi_end_p (si));
- insert_edge_copies (list, bsi->bb);
+ insert_edge_copies_seq (seq, gsi_bb (*gsi));
}
}
else
- sra_replace (bsi, list);
+ sra_replace (gsi, seq);
}
}
@@ -3556,7 +3559,7 @@ scalarize_ldst (struct sra_elt *elt, tree other,
static void
scalarize_parms (void)
{
- tree list = NULL;
+ gimple_seq seq = NULL;
unsigned i;
bitmap_iterator bi;
@@ -3564,13 +3567,13 @@ scalarize_parms (void)
{
tree var = referenced_var (i);
struct sra_elt *elt = lookup_element (NULL, var, NULL, NO_INSERT);
- generate_copy_inout (elt, true, var, &list);
+ generate_copy_inout (elt, true, var, &seq);
}
- if (list)
+ if (seq)
{
- insert_edge_copies (list, ENTRY_BLOCK_PTR);
- mark_all_v_defs (list);
+ insert_edge_copies_seq (seq, ENTRY_BLOCK_PTR);
+ mark_all_v_defs_seq (seq);
}
}
@@ -3585,7 +3588,7 @@ scalarize_function (void)
sra_walk_function (&fns);
scalarize_parms ();
- bsi_commit_edge_inserts ();
+ gsi_commit_edge_inserts ();
}
@@ -3635,13 +3638,14 @@ debug_sra_elt_name (struct sra_elt *elt)
void
sra_init_cache (void)
{
- if (sra_type_decomp_cache)
+ if (sra_type_decomp_cache)
return;
sra_type_decomp_cache = BITMAP_ALLOC (NULL);
sra_type_inst_cache = BITMAP_ALLOC (NULL);
}
+
/* Main entry point. */
static unsigned int
diff --git a/gcc/tree-ssa-address.c b/gcc/tree-ssa-address.c
index 55d43a5e362..198adb409e6 100644
--- a/gcc/tree-ssa-address.c
+++ b/gcc/tree-ssa-address.c
@@ -556,31 +556,31 @@ addr_to_parts (aff_tree *addr, struct mem_address *parts)
/* Force the PARTS to register. */
static void
-gimplify_mem_ref_parts (block_stmt_iterator *bsi, struct mem_address *parts)
+gimplify_mem_ref_parts (gimple_stmt_iterator *gsi, struct mem_address *parts)
{
if (parts->base)
- parts->base = force_gimple_operand_bsi (bsi, parts->base,
+ parts->base = force_gimple_operand_gsi (gsi, parts->base,
true, NULL_TREE,
- true, BSI_SAME_STMT);
+ true, GSI_SAME_STMT);
if (parts->index)
- parts->index = force_gimple_operand_bsi (bsi, parts->index,
+ parts->index = force_gimple_operand_gsi (gsi, parts->index,
true, NULL_TREE,
- true, BSI_SAME_STMT);
+ true, GSI_SAME_STMT);
}
/* Creates and returns a TARGET_MEM_REF for address ADDR. If necessary
- computations are emitted in front of BSI. TYPE is the mode
+ computations are emitted in front of GSI. TYPE is the mode
of created memory reference. */
tree
-create_mem_ref (block_stmt_iterator *bsi, tree type, aff_tree *addr)
+create_mem_ref (gimple_stmt_iterator *gsi, tree type, aff_tree *addr)
{
tree mem_ref, tmp;
tree atype;
struct mem_address parts;
addr_to_parts (addr, &parts);
- gimplify_mem_ref_parts (bsi, &parts);
+ gimplify_mem_ref_parts (gsi, &parts);
mem_ref = create_mem_ref_raw (type, &parts);
if (mem_ref)
return mem_ref;
@@ -591,10 +591,10 @@ create_mem_ref (block_stmt_iterator *bsi, tree type, aff_tree *addr)
{
/* Move the multiplication to index. */
gcc_assert (parts.index);
- parts.index = force_gimple_operand_bsi (bsi,
+ parts.index = force_gimple_operand_gsi (gsi,
fold_build2 (MULT_EXPR, sizetype,
parts.index, parts.step),
- true, NULL_TREE, true, BSI_SAME_STMT);
+ true, NULL_TREE, true, GSI_SAME_STMT);
parts.step = NULL_TREE;
mem_ref = create_mem_ref_raw (type, &parts);
@@ -616,11 +616,11 @@ create_mem_ref (block_stmt_iterator *bsi, tree type, aff_tree *addr)
if (parts.index)
{
atype = TREE_TYPE (tmp);
- parts.base = force_gimple_operand_bsi (bsi,
+ parts.base = force_gimple_operand_gsi (gsi,
fold_build2 (PLUS_EXPR, atype,
fold_convert (atype, parts.base),
tmp),
- true, NULL_TREE, true, BSI_SAME_STMT);
+ true, NULL_TREE, true, GSI_SAME_STMT);
}
else
{
@@ -643,11 +643,11 @@ create_mem_ref (block_stmt_iterator *bsi, tree type, aff_tree *addr)
if (parts.base)
{
atype = TREE_TYPE (parts.base);
- parts.base = force_gimple_operand_bsi (bsi,
+ parts.base = force_gimple_operand_gsi (gsi,
fold_build2 (POINTER_PLUS_EXPR, atype,
parts.base,
parts.index),
- true, NULL_TREE, true, BSI_SAME_STMT);
+ true, NULL_TREE, true, GSI_SAME_STMT);
}
else
parts.base = parts.index;
@@ -664,11 +664,11 @@ create_mem_ref (block_stmt_iterator *bsi, tree type, aff_tree *addr)
if (parts.base)
{
atype = TREE_TYPE (parts.base);
- parts.base = force_gimple_operand_bsi (bsi,
+ parts.base = force_gimple_operand_gsi (gsi,
fold_build2 (POINTER_PLUS_EXPR, atype,
parts.base,
fold_convert (sizetype, parts.offset)),
- true, NULL_TREE, true, BSI_SAME_STMT);
+ true, NULL_TREE, true, GSI_SAME_STMT);
}
else
parts.base = parts.offset;
diff --git a/gcc/tree-ssa-alias-warnings.c b/gcc/tree-ssa-alias-warnings.c
index be26cb37d49..67d7f94ea3d 100644
--- a/gcc/tree-ssa-alias-warnings.c
+++ b/gcc/tree-ssa-alias-warnings.c
@@ -244,7 +244,7 @@ struct alias_match
{
tree rhs;
bool is_rhs_pointer;
- tree site;
+ gimple site;
};
@@ -252,15 +252,14 @@ struct alias_match
of STMT matches DATA. */
static bool
-find_alias_site_helper (tree var ATTRIBUTE_UNUSED, tree stmt, void *data)
+find_alias_site_helper (tree var ATTRIBUTE_UNUSED, gimple stmt, void *data)
{
struct alias_match *match = (struct alias_match *) data;
- tree rhs_pointer = get_rhs (stmt);
+ tree rhs_pointer = NULL_TREE;
tree to_match = NULL_TREE;
- while (CONVERT_EXPR_P (rhs_pointer)
- || TREE_CODE (rhs_pointer) == VIEW_CONVERT_EXPR)
- rhs_pointer = TREE_OPERAND (rhs_pointer, 0);
+ if (gimple_assign_cast_p (stmt))
+ rhs_pointer = gimple_assign_rhs1 (stmt);
if (!rhs_pointer)
/* Not a type conversion. */
@@ -287,7 +286,7 @@ find_alias_site_helper (tree var ATTRIBUTE_UNUSED, tree stmt, void *data)
For now, just implement the case where OBJECT1 is an SSA name defined
by a PHI statement. */
-static tree
+static gimple
find_alias_site (tree object1, bool is_ptr1 ATTRIBUTE_UNUSED,
tree object2, bool is_ptr2)
{
@@ -295,10 +294,10 @@ find_alias_site (tree object1, bool is_ptr1 ATTRIBUTE_UNUSED,
match.rhs = object2;
match.is_rhs_pointer = is_ptr2;
- match.site = NULL_TREE;
+ match.site = NULL;
if (TREE_CODE (object1) != SSA_NAME)
- return NULL_TREE;
+ return NULL;
walk_use_def_chains (object1, find_alias_site_helper, &match, false);
return match.site;
@@ -344,29 +343,55 @@ get_ssa_base (tree expr)
objs: <ptr, 2>
PTR shows up twice as an object, but is dereferenced only once.
- The elements of the hash tables are tree_map objects. */
+ The elements of the hash tables are gimple_map objects. */
struct reference_matches
{
htab_t ptrs;
htab_t objs;
};
+struct gimple_tree_map
+{
+ tree from;
+ gimple to;
+};
+
+/* Return true if the from tree in both gimple-tree maps are equal.
+ VA and VB are really instances of struct gimple_tree_map. */
+
+static int
+gimple_tree_map_eq (const void *va, const void *vb)
+{
+ const struct gimple_tree_map *const a = (const struct gimple_tree_map *) va;
+ const struct gimple_tree_map *const b = (const struct gimple_tree_map *) vb;
+ return (a->from == b->from);
+}
+
+/* Hash a from tree in a gimple_tree_map. ITEM is really an instance
+ of struct gimple_tree_map. */
-/* Return the match, if any. Otherwise, return NULL_TREE. It will
- return NULL_TREE even when a match was found, if the value associated
- to KEY is NULL_TREE. */
+static unsigned int
+gimple_tree_map_hash (const void *item)
+{
+ return htab_hash_pointer (((const struct gimple_tree_map *)item)->from);
+}
+
+/* Return the match, if any. Otherwise, return NULL. It will return
+ NULL even when a match was found, if the value associated to KEY is
+ NULL. */
-static inline tree
+static inline gimple
match (htab_t ref_map, tree key)
{
- struct tree_map *found;
+ struct gimple_tree_map *found;
void **slot = NULL;
slot = htab_find_slot (ref_map, &key, NO_INSERT);
if (!slot)
- return NULL_TREE;
+ return NULL;
+
+ found = (struct gimple_tree_map *) *slot;
- found = (struct tree_map *) *slot;
return found->to;
}
@@ -375,9 +400,11 @@ match (htab_t ref_map, tree key)
already exists and its value is NULL_TREE. Otherwise, do nothing. */
static inline void
-maybe_add_match (htab_t ref_map, struct tree_map *key)
+maybe_add_match (htab_t ref_map, struct gimple_tree_map *key)
{
- struct tree_map *found = (struct tree_map *) htab_find (ref_map, key);
+ struct gimple_tree_map *found;
+
+ found = (struct gimple_tree_map *) htab_find (ref_map, key);
if (found && !found->to)
found->to = key->to;
@@ -390,10 +417,12 @@ static void
add_key (htab_t ht, tree t, alloc_pool references_pool)
{
void **slot;
- struct tree_map *tp = (struct tree_map *) pool_alloc (references_pool);
+ struct gimple_tree_map *tp;
+
+ tp = (struct gimple_tree_map *) pool_alloc (references_pool);
- tp->base.from = t;
- tp->to = NULL_TREE;
+ tp->from = t;
+ tp->to = NULL;
slot = htab_find_slot (ht, &t, INSERT);
*slot = (void *) tp;
}
@@ -412,8 +441,9 @@ reference_table_alloc_pool (bool build)
if (ref_table_alloc_pool || !build)
return ref_table_alloc_pool;
- ref_table_alloc_pool =
- create_alloc_pool ("ref_table_alloc_pool", sizeof (struct tree_map), 20);
+ ref_table_alloc_pool = create_alloc_pool ("ref_table_alloc_pool",
+ sizeof (struct gimple_tree_map),
+ 20);
return ref_table_alloc_pool;
}
@@ -430,8 +460,10 @@ build_reference_table (void)
alloc_pool references_pool = reference_table_alloc_pool (true);
ref_table = XNEW (struct reference_matches);
- ref_table->objs = htab_create (10, tree_map_base_hash, tree_map_eq, NULL);
- ref_table->ptrs = htab_create (10, tree_map_base_hash, tree_map_eq, NULL);
+ ref_table->objs = htab_create (10, gimple_tree_map_hash, gimple_tree_map_eq,
+ NULL);
+ ref_table->ptrs = htab_create (10, gimple_tree_map_hash, gimple_tree_map_eq,
+ NULL);
for (i = 1; i < num_ssa_names; i++)
{
@@ -518,8 +550,9 @@ find_references_in_tree_helper (tree *tp,
int *walk_subtrees ATTRIBUTE_UNUSED,
void *data)
{
- struct tree_map match;
+ struct gimple_tree_map match;
static int parent_tree_code = ERROR_MARK;
+ struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
/* Do not report references just for the purpose of taking an address.
XXX: we rely on the fact that the tree walk is in preorder
@@ -528,16 +561,16 @@ find_references_in_tree_helper (tree *tp,
if (parent_tree_code == ADDR_EXPR)
goto finish;
- match.to = (tree) data;
+ match.to = (gimple) wi->info;
if (TREE_CODE (*tp) == INDIRECT_REF)
{
- match.base.from = TREE_OPERAND (*tp, 0);
+ match.from = TREE_OPERAND (*tp, 0);
maybe_add_match (reference_table (true)->ptrs, &match);
}
else
{
- match.base.from = *tp;
+ match.from = *tp;
maybe_add_match (reference_table (true)->objs, &match);
}
@@ -553,12 +586,16 @@ static void
find_references_in_function (void)
{
basic_block bb;
- block_stmt_iterator i;
+ gimple_stmt_iterator i;
FOR_EACH_BB (bb)
- for (i = bsi_start (bb); !bsi_end_p (i); bsi_next (&i))
- walk_tree (bsi_stmt_ptr (i), find_references_in_tree_helper,
- (void *) *bsi_stmt_ptr (i), NULL);
+ for (i = gsi_start_bb (bb); !gsi_end_p (i); gsi_next (&i))
+ {
+ struct walk_stmt_info wi;
+ memset (&wi, 0, sizeof (wi));
+ wi.info = (void *) gsi_stmt (i);
+ walk_gimple_op (gsi_stmt (i), find_references_in_tree_helper, &wi);
+ }
}
@@ -567,7 +604,7 @@ find_references_in_function (void)
XXX: only the first site is returned in the current
implementation. If there are no matching sites, return NULL_TREE. */
-static tree
+static gimple
reference_site (tree object, bool is_ptr)
{
if (is_ptr)
@@ -590,19 +627,19 @@ reference_site (tree object, bool is_ptr)
static void
maybe_find_missing_stmts (tree object1, bool is_ptr1,
tree object2, bool is_ptr2,
- tree *alias_site,
- tree *deref_site1,
- tree *deref_site2)
+ gimple *alias_site,
+ gimple *deref_site1,
+ gimple *deref_site2)
{
if (object1 && object2)
{
- if (!*alias_site || !EXPR_HAS_LOCATION (*alias_site))
+ if (!*alias_site || !gimple_has_location (*alias_site))
*alias_site = find_alias_site (object1, is_ptr1, object2, is_ptr2);
- if (!*deref_site1 || !EXPR_HAS_LOCATION (*deref_site1))
+ if (!*deref_site1 || !gimple_has_location (*deref_site1))
*deref_site1 = reference_site (object1, is_ptr1);
- if (!*deref_site2 || !EXPR_HAS_LOCATION (*deref_site2))
+ if (!*deref_site2 || !gimple_has_location (*deref_site2))
*deref_site2 = reference_site (object2, is_ptr2);
}
@@ -683,7 +720,6 @@ get_maybe_star_prefix (tree object, bool is_ptr)
&& TREE_CODE (TREE_TYPE (object)) == POINTER_TYPE) ? "*" : "";
}
-
/* Callback for contains_node_type_p.
Returns true if *T has tree code *(int*)DATA. */
@@ -710,18 +746,13 @@ contains_node_type_p (tree t, int type)
/* Return true if a warning was issued in the front end at STMT. */
static bool
-already_warned_in_frontend_p (tree stmt)
+already_warned_in_frontend_p (gimple stmt)
{
- tree rhs_pointer;
-
- if (stmt == NULL_TREE)
+ if (stmt == NULL)
return false;
- rhs_pointer = get_rhs (stmt);
-
- if ((CONVERT_EXPR_P (rhs_pointer)
- || TREE_CODE (rhs_pointer) == VIEW_CONVERT_EXPR)
- && TREE_NO_WARNING (rhs_pointer))
+ if (gimple_assign_cast_p (stmt)
+ && TREE_NO_WARNING (gimple_assign_rhs1 (stmt)))
return true;
else
return false;
@@ -749,13 +780,13 @@ is_method_pointer (tree type)
case, that is where a pointer was assigned to the address of an object. */
static bool
-strict_aliasing_warn (tree alias_site,
+strict_aliasing_warn (gimple alias_site,
tree object1, bool is_ptr1,
tree object2, bool is_ptr2,
bool filter_artificials)
{
- tree ref_site1 = NULL_TREE;
- tree ref_site2 = NULL_TREE;
+ gimple ref_site1 = NULL;
+ gimple ref_site2 = NULL;
const char *name1;
const char *name2;
location_t alias_loc;
@@ -773,18 +804,18 @@ strict_aliasing_warn (tree alias_site,
maybe_find_missing_stmts (object1, is_ptr1, object2, is_ptr2, &alias_site,
&ref_site1, &ref_site2);
- if (EXPR_HAS_LOCATION (alias_site))
- alias_loc = EXPR_LOCATION (alias_site);
+ if (gimple_has_location (alias_site))
+ alias_loc = gimple_location (alias_site);
else
return false;
- if (EXPR_HAS_LOCATION (ref_site1))
- ref1_loc = EXPR_LOCATION (ref_site1);
+ if (gimple_has_location (ref_site1))
+ ref1_loc = gimple_location (ref_site1);
else
ref1_loc = alias_loc;
- if (EXPR_HAS_LOCATION (ref_site2))
- ref2_loc = EXPR_LOCATION (ref_site2);
+ if (gimple_has_location (ref_site2))
+ ref2_loc = gimple_location (ref_site2);
else
ref2_loc = alias_loc;
@@ -900,7 +931,7 @@ skip_this_pointer (tree ptr ATTRIBUTE_UNUSED, struct ptr_info_def *pi)
/* Find aliasing to named objects for pointer PTR. */
static void
-dsa_named_for (tree ptr)
+dsa_named_for (tree ptr ATTRIBUTE_UNUSED)
{
struct ptr_info_def *pi = SSA_NAME_PTR_INFO (ptr);
@@ -970,7 +1001,7 @@ processed_func_p (tree func)
void **slot = NULL;
if (!seen)
- seen = htab_create (10, tree_map_base_hash, tree_map_eq, NULL);
+ seen = htab_create (10, gimple_tree_map_hash, gimple_tree_map_eq, NULL);
slot = htab_find_slot (seen, &func, INSERT);
gcc_assert (slot);
diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c
index ee0f4a7316a..e1540f3b8f8 100644
--- a/gcc/tree-ssa-alias.c
+++ b/gcc/tree-ssa-alias.c
@@ -1,5 +1,5 @@
/* Alias analysis for trees.
- Copyright (C) 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
+ Copyright (C) 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
Contributed by Diego Novillo <dnovillo@redhat.com>
This file is part of GCC.
@@ -35,7 +35,7 @@ along with GCC; see the file COPYING3. If not see
#include "function.h"
#include "diagnostic.h"
#include "tree-dump.h"
-#include "tree-gimple.h"
+#include "gimple.h"
#include "tree-flow.h"
#include "tree-inline.h"
#include "tree-pass.h"
@@ -752,7 +752,7 @@ static void
count_mem_refs (long *num_vuses_p, long *num_vdefs_p,
long *num_partitioned_p, long *num_unpartitioned_p)
{
- block_stmt_iterator bsi;
+ gimple_stmt_iterator gsi;
basic_block bb;
long num_vdefs, num_vuses, num_partitioned, num_unpartitioned;
referenced_var_iterator rvi;
@@ -762,10 +762,10 @@ count_mem_refs (long *num_vuses_p, long *num_vdefs_p,
if (num_vuses_p || num_vdefs_p)
FOR_EACH_BB (bb)
- for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
- tree stmt = bsi_stmt (bsi);
- if (stmt_references_memory_p (stmt))
+ gimple stmt = gsi_stmt (gsi);
+ if (gimple_references_memory_p (stmt))
{
num_vuses += NUM_SSA_OPERANDS (stmt, SSA_OP_VUSE);
num_vdefs += NUM_SSA_OPERANDS (stmt, SSA_OP_VDEF);
@@ -1006,7 +1006,7 @@ debug_mp_info (VEC(mem_sym_stats_t,heap) *mp_info)
recorded by this function, see compute_memory_partitions). */
void
-update_mem_sym_stats_from_stmt (tree var, tree stmt, long num_direct_reads,
+update_mem_sym_stats_from_stmt (tree var, gimple stmt, long num_direct_reads,
long num_direct_writes)
{
mem_sym_stats_t stats;
@@ -1016,11 +1016,11 @@ update_mem_sym_stats_from_stmt (tree var, tree stmt, long num_direct_reads,
stats = get_mem_sym_stats_for (var);
stats->num_direct_reads += num_direct_reads;
- stats->frequency_reads += ((long) bb_for_stmt (stmt)->frequency
+ stats->frequency_reads += ((long) gimple_bb (stmt)->frequency
* num_direct_reads);
stats->num_direct_writes += num_direct_writes;
- stats->frequency_writes += ((long) bb_for_stmt (stmt)->frequency
+ stats->frequency_writes += ((long) gimple_bb (stmt)->frequency
* num_direct_writes);
}
@@ -1629,7 +1629,6 @@ done:
timevar_pop (TV_MEMORY_PARTITIONING);
}
-
/* Compute may-alias information for every variable referenced in function
FNDECL.
@@ -1812,11 +1811,11 @@ compute_may_aliases (void)
/* Populate all virtual operands and newly promoted register operands. */
{
- block_stmt_iterator bsi;
+ gimple_stmt_iterator gsi;
basic_block bb;
FOR_EACH_BB (bb)
- for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
- update_stmt_if_modified (bsi_stmt (bsi));
+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+ update_stmt_if_modified (gsi_stmt (gsi));
}
/* Debugging dumps. */
@@ -1852,7 +1851,8 @@ compute_may_aliases (void)
struct count_ptr_d
{
tree ptr;
- unsigned count;
+ unsigned num_stores;
+ unsigned num_loads;
};
@@ -1862,7 +1862,8 @@ struct count_ptr_d
static tree
count_ptr_derefs (tree *tp, int *walk_subtrees, void *data)
{
- struct count_ptr_d *count_p = (struct count_ptr_d *) data;
+ struct walk_stmt_info *wi_p = (struct walk_stmt_info *) data;
+ struct count_ptr_d *count_p = (struct count_ptr_d *) wi_p->info;
/* Do not walk inside ADDR_EXPR nodes. In the expression &ptr->fld,
pointer 'ptr' is *not* dereferenced, it is simply used to compute
@@ -1874,7 +1875,12 @@ count_ptr_derefs (tree *tp, int *walk_subtrees, void *data)
}
if (INDIRECT_REF_P (*tp) && TREE_OPERAND (*tp, 0) == count_p->ptr)
- count_p->count++;
+ {
+ if (wi_p->is_lhs)
+ count_p->num_stores++;
+ else
+ count_p->num_loads++;
+ }
return NULL_TREE;
}
@@ -1887,7 +1893,7 @@ count_ptr_derefs (tree *tp, int *walk_subtrees, void *data)
stored in *NUM_STORES_P and *NUM_LOADS_P. */
void
-count_uses_and_derefs (tree ptr, tree stmt, unsigned *num_uses_p,
+count_uses_and_derefs (tree ptr, gimple stmt, unsigned *num_uses_p,
unsigned *num_loads_p, unsigned *num_stores_p)
{
ssa_op_iter i;
@@ -1909,59 +1915,24 @@ count_uses_and_derefs (tree ptr, tree stmt, unsigned *num_uses_p,
find all the indirect and direct uses of x_1 inside. The only
shortcut we can take is the fact that GIMPLE only allows
INDIRECT_REFs inside the expressions below. */
- if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT
- || (TREE_CODE (stmt) == RETURN_EXPR
- && TREE_CODE (TREE_OPERAND (stmt, 0)) == GIMPLE_MODIFY_STMT)
- || TREE_CODE (stmt) == ASM_EXPR
- || TREE_CODE (stmt) == CALL_EXPR)
+ if (is_gimple_assign (stmt)
+ || gimple_code (stmt) == GIMPLE_RETURN
+ || gimple_code (stmt) == GIMPLE_ASM
+ || is_gimple_call (stmt))
{
- tree lhs, rhs;
+ struct walk_stmt_info wi;
+ struct count_ptr_d count;
- if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT)
- {
- lhs = GIMPLE_STMT_OPERAND (stmt, 0);
- rhs = GIMPLE_STMT_OPERAND (stmt, 1);
- }
- else if (TREE_CODE (stmt) == RETURN_EXPR)
- {
- tree e = TREE_OPERAND (stmt, 0);
- lhs = GIMPLE_STMT_OPERAND (e, 0);
- rhs = GIMPLE_STMT_OPERAND (e, 1);
- }
- else if (TREE_CODE (stmt) == ASM_EXPR)
- {
- lhs = ASM_OUTPUTS (stmt);
- rhs = ASM_INPUTS (stmt);
- }
- else
- {
- lhs = NULL_TREE;
- rhs = stmt;
- }
+ count.ptr = ptr;
+ count.num_stores = 0;
+ count.num_loads = 0;
- if (lhs
- && (TREE_CODE (lhs) == TREE_LIST
- || EXPR_P (lhs)
- || GIMPLE_STMT_P (lhs)))
- {
- struct count_ptr_d count;
- count.ptr = ptr;
- count.count = 0;
- walk_tree (&lhs, count_ptr_derefs, &count, NULL);
- *num_stores_p = count.count;
- }
+ memset (&wi, 0, sizeof (wi));
+ wi.info = &count;
+ walk_gimple_op (stmt, count_ptr_derefs, &wi);
- if (rhs
- && (TREE_CODE (rhs) == TREE_LIST
- || EXPR_P (rhs)
- || GIMPLE_STMT_P (rhs)))
- {
- struct count_ptr_d count;
- count.ptr = ptr;
- count.count = 0;
- walk_tree (&rhs, count_ptr_derefs, &count, NULL);
- *num_loads_p = count.count;
- }
+ *num_stores_p = count.num_stores;
+ *num_loads_p = count.num_loads;
}
gcc_assert (*num_uses_p >= *num_loads_p + *num_stores_p);
@@ -2316,7 +2287,6 @@ compute_flow_sensitive_aliasing (struct alias_info *ai)
tree ptr;
timevar_push (TV_FLOW_SENSITIVE);
- set_used_smts ();
for (i = 0; VEC_iterate (tree, ai->processed_ptrs, i, ptr); i++)
{
@@ -2371,6 +2341,8 @@ have_common_aliases_p (bitmap tag1aliases, bitmap tag2aliases)
static void
compute_flow_insensitive_aliasing (struct alias_info *ai)
{
+ referenced_var_iterator rvi;
+ tree var;
size_t i;
timevar_push (TV_FLOW_INSENSITIVE);
@@ -2461,6 +2433,24 @@ compute_flow_insensitive_aliasing (struct alias_info *ai)
add_may_alias (tag1, tag2);
}
}
+
+ /* We have to add all HEAP variables to all SMTs aliases bitmaps.
+ As we don't know which effective type the HEAP will have we cannot
+ do better here and we need the conflicts with obfuscated pointers
+ (a simple (*(int[n] *)ptr)[i] will do, with ptr from a VLA array
+ allocation). */
+ for (i = 0; i < ai->num_pointers; i++)
+ {
+ struct alias_map_d *p_map = ai->pointers[i];
+ tree tag = symbol_mem_tag (p_map->var);
+
+ FOR_EACH_REFERENCED_VAR (var, rvi)
+ {
+ if (var_ann (var)->is_heapvar)
+ add_may_alias (tag, var);
+ }
+ }
+
timevar_pop (TV_FLOW_INSENSITIVE);
}
@@ -2484,7 +2474,7 @@ create_alias_map_for (tree var, struct alias_info *ai)
ADDRESSABLE_VARS. */
static void
-update_alias_info_1 (tree stmt, struct alias_info *ai)
+update_alias_info_1 (gimple stmt, struct alias_info *ai)
{
bitmap addr_taken;
use_operand_p use_p;
@@ -2506,7 +2496,7 @@ update_alias_info_1 (tree stmt, struct alias_info *ai)
mem_ref_stats->num_asm_sites++;
/* Mark all the variables whose address are taken by the statement. */
- addr_taken = addresses_taken (stmt);
+ addr_taken = gimple_addresses_taken (stmt);
if (addr_taken)
bitmap_ior_into (gimple_addressable_vars (cfun), addr_taken);
@@ -2528,7 +2518,7 @@ update_alias_info_1 (tree stmt, struct alias_info *ai)
{
bitmap addressable_vars = gimple_addressable_vars (cfun);
- gcc_assert (TREE_CODE (stmt) == PHI_NODE);
+ gcc_assert (gimple_code (stmt) == GIMPLE_PHI);
gcc_assert (addressable_vars);
/* PHI nodes don't have annotations for pinning the set
@@ -2568,7 +2558,7 @@ update_alias_info_1 (tree stmt, struct alias_info *ai)
/* If STMT is a PHI node, then it will not have pointer
dereferences and it will not be an escape point. */
- if (TREE_CODE (stmt) == PHI_NODE)
+ if (gimple_code (stmt) == GIMPLE_PHI)
continue;
/* Determine whether OP is a dereferenced pointer, and if STMT
@@ -2602,13 +2592,13 @@ update_alias_info_1 (tree stmt, struct alias_info *ai)
are not GIMPLE invariants), they can only appear on the RHS
of an assignment and their base address is always an
INDIRECT_REF expression. */
- if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT
- && TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 1)) == ADDR_EXPR
- && !is_gimple_val (GIMPLE_STMT_OPERAND (stmt, 1)))
+ if (is_gimple_assign (stmt)
+ && gimple_assign_rhs_code (stmt) == ADDR_EXPR
+ && !is_gimple_val (gimple_assign_rhs1 (stmt)))
{
/* If the RHS if of the form &PTR->FLD and PTR == OP, then
this represents a potential dereference of PTR. */
- tree rhs = GIMPLE_STMT_OPERAND (stmt, 1);
+ tree rhs = gimple_assign_rhs1 (stmt);
tree base = get_base_address (TREE_OPERAND (rhs, 0));
if (TREE_CODE (base) == INDIRECT_REF
&& TREE_OPERAND (base, 0) == op)
@@ -2654,7 +2644,7 @@ update_alias_info_1 (tree stmt, struct alias_info *ai)
/* If the statement makes a function call, assume
that pointer OP will be dereferenced in a store
operation inside the called function. */
- if (get_call_expr_in (stmt)
+ if (is_gimple_call (stmt)
|| stmt_escape_type == ESCAPE_STORED_IN_GLOBAL)
{
pointer_set_insert (ai->dereferenced_ptrs_store, var);
@@ -2663,12 +2653,12 @@ update_alias_info_1 (tree stmt, struct alias_info *ai)
}
}
- if (TREE_CODE (stmt) == PHI_NODE)
+ if (gimple_code (stmt) == GIMPLE_PHI)
return;
/* Mark stored variables in STMT as being written to and update the
memory reference stats for all memory symbols referenced by STMT. */
- if (stmt_references_memory_p (stmt))
+ if (gimple_references_memory_p (stmt))
{
unsigned i;
bitmap_iterator bi;
@@ -2697,8 +2687,8 @@ update_alias_info_1 (tree stmt, struct alias_info *ai)
dereferences (e.g., MEMORY_VAR = *PTR) or if a call site has
memory symbols in its argument list, but these cases do not
occur so frequently as to constitute a serious problem. */
- if (STORED_SYMS (stmt))
- EXECUTE_IF_SET_IN_BITMAP (STORED_SYMS (stmt), 0, i, bi)
+ if (gimple_stored_syms (stmt))
+ EXECUTE_IF_SET_IN_BITMAP (gimple_stored_syms (stmt), 0, i, bi)
{
tree sym = referenced_var (i);
pointer_set_insert (ai->written_vars, sym);
@@ -2710,11 +2700,11 @@ update_alias_info_1 (tree stmt, struct alias_info *ai)
}
if (!stmt_dereferences_ptr_p
- && LOADED_SYMS (stmt)
+ && gimple_loaded_syms (stmt)
&& stmt_escape_type != ESCAPE_TO_CALL
&& stmt_escape_type != ESCAPE_TO_PURE_CONST
&& stmt_escape_type != ESCAPE_TO_ASM)
- EXECUTE_IF_SET_IN_BITMAP (LOADED_SYMS (stmt), 0, i, bi)
+ EXECUTE_IF_SET_IN_BITMAP (gimple_loaded_syms (stmt), 0, i, bi)
update_mem_sym_stats_from_stmt (referenced_var (i), stmt, 1, 0);
}
}
@@ -2730,15 +2720,18 @@ update_alias_info (struct alias_info *ai)
FOR_EACH_BB (bb)
{
- block_stmt_iterator bsi;
- tree phi;
+ gimple_stmt_iterator gsi;
+ gimple phi;
- for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
- if (is_gimple_reg (PHI_RESULT (phi)))
- update_alias_info_1 (phi, ai);
+ for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+ {
+ phi = gsi_stmt (gsi);
+ if (is_gimple_reg (PHI_RESULT (phi)))
+ update_alias_info_1 (phi, ai);
+ }
- for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
- update_alias_info_1 (bsi_stmt (bsi), ai);
+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+ update_alias_info_1 (gsi_stmt (gsi), ai);
}
}
@@ -3040,11 +3033,11 @@ may_alias_p (tree ptr, alias_set_type mem_alias_set,
/* The star count is -1 if the type at the end of the
pointer_to chain is not a record or union type. */
- if (!alias_set_only
- && ipa_type_escape_star_count_of_interesting_type (var_type) >= 0)
+ if (!alias_set_only &&
+ 0 /* FIXME tuples ipa_type_escape_star_count_of_interesting_type (var_type) >= 0*/)
{
int ptr_star_count = 0;
-
+
/* ipa_type_escape_star_count_of_interesting_type is a
little too restrictive for the pointer type, need to
allow pointers to primitive types as long as those
@@ -3166,21 +3159,20 @@ set_pt_anything (tree ptr)
if none. */
enum escape_type
-is_escape_site (tree stmt)
+is_escape_site (gimple stmt)
{
- tree call = get_call_expr_in (stmt);
- if (call != NULL_TREE)
+ if (is_gimple_call (stmt))
{
- if (!TREE_SIDE_EFFECTS (call))
+ if (gimple_call_flags (stmt) & (ECF_PURE | ECF_CONST))
return ESCAPE_TO_PURE_CONST;
return ESCAPE_TO_CALL;
}
- else if (TREE_CODE (stmt) == ASM_EXPR)
+ else if (gimple_code (stmt) == GIMPLE_ASM)
return ESCAPE_TO_ASM;
- else if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT)
+ else if (is_gimple_assign (stmt))
{
- tree lhs = GIMPLE_STMT_OPERAND (stmt, 0);
+ tree lhs = gimple_assign_lhs (stmt);
/* Get to the base of _REF nodes. */
if (TREE_CODE (lhs) != SSA_NAME)
@@ -3191,12 +3183,10 @@ is_escape_site (tree stmt)
if (lhs == NULL_TREE)
return ESCAPE_UNKNOWN;
- if (CONVERT_EXPR_P (GIMPLE_STMT_OPERAND (stmt, 1))
- || TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 1)) == VIEW_CONVERT_EXPR)
+ if (gimple_assign_cast_p (stmt))
{
- tree from
- = TREE_TYPE (TREE_OPERAND (GIMPLE_STMT_OPERAND (stmt, 1), 0));
- tree to = TREE_TYPE (GIMPLE_STMT_OPERAND (stmt, 1));
+ tree from = TREE_TYPE (gimple_assign_rhs1 (stmt));
+ tree to = TREE_TYPE (lhs);
/* If the RHS is a conversion between a pointer and an integer, the
pointer escapes since we can't track the integer. */
@@ -3226,7 +3216,7 @@ is_escape_site (tree stmt)
Applications (OOPSLA), pp. 1-19, 1999. */
return ESCAPE_STORED_IN_GLOBAL;
}
- else if (TREE_CODE (stmt) == RETURN_EXPR)
+ else if (gimple_code (stmt) == RETURN_EXPR)
return ESCAPE_TO_RETURN;
return NO_ESCAPE;
@@ -3520,7 +3510,6 @@ get_ptr_info (tree t)
return pi;
}
-
/* Dump points-to information for SSA_NAME PTR into FILE. */
void
@@ -3576,10 +3565,10 @@ debug_points_to_info_for (tree var)
it needs to traverse the whole CFG looking for pointer SSA_NAMEs. */
void
-dump_points_to_info (FILE *file)
+dump_points_to_info (FILE *file ATTRIBUTE_UNUSED)
{
basic_block bb;
- block_stmt_iterator si;
+ gimple_stmt_iterator si;
ssa_op_iter iter;
const char *fname =
lang_hooks.decl_printable_name (current_function_decl, 2);
@@ -3604,18 +3593,17 @@ dump_points_to_info (FILE *file)
/* Dump points-to information for every pointer defined in the program. */
FOR_EACH_BB (bb)
{
- tree phi;
-
- for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
+ for (si = gsi_start_phis (bb); !gsi_end_p (si); gsi_next (&si))
{
+ gimple phi = gsi_stmt (si);
tree ptr = PHI_RESULT (phi);
if (POINTER_TYPE_P (TREE_TYPE (ptr)))
dump_points_to_info_for (file, ptr);
}
- for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
+ for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
{
- tree stmt = bsi_stmt (si);
+ gimple stmt = gsi_stmt (si);
tree def;
FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_DEF)
if (TREE_CODE (def) == SSA_NAME
@@ -3670,7 +3658,6 @@ debug_may_aliases_for (tree var)
dump_may_aliases_for (stderr, var);
}
-
/* Return true if VAR may be aliased. */
bool
@@ -3695,17 +3682,7 @@ may_be_aliased (tree var)
if (!TREE_STATIC (var))
return false;
- /* If we're in unit-at-a-time mode, then we must have seen all
- occurrences of address-of operators, and so we can trust
- TREE_ADDRESSABLE. Otherwise we can only be sure the variable
- isn't addressable if it's local to the current function. */
- if (flag_unit_at_a_time)
- return false;
-
- if (decl_function_context (var) == current_function_decl)
- return false;
-
- return true;
+ return false;
}
/* The following is based on code in add_stmt_operand to ensure that the
diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c
index d4dfadbced0..44b5523263d 100644
--- a/gcc/tree-ssa-ccp.c
+++ b/gcc/tree-ssa-ccp.c
@@ -268,6 +268,7 @@ debug_lattice_value (prop_value_t val)
}
+
/* If SYM is a constant variable with known value, return the value.
NULL_TREE is returned otherwise. */
@@ -310,13 +311,10 @@ get_symbol_constant_value (tree sym)
change the constant value of the PHI node, which allows for more
constants to be propagated.
- 3- If SSA_NAME_VALUE is set and it is a constant, its value is
- used.
-
- 4- Variables defined by statements other than assignments and PHI
+ 3- Variables defined by statements other than assignments and PHI
nodes are considered VARYING.
- 5- Initial values of variables that are not GIMPLE registers are
+ 4- Initial values of variables that are not GIMPLE registers are
considered VARYING. */
static prop_value_t
@@ -332,12 +330,6 @@ get_default_value (tree var)
non-register when DO_STORE_CCP is false. */
val.lattice_val = VARYING;
}
- else if (SSA_NAME_VALUE (var)
- && is_gimple_min_invariant (SSA_NAME_VALUE (var)))
- {
- val.lattice_val = CONSTANT;
- val.value = SSA_NAME_VALUE (var);
- }
else if ((cst_val = get_symbol_constant_value (sym)) != NULL_TREE)
{
/* Globals and static variables declared 'const' take their
@@ -348,9 +340,9 @@ get_default_value (tree var)
}
else
{
- tree stmt = SSA_NAME_DEF_STMT (var);
+ gimple stmt = SSA_NAME_DEF_STMT (var);
- if (IS_EMPTY_STMT (stmt))
+ if (gimple_nop_p (stmt))
{
/* Variables defined by an empty statement are those used
before being initialized. If VAR is a local variable, we
@@ -361,9 +353,13 @@ get_default_value (tree var)
else
val.lattice_val = VARYING;
}
- else if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT
- || TREE_CODE (stmt) == PHI_NODE)
- {
+ else if (is_gimple_assign (stmt)
+ /* Value-returning GIMPLE_CALL statements assign to
+ a variable, and are treated similarly to GIMPLE_ASSIGN. */
+ || (is_gimple_call (stmt)
+ && gimple_call_lhs (stmt) != NULL_TREE)
+ || gimple_code (stmt) == GIMPLE_PHI)
+ {
/* Any other variable defined by an assignment or a PHI node
is considered UNDEFINED. */
val.lattice_val = UNDEFINED;
@@ -506,18 +502,24 @@ set_lattice_value (tree var, prop_value_t new_val)
Else return VARYING. */
static ccp_lattice_t
-likely_value (tree stmt)
+likely_value (gimple stmt)
{
bool has_constant_operand, has_undefined_operand, all_undefined_operands;
- stmt_ann_t ann;
tree use;
ssa_op_iter iter;
- ann = stmt_ann (stmt);
+ enum tree_code code = gimple_code (stmt);
+
+ /* This function appears to be called only for assignments, calls,
+ conditionals, and switches, due to the logic in visit_stmt. */
+ gcc_assert (code == GIMPLE_ASSIGN
+ || code == GIMPLE_CALL
+ || code == GIMPLE_COND
+ || code == GIMPLE_SWITCH);
/* If the statement has volatile operands, it won't fold to a
constant value. */
- if (ann->has_volatile_ops)
+ if (gimple_has_volatile_ops (stmt))
return VARYING;
/* If we are not doing store-ccp, statements with loads
@@ -526,23 +528,31 @@ likely_value (tree stmt)
&& !ZERO_SSA_OPERANDS (stmt, SSA_OP_ALL_VIRTUALS))
return VARYING;
-
- /* A CALL_EXPR is assumed to be varying. NOTE: This may be overly
+ /* A GIMPLE_CALL is assumed to be varying. NOTE: This may be overly
conservative, in the presence of const and pure calls. */
- if (get_call_expr_in (stmt) != NULL_TREE)
+ if (code == GIMPLE_CALL)
return VARYING;
- /* Anything other than assignments and conditional jumps are not
- interesting for CCP. */
- if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT
- && !(TREE_CODE (stmt) == RETURN_EXPR && get_rhs (stmt) != NULL_TREE)
- && TREE_CODE (stmt) != COND_EXPR
- && TREE_CODE (stmt) != SWITCH_EXPR)
- return VARYING;
+ /* Note that only a GIMPLE_SINGLE_RHS assignment can satisfy
+ is_gimple_min_invariant, so we do not consider calls or
+ other forms of assignment. */
+ if (code == GIMPLE_ASSIGN
+ && (get_gimple_rhs_class (gimple_assign_rhs_code (stmt))
+ == GIMPLE_SINGLE_RHS)
+ && is_gimple_min_invariant (gimple_assign_rhs1 (stmt)))
+ return CONSTANT;
- if (is_gimple_min_invariant (get_rhs (stmt)))
+ if (code == GIMPLE_COND
+ && is_gimple_min_invariant (gimple_cond_lhs (stmt))
+ && is_gimple_min_invariant (gimple_cond_rhs (stmt)))
return CONSTANT;
+ if (code == GIMPLE_SWITCH
+ && is_gimple_min_invariant (gimple_switch_index (stmt)))
+ return CONSTANT;
+
+ /* Arrive here for more complex cases. */
+
has_constant_operand = false;
has_undefined_operand = false;
all_undefined_operands = true;
@@ -562,13 +572,11 @@ likely_value (tree stmt)
/* If the operation combines operands like COMPLEX_EXPR make sure to
not mark the result UNDEFINED if only one part of the result is
undefined. */
- if (has_undefined_operand
- && all_undefined_operands)
+ if (has_undefined_operand && all_undefined_operands)
return UNDEFINED;
- else if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT
- && has_undefined_operand)
+ else if (code == GIMPLE_ASSIGN && has_undefined_operand)
{
- switch (TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 1)))
+ switch (gimple_assign_rhs_code (stmt))
{
/* Unary operators are handled with all_undefined_operands. */
case PLUS_EXPR:
@@ -604,11 +612,11 @@ likely_value (tree stmt)
/* Returns true if STMT cannot be constant. */
static bool
-surely_varying_stmt_p (tree stmt)
+surely_varying_stmt_p (gimple stmt)
{
/* If the statement has operands that we cannot handle, it cannot be
constant. */
- if (stmt_ann (stmt)->has_volatile_ops)
+ if (gimple_has_volatile_ops (stmt))
return true;
if (!ZERO_SSA_OPERANDS (stmt, SSA_OP_ALL_VIRTUALS))
@@ -623,15 +631,14 @@ surely_varying_stmt_p (tree stmt)
}
/* If it contains a call, it is varying. */
- if (get_call_expr_in (stmt) != NULL_TREE)
+ if (is_gimple_call (stmt))
return true;
/* Anything other than assignments and conditional jumps are not
interesting for CCP. */
- if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT
- && !(TREE_CODE (stmt) == RETURN_EXPR && get_rhs (stmt) != NULL_TREE)
- && TREE_CODE (stmt) != COND_EXPR
- && TREE_CODE (stmt) != SWITCH_EXPR)
+ if (gimple_code (stmt) != GIMPLE_ASSIGN
+ && (gimple_code (stmt) != GIMPLE_COND)
+ && (gimple_code (stmt) != GIMPLE_SWITCH))
return true;
return false;
@@ -649,11 +656,11 @@ ccp_initialize (void)
/* Initialize simulation flags for PHI nodes and statements. */
FOR_EACH_BB (bb)
{
- block_stmt_iterator i;
+ gimple_stmt_iterator i;
- for (i = bsi_start (bb); !bsi_end_p (i); bsi_next (&i))
+ for (i = gsi_start_bb (bb); !gsi_end_p (i); gsi_next (&i))
{
- tree stmt = bsi_stmt (i);
+ gimple stmt = gsi_stmt (i);
bool is_varying = surely_varying_stmt_p (stmt);
if (is_varying)
@@ -669,24 +676,25 @@ ccp_initialize (void)
set_value_varying (def);
}
}
-
- DONT_SIMULATE_AGAIN (stmt) = is_varying;
+ prop_set_simulate_again (stmt, !is_varying);
}
}
- /* Now process PHI nodes. We never set DONT_SIMULATE_AGAIN on phi node,
- since we do not know which edges are executable yet, except for
- phi nodes for virtual operands when we do not do store ccp. */
+ /* Now process PHI nodes. We never clear the simulate_again flag on
+ phi nodes, since we do not know which edges are executable yet,
+ except for phi nodes for virtual operands when we do not do store ccp. */
FOR_EACH_BB (bb)
{
- tree phi;
+ gimple_stmt_iterator i;
- for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
- {
- if (!do_store_ccp && !is_gimple_reg (PHI_RESULT (phi)))
- DONT_SIMULATE_AGAIN (phi) = true;
+ for (i = gsi_start_phis (bb); !gsi_end_p (i); gsi_next (&i))
+ {
+ gimple phi = gsi_stmt (i);
+
+ if (!do_store_ccp && !is_gimple_reg (gimple_phi_result (phi)))
+ prop_set_simulate_again (phi, false);
else
- DONT_SIMULATE_AGAIN (phi) = false;
+ prop_set_simulate_again (phi, true);
}
}
}
@@ -772,18 +780,18 @@ ccp_lattice_meet (prop_value_t *val1, prop_value_t *val2)
of the PHI node that are incoming via executable edges. */
static enum ssa_prop_result
-ccp_visit_phi_node (tree phi)
+ccp_visit_phi_node (gimple phi)
{
- int i;
+ unsigned i;
prop_value_t *old_val, new_val;
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "\nVisiting PHI node: ");
- print_generic_expr (dump_file, phi, dump_flags);
+ print_gimple_stmt (dump_file, phi, 0, dump_flags);
}
- old_val = get_value (PHI_RESULT (phi));
+ old_val = get_value (gimple_phi_result (phi));
switch (old_val->lattice_val)
{
case VARYING:
@@ -803,11 +811,11 @@ ccp_visit_phi_node (tree phi)
gcc_unreachable ();
}
- for (i = 0; i < PHI_NUM_ARGS (phi); i++)
+ for (i = 0; i < gimple_phi_num_args (phi); i++)
{
/* Compute the meet operator over all the PHI arguments flowing
through executable edges. */
- edge e = PHI_ARG_EDGE (phi, i);
+ edge e = gimple_phi_arg_edge (phi, i);
if (dump_file && (dump_flags & TDF_DETAILS))
{
@@ -821,7 +829,7 @@ ccp_visit_phi_node (tree phi)
the existing value of the PHI node and the current PHI argument. */
if (e->flags & EDGE_EXECUTABLE)
{
- tree arg = PHI_ARG_DEF (phi, i);
+ tree arg = gimple_phi_arg (phi, i)->def;
prop_value_t arg_val;
if (is_gimple_min_invariant (arg))
@@ -855,7 +863,7 @@ ccp_visit_phi_node (tree phi)
}
/* Make the transition to the new value. */
- if (set_lattice_value (PHI_RESULT (phi), new_val))
+ if (set_lattice_value (gimple_phi_result (phi), new_val))
{
if (new_val.lattice_val == VARYING)
return SSA_PROP_VARYING;
@@ -874,179 +882,200 @@ ccp_visit_phi_node (tree phi)
operands are constants.
If simplification is possible, return the simplified RHS,
- otherwise return the original RHS. */
+ otherwise return the original RHS or NULL_TREE. */
static tree
-ccp_fold (tree stmt)
+ccp_fold (gimple stmt)
{
- tree rhs = get_rhs (stmt);
- enum tree_code code = TREE_CODE (rhs);
- enum tree_code_class kind = TREE_CODE_CLASS (code);
- tree retval = NULL_TREE;
-
- if (TREE_CODE (rhs) == SSA_NAME)
- {
- /* If the RHS is an SSA_NAME, return its known constant value,
- if any. */
- return get_value (rhs)->value;
- }
- else if (do_store_ccp && stmt_makes_single_load (stmt))
- {
- /* If the RHS is a memory load, see if the VUSEs associated with
- it are a valid constant for that memory load. */
- prop_value_t *val = get_value_loaded_by (stmt, const_val);
- if (val && val->mem_ref)
- {
- if (operand_equal_p (val->mem_ref, rhs, 0))
- return val->value;
-
- /* If RHS is extracting REALPART_EXPR or IMAGPART_EXPR of a
- complex type with a known constant value, return it. */
- if ((TREE_CODE (rhs) == REALPART_EXPR
- || TREE_CODE (rhs) == IMAGPART_EXPR)
- && operand_equal_p (val->mem_ref, TREE_OPERAND (rhs, 0), 0))
- return fold_build1 (TREE_CODE (rhs), TREE_TYPE (rhs), val->value);
- }
- return NULL_TREE;
- }
-
- /* Unary operators. Note that we know the single operand must
- be a constant. So this should almost always return a
- simplified RHS. */
- if (kind == tcc_unary)
+ switch (gimple_code (stmt))
{
- /* Handle unary operators which can appear in GIMPLE form. */
- tree op0 = TREE_OPERAND (rhs, 0);
-
- /* Simplify the operand down to a constant. */
- if (TREE_CODE (op0) == SSA_NAME)
- {
- prop_value_t *val = get_value (op0);
- if (val->lattice_val == CONSTANT)
- op0 = get_value (op0)->value;
- }
+ case GIMPLE_ASSIGN:
+ {
+ enum tree_code subcode = gimple_assign_rhs_code (stmt);
+
+ switch (get_gimple_rhs_class (subcode))
+ {
+ case GIMPLE_SINGLE_RHS:
+ {
+ tree rhs = gimple_assign_rhs1 (stmt);
+ enum tree_code_class kind = TREE_CODE_CLASS (subcode);
+
+ if (TREE_CODE (rhs) == SSA_NAME)
+ {
+ /* If the RHS is an SSA_NAME, return its known constant value,
+ if any. */
+ return get_value (rhs)->value;
+ }
+ /* Handle propagating invariant addresses into address operations.
+ The folding we do here matches that in tree-ssa-forwprop.c. */
+ else if (TREE_CODE (rhs) == ADDR_EXPR)
+ {
+ tree *base;
+ base = &TREE_OPERAND (rhs, 0);
+ while (handled_component_p (*base))
+ base = &TREE_OPERAND (*base, 0);
+ if (TREE_CODE (*base) == INDIRECT_REF
+ && TREE_CODE (TREE_OPERAND (*base, 0)) == SSA_NAME)
+ {
+ prop_value_t *val = get_value (TREE_OPERAND (*base, 0));
+ if (val->lattice_val == CONSTANT
+ && TREE_CODE (val->value) == ADDR_EXPR
+ && useless_type_conversion_p
+ (TREE_TYPE (TREE_OPERAND (*base, 0)),
+ TREE_TYPE (val->value))
+ && useless_type_conversion_p
+ (TREE_TYPE (*base),
+ TREE_TYPE (TREE_OPERAND (val->value, 0))))
+ {
+ /* We need to return a new tree, not modify the IL
+ or share parts of it. So play some tricks to
+ avoid manually building it. */
+ tree ret, save = *base;
+ *base = TREE_OPERAND (val->value, 0);
+ ret = unshare_expr (rhs);
+ recompute_tree_invariant_for_addr_expr (ret);
+ *base = save;
+ return ret;
+ }
+ }
+ }
- /* Conversions are useless for CCP purposes if they are
- value-preserving. Thus the restrictions that
- useless_type_conversion_p places for pointer type conversions do
- not apply here. Substitution later will only substitute to
- allowed places. */
- if ((code == NOP_EXPR || code == CONVERT_EXPR)
- && ((POINTER_TYPE_P (TREE_TYPE (rhs))
- && POINTER_TYPE_P (TREE_TYPE (op0)))
- || useless_type_conversion_p (TREE_TYPE (rhs), TREE_TYPE (op0))))
- return op0;
- return fold_unary (code, TREE_TYPE (rhs), op0);
- }
-
- /* Binary and comparison operators. We know one or both of the
- operands are constants. */
- else if (kind == tcc_binary
- || kind == tcc_comparison
- || code == TRUTH_AND_EXPR
- || code == TRUTH_OR_EXPR
- || code == TRUTH_XOR_EXPR)
- {
- /* Handle binary and comparison operators that can appear in
- GIMPLE form. */
- tree op0 = TREE_OPERAND (rhs, 0);
- tree op1 = TREE_OPERAND (rhs, 1);
-
- /* Simplify the operands down to constants when appropriate. */
- if (TREE_CODE (op0) == SSA_NAME)
- {
- prop_value_t *val = get_value (op0);
- if (val->lattice_val == CONSTANT)
- op0 = val->value;
- }
+ else if (do_store_ccp && stmt_makes_single_load (stmt))
+ {
+ /* If the RHS is a memory load, see if the VUSEs associated with
+ it are a valid constant for that memory load. */
+ prop_value_t *val = get_value_loaded_by (stmt, const_val);
+ if (val && val->mem_ref)
+ {
+ if (operand_equal_p (val->mem_ref, rhs, 0))
+ return val->value;
+
+ /* If RHS is extracting REALPART_EXPR or IMAGPART_EXPR of a
+ complex type with a known constant value, return it. */
+ if ((TREE_CODE (rhs) == REALPART_EXPR
+ || TREE_CODE (rhs) == IMAGPART_EXPR)
+ && operand_equal_p (val->mem_ref, TREE_OPERAND (rhs, 0), 0))
+ return fold_build1 (TREE_CODE (rhs), TREE_TYPE (rhs), val->value);
+ }
+ }
+
+ if (kind == tcc_reference)
+ return fold_const_aggregate_ref (rhs);
+ else if (kind == tcc_declaration)
+ return get_symbol_constant_value (rhs);
+ return rhs;
+ }
+
+ case GIMPLE_UNARY_RHS:
+ {
+ /* Handle unary operators that can appear in GIMPLE form.
+ Note that we know the single operand must be a constant,
+ so this should almost always return a simplified RHS. */
+ tree lhs = gimple_assign_lhs (stmt);
+ tree op0 = gimple_assign_rhs1 (stmt);
+
+ /* Simplify the operand down to a constant. */
+ if (TREE_CODE (op0) == SSA_NAME)
+ {
+ prop_value_t *val = get_value (op0);
+ if (val->lattice_val == CONSTANT)
+ op0 = get_value (op0)->value;
+ }
+
+ /* Conversions are useless for CCP purposes if they are
+ value-preserving. Thus the restrictions that
+ useless_type_conversion_p places for pointer type conversions
+ do not apply here. Substitution later will only substitute to
+ allowed places. */
+ if ((subcode == NOP_EXPR || subcode == CONVERT_EXPR)
+ && ((POINTER_TYPE_P (TREE_TYPE (lhs))
+ && POINTER_TYPE_P (TREE_TYPE (op0)))
+ || useless_type_conversion_p (TREE_TYPE (lhs),
+ TREE_TYPE (op0))))
+ return op0;
+
+ return fold_unary (subcode, gimple_expr_type (stmt), op0);
+ }
+
+ case GIMPLE_BINARY_RHS:
+ {
+ /* Handle binary operators that can appear in GIMPLE form. */
+ tree op0 = gimple_assign_rhs1 (stmt);
+ tree op1 = gimple_assign_rhs2 (stmt);
+
+ /* Simplify the operands down to constants when appropriate. */
+ if (TREE_CODE (op0) == SSA_NAME)
+ {
+ prop_value_t *val = get_value (op0);
+ if (val->lattice_val == CONSTANT)
+ op0 = val->value;
+ }
+
+ if (TREE_CODE (op1) == SSA_NAME)
+ {
+ prop_value_t *val = get_value (op1);
+ if (val->lattice_val == CONSTANT)
+ op1 = val->value;
+ }
+
+ return fold_binary (subcode, gimple_expr_type (stmt), op0, op1);
+ }
+
+ default:
+ gcc_unreachable ();
+ }
+ }
+ break;
- if (TREE_CODE (op1) == SSA_NAME)
- {
- prop_value_t *val = get_value (op1);
- if (val->lattice_val == CONSTANT)
- op1 = val->value;
- }
+ case GIMPLE_CALL:
+ /* It may be possible to fold away calls to builtin functions if
+ their arguments are constants. At present, such folding will not
+ be attempted, as likely_value classifies all calls as VARYING. */
+ gcc_unreachable ();
+ break;
- return fold_binary (code, TREE_TYPE (rhs), op0, op1);
- }
+ case GIMPLE_COND:
+ {
+ /* Handle comparison operators that can appear in GIMPLE form. */
+ tree op0 = gimple_cond_lhs (stmt);
+ tree op1 = gimple_cond_rhs (stmt);
+ enum tree_code code = gimple_cond_code (stmt);
+
+ /* Simplify the operands down to constants when appropriate. */
+ if (TREE_CODE (op0) == SSA_NAME)
+ {
+ prop_value_t *val = get_value (op0);
+ if (val->lattice_val == CONSTANT)
+ op0 = val->value;
+ }
+
+ if (TREE_CODE (op1) == SSA_NAME)
+ {
+ prop_value_t *val = get_value (op1);
+ if (val->lattice_val == CONSTANT)
+ op1 = val->value;
+ }
+
+ return fold_binary (code, boolean_type_node, op0, op1);
+ }
- else if (kind == tcc_declaration)
- return get_symbol_constant_value (rhs);
+ case GIMPLE_SWITCH:
+ {
+ tree rhs = gimple_switch_index (stmt);
- else if (kind == tcc_reference)
- return fold_const_aggregate_ref (rhs);
+ if (TREE_CODE (rhs) == SSA_NAME)
+ {
+ /* If the RHS is an SSA_NAME, return its known constant value,
+ if any. */
+ return get_value (rhs)->value;
+ }
- /* Handle propagating invariant addresses into address operations.
- The folding we do here matches that in tree-ssa-forwprop.c. */
- else if (code == ADDR_EXPR)
- {
- tree *base;
- base = &TREE_OPERAND (rhs, 0);
- while (handled_component_p (*base))
- base = &TREE_OPERAND (*base, 0);
- if (TREE_CODE (*base) == INDIRECT_REF
- && TREE_CODE (TREE_OPERAND (*base, 0)) == SSA_NAME)
- {
- prop_value_t *val = get_value (TREE_OPERAND (*base, 0));
- if (val->lattice_val == CONSTANT
- && TREE_CODE (val->value) == ADDR_EXPR
- && useless_type_conversion_p (TREE_TYPE (TREE_OPERAND (*base, 0)),
- TREE_TYPE (val->value))
- && useless_type_conversion_p (TREE_TYPE (*base),
- TREE_TYPE (TREE_OPERAND (val->value, 0))))
- {
- /* We need to return a new tree, not modify the IL or share
- parts of it. So play some tricks to avoid manually
- building it. */
- tree ret, save = *base;
- *base = TREE_OPERAND (val->value, 0);
- ret = unshare_expr (rhs);
- recompute_tree_invariant_for_addr_expr (ret);
- *base = save;
- return ret;
- }
- }
- }
+ return rhs;
+ }
- /* We may be able to fold away calls to builtin functions if their
- arguments are constants. */
- else if (code == CALL_EXPR
- && TREE_CODE (CALL_EXPR_FN (rhs)) == ADDR_EXPR
- && TREE_CODE (TREE_OPERAND (CALL_EXPR_FN (rhs), 0)) == FUNCTION_DECL
- && DECL_BUILT_IN (TREE_OPERAND (CALL_EXPR_FN (rhs), 0)))
- {
- if (!ZERO_SSA_OPERANDS (stmt, SSA_OP_USE))
- {
- tree *orig, var;
- size_t i = 0;
- ssa_op_iter iter;
- use_operand_p var_p;
-
- /* Preserve the original values of every operand. */
- orig = XNEWVEC (tree, NUM_SSA_OPERANDS (stmt, SSA_OP_USE));
- FOR_EACH_SSA_TREE_OPERAND (var, stmt, iter, SSA_OP_USE)
- orig[i++] = var;
-
- /* Substitute operands with their values and try to fold. */
- replace_uses_in (stmt, NULL, const_val);
- retval = fold_call_expr (rhs, false);
-
- /* Restore operands to their original form. */
- i = 0;
- FOR_EACH_SSA_USE_OPERAND (var_p, stmt, iter, SSA_OP_USE)
- SET_USE (var_p, orig[i++]);
- free (orig);
- }
+ default:
+ gcc_unreachable ();
}
- else
- return rhs;
-
- /* If we got a simplified form, see if we need to convert its type. */
- if (retval)
- return fold_convert (TREE_TYPE (rhs), retval);
-
- /* No simplification was possible. */
- return rhs;
}
@@ -1215,11 +1244,12 @@ fold_const_aggregate_ref (tree t)
return NULL_TREE;
}
-
-/* Evaluate statement STMT. */
+
+/* Evaluate statement STMT.
+ Valid only for assignments, calls, conditionals, and switches. */
static prop_value_t
-evaluate_stmt (tree stmt)
+evaluate_stmt (gimple stmt)
{
prop_value_t val;
tree simplified = NULL_TREE;
@@ -1232,12 +1262,31 @@ evaluate_stmt (tree stmt)
/* If the statement is likely to have a CONSTANT result, then try
to fold the statement to determine the constant value. */
+ /* FIXME. This is the only place that we call ccp_fold.
+ Since likely_value never returns CONSTANT for calls, we will
+ not attempt to fold them, including builtins that may profit. */
if (likelyvalue == CONSTANT)
simplified = ccp_fold (stmt);
/* If the statement is likely to have a VARYING result, then do not
bother folding the statement. */
else if (likelyvalue == VARYING)
- simplified = get_rhs (stmt);
+ {
+ enum tree_code code = gimple_code (stmt);
+ if (code == GIMPLE_ASSIGN)
+ {
+ enum tree_code subcode = gimple_assign_rhs_code (stmt);
+
+ /* Other cases cannot satisfy is_gimple_min_invariant
+ without folding. */
+ if (get_gimple_rhs_class (subcode) == GIMPLE_SINGLE_RHS)
+ simplified = gimple_assign_rhs1 (stmt);
+ }
+ else if (code == GIMPLE_SWITCH)
+ simplified = gimple_switch_index (stmt);
+ else
+ /* These cannot satisfy is_gimple_min_invariant without folding. */
+ gcc_assert (code == GIMPLE_CALL || code == GIMPLE_COND);
+ }
is_constant = simplified && is_gimple_min_invariant (simplified);
@@ -1284,45 +1333,55 @@ evaluate_stmt (tree stmt)
return val;
}
-
/* Visit the assignment statement STMT. Set the value of its LHS to the
value computed by the RHS and store LHS in *OUTPUT_P. If STMT
creates virtual definitions, set the value of each new name to that
- of the RHS (if we can derive a constant out of the RHS). */
+ of the RHS (if we can derive a constant out of the RHS).
+ Value-returning call statements also perform an assignment, and
+ are handled here. */
static enum ssa_prop_result
-visit_assignment (tree stmt, tree *output_p)
+visit_assignment (gimple stmt, tree *output_p)
{
prop_value_t val;
- tree lhs, rhs;
enum ssa_prop_result retval;
- lhs = GIMPLE_STMT_OPERAND (stmt, 0);
- rhs = GIMPLE_STMT_OPERAND (stmt, 1);
+ tree lhs = gimple_get_lhs (stmt);
- if (TREE_CODE (rhs) == SSA_NAME)
- {
- /* For a simple copy operation, we copy the lattice values. */
- prop_value_t *nval = get_value (rhs);
- val = *nval;
- }
- else if (do_store_ccp && stmt_makes_single_load (stmt))
+ gcc_assert (gimple_code (stmt) != GIMPLE_CALL
+ || gimple_call_lhs (stmt) != NULL_TREE);
+
+ if (gimple_assign_copy_p (stmt))
{
- /* Same as above, but the RHS is not a gimple register and yet
- has a known VUSE. If STMT is loading from the same memory
- location that created the SSA_NAMEs for the virtual operands,
- we can propagate the value on the RHS. */
- prop_value_t *nval = get_value_loaded_by (stmt, const_val);
+ tree rhs = gimple_assign_rhs1 (stmt);
- if (nval
- && nval->mem_ref
- && operand_equal_p (nval->mem_ref, rhs, 0))
- val = *nval;
+ if (TREE_CODE (rhs) == SSA_NAME)
+ {
+ /* For a simple copy operation, we copy the lattice values. */
+ prop_value_t *nval = get_value (rhs);
+ val = *nval;
+ }
+ else if (do_store_ccp && stmt_makes_single_load (stmt))
+ {
+ /* Same as above, but the RHS is not a gimple register and yet
+ has a known VUSE. If STMT is loading from the same memory
+ location that created the SSA_NAMEs for the virtual operands,
+ we can propagate the value on the RHS. */
+ prop_value_t *nval = get_value_loaded_by (stmt, const_val);
+
+ if (nval
+ && nval->mem_ref
+ && operand_equal_p (nval->mem_ref, rhs, 0))
+ val = *nval;
+ else
+ val = evaluate_stmt (stmt);
+ }
else
- val = evaluate_stmt (stmt);
+ val = evaluate_stmt (stmt);
}
else
- /* Evaluate the statement. */
+ /* Evaluate the statement, which could be
+ either a GIMPLE_ASSIGN or a GIMPLE_CALL. */
val = evaluate_stmt (stmt);
retval = SSA_PROP_NOT_INTERESTING;
@@ -1391,12 +1450,12 @@ visit_assignment (tree stmt, tree *output_p)
SSA_PROP_VARYING. */
static enum ssa_prop_result
-visit_cond_stmt (tree stmt, edge *taken_edge_p)
+visit_cond_stmt (gimple stmt, edge *taken_edge_p)
{
prop_value_t val;
basic_block block;
- block = bb_for_stmt (stmt);
+ block = gimple_bb (stmt);
val = evaluate_stmt (stmt);
/* Find which edge out of the conditional block will be taken and add it
@@ -1421,7 +1480,7 @@ visit_cond_stmt (tree stmt, edge *taken_edge_p)
value, return SSA_PROP_VARYING. */
static enum ssa_prop_result
-ccp_visit_stmt (tree stmt, edge *taken_edge_p, tree *output_p)
+ccp_visit_stmt (gimple stmt, edge *taken_edge_p, tree *output_p)
{
tree def;
ssa_op_iter iter;
@@ -1429,21 +1488,33 @@ ccp_visit_stmt (tree stmt, edge *taken_edge_p, tree *output_p)
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "\nVisiting statement:\n");
- print_generic_stmt (dump_file, stmt, dump_flags);
+ print_gimple_stmt (dump_file, stmt, 0, dump_flags);
}
- if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT)
- {
- /* If the statement is an assignment that produces a single
- output value, evaluate its RHS to see if the lattice value of
- its output has changed. */
- return visit_assignment (stmt, output_p);
- }
- else if (TREE_CODE (stmt) == COND_EXPR || TREE_CODE (stmt) == SWITCH_EXPR)
+ switch (gimple_code (stmt))
{
- /* If STMT is a conditional branch, see if we can determine
- which branch will be taken. */
- return visit_cond_stmt (stmt, taken_edge_p);
+ case GIMPLE_ASSIGN:
+ /* If the statement is an assignment that produces a single
+ output value, evaluate its RHS to see if the lattice value of
+ its output has changed. */
+ return visit_assignment (stmt, output_p);
+
+ case GIMPLE_CALL:
+ /* A value-returning call also performs an assignment. */
+ if (gimple_call_lhs (stmt) != NULL_TREE)
+ return visit_assignment (stmt, output_p);
+ break;
+
+ case GIMPLE_COND:
+ case GIMPLE_SWITCH:
+ /* If STMT is a conditional branch, see if we can determine
+ which branch will be taken. */
+ /* FIXME. It appears that we should be able to optimize
+ computed GOTOs here as well. */
+ return visit_cond_stmt (stmt, taken_edge_p);
+
+ default:
+ break;
}
/* Any other kind of statement is not interesting for constant
@@ -1974,30 +2045,24 @@ maybe_fold_stmt_indirect (tree expr, tree base, tree offset)
}
-/* A subroutine of fold_stmt_r. EXPR is a POINTER_PLUS_EXPR.
-
- A quaint feature extant in our address arithmetic is that there
+/* A quaint feature extant in our address arithmetic is that there
can be hidden type changes here. The type of the result need
not be the same as the type of the input pointer.
What we're after here is an expression of the form
(T *)(&array + const)
- where the cast doesn't actually exist, but is implicit in the
+ where array is OP0, const is OP1, RES_TYPE is T and
+ the cast doesn't actually exist, but is implicit in the
type of the POINTER_PLUS_EXPR. We'd like to turn this into
&array[x]
which may be able to propagate further. */
-static tree
-maybe_fold_stmt_addition (tree expr)
+tree
+maybe_fold_stmt_addition (tree res_type, tree op0, tree op1)
{
- tree op0 = TREE_OPERAND (expr, 0);
- tree op1 = TREE_OPERAND (expr, 1);
- tree ptr_type = TREE_TYPE (expr);
tree ptd_type;
tree t;
- gcc_assert (TREE_CODE (expr) == POINTER_PLUS_EXPR);
-
/* It had better be a constant. */
if (TREE_CODE (op1) != INTEGER_CST)
return NULL_TREE;
@@ -2048,7 +2113,7 @@ maybe_fold_stmt_addition (tree expr)
op0 = array_obj;
}
- ptd_type = TREE_TYPE (ptr_type);
+ ptd_type = TREE_TYPE (res_type);
/* If we want a pointer to void, reconstruct the reference from the
array element type. A pointer to that can be trivially converted
to void *. This happens as we fold (void *)(ptr p+ off). */
@@ -2062,7 +2127,7 @@ maybe_fold_stmt_addition (tree expr)
t = maybe_fold_offset_to_component_ref (TREE_TYPE (op0), op0, op1,
ptd_type, false);
if (t)
- t = build1 (ADDR_EXPR, ptr_type, t);
+ t = build1 (ADDR_EXPR, res_type, t);
return t;
}
@@ -2072,7 +2137,7 @@ maybe_fold_stmt_addition (tree expr)
struct fold_stmt_r_data
{
- tree stmt;
+ gimple stmt;
bool *changed_p;
bool *inside_addr_expr_p;
};
@@ -2083,12 +2148,17 @@ struct fold_stmt_r_data
static tree
fold_stmt_r (tree *expr_p, int *walk_subtrees, void *data)
{
- struct fold_stmt_r_data *fold_stmt_r_data = (struct fold_stmt_r_data *) data;
- bool *inside_addr_expr_p = fold_stmt_r_data->inside_addr_expr_p;
- bool *changed_p = fold_stmt_r_data->changed_p;
+ struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
+ struct fold_stmt_r_data *fold_stmt_r_data;
+ bool *inside_addr_expr_p;
+ bool *changed_p;
tree expr = *expr_p, t;
bool volatile_p = TREE_THIS_VOLATILE (expr);
+ fold_stmt_r_data = (struct fold_stmt_r_data *) wi->info;
+ inside_addr_expr_p = fold_stmt_r_data->inside_addr_expr_p;
+ changed_p = fold_stmt_r_data->changed_p;
+
/* ??? It'd be nice if walk_tree had a pre-order option. */
switch (TREE_CODE (expr))
{
@@ -2154,18 +2224,6 @@ fold_stmt_r (tree *expr_p, int *walk_subtrees, void *data)
recompute_tree_invariant_for_addr_expr (expr);
return NULL_TREE;
- case POINTER_PLUS_EXPR:
- t = walk_tree (&TREE_OPERAND (expr, 0), fold_stmt_r, data, NULL);
- if (t)
- return t;
- t = walk_tree (&TREE_OPERAND (expr, 1), fold_stmt_r, data, NULL);
- if (t)
- return t;
- *walk_subtrees = 0;
-
- t = maybe_fold_stmt_addition (expr);
- break;
-
case COMPONENT_REF:
t = walk_tree (&TREE_OPERAND (expr, 0), fold_stmt_r, data, NULL);
if (t)
@@ -2191,6 +2249,20 @@ fold_stmt_r (tree *expr_p, int *walk_subtrees, void *data)
t = maybe_fold_tmr (expr);
break;
+ case POINTER_PLUS_EXPR:
+ t = walk_tree (&TREE_OPERAND (expr, 0), fold_stmt_r, data, NULL);
+ if (t)
+ return t;
+ t = walk_tree (&TREE_OPERAND (expr, 1), fold_stmt_r, data, NULL);
+ if (t)
+ return t;
+ *walk_subtrees = 0;
+
+ t = maybe_fold_stmt_addition (TREE_TYPE (expr),
+ TREE_OPERAND (expr, 0),
+ TREE_OPERAND (expr, 1));
+ break;
+
case COND_EXPR:
if (COMPARISON_CLASS_P (TREE_OPERAND (expr, 0)))
{
@@ -2202,11 +2274,15 @@ fold_stmt_r (tree *expr_p, int *walk_subtrees, void *data)
tem = fold_binary (TREE_CODE (op0), TREE_TYPE (op0),
TREE_OPERAND (op0, 0),
TREE_OPERAND (op0, 1));
- set = tem && set_rhs (expr_p, tem);
+ /* This is actually a conditional expression, not a GIMPLE
+ conditional statement, however, the valid_gimple_rhs_p
+ test still applies. */
+ set = tem && is_gimple_condexpr (tem) && valid_gimple_rhs_p (tem);
fold_undefer_overflow_warnings (set, fold_stmt_r_data->stmt, 0);
if (set)
{
- t = *expr_p;
+ COND_EXPR_COND (expr) = tem;
+ t = expr;
break;
}
}
@@ -2227,7 +2303,6 @@ fold_stmt_r (tree *expr_p, int *walk_subtrees, void *data)
return NULL_TREE;
}
-
/* Return the string length, maximum string length or maximum value of
ARG in LENGTH.
If ARG is an SSA name variable, follow its use-def chains. If LENGTH
@@ -2240,7 +2315,8 @@ fold_stmt_r (tree *expr_p, int *walk_subtrees, void *data)
static bool
get_maxval_strlen (tree arg, tree *length, bitmap visited, int type)
{
- tree var, def_stmt, val;
+ tree var, val;
+ gimple def_stmt;
if (TREE_CODE (arg) != SSA_NAME)
{
@@ -2299,74 +2375,75 @@ get_maxval_strlen (tree arg, tree *length, bitmap visited, int type)
var = arg;
def_stmt = SSA_NAME_DEF_STMT (var);
- switch (TREE_CODE (def_stmt))
- {
- case GIMPLE_MODIFY_STMT:
- {
- tree rhs;
-
- /* The RHS of the statement defining VAR must either have a
- constant length or come from another SSA_NAME with a constant
- length. */
- rhs = GIMPLE_STMT_OPERAND (def_stmt, 1);
- STRIP_NOPS (rhs);
- return get_maxval_strlen (rhs, length, visited, type);
- }
-
- case PHI_NODE:
+ switch (gimple_code (def_stmt))
+ {
+ case GIMPLE_ASSIGN:
+ /* The RHS of the statement defining VAR must either have a
+ constant length or come from another SSA_NAME with a constant
+ length. */
+ if (gimple_assign_single_p (def_stmt)
+ || gimple_assign_unary_nop_p (def_stmt))
+ {
+ tree rhs = gimple_assign_rhs1 (def_stmt);
+ return get_maxval_strlen (rhs, length, visited, type);
+ }
+ return false;
+
+ case GIMPLE_PHI:
{
/* All the arguments of the PHI node must have the same constant
length. */
- int i;
-
- for (i = 0; i < PHI_NUM_ARGS (def_stmt); i++)
- {
- tree arg = PHI_ARG_DEF (def_stmt, i);
-
- /* If this PHI has itself as an argument, we cannot
- determine the string length of this argument. However,
- if we can find a constant string length for the other
- PHI args then we can still be sure that this is a
- constant string length. So be optimistic and just
- continue with the next argument. */
- if (arg == PHI_RESULT (def_stmt))
- continue;
-
- if (!get_maxval_strlen (arg, length, visited, type))
- return false;
- }
-
- return true;
- }
+ unsigned i;
+
+ for (i = 0; i < gimple_phi_num_args (def_stmt); i++)
+ {
+ tree arg = gimple_phi_arg (def_stmt, i)->def;
+
+ /* If this PHI has itself as an argument, we cannot
+ determine the string length of this argument. However,
+ if we can find a constant string length for the other
+ PHI args then we can still be sure that this is a
+ constant string length. So be optimistic and just
+ continue with the next argument. */
+ if (arg == gimple_phi_result (def_stmt))
+ continue;
+
+ if (!get_maxval_strlen (arg, length, visited, type))
+ return false;
+ }
+ }
+ return true;
default:
- break;
+ return false;
}
-
-
- return false;
}
-/* Fold builtin call FN in statement STMT. If it cannot be folded into a
- constant, return NULL_TREE. Otherwise, return its constant value. */
+/* Fold builtin call in statement STMT. Returns a simplified tree.
+ We may return a non-constant expression, including another call
+ to a different function and with different arguments, e.g.,
+ substituting memcpy for strcpy when the string length is known.
+ Note that some builtins expand into inline code that may not
+ be valid in GIMPLE. Callers must take care. */
static tree
-ccp_fold_builtin (tree stmt, tree fn)
+ccp_fold_builtin (gimple stmt)
{
tree result, val[3];
tree callee, a;
int arg_mask, i, type;
bitmap visited;
bool ignore;
- call_expr_arg_iterator iter;
int nargs;
- ignore = TREE_CODE (stmt) != GIMPLE_MODIFY_STMT;
+ gcc_assert (is_gimple_call (stmt));
+
+ ignore = (gimple_call_lhs (stmt) == NULL);
/* First try the generic builtin folder. If that succeeds, return the
result directly. */
- result = fold_call_expr (fn, ignore);
+ result = fold_call_stmt (stmt, ignore);
if (result)
{
if (ignore)
@@ -2375,13 +2452,13 @@ ccp_fold_builtin (tree stmt, tree fn)
}
/* Ignore MD builtins. */
- callee = get_callee_fndecl (fn);
+ callee = gimple_call_fndecl (stmt);
if (DECL_BUILT_IN_CLASS (callee) == BUILT_IN_MD)
return NULL_TREE;
/* If the builtin could not be folded, and it has no argument list,
we're done. */
- nargs = call_expr_nargs (fn);
+ nargs = gimple_call_num_args (stmt);
if (nargs == 0)
return NULL_TREE;
@@ -2425,16 +2502,15 @@ ccp_fold_builtin (tree stmt, tree fn)
visited = BITMAP_ALLOC (NULL);
memset (val, 0, sizeof (val));
- init_call_expr_arg_iterator (fn, &iter);
- for (i = 0; arg_mask; i++, arg_mask >>= 1)
+ for (i = 0; i < nargs; i++)
{
- a = next_call_expr_arg (&iter);
- if (arg_mask & 1)
- {
- bitmap_clear (visited);
- if (!get_maxval_strlen (a, &val[i], visited, type))
- val[i] = NULL_TREE;
- }
+ if ((arg_mask >> i) & 1)
+ {
+ a = gimple_call_arg (stmt, i);
+ bitmap_clear (visited);
+ if (!get_maxval_strlen (a, &val[i], visited, type))
+ val[i] = NULL_TREE;
+ }
}
BITMAP_FREE (visited);
@@ -2445,7 +2521,8 @@ ccp_fold_builtin (tree stmt, tree fn)
case BUILT_IN_STRLEN:
if (val[0])
{
- tree new_val = fold_convert (TREE_TYPE (fn), val[0]);
+ tree new_val =
+ fold_convert (TREE_TYPE (gimple_call_lhs (stmt)), val[0]);
/* If the result is not a valid gimple value, or not a cast
of a valid gimple value, then we can not use the result. */
@@ -2459,32 +2536,30 @@ ccp_fold_builtin (tree stmt, tree fn)
case BUILT_IN_STRCPY:
if (val[1] && is_gimple_val (val[1]) && nargs == 2)
result = fold_builtin_strcpy (callee,
- CALL_EXPR_ARG (fn, 0),
- CALL_EXPR_ARG (fn, 1),
+ gimple_call_arg (stmt, 0),
+ gimple_call_arg (stmt, 1),
val[1]);
break;
case BUILT_IN_STRNCPY:
if (val[1] && is_gimple_val (val[1]) && nargs == 3)
result = fold_builtin_strncpy (callee,
- CALL_EXPR_ARG (fn, 0),
- CALL_EXPR_ARG (fn, 1),
- CALL_EXPR_ARG (fn, 2),
+ gimple_call_arg (stmt, 0),
+ gimple_call_arg (stmt, 1),
+ gimple_call_arg (stmt, 2),
val[1]);
break;
case BUILT_IN_FPUTS:
- result = fold_builtin_fputs (CALL_EXPR_ARG (fn, 0),
- CALL_EXPR_ARG (fn, 1),
- TREE_CODE (stmt) != GIMPLE_MODIFY_STMT, 0,
- val[0]);
+ result = fold_builtin_fputs (gimple_call_arg (stmt, 0),
+ gimple_call_arg (stmt, 1),
+ ignore, false, val[0]);
break;
case BUILT_IN_FPUTS_UNLOCKED:
- result = fold_builtin_fputs (CALL_EXPR_ARG (fn, 0),
- CALL_EXPR_ARG (fn, 1),
- TREE_CODE (stmt) != GIMPLE_MODIFY_STMT, 1,
- val[0]);
+ result = fold_builtin_fputs (gimple_call_arg (stmt, 0),
+ gimple_call_arg (stmt, 1),
+ ignore, true, val[0]);
break;
case BUILT_IN_MEMCPY_CHK:
@@ -2493,10 +2568,10 @@ ccp_fold_builtin (tree stmt, tree fn)
case BUILT_IN_MEMSET_CHK:
if (val[2] && is_gimple_val (val[2]))
result = fold_builtin_memory_chk (callee,
- CALL_EXPR_ARG (fn, 0),
- CALL_EXPR_ARG (fn, 1),
- CALL_EXPR_ARG (fn, 2),
- CALL_EXPR_ARG (fn, 3),
+ gimple_call_arg (stmt, 0),
+ gimple_call_arg (stmt, 1),
+ gimple_call_arg (stmt, 2),
+ gimple_call_arg (stmt, 3),
val[2], ignore,
DECL_FUNCTION_CODE (callee));
break;
@@ -2505,27 +2580,27 @@ ccp_fold_builtin (tree stmt, tree fn)
case BUILT_IN_STPCPY_CHK:
if (val[1] && is_gimple_val (val[1]))
result = fold_builtin_stxcpy_chk (callee,
- CALL_EXPR_ARG (fn, 0),
- CALL_EXPR_ARG (fn, 1),
- CALL_EXPR_ARG (fn, 2),
+ gimple_call_arg (stmt, 0),
+ gimple_call_arg (stmt, 1),
+ gimple_call_arg (stmt, 2),
val[1], ignore,
DECL_FUNCTION_CODE (callee));
break;
case BUILT_IN_STRNCPY_CHK:
if (val[2] && is_gimple_val (val[2]))
- result = fold_builtin_strncpy_chk (CALL_EXPR_ARG (fn, 0),
- CALL_EXPR_ARG (fn, 1),
- CALL_EXPR_ARG (fn, 2),
- CALL_EXPR_ARG (fn, 3),
+ result = fold_builtin_strncpy_chk (gimple_call_arg (stmt, 0),
+ gimple_call_arg (stmt, 1),
+ gimple_call_arg (stmt, 2),
+ gimple_call_arg (stmt, 3),
val[2]);
break;
case BUILT_IN_SNPRINTF_CHK:
case BUILT_IN_VSNPRINTF_CHK:
if (val[1] && is_gimple_val (val[1]))
- result = fold_builtin_snprintf_chk (fn, val[1],
- DECL_FUNCTION_CODE (callee));
+ result = gimple_fold_builtin_snprintf_chk (stmt, val[1],
+ DECL_FUNCTION_CODE (callee));
break;
default:
@@ -2537,114 +2612,267 @@ ccp_fold_builtin (tree stmt, tree fn)
return result;
}
+/* Attempt to fold an assignment statement pointed-to by SI. Returns a
+ replacement rhs for the statement or NULL_TREE if no simplification
+ could be made. It is assumed that the operands have been previously
+ folded. */
+
+static tree
+fold_gimple_assign (gimple_stmt_iterator *si)
+{
+ gimple stmt = gsi_stmt (*si);
+ enum tree_code subcode = gimple_assign_rhs_code (stmt);
+
+ tree result = NULL;
+
+ switch (get_gimple_rhs_class (subcode))
+ {
+ case GIMPLE_SINGLE_RHS:
+ {
+ tree rhs = gimple_assign_rhs1 (stmt);
+
+ /* Try to fold a conditional expression. */
+ if (TREE_CODE (rhs) == COND_EXPR)
+ {
+ tree temp = fold (COND_EXPR_COND (rhs));
+ if (temp != COND_EXPR_COND (rhs))
+ result = fold_build3 (COND_EXPR, TREE_TYPE (rhs), temp,
+ COND_EXPR_THEN (rhs), COND_EXPR_ELSE (rhs));
+ }
+
+ /* If we couldn't fold the RHS, hand over to the generic
+ fold routines. */
+ if (result == NULL_TREE)
+ result = fold (rhs);
+
+ /* Strip away useless type conversions. Both the NON_LVALUE_EXPR
+ that may have been added by fold, and "useless" type
+ conversions that might now be apparent due to propagation. */
+ STRIP_USELESS_TYPE_CONVERSION (result);
+
+ if (result != rhs && valid_gimple_rhs_p (result))
+ return result;
+ else
+ /* It is possible that fold_stmt_r simplified the RHS.
+ Make sure that the subcode of this statement still
+ reflects the principal operator of the rhs operand. */
+ return rhs;
+ }
+ break;
+
+ case GIMPLE_UNARY_RHS:
+ result = fold_unary (subcode,
+ gimple_expr_type (stmt),
+ gimple_assign_rhs1 (stmt));
+
+ if (result)
+ {
+ STRIP_USELESS_TYPE_CONVERSION (result);
+ if (valid_gimple_rhs_p (result))
+ return result;
+ }
+ else if ((gimple_assign_rhs_code (stmt) == NOP_EXPR
+ || gimple_assign_rhs_code (stmt) == CONVERT_EXPR)
+ && POINTER_TYPE_P (gimple_expr_type (stmt))
+ && POINTER_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (stmt))))
+ {
+ tree type = gimple_expr_type (stmt);
+ tree t = maybe_fold_offset_to_reference (gimple_assign_rhs1 (stmt),
+ integer_zero_node,
+ TREE_TYPE (type));
+ if (t)
+ {
+ tree ptr_type = build_pointer_type (TREE_TYPE (t));
+ if (useless_type_conversion_p (type, ptr_type))
+ return build_fold_addr_expr_with_type (t, ptr_type);
+ }
+ }
+ break;
+
+ case GIMPLE_BINARY_RHS:
+ /* Try to fold pointer addition. */
+ if (gimple_assign_rhs_code (stmt) == POINTER_PLUS_EXPR)
+ result = maybe_fold_stmt_addition (
+ TREE_TYPE (gimple_assign_lhs (stmt)),
+ gimple_assign_rhs1 (stmt),
+ gimple_assign_rhs2 (stmt));
+
+ if (!result)
+ result = fold_binary (subcode,
+ TREE_TYPE (gimple_assign_lhs (stmt)),
+ gimple_assign_rhs1 (stmt),
+ gimple_assign_rhs2 (stmt));
+
+ if (result)
+ {
+ STRIP_USELESS_TYPE_CONVERSION (result);
+ if (valid_gimple_rhs_p (result))
+ return result;
+ }
+ break;
+
+ case GIMPLE_INVALID_RHS:
+ gcc_unreachable ();
+ }
+
+ return NULL_TREE;
+}
+
+/* Attempt to fold a conditional statement. Return true if any changes were
+ made. We only attempt to fold the condition expression, and do not perform
+ any transformation that would require alteration of the cfg. It is
+ assumed that the operands have been previously folded. */
+
+static bool
+fold_gimple_cond (gimple stmt)
+{
+ tree result = fold_binary (gimple_cond_code (stmt),
+ boolean_type_node,
+ gimple_cond_lhs (stmt),
+ gimple_cond_rhs (stmt));
+
+ if (result)
+ {
+ STRIP_USELESS_TYPE_CONVERSION (result);
+ if (is_gimple_condexpr (result) && valid_gimple_rhs_p (result))
+ {
+ gimple_cond_set_condition_from_tree (stmt, result);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+
+/* Attempt to fold a call statement referenced by the statement iterator GSI.
+ The statement may be replaced by another statement, e.g., if the call
+ simplifies to a constant value. Return true if any changes were made.
+ It is assumed that the operands have been previously folded. */
+
+static bool
+fold_gimple_call (gimple_stmt_iterator *gsi)
+{
+ gimple stmt = gsi_stmt (*gsi);
+
+ tree callee = gimple_call_fndecl (stmt);
+
+ /* Check for builtins that CCP can handle using information not
+ available in the generic fold routines. */
+ if (callee && DECL_BUILT_IN (callee))
+ {
+ tree result = ccp_fold_builtin (stmt);
+
+ if (result)
+ return update_call_from_tree (gsi, result);
+ }
+ else
+ {
+ /* Check for resolvable OBJ_TYPE_REF. The only sorts we can resolve
+ here are when we've propagated the address of a decl into the
+ object slot. */
+ /* ??? Should perhaps do this in fold proper. However, doing it
+ there requires that we create a new CALL_EXPR, and that requires
+ copying EH region info to the new node. Easier to just do it
+ here where we can just smash the call operand. */
+ /* ??? Is there a good reason not to do this in fold_stmt_inplace? */
+ callee = gimple_call_fn (stmt);
+ if (TREE_CODE (callee) == OBJ_TYPE_REF
+ && lang_hooks.fold_obj_type_ref
+ && TREE_CODE (OBJ_TYPE_REF_OBJECT (callee)) == ADDR_EXPR
+ && DECL_P (TREE_OPERAND
+ (OBJ_TYPE_REF_OBJECT (callee), 0)))
+ {
+ tree t;
+
+ /* ??? Caution: Broken ADDR_EXPR semantics means that
+ looking at the type of the operand of the addr_expr
+ can yield an array type. See silly exception in
+ check_pointer_types_r. */
+ t = TREE_TYPE (TREE_TYPE (OBJ_TYPE_REF_OBJECT (callee)));
+ t = lang_hooks.fold_obj_type_ref (callee, t);
+ if (t)
+ {
+ gimple_call_set_fn (stmt, t);
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
-/* Fold the statement pointed to by STMT_P. In some cases, this function may
+/* Fold the statement pointed to by GSI. In some cases, this function may
replace the whole statement with a new one. Returns true iff folding
makes any changes. */
bool
-fold_stmt (tree *stmt_p)
+fold_stmt (gimple_stmt_iterator *gsi)
{
- tree rhs, result, stmt;
+ tree res;
struct fold_stmt_r_data fold_stmt_r_data;
+ struct walk_stmt_info wi;
+
bool changed = false;
bool inside_addr_expr = false;
- stmt = *stmt_p;
+ gimple stmt = gsi_stmt (*gsi);
fold_stmt_r_data.stmt = stmt;
fold_stmt_r_data.changed_p = &changed;
fold_stmt_r_data.inside_addr_expr_p = &inside_addr_expr;
- /* If we replaced constants and the statement makes pointer dereferences,
- then we may need to fold instances of *&VAR into VAR, etc. */
- if (walk_tree (stmt_p, fold_stmt_r, &fold_stmt_r_data, NULL))
- {
- *stmt_p = build_call_expr (implicit_built_in_decls[BUILT_IN_TRAP], 0);
- return true;
- }
+ memset (&wi, 0, sizeof (wi));
+ wi.info = &fold_stmt_r_data;
- rhs = get_rhs (stmt);
- if (!rhs)
- return changed;
- result = NULL_TREE;
+ /* Fold the individual operands.
+ For example, fold instances of *&VAR into VAR, etc. */
+ res = walk_gimple_op (stmt, fold_stmt_r, &wi);
+ gcc_assert (!res);
- if (TREE_CODE (rhs) == CALL_EXPR)
+ /* Fold the main computation performed by the statement. */
+ switch (gimple_code (stmt))
{
- tree callee;
-
- /* Check for builtins that CCP can handle using information not
- available in the generic fold routines. */
- callee = get_callee_fndecl (rhs);
- if (callee && DECL_BUILT_IN (callee))
- result = ccp_fold_builtin (stmt, rhs);
- else
- {
- /* Check for resolvable OBJ_TYPE_REF. The only sorts we can resolve
- here are when we've propagated the address of a decl into the
- object slot. */
- /* ??? Should perhaps do this in fold proper. However, doing it
- there requires that we create a new CALL_EXPR, and that requires
- copying EH region info to the new node. Easier to just do it
- here where we can just smash the call operand. Also
- CALL_EXPR_RETURN_SLOT_OPT needs to be handled correctly and
- copied, fold_call_expr does not have not information. */
- callee = CALL_EXPR_FN (rhs);
- if (TREE_CODE (callee) == OBJ_TYPE_REF
- && lang_hooks.fold_obj_type_ref
- && TREE_CODE (OBJ_TYPE_REF_OBJECT (callee)) == ADDR_EXPR
- && DECL_P (TREE_OPERAND
- (OBJ_TYPE_REF_OBJECT (callee), 0)))
- {
- tree t;
-
- /* ??? Caution: Broken ADDR_EXPR semantics means that
- looking at the type of the operand of the addr_expr
- can yield an array type. See silly exception in
- check_pointer_types_r. */
+ case GIMPLE_ASSIGN:
+ {
+ tree new_rhs = fold_gimple_assign (gsi);
+ if (new_rhs != NULL_TREE)
+ {
+ gimple_assign_set_rhs_from_tree (gsi, new_rhs);
+ changed = true;
+ }
+ stmt = gsi_stmt (*gsi);
+ break;
+ }
+ case GIMPLE_COND:
+ changed |= fold_gimple_cond (stmt);
+ break;
+ case GIMPLE_CALL:
+ /* The entire statement may be replaced in this case. */
+ changed |= fold_gimple_call (gsi);
+ break;
- t = TREE_TYPE (TREE_TYPE (OBJ_TYPE_REF_OBJECT (callee)));
- t = lang_hooks.fold_obj_type_ref (callee, t);
- if (t)
- {
- CALL_EXPR_FN (rhs) = t;
- changed = true;
- }
- }
- }
- }
- else if (TREE_CODE (rhs) == COND_EXPR)
- {
- tree temp = fold (COND_EXPR_COND (rhs));
- if (temp != COND_EXPR_COND (rhs))
- result = fold_build3 (COND_EXPR, TREE_TYPE (rhs), temp,
- COND_EXPR_THEN (rhs), COND_EXPR_ELSE (rhs));
+ default:
+ return changed;
+ break;
}
- /* If we couldn't fold the RHS, hand over to the generic fold routines. */
- if (result == NULL_TREE)
- result = fold (rhs);
-
- /* Strip away useless type conversions. Both the NON_LVALUE_EXPR that
- may have been added by fold, and "useless" type conversions that might
- now be apparent due to propagation. */
- STRIP_USELESS_TYPE_CONVERSION (result);
-
- if (result != rhs)
- changed |= set_rhs (stmt_p, result);
-
return changed;
}
/* Perform the minimal folding on statement STMT. Only operations like
*&x created by constant propagation are handled. The statement cannot
- be replaced with a new one. */
+ be replaced with a new one. Return true if the statement was
+ changed, false otherwise. */
bool
-fold_stmt_inplace (tree stmt)
+fold_stmt_inplace (gimple stmt)
{
- tree old_stmt = stmt, rhs, new_rhs;
+ tree res;
struct fold_stmt_r_data fold_stmt_r_data;
+ struct walk_stmt_info wi;
+ gimple_stmt_iterator si;
+
bool changed = false;
bool inside_addr_expr = false;
@@ -2652,24 +2880,50 @@ fold_stmt_inplace (tree stmt)
fold_stmt_r_data.changed_p = &changed;
fold_stmt_r_data.inside_addr_expr_p = &inside_addr_expr;
- walk_tree (&stmt, fold_stmt_r, &fold_stmt_r_data, NULL);
- gcc_assert (stmt == old_stmt);
+ memset (&wi, 0, sizeof (wi));
+ wi.info = &fold_stmt_r_data;
- rhs = get_rhs (stmt);
- if (!rhs || rhs == stmt)
- return changed;
+ /* Fold the individual operands.
+ For example, fold instances of *&VAR into VAR, etc.
- new_rhs = fold (rhs);
- STRIP_USELESS_TYPE_CONVERSION (new_rhs);
- if (new_rhs == rhs)
- return changed;
+ It appears that, at one time, maybe_fold_stmt_indirect
+ would cause the walk to return non-null in order to
+ signal that the entire statement should be replaced with
+ a call to _builtin_trap. This functionality is currently
+ disabled, as noted in a FIXME, and cannot be supported here. */
+ res = walk_gimple_op (stmt, fold_stmt_r, &wi);
+ gcc_assert (!res);
- changed |= set_rhs (&stmt, new_rhs);
- gcc_assert (stmt == old_stmt);
+ /* Fold the main computation performed by the statement. */
+ switch (gimple_code (stmt))
+ {
+ case GIMPLE_ASSIGN:
+ {
+ unsigned old_num_ops;
+ tree new_rhs;
+ old_num_ops = gimple_num_ops (stmt);
+ si = gsi_for_stmt (stmt);
+ new_rhs = fold_gimple_assign (&si);
+ if (new_rhs != NULL_TREE
+ && get_gimple_rhs_num_ops (TREE_CODE (new_rhs)) < old_num_ops)
+ {
+ gimple_assign_set_rhs_from_tree (&si, new_rhs);
+ changed = true;
+ }
+ gcc_assert (gsi_stmt (si) == stmt);
+ break;
+ }
+ case GIMPLE_COND:
+ changed |= fold_gimple_cond (stmt);
+ break;
+
+ default:
+ break;
+ }
return changed;
}
-
+
/* Try to optimize out __builtin_stack_restore. Optimize it out
if there is another __builtin_stack_restore in the same basic
block and no calls or ASM_EXPRs are in between, or if this block's
@@ -2677,28 +2931,30 @@ fold_stmt_inplace (tree stmt)
ASM_EXPRs after this __builtin_stack_restore. */
static tree
-optimize_stack_restore (basic_block bb, tree call, block_stmt_iterator i)
+optimize_stack_restore (gimple_stmt_iterator i)
{
- tree stack_save, stmt, callee;
+ tree callee, rhs;
+ gimple stmt, stack_save;
+ gimple_stmt_iterator stack_save_gsi;
- if (TREE_CODE (call) != CALL_EXPR
- || call_expr_nargs (call) != 1
- || TREE_CODE (CALL_EXPR_ARG (call, 0)) != SSA_NAME
- || !POINTER_TYPE_P (TREE_TYPE (CALL_EXPR_ARG (call, 0))))
+ basic_block bb = gsi_bb (i);
+ gimple call = gsi_stmt (i);
+
+ if (gimple_code (call) != GIMPLE_CALL
+ || gimple_call_num_args (call) != 1
+ || TREE_CODE (gimple_call_arg (call, 0)) != SSA_NAME
+ || !POINTER_TYPE_P (TREE_TYPE (gimple_call_arg (call, 0))))
return NULL_TREE;
- for (bsi_next (&i); !bsi_end_p (i); bsi_next (&i))
+ for (gsi_next (&i); !gsi_end_p (i); gsi_next (&i))
{
- tree call;
-
- stmt = bsi_stmt (i);
- if (TREE_CODE (stmt) == ASM_EXPR)
+ stmt = gsi_stmt (i);
+ if (gimple_code (stmt) == GIMPLE_ASM)
return NULL_TREE;
- call = get_call_expr_in (stmt);
- if (call == NULL)
+ if (gimple_code (stmt) != GIMPLE_CALL)
continue;
- callee = get_callee_fndecl (call);
+ callee = gimple_call_fndecl (stmt);
if (!callee || DECL_BUILT_IN_CLASS (callee) != BUILT_IN_NORMAL)
return NULL_TREE;
@@ -2706,79 +2962,80 @@ optimize_stack_restore (basic_block bb, tree call, block_stmt_iterator i)
break;
}
- if (bsi_end_p (i)
+ if (gsi_end_p (i)
&& (! single_succ_p (bb)
|| single_succ_edge (bb)->dest != EXIT_BLOCK_PTR))
return NULL_TREE;
- stack_save = SSA_NAME_DEF_STMT (CALL_EXPR_ARG (call, 0));
- if (TREE_CODE (stack_save) != GIMPLE_MODIFY_STMT
- || GIMPLE_STMT_OPERAND (stack_save, 0) != CALL_EXPR_ARG (call, 0)
- || TREE_CODE (GIMPLE_STMT_OPERAND (stack_save, 1)) != CALL_EXPR
- || tree_could_throw_p (stack_save)
- || !has_single_use (CALL_EXPR_ARG (call, 0)))
+ stack_save = SSA_NAME_DEF_STMT (gimple_call_arg (call, 0));
+ if (gimple_code (stack_save) != GIMPLE_CALL
+ || gimple_call_lhs (stack_save) != gimple_call_arg (call, 0)
+ || stmt_could_throw_p (stack_save)
+ || !has_single_use (gimple_call_arg (call, 0)))
return NULL_TREE;
- callee = get_callee_fndecl (GIMPLE_STMT_OPERAND (stack_save, 1));
+ callee = gimple_call_fndecl (stack_save);
if (!callee
|| DECL_BUILT_IN_CLASS (callee) != BUILT_IN_NORMAL
|| DECL_FUNCTION_CODE (callee) != BUILT_IN_STACK_SAVE
- || call_expr_nargs (GIMPLE_STMT_OPERAND (stack_save, 1)) != 0)
+ || gimple_call_num_args (stack_save) != 0)
return NULL_TREE;
- stmt = stack_save;
- push_stmt_changes (&stmt);
- if (!set_rhs (&stmt,
- build_int_cst (TREE_TYPE (CALL_EXPR_ARG (call, 0)), 0)))
+ stack_save_gsi = gsi_for_stmt (stack_save);
+ push_stmt_changes (gsi_stmt_ptr (&stack_save_gsi));
+ rhs = build_int_cst (TREE_TYPE (gimple_call_arg (call, 0)), 0);
+ if (!update_call_from_tree (&stack_save_gsi, rhs))
{
- discard_stmt_changes (&stmt);
+ discard_stmt_changes (gsi_stmt_ptr (&stack_save_gsi));
return NULL_TREE;
}
- gcc_assert (stmt == stack_save);
- pop_stmt_changes (&stmt);
+ pop_stmt_changes (gsi_stmt_ptr (&stack_save_gsi));
+ /* No effect, so the statement will be deleted. */
return integer_zero_node;
}
-
+
/* If va_list type is a simple pointer and nothing special is needed,
optimize __builtin_va_start (&ap, 0) into ap = __builtin_next_arg (0),
__builtin_va_end (&ap) out as NOP and __builtin_va_copy into a simple
pointer assignment. */
static tree
-optimize_stdarg_builtin (tree call)
+optimize_stdarg_builtin (gimple call)
{
- tree callee, lhs, rhs;
+ tree callee, lhs, rhs, cfun_va_list;
bool va_list_simple_ptr;
- if (TREE_CODE (call) != CALL_EXPR)
+ if (gimple_code (call) != GIMPLE_CALL)
return NULL_TREE;
- va_list_simple_ptr = POINTER_TYPE_P (va_list_type_node)
- && (TREE_TYPE (va_list_type_node) == void_type_node
- || TREE_TYPE (va_list_type_node) == char_type_node);
+ callee = gimple_call_fndecl (call);
+
+ cfun_va_list = targetm.fn_abi_va_list (callee);
+ va_list_simple_ptr = POINTER_TYPE_P (cfun_va_list)
+ && (TREE_TYPE (cfun_va_list) == void_type_node
+ || TREE_TYPE (cfun_va_list) == char_type_node);
- callee = get_callee_fndecl (call);
switch (DECL_FUNCTION_CODE (callee))
{
case BUILT_IN_VA_START:
if (!va_list_simple_ptr
|| targetm.expand_builtin_va_start != NULL
- || built_in_decls[BUILT_IN_NEXT_ARG] == NULL)
+ || built_in_decls[BUILT_IN_NEXT_ARG] == NULL)
return NULL_TREE;
- if (call_expr_nargs (call) != 2)
+ if (gimple_call_num_args (call) != 2)
return NULL_TREE;
- lhs = CALL_EXPR_ARG (call, 0);
+ lhs = gimple_call_arg (call, 0);
if (!POINTER_TYPE_P (TREE_TYPE (lhs))
|| TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (lhs)))
- != TYPE_MAIN_VARIANT (va_list_type_node))
+ != TYPE_MAIN_VARIANT (cfun_va_list))
return NULL_TREE;
-
+
lhs = build_fold_indirect_ref (lhs);
rhs = build_call_expr (built_in_decls[BUILT_IN_NEXT_ARG],
- 1, integer_zero_node);
+ 1, integer_zero_node);
rhs = fold_convert (TREE_TYPE (lhs), rhs);
return build2 (MODIFY_EXPR, TREE_TYPE (lhs), lhs, rhs);
@@ -2786,71 +3043,92 @@ optimize_stdarg_builtin (tree call)
if (!va_list_simple_ptr)
return NULL_TREE;
- if (call_expr_nargs (call) != 2)
+ if (gimple_call_num_args (call) != 2)
return NULL_TREE;
- lhs = CALL_EXPR_ARG (call, 0);
+ lhs = gimple_call_arg (call, 0);
if (!POINTER_TYPE_P (TREE_TYPE (lhs))
|| TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (lhs)))
- != TYPE_MAIN_VARIANT (va_list_type_node))
+ != TYPE_MAIN_VARIANT (cfun_va_list))
return NULL_TREE;
lhs = build_fold_indirect_ref (lhs);
- rhs = CALL_EXPR_ARG (call, 1);
+ rhs = gimple_call_arg (call, 1);
if (TYPE_MAIN_VARIANT (TREE_TYPE (rhs))
- != TYPE_MAIN_VARIANT (va_list_type_node))
+ != TYPE_MAIN_VARIANT (cfun_va_list))
return NULL_TREE;
rhs = fold_convert (TREE_TYPE (lhs), rhs);
return build2 (MODIFY_EXPR, TREE_TYPE (lhs), lhs, rhs);
case BUILT_IN_VA_END:
+ /* No effect, so the statement will be deleted. */
return integer_zero_node;
default:
gcc_unreachable ();
}
}
-
+
/* Convert EXPR into a GIMPLE value suitable for substitution on the
RHS of an assignment. Insert the necessary statements before
- iterator *SI_P.
- When IGNORE is set, don't worry about the return value. */
+ iterator *SI_P. The statement at *SI_P, which must be a GIMPLE_CALL
+ is replaced. If the call is expected to produces a result, then it
+ is replaced by an assignment of the new RHS to the result variable.
+ If the result is to be ignored, then the call is replaced by a
+ GIMPLE_NOP. */
-static tree
-convert_to_gimple_builtin (block_stmt_iterator *si_p, tree expr, bool ignore)
+static void
+gimplify_and_update_call_from_tree (gimple_stmt_iterator *si_p, tree expr)
{
- tree_stmt_iterator ti;
- tree stmt = bsi_stmt (*si_p);
- tree tmp, stmts = NULL;
+ tree lhs;
+ tree tmp = NULL_TREE; /* Silence warning. */
+ gimple stmt, new_stmt;
+ gimple_stmt_iterator i;
+ gimple_seq stmts = gimple_seq_alloc();
+ struct gimplify_ctx gctx;
- push_gimplify_context ();
- if (ignore)
- {
- tmp = build_empty_stmt ();
- gimplify_and_add (expr, &stmts);
- }
- else
+ stmt = gsi_stmt (*si_p);
+
+ gcc_assert (is_gimple_call (stmt));
+
+ lhs = gimple_call_lhs (stmt);
+
+ push_gimplify_context (&gctx);
+
+ if (lhs == NULL_TREE)
+ gimplify_and_add (expr, &stmts);
+ else
tmp = get_initialized_tmp_var (expr, &stmts, NULL);
+
pop_gimplify_context (NULL);
- if (EXPR_HAS_LOCATION (stmt))
- annotate_all_with_locus (&stmts, EXPR_LOCATION (stmt));
+ if (gimple_has_location (stmt))
+ annotate_all_with_location (stmts, gimple_location (stmt));
/* The replacement can expose previously unreferenced variables. */
- for (ti = tsi_start (stmts); !tsi_end_p (ti); tsi_next (&ti))
+ for (i = gsi_start (stmts); !gsi_end_p (i); gsi_next (&i))
+ {
+ new_stmt = gsi_stmt (i);
+ find_new_referenced_vars (new_stmt);
+ gsi_insert_before (si_p, new_stmt, GSI_NEW_STMT);
+ mark_symbols_for_renaming (new_stmt);
+ gsi_next (si_p);
+ }
+
+ if (lhs == NULL_TREE)
+ new_stmt = gimple_build_nop ();
+ else
{
- tree new_stmt = tsi_stmt (ti);
- find_new_referenced_vars (tsi_stmt_ptr (ti));
- bsi_insert_before (si_p, new_stmt, BSI_NEW_STMT);
- mark_symbols_for_renaming (new_stmt);
- bsi_next (si_p);
+ new_stmt = gimple_build_assign (lhs, tmp);
+ copy_virtual_operands (new_stmt, stmt);
+ move_ssa_defining_stmt_for_defs (new_stmt, stmt);
}
- return tmp;
+ gimple_set_location (new_stmt, gimple_location (stmt));
+ gsi_replace (si_p, new_stmt, false);
}
-
/* A simple pass that attempts to fold all builtin functions. This pass
is run after we've propagated as many constants as we can. */
@@ -2863,32 +3141,32 @@ execute_fold_all_builtins (void)
FOR_EACH_BB (bb)
{
- block_stmt_iterator i;
- for (i = bsi_start (bb); !bsi_end_p (i); )
+ gimple_stmt_iterator i;
+ for (i = gsi_start_bb (bb); !gsi_end_p (i); )
{
- tree *stmtp = bsi_stmt_ptr (i);
- tree old_stmt = *stmtp;
- tree call = get_rhs (*stmtp);
+ gimple stmt, old_stmt;
tree callee, result;
enum built_in_function fcode;
- if (!call || TREE_CODE (call) != CALL_EXPR)
+ stmt = gsi_stmt (i);
+
+ if (gimple_code (stmt) != GIMPLE_CALL)
{
- bsi_next (&i);
+ gsi_next (&i);
continue;
}
- callee = get_callee_fndecl (call);
+ callee = gimple_call_fndecl (stmt);
if (!callee || DECL_BUILT_IN_CLASS (callee) != BUILT_IN_NORMAL)
{
- bsi_next (&i);
+ gsi_next (&i);
continue;
}
fcode = DECL_FUNCTION_CODE (callee);
- result = ccp_fold_builtin (*stmtp, call);
+ result = ccp_fold_builtin (stmt);
if (result)
- gimple_remove_stmt_histograms (cfun, *stmtp);
+ gimple_remove_stmt_histograms (cfun, stmt);
if (!result)
switch (DECL_FUNCTION_CODE (callee))
@@ -2897,77 +3175,71 @@ execute_fold_all_builtins (void)
/* Resolve __builtin_constant_p. If it hasn't been
folded to integer_one_node by now, it's fairly
certain that the value simply isn't constant. */
- result = integer_zero_node;
+ result = integer_zero_node;
break;
case BUILT_IN_STACK_RESTORE:
- result = optimize_stack_restore (bb, *stmtp, i);
+ result = optimize_stack_restore (i);
if (result)
break;
- bsi_next (&i);
+ gsi_next (&i);
continue;
case BUILT_IN_VA_START:
case BUILT_IN_VA_END:
case BUILT_IN_VA_COPY:
/* These shouldn't be folded before pass_stdarg. */
- result = optimize_stdarg_builtin (*stmtp);
+ result = optimize_stdarg_builtin (stmt);
if (result)
break;
/* FALLTHRU */
default:
- bsi_next (&i);
+ gsi_next (&i);
continue;
}
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "Simplified\n ");
- print_generic_stmt (dump_file, *stmtp, dump_flags);
+ print_gimple_stmt (dump_file, stmt, 0, dump_flags);
}
- push_stmt_changes (stmtp);
+ old_stmt = stmt;
+ push_stmt_changes (gsi_stmt_ptr (&i));
- if (!set_rhs (stmtp, result))
- {
- result = convert_to_gimple_builtin (&i, result,
- TREE_CODE (old_stmt)
- != GIMPLE_MODIFY_STMT);
- if (result)
- {
- bool ok = set_rhs (stmtp, result);
- gcc_assert (ok);
- todoflags |= TODO_rebuild_alias;
- }
- }
+ if (!update_call_from_tree (&i, result))
+ {
+ gimplify_and_update_call_from_tree (&i, result);
+ todoflags |= TODO_rebuild_alias;
+ }
- pop_stmt_changes (stmtp);
+ stmt = gsi_stmt (i);
+ pop_stmt_changes (gsi_stmt_ptr (&i));
- if (maybe_clean_or_replace_eh_stmt (old_stmt, *stmtp)
- && tree_purge_dead_eh_edges (bb))
+ if (maybe_clean_or_replace_eh_stmt (old_stmt, stmt)
+ && gimple_purge_dead_eh_edges (bb))
cfg_changed = true;
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "to\n ");
- print_generic_stmt (dump_file, *stmtp, dump_flags);
+ print_gimple_stmt (dump_file, stmt, 0, dump_flags);
fprintf (dump_file, "\n");
}
/* Retry the same statement if it changed into another
builtin, there might be new opportunities now. */
- call = get_rhs (*stmtp);
- if (!call || TREE_CODE (call) != CALL_EXPR)
+ if (gimple_code (stmt) != GIMPLE_CALL)
{
- bsi_next (&i);
+ gsi_next (&i);
continue;
}
- callee = get_callee_fndecl (call);
+ callee = gimple_call_fndecl (stmt);
if (!callee
- || DECL_BUILT_IN_CLASS (callee) != BUILT_IN_NORMAL
+ || DECL_BUILT_IN_CLASS (callee) != BUILT_IN_NORMAL
|| DECL_FUNCTION_CODE (callee) == fcode)
- bsi_next (&i);
+ gsi_next (&i);
}
}
diff --git a/gcc/tree-ssa-coalesce.c b/gcc/tree-ssa-coalesce.c
index 388437d44bb..d5e5f8702ff 100644
--- a/gcc/tree-ssa-coalesce.c
+++ b/gcc/tree-ssa-coalesce.c
@@ -841,16 +841,15 @@ build_ssa_conflict_graph (tree_live_info_p liveinfo)
FOR_EACH_BB (bb)
{
- block_stmt_iterator bsi;
- tree phi;
+ gimple_stmt_iterator gsi;
/* Start with live on exit temporaries. */
live_track_init (live, live_on_exit (liveinfo, bb));
- for (bsi = bsi_last (bb); !bsi_end_p (bsi); bsi_prev (&bsi))
+ for (gsi = gsi_last_bb (bb); !gsi_end_p (gsi); gsi_prev (&gsi))
{
tree var;
- tree stmt = bsi_stmt (bsi);
+ gimple stmt = gsi_stmt (gsi);
/* A copy between 2 partitions does not introduce an interference
by itself. If they did, you would never be able to coalesce
@@ -859,12 +858,14 @@ build_ssa_conflict_graph (tree_live_info_p liveinfo)
This is handled by simply removing the SRC of the copy from the
live list, and processing the stmt normally. */
- if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT)
+ if (is_gimple_assign (stmt))
{
- tree lhs = GIMPLE_STMT_OPERAND (stmt, 0);
- tree rhs = GIMPLE_STMT_OPERAND (stmt, 1);
- if (TREE_CODE (lhs) == SSA_NAME && TREE_CODE (rhs) == SSA_NAME)
- live_track_clear_var (live, rhs);
+ tree lhs = gimple_assign_lhs (stmt);
+ tree rhs1 = gimple_assign_rhs1 (stmt);
+ if (gimple_assign_copy_p (stmt)
+ && TREE_CODE (lhs) == SSA_NAME
+ && TREE_CODE (rhs1) == SSA_NAME)
+ live_track_clear_var (live, rhs1);
}
FOR_EACH_SSA_TREE_OPERAND (var, stmt, iter, SSA_OP_DEF)
@@ -880,8 +881,9 @@ build_ssa_conflict_graph (tree_live_info_p liveinfo)
There must be a conflict recorded between the result of the PHI and
any variables that are live. Otherwise the out-of-ssa translation
may create incorrect code. */
- for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
+ for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
+ gimple phi = gsi_stmt (gsi);
tree result = PHI_RESULT (phi);
if (live_track_live_p (live, result))
live_track_process_def (live, result, graph);
@@ -915,11 +917,11 @@ print_exprs (FILE *f, const char *str1, tree expr1, const char *str2,
printed and compilation is then terminated. */
static inline void
-abnormal_corrupt (tree phi, int i)
+abnormal_corrupt (gimple phi, int i)
{
- edge e = PHI_ARG_EDGE (phi, i);
- tree res = PHI_RESULT (phi);
- tree arg = PHI_ARG_DEF (phi, i);
+ edge e = gimple_phi_arg_edge (phi, i);
+ tree res = gimple_phi_result (phi);
+ tree arg = gimple_phi_arg_def (phi, i);
fprintf (stderr, " Corrupt SSA across abnormal edge BB%d->BB%d\n",
e->src->index, e->dest->index);
@@ -959,10 +961,10 @@ fail_abnormal_edge_coalesce (int x, int y)
static var_map
create_outofssa_var_map (coalesce_list_p cl, bitmap used_in_copy)
{
- block_stmt_iterator bsi;
+ gimple_stmt_iterator gsi;
basic_block bb;
tree var;
- tree stmt;
+ gimple stmt;
tree first;
var_map map;
ssa_op_iter iter;
@@ -981,24 +983,25 @@ create_outofssa_var_map (coalesce_list_p cl, bitmap used_in_copy)
FOR_EACH_BB (bb)
{
- tree phi, arg;
+ tree arg;
- for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
+ for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
- int i;
+ gimple phi = gsi_stmt (gsi);
+ size_t i;
int ver;
tree res;
bool saw_copy = false;
- res = PHI_RESULT (phi);
+ res = gimple_phi_result (phi);
ver = SSA_NAME_VERSION (res);
register_ssa_partition (map, res);
/* Register ssa_names and coalesces between the args and the result
of all PHI. */
- for (i = 0; i < PHI_NUM_ARGS (phi); i++)
+ for (i = 0; i < gimple_phi_num_args (phi); i++)
{
- edge e = PHI_ARG_EDGE (phi, i);
+ edge e = gimple_phi_arg_edge (phi, i);
arg = PHI_ARG_DEF (phi, i);
if (TREE_CODE (arg) == SSA_NAME)
register_ssa_partition (map, arg);
@@ -1024,27 +1027,29 @@ create_outofssa_var_map (coalesce_list_p cl, bitmap used_in_copy)
bitmap_set_bit (used_in_copy, ver);
}
- for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
- stmt = bsi_stmt (bsi);
+ stmt = gsi_stmt (gsi);
/* Register USE and DEF operands in each statement. */
FOR_EACH_SSA_TREE_OPERAND (var, stmt, iter, (SSA_OP_DEF|SSA_OP_USE))
register_ssa_partition (map, var);
/* Check for copy coalesces. */
- switch (TREE_CODE (stmt))
+ switch (gimple_code (stmt))
{
- case GIMPLE_MODIFY_STMT:
+ case GIMPLE_ASSIGN:
{
- tree op1 = GIMPLE_STMT_OPERAND (stmt, 0);
- tree op2 = GIMPLE_STMT_OPERAND (stmt, 1);
- if (TREE_CODE (op1) == SSA_NAME
- && TREE_CODE (op2) == SSA_NAME
- && SSA_NAME_VAR (op1) == SSA_NAME_VAR (op2))
+ tree lhs = gimple_assign_lhs (stmt);
+ tree rhs1 = gimple_assign_rhs1 (stmt);
+
+ if (gimple_assign_copy_p (stmt)
+ && TREE_CODE (lhs) == SSA_NAME
+ && TREE_CODE (rhs1) == SSA_NAME
+ && SSA_NAME_VAR (lhs) == SSA_NAME_VAR (rhs1))
{
- v1 = SSA_NAME_VERSION (op1);
- v2 = SSA_NAME_VERSION (op2);
+ v1 = SSA_NAME_VERSION (lhs);
+ v2 = SSA_NAME_VERSION (rhs1);
cost = coalesce_cost_bb (bb);
add_coalesce (cl, v1, v2, cost);
bitmap_set_bit (used_in_copy, v1);
@@ -1053,24 +1058,31 @@ create_outofssa_var_map (coalesce_list_p cl, bitmap used_in_copy)
}
break;
- case ASM_EXPR:
+ case GIMPLE_ASM:
{
unsigned long noutputs, i;
+ unsigned long ninputs;
tree *outputs, link;
- noutputs = list_length (ASM_OUTPUTS (stmt));
+ noutputs = gimple_asm_noutputs (stmt);
+ ninputs = gimple_asm_ninputs (stmt);
outputs = (tree *) alloca (noutputs * sizeof (tree));
- for (i = 0, link = ASM_OUTPUTS (stmt); link;
- ++i, link = TREE_CHAIN (link))
+ for (i = 0; i < noutputs; ++i) {
+ link = gimple_asm_output_op (stmt, i);
outputs[i] = TREE_VALUE (link);
+ }
- for (link = ASM_INPUTS (stmt); link; link = TREE_CHAIN (link))
+ for (i = 0; i < ninputs; ++i)
{
- const char *constraint
- = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
- tree input = TREE_VALUE (link);
+ const char *constraint;
+ tree input;
char *end;
unsigned long match;
+ link = gimple_asm_input_op (stmt, i);
+ constraint
+ = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
+ input = TREE_VALUE (link);
+
if (TREE_CODE (input) != SSA_NAME)
continue;
@@ -1247,7 +1259,7 @@ coalesce_partitions (var_map map, ssa_conflicts_p graph, coalesce_list_p cl,
FILE *debug)
{
int x = 0, y = 0;
- tree var1, var2, phi;
+ tree var1, var2;
int cost;
basic_block bb;
edge e;
@@ -1262,8 +1274,11 @@ coalesce_partitions (var_map map, ssa_conflicts_p graph, coalesce_list_p cl,
FOR_EACH_EDGE (e, ei, bb->preds)
if (e->flags & EDGE_ABNORMAL)
{
- for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
+ gimple_stmt_iterator gsi;
+ for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi);
+ gsi_next (&gsi))
{
+ gimple phi = gsi_stmt (gsi);
tree res = PHI_RESULT (phi);
tree arg = PHI_ARG_DEF (phi, e->dest_idx);
int v1 = SSA_NAME_VERSION (res);
@@ -1297,6 +1312,24 @@ coalesce_partitions (var_map map, ssa_conflicts_p graph, coalesce_list_p cl,
}
}
+/* Returns a hash code for P. */
+
+static hashval_t
+hash_ssa_name_by_var (const void *p)
+{
+ const_tree n = (const_tree) p;
+ return (hashval_t) htab_hash_pointer (SSA_NAME_VAR (n));
+}
+
+/* Returns nonzero if P1 and P2 are equal. */
+
+static int
+eq_ssa_name_by_var (const void *p1, const void *p2)
+{
+ const_tree n1 = (const_tree) p1;
+ const_tree n2 = (const_tree) p2;
+ return SSA_NAME_VAR (n1) == SSA_NAME_VAR (n2);
+}
/* Reduce the number of copies by coalescing variables in the function. Return
a partition map with the resulting coalesces. */
@@ -1310,10 +1343,42 @@ coalesce_ssa_name (void)
coalesce_list_p cl;
bitmap used_in_copies = BITMAP_ALLOC (NULL);
var_map map;
+ unsigned int i;
+ static htab_t ssa_name_hash;
cl = create_coalesce_list ();
map = create_outofssa_var_map (cl, used_in_copies);
+ /* We need to coalesce all names originating same SSA_NAME_VAR
+ so debug info remains undisturbed. */
+ if (!optimize)
+ {
+ ssa_name_hash = htab_create (10, hash_ssa_name_by_var,
+ eq_ssa_name_by_var, NULL);
+ for (i = 1; i < num_ssa_names; i++)
+ {
+ tree a = ssa_name (i);
+
+ if (a && SSA_NAME_VAR (a) && !DECL_ARTIFICIAL (SSA_NAME_VAR (a)))
+ {
+ tree *slot = (tree *) htab_find_slot (ssa_name_hash, a, INSERT);
+
+ if (!*slot)
+ *slot = a;
+ else
+ {
+ add_coalesce (cl, SSA_NAME_VERSION (a), SSA_NAME_VERSION (*slot),
+ MUST_COALESCE_COST - 1);
+ bitmap_set_bit (used_in_copies, SSA_NAME_VERSION (a));
+ bitmap_set_bit (used_in_copies, SSA_NAME_VERSION (*slot));
+ }
+ }
+ }
+ htab_delete (ssa_name_hash);
+ }
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ dump_var_map (dump_file, map);
+
/* Don't calculate live ranges for variables not in the coalesce list. */
partition_view_bitmap (map, used_in_copies, true);
BITMAP_FREE (used_in_copies);
@@ -1387,4 +1452,3 @@ coalesce_ssa_name (void)
return map;
}
-
diff --git a/gcc/tree-ssa-copy.c b/gcc/tree-ssa-copy.c
index bc8a874eeda..c228725e59e 100644
--- a/gcc/tree-ssa-copy.c
+++ b/gcc/tree-ssa-copy.c
@@ -184,6 +184,55 @@ may_propagate_copy (tree dest, tree orig)
return true;
}
+/* Like may_propagate_copy, but use as the destination expression
+ the principal expression (typically, the RHS) contained in
+ statement DEST. This is more efficient when working with the
+ gimple tuples representation. */
+
+bool
+may_propagate_copy_into_stmt (gimple dest, tree orig)
+{
+ tree type_d;
+ tree type_o;
+
+ /* If the statement is a switch or a single-rhs assignment,
+ then the expression to be replaced by the propagation may
+ be an SSA_NAME. Fortunately, there is an explicit tree
+ for the expression, so we delegate to may_propagate_copy. */
+
+ if (gimple_assign_single_p (dest))
+ return may_propagate_copy (gimple_assign_rhs1 (dest), orig);
+ else if (gimple_code (dest) == GIMPLE_SWITCH)
+ return may_propagate_copy (gimple_switch_index (dest), orig);
+
+ /* In other cases, the expression is not materialized, so there
+ is no destination to pass to may_propagate_copy. On the other
+ hand, the expression cannot be an SSA_NAME, so the analysis
+ is much simpler. */
+
+ if (TREE_CODE (orig) == SSA_NAME
+ && (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (orig)
+ || TREE_CODE (SSA_NAME_VAR (orig)) == MEMORY_PARTITION_TAG))
+ return false;
+
+ if (is_gimple_assign (dest))
+ type_d = TREE_TYPE (gimple_assign_lhs (dest));
+ else if (gimple_code (dest) == GIMPLE_COND)
+ type_d = boolean_type_node;
+ else if (is_gimple_call (dest)
+ && gimple_call_lhs (dest) != NULL_TREE)
+ type_d = TREE_TYPE (gimple_call_lhs (dest));
+ else
+ gcc_unreachable ();
+
+ type_o = TREE_TYPE (orig);
+
+ if (!useless_type_conversion_p (type_d, type_o))
+ return false;
+
+ return true;
+}
+
/* Similarly, but we know that we're propagating into an ASM_EXPR. */
bool
@@ -303,7 +352,7 @@ merge_alias_info (tree orig_name, tree new_name)
static void
replace_exp_1 (use_operand_p op_p, tree val,
- bool for_propagation ATTRIBUTE_UNUSED)
+ bool for_propagation ATTRIBUTE_UNUSED)
{
tree op = USE_FROM_PTR (op_p);
@@ -337,6 +386,18 @@ propagate_value (use_operand_p op_p, tree val)
replace_exp_1 (op_p, val, true);
}
+/* Replace *OP_P with value VAL (assumed to be a constant or another SSA_NAME).
+
+ Use this version when not const/copy propagating values. For example,
+ PRE uses this version when building expressions as they would appear
+ in specific blocks taking into account actions of PHI nodes. */
+
+void
+replace_exp (use_operand_p op_p, tree val)
+{
+ replace_exp_1 (op_p, val, false);
+}
+
/* Propagate the value VAL (assumed to be a constant or another SSA_NAME)
into the tree pointed to by OP_P.
@@ -351,13 +412,14 @@ propagate_tree_value (tree *op_p, tree val)
{
#if defined ENABLE_CHECKING
gcc_assert (!(TREE_CODE (val) == SSA_NAME
+ && *op_p
&& TREE_CODE (*op_p) == SSA_NAME
&& !may_propagate_copy (*op_p, val)));
#endif
if (TREE_CODE (val) == SSA_NAME)
{
- if (TREE_CODE (*op_p) == SSA_NAME && POINTER_TYPE_P (TREE_TYPE (*op_p)))
+ if (*op_p && TREE_CODE (*op_p) == SSA_NAME && POINTER_TYPE_P (TREE_TYPE (*op_p)))
merge_alias_info (*op_p, val);
*op_p = val;
}
@@ -366,18 +428,52 @@ propagate_tree_value (tree *op_p, tree val)
}
-/* Replace *OP_P with value VAL (assumed to be a constant or another SSA_NAME).
-
- Use this version when not const/copy propagating values. For example,
- PRE uses this version when building expressions as they would appear
- in specific blocks taking into account actions of PHI nodes. */
+/* Like propagate_tree_value, but use as the operand to replace
+ the principal expression (typically, the RHS) contained in the
+ statement referenced by iterator GSI. Note that it is not
+ always possible to update the statement in-place, so a new
+ statement may be created to replace the original. */
void
-replace_exp (use_operand_p op_p, tree val)
+propagate_tree_value_into_stmt (gimple_stmt_iterator *gsi, tree val)
{
- replace_exp_1 (op_p, val, false);
-}
+ gimple stmt = gsi_stmt (*gsi);
+ if (is_gimple_assign (stmt))
+ {
+ tree expr = NULL_TREE;
+ if (gimple_assign_single_p (stmt))
+ expr = gimple_assign_rhs1 (stmt);
+ propagate_tree_value (&expr, val);
+ gimple_assign_set_rhs_from_tree (gsi, expr);
+ stmt = gsi_stmt (*gsi);
+ }
+ else if (gimple_code (stmt) == GIMPLE_COND)
+ {
+ tree lhs = NULL_TREE;
+ tree rhs = fold_convert (TREE_TYPE (val), integer_zero_node);
+ propagate_tree_value (&lhs, val);
+ gimple_cond_set_code (stmt, NE_EXPR);
+ gimple_cond_set_lhs (stmt, lhs);
+ gimple_cond_set_rhs (stmt, rhs);
+ }
+ else if (is_gimple_call (stmt)
+ && gimple_call_lhs (stmt) != NULL_TREE)
+ {
+ gimple new_stmt;
+
+ tree expr = NULL_TREE;
+ propagate_tree_value (&expr, val);
+ new_stmt = gimple_build_assign (gimple_call_lhs (stmt), expr);
+ copy_virtual_operands (new_stmt, stmt);
+ move_ssa_defining_stmt_for_defs (new_stmt, stmt);
+ gsi_replace (gsi, new_stmt, false);
+ }
+ else if (gimple_code (stmt) == GIMPLE_SWITCH)
+ propagate_tree_value (gimple_switch_index_ptr (stmt), val);
+ else
+ gcc_unreachable ();
+}
/*---------------------------------------------------------------------------
Copy propagation
@@ -403,24 +499,17 @@ static tree *cached_last_copy_of;
/* Return true if this statement may generate a useful copy. */
static bool
-stmt_may_generate_copy (tree stmt)
+stmt_may_generate_copy (gimple stmt)
{
- tree lhs, rhs;
- stmt_ann_t ann;
-
- if (TREE_CODE (stmt) == PHI_NODE)
- return !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (PHI_RESULT (stmt));
+ if (gimple_code (stmt) == GIMPLE_PHI)
+ return !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (gimple_phi_result (stmt));
- if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT)
+ if (gimple_code (stmt) != GIMPLE_ASSIGN)
return false;
- lhs = GIMPLE_STMT_OPERAND (stmt, 0);
- rhs = GIMPLE_STMT_OPERAND (stmt, 1);
- ann = stmt_ann (stmt);
-
/* If the statement has volatile operands, it won't generate a
useful copy. */
- if (ann->has_volatile_ops)
+ if (gimple_has_volatile_ops (stmt))
return false;
/* Statements with loads and/or stores will never generate a useful copy. */
@@ -430,8 +519,8 @@ stmt_may_generate_copy (tree stmt)
/* Otherwise, the only statements that generate useful copies are
assignments whose RHS is just an SSA name that doesn't flow
through abnormal edges. */
- return (TREE_CODE (rhs) == SSA_NAME
- && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs));
+ return (gimple_assign_rhs_code (stmt) == SSA_NAME
+ && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (gimple_assign_rhs1 (stmt)));
}
@@ -584,15 +673,16 @@ dump_copy_of (FILE *file, tree var)
all, the names generated will be VUSEd in the same statements. */
static enum ssa_prop_result
-copy_prop_visit_assignment (tree stmt, tree *result_p)
+copy_prop_visit_assignment (gimple stmt, tree *result_p)
{
tree lhs, rhs;
prop_value_t *rhs_val;
- lhs = GIMPLE_STMT_OPERAND (stmt, 0);
- rhs = GIMPLE_STMT_OPERAND (stmt, 1);
+ lhs = gimple_assign_lhs (stmt);
+ rhs = gimple_assign_rhs1 (stmt);
+
- gcc_assert (TREE_CODE (rhs) == SSA_NAME);
+ gcc_assert (gimple_assign_rhs_code (stmt) == SSA_NAME);
rhs_val = get_copy_of_val (rhs);
@@ -620,45 +710,42 @@ copy_prop_visit_assignment (tree stmt, tree *result_p)
}
-/* Visit the COND_EXPR STMT. Return SSA_PROP_INTERESTING
+/* Visit the GIMPLE_COND STMT. Return SSA_PROP_INTERESTING
if it can determine which edge will be taken. Otherwise, return
SSA_PROP_VARYING. */
static enum ssa_prop_result
-copy_prop_visit_cond_stmt (tree stmt, edge *taken_edge_p)
+copy_prop_visit_cond_stmt (gimple stmt, edge *taken_edge_p)
{
- enum ssa_prop_result retval;
- tree cond;
+ enum ssa_prop_result retval = SSA_PROP_VARYING;
- cond = COND_EXPR_COND (stmt);
- retval = SSA_PROP_VARYING;
+ tree op0 = gimple_cond_lhs (stmt);
+ tree op1 = gimple_cond_rhs (stmt);
/* The only conditionals that we may be able to compute statically
are predicates involving two SSA_NAMEs. */
- if (COMPARISON_CLASS_P (cond)
- && TREE_CODE (TREE_OPERAND (cond, 0)) == SSA_NAME
- && TREE_CODE (TREE_OPERAND (cond, 1)) == SSA_NAME)
+ if (TREE_CODE (op0) == SSA_NAME && TREE_CODE (op1) == SSA_NAME)
{
- tree op0 = get_last_copy_of (TREE_OPERAND (cond, 0));
- tree op1 = get_last_copy_of (TREE_OPERAND (cond, 1));
+ op0 = get_last_copy_of (op0);
+ op1 = get_last_copy_of (op1);
/* See if we can determine the predicate's value. */
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "Trying to determine truth value of ");
fprintf (dump_file, "predicate ");
- print_generic_stmt (dump_file, cond, 0);
+ print_gimple_stmt (dump_file, stmt, 0, 0);
}
/* We can fold COND and get a useful result only when we have
the same SSA_NAME on both sides of a comparison operator. */
if (op0 == op1)
{
- tree folded_cond = fold_binary (TREE_CODE (cond), boolean_type_node,
- op0, op1);
+ tree folded_cond = fold_binary (gimple_cond_code (stmt),
+ boolean_type_node, op0, op1);
if (folded_cond)
{
- basic_block bb = bb_for_stmt (stmt);
+ basic_block bb = gimple_bb (stmt);
*taken_edge_p = find_taken_edge (bb, folded_cond);
if (*taken_edge_p)
retval = SSA_PROP_INTERESTING;
@@ -685,26 +772,26 @@ copy_prop_visit_cond_stmt (tree stmt, edge *taken_edge_p)
SSA_PROP_VARYING. */
static enum ssa_prop_result
-copy_prop_visit_stmt (tree stmt, edge *taken_edge_p, tree *result_p)
+copy_prop_visit_stmt (gimple stmt, edge *taken_edge_p, tree *result_p)
{
enum ssa_prop_result retval;
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "\nVisiting statement:\n");
- print_generic_stmt (dump_file, stmt, dump_flags);
+ print_gimple_stmt (dump_file, stmt, 0, dump_flags);
fprintf (dump_file, "\n");
}
- if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT
- && TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 1)) == SSA_NAME
- && TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 0)) == SSA_NAME)
+ if (gimple_assign_single_p (stmt)
+ && TREE_CODE (gimple_assign_lhs (stmt)) == SSA_NAME
+ && TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME)
{
/* If the statement is a copy assignment, evaluate its RHS to
see if the lattice value of its output has changed. */
retval = copy_prop_visit_assignment (stmt, result_p);
}
- else if (TREE_CODE (stmt) == COND_EXPR)
+ else if (gimple_code (stmt) == GIMPLE_COND)
{
/* See if we can determine which edge goes out of a conditional
jump. */
@@ -738,27 +825,26 @@ copy_prop_visit_stmt (tree stmt, edge *taken_edge_p, tree *result_p)
set it to be the value of the LHS of PHI. */
static enum ssa_prop_result
-copy_prop_visit_phi_node (tree phi)
+copy_prop_visit_phi_node (gimple phi)
{
enum ssa_prop_result retval;
- int i;
- tree lhs;
+ unsigned i;
prop_value_t phi_val = { 0, NULL_TREE, NULL_TREE };
- lhs = PHI_RESULT (phi);
+ tree lhs = gimple_phi_result (phi);
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "\nVisiting PHI node: ");
- print_generic_expr (dump_file, phi, dump_flags);
+ print_gimple_stmt (dump_file, phi, 0, dump_flags);
fprintf (dump_file, "\n\n");
}
- for (i = 0; i < PHI_NUM_ARGS (phi); i++)
+ for (i = 0; i < gimple_phi_num_args (phi); i++)
{
prop_value_t *arg_val;
- tree arg = PHI_ARG_DEF (phi, i);
- edge e = PHI_ARG_EDGE (phi, i);
+ tree arg = gimple_phi_arg_def (phi, i);
+ edge e = gimple_phi_arg_edge (phi, i);
/* We don't care about values flowing through non-executable
edges. */
@@ -860,14 +946,14 @@ init_copy_prop (void)
FOR_EACH_BB (bb)
{
- block_stmt_iterator si;
- tree phi, def;
+ gimple_stmt_iterator si;
int depth = bb->loop_depth;
- for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
+ for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
{
- tree stmt = bsi_stmt (si);
+ gimple stmt = gsi_stmt (si);
ssa_op_iter iter;
+ tree def;
/* The only statements that we care about are those that may
generate useful copies. We also need to mark conditional
@@ -880,31 +966,37 @@ init_copy_prop (void)
value was loop invariant, it will be hoisted by LICM and
exposed for copy propagation. */
if (stmt_ends_bb_p (stmt))
- DONT_SIMULATE_AGAIN (stmt) = false;
+ prop_set_simulate_again (stmt, true);
else if (stmt_may_generate_copy (stmt)
- && loop_depth_of_name (GIMPLE_STMT_OPERAND (stmt, 1)) <= depth)
- DONT_SIMULATE_AGAIN (stmt) = false;
+ /* Since we are iterating over the statements in
+ BB, not the phi nodes, STMT will always be an
+ assignment. */
+ && loop_depth_of_name (gimple_assign_rhs1 (stmt)) <= depth)
+ prop_set_simulate_again (stmt, true);
else
- DONT_SIMULATE_AGAIN (stmt) = true;
+ prop_set_simulate_again (stmt, false);
/* Mark all the outputs of this statement as not being
the copy of anything. */
FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_ALL_DEFS)
- if (DONT_SIMULATE_AGAIN (stmt))
+ if (!prop_simulate_again_p (stmt))
set_copy_of_val (def, def);
else
cached_last_copy_of[SSA_NAME_VERSION (def)] = def;
}
- for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
+ for (si = gsi_start_phis (bb); !gsi_end_p (si); gsi_next (&si))
{
- def = PHI_RESULT (phi);
+ gimple phi = gsi_stmt (si);
+ tree def;
+
+ def = gimple_phi_result (phi);
if (!is_gimple_reg (def))
- DONT_SIMULATE_AGAIN (phi) = true;
+ prop_set_simulate_again (phi, false);
else
- DONT_SIMULATE_AGAIN (phi) = false;
+ prop_set_simulate_again (phi, true);
- if (DONT_SIMULATE_AGAIN (phi))
+ if (!prop_simulate_again_p (phi))
set_copy_of_val (def, def);
else
cached_last_copy_of[SSA_NAME_VERSION (def)] = def;
@@ -1084,4 +1176,3 @@ struct gimple_opt_pass pass_copy_prop =
| TODO_update_ssa /* todo_flags_finish */
}
};
-
diff --git a/gcc/tree-ssa-copyrename.c b/gcc/tree-ssa-copyrename.c
index 46b33143cb0..d30e2372e7e 100644
--- a/gcc/tree-ssa-copyrename.c
+++ b/gcc/tree-ssa-copyrename.c
@@ -23,13 +23,14 @@ along with GCC; see the file COPYING3. If not see
#include "coretypes.h"
#include "tm.h"
#include "tree.h"
+#include "gimple.h"
#include "flags.h"
#include "basic-block.h"
#include "function.h"
#include "diagnostic.h"
#include "bitmap.h"
#include "tree-flow.h"
-#include "tree-gimple.h"
+#include "gimple.h"
#include "tree-inline.h"
#include "timevar.h"
#include "hashtab.h"
@@ -300,8 +301,9 @@ rename_ssa_copies (void)
{
var_map map;
basic_block bb;
- block_stmt_iterator bsi;
- tree phi, stmt, var, part_var;
+ gimple_stmt_iterator gsi;
+ tree var, part_var;
+ gimple stmt, phi;
unsigned x;
FILE *debug;
bool updated = false;
@@ -316,16 +318,15 @@ rename_ssa_copies (void)
FOR_EACH_BB (bb)
{
/* Scan for real copies. */
- for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
- stmt = bsi_stmt (bsi);
- if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT)
+ stmt = gsi_stmt (gsi);
+ if (gimple_assign_ssa_name_copy_p (stmt))
{
- tree lhs = GIMPLE_STMT_OPERAND (stmt, 0);
- tree rhs = GIMPLE_STMT_OPERAND (stmt, 1);
+ tree lhs = gimple_assign_lhs (stmt);
+ tree rhs = gimple_assign_rhs1 (stmt);
- if (TREE_CODE (lhs) == SSA_NAME && TREE_CODE (rhs) == SSA_NAME)
- updated |= copy_rename_partition_coalesce (map, lhs, rhs, debug);
+ updated |= copy_rename_partition_coalesce (map, lhs, rhs, debug);
}
}
}
@@ -333,18 +334,21 @@ rename_ssa_copies (void)
FOR_EACH_BB (bb)
{
/* Treat PHI nodes as copies between the result and each argument. */
- for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
+ for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
- int i;
- tree res = PHI_RESULT (phi);
+ size_t i;
+ tree res;
+
+ phi = gsi_stmt (gsi);
+ res = gimple_phi_result (phi);
/* Do not process virtual SSA_NAMES. */
if (!is_gimple_reg (SSA_NAME_VAR (res)))
continue;
- for (i = 0; i < PHI_NUM_ARGS (phi); i++)
+ for (i = 0; i < gimple_phi_num_args (phi); i++)
{
- tree arg = PHI_ARG_DEF (phi, i);
+ tree arg = gimple_phi_arg (phi, i)->def;
if (TREE_CODE (arg) == SSA_NAME)
updated |= copy_rename_partition_coalesce (map, res, arg, debug);
}
@@ -407,4 +411,3 @@ struct gimple_opt_pass pass_rename_ssa_copies =
TODO_dump_func | TODO_verify_ssa /* todo_flags_finish */
}
};
-
diff --git a/gcc/tree-ssa-dce.c b/gcc/tree-ssa-dce.c
index 760e20d14bc..3c750469682 100644
--- a/gcc/tree-ssa-dce.c
+++ b/gcc/tree-ssa-dce.c
@@ -1,5 +1,5 @@
/* Dead code elimination pass for the GNU compiler.
- Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007
+ Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008
Free Software Foundation, Inc.
Contributed by Ben Elliston <bje@redhat.com>
and Andrew MacLeod <amacleod@redhat.com>
@@ -59,14 +59,14 @@ along with GCC; see the file COPYING3. If not see
#include "tree.h"
#include "diagnostic.h"
#include "tree-flow.h"
-#include "tree-gimple.h"
+#include "gimple.h"
#include "tree-dump.h"
#include "tree-pass.h"
#include "timevar.h"
#include "flags.h"
#include "cfgloop.h"
#include "tree-scalar-evolution.h"
-
+
static struct stmt_stats
{
int total;
@@ -75,7 +75,9 @@ static struct stmt_stats
int removed_phis;
} stats;
-static VEC(tree,heap) *worklist;
+#define STMT_NECESSARY GF_PLF_1
+
+static VEC(gimple,heap) *worklist;
/* Vector indicating an SSA name has already been processed and marked
as necessary. */
@@ -196,30 +198,26 @@ find_all_control_dependences (struct edge_list *el)
find_control_dependence (el, i);
}
-
-#define NECESSARY(stmt) stmt->base.asm_written_flag
-
/* If STMT is not already marked necessary, mark it, and add it to the
worklist if ADD_TO_WORKLIST is true. */
static inline void
-mark_stmt_necessary (tree stmt, bool add_to_worklist)
+mark_stmt_necessary (gimple stmt, bool add_to_worklist)
{
gcc_assert (stmt);
- gcc_assert (!DECL_P (stmt));
- if (NECESSARY (stmt))
+ if (gimple_plf (stmt, STMT_NECESSARY))
return;
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "Marking useful stmt: ");
- print_generic_stmt (dump_file, stmt, TDF_SLIM);
+ print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
fprintf (dump_file, "\n");
}
- NECESSARY (stmt) = 1;
+ gimple_set_plf (stmt, STMT_NECESSARY, true);
if (add_to_worklist)
- VEC_safe_push (tree, heap, worklist, stmt);
+ VEC_safe_push (gimple, heap, worklist, stmt);
}
@@ -228,7 +226,7 @@ mark_stmt_necessary (tree stmt, bool add_to_worklist)
static inline void
mark_operand_necessary (tree op)
{
- tree stmt;
+ gimple stmt;
int ver;
gcc_assert (op);
@@ -241,11 +239,11 @@ mark_operand_necessary (tree op)
stmt = SSA_NAME_DEF_STMT (op);
gcc_assert (stmt);
- if (NECESSARY (stmt) || IS_EMPTY_STMT (stmt))
+ if (gimple_plf (stmt, STMT_NECESSARY) || gimple_nop_p (stmt))
return;
- NECESSARY (stmt) = 1;
- VEC_safe_push (tree, heap, worklist, stmt);
+ gimple_set_plf (stmt, STMT_NECESSARY, true);
+ VEC_safe_push (gimple, heap, worklist, stmt);
}
@@ -256,77 +254,76 @@ mark_operand_necessary (tree op)
necessary. */
static void
-mark_stmt_if_obviously_necessary (tree stmt, bool aggressive)
+mark_stmt_if_obviously_necessary (gimple stmt, bool aggressive)
{
- stmt_ann_t ann;
- tree op;
-
+ tree lhs = NULL_TREE;
/* With non-call exceptions, we have to assume that all statements could
throw. If a statement may throw, it is inherently necessary. */
if (flag_non_call_exceptions
- && tree_could_throw_p (stmt))
+ && stmt_could_throw_p (stmt))
{
mark_stmt_necessary (stmt, true);
return;
}
- /* Statements that are implicitly live. Most function calls, asm and return
- statements are required. Labels and BIND_EXPR nodes are kept because
- they are control flow, and we have no way of knowing whether they can be
- removed. DCE can eliminate all the other statements in a block, and CFG
- can then remove the block and labels. */
- switch (TREE_CODE (stmt))
+ /* Statements that are implicitly live. Most function calls, asm
+ and return statements are required. Labels and GIMPLE_BIND nodes
+ are kept because they are control flow, and we have no way of
+ knowing whether they can be removed. DCE can eliminate all the
+ other statements in a block, and CFG can then remove the block
+ and labels. */
+ switch (gimple_code (stmt))
{
- case PREDICT_EXPR:
- case LABEL_EXPR:
- case CASE_LABEL_EXPR:
+ case GIMPLE_PREDICT:
+ case GIMPLE_LABEL:
mark_stmt_necessary (stmt, false);
return;
- case ASM_EXPR:
- case RESX_EXPR:
- case RETURN_EXPR:
- case CHANGE_DYNAMIC_TYPE_EXPR:
+ case GIMPLE_ASM:
+ case GIMPLE_RESX:
+ case GIMPLE_RETURN:
+ case GIMPLE_CHANGE_DYNAMIC_TYPE:
mark_stmt_necessary (stmt, true);
return;
- case CALL_EXPR:
+ case GIMPLE_CALL:
/* Most, but not all function calls are required. Function calls that
produce no result and have no side effects (i.e. const pure
functions) are unnecessary. */
- if (TREE_SIDE_EFFECTS (stmt))
- mark_stmt_necessary (stmt, true);
- return;
-
- case GIMPLE_MODIFY_STMT:
- op = get_call_expr_in (stmt);
- if (op && TREE_SIDE_EFFECTS (op))
+ if (gimple_has_side_effects (stmt))
{
mark_stmt_necessary (stmt, true);
return;
}
-
+ if (!gimple_call_lhs (stmt))
+ return;
+ lhs = gimple_call_lhs (stmt);
+ /* Fall through */
+
+ case GIMPLE_ASSIGN:
+ if (!lhs)
+ lhs = gimple_assign_lhs (stmt);
/* These values are mildly magic bits of the EH runtime. We can't
see the entire lifetime of these values until landing pads are
generated. */
- if (TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 0)) == EXC_PTR_EXPR
- || TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 0)) == FILTER_EXPR)
+ if (TREE_CODE (lhs) == EXC_PTR_EXPR
+ || TREE_CODE (lhs) == FILTER_EXPR)
{
mark_stmt_necessary (stmt, true);
return;
}
break;
- case GOTO_EXPR:
+ case GIMPLE_GOTO:
gcc_assert (!simple_goto_p (stmt));
mark_stmt_necessary (stmt, true);
return;
- case COND_EXPR:
- gcc_assert (EDGE_COUNT (bb_for_stmt (stmt)->succs) == 2);
+ case GIMPLE_COND:
+ gcc_assert (EDGE_COUNT (gimple_bb (stmt)->succs) == 2);
/* Fall through. */
- case SWITCH_EXPR:
+ case GIMPLE_SWITCH:
if (! aggressive)
mark_stmt_necessary (stmt, true);
break;
@@ -335,12 +332,10 @@ mark_stmt_if_obviously_necessary (tree stmt, bool aggressive)
break;
}
- ann = stmt_ann (stmt);
-
/* If the statement has volatile operands, it needs to be preserved.
Same for statements that can alter control flow in unpredictable
ways. */
- if (ann->has_volatile_ops || is_ctrl_altering_stmt (stmt))
+ if (gimple_has_volatile_ops (stmt) || is_ctrl_altering_stmt (stmt))
{
mark_stmt_necessary (stmt, true);
return;
@@ -372,16 +367,16 @@ mark_control_dependent_edges_necessary (basic_block bb, struct edge_list *el)
EXECUTE_IF_CONTROL_DEPENDENT (bi, bb->index, edge_number)
{
- tree t;
+ gimple stmt;
basic_block cd_bb = INDEX_EDGE_PRED_BB (el, edge_number);
if (TEST_BIT (last_stmt_necessary, cd_bb->index))
continue;
SET_BIT (last_stmt_necessary, cd_bb->index);
- t = last_stmt (cd_bb);
- if (t && is_ctrl_stmt (t))
- mark_stmt_necessary (t, true);
+ stmt = last_stmt (cd_bb);
+ if (stmt && is_ctrl_stmt (stmt))
+ mark_stmt_necessary (stmt, true);
}
}
@@ -397,22 +392,24 @@ static void
find_obviously_necessary_stmts (struct edge_list *el)
{
basic_block bb;
- block_stmt_iterator i;
+ gimple_stmt_iterator gsi;
edge e;
+ gimple phi, stmt;
FOR_EACH_BB (bb)
{
- tree phi;
-
/* PHI nodes are never inherently necessary. */
- for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
- NECESSARY (phi) = 0;
+ for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+ {
+ phi = gsi_stmt (gsi);
+ gimple_set_plf (phi, STMT_NECESSARY, false);
+ }
/* Check all statements in the block. */
- for (i = bsi_start (bb); ! bsi_end_p (i); bsi_next (&i))
+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
- tree stmt = bsi_stmt (i);
- NECESSARY (stmt) = 0;
+ stmt = gsi_stmt (gsi);
+ gimple_set_plf (stmt, STMT_NECESSARY, false);
mark_stmt_if_obviously_necessary (stmt, el != NULL);
}
}
@@ -442,21 +439,21 @@ find_obviously_necessary_stmts (struct edge_list *el)
static void
propagate_necessity (struct edge_list *el)
{
- tree stmt;
+ gimple stmt;
bool aggressive = (el ? true : false);
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, "\nProcessing worklist:\n");
- while (VEC_length (tree, worklist) > 0)
+ while (VEC_length (gimple, worklist) > 0)
{
/* Take STMT from worklist. */
- stmt = VEC_pop (tree, worklist);
+ stmt = VEC_pop (gimple, worklist);
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "processing: ");
- print_generic_stmt (dump_file, stmt, TDF_SLIM);
+ print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
fprintf (dump_file, "\n");
}
@@ -465,7 +462,7 @@ propagate_necessity (struct edge_list *el)
/* Mark the last statements of the basic blocks that the block
containing STMT is control dependent on, but only if we haven't
already done so. */
- basic_block bb = bb_for_stmt (stmt);
+ basic_block bb = gimple_bb (stmt);
if (bb != ENTRY_BLOCK_PTR
&& ! TEST_BIT (visited_control_parents, bb->index))
{
@@ -474,7 +471,7 @@ propagate_necessity (struct edge_list *el)
}
}
- if (TREE_CODE (stmt) == PHI_NODE)
+ if (gimple_code (stmt) == GIMPLE_PHI)
{
/* PHI nodes are somewhat special in that each PHI alternative has
data and control dependencies. All the statements feeding the
@@ -482,9 +479,9 @@ propagate_necessity (struct edge_list *el)
we also consider the control dependent edges leading to the
predecessor block associated with each PHI alternative as
necessary. */
- int k;
+ size_t k;
- for (k = 0; k < PHI_NUM_ARGS (stmt); k++)
+ for (k = 0; k < gimple_phi_num_args (stmt); k++)
{
tree arg = PHI_ARG_DEF (stmt, k);
if (TREE_CODE (arg) == SSA_NAME)
@@ -493,9 +490,9 @@ propagate_necessity (struct edge_list *el)
if (aggressive)
{
- for (k = 0; k < PHI_NUM_ARGS (stmt); k++)
+ for (k = 0; k < gimple_phi_num_args (stmt); k++)
{
- basic_block arg_bb = PHI_ARG_EDGE (stmt, k)->src;
+ basic_block arg_bb = gimple_phi_arg_edge (stmt, k)->src;
if (arg_bb != ENTRY_BLOCK_PTR
&& ! TEST_BIT (visited_control_parents, arg_bb->index))
{
@@ -529,35 +526,33 @@ propagate_necessity (struct edge_list *el)
static bool
remove_dead_phis (basic_block bb)
{
- tree prev, phi;
bool something_changed = false;
+ gimple_seq phis;
+ gimple phi;
+ gimple_stmt_iterator gsi;
+ phis = phi_nodes (bb);
- prev = NULL_TREE;
- phi = phi_nodes (bb);
- while (phi)
+ for (gsi = gsi_start (phis); !gsi_end_p (gsi);)
{
stats.total_phis++;
+ phi = gsi_stmt (gsi);
- if (! NECESSARY (phi))
+ if (!gimple_plf (phi, STMT_NECESSARY))
{
- tree next = PHI_CHAIN (phi);
-
something_changed = true;
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "Deleting : ");
- print_generic_stmt (dump_file, phi, TDF_SLIM);
+ print_gimple_stmt (dump_file, phi, 0, TDF_SLIM);
fprintf (dump_file, "\n");
}
- remove_phi_node (phi, prev, true);
+ remove_phi_node (&gsi, true);
stats.removed_phis++;
- phi = next;
}
else
{
- prev = phi;
- phi = PHI_CHAIN (phi);
+ gsi_next (&gsi);
}
}
return something_changed;
@@ -568,14 +563,14 @@ remove_dead_phis (basic_block bb)
containing I so that we don't have to look it up. */
static void
-remove_dead_stmt (block_stmt_iterator *i, basic_block bb)
+remove_dead_stmt (gimple_stmt_iterator *i, basic_block bb)
{
- tree t = bsi_stmt (*i);
+ gimple stmt = gsi_stmt (*i);
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "Deleting : ");
- print_generic_stmt (dump_file, t, TDF_SLIM);
+ print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
fprintf (dump_file, "\n");
}
@@ -587,7 +582,7 @@ remove_dead_stmt (block_stmt_iterator *i, basic_block bb)
immediate post-dominator. The blocks we are circumventing will be
removed by cleanup_tree_cfg if this change in the flow graph makes them
unreachable. */
- if (is_ctrl_stmt (t))
+ if (is_ctrl_stmt (stmt))
{
basic_block post_dom_bb;
@@ -649,8 +644,8 @@ remove_dead_stmt (block_stmt_iterator *i, basic_block bb)
}
}
- bsi_remove (i, true);
- release_defs (t);
+ gsi_remove (i, true);
+ release_defs (stmt);
}
@@ -662,7 +657,9 @@ eliminate_unnecessary_stmts (void)
{
bool something_changed = false;
basic_block bb;
- block_stmt_iterator i;
+ gimple_stmt_iterator gsi;
+ gimple stmt;
+ tree call;
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, "\nEliminating unnecessary statements:\n");
@@ -677,51 +674,56 @@ eliminate_unnecessary_stmts (void)
FOR_EACH_BB (bb)
{
/* Remove dead statements. */
- for (i = bsi_start (bb); ! bsi_end_p (i) ; )
+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi);)
{
- tree t = bsi_stmt (i);
+ stmt = gsi_stmt (gsi);
stats.total++;
- /* If `i' is not necessary then remove it. */
- if (! NECESSARY (t))
+ /* If GSI is not necessary then remove it. */
+ if (!gimple_plf (stmt, STMT_NECESSARY))
{
- remove_dead_stmt (&i, bb);
+ remove_dead_stmt (&gsi, bb);
something_changed = true;
}
- else
+ else if (is_gimple_call (stmt))
{
- tree call = get_call_expr_in (t);
+ call = gimple_call_fndecl (stmt);
if (call)
{
tree name;
+ gimple g;
/* When LHS of var = call (); is dead, simplify it into
call (); saving one operand. */
- if (TREE_CODE (t) == GIMPLE_MODIFY_STMT
- && (TREE_CODE ((name = GIMPLE_STMT_OPERAND (t, 0)))
- == SSA_NAME)
- && !TEST_BIT (processed, SSA_NAME_VERSION (name)))
+ name = gimple_call_lhs (stmt);
+ if (name && TREE_CODE (name) == SSA_NAME
+ && !TEST_BIT (processed, SSA_NAME_VERSION (name)))
{
- tree oldlhs = GIMPLE_STMT_OPERAND (t, 0);
something_changed = true;
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "Deleting LHS of call: ");
- print_generic_stmt (dump_file, t, TDF_SLIM);
+ print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
fprintf (dump_file, "\n");
}
- push_stmt_changes (bsi_stmt_ptr (i));
- TREE_BLOCK (call) = TREE_BLOCK (t);
- bsi_replace (&i, call, false);
- maybe_clean_or_replace_eh_stmt (t, call);
- mark_symbols_for_renaming (call);
- pop_stmt_changes (bsi_stmt_ptr (i));
- release_ssa_name (oldlhs);
+
+ push_stmt_changes (gsi_stmt_ptr (&gsi));
+ g = gimple_copy (stmt);
+ gimple_call_set_lhs (g, NULL_TREE);
+ gsi_replace (&gsi, g, false);
+ maybe_clean_or_replace_eh_stmt (stmt, g);
+ mark_symbols_for_renaming (g);
+ pop_stmt_changes (gsi_stmt_ptr (&gsi));
+ release_ssa_name (name);
}
- notice_special_calls (call);
+ notice_special_calls (stmt);
}
- bsi_next (&i);
+ gsi_next (&gsi);
+ }
+ else
+ {
+ gsi_next (&gsi);
}
}
}
@@ -749,7 +751,7 @@ print_stats (void)
fprintf (dump_file, "Removed %d of %d PHI nodes (%d%%)\n",
stats.removed_phis, stats.total_phis, (int) percg);
}
-
+
/* Initialization for this pass. Set up the used data structures. */
static void
@@ -772,7 +774,7 @@ tree_dce_init (bool aggressive)
processed = sbitmap_alloc (num_ssa_names + 1);
sbitmap_zero (processed);
- worklist = VEC_alloc (tree, heap, 64);
+ worklist = VEC_alloc (gimple, heap, 64);
cfg_altered = false;
}
@@ -795,9 +797,9 @@ tree_dce_done (bool aggressive)
sbitmap_free (processed);
- VEC_free (tree, heap, worklist);
+ VEC_free (gimple, heap, worklist);
}
-
+
/* Main routine to eliminate dead code.
AGGRESSIVE controls the aggressiveness of the algorithm.
diff --git a/gcc/tree-ssa-dom.c b/gcc/tree-ssa-dom.c
index ea99a021fb1..4e7a390d91e 100644
--- a/gcc/tree-ssa-dom.c
+++ b/gcc/tree-ssa-dom.c
@@ -46,6 +46,37 @@ along with GCC; see the file COPYING3. If not see
/* This file implements optimizations on the dominator tree. */
+/* Representation of a "naked" right-hand-side expression, to be used
+ in recording available expressions in the expression hash table. */
+
+enum expr_kind
+{
+ EXPR_SINGLE,
+ EXPR_UNARY,
+ EXPR_BINARY,
+ EXPR_CALL
+};
+
+struct hashable_expr
+{
+ tree type;
+ enum expr_kind kind;
+ union {
+ struct { tree rhs; } single;
+ struct { enum tree_code op; tree opnd; } unary;
+ struct { enum tree_code op; tree opnd0; tree opnd1; } binary;
+ struct { tree fn; bool pure; size_t nargs; tree *args; } call;
+ } ops;
+};
+
+/* Structure for recording known values of a conditional expression
+ at the exits from its block. */
+
+struct cond_equivalence
+{
+ struct hashable_expr cond;
+ tree value;
+};
/* Structure for recording edge equivalences as well as any pending
edge redirections during the dominator optimizer.
@@ -72,11 +103,10 @@ struct edge_info
are true or false. The number of recorded conditions can vary, but
can be determined by the condition's code. So we have an array
and its maximum index rather than use a varray. */
- tree *cond_equivalences;
+ struct cond_equivalence *cond_equivalences;
unsigned int max_cond_equivalences;
};
-
/* Hash table with expressions made available during the renaming process.
When an assignment of the form X_i = EXPR is found, the statement is
stored in this table. If the same expression EXPR is later found on the
@@ -91,7 +121,11 @@ static htab_t avail_exprs;
(null). When we finish processing the block, we pop off entries and
remove the expressions from the global hash table until we hit the
marker. */
-static VEC(tree,heap) *avail_exprs_stack;
+typedef struct expr_hash_elt * expr_hash_elt_t;
+DEF_VEC_P(expr_hash_elt_t);
+DEF_VEC_ALLOC_P(expr_hash_elt_t,heap);
+
+static VEC(expr_hash_elt_t,heap) *avail_exprs_stack;
/* Stack of statements we need to rescan during finalization for newly
exposed variables.
@@ -100,22 +134,13 @@ static VEC(tree,heap) *avail_exprs_stack;
expressions are removed from AVAIL_EXPRS. Else we may change the
hash code for an expression and be unable to find/remove it from
AVAIL_EXPRS. */
-typedef tree *tree_p;
-DEF_VEC_P(tree_p);
-DEF_VEC_ALLOC_P(tree_p,heap);
-
-static VEC(tree_p,heap) *stmts_to_rescan;
+typedef gimple *gimple_p;
+DEF_VEC_P(gimple_p);
+DEF_VEC_ALLOC_P(gimple_p,heap);
-/* Structure for entries in the expression hash table.
+static VEC(gimple_p,heap) *stmts_to_rescan;
- This requires more memory for the hash table entries, but allows us
- to avoid creating silly tree nodes and annotations for conditionals,
- eliminates 2 global hash tables and two block local varrays.
-
- It also allows us to reduce the number of hash table lookups we
- have to perform in lookup_avail_expr and finally it allows us to
- significantly reduce the number of calls into the hashing routine
- itself. */
+/* Structure for entries in the expression hash table. */
struct expr_hash_elt
{
@@ -123,13 +148,17 @@ struct expr_hash_elt
tree lhs;
/* The expression (rhs) we want to record. */
- tree rhs;
+ struct hashable_expr expr;
/* The stmt pointer if this element corresponds to a statement. */
- tree stmt;
+ gimple stmt;
- /* The hash value for RHS/ann. */
+ /* The hash value for RHS. */
hashval_t hash;
+
+ /* A unique stamp, typically the address of the hash
+ element itself, used in removing entries from the table. */
+ struct expr_hash_elt *stamp;
};
/* Stack of dest,src pairs that need to be restored during finalization.
@@ -157,28 +186,22 @@ struct opt_stats_d
static struct opt_stats_d opt_stats;
-struct eq_expr_value
-{
- tree src;
- tree dst;
-};
-
/* Local functions. */
static void optimize_stmt (struct dom_walk_data *,
- basic_block bb,
- block_stmt_iterator);
-static tree lookup_avail_expr (tree, bool);
+ basic_block,
+ gimple_stmt_iterator);
+static tree lookup_avail_expr (gimple, bool);
static hashval_t avail_expr_hash (const void *);
static hashval_t real_avail_expr_hash (const void *);
static int avail_expr_eq (const void *, const void *);
static void htab_statistics (FILE *, htab_t);
-static void record_cond (tree, tree);
+static void record_cond (struct cond_equivalence *);
static void record_const_or_copy (tree, tree);
static void record_equality (tree, tree);
static void record_equivalences_from_phis (basic_block);
static void record_equivalences_from_incoming_edge (basic_block);
-static bool eliminate_redundant_computations (tree);
-static void record_equivalences_from_stmt (tree, int, stmt_ann_t);
+static bool eliminate_redundant_computations (gimple_stmt_iterator *);
+static void record_equivalences_from_stmt (gimple, int);
static void dom_thread_across_edge (struct dom_walk_data *, edge);
static void dom_opt_finalize_block (struct dom_walk_data *, basic_block);
static void dom_opt_initialize_block (struct dom_walk_data *, basic_block);
@@ -188,6 +211,366 @@ static void restore_vars_to_original_value (void);
static edge single_incoming_edge_ignoring_loop_edges (basic_block);
+/* Given a statement STMT, initialize the hash table element pointed to
+ by ELEMENT. */
+
+static void
+initialize_hash_element (gimple stmt, tree lhs,
+ struct expr_hash_elt *element)
+{
+ enum gimple_code code = gimple_code (stmt);
+ struct hashable_expr *expr = &element->expr;
+
+ if (code == GIMPLE_ASSIGN)
+ {
+ enum tree_code subcode = gimple_assign_rhs_code (stmt);
+
+ expr->type = NULL_TREE;
+
+ switch (get_gimple_rhs_class (subcode))
+ {
+ case GIMPLE_SINGLE_RHS:
+ expr->kind = EXPR_SINGLE;
+ expr->ops.single.rhs = gimple_assign_rhs1 (stmt);
+ break;
+ case GIMPLE_UNARY_RHS:
+ expr->kind = EXPR_UNARY;
+ expr->type = TREE_TYPE (gimple_assign_lhs (stmt));
+ expr->ops.unary.op = subcode;
+ expr->ops.unary.opnd = gimple_assign_rhs1 (stmt);
+ break;
+ case GIMPLE_BINARY_RHS:
+ expr->kind = EXPR_BINARY;
+ expr->type = TREE_TYPE (gimple_assign_lhs (stmt));
+ expr->ops.binary.op = subcode;
+ expr->ops.binary.opnd0 = gimple_assign_rhs1 (stmt);
+ expr->ops.binary.opnd1 = gimple_assign_rhs2 (stmt);
+ break;
+ default:
+ gcc_unreachable ();
+ }
+ }
+ else if (code == GIMPLE_COND)
+ {
+ expr->type = boolean_type_node;
+ expr->kind = EXPR_BINARY;
+ expr->ops.binary.op = gimple_cond_code (stmt);
+ expr->ops.binary.opnd0 = gimple_cond_lhs (stmt);
+ expr->ops.binary.opnd1 = gimple_cond_rhs (stmt);
+ }
+ else if (code == GIMPLE_CALL)
+ {
+ size_t nargs = gimple_call_num_args (stmt);
+ size_t i;
+
+ gcc_assert (gimple_call_lhs (stmt));
+
+ expr->type = TREE_TYPE (gimple_call_lhs (stmt));
+ expr->kind = EXPR_CALL;
+ expr->ops.call.fn = gimple_call_fn (stmt);
+
+ if (gimple_call_flags (stmt) & (ECF_CONST | ECF_PURE))
+ expr->ops.call.pure = true;
+ else
+ expr->ops.call.pure = false;
+
+ expr->ops.call.nargs = nargs;
+ expr->ops.call.args = (tree *) xcalloc (nargs, sizeof (tree));
+ for (i = 0; i < nargs; i++)
+ expr->ops.call.args[i] = gimple_call_arg (stmt, i);
+ }
+ else if (code == GIMPLE_SWITCH)
+ {
+ expr->type = TREE_TYPE (gimple_switch_index (stmt));
+ expr->kind = EXPR_SINGLE;
+ expr->ops.single.rhs = gimple_switch_index (stmt);
+ }
+ else if (code == GIMPLE_GOTO)
+ {
+ expr->type = TREE_TYPE (gimple_goto_dest (stmt));
+ expr->kind = EXPR_SINGLE;
+ expr->ops.single.rhs = gimple_goto_dest (stmt);
+ }
+ else
+ gcc_unreachable ();
+
+ element->lhs = lhs;
+ element->stmt = stmt;
+ element->hash = avail_expr_hash (element);
+ element->stamp = element;
+}
+
+/* Given a conditional expression COND as a tree, initialize
+ a hashable_expr expression EXPR. The conditional must be a
+ comparison or logical negation. A constant or a variable is
+ not permitted. */
+
+static void
+initialize_expr_from_cond (tree cond, struct hashable_expr *expr)
+{
+ expr->type = boolean_type_node;
+
+ if (COMPARISON_CLASS_P (cond))
+ {
+ expr->kind = EXPR_BINARY;
+ expr->ops.binary.op = TREE_CODE (cond);
+ expr->ops.binary.opnd0 = TREE_OPERAND (cond, 0);
+ expr->ops.binary.opnd1 = TREE_OPERAND (cond, 1);
+ }
+ else if (TREE_CODE (cond) == TRUTH_NOT_EXPR)
+ {
+ expr->kind = EXPR_UNARY;
+ expr->ops.unary.op = TRUTH_NOT_EXPR;
+ expr->ops.unary.opnd = TREE_OPERAND (cond, 0);
+ }
+ else
+ gcc_unreachable ();
+}
+
+/* Given a hashable_expr expression EXPR and an LHS,
+ initialize the hash table element pointed to by ELEMENT. */
+
+static void
+initialize_hash_element_from_expr (struct hashable_expr *expr,
+ tree lhs,
+ struct expr_hash_elt *element)
+{
+ element->expr = *expr;
+ element->lhs = lhs;
+ element->stmt = NULL;
+ element->hash = avail_expr_hash (element);
+ element->stamp = element;
+}
+
+/* Compare two hashable_expr structures for equivalence.
+ They are considered equivalent when the the expressions
+ they denote must necessarily be equal. The logic is intended
+ to follow that of operand_equal_p in fold-const.c */
+
+static bool
+hashable_expr_equal_p (const struct hashable_expr *expr0,
+ const struct hashable_expr *expr1)
+{
+ tree type0 = expr0->type;
+ tree type1 = expr1->type;
+
+ /* If either type is NULL, there is nothing to check. */
+ if ((type0 == NULL_TREE) ^ (type1 == NULL_TREE))
+ return false;
+
+ /* If both types don't have the same signedness, precision, and mode,
+ then we can't consider them equal. */
+ if (type0 != type1
+ && (TREE_CODE (type0) == ERROR_MARK
+ || TREE_CODE (type1) == ERROR_MARK
+ || TYPE_UNSIGNED (type0) != TYPE_UNSIGNED (type1)
+ || TYPE_PRECISION (type0) != TYPE_PRECISION (type1)
+ || TYPE_MODE (type0) != TYPE_MODE (type1)))
+ return false;
+
+ if (expr0->kind != expr1->kind)
+ return false;
+
+ switch (expr0->kind)
+ {
+ case EXPR_SINGLE:
+ return operand_equal_p (expr0->ops.single.rhs,
+ expr1->ops.single.rhs, 0);
+
+ case EXPR_UNARY:
+ if (expr0->ops.unary.op != expr1->ops.unary.op)
+ return false;
+
+ if ((expr0->ops.unary.op == NOP_EXPR
+ || expr0->ops.unary.op == CONVERT_EXPR
+ || expr0->ops.unary.op == NON_LVALUE_EXPR)
+ && TYPE_UNSIGNED (expr0->type) != TYPE_UNSIGNED (expr1->type))
+ return false;
+
+ return operand_equal_p (expr0->ops.unary.opnd,
+ expr1->ops.unary.opnd, 0);
+
+ case EXPR_BINARY:
+ {
+ if (expr0->ops.binary.op != expr1->ops.binary.op)
+ return false;
+
+ if (operand_equal_p (expr0->ops.binary.opnd0,
+ expr1->ops.binary.opnd0, 0)
+ && operand_equal_p (expr0->ops.binary.opnd1,
+ expr1->ops.binary.opnd1, 0))
+ return true;
+
+ /* For commutative ops, allow the other order. */
+ return (commutative_tree_code (expr0->ops.binary.op)
+ && operand_equal_p (expr0->ops.binary.opnd0,
+ expr1->ops.binary.opnd1, 0)
+ && operand_equal_p (expr0->ops.binary.opnd1,
+ expr1->ops.binary.opnd0, 0));
+ }
+
+ case EXPR_CALL:
+ {
+ size_t i;
+
+ /* If the calls are to different functions, then they
+ clearly cannot be equal. */
+ if (! operand_equal_p (expr0->ops.call.fn,
+ expr1->ops.call.fn, 0))
+ return false;
+
+ if (! expr0->ops.call.pure)
+ return false;
+
+ if (expr0->ops.call.nargs != expr1->ops.call.nargs)
+ return false;
+
+ for (i = 0; i < expr0->ops.call.nargs; i++)
+ if (! operand_equal_p (expr0->ops.call.args[i],
+ expr1->ops.call.args[i], 0))
+ return false;
+
+ return true;
+ }
+
+ default:
+ gcc_unreachable ();
+ }
+}
+
+/* Compute a hash value for a hashable_expr value EXPR and a
+ previously accumulated hash value VAL. If two hashable_expr
+ values compare equal with hashable_expr_equal_p, they must
+ hash to the same value, given an identical value of VAL.
+ The logic is intended to follow iterative_hash_expr in tree.c. */
+
+static hashval_t
+iterative_hash_hashable_expr (const struct hashable_expr *expr, hashval_t val)
+{
+ switch (expr->kind)
+ {
+ case EXPR_SINGLE:
+ val = iterative_hash_expr (expr->ops.single.rhs, val);
+ break;
+
+ case EXPR_UNARY:
+ val = iterative_hash_object (expr->ops.unary.op, val);
+
+ /* Make sure to include signedness in the hash computation.
+ Don't hash the type, that can lead to having nodes which
+ compare equal according to operand_equal_p, but which
+ have different hash codes. */
+ if (expr->ops.unary.op == NOP_EXPR
+ || expr->ops.unary.op == CONVERT_EXPR
+ || expr->ops.unary.op == NON_LVALUE_EXPR)
+ val += TYPE_UNSIGNED (expr->type);
+
+ val = iterative_hash_expr (expr->ops.unary.opnd, val);
+ break;
+
+ case EXPR_BINARY:
+ val = iterative_hash_object (expr->ops.binary.op, val);
+ if (commutative_tree_code (expr->ops.binary.op))
+ val = iterative_hash_exprs_commutative (expr->ops.binary.opnd0,
+ expr->ops.binary.opnd1, val);
+ else
+ {
+ val = iterative_hash_expr (expr->ops.binary.opnd0, val);
+ val = iterative_hash_expr (expr->ops.binary.opnd1, val);
+ }
+ break;
+
+ case EXPR_CALL:
+ {
+ size_t i;
+ enum tree_code code = CALL_EXPR;
+
+ val = iterative_hash_object (code, val);
+ val = iterative_hash_expr (expr->ops.call.fn, val);
+ for (i = 0; i < expr->ops.call.nargs; i++)
+ val = iterative_hash_expr (expr->ops.call.args[i], val);
+ }
+ break;
+
+ default:
+ gcc_unreachable ();
+ }
+
+ return val;
+}
+
+/* Print a diagnostic dump of an expression hash table entry. */
+
+static void
+print_expr_hash_elt (FILE * stream, const struct expr_hash_elt *element)
+{
+ if (element->stmt)
+ fprintf (stream, "STMT ");
+ else
+ fprintf (stream, "COND ");
+
+ if (element->lhs)
+ {
+ print_generic_expr (stream, element->lhs, 0);
+ fprintf (stream, " = ");
+ }
+
+ switch (element->expr.kind)
+ {
+ case EXPR_SINGLE:
+ print_generic_expr (stream, element->expr.ops.single.rhs, 0);
+ break;
+
+ case EXPR_UNARY:
+ fprintf (stream, "%s ", tree_code_name[element->expr.ops.unary.op]);
+ print_generic_expr (stream, element->expr.ops.unary.opnd, 0);
+ break;
+
+ case EXPR_BINARY:
+ print_generic_expr (stream, element->expr.ops.binary.opnd0, 0);
+ fprintf (stream, " %s ", tree_code_name[element->expr.ops.binary.op]);
+ print_generic_expr (stream, element->expr.ops.binary.opnd1, 0);
+ break;
+
+ case EXPR_CALL:
+ {
+ size_t i;
+ size_t nargs = element->expr.ops.call.nargs;
+
+ print_generic_expr (stream, element->expr.ops.call.fn, 0);
+ fprintf (stream, " (");
+ for (i = 0; i < nargs; i++)
+ {
+ print_generic_expr (stream, element->expr.ops.call.args[i], 0);
+ if (i + 1 < nargs)
+ fprintf (stream, ", ");
+ }
+ fprintf (stream, ")");
+ }
+ break;
+ }
+ fprintf (stream, "\n");
+
+ if (element->stmt)
+ {
+ fprintf (stream, " ");
+ print_gimple_stmt (stream, element->stmt, 0, 0);
+ }
+}
+
+/* Delete an expr_hash_elt and reclaim its storage. */
+
+static void
+free_expr_hash_elt (void *elt)
+{
+ struct expr_hash_elt *element = ((struct expr_hash_elt *)elt);
+
+ if (element->expr.kind == EXPR_CALL)
+ free (element->expr.ops.call.args);
+
+ free (element);
+}
+
/* Allocate an EDGE_INFO for edge E and attach it to E.
Return the new EDGE_INFO structure. */
@@ -247,10 +630,10 @@ tree_ssa_dominator_optimize (void)
memset (&opt_stats, 0, sizeof (opt_stats));
/* Create our hash tables. */
- avail_exprs = htab_create (1024, real_avail_expr_hash, avail_expr_eq, free);
- avail_exprs_stack = VEC_alloc (tree, heap, 20);
+ avail_exprs = htab_create (1024, real_avail_expr_hash, avail_expr_eq, free_expr_hash_elt);
+ avail_exprs_stack = VEC_alloc (expr_hash_elt_t, heap, 20);
const_and_copies_stack = VEC_alloc (tree, heap, 20);
- stmts_to_rescan = VEC_alloc (tree_p, heap, 20);
+ stmts_to_rescan = VEC_alloc (gimple_p, heap, 20);
need_eh_cleanup = BITMAP_ALLOC (NULL);
/* Setup callbacks for the generic dominator tree walker. */
@@ -291,12 +674,11 @@ tree_ssa_dominator_optimize (void)
walk_dominator_tree (&walk_data, ENTRY_BLOCK_PTR);
{
- block_stmt_iterator bsi;
+ gimple_stmt_iterator gsi;
basic_block bb;
FOR_EACH_BB (bb)
- {
- for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
- update_stmt_if_modified (bsi_stmt (bsi));
+ {for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+ update_stmt_if_modified (gsi_stmt (gsi));
}
}
@@ -336,7 +718,7 @@ tree_ssa_dominator_optimize (void)
}
}
- tree_purge_all_dead_eh_edges (need_eh_cleanup);
+ gimple_purge_all_dead_eh_edges (need_eh_cleanup);
bitmap_zero (need_eh_cleanup);
}
@@ -379,9 +761,10 @@ tree_ssa_dominator_optimize (void)
/* Free asserted bitmaps and stacks. */
BITMAP_FREE (need_eh_cleanup);
- VEC_free (tree, heap, avail_exprs_stack);
+ VEC_free (expr_hash_elt_t, heap, avail_exprs_stack);
VEC_free (tree, heap, const_and_copies_stack);
- VEC_free (tree_p, heap, stmts_to_rescan);
+ VEC_free (gimple_p, heap, stmts_to_rescan);
+
return 0;
}
@@ -414,22 +797,22 @@ struct gimple_opt_pass pass_dominator =
};
-/* Given a stmt CONDSTMT containing a COND_EXPR, canonicalize the
- COND_EXPR into a canonical form. */
+/* Given a conditional statement CONDSTMT, convert the
+ condition to a canonical form. */
static void
-canonicalize_comparison (tree condstmt)
+canonicalize_comparison (gimple condstmt)
{
- tree cond = COND_EXPR_COND (condstmt);
tree op0;
tree op1;
- enum tree_code code = TREE_CODE (cond);
+ enum tree_code code;
- if (!COMPARISON_CLASS_P (cond))
- return;
+ gcc_assert (gimple_code (condstmt) == GIMPLE_COND);
- op0 = TREE_OPERAND (cond, 0);
- op1 = TREE_OPERAND (cond, 1);
+ op0 = gimple_cond_lhs (condstmt);
+ op1 = gimple_cond_rhs (condstmt);
+
+ code = gimple_cond_code (condstmt);
/* If it would be profitable to swap the operands, then do so to
canonicalize the statement, enabling better optimization.
@@ -446,17 +829,13 @@ canonicalize_comparison (tree condstmt)
|| code == LE_EXPR
|| code == GE_EXPR)
{
- TREE_SET_CODE (cond, swap_tree_comparison (code));
- swap_tree_operands (condstmt,
- &TREE_OPERAND (cond, 0),
- &TREE_OPERAND (cond, 1));
- /* If one operand was in the operand cache, but the other is
- not, because it is a constant, this is a case that the
- internal updating code of swap_tree_operands can't handle
- properly. */
- if (TREE_CODE_CLASS (TREE_CODE (op0))
- != TREE_CODE_CLASS (TREE_CODE (op1)))
- update_stmt (condstmt);
+ code = swap_tree_comparison (code);
+
+ gimple_cond_set_code (condstmt, code);
+ gimple_cond_set_lhs (condstmt, op1);
+ gimple_cond_set_rhs (condstmt, op0);
+
+ update_stmt (condstmt);
}
}
}
@@ -474,7 +853,7 @@ dom_opt_initialize_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
/* Push a marker on the stacks of local information so that we know how
far to unwind when we finalize this block. */
- VEC_safe_push (tree, heap, avail_exprs_stack, NULL_TREE);
+ VEC_safe_push (expr_hash_elt_t, heap, avail_exprs_stack, NULL);
VEC_safe_push (tree, heap, const_and_copies_stack, NULL_TREE);
record_equivalences_from_incoming_edge (bb);
@@ -483,52 +862,6 @@ dom_opt_initialize_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
record_equivalences_from_phis (bb);
}
-/* Given an expression EXPR (a relational expression or a statement),
- initialize the hash table element pointed to by ELEMENT. */
-
-static void
-initialize_hash_element (tree expr, tree lhs, struct expr_hash_elt *element)
-{
- /* Hash table elements may be based on conditional expressions or statements.
-
- For the former case, we have no annotation and we want to hash the
- conditional expression. In the latter case we have an annotation and
- we want to record the expression the statement evaluates. */
- if (COMPARISON_CLASS_P (expr) || TREE_CODE (expr) == TRUTH_NOT_EXPR)
- {
- element->stmt = NULL;
- element->rhs = expr;
- }
- else if (TREE_CODE (expr) == COND_EXPR)
- {
- element->stmt = expr;
- element->rhs = COND_EXPR_COND (expr);
- }
- else if (TREE_CODE (expr) == SWITCH_EXPR)
- {
- element->stmt = expr;
- element->rhs = SWITCH_COND (expr);
- }
- else if (TREE_CODE (expr) == RETURN_EXPR && TREE_OPERAND (expr, 0))
- {
- element->stmt = expr;
- element->rhs = GIMPLE_STMT_OPERAND (TREE_OPERAND (expr, 0), 1);
- }
- else if (TREE_CODE (expr) == GOTO_EXPR)
- {
- element->stmt = expr;
- element->rhs = GOTO_DESTINATION (expr);
- }
- else
- {
- element->stmt = expr;
- element->rhs = GENERIC_TREE_OPERAND (expr, 1);
- }
-
- element->lhs = lhs;
- element->hash = avail_expr_hash (element);
-}
-
/* Remove all the expressions in LOCALS from TABLE, stopping when there are
LIMIT entries left in LOCALs. */
@@ -536,15 +869,25 @@ static void
remove_local_expressions_from_table (void)
{
/* Remove all the expressions made available in this block. */
- while (VEC_length (tree, avail_exprs_stack) > 0)
+ while (VEC_length (expr_hash_elt_t, avail_exprs_stack) > 0)
{
struct expr_hash_elt element;
- tree expr = VEC_pop (tree, avail_exprs_stack);
+ expr_hash_elt_t victim = VEC_pop (expr_hash_elt_t, avail_exprs_stack);
- if (expr == NULL_TREE)
+ if (victim == NULL)
break;
- initialize_hash_element (expr, NULL, &element);
+ element = *victim;
+
+ /* This must precede the actual removal from the hash table,
+ as ELEMENT and the table entry may share a call argument
+ vector which will be freed during removal. */
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "<<<< ");
+ print_expr_hash_elt (dump_file, &element);
+ }
+
htab_remove_elt_with_hash (avail_exprs, &element, element.hash);
}
}
@@ -565,6 +908,15 @@ restore_vars_to_original_value (void)
if (dest == NULL)
break;
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "<<<< COPY ");
+ print_generic_expr (dump_file, dest, 0);
+ fprintf (dump_file, " = ");
+ print_generic_expr (dump_file, SSA_NAME_VALUE (dest), 0);
+ fprintf (dump_file, "\n");
+ }
+
prev_value = VEC_pop (tree, const_and_copies_stack);
SSA_NAME_VALUE (dest) = prev_value;
}
@@ -573,7 +925,8 @@ restore_vars_to_original_value (void)
/* A trivial wrapper so that we can present the generic jump
threading code with a simple API for simplifying statements. */
static tree
-simplify_stmt_for_jump_threading (tree stmt, tree within_stmt ATTRIBUTE_UNUSED)
+simplify_stmt_for_jump_threading (gimple stmt,
+ gimple within_stmt ATTRIBUTE_UNUSED)
{
return lookup_avail_expr (stmt, false);
}
@@ -585,16 +938,16 @@ simplify_stmt_for_jump_threading (tree stmt, tree within_stmt ATTRIBUTE_UNUSED)
static void
dom_thread_across_edge (struct dom_walk_data *walk_data, edge e)
{
- /* If we don't already have a dummy condition, build it now. */
if (! walk_data->global_data)
- {
- tree dummy_cond = build2 (NE_EXPR, boolean_type_node,
- integer_zero_node, integer_zero_node);
- dummy_cond = build3 (COND_EXPR, void_type_node, dummy_cond, NULL, NULL);
- walk_data->global_data = dummy_cond;
- }
+ {
+ gimple dummy_cond =
+ gimple_build_cond (NE_EXPR,
+ integer_zero_node, integer_zero_node,
+ NULL, NULL);
+ walk_data->global_data = dummy_cond;
+ }
- thread_across_edge ((tree) walk_data->global_data, e, false,
+ thread_across_edge ((gimple) walk_data->global_data, e, false,
&const_and_copies_stack,
simplify_stmt_for_jump_threading);
}
@@ -606,8 +959,7 @@ dom_thread_across_edge (struct dom_walk_data *walk_data, edge e)
static void
dom_opt_finalize_block (struct dom_walk_data *walk_data, basic_block bb)
{
- tree last;
-
+ gimple last;
/* If we have an outgoing edge to a block with multiple incoming and
outgoing edges, then we may be able to thread the edge, i.e., we
@@ -620,9 +972,7 @@ dom_opt_finalize_block (struct dom_walk_data *walk_data, basic_block bb)
dom_thread_across_edge (walk_data, single_succ_edge (bb));
}
else if ((last = last_stmt (bb))
- && TREE_CODE (last) == COND_EXPR
- && (COMPARISON_CLASS_P (COND_EXPR_COND (last))
- || TREE_CODE (COND_EXPR_COND (last)) == SSA_NAME)
+ && gimple_code (last) == GIMPLE_COND
&& EDGE_COUNT (bb->succs) == 2
&& (EDGE_SUCC (bb, 0)->flags & EDGE_ABNORMAL) == 0
&& (EDGE_SUCC (bb, 1)->flags & EDGE_ABNORMAL) == 0)
@@ -641,33 +991,28 @@ dom_opt_finalize_block (struct dom_walk_data *walk_data, basic_block bb)
/* Push a marker onto the available expression stack so that we
unwind any expressions related to the TRUE arm before processing
the false arm below. */
- VEC_safe_push (tree, heap, avail_exprs_stack, NULL_TREE);
+ VEC_safe_push (expr_hash_elt_t, heap, avail_exprs_stack, NULL);
VEC_safe_push (tree, heap, const_and_copies_stack, NULL_TREE);
edge_info = (struct edge_info *) true_edge->aux;
/* If we have info associated with this edge, record it into
- our equivalency tables. */
+ our equivalence tables. */
if (edge_info)
{
- tree *cond_equivalences = edge_info->cond_equivalences;
+ struct cond_equivalence *cond_equivalences = edge_info->cond_equivalences;
tree lhs = edge_info->lhs;
tree rhs = edge_info->rhs;
- /* If we have a simple NAME = VALUE equivalency record it. */
+ /* If we have a simple NAME = VALUE equivalence, record it. */
if (lhs && TREE_CODE (lhs) == SSA_NAME)
record_const_or_copy (lhs, rhs);
/* If we have 0 = COND or 1 = COND equivalences, record them
into our expression hash tables. */
if (cond_equivalences)
- for (i = 0; i < edge_info->max_cond_equivalences; i += 2)
- {
- tree expr = cond_equivalences[i];
- tree value = cond_equivalences[i + 1];
-
- record_cond (expr, value);
- }
+ for (i = 0; i < edge_info->max_cond_equivalences; i++)
+ record_cond (&cond_equivalences[i]);
}
dom_thread_across_edge (walk_data, true_edge);
@@ -687,27 +1032,22 @@ dom_opt_finalize_block (struct dom_walk_data *walk_data, basic_block bb)
edge_info = (struct edge_info *) false_edge->aux;
/* If we have info associated with this edge, record it into
- our equivalency tables. */
+ our equivalence tables. */
if (edge_info)
{
- tree *cond_equivalences = edge_info->cond_equivalences;
+ struct cond_equivalence *cond_equivalences = edge_info->cond_equivalences;
tree lhs = edge_info->lhs;
tree rhs = edge_info->rhs;
- /* If we have a simple NAME = VALUE equivalency record it. */
+ /* If we have a simple NAME = VALUE equivalence, record it. */
if (lhs && TREE_CODE (lhs) == SSA_NAME)
record_const_or_copy (lhs, rhs);
/* If we have 0 = COND or 1 = COND equivalences, record them
into our expression hash tables. */
if (cond_equivalences)
- for (i = 0; i < edge_info->max_cond_equivalences; i += 2)
- {
- tree expr = cond_equivalences[i];
- tree value = cond_equivalences[i + 1];
-
- record_cond (expr, value);
- }
+ for (i = 0; i < edge_info->max_cond_equivalences; i++)
+ record_cond (&cond_equivalences[i]);
}
/* Now thread the edge. */
@@ -724,16 +1064,16 @@ dom_opt_finalize_block (struct dom_walk_data *walk_data, basic_block bb)
/* If we queued any statements to rescan in this block, then
go ahead and rescan them now. */
- while (VEC_length (tree_p, stmts_to_rescan) > 0)
+ while (VEC_length (gimple_p, stmts_to_rescan) > 0)
{
- tree *stmt_p = VEC_last (tree_p, stmts_to_rescan);
- tree stmt = *stmt_p;
- basic_block stmt_bb = bb_for_stmt (stmt);
+ gimple *stmt_p = VEC_last (gimple_p, stmts_to_rescan);
+ gimple stmt = *stmt_p;
+ basic_block stmt_bb = gimple_bb (stmt);
if (stmt_bb != bb)
break;
- VEC_pop (tree_p, stmts_to_rescan);
+ VEC_pop (gimple_p, stmts_to_rescan);
pop_stmt_changes (stmt_p);
}
}
@@ -747,17 +1087,19 @@ dom_opt_finalize_block (struct dom_walk_data *walk_data, basic_block bb)
static void
record_equivalences_from_phis (basic_block bb)
{
- tree phi;
-
- for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
+ gimple_stmt_iterator gsi;
+
+ for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
- tree lhs = PHI_RESULT (phi);
+ gimple phi = gsi_stmt (gsi);
+
+ tree lhs = gimple_phi_result (phi);
tree rhs = NULL;
- int i;
+ size_t i;
- for (i = 0; i < PHI_NUM_ARGS (phi); i++)
+ for (i = 0; i < gimple_phi_num_args (phi); i++)
{
- tree t = PHI_ARG_DEF (phi, i);
+ tree t = gimple_phi_arg_def (phi, i);
/* Ignore alternatives which are the same as our LHS. Since
LHS is a PHI_RESULT, it is known to be a SSA_NAME, so we
@@ -787,8 +1129,7 @@ record_equivalences_from_phis (basic_block bb)
this, since this is a true assignment and not an equivalence
inferred from a comparison. All uses of this ssa name are dominated
by this assignment, so unwinding just costs time and space. */
- if (i == PHI_NUM_ARGS (phi)
- && may_propagate_copy (lhs, rhs))
+ if (i == gimple_phi_num_args (phi) && may_propagate_copy (lhs, rhs))
SSA_NAME_VALUE (lhs) = rhs;
}
}
@@ -851,21 +1192,14 @@ record_equivalences_from_incoming_edge (basic_block bb)
{
tree lhs = edge_info->lhs;
tree rhs = edge_info->rhs;
- tree *cond_equivalences = edge_info->cond_equivalences;
+ struct cond_equivalence *cond_equivalences = edge_info->cond_equivalences;
if (lhs)
record_equality (lhs, rhs);
if (cond_equivalences)
- {
- for (i = 0; i < edge_info->max_cond_equivalences; i += 2)
- {
- tree expr = cond_equivalences[i];
- tree value = cond_equivalences[i + 1];
-
- record_cond (expr, value);
- }
- }
+ for (i = 0; i < edge_info->max_cond_equivalences; i++)
+ record_cond (&cond_equivalences[i]);
}
}
}
@@ -907,38 +1241,56 @@ htab_statistics (FILE *file, htab_t htab)
htab_collisions (htab));
}
-/* Enter a statement into the true/false expression hash table indicating
- that the condition COND has the value VALUE. */
+
+/* Enter condition equivalence into the expression hash table.
+ This indicates that a conditional expression has a known
+ boolean value. */
static void
-record_cond (tree cond, tree value)
+record_cond (struct cond_equivalence *p)
{
struct expr_hash_elt *element = XCNEW (struct expr_hash_elt);
void **slot;
- initialize_hash_element (cond, value, element);
+ initialize_hash_element_from_expr (&p->cond, p->value, element);
slot = htab_find_slot_with_hash (avail_exprs, (void *)element,
element->hash, INSERT);
if (*slot == NULL)
{
*slot = (void *) element;
- VEC_safe_push (tree, heap, avail_exprs_stack, cond);
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "1>>> ");
+ print_expr_hash_elt (dump_file, element);
+ }
+
+ VEC_safe_push (expr_hash_elt_t, heap, avail_exprs_stack, element);
}
else
free (element);
}
-/* Build a new conditional using NEW_CODE, OP0 and OP1 and store
- the new conditional into *p, then store a boolean_true_node
- into *(p + 1). */
+/* Build a cond_equivalence record indicating that the comparison
+ CODE holds between operands OP0 and OP1. */
static void
-build_and_record_new_cond (enum tree_code new_code, tree op0, tree op1, tree *p)
+build_and_record_new_cond (enum tree_code code,
+ tree op0, tree op1,
+ struct cond_equivalence *p)
{
- *p = build2 (new_code, boolean_type_node, op0, op1);
- p++;
- *p = boolean_true_node;
+ struct hashable_expr *cond = &p->cond;
+
+ gcc_assert (TREE_CODE_CLASS (code) == tcc_comparison);
+
+ cond->type = boolean_type_node;
+ cond->kind = EXPR_BINARY;
+ cond->ops.binary.op = code;
+ cond->ops.binary.opnd0 = op0;
+ cond->ops.binary.opnd1 = op1;
+
+ p->value = boolean_true_node;
}
/* Record that COND is true and INVERTED is false into the edge information
@@ -964,119 +1316,125 @@ record_conditions (struct edge_info *edge_info, tree cond, tree inverted)
case GT_EXPR:
if (FLOAT_TYPE_P (TREE_TYPE (op0)))
{
- edge_info->max_cond_equivalences = 12;
- edge_info->cond_equivalences = XNEWVEC (tree, 12);
+ edge_info->max_cond_equivalences = 6;
+ edge_info->cond_equivalences = XNEWVEC (struct cond_equivalence, 6);
build_and_record_new_cond (ORDERED_EXPR, op0, op1,
- &edge_info->cond_equivalences[8]);
+ &edge_info->cond_equivalences[4]);
build_and_record_new_cond (LTGT_EXPR, op0, op1,
- &edge_info->cond_equivalences[10]);
+ &edge_info->cond_equivalences[5]);
}
else
- {
- edge_info->max_cond_equivalences = 8;
- edge_info->cond_equivalences = XNEWVEC (tree, 8);
+ {
+ edge_info->max_cond_equivalences = 4;
+ edge_info->cond_equivalences = XNEWVEC (struct cond_equivalence, 4);
}
build_and_record_new_cond ((TREE_CODE (cond) == LT_EXPR
? LE_EXPR : GE_EXPR),
- op0, op1, &edge_info->cond_equivalences[4]);
+ op0, op1, &edge_info->cond_equivalences[2]);
build_and_record_new_cond (NE_EXPR, op0, op1,
- &edge_info->cond_equivalences[6]);
+ &edge_info->cond_equivalences[3]);
break;
case GE_EXPR:
case LE_EXPR:
if (FLOAT_TYPE_P (TREE_TYPE (op0)))
{
- edge_info->max_cond_equivalences = 6;
- edge_info->cond_equivalences = XNEWVEC (tree, 6);
+ edge_info->max_cond_equivalences = 3;
+ edge_info->cond_equivalences = XNEWVEC (struct cond_equivalence, 3);
build_and_record_new_cond (ORDERED_EXPR, op0, op1,
- &edge_info->cond_equivalences[4]);
+ &edge_info->cond_equivalences[2]);
}
else
{
- edge_info->max_cond_equivalences = 4;
- edge_info->cond_equivalences = XNEWVEC (tree, 4);
+ edge_info->max_cond_equivalences = 2;
+ edge_info->cond_equivalences = XNEWVEC (struct cond_equivalence, 2);
}
break;
case EQ_EXPR:
if (FLOAT_TYPE_P (TREE_TYPE (op0)))
{
- edge_info->max_cond_equivalences = 10;
- edge_info->cond_equivalences = XNEWVEC (tree, 10);
+ edge_info->max_cond_equivalences = 5;
+ edge_info->cond_equivalences = XNEWVEC (struct cond_equivalence, 5);
build_and_record_new_cond (ORDERED_EXPR, op0, op1,
- &edge_info->cond_equivalences[8]);
+ &edge_info->cond_equivalences[4]);
}
else
{
- edge_info->max_cond_equivalences = 8;
- edge_info->cond_equivalences = XNEWVEC (tree, 8);
+ edge_info->max_cond_equivalences = 4;
+ edge_info->cond_equivalences = XNEWVEC (struct cond_equivalence, 4);
}
build_and_record_new_cond (LE_EXPR, op0, op1,
- &edge_info->cond_equivalences[4]);
+ &edge_info->cond_equivalences[2]);
build_and_record_new_cond (GE_EXPR, op0, op1,
- &edge_info->cond_equivalences[6]);
+ &edge_info->cond_equivalences[3]);
break;
case UNORDERED_EXPR:
- edge_info->max_cond_equivalences = 16;
- edge_info->cond_equivalences = XNEWVEC (tree, 16);
+ edge_info->max_cond_equivalences = 8;
+ edge_info->cond_equivalences = XNEWVEC (struct cond_equivalence, 8);
build_and_record_new_cond (NE_EXPR, op0, op1,
- &edge_info->cond_equivalences[4]);
+ &edge_info->cond_equivalences[2]);
build_and_record_new_cond (UNLE_EXPR, op0, op1,
- &edge_info->cond_equivalences[6]);
+ &edge_info->cond_equivalences[3]);
build_and_record_new_cond (UNGE_EXPR, op0, op1,
- &edge_info->cond_equivalences[8]);
+ &edge_info->cond_equivalences[4]);
build_and_record_new_cond (UNEQ_EXPR, op0, op1,
- &edge_info->cond_equivalences[10]);
+ &edge_info->cond_equivalences[5]);
build_and_record_new_cond (UNLT_EXPR, op0, op1,
- &edge_info->cond_equivalences[12]);
+ &edge_info->cond_equivalences[6]);
build_and_record_new_cond (UNGT_EXPR, op0, op1,
- &edge_info->cond_equivalences[14]);
+ &edge_info->cond_equivalences[7]);
break;
case UNLT_EXPR:
case UNGT_EXPR:
- edge_info->max_cond_equivalences = 8;
- edge_info->cond_equivalences = XNEWVEC (tree, 8);
+ edge_info->max_cond_equivalences = 4;
+ edge_info->cond_equivalences = XNEWVEC (struct cond_equivalence, 4);
build_and_record_new_cond ((TREE_CODE (cond) == UNLT_EXPR
? UNLE_EXPR : UNGE_EXPR),
- op0, op1, &edge_info->cond_equivalences[4]);
+ op0, op1, &edge_info->cond_equivalences[2]);
build_and_record_new_cond (NE_EXPR, op0, op1,
- &edge_info->cond_equivalences[6]);
+ &edge_info->cond_equivalences[3]);
break;
case UNEQ_EXPR:
- edge_info->max_cond_equivalences = 8;
- edge_info->cond_equivalences = XNEWVEC (tree, 8);
+ edge_info->max_cond_equivalences = 4;
+ edge_info->cond_equivalences = XNEWVEC (struct cond_equivalence, 4);
build_and_record_new_cond (UNLE_EXPR, op0, op1,
- &edge_info->cond_equivalences[4]);
+ &edge_info->cond_equivalences[2]);
build_and_record_new_cond (UNGE_EXPR, op0, op1,
- &edge_info->cond_equivalences[6]);
+ &edge_info->cond_equivalences[3]);
break;
case LTGT_EXPR:
- edge_info->max_cond_equivalences = 8;
- edge_info->cond_equivalences = XNEWVEC (tree, 8);
+ edge_info->max_cond_equivalences = 4;
+ edge_info->cond_equivalences = XNEWVEC (struct cond_equivalence, 4);
build_and_record_new_cond (NE_EXPR, op0, op1,
- &edge_info->cond_equivalences[4]);
+ &edge_info->cond_equivalences[2]);
build_and_record_new_cond (ORDERED_EXPR, op0, op1,
- &edge_info->cond_equivalences[6]);
+ &edge_info->cond_equivalences[3]);
break;
default:
- edge_info->max_cond_equivalences = 4;
- edge_info->cond_equivalences = XNEWVEC (tree, 4);
+ edge_info->max_cond_equivalences = 2;
+ edge_info->cond_equivalences = XNEWVEC (struct cond_equivalence, 2);
break;
}
/* Now store the original true and false conditions into the first
two slots. */
- edge_info->cond_equivalences[0] = cond;
- edge_info->cond_equivalences[1] = boolean_true_node;
- edge_info->cond_equivalences[2] = inverted;
- edge_info->cond_equivalences[3] = boolean_false_node;
+ initialize_expr_from_cond (cond, &edge_info->cond_equivalences[0].cond);
+ edge_info->cond_equivalences[0].value = boolean_true_node;
+
+ /* It is possible for INVERTED to be the negation of a comparison,
+ and not a valid RHS or GIMPLE_COND condition. This happens because
+ invert_truthvalue may return such an expression when asked to invert
+ a floating-point comparison. These comparisons are not assumed to
+ obey the trichotomy law. */
+ initialize_expr_from_cond (inverted, &edge_info->cond_equivalences[1].cond);
+ edge_info->cond_equivalences[1].value = boolean_false_node;
}
/* A helper function for record_const_or_copy and record_equality.
@@ -1087,12 +1445,20 @@ record_const_or_copy_1 (tree x, tree y, tree prev_x)
{
SSA_NAME_VALUE (x) = y;
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "0>>> COPY ");
+ print_generic_expr (dump_file, x, 0);
+ fprintf (dump_file, " = ");
+ print_generic_expr (dump_file, y, 0);
+ fprintf (dump_file, "\n");
+ }
+
VEC_reserve (tree, heap, const_and_copies_stack, 2);
VEC_quick_push (tree, const_and_copies_stack, prev_x);
VEC_quick_push (tree, const_and_copies_stack, x);
}
-
/* Return the loop depth of the basic block of the defining statement of X.
This number should not be treated as absolutely correct because the loop
information may not be completely up-to-date when dom runs. However, it
@@ -1102,7 +1468,7 @@ record_const_or_copy_1 (tree x, tree y, tree prev_x)
int
loop_depth_of_name (tree x)
{
- tree defstmt;
+ gimple defstmt;
basic_block defbb;
/* If it's not an SSA_NAME, we have no clue where the definition is. */
@@ -1113,14 +1479,13 @@ loop_depth_of_name (tree x)
Note that there may not actually be a bb for this statement, if the
ssa_name is live on entry. */
defstmt = SSA_NAME_DEF_STMT (x);
- defbb = bb_for_stmt (defstmt);
+ defbb = gimple_bb (defstmt);
if (!defbb)
return 0;
return defbb->loop_depth;
}
-
/* Record that X is equal to Y in const_and_copies. Record undo
information in the block-local vector. */
@@ -1129,6 +1494,8 @@ record_const_or_copy (tree x, tree y)
{
tree prev_x = SSA_NAME_VALUE (x);
+ gcc_assert (TREE_CODE (x) == SSA_NAME);
+
if (TREE_CODE (y) == SSA_NAME)
{
tree tmp = SSA_NAME_VALUE (y);
@@ -1163,7 +1530,7 @@ record_equality (tree x, tree y)
prev_x = x, x = y, y = prev_x, prev_x = prev_y;
else if (prev_x && is_gimple_min_invariant (prev_x))
x = y, y = prev_x, prev_x = prev_y;
- else if (prev_y && TREE_CODE (prev_y) != VALUE_HANDLE)
+ else if (prev_y)
y = prev_y;
/* After the swapping, we must have one SSA_NAME. */
@@ -1189,34 +1556,34 @@ record_equality (tree x, tree y)
i_2 = i_1 +/- ... */
static bool
-simple_iv_increment_p (tree stmt)
+simple_iv_increment_p (gimple stmt)
{
- tree lhs, rhs, preinc, phi;
- unsigned i;
+ tree lhs, preinc;
+ gimple phi;
+ size_t i;
- if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT)
+ if (gimple_code (stmt) != GIMPLE_ASSIGN)
return false;
- lhs = GIMPLE_STMT_OPERAND (stmt, 0);
+ lhs = gimple_assign_lhs (stmt);
if (TREE_CODE (lhs) != SSA_NAME)
return false;
- rhs = GIMPLE_STMT_OPERAND (stmt, 1);
-
- if (TREE_CODE (rhs) != PLUS_EXPR
- && TREE_CODE (rhs) != MINUS_EXPR)
+ if (gimple_assign_rhs_code (stmt) != PLUS_EXPR
+ && gimple_assign_rhs_code (stmt) != MINUS_EXPR)
return false;
- preinc = TREE_OPERAND (rhs, 0);
+ preinc = gimple_assign_rhs1 (stmt);
+
if (TREE_CODE (preinc) != SSA_NAME)
return false;
phi = SSA_NAME_DEF_STMT (preinc);
- if (TREE_CODE (phi) != PHI_NODE)
+ if (gimple_code (phi) != GIMPLE_PHI)
return false;
- for (i = 0; i < (unsigned) PHI_NUM_ARGS (phi); i++)
- if (PHI_ARG_DEF (phi, i) == lhs)
+ for (i = 0; i < gimple_phi_num_args (phi); i++)
+ if (gimple_phi_arg_def (phi, i) == lhs)
return true;
return false;
@@ -1236,29 +1603,30 @@ cprop_into_successor_phis (basic_block bb)
FOR_EACH_EDGE (e, ei, bb->succs)
{
- tree phi;
int indx;
+ gimple_stmt_iterator gsi;
/* If this is an abnormal edge, then we do not want to copy propagate
into the PHI alternative associated with this edge. */
if (e->flags & EDGE_ABNORMAL)
continue;
- phi = phi_nodes (e->dest);
- if (! phi)
+ gsi = gsi_start_phis (e->dest);
+ if (gsi_end_p (gsi))
continue;
indx = e->dest_idx;
- for ( ; phi; phi = PHI_CHAIN (phi))
+ for ( ; !gsi_end_p (gsi); gsi_next (&gsi))
{
tree new_val;
use_operand_p orig_p;
tree orig_val;
+ gimple phi = gsi_stmt (gsi);
/* The alternative may be associated with a constant, so verify
it is an SSA_NAME before doing anything with it. */
- orig_p = PHI_ARG_DEF_PTR (phi, indx);
- orig_val = USE_FROM_PTR (orig_p);
+ orig_p = gimple_phi_arg_imm_use_ptr (phi, indx);
+ orig_val = get_use_from_ptr (orig_p);
if (TREE_CODE (orig_val) != SSA_NAME)
continue;
@@ -1281,30 +1649,29 @@ cprop_into_successor_phis (basic_block bb)
static void
record_edge_info (basic_block bb)
{
- block_stmt_iterator bsi = bsi_last (bb);
+ gimple_stmt_iterator gsi = gsi_last_bb (bb);
struct edge_info *edge_info;
- if (! bsi_end_p (bsi))
+ if (! gsi_end_p (gsi))
{
- tree stmt = bsi_stmt (bsi);
+ gimple stmt = gsi_stmt (gsi);
- if (stmt && TREE_CODE (stmt) == SWITCH_EXPR)
+ if (gimple_code (stmt) == GIMPLE_SWITCH)
{
- tree cond = SWITCH_COND (stmt);
+ tree index = gimple_switch_index (stmt);
- if (TREE_CODE (cond) == SSA_NAME)
+ if (TREE_CODE (index) == SSA_NAME)
{
- tree labels = SWITCH_LABELS (stmt);
- int i, n_labels = TREE_VEC_LENGTH (labels);
+ int i;
+ int n_labels = gimple_switch_num_labels (stmt);
tree *info = XCNEWVEC (tree, last_basic_block);
edge e;
edge_iterator ei;
for (i = 0; i < n_labels; i++)
{
- tree label = TREE_VEC_ELT (labels, i);
+ tree label = gimple_switch_label (stmt, i);
basic_block target_bb = label_to_block (CASE_LABEL (label));
-
if (CASE_HIGH (label)
|| !CASE_LOW (label)
|| info[target_bb->index])
@@ -1316,13 +1683,13 @@ record_edge_info (basic_block bb)
FOR_EACH_EDGE (e, ei, bb->succs)
{
basic_block target_bb = e->dest;
- tree node = info[target_bb->index];
+ tree label = info[target_bb->index];
- if (node != NULL && node != error_mark_node)
+ if (label != NULL && label != error_mark_node)
{
- tree x = fold_convert (TREE_TYPE (cond), CASE_LOW (node));
+ tree x = fold_convert (TREE_TYPE (index), CASE_LOW (label));
edge_info = allocate_edge_info (e);
- edge_info->lhs = cond;
+ edge_info->lhs = index;
edge_info->rhs = x;
}
}
@@ -1331,133 +1698,116 @@ record_edge_info (basic_block bb)
}
/* A COND_EXPR may create equivalences too. */
- if (stmt && TREE_CODE (stmt) == COND_EXPR)
+ if (gimple_code (stmt) == GIMPLE_COND)
{
- tree cond = COND_EXPR_COND (stmt);
edge true_edge;
edge false_edge;
- extract_true_false_edges_from_block (bb, &true_edge, &false_edge);
-
- /* If the conditional is a single variable 'X', record 'X = 1'
- for the true edge and 'X = 0' on the false edge. */
- if (SSA_VAR_P (cond))
- {
- struct edge_info *edge_info;
-
- edge_info = allocate_edge_info (true_edge);
- edge_info->lhs = cond;
- edge_info->rhs = constant_boolean_node (1, TREE_TYPE (cond));
-
- edge_info = allocate_edge_info (false_edge);
- edge_info->lhs = cond;
- edge_info->rhs = constant_boolean_node (0, TREE_TYPE (cond));
- }
- /* Equality tests may create one or two equivalences. */
- else if (COMPARISON_CLASS_P (cond))
- {
- tree op0 = TREE_OPERAND (cond, 0);
- tree op1 = TREE_OPERAND (cond, 1);
-
- /* Special case comparing booleans against a constant as we
- know the value of OP0 on both arms of the branch, i.e., we
- can record an equivalence for OP0 rather than COND. */
- if ((TREE_CODE (cond) == EQ_EXPR || TREE_CODE (cond) == NE_EXPR)
- && TREE_CODE (op0) == SSA_NAME
- && TREE_CODE (TREE_TYPE (op0)) == BOOLEAN_TYPE
- && is_gimple_min_invariant (op1))
- {
- if (TREE_CODE (cond) == EQ_EXPR)
- {
- edge_info = allocate_edge_info (true_edge);
- edge_info->lhs = op0;
- edge_info->rhs = (integer_zerop (op1)
- ? boolean_false_node
- : boolean_true_node);
-
- edge_info = allocate_edge_info (false_edge);
- edge_info->lhs = op0;
- edge_info->rhs = (integer_zerop (op1)
- ? boolean_true_node
- : boolean_false_node);
- }
- else
- {
- edge_info = allocate_edge_info (true_edge);
- edge_info->lhs = op0;
- edge_info->rhs = (integer_zerop (op1)
- ? boolean_true_node
- : boolean_false_node);
-
- edge_info = allocate_edge_info (false_edge);
- edge_info->lhs = op0;
- edge_info->rhs = (integer_zerop (op1)
- ? boolean_false_node
- : boolean_true_node);
- }
- }
-
- else if (is_gimple_min_invariant (op0)
- && (TREE_CODE (op1) == SSA_NAME
- || is_gimple_min_invariant (op1)))
- {
- tree inverted = invert_truthvalue (cond);
- struct edge_info *edge_info;
-
- edge_info = allocate_edge_info (true_edge);
- record_conditions (edge_info, cond, inverted);
-
- if (TREE_CODE (cond) == EQ_EXPR)
- {
- edge_info->lhs = op1;
- edge_info->rhs = op0;
- }
-
- edge_info = allocate_edge_info (false_edge);
- record_conditions (edge_info, inverted, cond);
-
- if (TREE_CODE (cond) == NE_EXPR)
- {
- edge_info->lhs = op1;
- edge_info->rhs = op0;
- }
- }
-
- else if (TREE_CODE (op0) == SSA_NAME
- && (is_gimple_min_invariant (op1)
- || TREE_CODE (op1) == SSA_NAME))
- {
- tree inverted = invert_truthvalue (cond);
- struct edge_info *edge_info;
-
- edge_info = allocate_edge_info (true_edge);
- record_conditions (edge_info, cond, inverted);
-
- if (TREE_CODE (cond) == EQ_EXPR)
- {
- edge_info->lhs = op0;
- edge_info->rhs = op1;
- }
-
- edge_info = allocate_edge_info (false_edge);
- record_conditions (edge_info, inverted, cond);
+ tree op0 = gimple_cond_lhs (stmt);
+ tree op1 = gimple_cond_rhs (stmt);
+ enum tree_code code = gimple_cond_code (stmt);
- if (TREE_CODE (cond) == NE_EXPR)
- {
- edge_info->lhs = op0;
- edge_info->rhs = op1;
- }
- }
- }
+ extract_true_false_edges_from_block (bb, &true_edge, &false_edge);
- /* ??? TRUTH_NOT_EXPR can create an equivalence too. */
- }
+ /* Special case comparing booleans against a constant as we
+ know the value of OP0 on both arms of the branch. i.e., we
+ can record an equivalence for OP0 rather than COND. */
+ if ((code == EQ_EXPR || code == NE_EXPR)
+ && TREE_CODE (op0) == SSA_NAME
+ && TREE_CODE (TREE_TYPE (op0)) == BOOLEAN_TYPE
+ && is_gimple_min_invariant (op1))
+ {
+ if (code == EQ_EXPR)
+ {
+ edge_info = allocate_edge_info (true_edge);
+ edge_info->lhs = op0;
+ edge_info->rhs = (integer_zerop (op1)
+ ? boolean_false_node
+ : boolean_true_node);
+
+ edge_info = allocate_edge_info (false_edge);
+ edge_info->lhs = op0;
+ edge_info->rhs = (integer_zerop (op1)
+ ? boolean_true_node
+ : boolean_false_node);
+ }
+ else
+ {
+ edge_info = allocate_edge_info (true_edge);
+ edge_info->lhs = op0;
+ edge_info->rhs = (integer_zerop (op1)
+ ? boolean_true_node
+ : boolean_false_node);
+
+ edge_info = allocate_edge_info (false_edge);
+ edge_info->lhs = op0;
+ edge_info->rhs = (integer_zerop (op1)
+ ? boolean_false_node
+ : boolean_true_node);
+ }
+ }
+ else if (is_gimple_min_invariant (op0)
+ && (TREE_CODE (op1) == SSA_NAME
+ || is_gimple_min_invariant (op1)))
+ {
+ tree cond = build2 (code, boolean_type_node, op0, op1);
+ tree inverted = invert_truthvalue (cond);
+ struct edge_info *edge_info;
+
+ edge_info = allocate_edge_info (true_edge);
+ record_conditions (edge_info, cond, inverted);
+
+ if (code == EQ_EXPR)
+ {
+ edge_info->lhs = op1;
+ edge_info->rhs = op0;
+ }
+
+ edge_info = allocate_edge_info (false_edge);
+ record_conditions (edge_info, inverted, cond);
+
+ if (code == NE_EXPR)
+ {
+ edge_info->lhs = op1;
+ edge_info->rhs = op0;
+ }
+ }
+
+ else if (TREE_CODE (op0) == SSA_NAME
+ && (is_gimple_min_invariant (op1)
+ || TREE_CODE (op1) == SSA_NAME))
+ {
+ tree cond = build2 (code, boolean_type_node, op0, op1);
+ tree inverted = invert_truthvalue (cond);
+ struct edge_info *edge_info;
+
+ edge_info = allocate_edge_info (true_edge);
+ record_conditions (edge_info, cond, inverted);
+
+ if (code == EQ_EXPR)
+ {
+ edge_info->lhs = op0;
+ edge_info->rhs = op1;
+ }
+
+ edge_info = allocate_edge_info (false_edge);
+ record_conditions (edge_info, inverted, cond);
+
+ if (TREE_CODE (cond) == NE_EXPR)
+ {
+ edge_info->lhs = op0;
+ edge_info->rhs = op1;
+ }
+ }
+ }
+
+ /* ??? TRUTH_NOT_EXPR can create an equivalence too. */
}
}
/* Propagate information from BB to its outgoing edges.
- This can include equivalency information implied by control statements
+ This can include equivalence information implied by control statements
at the end of BB and const/copy propagation into PHIs in BB's
successor blocks. */
@@ -1476,16 +1826,17 @@ propagate_to_outgoing_edges (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
table. */
static bool
-eliminate_redundant_computations (tree stmt)
+eliminate_redundant_computations (gimple_stmt_iterator* gsi)
{
- tree *expr_p, def = NULL_TREE;
- bool insert = true;
+ tree expr_type;
tree cached_lhs;
+ bool insert = true;
bool retval = false;
- bool modify_expr_p = false;
+ bool assigns_var_p = false;
- if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT)
- def = GIMPLE_STMT_OPERAND (stmt, 0);
+ gimple stmt = gsi_stmt (*gsi);
+
+ tree def = gimple_get_lhs (stmt);
/* Certain expressions on the RHS can be optimized away, but can not
themselves be entered into the hash tables. */
@@ -1503,80 +1854,117 @@ eliminate_redundant_computations (tree stmt)
opt_stats.num_exprs_considered++;
- /* Get a pointer to the expression we are trying to optimize. */
- if (TREE_CODE (stmt) == COND_EXPR)
- expr_p = &COND_EXPR_COND (stmt);
- else if (TREE_CODE (stmt) == SWITCH_EXPR)
- expr_p = &SWITCH_COND (stmt);
- else if (TREE_CODE (stmt) == RETURN_EXPR && TREE_OPERAND (stmt, 0))
+ /* Get the type of the expression we are trying to optimize. */
+ if (is_gimple_assign (stmt))
{
- expr_p = &GIMPLE_STMT_OPERAND (TREE_OPERAND (stmt, 0), 1);
- modify_expr_p = true;
+ expr_type = TREE_TYPE (gimple_assign_lhs (stmt));
+ assigns_var_p = true;
}
- else
+ else if (gimple_code (stmt) == GIMPLE_COND)
+ expr_type = boolean_type_node;
+ else if (is_gimple_call (stmt))
{
- expr_p = &GENERIC_TREE_OPERAND (stmt, 1);
- modify_expr_p = true;
+ gcc_assert (gimple_call_lhs (stmt));
+ expr_type = TREE_TYPE (gimple_call_lhs (stmt));
+ assigns_var_p = true;
}
+ else if (gimple_code (stmt) == GIMPLE_SWITCH)
+ expr_type = TREE_TYPE (gimple_switch_index (stmt));
+ else
+ gcc_unreachable ();
+
+ if (!cached_lhs)
+ return false;
/* It is safe to ignore types here since we have already done
type checking in the hashing and equality routines. In fact
type checking here merely gets in the way of constant
propagation. Also, make sure that it is safe to propagate
- CACHED_LHS into *EXPR_P. */
- if (cached_lhs
- && ((TREE_CODE (cached_lhs) != SSA_NAME
- && (modify_expr_p
- || useless_type_conversion_p (TREE_TYPE (*expr_p),
- TREE_TYPE (cached_lhs))))
- || may_propagate_copy (*expr_p, cached_lhs)))
- {
+ CACHED_LHS into the expression in STMT. */
+ if ((TREE_CODE (cached_lhs) != SSA_NAME
+ && (assigns_var_p
+ || useless_type_conversion_p (expr_type, TREE_TYPE (cached_lhs))))
+ || may_propagate_copy_into_stmt (stmt, cached_lhs))
+ {
+#if defined ENABLE_CHECKING
+ gcc_assert (TREE_CODE (cached_lhs) == SSA_NAME
+ || is_gimple_min_invariant (cached_lhs));
+#endif
+
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, " Replaced redundant expr '");
- print_generic_expr (dump_file, *expr_p, dump_flags);
+ print_gimple_expr (dump_file, stmt, 0, dump_flags);
fprintf (dump_file, "' with '");
print_generic_expr (dump_file, cached_lhs, dump_flags);
- fprintf (dump_file, "'\n");
+ fprintf (dump_file, "'\n");
}
opt_stats.num_re++;
-#if defined ENABLE_CHECKING
- gcc_assert (TREE_CODE (cached_lhs) == SSA_NAME
- || is_gimple_min_invariant (cached_lhs));
-#endif
-
if (TREE_CODE (cached_lhs) == ADDR_EXPR
- || (POINTER_TYPE_P (TREE_TYPE (*expr_p))
+ || (POINTER_TYPE_P (expr_type)
&& is_gimple_min_invariant (cached_lhs)))
retval = true;
- if (modify_expr_p
- && !useless_type_conversion_p (TREE_TYPE (*expr_p),
- TREE_TYPE (cached_lhs)))
- cached_lhs = fold_convert (TREE_TYPE (*expr_p), cached_lhs);
+ if (assigns_var_p
+ && !useless_type_conversion_p (expr_type, TREE_TYPE (cached_lhs)))
+ cached_lhs = fold_convert (expr_type, cached_lhs);
- propagate_tree_value (expr_p, cached_lhs);
- mark_stmt_modified (stmt);
- }
+ propagate_tree_value_into_stmt (gsi, cached_lhs);
+
+ /* Since it is always necessary to mark the result as modified,
+ perhaps we should move this into propagate_tree_value_into_stmt
+ itself. */
+ gimple_set_modified (gsi_stmt (*gsi), true);
+ }
return retval;
}
-/* STMT, a GIMPLE_MODIFY_STMT, may create certain equivalences, in either
+/* Return true if statement GS is an assignment that peforms a useless
+ type conversion. It is is intended to be a tuples analog of function
+ tree_ssa_useless_type_conversion. */
+
+static bool
+gimple_assign_unary_useless_conversion_p (gimple gs)
+{
+ if (is_gimple_assign (gs)
+ && (gimple_assign_rhs_code (gs) == NOP_EXPR
+ || gimple_assign_rhs_code (gs) == CONVERT_EXPR
+ || gimple_assign_rhs_code (gs) == VIEW_CONVERT_EXPR
+ || gimple_assign_rhs_code (gs) == NON_LVALUE_EXPR))
+ {
+ tree lhs_type = TREE_TYPE (gimple_assign_lhs (gs));
+ tree rhs_type = TREE_TYPE (gimple_assign_rhs1 (gs));
+ return useless_type_conversion_p (lhs_type, rhs_type);
+ }
+
+ return false;
+}
+
+/* STMT, a GIMPLE_ASSIGN, may create certain equivalences, in either
the available expressions table or the const_and_copies table.
Detect and record those equivalences. */
+/* We handle only very simple copy equivalences here. The heavy
+ lifing is done by eliminate_redundant_computations. */
static void
-record_equivalences_from_stmt (tree stmt, int may_optimize_p, stmt_ann_t ann)
+record_equivalences_from_stmt (gimple stmt, int may_optimize_p)
{
- tree lhs = GIMPLE_STMT_OPERAND (stmt, 0);
- enum tree_code lhs_code = TREE_CODE (lhs);
+ tree lhs;
+ enum tree_code lhs_code;
- if (lhs_code == SSA_NAME)
- {
- tree rhs = GIMPLE_STMT_OPERAND (stmt, 1);
+ gcc_assert (is_gimple_assign (stmt));
+
+ lhs = gimple_assign_lhs (stmt);
+ lhs_code = TREE_CODE (lhs);
+ if (lhs_code == SSA_NAME
+ && (gimple_assign_single_p (stmt)
+ || gimple_assign_unary_useless_conversion_p (stmt)))
+ {
+ tree rhs = gimple_assign_rhs1 (stmt);
+
/* Strip away any useless type conversions. */
STRIP_USELESS_TYPE_CONVERSION (rhs);
@@ -1589,24 +1977,53 @@ record_equivalences_from_stmt (tree stmt, int may_optimize_p, stmt_ann_t ann)
if (may_optimize_p
&& (TREE_CODE (rhs) == SSA_NAME
|| is_gimple_min_invariant (rhs)))
+ {
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "==== ASGN ");
+ print_generic_expr (dump_file, lhs, 0);
+ fprintf (dump_file, " = ");
+ print_generic_expr (dump_file, rhs, 0);
+ fprintf (dump_file, "\n");
+ }
+
SSA_NAME_VALUE (lhs) = rhs;
+ }
}
/* A memory store, even an aliased store, creates a useful
equivalence. By exchanging the LHS and RHS, creating suitable
vops and recording the result in the available expression table,
we may be able to expose more redundant loads. */
- if (!ann->has_volatile_ops
- && stmt_references_memory_p (stmt)
- && (TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 1)) == SSA_NAME
- || is_gimple_min_invariant (GIMPLE_STMT_OPERAND (stmt, 1)))
+ if (!gimple_has_volatile_ops (stmt)
+ && gimple_references_memory_p (stmt)
+ && gimple_assign_single_p (stmt)
+ && (TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME
+ || is_gimple_min_invariant (gimple_assign_rhs1 (stmt)))
&& !is_gimple_reg (lhs))
{
- tree rhs = GIMPLE_STMT_OPERAND (stmt, 1);
- tree new_stmt;
+ tree rhs = gimple_assign_rhs1 (stmt);
+ gimple new_stmt;
/* Build a new statement with the RHS and LHS exchanged. */
- new_stmt = build_gimple_modify_stmt (rhs, lhs);
+ if (TREE_CODE (rhs) == SSA_NAME)
+ {
+ /* NOTE tuples. The call to gimple_build_assign below replaced
+ a call to build_gimple_modify_stmt, which did not set the
+ SSA_NAME_DEF_STMT on the LHS of the assignment. Doing so
+ may cause an SSA validation failure, as the LHS may be a
+ default-initialized name and should have no definition. I'm
+ a bit dubious of this, as the artificial statement that we
+ generate here may in fact be ill-formed, but it is simply
+ used as an internal device in this pass, and never becomes
+ part of the CFG. */
+ gimple defstmt = SSA_NAME_DEF_STMT (rhs);
+ new_stmt = gimple_build_assign (rhs, lhs);
+ SSA_NAME_DEF_STMT (rhs) = defstmt;
+ }
+ else
+ new_stmt = gimple_build_assign (rhs, lhs);
+
create_ssa_artificial_load_stmt (new_stmt, stmt, true);
/* Finally enter the statement into the available expression
@@ -1619,7 +2036,7 @@ record_equivalences_from_stmt (tree stmt, int may_optimize_p, stmt_ann_t ann)
CONST_AND_COPIES. */
static bool
-cprop_operand (tree stmt, use_operand_p op_p)
+cprop_operand (gimple stmt, use_operand_p op_p)
{
bool may_have_exposed_new_symbols = false;
tree val;
@@ -1629,7 +2046,7 @@ cprop_operand (tree stmt, use_operand_p op_p)
copy of some other variable, use the value or copy stored in
CONST_AND_COPIES. */
val = SSA_NAME_VALUE (op);
- if (val && val != op && TREE_CODE (val) != VALUE_HANDLE)
+ if (val && val != op)
{
tree op_type, val_type;
@@ -1645,7 +2062,7 @@ cprop_operand (tree stmt, use_operand_p op_p)
return false;
/* Do not replace hard register operands in asm statements. */
- if (TREE_CODE (stmt) == ASM_EXPR
+ if (gimple_code (stmt) == GIMPLE_ASM
&& !may_propagate_copy_into_asm (op))
return false;
@@ -1717,7 +2134,7 @@ cprop_operand (tree stmt, use_operand_p op_p)
/* And note that we modified this statement. This is now
safe, even if we changed virtual operands since we will
rescan the statement and rewrite its operands again. */
- mark_stmt_modified (stmt);
+ gimple_set_modified (stmt, true);
}
return may_have_exposed_new_symbols;
}
@@ -1729,7 +2146,7 @@ cprop_operand (tree stmt, use_operand_p op_p)
vdef_ops of STMT. */
static bool
-cprop_into_stmt (tree stmt)
+cprop_into_stmt (gimple stmt)
{
bool may_have_exposed_new_symbols = false;
use_operand_p op_p;
@@ -1744,7 +2161,6 @@ cprop_into_stmt (tree stmt)
return may_have_exposed_new_symbols;
}
-
/* Optimize the statement pointed to by iterator SI.
We try to perform some simplistic global redundancy elimination and
@@ -1762,28 +2178,26 @@ cprop_into_stmt (tree stmt)
static void
optimize_stmt (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
- basic_block bb, block_stmt_iterator si)
+ basic_block bb, gimple_stmt_iterator si)
{
- stmt_ann_t ann;
- tree stmt, old_stmt;
+ gimple stmt, old_stmt;
bool may_optimize_p;
bool may_have_exposed_new_symbols = false;
- old_stmt = stmt = bsi_stmt (si);
+ old_stmt = stmt = gsi_stmt (si);
- if (TREE_CODE (stmt) == COND_EXPR)
+ if (gimple_code (stmt) == GIMPLE_COND)
canonicalize_comparison (stmt);
update_stmt_if_modified (stmt);
- ann = stmt_ann (stmt);
opt_stats.num_stmts++;
may_have_exposed_new_symbols = false;
- push_stmt_changes (bsi_stmt_ptr (si));
+ push_stmt_changes (gsi_stmt_ptr (&si));
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "Optimizing statement ");
- print_generic_stmt (dump_file, stmt, TDF_SLIM);
+ print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
}
/* Const/copy propagate into USES, VUSES and the RHS of VDEFs. */
@@ -1791,27 +2205,34 @@ optimize_stmt (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
/* If the statement has been modified with constant replacements,
fold its RHS before checking for redundant computations. */
- if (ann->modified)
+ if (gimple_modified_p (stmt))
{
- tree rhs;
+ tree rhs = NULL;
/* Try to fold the statement making sure that STMT is kept
up to date. */
- if (fold_stmt (bsi_stmt_ptr (si)))
+ if (fold_stmt (&si))
{
- stmt = bsi_stmt (si);
- ann = stmt_ann (stmt);
+ stmt = gsi_stmt (si);
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, " Folded to: ");
- print_generic_stmt (dump_file, stmt, TDF_SLIM);
+ print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
}
}
- rhs = get_rhs (stmt);
+ /* We only need to consider cases that can yield a gimple operand. */
+ if (gimple_assign_single_p (stmt))
+ rhs = gimple_assign_rhs1 (stmt);
+ else if (gimple_code (stmt) == GIMPLE_GOTO)
+ rhs = gimple_goto_dest (stmt);
+ else if (gimple_code (stmt) == GIMPLE_SWITCH)
+ /* This should never be an ADDR_EXPR. */
+ rhs = gimple_switch_index (stmt);
+
if (rhs && TREE_CODE (rhs) == ADDR_EXPR)
- recompute_tree_invariant_for_addr_expr (rhs);
+ recompute_tree_invariant_for_addr_expr (rhs);
/* Constant/copy propagation above may change the set of
virtual operands associated with this statement. Folding
@@ -1823,26 +2244,24 @@ optimize_stmt (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
/* Check for redundant computations. Do this optimization only
for assignments that have no volatile ops and conditionals. */
- may_optimize_p = (!ann->has_volatile_ops
- && ((TREE_CODE (stmt) == RETURN_EXPR
- && TREE_OPERAND (stmt, 0)
- && TREE_CODE (TREE_OPERAND (stmt, 0))
- == GIMPLE_MODIFY_STMT
- && ! (TREE_SIDE_EFFECTS
- (GIMPLE_STMT_OPERAND
- (TREE_OPERAND (stmt, 0), 1))))
- || (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT
- && ! TREE_SIDE_EFFECTS (GIMPLE_STMT_OPERAND (stmt,
- 1)))
- || TREE_CODE (stmt) == COND_EXPR
- || TREE_CODE (stmt) == SWITCH_EXPR));
+ may_optimize_p = (!gimple_has_volatile_ops (stmt)
+ && ((is_gimple_assign (stmt)
+ && !gimple_rhs_has_side_effects (stmt))
+ || (is_gimple_call (stmt)
+ && gimple_call_lhs (stmt) != NULL_TREE
+ && !gimple_rhs_has_side_effects (stmt))
+ || gimple_code (stmt) == GIMPLE_COND
+ || gimple_code (stmt) == GIMPLE_SWITCH));
if (may_optimize_p)
- may_have_exposed_new_symbols |= eliminate_redundant_computations (stmt);
+ {
+ may_have_exposed_new_symbols |= eliminate_redundant_computations (&si);
+ stmt = gsi_stmt (si);
+ }
/* Record any additional equivalences created by this statement. */
- if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT)
- record_equivalences_from_stmt (stmt, may_optimize_p, ann);
+ if (is_gimple_assign (stmt))
+ record_equivalences_from_stmt (stmt, may_optimize_p);
/* If STMT is a COND_EXPR and it was modified, then we may know
where it goes. If that is the case, then mark the CFG as altered.
@@ -1869,14 +2288,15 @@ optimize_stmt (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
Ultimately I suspect we're going to need to change the interface
into the SSA_NAME manager. */
- if (ann->modified)
+ if (gimple_modified_p (stmt))
{
tree val = NULL;
- if (TREE_CODE (stmt) == COND_EXPR)
- val = COND_EXPR_COND (stmt);
- else if (TREE_CODE (stmt) == SWITCH_EXPR)
- val = SWITCH_COND (stmt);
+ if (gimple_code (stmt) == GIMPLE_COND)
+ val = fold_binary (gimple_cond_code (stmt), boolean_type_node,
+ gimple_cond_lhs (stmt), gimple_cond_rhs (stmt));
+ else if (gimple_code (stmt) == GIMPLE_SWITCH)
+ val = gimple_switch_index (stmt);
if (val && TREE_CODE (val) == INTEGER_CST && find_taken_edge (bb, val))
cfg_altered = true;
@@ -1897,47 +2317,50 @@ optimize_stmt (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
AVAIL_EXPRS have been processed. The change buffer stack for
all the pushed statements will be processed when this queue
is emptied. */
- VEC_safe_push (tree_p, heap, stmts_to_rescan, bsi_stmt_ptr (si));
+ VEC_safe_push (gimple_p, heap, stmts_to_rescan, gsi_stmt_ptr (&si));
}
else
{
/* Otherwise, just discard the recently pushed change buffer. If
not, the STMTS_TO_RESCAN queue will get out of synch with the
change buffer stack. */
- discard_stmt_changes (bsi_stmt_ptr (si));
+ discard_stmt_changes (gsi_stmt_ptr (&si));
}
}
-/* Search for an existing instance of STMT in the AVAIL_EXPRS table. If
- found, return its LHS. Otherwise insert STMT in the table and return
- NULL_TREE.
+/* Search for an existing instance of STMT in the AVAIL_EXPRS table.
+ If found, return its LHS. Otherwise insert STMT in the table and
+ return NULL_TREE.
- Also, when an expression is first inserted in the AVAIL_EXPRS table, it
- is also added to the stack pointed to by BLOCK_AVAIL_EXPRS_P, so that they
- can be removed when we finish processing this block and its children.
-
- NOTE: This function assumes that STMT is a GIMPLE_MODIFY_STMT node that
- contains no CALL_EXPR on its RHS and makes no volatile nor
- aliased references. */
+ Also, when an expression is first inserted in the table, it is also
+ is also added to AVAIL_EXPRS_STACK, so that it can be removed when
+ we finish processing this block and its children. */
static tree
-lookup_avail_expr (tree stmt, bool insert)
+lookup_avail_expr (gimple stmt, bool insert)
{
void **slot;
tree lhs;
tree temp;
struct expr_hash_elt *element = XNEW (struct expr_hash_elt);
- lhs = TREE_CODE (stmt) == GIMPLE_MODIFY_STMT
- ? GIMPLE_STMT_OPERAND (stmt, 0) : NULL;
+ /* Get LHS of assignment or call, else NULL_TREE. */
+ lhs = gimple_get_lhs (stmt);
initialize_hash_element (stmt, lhs, element);
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "LKUP ");
+ print_expr_hash_elt (dump_file, element);
+ }
+
/* Don't bother remembering constant assignments and copy operations.
Constants and copy operations are handled by the constant/copy propagator
in optimize_stmt. */
- if (TREE_CODE (element->rhs) == SSA_NAME
- || is_gimple_min_invariant (element->rhs))
+ if (element->expr.kind == EXPR_SINGLE
+ && (TREE_CODE (element->expr.ops.single.rhs) == SSA_NAME
+ || is_gimple_min_invariant (element->expr.ops.single.rhs)))
{
free (element);
return NULL_TREE;
@@ -1949,14 +2372,20 @@ lookup_avail_expr (tree stmt, bool insert)
if (slot == NULL)
{
free (element);
- return NULL_TREE;
+ return NULL_TREE;
}
if (*slot == NULL)
{
*slot = (void *) element;
- VEC_safe_push (tree, heap, avail_exprs_stack,
- stmt ? stmt : element->rhs);
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "2>>> ");
+ print_expr_hash_elt (dump_file, element);
+ }
+
+ VEC_safe_push (expr_hash_elt_t, heap, avail_exprs_stack, element);
return NULL_TREE;
}
@@ -1969,36 +2398,41 @@ lookup_avail_expr (tree stmt, bool insert)
if (TREE_CODE (lhs) == SSA_NAME)
{
temp = SSA_NAME_VALUE (lhs);
- if (temp && TREE_CODE (temp) != VALUE_HANDLE)
+ if (temp)
lhs = temp;
}
free (element);
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "FIND: ");
+ print_generic_expr (dump_file, lhs, 0);
+ fprintf (dump_file, "\n");
+ }
+
return lhs;
}
-/* Hashing and equality functions for AVAIL_EXPRS. The table stores
- GIMPLE_MODIFY_STMT statements. We compute a value number for expressions
- using the code of the expression and the SSA numbers of its operands. */
+/* Hashing and equality functions for AVAIL_EXPRS. We compute a value number
+ for expressions using the code of the expression and the SSA numbers of
+ its operands. */
static hashval_t
avail_expr_hash (const void *p)
{
- tree stmt = ((const struct expr_hash_elt *)p)->stmt;
- tree rhs = ((const struct expr_hash_elt *)p)->rhs;
+ gimple stmt = ((const struct expr_hash_elt *)p)->stmt;
+ const struct hashable_expr *expr = &((const struct expr_hash_elt *)p)->expr;
tree vuse;
ssa_op_iter iter;
hashval_t val = 0;
- /* iterative_hash_expr knows how to deal with any expression and
- deals with commutative operators as well, so just use it instead
- of duplicating such complexities here. */
- val = iterative_hash_expr (rhs, val);
+ val = iterative_hash_hashable_expr (expr, val);
/* If the hash table entry is not associated with a statement, then we
can just hash the expression and not worry about virtual operands
and such. */
- if (!stmt || !stmt_ann (stmt))
+ if (!stmt)
return val;
/* Add the SSA version numbers of every vuse operand. This is important
@@ -2020,27 +2454,34 @@ real_avail_expr_hash (const void *p)
static int
avail_expr_eq (const void *p1, const void *p2)
{
- tree stmt1 = ((const struct expr_hash_elt *)p1)->stmt;
- tree rhs1 = ((const struct expr_hash_elt *)p1)->rhs;
- tree stmt2 = ((const struct expr_hash_elt *)p2)->stmt;
- tree rhs2 = ((const struct expr_hash_elt *)p2)->rhs;
-
- /* If they are the same physical expression, return true. */
- if (rhs1 == rhs2 && stmt1 == stmt2)
+ gimple stmt1 = ((const struct expr_hash_elt *)p1)->stmt;
+ const struct hashable_expr *expr1 = &((const struct expr_hash_elt *)p1)->expr;
+ const struct expr_hash_elt *stamp1 = ((const struct expr_hash_elt *)p1)->stamp;
+ gimple stmt2 = ((const struct expr_hash_elt *)p2)->stmt;
+ const struct hashable_expr *expr2 = &((const struct expr_hash_elt *)p2)->expr;
+ const struct expr_hash_elt *stamp2 = ((const struct expr_hash_elt *)p2)->stamp;
+
+ /* This case should apply only when removing entries from the table. */
+ if (stamp1 == stamp2)
return true;
- /* If their codes are not equal, then quit now. */
- if (TREE_CODE (rhs1) != TREE_CODE (rhs2))
+ /* FIXME tuples:
+ We add stmts to a hash table and them modify them. To detect the case
+ that we modify a stmt and then search for it, we assume that the hash
+ is always modified by that change.
+ We have to fully check why this doesn't happen on trunk or rewrite
+ this in a more reliable (and easier to understand) way. */
+ if (((const struct expr_hash_elt *)p1)->hash
+ != ((const struct expr_hash_elt *)p2)->hash)
return false;
/* In case of a collision, both RHS have to be identical and have the
same VUSE operands. */
- if (types_compatible_p (TREE_TYPE (rhs1), TREE_TYPE (rhs2))
- && operand_equal_p (rhs1, rhs2, OEP_PURE_SAME))
+ if (hashable_expr_equal_p (expr1, expr2)
+ && types_compatible_p (expr1->type, expr2->type))
{
+ /* Note that STMT1 and/or STMT2 may be NULL. */
bool ret = compare_ssa_operands_equal (stmt1, stmt2, SSA_OP_VUSE);
- gcc_assert (!ret || ((const struct expr_hash_elt *)p1)->hash
- == ((const struct expr_hash_elt *)p2)->hash);
return ret;
}
@@ -2054,18 +2495,18 @@ avail_expr_eq (const void *p1, const void *p2)
NULL. */
static tree
-degenerate_phi_result (tree phi)
+degenerate_phi_result (gimple phi)
{
- tree lhs = PHI_RESULT (phi);
+ tree lhs = gimple_phi_result (phi);
tree val = NULL;
- int i;
+ size_t i;
/* Ignoring arguments which are the same as LHS, if all the remaining
arguments are the same, then the PHI is a degenerate and has the
value of that common argument. */
- for (i = 0; i < PHI_NUM_ARGS (phi); i++)
+ for (i = 0; i < gimple_phi_num_args (phi); i++)
{
- tree arg = PHI_ARG_DEF (phi, i);
+ tree arg = gimple_phi_arg_def (phi, i);
if (arg == lhs)
continue;
@@ -2074,51 +2515,54 @@ degenerate_phi_result (tree phi)
else if (!operand_equal_p (arg, val, 0))
break;
}
- return (i == PHI_NUM_ARGS (phi) ? val : NULL);
+ return (i == gimple_phi_num_args (phi) ? val : NULL);
}
-/* Given a tree node T, which is either a PHI_NODE or GIMPLE_MODIFY_STMT,
+/* Given a statement STMT, which is either a PHI node or an assignment,
remove it from the IL. */
static void
-remove_stmt_or_phi (tree t)
+remove_stmt_or_phi (gimple stmt)
{
- if (TREE_CODE (t) == PHI_NODE)
- remove_phi_node (t, NULL, true);
+ gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
+
+ if (gimple_code (stmt) == GIMPLE_PHI)
+ remove_phi_node (&gsi, true);
else
{
- block_stmt_iterator bsi = bsi_for_stmt (t);
- bsi_remove (&bsi, true);
- release_defs (t);
+ gsi_remove (&gsi, true);
+ release_defs (stmt);
}
}
-/* Given a tree node T, which is either a PHI_NODE or GIMPLE_MODIFY_STMT,
+/* Given a statement STMT, which is either a PHI node or an assignment,
return the "rhs" of the node, in the case of a non-degenerate
- PHI, NULL is returned. */
+ phi, NULL is returned. */
static tree
-get_rhs_or_phi_arg (tree t)
+get_rhs_or_phi_arg (gimple stmt)
{
- if (TREE_CODE (t) == PHI_NODE)
- return degenerate_phi_result (t);
- else if (TREE_CODE (t) == GIMPLE_MODIFY_STMT)
- return GIMPLE_STMT_OPERAND (t, 1);
- gcc_unreachable ();
+ if (gimple_code (stmt) == GIMPLE_PHI)
+ return degenerate_phi_result (stmt);
+ else if (gimple_assign_single_p (stmt))
+ return gimple_assign_rhs1 (stmt);
+ else
+ gcc_unreachable ();
}
-/* Given a tree node T, which is either a PHI_NODE or a GIMPLE_MODIFY_STMT,
+/* Given a statement STMT, which is either a PHI node or an assignment,
return the "lhs" of the node. */
static tree
-get_lhs_or_phi_result (tree t)
+get_lhs_or_phi_result (gimple stmt)
{
- if (TREE_CODE (t) == PHI_NODE)
- return PHI_RESULT (t);
- else if (TREE_CODE (t) == GIMPLE_MODIFY_STMT)
- return GIMPLE_STMT_OPERAND (t, 0);
- gcc_unreachable ();
+ if (gimple_code (stmt) == GIMPLE_PHI)
+ return gimple_phi_result (stmt);
+ else if (is_gimple_assign (stmt))
+ return gimple_assign_lhs (stmt);
+ else
+ gcc_unreachable ();
}
/* Propagate RHS into all uses of LHS (when possible).
@@ -2133,7 +2577,7 @@ get_lhs_or_phi_result (tree t)
opportunities. */
static void
-propagate_rhs_into_lhs (tree stmt, tree lhs, tree rhs, bitmap interesting_names)
+propagate_rhs_into_lhs (gimple stmt, tree lhs, tree rhs, bitmap interesting_names)
{
/* First verify that propagation is valid and isn't going to move a
loop variant variable outside its loop. */
@@ -2145,7 +2589,7 @@ propagate_rhs_into_lhs (tree stmt, tree lhs, tree rhs, bitmap interesting_names)
{
use_operand_p use_p;
imm_use_iterator iter;
- tree use_stmt;
+ gimple use_stmt;
bool all = true;
/* Dump details. */
@@ -2166,8 +2610,8 @@ propagate_rhs_into_lhs (tree stmt, tree lhs, tree rhs, bitmap interesting_names)
{
/* It's not always safe to propagate into an ASM_EXPR. */
- if (TREE_CODE (use_stmt) == ASM_EXPR
- && ! may_propagate_copy_into_asm (lhs))
+ if (gimple_code (use_stmt) == GIMPLE_ASM
+ && ! may_propagate_copy_into_asm (lhs))
{
all = false;
continue;
@@ -2177,8 +2621,7 @@ propagate_rhs_into_lhs (tree stmt, tree lhs, tree rhs, bitmap interesting_names)
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, " Original statement:");
- print_generic_expr (dump_file, use_stmt, dump_flags);
- fprintf (dump_file, "\n");
+ print_gimple_stmt (dump_file, use_stmt, 0, dump_flags);
}
push_stmt_changes (&use_stmt);
@@ -2197,7 +2640,7 @@ propagate_rhs_into_lhs (tree stmt, tree lhs, tree rhs, bitmap interesting_names)
Second, if we're propagating a virtual operand and the
propagation does not change the underlying _DECL node for
the virtual operand, then no further actions are necessary. */
- if (TREE_CODE (use_stmt) == PHI_NODE
+ if (gimple_code (use_stmt) == GIMPLE_PHI
|| (! is_gimple_reg (lhs)
&& TREE_CODE (rhs) == SSA_NAME
&& SSA_NAME_VAR (lhs) == SSA_NAME_VAR (rhs)))
@@ -2206,13 +2649,12 @@ propagate_rhs_into_lhs (tree stmt, tree lhs, tree rhs, bitmap interesting_names)
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, " Updated statement:");
- print_generic_expr (dump_file, use_stmt, dump_flags);
- fprintf (dump_file, "\n");
+ print_gimple_stmt (dump_file, use_stmt, 0, dump_flags);
}
/* Propagation into a PHI may expose new degenerate PHIs,
so mark the result of the PHI as interesting. */
- if (TREE_CODE (use_stmt) == PHI_NODE)
+ if (gimple_code (use_stmt) == GIMPLE_PHI)
{
tree result = get_lhs_or_phi_result (use_stmt);
bitmap_set_bit (interesting_names, SSA_NAME_VERSION (result));
@@ -2226,6 +2668,12 @@ propagate_rhs_into_lhs (tree stmt, tree lhs, tree rhs, bitmap interesting_names)
real statement. Folding may (or may not) be possible,
we may expose new operands, expose dead EH edges,
etc. */
+ /* NOTE tuples. In the tuples world, fold_stmt_inplace
+ cannot fold a call that simplifies to a constant,
+ because the GIMPLE_CALL must be replaced by a
+ GIMPLE_ASSIGN, and there is no way to effect such a
+ transformation in-place. We might want to consider
+ using the more general fold_stmt here. */
fold_stmt_inplace (use_stmt);
/* Sometimes propagation can expose new operands to the
@@ -2237,34 +2685,32 @@ propagate_rhs_into_lhs (tree stmt, tree lhs, tree rhs, bitmap interesting_names)
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, " Updated statement:");
- print_generic_expr (dump_file, use_stmt, dump_flags);
- fprintf (dump_file, "\n");
+ print_gimple_stmt (dump_file, use_stmt, 0, dump_flags);
}
/* If we replaced a variable index with a constant, then
we would need to update the invariant flag for ADDR_EXPRs. */
- if (TREE_CODE (use_stmt) == GIMPLE_MODIFY_STMT
- && TREE_CODE (GIMPLE_STMT_OPERAND (use_stmt, 1)) == ADDR_EXPR)
+ if (gimple_assign_single_p (use_stmt)
+ && TREE_CODE (gimple_assign_rhs1 (use_stmt)) == ADDR_EXPR)
recompute_tree_invariant_for_addr_expr
- (GIMPLE_STMT_OPERAND (use_stmt, 1));
+ (gimple_assign_rhs1 (use_stmt));
/* If we cleaned up EH information from the statement,
mark its containing block as needing EH cleanups. */
if (maybe_clean_or_replace_eh_stmt (use_stmt, use_stmt))
{
- bitmap_set_bit (need_eh_cleanup, bb_for_stmt (use_stmt)->index);
+ bitmap_set_bit (need_eh_cleanup, gimple_bb (use_stmt)->index);
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, " Flagged to clear EH edges.\n");
}
/* Propagation may expose new trivial copy/constant propagation
opportunities. */
- if (TREE_CODE (use_stmt) == GIMPLE_MODIFY_STMT
- && TREE_CODE (GIMPLE_STMT_OPERAND (use_stmt, 0)) == SSA_NAME
- && (TREE_CODE (GIMPLE_STMT_OPERAND (use_stmt, 1)) == SSA_NAME
- || is_gimple_min_invariant (GIMPLE_STMT_OPERAND (use_stmt,
- 1))))
- {
+ if (gimple_assign_single_p (use_stmt)
+ && TREE_CODE (gimple_assign_lhs (use_stmt)) == SSA_NAME
+ && (TREE_CODE (gimple_assign_rhs1 (use_stmt)) == SSA_NAME
+ || is_gimple_min_invariant (gimple_assign_rhs1 (use_stmt))))
+ {
tree result = get_lhs_or_phi_result (use_stmt);
bitmap_set_bit (interesting_names, SSA_NAME_VERSION (result));
}
@@ -2273,41 +2719,44 @@ propagate_rhs_into_lhs (tree stmt, tree lhs, tree rhs, bitmap interesting_names)
the CFG unexecutable. We want to identify them as PHI nodes
at the destination of those unexecutable edges may become
degenerates. */
- else if (TREE_CODE (use_stmt) == COND_EXPR
- || TREE_CODE (use_stmt) == SWITCH_EXPR
- || TREE_CODE (use_stmt) == GOTO_EXPR)
- {
+ else if (gimple_code (use_stmt) == GIMPLE_COND
+ || gimple_code (use_stmt) == GIMPLE_SWITCH
+ || gimple_code (use_stmt) == GIMPLE_GOTO)
+ {
tree val;
- if (TREE_CODE (use_stmt) == COND_EXPR)
- val = COND_EXPR_COND (use_stmt);
- else if (TREE_CODE (use_stmt) == SWITCH_EXPR)
- val = SWITCH_COND (use_stmt);
+ if (gimple_code (use_stmt) == GIMPLE_COND)
+ val = fold_binary (gimple_cond_code (use_stmt),
+ boolean_type_node,
+ gimple_cond_lhs (use_stmt),
+ gimple_cond_rhs (use_stmt));
+ else if (gimple_code (use_stmt) == GIMPLE_SWITCH)
+ val = gimple_switch_index (use_stmt);
else
- val = GOTO_DESTINATION (use_stmt);
+ val = gimple_goto_dest (use_stmt);
- if (is_gimple_min_invariant (val))
+ if (val && is_gimple_min_invariant (val))
{
- basic_block bb = bb_for_stmt (use_stmt);
+ basic_block bb = gimple_bb (use_stmt);
edge te = find_taken_edge (bb, val);
edge_iterator ei;
edge e;
- block_stmt_iterator bsi;
+ gimple_stmt_iterator gsi, psi;
/* Remove all outgoing edges except TE. */
for (ei = ei_start (bb->succs); (e = ei_safe_edge (ei));)
{
if (e != te)
{
- tree phi;
-
/* Mark all the PHI nodes at the destination of
the unexecutable edge as interesting. */
- for (phi = phi_nodes (e->dest);
- phi;
- phi = PHI_CHAIN (phi))
- {
- tree result = PHI_RESULT (phi);
+ for (psi = gsi_start_phis (e->dest);
+ !gsi_end_p (psi);
+ gsi_next (&psi))
+ {
+ gimple phi = gsi_stmt (psi);
+
+ tree result = gimple_phi_result (phi);
int version = SSA_NAME_VERSION (result);
bitmap_set_bit (interesting_names, version);
@@ -2323,8 +2772,8 @@ propagate_rhs_into_lhs (tree stmt, tree lhs, tree rhs, bitmap interesting_names)
ei_next (&ei);
}
- bsi = bsi_last (bb_for_stmt (use_stmt));
- bsi_remove (&bsi, true);
+ gsi = gsi_last_bb (gimple_bb (use_stmt));
+ gsi_remove (&gsi, true);
/* And fixup the flags on the single remaining edge. */
te->flags &= ~(EDGE_TRUE_VALUE | EDGE_FALSE_VALUE);
@@ -2346,7 +2795,7 @@ propagate_rhs_into_lhs (tree stmt, tree lhs, tree rhs, bitmap interesting_names)
}
}
-/* T is either a PHI node (potentially a degenerate PHI node) or
+/* STMT is either a PHI node (potentially a degenerate PHI node) or
a statement that is a trivial copy or constant initialization.
Attempt to eliminate T by propagating its RHS into all uses of
@@ -2354,12 +2803,12 @@ propagate_rhs_into_lhs (tree stmt, tree lhs, tree rhs, bitmap interesting_names)
for nodes we want to revisit later.
All exit paths should clear INTERESTING_NAMES for the result
- of T. */
+ of STMT. */
static void
-eliminate_const_or_copy (tree t, bitmap interesting_names)
+eliminate_const_or_copy (gimple stmt, bitmap interesting_names)
{
- tree lhs = get_lhs_or_phi_result (t);
+ tree lhs = get_lhs_or_phi_result (stmt);
tree rhs;
int version = SSA_NAME_VERSION (lhs);
@@ -2371,22 +2820,22 @@ eliminate_const_or_copy (tree t, bitmap interesting_names)
if (has_zero_uses (lhs))
{
bitmap_clear_bit (interesting_names, version);
- remove_stmt_or_phi (t);
+ remove_stmt_or_phi (stmt);
return;
}
/* Get the RHS of the assignment or PHI node if the PHI is a
degenerate. */
- rhs = get_rhs_or_phi_arg (t);
+ rhs = get_rhs_or_phi_arg (stmt);
if (!rhs)
{
bitmap_clear_bit (interesting_names, version);
return;
}
- propagate_rhs_into_lhs (t, lhs, rhs, interesting_names);
+ propagate_rhs_into_lhs (stmt, lhs, rhs, interesting_names);
- /* Note that T may well have been deleted by now, so do
+ /* Note that STMT may well have been deleted by now, so do
not access it, instead use the saved version # to clear
T's entry in the worklist. */
bitmap_clear_bit (interesting_names, version);
@@ -2400,12 +2849,13 @@ eliminate_const_or_copy (tree t, bitmap interesting_names)
static void
eliminate_degenerate_phis_1 (basic_block bb, bitmap interesting_names)
{
- tree phi, next;
+ gimple_stmt_iterator gsi;
basic_block son;
- for (phi = phi_nodes (bb); phi; phi = next)
+ for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
- next = PHI_CHAIN (phi);
+ gimple phi = gsi_stmt (gsi);
+
eliminate_const_or_copy (phi, interesting_names);
}
@@ -2512,7 +2962,7 @@ eliminate_degenerate_phis (void)
such edges from the CFG as needed. */
if (!bitmap_empty_p (need_eh_cleanup))
{
- tree_purge_all_dead_eh_edges (need_eh_cleanup);
+ gimple_purge_all_dead_eh_edges (need_eh_cleanup);
BITMAP_FREE (need_eh_cleanup);
}
diff --git a/gcc/tree-ssa-dse.c b/gcc/tree-ssa-dse.c
index 2f7e9238ab1..b4be5142e01 100644
--- a/gcc/tree-ssa-dse.c
+++ b/gcc/tree-ssa-dse.c
@@ -63,7 +63,7 @@ along with GCC; see the file COPYING3. If not see
relationship between dead store and redundant load elimination. In
fact, they are the same transformation applied to different views of
the CFG. */
-
+
struct dse_global_data
{
@@ -97,7 +97,7 @@ static void dse_initialize_block_local_data (struct dom_walk_data *,
bool);
static void dse_optimize_stmt (struct dom_walk_data *,
basic_block,
- block_stmt_iterator);
+ gimple_stmt_iterator);
static void dse_record_phis (struct dom_walk_data *, basic_block);
static void dse_finalize_block (struct dom_walk_data *, basic_block);
static void record_voperand_set (bitmap, bitmap *, unsigned int);
@@ -105,12 +105,13 @@ static void record_voperand_set (bitmap, bitmap *, unsigned int);
/* Returns uid of statement STMT. */
static unsigned
-get_stmt_uid (tree stmt)
+get_stmt_uid (gimple stmt)
{
- if (TREE_CODE (stmt) == PHI_NODE)
- return SSA_NAME_VERSION (PHI_RESULT (stmt)) + gimple_stmt_max_uid (cfun);
+ if (gimple_code (stmt) == GIMPLE_PHI)
+ return SSA_NAME_VERSION (gimple_phi_result (stmt))
+ + gimple_stmt_max_uid (cfun);
- return gimple_stmt_uid (stmt);
+ return gimple_uid (stmt);
}
/* Set bit UID in bitmaps GLOBAL and *LOCAL, creating *LOCAL as needed. */
@@ -162,7 +163,7 @@ memory_ssa_name_same (tree *expr_p, int *walk_subtrees ATTRIBUTE_UNUSED,
{
struct address_walk_data *walk_data = (struct address_walk_data *) data;
tree expr = *expr_p;
- tree def_stmt;
+ gimple def_stmt;
basic_block def_bb;
if (TREE_CODE (expr) != SSA_NAME)
@@ -174,7 +175,7 @@ memory_ssa_name_same (tree *expr_p, int *walk_subtrees ATTRIBUTE_UNUSED,
return NULL_TREE;
def_stmt = SSA_NAME_DEF_STMT (expr);
- def_bb = bb_for_stmt (def_stmt);
+ def_bb = gimple_bb (def_stmt);
/* DEF_STMT must dominate both stores. So if it is in the same
basic block as one, it does not post-dominate that store. */
@@ -185,7 +186,7 @@ memory_ssa_name_same (tree *expr_p, int *walk_subtrees ATTRIBUTE_UNUSED,
|| !dominated_by_p (CDI_POST_DOMINATORS, walk_data->store2_bb,
def_bb))
/* Return non-NULL to stop the walk. */
- return def_stmt;
+ return *expr_p;
}
return NULL_TREE;
@@ -195,14 +196,14 @@ memory_ssa_name_same (tree *expr_p, int *walk_subtrees ATTRIBUTE_UNUSED,
might be modified after STORE1, before control reaches STORE2. */
static bool
-memory_address_same (tree store1, tree store2)
+memory_address_same (gimple store1, gimple store2)
{
struct address_walk_data walk_data;
- walk_data.store1_bb = bb_for_stmt (store1);
- walk_data.store2_bb = bb_for_stmt (store2);
+ walk_data.store1_bb = gimple_bb (store1);
+ walk_data.store2_bb = gimple_bb (store2);
- return (walk_tree (&GIMPLE_STMT_OPERAND (store1, 0), memory_ssa_name_same,
+ return (walk_tree (gimple_assign_lhs_ptr (store1), memory_ssa_name_same,
&walk_data, NULL)
== NULL);
}
@@ -214,15 +215,15 @@ memory_address_same (tree store1, tree store2)
STMT. *USE_P is set to the vop killed by *USE_STMT. */
static bool
-get_kill_of_stmt_lhs (tree stmt,
+get_kill_of_stmt_lhs (gimple stmt,
use_operand_p * first_use_p,
- use_operand_p * use_p, tree * use_stmt)
+ use_operand_p * use_p, gimple * use_stmt)
{
tree lhs;
- gcc_assert (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT);
+ gcc_assert (is_gimple_assign (stmt));
- lhs = GIMPLE_STMT_OPERAND (stmt, 0);
+ lhs = gimple_assign_lhs (stmt);
/* We now walk the chain of single uses of the single VDEFs.
We succeeded finding a kill if the lhs of the use stmt is
@@ -231,7 +232,7 @@ get_kill_of_stmt_lhs (tree stmt,
the stmt. */
do
{
- tree use_lhs, use_rhs;
+ tree use_lhs;
def_operand_p def_p;
/* The stmt must have a single VDEF. */
@@ -245,17 +246,14 @@ get_kill_of_stmt_lhs (tree stmt,
first_use_p = use_p;
/* If there are possible hidden uses, give up. */
- if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT)
- return false;
- use_rhs = GIMPLE_STMT_OPERAND (stmt, 1);
- if (TREE_CODE (use_rhs) == CALL_EXPR
- || (!is_gimple_min_invariant (use_rhs)
- && TREE_CODE (use_rhs) != SSA_NAME))
+ if (!gimple_assign_single_p (stmt)
+ || (TREE_CODE (gimple_assign_rhs1 (stmt)) != SSA_NAME
+ && !is_gimple_min_invariant (gimple_assign_rhs1 (stmt))))
return false;
/* If the use stmts lhs matches the original lhs we have
found the kill, otherwise continue walking. */
- use_lhs = GIMPLE_STMT_OPERAND (stmt, 0);
+ use_lhs = gimple_assign_lhs (stmt);
if (operand_equal_p (use_lhs, lhs, 0))
{
*use_stmt = stmt;
@@ -266,16 +264,16 @@ get_kill_of_stmt_lhs (tree stmt,
}
/* A helper of dse_optimize_stmt.
- Given a GIMPLE_MODIFY_STMT in STMT, check that each VDEF has one
+ Given a GIMPLE_ASSIGN in STMT, check that each VDEF has one
use, and that one use is another VDEF clobbering the first one.
Return TRUE if the above conditions are met, otherwise FALSE. */
static bool
-dse_possible_dead_store_p (tree stmt,
+dse_possible_dead_store_p (gimple stmt,
use_operand_p *first_use_p,
use_operand_p *use_p,
- tree *use_stmt,
+ gimple *use_stmt,
struct dse_global_data *dse_gd,
struct dse_block_local_data *bd)
{
@@ -283,8 +281,9 @@ dse_possible_dead_store_p (tree stmt,
bool fail = false;
def_operand_p var1;
vuse_vec_p vv;
- tree defvar = NULL_TREE, temp;
+ tree defvar = NULL_TREE;
tree prev_defvar = NULL_TREE;
+ gimple temp;
/* We want to verify that each virtual definition in STMT has
precisely one use and that all the virtual definitions are
@@ -309,9 +308,9 @@ dse_possible_dead_store_p (tree stmt,
gcc_assert (*use_p != NULL_USE_OPERAND_P);
*first_use_p = *use_p;
- /* ??? If we hit a PHI_NODE we could skip to the PHI_RESULT uses.
+ /* ??? If we hit a GIMPLE_PHI we could skip to the PHI_RESULT uses.
Don't bother to do that for now. */
- if (TREE_CODE (temp) == PHI_NODE)
+ if (gimple_code (temp) == GIMPLE_PHI)
{
fail = true;
break;
@@ -326,10 +325,10 @@ dse_possible_dead_store_p (tree stmt,
So we must make sure we're talking about the same LHS.
*/
- if (TREE_CODE (temp) == GIMPLE_MODIFY_STMT)
+ if (is_gimple_assign (temp))
{
- tree base1 = get_base_address (GIMPLE_STMT_OPERAND (stmt, 0));
- tree base2 = get_base_address (GIMPLE_STMT_OPERAND (temp, 0));
+ tree base1 = get_base_address (gimple_assign_lhs (stmt));
+ tree base2 = get_base_address (gimple_assign_lhs (temp));
while (base1 && INDIRECT_REF_P (base1))
base1 = TREE_OPERAND (base1, 0);
@@ -360,7 +359,7 @@ dse_possible_dead_store_p (tree stmt,
if (fail)
{
- record_voperand_set (dse_gd->stores, &bd->stores, gimple_stmt_uid (stmt));
+ record_voperand_set (dse_gd->stores, &bd->stores, gimple_uid (stmt));
return false;
}
@@ -382,36 +381,35 @@ dse_possible_dead_store_p (tree stmt,
static void
dse_optimize_stmt (struct dom_walk_data *walk_data,
basic_block bb ATTRIBUTE_UNUSED,
- block_stmt_iterator bsi)
+ gimple_stmt_iterator gsi)
{
struct dse_block_local_data *bd
= (struct dse_block_local_data *)
VEC_last (void_p, walk_data->block_data_stack);
struct dse_global_data *dse_gd
= (struct dse_global_data *) walk_data->global_data;
- tree stmt = bsi_stmt (bsi);
- stmt_ann_t ann = stmt_ann (stmt);
+ gimple stmt = gsi_stmt (gsi);
/* If this statement has no virtual defs, then there is nothing
to do. */
if (ZERO_SSA_OPERANDS (stmt, SSA_OP_VDEF))
return;
- /* We know we have virtual definitions. If this is a GIMPLE_MODIFY_STMT
+ /* We know we have virtual definitions. If this is a GIMPLE_ASSIGN
that's not also a function call, then record it into our table. */
- if (get_call_expr_in (stmt))
+ if (is_gimple_call (stmt) && gimple_call_fndecl (stmt))
return;
- if (ann->has_volatile_ops)
+ if (gimple_has_volatile_ops (stmt))
return;
- if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT)
+ if (is_gimple_assign (stmt))
{
use_operand_p first_use_p = NULL_USE_OPERAND_P;
use_operand_p use_p = NULL;
- tree use_stmt;
+ gimple use_stmt;
- if (!dse_possible_dead_store_p (stmt, &first_use_p, &use_p, &use_stmt,
+ if (!dse_possible_dead_store_p (stmt, &first_use_p, &use_p, &use_stmt,
dse_gd, bd))
return;
@@ -421,8 +419,8 @@ dse_optimize_stmt (struct dom_walk_data *walk_data,
SSA-form variables in the address will have the same values. */
if (use_p != NULL_USE_OPERAND_P
&& bitmap_bit_p (dse_gd->stores, get_stmt_uid (use_stmt))
- && !operand_equal_p (GIMPLE_STMT_OPERAND (stmt, 0),
- GIMPLE_STMT_OPERAND (use_stmt, 0), 0)
+ && !operand_equal_p (gimple_assign_lhs (stmt),
+ gimple_assign_lhs (use_stmt), 0)
&& memory_address_same (stmt, use_stmt))
{
/* If we have precisely one immediate use at this point, but
@@ -431,7 +429,8 @@ dse_optimize_stmt (struct dom_walk_data *walk_data,
memory location. */
if (!get_kill_of_stmt_lhs (stmt, &first_use_p, &use_p, &use_stmt))
{
- record_voperand_set (dse_gd->stores, &bd->stores, gimple_stmt_uid (stmt));
+ record_voperand_set (dse_gd->stores, &bd->stores,
+ gimple_uid (stmt));
return;
}
}
@@ -442,8 +441,8 @@ dse_optimize_stmt (struct dom_walk_data *walk_data,
memory location, then we may have found redundant store. */
if (use_p != NULL_USE_OPERAND_P
&& bitmap_bit_p (dse_gd->stores, get_stmt_uid (use_stmt))
- && operand_equal_p (GIMPLE_STMT_OPERAND (stmt, 0),
- GIMPLE_STMT_OPERAND (use_stmt, 0), 0)
+ && operand_equal_p (gimple_assign_lhs (stmt),
+ gimple_assign_lhs (use_stmt), 0)
&& memory_address_same (stmt, use_stmt))
{
ssa_op_iter op_iter;
@@ -462,18 +461,19 @@ dse_optimize_stmt (struct dom_walk_data *walk_data,
*p = *u; *p = *v; where p might be v, then USE_STMT
acts as a use as well as definition, so store in STMT
is not dead. */
- if (LOADED_SYMS (use_stmt)
- && bitmap_intersect_p (LOADED_SYMS (use_stmt),
- STORED_SYMS (use_stmt)))
+ if (gimple_loaded_syms (use_stmt)
+ && bitmap_intersect_p (gimple_loaded_syms (use_stmt),
+ gimple_stored_syms (use_stmt)))
{
- record_voperand_set (dse_gd->stores, &bd->stores, ann->uid);
+ record_voperand_set (dse_gd->stores, &bd->stores,
+ gimple_uid (stmt));
return;
}
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, " Deleted dead store '");
- print_generic_expr (dump_file, bsi_stmt (bsi), dump_flags);
+ print_gimple_stmt (dump_file, gsi_stmt (gsi), dump_flags, 0);
fprintf (dump_file, "'\n");
}
@@ -481,7 +481,8 @@ dse_optimize_stmt (struct dom_walk_data *walk_data,
stmt_lhs = USE_FROM_PTR (first_use_p);
FOR_EACH_SSA_VDEF_OPERAND (var1, vv, stmt, op_iter)
{
- tree usevar, temp;
+ tree usevar;
+ gimple temp;
single_imm_use (DEF_FROM_PTR (var1), &use_p, &temp);
gcc_assert (VUSE_VECT_NUM_ELEM (*vv) == 1);
@@ -494,14 +495,14 @@ dse_optimize_stmt (struct dom_walk_data *walk_data,
}
/* Remove the dead store. */
- bsi_remove (&bsi, true);
+ gsi_remove (&gsi, true);
/* And release any SSA_NAMEs set in this statement back to the
SSA_NAME manager. */
release_defs (stmt);
}
- record_voperand_set (dse_gd->stores, &bd->stores, gimple_stmt_uid (stmt));
+ record_voperand_set (dse_gd->stores, &bd->stores, gimple_uid (stmt));
}
}
@@ -515,13 +516,15 @@ dse_record_phis (struct dom_walk_data *walk_data, basic_block bb)
VEC_last (void_p, walk_data->block_data_stack);
struct dse_global_data *dse_gd
= (struct dse_global_data *) walk_data->global_data;
- tree phi;
+ gimple phi;
+ gimple_stmt_iterator gsi;
- for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
- if (!is_gimple_reg (PHI_RESULT (phi)))
- record_voperand_set (dse_gd->stores,
- &bd->stores,
- get_stmt_uid (phi));
+ for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+ {
+ phi = gsi_stmt (gsi);
+ if (!is_gimple_reg (gimple_phi_result (phi)))
+ record_voperand_set (dse_gd->stores, &bd->stores, get_stmt_uid (phi));
+ }
}
static void
@@ -633,7 +636,7 @@ struct gimple_opt_pass pass_dse =
static unsigned int
execute_simple_dse (void)
{
- block_stmt_iterator bsi;
+ gimple_stmt_iterator gsi;
basic_block bb;
bitmap variables_loaded = BITMAP_ALLOC (NULL);
unsigned int todo = 0;
@@ -641,24 +644,29 @@ execute_simple_dse (void)
/* Collect into VARIABLES LOADED all variables that are read in function
body. */
FOR_EACH_BB (bb)
- for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
- if (LOADED_SYMS (bsi_stmt (bsi)))
+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+
+ if (gimple_loaded_syms (gsi_stmt (gsi)))
bitmap_ior_into (variables_loaded,
- LOADED_SYMS (bsi_stmt (bsi)));
+ gimple_loaded_syms (gsi_stmt (gsi)));
/* Look for statements writing into the write only variables.
And try to remove them. */
FOR_EACH_BB (bb)
- for (bsi = bsi_start (bb); !bsi_end_p (bsi);)
+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi);)
{
- tree stmt = bsi_stmt (bsi), op;
+ gimple stmt = gsi_stmt (gsi);
+ tree op;
bool removed = false;
ssa_op_iter iter;
- if (STORED_SYMS (stmt) && TREE_CODE (stmt) == GIMPLE_MODIFY_STMT
- && TREE_CODE (stmt) != RETURN_EXPR
- && !bitmap_intersect_p (STORED_SYMS (stmt), variables_loaded))
+ if (gimple_stored_syms (stmt)
+ && !bitmap_empty_p (gimple_stored_syms (stmt))
+ && (is_gimple_assign (stmt)
+ || (is_gimple_call (stmt)
+ && gimple_call_lhs (stmt)))
+ && !bitmap_intersect_p (gimple_stored_syms (stmt), variables_loaded))
{
unsigned int i;
bitmap_iterator bi;
@@ -673,7 +681,7 @@ execute_simple_dse (void)
from removing them as dead. The flag thus has no use for us
and we need to look into all operands. */
- EXECUTE_IF_SET_IN_BITMAP (STORED_SYMS (stmt), 0, i, bi)
+ EXECUTE_IF_SET_IN_BITMAP (gimple_stored_syms (stmt), 0, i, bi)
{
tree var = referenced_var_lookup (i);
if (TREE_ADDRESSABLE (var)
@@ -682,8 +690,8 @@ execute_simple_dse (void)
dead = false;
}
- if (dead && LOADED_SYMS (stmt))
- EXECUTE_IF_SET_IN_BITMAP (LOADED_SYMS (stmt), 0, i, bi)
+ if (dead && gimple_loaded_syms (stmt))
+ EXECUTE_IF_SET_IN_BITMAP (gimple_loaded_syms (stmt), 0, i, bi)
if (TREE_THIS_VOLATILE (referenced_var_lookup (i)))
dead = false;
@@ -695,49 +703,44 @@ execute_simple_dse (void)
/* Look for possible occurrence var = indirect_ref (...) where
indirect_ref itself is volatile. */
- if (dead && TREE_THIS_VOLATILE (GIMPLE_STMT_OPERAND (stmt, 1)))
+ if (dead && is_gimple_assign (stmt)
+ && TREE_THIS_VOLATILE (gimple_assign_rhs1 (stmt)))
dead = false;
if (dead)
{
- tree call = get_call_expr_in (stmt);
-
/* When LHS of var = call (); is dead, simplify it into
call (); saving one operand. */
- if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT
- && call
- && TREE_SIDE_EFFECTS (call))
+ if (is_gimple_call (stmt)
+ && gimple_has_side_effects (stmt))
{
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "Deleted LHS of call: ");
- print_generic_stmt (dump_file, stmt, TDF_SLIM);
+ print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
fprintf (dump_file, "\n");
}
- push_stmt_changes (bsi_stmt_ptr (bsi));
- TREE_BLOCK (call) = TREE_BLOCK (stmt);
- bsi_replace (&bsi, call, false);
- maybe_clean_or_replace_eh_stmt (stmt, call);
- mark_symbols_for_renaming (call);
- pop_stmt_changes (bsi_stmt_ptr (bsi));
+ push_stmt_changes (gsi_stmt_ptr (&gsi));
+ gimple_call_set_lhs (stmt, NULL);
+ pop_stmt_changes (gsi_stmt_ptr (&gsi));
}
else
{
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, " Deleted dead store '");
- print_generic_expr (dump_file, stmt, dump_flags);
+ print_gimple_stmt (dump_file, stmt, 0, dump_flags);
fprintf (dump_file, "'\n");
}
removed = true;
- bsi_remove (&bsi, true);
+ gsi_remove (&gsi, true);
todo |= TODO_cleanup_cfg;
}
todo |= TODO_remove_unused_locals | TODO_ggc_collect;
}
}
if (!removed)
- bsi_next (&bsi);
+ gsi_next (&gsi);
}
BITMAP_FREE (variables_loaded);
return todo;
diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c
index c49f0a48909..6c5c6cabc46 100644
--- a/gcc/tree-ssa-forwprop.c
+++ b/gcc/tree-ssa-forwprop.c
@@ -33,17 +33,13 @@ along with GCC; see the file COPYING3. If not see
#include "tree-dump.h"
#include "langhooks.h"
#include "flags.h"
+#include "gimple.h"
/* This pass propagates the RHS of assignment statements into use
sites of the LHS of the assignment. It's basically a specialized
form of tree combination. It is hoped all of this can disappear
when we have a generalized tree combiner.
- Note carefully that after propagation the resulting statement
- must still be a proper gimple statement. Right now we simply
- only perform propagations we know will result in valid gimple
- code. One day we'll want to generalize this code.
-
One class of common cases we handle is forward propagating a single use
variable into a COND_EXPR.
@@ -162,6 +158,7 @@ static bool forward_propagate_addr_expr (tree name, tree rhs);
/* Set to true if we delete EH edges during the optimization. */
static bool cfg_changed;
+static tree rhs_to_tree (tree type, gimple stmt);
/* Get the next statement we can propagate NAME's value into skipping
trivial copies. Returns the statement that is suitable as a
@@ -169,25 +166,25 @@ static bool cfg_changed;
This only returns destinations in a single-use chain. FINAL_NAME_P
if non-NULL is written to the ssa name that represents the use. */
-static tree
+static gimple
get_prop_dest_stmt (tree name, tree *final_name_p)
{
use_operand_p use;
- tree use_stmt;
+ gimple use_stmt;
do {
/* If name has multiple uses, bail out. */
if (!single_imm_use (name, &use, &use_stmt))
- return NULL_TREE;
+ return NULL;
/* If this is not a trivial copy, we found it. */
- if (TREE_CODE (use_stmt) != GIMPLE_MODIFY_STMT
- || TREE_CODE (GIMPLE_STMT_OPERAND (use_stmt, 0)) != SSA_NAME
- || GIMPLE_STMT_OPERAND (use_stmt, 1) != name)
+ if (!gimple_assign_copy_p (use_stmt)
+ || TREE_CODE (gimple_assign_lhs (use_stmt)) != SSA_NAME
+ || gimple_assign_rhs1 (use_stmt) != name)
break;
/* Continue searching uses of the copy destination. */
- name = GIMPLE_STMT_OPERAND (use_stmt, 0);
+ name = gimple_assign_lhs (use_stmt);
} while (1);
if (final_name_p)
@@ -204,27 +201,28 @@ get_prop_dest_stmt (tree name, tree *final_name_p)
it is set to whether the chain to NAME is a single use chain
or not. SINGLE_USE_P is not written to if SINGLE_USE_ONLY is set. */
-static tree
+static gimple
get_prop_source_stmt (tree name, bool single_use_only, bool *single_use_p)
{
bool single_use = true;
do {
- tree def_stmt = SSA_NAME_DEF_STMT (name);
+ gimple def_stmt = SSA_NAME_DEF_STMT (name);
if (!has_single_use (name))
{
single_use = false;
if (single_use_only)
- return NULL_TREE;
+ return NULL;
}
/* If name is defined by a PHI node or is the default def, bail out. */
- if (TREE_CODE (def_stmt) != GIMPLE_MODIFY_STMT)
- return NULL_TREE;
+ if (gimple_code (def_stmt) != GIMPLE_ASSIGN)
+ return NULL;
/* If name is not a simple copy destination, we found it. */
- if (TREE_CODE (GIMPLE_STMT_OPERAND (def_stmt, 1)) != SSA_NAME)
+ if (!gimple_assign_copy_p (def_stmt)
+ || TREE_CODE (gimple_assign_rhs1 (def_stmt)) != SSA_NAME)
{
tree rhs;
@@ -233,19 +231,19 @@ get_prop_source_stmt (tree name, bool single_use_only, bool *single_use_p)
/* We can look through pointer conversions in the search
for a useful stmt for the comparison folding. */
- rhs = GIMPLE_STMT_OPERAND (def_stmt, 1);
- if (CONVERT_EXPR_P (rhs)
- && TREE_CODE (TREE_OPERAND (rhs, 0)) == SSA_NAME
- && POINTER_TYPE_P (TREE_TYPE (rhs))
- && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (rhs, 0))))
- name = TREE_OPERAND (rhs, 0);
+ rhs = gimple_assign_rhs1 (def_stmt);
+ if (IS_CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def_stmt))
+ && TREE_CODE (rhs) == SSA_NAME
+ && POINTER_TYPE_P (TREE_TYPE (gimple_assign_lhs (def_stmt)))
+ && POINTER_TYPE_P (TREE_TYPE (rhs)))
+ name = rhs;
else
return def_stmt;
}
else
{
/* Continue searching the def of the copy source name. */
- name = GIMPLE_STMT_OPERAND (def_stmt, 1);
+ name = gimple_assign_rhs1 (def_stmt);
}
} while (1);
}
@@ -254,41 +252,43 @@ get_prop_source_stmt (tree name, bool single_use_only, bool *single_use_p)
propagation source. Returns true if so, otherwise false. */
static bool
-can_propagate_from (tree def_stmt)
+can_propagate_from (gimple def_stmt)
{
- tree rhs = GIMPLE_STMT_OPERAND (def_stmt, 1);
use_operand_p use_p;
ssa_op_iter iter;
+ gcc_assert (is_gimple_assign (def_stmt));
/* If the rhs has side-effects we cannot propagate from it. */
- if (TREE_SIDE_EFFECTS (rhs))
+ if (gimple_has_volatile_ops (def_stmt))
return false;
/* If the rhs is a load we cannot propagate from it. */
- if (REFERENCE_CLASS_P (rhs)
- || DECL_P (rhs))
+ if (TREE_CODE_CLASS (gimple_assign_rhs_code (def_stmt)) == tcc_reference
+ || TREE_CODE_CLASS (gimple_assign_rhs_code (def_stmt)) == tcc_declaration)
return false;
/* Constants can be always propagated. */
- if (is_gimple_min_invariant (rhs))
+ if (is_gimple_min_invariant
+ (rhs_to_tree (TREE_TYPE (gimple_assign_lhs (def_stmt)), def_stmt)))
return true;
- /* If any of the SSA operands occurs in abnormal PHIs we cannot
- propagate from this stmt. */
+ /* We cannot propagate ssa names that occur in abnormal phi nodes. */
FOR_EACH_SSA_USE_OPERAND (use_p, def_stmt, iter, SSA_OP_USE)
if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (USE_FROM_PTR (use_p)))
return false;
/* If the definition is a conversion of a pointer to a function type,
- then we can not apply optimizations as some targets require function
- pointers to be canonicalized and in this case this optimization could
- eliminate a necessary canonicalization. */
- if (CONVERT_EXPR_P (rhs)
- && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (rhs, 0)))
- && TREE_CODE (TREE_TYPE (TREE_TYPE
- (TREE_OPERAND (rhs, 0)))) == FUNCTION_TYPE)
- return false;
-
+ then we can not apply optimizations as some targets require
+ function pointers to be canonicalized and in this case this
+ optimization could eliminate a necessary canonicalization. */
+ if (is_gimple_assign (def_stmt)
+ && (IS_CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def_stmt))))
+ {
+ tree rhs = gimple_assign_rhs1 (def_stmt);
+ if (POINTER_TYPE_P (TREE_TYPE (rhs))
+ && TREE_CODE (TREE_TYPE (TREE_TYPE (rhs))) == FUNCTION_TYPE)
+ return false;
+ }
return true;
}
@@ -299,10 +299,10 @@ can_propagate_from (tree def_stmt)
as well, otherwise false. */
static bool
-remove_prop_source_from_use (tree name, tree up_to_stmt)
+remove_prop_source_from_use (tree name, gimple up_to_stmt)
{
- block_stmt_iterator bsi;
- tree stmt;
+ gimple_stmt_iterator gsi;
+ gimple stmt;
do {
if (!has_zero_uses (name))
@@ -312,16 +312,38 @@ remove_prop_source_from_use (tree name, tree up_to_stmt)
if (stmt == up_to_stmt)
return true;
- bsi = bsi_for_stmt (stmt);
+ gsi = gsi_for_stmt (stmt);
release_defs (stmt);
- bsi_remove (&bsi, true);
+ gsi_remove (&gsi, true);
- name = GIMPLE_STMT_OPERAND (stmt, 1);
- } while (TREE_CODE (name) == SSA_NAME);
+ name = (gimple_assign_copy_p (stmt)) ? gimple_assign_rhs1 (stmt) : NULL;
+ } while (name && TREE_CODE (name) == SSA_NAME);
return false;
}
+/* Return the rhs of a gimple_assign STMT in a form of a single tree,
+ converted to type TYPE.
+
+ This should disappear, but is needed so we can combine expressions and use
+ the fold() interfaces. Long term, we need to develop folding and combine
+ routines that deal with gimple exclusively . */
+
+static tree
+rhs_to_tree (tree type, gimple stmt)
+{
+ enum tree_code code = gimple_assign_rhs_code (stmt);
+ if (get_gimple_rhs_class (code) == GIMPLE_BINARY_RHS)
+ return fold_convert (type, build2 (code, type, gimple_assign_rhs1 (stmt),
+ gimple_assign_rhs2 (stmt)));
+ else if (get_gimple_rhs_class (code) == GIMPLE_UNARY_RHS)
+ return fold_convert (type, build1 (code, type, gimple_assign_rhs1 (stmt)));
+ else if (get_gimple_rhs_class (code) == GIMPLE_SINGLE_RHS)
+ return gimple_assign_rhs1 (stmt);
+ else
+ gcc_unreachable ();
+}
+
/* Combine OP0 CODE OP1 in the context of a COND_EXPR. Returns
the folded result in a form suitable for COND_EXPR_COND or
NULL_TREE, if there is no suitable simplified form. If
@@ -347,28 +369,124 @@ combine_cond_expr_cond (enum tree_code code, tree type,
t = canonicalize_cond_expr_cond (t);
/* Bail out if we required an invariant but didn't get one. */
- if (!t
- || (invariant_only
- && !is_gimple_min_invariant (t)))
+ if (!t || (invariant_only && !is_gimple_min_invariant (t)))
return NULL_TREE;
return t;
}
/* Propagate from the ssa name definition statements of COND_EXPR
- in statement STMT into the conditional if that simplifies it.
+ in GIMPLE_COND statement STMT into the conditional if that simplifies it.
+ Returns zero if no statement was changed, one if there were
+ changes and two if cfg_cleanup needs to run.
+
+ This must be kept in sync with forward_propagate_into_cond. */
+
+static int
+forward_propagate_into_gimple_cond (gimple stmt)
+{
+ int did_something = 0;
+
+ do {
+ tree tmp = NULL_TREE;
+ tree name, rhs0 = NULL_TREE, rhs1 = NULL_TREE;
+ gimple def_stmt;
+ bool single_use0_p = false, single_use1_p = false;
+ enum tree_code code = gimple_cond_code (stmt);
+
+ /* We can do tree combining on SSA_NAME and comparison expressions. */
+ if (TREE_CODE_CLASS (gimple_cond_code (stmt)) == tcc_comparison
+ && TREE_CODE (gimple_cond_lhs (stmt)) == SSA_NAME)
+ {
+ /* For comparisons use the first operand, that is likely to
+ simplify comparisons against constants. */
+ name = gimple_cond_lhs (stmt);
+ def_stmt = get_prop_source_stmt (name, false, &single_use0_p);
+ if (def_stmt && can_propagate_from (def_stmt))
+ {
+ tree op1 = gimple_cond_rhs (stmt);
+ rhs0 = rhs_to_tree (TREE_TYPE (op1), def_stmt);
+ tmp = combine_cond_expr_cond (code, boolean_type_node, rhs0,
+ op1, !single_use0_p);
+ }
+ /* If that wasn't successful, try the second operand. */
+ if (tmp == NULL_TREE
+ && TREE_CODE (gimple_cond_rhs (stmt)) == SSA_NAME)
+ {
+ tree op0 = gimple_cond_lhs (stmt);
+ name = gimple_cond_rhs (stmt);
+ def_stmt = get_prop_source_stmt (name, false, &single_use1_p);
+ if (!def_stmt || !can_propagate_from (def_stmt))
+ return did_something;
+
+ rhs1 = rhs_to_tree (TREE_TYPE (op0), def_stmt);
+ tmp = combine_cond_expr_cond (code, boolean_type_node, op0, rhs1,
+ !single_use1_p);
+ }
+ /* If that wasn't successful either, try both operands. */
+ if (tmp == NULL_TREE
+ && rhs0 != NULL_TREE
+ && rhs1 != NULL_TREE)
+ tmp = combine_cond_expr_cond (code, boolean_type_node, rhs0,
+ fold_convert (TREE_TYPE (rhs0), rhs1),
+ !(single_use0_p && single_use1_p));
+ }
+
+ if (tmp)
+ {
+ if (dump_file && tmp)
+ {
+ tree cond = build2 (gimple_cond_code (stmt),
+ boolean_type_node,
+ gimple_cond_lhs (stmt),
+ gimple_cond_rhs (stmt));
+ fprintf (dump_file, " Replaced '");
+ print_generic_expr (dump_file, cond, 0);
+ fprintf (dump_file, "' with '");
+ print_generic_expr (dump_file, tmp, 0);
+ fprintf (dump_file, "'\n");
+ }
+
+ gimple_cond_set_condition_from_tree (stmt, unshare_expr (tmp));
+ update_stmt (stmt);
+
+ /* Remove defining statements. */
+ remove_prop_source_from_use (name, NULL);
+
+ if (is_gimple_min_invariant (tmp))
+ did_something = 2;
+ else if (did_something == 0)
+ did_something = 1;
+
+ /* Continue combining. */
+ continue;
+ }
+
+ break;
+ } while (1);
+
+ return did_something;
+}
+
+
+/* Propagate from the ssa name definition statements of COND_EXPR
+ in the rhs of statement STMT into the conditional if that simplifies it.
Returns zero if no statement was changed, one if there were
- changes and two if cfg_cleanup needs to run. */
+ changes and two if cfg_cleanup needs to run.
+
+ This must be kept in sync with forward_propagate_into_gimple_cond. */
static int
-forward_propagate_into_cond (tree cond_expr, tree stmt)
+forward_propagate_into_cond (gimple_stmt_iterator *gsi_p)
{
+ gimple stmt = gsi_stmt (*gsi_p);
int did_something = 0;
do {
tree tmp = NULL_TREE;
- tree cond = COND_EXPR_COND (cond_expr);
- tree name, def_stmt, rhs0 = NULL_TREE, rhs1 = NULL_TREE;
+ tree cond = gimple_assign_rhs1 (stmt);
+ tree name, rhs0 = NULL_TREE, rhs1 = NULL_TREE;
+ gimple def_stmt;
bool single_use0_p = false, single_use1_p = false;
/* We can do tree combining on SSA_NAME and comparison expressions. */
@@ -379,14 +497,12 @@ forward_propagate_into_cond (tree cond_expr, tree stmt)
simplify comparisons against constants. */
name = TREE_OPERAND (cond, 0);
def_stmt = get_prop_source_stmt (name, false, &single_use0_p);
- if (def_stmt != NULL_TREE
- && can_propagate_from (def_stmt))
+ if (def_stmt && can_propagate_from (def_stmt))
{
tree op1 = TREE_OPERAND (cond, 1);
- rhs0 = GIMPLE_STMT_OPERAND (def_stmt, 1);
+ rhs0 = rhs_to_tree (TREE_TYPE (op1), def_stmt);
tmp = combine_cond_expr_cond (TREE_CODE (cond), boolean_type_node,
- fold_convert (TREE_TYPE (op1), rhs0),
- op1, !single_use0_p);
+ rhs0, op1, !single_use0_p);
}
/* If that wasn't successful, try the second operand. */
if (tmp == NULL_TREE
@@ -395,34 +511,30 @@ forward_propagate_into_cond (tree cond_expr, tree stmt)
tree op0 = TREE_OPERAND (cond, 0);
name = TREE_OPERAND (cond, 1);
def_stmt = get_prop_source_stmt (name, false, &single_use1_p);
- if (def_stmt == NULL_TREE
- || !can_propagate_from (def_stmt))
+ if (!def_stmt || !can_propagate_from (def_stmt))
return did_something;
- rhs1 = GIMPLE_STMT_OPERAND (def_stmt, 1);
+ rhs1 = rhs_to_tree (TREE_TYPE (op0), def_stmt);
tmp = combine_cond_expr_cond (TREE_CODE (cond), boolean_type_node,
- op0,
- fold_convert (TREE_TYPE (op0), rhs1),
- !single_use1_p);
+ op0, rhs1, !single_use1_p);
}
/* If that wasn't successful either, try both operands. */
if (tmp == NULL_TREE
&& rhs0 != NULL_TREE
&& rhs1 != NULL_TREE)
tmp = combine_cond_expr_cond (TREE_CODE (cond), boolean_type_node,
- rhs0,
- fold_convert (TREE_TYPE (rhs0), rhs1),
+ rhs0, fold_convert (TREE_TYPE (rhs0),
+ rhs1),
!(single_use0_p && single_use1_p));
}
else if (TREE_CODE (cond) == SSA_NAME)
{
name = cond;
def_stmt = get_prop_source_stmt (name, true, NULL);
- if (def_stmt == NULL_TREE
- || !can_propagate_from (def_stmt))
+ if (def_stmt || !can_propagate_from (def_stmt))
return did_something;
- rhs0 = GIMPLE_STMT_OPERAND (def_stmt, 1);
+ rhs0 = gimple_assign_rhs1 (def_stmt);
tmp = combine_cond_expr_cond (NE_EXPR, boolean_type_node, rhs0,
build_int_cst (TREE_TYPE (rhs0), 0),
false);
@@ -439,7 +551,8 @@ forward_propagate_into_cond (tree cond_expr, tree stmt)
fprintf (dump_file, "'\n");
}
- COND_EXPR_COND (cond_expr) = unshare_expr (tmp);
+ gimple_assign_set_rhs_from_tree (gsi_p, unshare_expr (tmp));
+ stmt = gsi_stmt (*gsi_p);
update_stmt (stmt);
/* Remove defining statements. */
@@ -464,20 +577,20 @@ forward_propagate_into_cond (tree cond_expr, tree stmt)
relevant data structures to match. */
static void
-tidy_after_forward_propagate_addr (tree stmt)
+tidy_after_forward_propagate_addr (gimple stmt)
{
/* We may have turned a trapping insn into a non-trapping insn. */
if (maybe_clean_or_replace_eh_stmt (stmt, stmt)
- && tree_purge_dead_eh_edges (bb_for_stmt (stmt)))
+ && gimple_purge_dead_eh_edges (gimple_bb (stmt)))
cfg_changed = true;
- if (TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 1)) == ADDR_EXPR)
- recompute_tree_invariant_for_addr_expr (GIMPLE_STMT_OPERAND (stmt, 1));
+ if (TREE_CODE (gimple_assign_rhs1 (stmt)) == ADDR_EXPR)
+ recompute_tree_invariant_for_addr_expr (gimple_assign_rhs1 (stmt));
mark_symbols_for_renaming (stmt);
}
-/* DEF_RHS contains the address of the 0th element in an array.
+/* DEF_RHS contains the address of the 0th element in an array.
USE_STMT uses type of DEF_RHS to compute the address of an
arbitrary element within the array. The (variable) byte offset
of the element is contained in OFFSET.
@@ -494,9 +607,11 @@ tidy_after_forward_propagate_addr (tree stmt)
static bool
forward_propagate_addr_into_variable_array_index (tree offset,
- tree def_rhs, tree use_stmt)
+ tree def_rhs,
+ gimple_stmt_iterator *use_stmt_gsi)
{
tree index;
+ gimple offset_def, use_stmt = gsi_stmt (*use_stmt_gsi);
/* Try to find an expression for a proper index. This is either
a multiplication expression by the element size or just the
@@ -506,31 +621,32 @@ forward_propagate_addr_into_variable_array_index (tree offset,
else
{
/* Get the offset's defining statement. */
- offset = SSA_NAME_DEF_STMT (offset);
+ offset_def = SSA_NAME_DEF_STMT (offset);
/* The statement which defines OFFSET before type conversion
- must be a simple GIMPLE_MODIFY_STMT. */
- if (TREE_CODE (offset) != GIMPLE_MODIFY_STMT)
+ must be a simple GIMPLE_ASSIGN. */
+ if (gimple_code (offset_def) != GIMPLE_ASSIGN)
return false;
/* The RHS of the statement which defines OFFSET must be a
multiplication of an object by the size of the array elements.
This implicitly verifies that the size of the array elements
is constant. */
- offset = GIMPLE_STMT_OPERAND (offset, 1);
- if (TREE_CODE (offset) != MULT_EXPR
- || TREE_CODE (TREE_OPERAND (offset, 1)) != INTEGER_CST
- || !simple_cst_equal (TREE_OPERAND (offset, 1),
- TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (def_rhs)))))
+ offset = gimple_assign_rhs1 (offset_def);
+ if (gimple_assign_rhs_code (offset_def) != MULT_EXPR
+ || TREE_CODE (gimple_assign_rhs2 (offset_def)) != INTEGER_CST
+ || !simple_cst_equal (gimple_assign_rhs2 (offset_def),
+ TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (def_rhs)))))
return false;
/* The first operand to the MULT_EXPR is the desired index. */
- index = TREE_OPERAND (offset, 0);
+ index = offset;
}
/* Replace the pointer addition with array indexing. */
- GIMPLE_STMT_OPERAND (use_stmt, 1) = unshare_expr (def_rhs);
- TREE_OPERAND (TREE_OPERAND (GIMPLE_STMT_OPERAND (use_stmt, 1), 0), 1)
+ gimple_assign_set_rhs_from_tree (use_stmt_gsi, unshare_expr (def_rhs));
+ use_stmt = gsi_stmt (*use_stmt_gsi);
+ TREE_OPERAND (TREE_OPERAND (gimple_assign_rhs1 (use_stmt), 0), 1)
= index;
/* That should have created gimple, so there is no need to
@@ -546,21 +662,25 @@ forward_propagate_addr_into_variable_array_index (tree offset,
Try to forward propagate the ADDR_EXPR into the use USE_STMT.
Often this will allow for removal of an ADDR_EXPR and INDIRECT_REF
node or for recovery of array indexing from pointer arithmetic.
-
+
Return true if the propagation was successful (the propagation can
be not totally successful, yet things may have been changed). */
static bool
-forward_propagate_addr_expr_1 (tree name, tree def_rhs, tree use_stmt,
+forward_propagate_addr_expr_1 (tree name, tree def_rhs,
+ gimple_stmt_iterator *use_stmt_gsi,
bool single_use_p)
{
- tree lhs, rhs, array_ref;
+ tree lhs, rhs, rhs2, array_ref;
tree *rhsp, *lhsp;
+ gimple use_stmt = gsi_stmt (*use_stmt_gsi);
+ enum tree_code rhs_code;
gcc_assert (TREE_CODE (def_rhs) == ADDR_EXPR);
- lhs = GIMPLE_STMT_OPERAND (use_stmt, 0);
- rhs = GIMPLE_STMT_OPERAND (use_stmt, 1);
+ lhs = gimple_assign_lhs (use_stmt);
+ rhs_code = gimple_assign_rhs_code (use_stmt);
+ rhs = gimple_assign_rhs1 (use_stmt);
/* Trivial cases. The use statement could be a trivial copy or a
useless conversion. Recurse to the uses of the lhs as copyprop does
@@ -568,21 +688,22 @@ forward_propagate_addr_expr_1 (tree name, tree def_rhs, tree use_stmt,
all useless conversions. Treat the case of a single-use name and
a conversion to def_rhs type separate, though. */
if (TREE_CODE (lhs) == SSA_NAME
- && (rhs == name
- || CONVERT_EXPR_P (rhs))
- && useless_type_conversion_p (TREE_TYPE (rhs), TREE_TYPE (def_rhs)))
+ && ((rhs_code == SSA_NAME && rhs == name)
+ || IS_CONVERT_EXPR_CODE_P (rhs_code))
+ && useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (def_rhs)))
{
/* Only recurse if we don't deal with a single use. */
if (!single_use_p)
return forward_propagate_addr_expr (lhs, def_rhs);
- GIMPLE_STMT_OPERAND (use_stmt, 1) = unshare_expr (def_rhs);
+ gimple_assign_set_rhs1 (use_stmt, unshare_expr (def_rhs));
+ gimple_assign_set_rhs_code (use_stmt, TREE_CODE (def_rhs));
return true;
}
/* Now strip away any outer COMPONENT_REF/ARRAY_REF nodes from the LHS.
ADDR_EXPR will not appear on the LHS. */
- lhsp = &GIMPLE_STMT_OPERAND (use_stmt, 0);
+ lhsp = gimple_assign_lhs_ptr (use_stmt);
while (handled_component_p (*lhsp))
lhsp = &TREE_OPERAND (*lhsp, 0);
lhs = *lhsp;
@@ -609,13 +730,13 @@ forward_propagate_addr_expr_1 (tree name, tree def_rhs, tree use_stmt,
/* Strip away any outer COMPONENT_REF, ARRAY_REF or ADDR_EXPR
nodes from the RHS. */
- rhsp = &GIMPLE_STMT_OPERAND (use_stmt, 1);
+ rhsp = gimple_assign_rhs1_ptr (use_stmt);
while (handled_component_p (*rhsp)
|| TREE_CODE (*rhsp) == ADDR_EXPR)
rhsp = &TREE_OPERAND (*rhsp, 0);
rhs = *rhsp;
- /* Now see if the RHS node is an INDIRECT_REF using NAME. If so,
+ /* Now see if the RHS node is an INDIRECT_REF using NAME. If so,
propagate the ADDR_EXPR into the use of NAME and fold the result. */
if (TREE_CODE (rhs) == INDIRECT_REF
&& TREE_OPERAND (rhs, 0) == name
@@ -654,8 +775,8 @@ forward_propagate_addr_expr_1 (tree name, tree def_rhs, tree use_stmt,
/* If we have folded the VCE, then we have to create a new statement. */
if (TREE_CODE (new_rhs) != VIEW_CONVERT_EXPR)
{
- block_stmt_iterator bsi = bsi_for_stmt (use_stmt);
- new_rhs = force_gimple_operand_bsi (&bsi, new_rhs, true, NULL, true, BSI_SAME_STMT);
+ gimple_stmt_iterator gsi = gsi_for_stmt (use_stmt);
+ new_rhs = force_gimple_operand_gsi (&gsi, new_rhs, true, NULL, true, GSI_SAME_STMT);
/* As we change the deference to a SSA_NAME, we need to return false to make sure that
the statement does not get removed. */
res = false;
@@ -668,8 +789,8 @@ forward_propagate_addr_expr_1 (tree name, tree def_rhs, tree use_stmt,
/* If the use of the ADDR_EXPR is not a POINTER_PLUS_EXPR, there
is nothing to do. */
- if (TREE_CODE (rhs) != POINTER_PLUS_EXPR
- || TREE_OPERAND (rhs, 0) != name)
+ if (gimple_assign_rhs_code (use_stmt) != POINTER_PLUS_EXPR
+ || gimple_assign_rhs1 (use_stmt) != name)
return false;
/* The remaining cases are all for turning pointer arithmetic into
@@ -682,44 +803,33 @@ forward_propagate_addr_expr_1 (tree name, tree def_rhs, tree use_stmt,
|| !integer_zerop (TREE_OPERAND (array_ref, 1)))
return false;
+ rhs2 = gimple_assign_rhs2 (use_stmt);
/* Try to optimize &x[0] p+ C where C is a multiple of the size
of the elements in X into &x[C/element size]. */
- if (TREE_CODE (TREE_OPERAND (rhs, 1)) == INTEGER_CST)
+ if (TREE_CODE (rhs2) == INTEGER_CST)
{
- tree orig = unshare_expr (rhs);
- TREE_OPERAND (rhs, 0) = unshare_expr (def_rhs);
-
- /* If folding succeeds, then we have just exposed new variables
- in USE_STMT which will need to be renamed. If folding fails,
- then we need to put everything back the way it was. */
- if (fold_stmt_inplace (use_stmt))
+ tree new_rhs = maybe_fold_stmt_addition (gimple_expr_type (use_stmt),
+ array_ref, rhs2);
+ if (new_rhs)
{
+ gimple_assign_set_rhs_from_tree (use_stmt_gsi, new_rhs);
+ use_stmt = gsi_stmt (*use_stmt_gsi);
+ update_stmt (use_stmt);
tidy_after_forward_propagate_addr (use_stmt);
return true;
}
- else
- {
- GIMPLE_STMT_OPERAND (use_stmt, 1) = orig;
- update_stmt (use_stmt);
- return false;
- }
}
/* Try to optimize &x[0] p+ OFFSET where OFFSET is defined by
converting a multiplication of an index by the size of the
array elements, then the result is converted into the proper
type for the arithmetic. */
- if (TREE_CODE (TREE_OPERAND (rhs, 1)) == SSA_NAME
+ if (TREE_CODE (rhs2) == SSA_NAME
/* Avoid problems with IVopts creating PLUS_EXPRs with a
different type than their operands. */
- && useless_type_conversion_p (TREE_TYPE (rhs), TREE_TYPE (name)))
- {
- bool res;
-
- res = forward_propagate_addr_into_variable_array_index (TREE_OPERAND (rhs, 1),
- def_rhs, use_stmt);
- return res;
- }
+ && useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (name)))
+ return forward_propagate_addr_into_variable_array_index (rhs2, def_rhs,
+ use_stmt_gsi);
return false;
}
@@ -733,9 +843,9 @@ forward_propagate_addr_expr_1 (tree name, tree def_rhs, tree use_stmt,
static bool
forward_propagate_addr_expr (tree name, tree rhs)
{
- int stmt_loop_depth = bb_for_stmt (SSA_NAME_DEF_STMT (name))->loop_depth;
+ int stmt_loop_depth = gimple_bb (SSA_NAME_DEF_STMT (name))->loop_depth;
imm_use_iterator iter;
- tree use_stmt;
+ gimple use_stmt;
bool all = true;
bool single_use_p = has_single_use (name);
@@ -746,16 +856,16 @@ forward_propagate_addr_expr (tree name, tree rhs)
/* If the use is not in a simple assignment statement, then
there is nothing we can do. */
- if (TREE_CODE (use_stmt) != GIMPLE_MODIFY_STMT)
+ if (gimple_code (use_stmt) != GIMPLE_ASSIGN)
{
all = false;
continue;
}
/* If the use is in a deeper loop nest, then we do not want
- to propagate the ADDR_EXPR into the loop as that is likely
- adding expression evaluations into the loop. */
- if (bb_for_stmt (use_stmt)->loop_depth > stmt_loop_depth)
+ to propagate the ADDR_EXPR into the loop as that is likely
+ adding expression evaluations into the loop. */
+ if (gimple_bb (use_stmt)->loop_depth > stmt_loop_depth)
{
all = false;
continue;
@@ -763,30 +873,34 @@ forward_propagate_addr_expr (tree name, tree rhs)
push_stmt_changes (&use_stmt);
- result = forward_propagate_addr_expr_1 (name, rhs, use_stmt,
- single_use_p);
+ {
+ gimple_stmt_iterator gsi = gsi_for_stmt (use_stmt);
+ result = forward_propagate_addr_expr_1 (name, rhs, &gsi,
+ single_use_p);
+ use_stmt = gsi_stmt (gsi);
+ }
all &= result;
pop_stmt_changes (&use_stmt);
/* Remove intermediate now unused copy and conversion chains. */
- use_rhs = GIMPLE_STMT_OPERAND (use_stmt, 1);
+ use_rhs = gimple_assign_rhs1 (use_stmt);
if (result
- && TREE_CODE (GIMPLE_STMT_OPERAND (use_stmt, 0)) == SSA_NAME
+ && TREE_CODE (gimple_assign_lhs (use_stmt)) == SSA_NAME
&& (TREE_CODE (use_rhs) == SSA_NAME
|| (CONVERT_EXPR_P (use_rhs)
&& TREE_CODE (TREE_OPERAND (use_rhs, 0)) == SSA_NAME)))
{
- block_stmt_iterator bsi = bsi_for_stmt (use_stmt);
+ gimple_stmt_iterator gsi = gsi_for_stmt (use_stmt);
release_defs (use_stmt);
- bsi_remove (&bsi, true);
+ gsi_remove (&gsi, true);
}
}
return all;
}
-/* Forward propagate the comparison COND defined in STMT like
+/* Forward propagate the comparison defined in STMT like
cond_1 = x CMP y to uses of the form
a_1 = (T')cond_1
a_1 = !cond_1
@@ -794,83 +908,95 @@ forward_propagate_addr_expr (tree name, tree rhs)
Returns true if stmt is now unused. */
static bool
-forward_propagate_comparison (tree cond, tree stmt)
+forward_propagate_comparison (gimple stmt)
{
- tree name = GIMPLE_STMT_OPERAND (stmt, 0);
- tree use_stmt, tmp = NULL_TREE;
+ tree name = gimple_assign_lhs (stmt);
+ gimple use_stmt;
+ tree tmp = NULL_TREE;
/* Don't propagate ssa names that occur in abnormal phis. */
- if ((TREE_CODE (TREE_OPERAND (cond, 0)) == SSA_NAME
- && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (TREE_OPERAND (cond, 0)))
- || (TREE_CODE (TREE_OPERAND (cond, 1)) == SSA_NAME
- && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (TREE_OPERAND (cond, 1))))
+ if ((TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME
+ && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (gimple_assign_rhs1 (stmt)))
+ || (TREE_CODE (gimple_assign_rhs2 (stmt)) == SSA_NAME
+ && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (gimple_assign_rhs2 (stmt))))
return false;
/* Do not un-cse comparisons. But propagate through copies. */
use_stmt = get_prop_dest_stmt (name, &name);
- if (use_stmt == NULL_TREE)
+ if (!use_stmt)
return false;
/* Conversion of the condition result to another integral type. */
- if (TREE_CODE (use_stmt) == GIMPLE_MODIFY_STMT
- && (CONVERT_EXPR_P (GIMPLE_STMT_OPERAND (use_stmt, 1))
- || COMPARISON_CLASS_P (GIMPLE_STMT_OPERAND (use_stmt, 1))
- || TREE_CODE (GIMPLE_STMT_OPERAND (use_stmt, 1)) == TRUTH_NOT_EXPR)
- && INTEGRAL_TYPE_P (TREE_TYPE (GIMPLE_STMT_OPERAND (use_stmt, 0))))
+ if (is_gimple_assign (use_stmt)
+ && (IS_CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (use_stmt))
+ || TREE_CODE_CLASS (gimple_assign_rhs_code (use_stmt))
+ == tcc_comparison
+ || gimple_assign_rhs_code (use_stmt) == TRUTH_NOT_EXPR)
+ && INTEGRAL_TYPE_P (TREE_TYPE (gimple_assign_lhs (use_stmt))))
{
- tree lhs = GIMPLE_STMT_OPERAND (use_stmt, 0);
- tree rhs = GIMPLE_STMT_OPERAND (use_stmt, 1);
+ tree lhs = gimple_assign_lhs (use_stmt);
/* We can propagate the condition into a conversion. */
- if (CONVERT_EXPR_P (rhs))
+ if (IS_CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (use_stmt)))
{
/* Avoid using fold here as that may create a COND_EXPR with
non-boolean condition as canonical form. */
- tmp = build2 (TREE_CODE (cond), TREE_TYPE (lhs),
- TREE_OPERAND (cond, 0), TREE_OPERAND (cond, 1));
+ tmp = build2 (gimple_assign_rhs_code (stmt), TREE_TYPE (lhs),
+ gimple_assign_rhs1 (stmt), gimple_assign_rhs2 (stmt));
}
/* We can propagate the condition into X op CST where op
is EQ_EXPR or NE_EXPR and CST is either one or zero. */
- else if (COMPARISON_CLASS_P (rhs)
- && TREE_CODE (TREE_OPERAND (rhs, 0)) == SSA_NAME
- && TREE_CODE (TREE_OPERAND (rhs, 1)) == INTEGER_CST)
- {
- enum tree_code code = TREE_CODE (rhs);
- tree cst = TREE_OPERAND (rhs, 1);
-
- tmp = combine_cond_expr_cond (code, TREE_TYPE (lhs),
- fold_convert (TREE_TYPE (cst), cond),
- cst, false);
- if (tmp == NULL_TREE)
- return false;
- }
+ else if (TREE_CODE_CLASS (gimple_assign_rhs_code (use_stmt))
+ == tcc_comparison
+ && TREE_CODE (gimple_assign_rhs1 (use_stmt)) == SSA_NAME
+ && TREE_CODE (gimple_assign_rhs2 (use_stmt)) == INTEGER_CST)
+ {
+ enum tree_code code = gimple_assign_rhs_code (use_stmt);
+ tree cst = gimple_assign_rhs2 (use_stmt);
+ tree cond;
+
+ cond = build2 (gimple_assign_rhs_code (stmt),
+ TREE_TYPE (cst),
+ gimple_assign_rhs1 (stmt),
+ gimple_assign_rhs2 (stmt));
+
+ tmp = combine_cond_expr_cond (code, TREE_TYPE (lhs), cond, cst, false);
+ if (tmp == NULL_TREE)
+ return false;
+ }
/* We can propagate the condition into a statement that
computes the logical negation of the comparison result. */
- else if (TREE_CODE (rhs) == TRUTH_NOT_EXPR)
+ else if (gimple_assign_rhs_code (use_stmt) == TRUTH_NOT_EXPR)
{
- tree type = TREE_TYPE (TREE_OPERAND (cond, 0));
+ tree type = TREE_TYPE (gimple_assign_rhs1 (stmt));
bool nans = HONOR_NANS (TYPE_MODE (type));
enum tree_code code;
- code = invert_tree_comparison (TREE_CODE (cond), nans);
+ code = invert_tree_comparison (gimple_assign_rhs_code (stmt), nans);
if (code == ERROR_MARK)
return false;
- tmp = build2 (code, TREE_TYPE (lhs), TREE_OPERAND (cond, 0),
- TREE_OPERAND (cond, 1));
+ tmp = build2 (code, TREE_TYPE (lhs), gimple_assign_rhs1 (stmt),
+ gimple_assign_rhs2 (stmt));
}
else
return false;
- GIMPLE_STMT_OPERAND (use_stmt, 1) = unshare_expr (tmp);
- update_stmt (use_stmt);
+ {
+ gimple_stmt_iterator gsi = gsi_for_stmt (use_stmt);
+ gimple_assign_set_rhs_from_tree (&gsi, unshare_expr (tmp));
+ use_stmt = gsi_stmt (gsi);
+ update_stmt (use_stmt);
+ }
/* Remove defining statements. */
remove_prop_source_from_use (name, stmt);
if (dump_file && (dump_flags & TDF_DETAILS))
{
+ tree old_rhs = rhs_to_tree (TREE_TYPE (gimple_assign_lhs (stmt)),
+ stmt);
fprintf (dump_file, " Replaced '");
- print_generic_expr (dump_file, rhs, dump_flags);
+ print_generic_expr (dump_file, old_rhs, dump_flags);
fprintf (dump_file, "' with '");
print_generic_expr (dump_file, tmp, dump_flags);
fprintf (dump_file, "'\n");
@@ -897,23 +1023,24 @@ forward_propagate_comparison (tree cond, tree stmt)
than one forward link. */
static void
-simplify_not_neg_expr (tree stmt)
+simplify_not_neg_expr (gimple_stmt_iterator *gsi_p)
{
- tree rhs = GIMPLE_STMT_OPERAND (stmt, 1);
- tree rhs_def_stmt = SSA_NAME_DEF_STMT (TREE_OPERAND (rhs, 0));
+ gimple stmt = gsi_stmt (*gsi_p);
+ tree rhs = gimple_assign_rhs1 (stmt);
+ gimple rhs_def_stmt = SSA_NAME_DEF_STMT (rhs);
/* See if the RHS_DEF_STMT has the same form as our statement. */
- if (TREE_CODE (rhs_def_stmt) == GIMPLE_MODIFY_STMT
- && TREE_CODE (GIMPLE_STMT_OPERAND (rhs_def_stmt, 1)) == TREE_CODE (rhs))
+ if (is_gimple_assign (rhs_def_stmt)
+ && gimple_assign_rhs_code (rhs_def_stmt) == gimple_assign_rhs_code (stmt))
{
- tree rhs_def_operand =
- TREE_OPERAND (GIMPLE_STMT_OPERAND (rhs_def_stmt, 1), 0);
+ tree rhs_def_operand = gimple_assign_rhs1 (rhs_def_stmt);
/* Verify that RHS_DEF_OPERAND is a suitable SSA_NAME. */
if (TREE_CODE (rhs_def_operand) == SSA_NAME
&& ! SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs_def_operand))
{
- GIMPLE_STMT_OPERAND (stmt, 1) = rhs_def_operand;
+ gimple_assign_set_rhs_from_tree (gsi_p, rhs_def_operand);
+ stmt = gsi_stmt (*gsi_p);
update_stmt (stmt);
}
}
@@ -923,26 +1050,26 @@ simplify_not_neg_expr (tree stmt)
the condition which we may be able to optimize better. */
static void
-simplify_switch_expr (tree stmt)
+simplify_gimple_switch (gimple stmt)
{
- tree cond = SWITCH_COND (stmt);
+ tree cond = gimple_switch_index (stmt);
tree def, to, ti;
+ gimple def_stmt;
/* The optimization that we really care about is removing unnecessary
casts. That will let us do much better in propagating the inferred
constant at the switch target. */
if (TREE_CODE (cond) == SSA_NAME)
{
- def = SSA_NAME_DEF_STMT (cond);
- if (TREE_CODE (def) == GIMPLE_MODIFY_STMT)
+ def_stmt = SSA_NAME_DEF_STMT (cond);
+ if (is_gimple_assign (def_stmt))
{
- def = GIMPLE_STMT_OPERAND (def, 1);
- if (TREE_CODE (def) == NOP_EXPR)
+ if (gimple_assign_rhs_code (def_stmt) == NOP_EXPR)
{
int need_precision;
bool fail;
- def = TREE_OPERAND (def, 0);
+ def = gimple_assign_rhs1 (def_stmt);
#ifdef ENABLE_CHECKING
/* ??? Why was Jeff testing this? We are gimple... */
@@ -968,7 +1095,7 @@ simplify_switch_expr (tree stmt)
if (!fail)
{
- SWITCH_COND (stmt) = def;
+ gimple_switch_set_index (stmt, def);
update_stmt (stmt);
}
}
@@ -988,33 +1115,32 @@ tree_ssa_forward_propagate_single_use_vars (void)
FOR_EACH_BB (bb)
{
- block_stmt_iterator bsi;
+ gimple_stmt_iterator gsi;
- /* Note we update BSI within the loop as necessary. */
- for (bsi = bsi_start (bb); !bsi_end_p (bsi); )
+ /* Note we update GSI within the loop as necessary. */
+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); )
{
- tree stmt = bsi_stmt (bsi);
+ gimple stmt = gsi_stmt (gsi);
/* If this statement sets an SSA_NAME to an address,
try to propagate the address into the uses of the SSA_NAME. */
- if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT)
+ if (is_gimple_assign (stmt))
{
- tree lhs = GIMPLE_STMT_OPERAND (stmt, 0);
- tree rhs = GIMPLE_STMT_OPERAND (stmt, 1);
-
+ tree lhs = gimple_assign_lhs (stmt);
+ tree rhs = gimple_assign_rhs1 (stmt);
if (TREE_CODE (lhs) != SSA_NAME)
{
- bsi_next (&bsi);
+ gsi_next (&gsi);
continue;
}
- if (TREE_CODE (rhs) == ADDR_EXPR
+ if (gimple_assign_rhs_code (stmt) == ADDR_EXPR
/* Handle pointer conversions on invariant addresses
as well, as this is valid gimple. */
- || (CONVERT_EXPR_P (rhs)
- && TREE_CODE (TREE_OPERAND (rhs, 0)) == ADDR_EXPR
- && POINTER_TYPE_P (TREE_TYPE (rhs))))
+ || (IS_CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (stmt))
+ && TREE_CODE (rhs) == ADDR_EXPR
+ && POINTER_TYPE_P (TREE_TYPE (lhs))))
{
STRIP_NOPS (rhs);
if (!stmt_references_abnormal_ssa_name (stmt)
@@ -1022,61 +1148,64 @@ tree_ssa_forward_propagate_single_use_vars (void)
{
release_defs (stmt);
todoflags |= TODO_remove_unused_locals;
- bsi_remove (&bsi, true);
+ gsi_remove (&gsi, true);
}
else
- bsi_next (&bsi);
+ gsi_next (&gsi);
}
- else if ((TREE_CODE (rhs) == BIT_NOT_EXPR
- || TREE_CODE (rhs) == NEGATE_EXPR)
- && TREE_CODE (TREE_OPERAND (rhs, 0)) == SSA_NAME)
+ else if ((gimple_assign_rhs_code (stmt) == BIT_NOT_EXPR
+ || gimple_assign_rhs_code (stmt) == NEGATE_EXPR)
+ && TREE_CODE (rhs) == SSA_NAME)
{
- simplify_not_neg_expr (stmt);
- bsi_next (&bsi);
+ simplify_not_neg_expr (&gsi);
+ gsi_next (&gsi);
}
- else if (TREE_CODE (rhs) == COND_EXPR)
+ else if (gimple_assign_rhs_code (stmt) == COND_EXPR)
{
+ /* In this case the entire COND_EXPR is in rhs1. */
int did_something;
fold_defer_overflow_warnings ();
- did_something = forward_propagate_into_cond (rhs, stmt);
+ did_something = forward_propagate_into_cond (&gsi);
+ stmt = gsi_stmt (gsi);
if (did_something == 2)
cfg_changed = true;
fold_undefer_overflow_warnings (!TREE_NO_WARNING (rhs)
&& did_something, stmt, WARN_STRICT_OVERFLOW_CONDITIONAL);
- bsi_next (&bsi);
+ gsi_next (&gsi);
}
- else if (COMPARISON_CLASS_P (rhs))
+ else if (TREE_CODE_CLASS (gimple_assign_rhs_code (stmt))
+ == tcc_comparison)
{
- if (forward_propagate_comparison (rhs, stmt))
+ if (forward_propagate_comparison (stmt))
{
release_defs (stmt);
todoflags |= TODO_remove_unused_locals;
- bsi_remove (&bsi, true);
+ gsi_remove (&gsi, true);
}
else
- bsi_next (&bsi);
+ gsi_next (&gsi);
}
else
- bsi_next (&bsi);
+ gsi_next (&gsi);
}
- else if (TREE_CODE (stmt) == SWITCH_EXPR)
+ else if (gimple_code (stmt) == GIMPLE_SWITCH)
{
- simplify_switch_expr (stmt);
- bsi_next (&bsi);
+ simplify_gimple_switch (stmt);
+ gsi_next (&gsi);
}
- else if (TREE_CODE (stmt) == COND_EXPR)
+ else if (gimple_code (stmt) == GIMPLE_COND)
{
int did_something;
fold_defer_overflow_warnings ();
- did_something = forward_propagate_into_cond (stmt, stmt);
+ did_something = forward_propagate_into_gimple_cond (stmt);
if (did_something == 2)
cfg_changed = true;
fold_undefer_overflow_warnings (did_something, stmt,
WARN_STRICT_OVERFLOW_CONDITIONAL);
- bsi_next (&bsi);
+ gsi_next (&gsi);
}
else
- bsi_next (&bsi);
+ gsi_next (&gsi);
}
}
diff --git a/gcc/tree-ssa-ifcombine.c b/gcc/tree-ssa-ifcombine.c
index 93e7810cb3b..143608e28eb 100644
--- a/gcc/tree-ssa-ifcombine.c
+++ b/gcc/tree-ssa-ifcombine.c
@@ -101,14 +101,13 @@ recognize_if_then_else (basic_block cond_bb,
static bool
bb_no_side_effects_p (basic_block bb)
{
- block_stmt_iterator bsi;
+ gimple_stmt_iterator gsi;
- for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
- tree stmt = bsi_stmt (bsi);
- stmt_ann_t ann = stmt_ann (stmt);
+ gimple stmt = gsi_stmt (gsi);
- if (ann->has_volatile_ops
+ if (gimple_has_volatile_ops (stmt)
|| !ZERO_SSA_OPERANDS (stmt, SSA_OP_ALL_VIRTUALS))
return false;
}
@@ -125,12 +124,16 @@ same_phi_args_p (basic_block bb1, basic_block bb2, basic_block dest)
{
edge e1 = find_edge (bb1, dest);
edge e2 = find_edge (bb2, dest);
- tree phi;
+ gimple_stmt_iterator gsi;
+ gimple phi;
- for (phi = phi_nodes (dest); phi; phi = PHI_CHAIN (phi))
- if (!operand_equal_p (PHI_ARG_DEF_FROM_EDGE (phi, e1),
- PHI_ARG_DEF_FROM_EDGE (phi, e2), 0))
- return false;
+ for (gsi = gsi_start_phis (dest); !gsi_end_p (gsi); gsi_next (&gsi))
+ {
+ phi = gsi_stmt (gsi);
+ if (!operand_equal_p (PHI_ARG_DEF_FROM_EDGE (phi, e1),
+ PHI_ARG_DEF_FROM_EDGE (phi, e2), 0))
+ return false;
+ }
return true;
}
@@ -146,71 +149,86 @@ get_name_for_bit_test (tree candidate)
if (TREE_CODE (candidate) == SSA_NAME
&& has_single_use (candidate))
{
- tree def_stmt = SSA_NAME_DEF_STMT (candidate);
- if (TREE_CODE (def_stmt) == GIMPLE_MODIFY_STMT
- && CONVERT_EXPR_P (GIMPLE_STMT_OPERAND (def_stmt, 1)))
+ gimple def_stmt = SSA_NAME_DEF_STMT (candidate);
+ if (is_gimple_assign (def_stmt)
+ && gimple_assign_cast_p (def_stmt))
{
- tree rhs = GIMPLE_STMT_OPERAND (def_stmt, 1);
- if (TYPE_PRECISION (TREE_TYPE (rhs))
- <= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (rhs, 0))))
- return TREE_OPERAND (rhs, 0);
+ if (TYPE_PRECISION (TREE_TYPE (candidate))
+ <= TYPE_PRECISION (TREE_TYPE (gimple_assign_rhs1 (def_stmt))))
+ return gimple_assign_rhs1 (def_stmt);
}
}
return candidate;
}
-/* Recognize a single bit test pattern in COND_EXPR and its defining
+/* Helpers for recognize_single_bit_test defined mainly for source code
+ formating. */
+
+static int
+operand_precision (tree t)
+{
+ return TYPE_PRECISION (TREE_TYPE (t));
+}
+
+static bool
+integral_operand_p (tree t)
+{
+ return INTEGRAL_TYPE_P (TREE_TYPE (t));
+}
+
+/* Recognize a single bit test pattern in GIMPLE_COND and its defining
statements. Store the name being tested in *NAME and the bit
- in *BIT. The COND_EXPR computes *NAME & (1 << *BIT).
+ in *BIT. The GIMPLE_COND computes *NAME & (1 << *BIT).
Returns true if the pattern matched, false otherwise. */
static bool
-recognize_single_bit_test (tree cond_expr, tree *name, tree *bit)
+recognize_single_bit_test (gimple cond, tree *name, tree *bit)
{
- tree t;
+ gimple stmt;
/* Get at the definition of the result of the bit test. */
- t = TREE_OPERAND (cond_expr, 0);
- if (TREE_CODE (t) == NE_EXPR
- && integer_zerop (TREE_OPERAND (t, 1)))
- t = TREE_OPERAND (t, 0);
- if (TREE_CODE (t) != SSA_NAME)
+ if (gimple_cond_code (cond) != NE_EXPR
+ || TREE_CODE (gimple_cond_lhs (cond)) != SSA_NAME
+ || !integer_zerop (gimple_cond_rhs (cond)))
return false;
- t = SSA_NAME_DEF_STMT (t);
- if (TREE_CODE (t) != GIMPLE_MODIFY_STMT)
+ stmt = SSA_NAME_DEF_STMT (gimple_cond_lhs (cond));
+ if (!is_gimple_assign (stmt))
return false;
- t = GIMPLE_STMT_OPERAND (t, 1);
/* Look at which bit is tested. One form to recognize is
D.1985_5 = state_3(D) >> control1_4(D);
D.1986_6 = (int) D.1985_5;
D.1987_7 = op0 & 1;
if (D.1987_7 != 0) */
- if (TREE_CODE (t) == BIT_AND_EXPR
- && integer_onep (TREE_OPERAND (t, 1))
- && TREE_CODE (TREE_OPERAND (t, 0)) == SSA_NAME)
+ if (gimple_assign_rhs_code (stmt) == BIT_AND_EXPR
+ && integer_onep (gimple_assign_rhs2 (stmt))
+ && TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME)
{
- tree orig_name = TREE_OPERAND (t, 0);
+ tree orig_name = gimple_assign_rhs1 (stmt);
/* Look through copies and conversions to eventually
find the stmt that computes the shift. */
- t = orig_name;
- do {
- t = SSA_NAME_DEF_STMT (t);
- if (TREE_CODE (t) != GIMPLE_MODIFY_STMT)
- break;
- t = GIMPLE_STMT_OPERAND (t, 1);
- if (CONVERT_EXPR_P (t))
- t = TREE_OPERAND (t, 0);
- } while (TREE_CODE (t) == SSA_NAME);
+ stmt = SSA_NAME_DEF_STMT (orig_name);
+
+ while (is_gimple_assign (stmt)
+ && (gimple_assign_copy_p (stmt)
+ || (gimple_assign_cast_p (stmt)
+ && integral_operand_p (gimple_assign_lhs (stmt))
+ && integral_operand_p (gimple_assign_rhs1 (stmt))
+ && (operand_precision (gimple_assign_lhs (stmt))
+ <= operand_precision (gimple_assign_rhs1 (stmt))))))
+ {
+ stmt = SSA_NAME_DEF_STMT (gimple_assign_rhs1 (stmt));
+ }
/* If we found such, decompose it. */
- if (TREE_CODE (t) == RSHIFT_EXPR)
+ if (is_gimple_assign (stmt)
+ && gimple_assign_rhs_code (stmt) == RSHIFT_EXPR)
{
/* op0 & (1 << op1) */
- *bit = TREE_OPERAND (t, 1);
- *name = TREE_OPERAND (t, 0);
+ *bit = gimple_assign_rhs2 (stmt);
+ *name = gimple_assign_rhs1 (stmt);
}
else
{
@@ -225,13 +243,13 @@ recognize_single_bit_test (tree cond_expr, tree *name, tree *bit)
/* Another form is
D.1987_7 = op0 & (1 << CST)
if (D.1987_7 != 0) */
- if (TREE_CODE (t) == BIT_AND_EXPR
- && TREE_CODE (TREE_OPERAND (t, 0)) == SSA_NAME
- && integer_pow2p (TREE_OPERAND (t, 1)))
+ if (gimple_assign_rhs_code (stmt) == BIT_AND_EXPR
+ && TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME
+ && integer_pow2p (gimple_assign_rhs2 (stmt)))
{
- *name = TREE_OPERAND (t, 0);
+ *name = gimple_assign_rhs1 (stmt);
*bit = build_int_cst (integer_type_node,
- tree_log2 (TREE_OPERAND (t, 1)));
+ tree_log2 (gimple_assign_rhs2 (stmt)));
return true;
}
@@ -239,31 +257,31 @@ recognize_single_bit_test (tree cond_expr, tree *name, tree *bit)
D.1986_6 = 1 << control1_4(D)
D.1987_7 = op0 & D.1986_6
if (D.1987_7 != 0) */
- if (TREE_CODE (t) == BIT_AND_EXPR
- && TREE_CODE (TREE_OPERAND (t, 0)) == SSA_NAME
- && TREE_CODE (TREE_OPERAND (t, 1)) == SSA_NAME)
+ if (gimple_assign_rhs_code (stmt) == BIT_AND_EXPR
+ && TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME
+ && TREE_CODE (gimple_assign_rhs2 (stmt)) == SSA_NAME)
{
- tree tmp;
+ gimple tmp;
/* Both arguments of the BIT_AND_EXPR can be the single-bit
specifying expression. */
- tmp = SSA_NAME_DEF_STMT (TREE_OPERAND (t, 0));
- if (TREE_CODE (tmp) == GIMPLE_MODIFY_STMT
- && TREE_CODE (GIMPLE_STMT_OPERAND (tmp, 1)) == LSHIFT_EXPR
- && integer_onep (TREE_OPERAND (GIMPLE_STMT_OPERAND (tmp, 1), 0)))
+ tmp = SSA_NAME_DEF_STMT (gimple_assign_rhs1 (stmt));
+ if (is_gimple_assign (tmp)
+ && gimple_assign_rhs_code (tmp) == LSHIFT_EXPR
+ && integer_onep (gimple_assign_rhs1 (tmp)))
{
- *name = TREE_OPERAND (t, 1);
- *bit = TREE_OPERAND (GIMPLE_STMT_OPERAND (tmp, 1), 1);
+ *name = gimple_assign_rhs2 (stmt);
+ *bit = gimple_assign_rhs2 (tmp);
return true;
}
- tmp = SSA_NAME_DEF_STMT (TREE_OPERAND (t, 1));
- if (TREE_CODE (tmp) == GIMPLE_MODIFY_STMT
- && TREE_CODE (GIMPLE_STMT_OPERAND (tmp, 1)) == LSHIFT_EXPR
- && integer_onep (TREE_OPERAND (GIMPLE_STMT_OPERAND (tmp, 1), 0)))
+ tmp = SSA_NAME_DEF_STMT (gimple_assign_rhs2 (stmt));
+ if (is_gimple_assign (tmp)
+ && gimple_assign_rhs_code (tmp) == LSHIFT_EXPR
+ && integer_onep (gimple_assign_rhs1 (tmp)))
{
- *name = TREE_OPERAND (t, 0);
- *bit = TREE_OPERAND (GIMPLE_STMT_OPERAND (tmp, 1), 1);
+ *name = gimple_assign_rhs1 (stmt);
+ *bit = gimple_assign_rhs2 (tmp);
return true;
}
}
@@ -271,33 +289,28 @@ recognize_single_bit_test (tree cond_expr, tree *name, tree *bit)
return false;
}
-/* Recognize a bit test pattern in COND_EXPR and its defining
+/* Recognize a bit test pattern in a GIMPLE_COND and its defining
statements. Store the name being tested in *NAME and the bits
in *BITS. The COND_EXPR computes *NAME & *BITS.
Returns true if the pattern matched, false otherwise. */
static bool
-recognize_bits_test (tree cond_expr, tree *name, tree *bits)
+recognize_bits_test (gimple cond, tree *name, tree *bits)
{
- tree t;
+ gimple stmt;
/* Get at the definition of the result of the bit test. */
- t = TREE_OPERAND (cond_expr, 0);
- if (TREE_CODE (t) == NE_EXPR
- && integer_zerop (TREE_OPERAND (t, 1)))
- t = TREE_OPERAND (t, 0);
- if (TREE_CODE (t) != SSA_NAME)
- return false;
- t = SSA_NAME_DEF_STMT (t);
- if (TREE_CODE (t) != GIMPLE_MODIFY_STMT)
+ if (gimple_cond_code (cond) != NE_EXPR
+ || TREE_CODE (gimple_cond_lhs (cond)) != SSA_NAME
+ || !integer_zerop (gimple_cond_rhs (cond)))
return false;
- t = GIMPLE_STMT_OPERAND (t, 1);
-
- if (TREE_CODE (t) != BIT_AND_EXPR)
+ stmt = SSA_NAME_DEF_STMT (gimple_cond_lhs (cond));
+ if (!is_gimple_assign (stmt)
+ || gimple_assign_rhs_code (stmt) != BIT_AND_EXPR)
return false;
- *name = get_name_for_bit_test (TREE_OPERAND (t, 0));
- *bits = TREE_OPERAND (t, 1);
+ *name = get_name_for_bit_test (gimple_assign_rhs1 (stmt));
+ *bits = gimple_assign_rhs2 (stmt);
return true;
}
@@ -309,18 +322,18 @@ recognize_bits_test (tree cond_expr, tree *name, tree *bits)
static bool
ifcombine_ifandif (basic_block inner_cond_bb, basic_block outer_cond_bb)
{
- block_stmt_iterator bsi;
- tree inner_cond, outer_cond;
+ gimple_stmt_iterator gsi;
+ gimple inner_cond, outer_cond;
tree name1, name2, bit1, bit2;
inner_cond = last_stmt (inner_cond_bb);
if (!inner_cond
- || TREE_CODE (inner_cond) != COND_EXPR)
+ || gimple_code (inner_cond) != GIMPLE_COND)
return false;
outer_cond = last_stmt (outer_cond_bb);
if (!outer_cond
- || TREE_CODE (outer_cond) != COND_EXPR)
+ || gimple_code (outer_cond) != GIMPLE_COND)
return false;
/* See if we test a single bit of the same name in both tests. In
@@ -334,23 +347,23 @@ ifcombine_ifandif (basic_block inner_cond_bb, basic_block outer_cond_bb)
tree t, t2;
/* Do it. */
- bsi = bsi_for_stmt (inner_cond);
+ gsi = gsi_for_stmt (inner_cond);
t = fold_build2 (LSHIFT_EXPR, TREE_TYPE (name1),
build_int_cst (TREE_TYPE (name1), 1), bit1);
t2 = fold_build2 (LSHIFT_EXPR, TREE_TYPE (name1),
build_int_cst (TREE_TYPE (name1), 1), bit2);
t = fold_build2 (BIT_IOR_EXPR, TREE_TYPE (name1), t, t2);
- t = force_gimple_operand_bsi (&bsi, t, true, NULL_TREE,
- true, BSI_SAME_STMT);
+ t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
+ true, GSI_SAME_STMT);
t2 = fold_build2 (BIT_AND_EXPR, TREE_TYPE (name1), name1, t);
- t2 = force_gimple_operand_bsi (&bsi, t2, true, NULL_TREE,
- true, BSI_SAME_STMT);
- COND_EXPR_COND (inner_cond) = fold_build2 (EQ_EXPR, boolean_type_node,
- t2, t);
+ t2 = force_gimple_operand_gsi (&gsi, t2, true, NULL_TREE,
+ true, GSI_SAME_STMT);
+ t = fold_build2 (EQ_EXPR, boolean_type_node, t2, t);
+ gimple_cond_set_condition_from_tree (inner_cond, t);
update_stmt (inner_cond);
/* Leave CFG optimization to cfg_cleanup. */
- COND_EXPR_COND (outer_cond) = boolean_true_node;
+ gimple_cond_set_condition_from_tree (outer_cond, boolean_true_node);
update_stmt (outer_cond);
if (dump_file)
@@ -378,17 +391,17 @@ ifcombine_ifandif (basic_block inner_cond_bb, basic_block outer_cond_bb)
static bool
ifcombine_iforif (basic_block inner_cond_bb, basic_block outer_cond_bb)
{
- tree inner_cond, outer_cond;
+ gimple inner_cond, outer_cond;
tree name1, name2, bits1, bits2;
inner_cond = last_stmt (inner_cond_bb);
if (!inner_cond
- || TREE_CODE (inner_cond) != COND_EXPR)
+ || gimple_code (inner_cond) != GIMPLE_COND)
return false;
outer_cond = last_stmt (outer_cond_bb);
if (!outer_cond
- || TREE_CODE (outer_cond) != COND_EXPR)
+ || gimple_code (outer_cond) != GIMPLE_COND)
return false;
/* See if we have two bit tests of the same name in both tests.
@@ -397,7 +410,7 @@ ifcombine_iforif (basic_block inner_cond_bb, basic_block outer_cond_bb)
if (recognize_bits_test (inner_cond, &name1, &bits1)
&& recognize_bits_test (outer_cond, &name2, &bits2))
{
- block_stmt_iterator bsi;
+ gimple_stmt_iterator gsi;
tree t;
/* Find the common name which is bit-tested. */
@@ -428,19 +441,20 @@ ifcombine_iforif (basic_block inner_cond_bb, basic_block outer_cond_bb)
return false;
/* Do it. */
- bsi = bsi_for_stmt (inner_cond);
+ gsi = gsi_for_stmt (inner_cond);
t = fold_build2 (BIT_IOR_EXPR, TREE_TYPE (name1), bits1, bits2);
- t = force_gimple_operand_bsi (&bsi, t, true, NULL_TREE,
- true, BSI_SAME_STMT);
+ t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
+ true, GSI_SAME_STMT);
t = fold_build2 (BIT_AND_EXPR, TREE_TYPE (name1), name1, t);
- t = force_gimple_operand_bsi (&bsi, t, true, NULL_TREE,
- true, BSI_SAME_STMT);
- COND_EXPR_COND (inner_cond) = fold_build2 (NE_EXPR, boolean_type_node, t,
- build_int_cst (TREE_TYPE (t), 0));
+ t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
+ true, GSI_SAME_STMT);
+ t = fold_build2 (NE_EXPR, boolean_type_node, t,
+ build_int_cst (TREE_TYPE (t), 0));
+ gimple_cond_set_condition_from_tree (inner_cond, t);
update_stmt (inner_cond);
/* Leave CFG optimization to cfg_cleanup. */
- COND_EXPR_COND (outer_cond) = boolean_false_node;
+ gimple_cond_set_condition_from_tree (outer_cond, boolean_false_node);
update_stmt (outer_cond);
if (dump_file)
@@ -460,17 +474,15 @@ ifcombine_iforif (basic_block inner_cond_bb, basic_block outer_cond_bb)
/* See if we have two comparisons that we can merge into one.
This happens for C++ operator overloading where for example
GE_EXPR is implemented as GT_EXPR || EQ_EXPR. */
- else if (COMPARISON_CLASS_P (COND_EXPR_COND (inner_cond))
- && COMPARISON_CLASS_P (COND_EXPR_COND (outer_cond))
- && operand_equal_p (TREE_OPERAND (COND_EXPR_COND (inner_cond), 0),
- TREE_OPERAND (COND_EXPR_COND (outer_cond), 0), 0)
- && operand_equal_p (TREE_OPERAND (COND_EXPR_COND (inner_cond), 1),
- TREE_OPERAND (COND_EXPR_COND (outer_cond), 1), 0))
+ else if (TREE_CODE_CLASS (gimple_cond_code (inner_cond)) == tcc_comparison
+ && TREE_CODE_CLASS (gimple_cond_code (outer_cond)) == tcc_comparison
+ && operand_equal_p (gimple_cond_lhs (inner_cond),
+ gimple_cond_lhs (outer_cond), 0)
+ && operand_equal_p (gimple_cond_rhs (inner_cond),
+ gimple_cond_rhs (outer_cond), 0))
{
- tree ccond1 = COND_EXPR_COND (inner_cond);
- tree ccond2 = COND_EXPR_COND (outer_cond);
- enum tree_code code1 = TREE_CODE (ccond1);
- enum tree_code code2 = TREE_CODE (ccond2);
+ enum tree_code code1 = gimple_cond_code (inner_cond);
+ enum tree_code code2 = gimple_cond_code (outer_cond);
enum tree_code code;
tree t;
@@ -487,7 +499,7 @@ ifcombine_iforif (basic_block inner_cond_bb, basic_block outer_cond_bb)
code = LE_EXPR;
else if (CHK (GT, GE))
code = GE_EXPR;
- else if (INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (ccond1, 0)))
+ else if (INTEGRAL_TYPE_P (TREE_TYPE (gimple_cond_lhs (inner_cond)))
|| flag_unsafe_math_optimizations)
{
if (CHK (LT, GT))
@@ -505,16 +517,16 @@ ifcombine_iforif (basic_block inner_cond_bb, basic_block outer_cond_bb)
#undef CHK
/* Do it. */
- t = fold_build2 (code, boolean_type_node,
- TREE_OPERAND (ccond2, 0), TREE_OPERAND (ccond2, 1));
+ t = fold_build2 (code, boolean_type_node, gimple_cond_lhs (outer_cond),
+ gimple_cond_rhs (outer_cond));
t = canonicalize_cond_expr_cond (t);
if (!t)
return false;
- COND_EXPR_COND (inner_cond) = t;
+ gimple_cond_set_condition_from_tree (inner_cond, t);
update_stmt (inner_cond);
/* Leave CFG optimization to cfg_cleanup. */
- COND_EXPR_COND (outer_cond) = boolean_false_node;
+ gimple_cond_set_condition_from_tree (outer_cond, boolean_false_node);
update_stmt (outer_cond);
if (dump_file)
@@ -611,10 +623,10 @@ tree_ssa_ifcombine (void)
for (i = 0; i < n_basic_blocks - NUM_FIXED_BLOCKS; ++i)
{
basic_block bb = bbs[i];
- tree stmt = last_stmt (bb);
+ gimple stmt = last_stmt (bb);
if (stmt
- && TREE_CODE (stmt) == COND_EXPR)
+ && gimple_code (stmt) == GIMPLE_COND)
cfg_changed |= tree_ssa_ifcombine_bb (bb);
}
diff --git a/gcc/tree-ssa-live.c b/gcc/tree-ssa-live.c
index c277980ed86..fa3834d21c5 100644
--- a/gcc/tree-ssa-live.c
+++ b/gcc/tree-ssa-live.c
@@ -403,8 +403,7 @@ static inline void mark_all_vars_used (tree *, void *data);
/* Helper function for mark_all_vars_used, called via walk_tree. */
static tree
-mark_all_vars_used_1 (tree *tp, int *walk_subtrees,
- void *data)
+mark_all_vars_used_1 (tree *tp, int *walk_subtrees, void *data)
{
tree t = *tp;
enum tree_code_class c = TREE_CODE_CLASS (TREE_CODE (t));
@@ -412,8 +411,8 @@ mark_all_vars_used_1 (tree *tp, int *walk_subtrees,
if (TREE_CODE (t) == SSA_NAME)
t = SSA_NAME_VAR (t);
- if ((IS_EXPR_CODE_CLASS (c)
- || IS_GIMPLE_STMT_CODE_CLASS (c))
+
+ if (IS_EXPR_CODE_CLASS (c)
&& (b = TREE_BLOCK (t)) != NULL)
TREE_USED (b) = true;
@@ -582,7 +581,9 @@ remove_unused_locals (void)
var_ann_t ann;
bitmap global_unused_vars = NULL;
- mark_scope_block_unused (DECL_INITIAL (current_function_decl));
+ if (optimize)
+ mark_scope_block_unused (DECL_INITIAL (current_function_decl));
+
/* Assume all locals are unused. */
FOR_EACH_REFERENCED_VAR (t, rvi)
var_ann (t)->used = false;
@@ -590,23 +591,34 @@ remove_unused_locals (void)
/* Walk the CFG marking all referenced symbols. */
FOR_EACH_BB (bb)
{
- block_stmt_iterator bsi;
- tree phi, def;
+ gimple_stmt_iterator gsi;
+ size_t i;
/* Walk the statements. */
- for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
- mark_all_vars_used (bsi_stmt_ptr (bsi), NULL);
+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+ {
+ gimple stmt = gsi_stmt (gsi);
+ tree b = gimple_block (stmt);
+
+ if (b)
+ TREE_USED (b) = true;
- for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
+ for (i = 0; i < gimple_num_ops (stmt); i++)
+ mark_all_vars_used (gimple_op_ptr (gsi_stmt (gsi), i), NULL);
+ }
+
+ for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
use_operand_p arg_p;
ssa_op_iter i;
+ tree def;
+ gimple phi = gsi_stmt (gsi);
/* No point processing globals. */
- if (is_global_var (SSA_NAME_VAR (PHI_RESULT (phi))))
+ if (is_global_var (SSA_NAME_VAR (gimple_phi_result (phi))))
continue;
- def = PHI_RESULT (phi);
+ def = gimple_phi_result (phi);
mark_all_vars_used (&def, NULL);
FOR_EACH_PHI_ARG (arg_p, phi, i, SSA_OP_ALL_USES)
@@ -661,7 +673,8 @@ remove_unused_locals (void)
if (TREE_CODE (var) == VAR_DECL
&& is_global_var (var)
- && bitmap_bit_p (global_unused_vars, DECL_UID (var)))
+ && bitmap_bit_p (global_unused_vars, DECL_UID (var))
+ && (optimize || DECL_ARTIFICIAL (var)))
*cell = TREE_CHAIN (*cell);
else
cell = &TREE_CHAIN (*cell);
@@ -681,9 +694,11 @@ remove_unused_locals (void)
&& TREE_CODE (t) != RESULT_DECL
&& !(ann = var_ann (t))->used
&& !ann->symbol_mem_tag
- && !TREE_ADDRESSABLE (t))
+ && !TREE_ADDRESSABLE (t)
+ && (optimize || DECL_ARTIFICIAL (t)))
remove_referenced_var (t);
- remove_unused_scope_block_p (DECL_INITIAL (current_function_decl));
+ if (optimize)
+ remove_unused_scope_block_p (DECL_INITIAL (current_function_decl));
}
@@ -818,7 +833,7 @@ static void
set_var_live_on_entry (tree ssa_name, tree_live_info_p live)
{
int p;
- tree stmt;
+ gimple stmt;
use_operand_p use;
basic_block def_bb = NULL;
imm_use_iterator imm_iter;
@@ -831,7 +846,7 @@ set_var_live_on_entry (tree ssa_name, tree_live_info_p live)
stmt = SSA_NAME_DEF_STMT (ssa_name);
if (stmt)
{
- def_bb = bb_for_stmt (stmt);
+ def_bb = gimple_bb (stmt);
/* Mark defs in liveout bitmap temporarily. */
if (def_bb)
bitmap_set_bit (live->liveout[def_bb->index], p);
@@ -843,16 +858,16 @@ set_var_live_on_entry (tree ssa_name, tree_live_info_p live)
add it to the list of live on entry blocks. */
FOR_EACH_IMM_USE_FAST (use, imm_iter, ssa_name)
{
- tree use_stmt = USE_STMT (use);
+ gimple use_stmt = USE_STMT (use);
basic_block add_block = NULL;
- if (TREE_CODE (use_stmt) == PHI_NODE)
+ if (gimple_code (use_stmt) == GIMPLE_PHI)
{
/* Uses in PHI's are considered to be live at exit of the SRC block
as this is where a copy would be inserted. Check to see if it is
defined in that block, or whether its live on entry. */
int index = PHI_ARG_INDEX_FROM_USE (use);
- edge e = PHI_ARG_EDGE (use_stmt, index);
+ edge e = gimple_phi_arg_edge (use_stmt, index);
if (e->src != ENTRY_BLOCK_PTR)
{
if (e->src != def_bb)
@@ -862,7 +877,7 @@ set_var_live_on_entry (tree ssa_name, tree_live_info_p live)
else
{
/* If its not defined in this block, its live on entry. */
- basic_block use_bb = bb_for_stmt (use_stmt);
+ basic_block use_bb = gimple_bb (use_stmt);
if (use_bb != def_bb)
add_block = use_bb;
}
@@ -887,9 +902,6 @@ set_var_live_on_entry (tree ssa_name, tree_live_info_p live)
void
calculate_live_on_exit (tree_live_info_p liveinfo)
{
- unsigned i;
- int p;
- tree t, phi;
basic_block bb;
edge e;
edge_iterator ei;
@@ -901,20 +913,29 @@ calculate_live_on_exit (tree_live_info_p liveinfo)
/* Set all the live-on-exit bits for uses in PHIs. */
FOR_EACH_BB (bb)
{
+ gimple_stmt_iterator gsi;
+ size_t i;
+
/* Mark the PHI arguments which are live on exit to the pred block. */
- for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
- for (i = 0; i < (unsigned)PHI_NUM_ARGS (phi); i++)
- {
- t = PHI_ARG_DEF (phi, i);
- if (TREE_CODE (t) != SSA_NAME)
- continue;
- p = var_to_partition (liveinfo->map, t);
- if (p == NO_PARTITION)
- continue;
- e = PHI_ARG_EDGE (phi, i);
- if (e->src != ENTRY_BLOCK_PTR)
- bitmap_set_bit (liveinfo->liveout[e->src->index], p);
- }
+ for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+ {
+ gimple phi = gsi_stmt (gsi);
+ for (i = 0; i < gimple_phi_num_args (phi); i++)
+ {
+ tree t = PHI_ARG_DEF (phi, i);
+ int p;
+
+ if (TREE_CODE (t) != SSA_NAME)
+ continue;
+
+ p = var_to_partition (liveinfo->map, t);
+ if (p == NO_PARTITION)
+ continue;
+ e = gimple_phi_arg_edge (phi, i);
+ if (e->src != ENTRY_BLOCK_PTR)
+ bitmap_set_bit (liveinfo->liveout[e->src->index], p);
+ }
+ }
/* Add each successors live on entry to this bock live on exit. */
FOR_EACH_EDGE (e, ei, bb->succs)
@@ -1063,7 +1084,7 @@ verify_live_on_entry (tree_live_info_p live)
{
unsigned i;
tree var;
- tree phi, stmt;
+ gimple stmt;
basic_block bb;
edge e;
int num;
@@ -1087,13 +1108,13 @@ verify_live_on_entry (tree_live_info_p live)
bitmap loe;
var = partition_to_var (map, i);
stmt = SSA_NAME_DEF_STMT (var);
- tmp = bb_for_stmt (stmt);
+ tmp = gimple_bb (stmt);
d = gimple_default_def (cfun, SSA_NAME_VAR (var));
loe = live_on_entry (live, e->dest);
if (loe && bitmap_bit_p (loe, i))
{
- if (!IS_EMPTY_STMT (stmt))
+ if (!gimple_nop_p (stmt))
{
num++;
print_generic_expr (stderr, var, TDF_SLIM);
@@ -1101,7 +1122,7 @@ verify_live_on_entry (tree_live_info_p live)
if (tmp)
fprintf (stderr, " in BB%d, ", tmp->index);
fprintf (stderr, "by:\n");
- print_generic_expr (stderr, stmt, TDF_SLIM);
+ print_gimple_stmt (stderr, stmt, 0, TDF_SLIM);
fprintf (stderr, "\nIt is also live-on-entry to entry BB %d",
entry_block);
fprintf (stderr, " So it appears to have multiple defs.\n");
@@ -1112,7 +1133,8 @@ verify_live_on_entry (tree_live_info_p live)
{
num++;
print_generic_expr (stderr, var, TDF_SLIM);
- fprintf (stderr, " is live-on-entry to BB%d ",entry_block);
+ fprintf (stderr, " is live-on-entry to BB%d ",
+ entry_block);
if (d)
{
fprintf (stderr, " but is not the default def of ");
@@ -1129,15 +1151,18 @@ verify_live_on_entry (tree_live_info_p live)
{
/* The only way this var shouldn't be marked live on entry is
if it occurs in a PHI argument of the block. */
- int z, ok = 0;
- for (phi = phi_nodes (e->dest);
- phi && !ok;
- phi = PHI_CHAIN (phi))
+ size_t z;
+ bool ok = false;
+ gimple_stmt_iterator gsi;
+ for (gsi = gsi_start_phis (e->dest);
+ !gsi_end_p (gsi) && !ok;
+ gsi_next (&gsi))
{
- for (z = 0; z < PHI_NUM_ARGS (phi); z++)
- if (var == PHI_ARG_DEF (phi, z))
+ gimple phi = gsi_stmt (gsi);
+ for (z = 0; z < gimple_phi_num_args (phi); z++)
+ if (var == gimple_phi_arg_def (phi, z))
{
- ok = 1;
+ ok = true;
break;
}
}
diff --git a/gcc/tree-ssa-live.h b/gcc/tree-ssa-live.h
index 4f021609b2f..de4726245f8 100644
--- a/gcc/tree-ssa-live.h
+++ b/gcc/tree-ssa-live.h
@@ -361,8 +361,8 @@ extern var_map coalesce_ssa_name (void);
/* From tree-ssa-ter.c */
-extern tree *find_replaceable_exprs (var_map);
-extern void dump_replaceable_exprs (FILE *, tree *);
+extern gimple *find_replaceable_exprs (var_map);
+extern void dump_replaceable_exprs (FILE *, gimple *);
#endif /* _TREE_SSA_LIVE_H */
diff --git a/gcc/tree-ssa-loop-ch.c b/gcc/tree-ssa-loop-ch.c
index 47b93f8beeb..9a0dca7265e 100644
--- a/gcc/tree-ssa-loop-ch.c
+++ b/gcc/tree-ssa-loop-ch.c
@@ -50,8 +50,8 @@ static bool
should_duplicate_loop_header_p (basic_block header, struct loop *loop,
int *limit)
{
- block_stmt_iterator bsi;
- tree last;
+ gimple_stmt_iterator bsi;
+ gimple last;
/* Do not copy one block more than once (we do not really want to do
loop peeling here). */
@@ -71,19 +71,19 @@ should_duplicate_loop_header_p (basic_block header, struct loop *loop,
return false;
last = last_stmt (header);
- if (TREE_CODE (last) != COND_EXPR)
+ if (gimple_code (last) != GIMPLE_COND)
return false;
/* Approximately copy the conditions that used to be used in jump.c --
at most 20 insns and no calls. */
- for (bsi = bsi_start (header); !bsi_end_p (bsi); bsi_next (&bsi))
+ for (bsi = gsi_start_bb (header); !gsi_end_p (bsi); gsi_next (&bsi))
{
- last = bsi_stmt (bsi);
+ last = gsi_stmt (bsi);
- if (TREE_CODE (last) == LABEL_EXPR)
+ if (gimple_code (last) == GIMPLE_LABEL)
continue;
- if (get_call_expr_in (last))
+ if (is_gimple_call (last))
return false;
*limit -= estimate_num_insns (last, &eni_size_weights);
@@ -99,17 +99,17 @@ should_duplicate_loop_header_p (basic_block header, struct loop *loop,
static bool
do_while_loop_p (struct loop *loop)
{
- tree stmt = last_stmt (loop->latch);
+ gimple stmt = last_stmt (loop->latch);
/* If the latch of the loop is not empty, it is not a do-while loop. */
if (stmt
- && TREE_CODE (stmt) != LABEL_EXPR)
+ && gimple_code (stmt) != GIMPLE_LABEL)
return false;
/* If the header contains just a condition, it is not a do-while loop. */
stmt = last_and_only_stmt (loop->header);
if (stmt
- && TREE_CODE (stmt) == COND_EXPR)
+ && gimple_code (stmt) == GIMPLE_COND)
return false;
return true;
@@ -196,7 +196,7 @@ copy_loop_headers (void)
entry = loop_preheader_edge (loop);
- if (!tree_duplicate_sese_region (entry, exit, bbs, n_bbs, copied_bbs))
+ if (!gimple_duplicate_sese_region (entry, exit, bbs, n_bbs, copied_bbs))
{
fprintf (dump_file, "Duplication failed.\n");
continue;
@@ -208,27 +208,27 @@ copy_loop_headers (void)
we assume that "j < j + 10" is true. We don't want to warn
about that case for -Wstrict-overflow, because in general we
don't warn about overflow involving loops. Prevent the
- warning by setting TREE_NO_WARNING. */
+ warning by setting the no_warning flag in the condition. */
if (warn_strict_overflow > 0)
{
unsigned int i;
for (i = 0; i < n_bbs; ++i)
{
- block_stmt_iterator bsi;
+ gimple_stmt_iterator bsi;
- for (bsi = bsi_start (copied_bbs[i]);
- !bsi_end_p (bsi);
- bsi_next (&bsi))
+ for (bsi = gsi_start_bb (copied_bbs[i]);
+ !gsi_end_p (bsi);
+ gsi_next (&bsi))
{
- tree stmt = bsi_stmt (bsi);
- if (TREE_CODE (stmt) == COND_EXPR)
- TREE_NO_WARNING (stmt) = 1;
- else if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT)
+ gimple stmt = gsi_stmt (bsi);
+ if (gimple_code (stmt) == GIMPLE_COND)
+ gimple_set_no_warning (stmt, true);
+ else if (is_gimple_assign (stmt))
{
- tree rhs = GIMPLE_STMT_OPERAND (stmt, 1);
- if (COMPARISON_CLASS_P (rhs))
- TREE_NO_WARNING (stmt) = 1;
+ enum tree_code rhs_code = gimple_assign_rhs_code (stmt);
+ if (TREE_CODE_CLASS (rhs_code) == tcc_comparison)
+ gimple_set_no_warning (stmt, true);
}
}
}
diff --git a/gcc/tree-ssa-loop-im.c b/gcc/tree-ssa-loop-im.c
index 899eb8ab1a9..4c85c878e6c 100644
--- a/gcc/tree-ssa-loop-im.c
+++ b/gcc/tree-ssa-loop-im.c
@@ -70,7 +70,7 @@ along with GCC; see the file COPYING3. If not see
struct depend
{
- tree stmt;
+ gimple stmt;
struct depend *next;
};
@@ -99,16 +99,16 @@ struct lim_aux_data
MAX_LOOP loop. */
};
-#define LIM_DATA(STMT) (TREE_CODE (STMT) == PHI_NODE \
- ? NULL \
- : (struct lim_aux_data *) (stmt_ann (STMT)->common.aux))
+/* Maps statements to their lim_aux_data. */
+
+static struct pointer_map_t *lim_aux_data_map;
/* Description of a memory reference location. */
typedef struct mem_ref_loc
{
tree *ref; /* The reference itself. */
- tree stmt; /* The statement in that it occurs. */
+ gimple stmt; /* The statement in that it occurs. */
} *mem_ref_loc_p;
DEF_VEC_P(mem_ref_loc_p);
@@ -203,6 +203,51 @@ static bool ref_indep_loop_p (struct loop *, mem_ref_p);
block will be executed. */
#define ALWAYS_EXECUTED_IN(BB) ((struct loop *) (BB)->aux)
+static struct lim_aux_data *
+init_lim_data (gimple stmt)
+{
+ void **p = pointer_map_insert (lim_aux_data_map, stmt);
+
+ *p = XCNEW (struct lim_aux_data);
+ return (struct lim_aux_data *) *p;
+}
+
+static struct lim_aux_data *
+get_lim_data (gimple stmt)
+{
+ void **p = pointer_map_contains (lim_aux_data_map, stmt);
+ if (!p)
+ return NULL;
+
+ return (struct lim_aux_data *) *p;
+}
+
+/* Releases the memory occupied by DATA. */
+
+static void
+free_lim_aux_data (struct lim_aux_data *data)
+{
+ struct depend *dep, *next;
+
+ for (dep = data->depends; dep; dep = next)
+ {
+ next = dep->next;
+ free (dep);
+ }
+ free (data);
+}
+
+static void
+clear_lim_data (gimple stmt)
+{
+ void **p = pointer_map_contains (lim_aux_data_map, stmt);
+ if (!p)
+ return;
+
+ free_lim_aux_data ((struct lim_aux_data *) *p);
+ *p = NULL;
+}
+
/* Calls CBCK for each index in memory reference ADDR_P. There are two
kinds situations handled; in each of these cases, the memory reference
and DATA are passed to the callback:
@@ -301,46 +346,32 @@ for_each_index (tree *addr_p, bool (*cbck) (tree, tree *, void *), void *data)
Otherwise return MOVE_IMPOSSIBLE. */
enum move_pos
-movement_possibility (tree stmt)
+movement_possibility (gimple stmt)
{
- tree lhs, rhs;
+ tree lhs;
+ enum move_pos ret = MOVE_POSSIBLE;
if (flag_unswitch_loops
- && TREE_CODE (stmt) == COND_EXPR)
+ && gimple_code (stmt) == GIMPLE_COND)
{
/* If we perform unswitching, force the operands of the invariant
condition to be moved out of the loop. */
return MOVE_POSSIBLE;
}
- if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT)
+ if (gimple_get_lhs (stmt) == NULL_TREE)
return MOVE_IMPOSSIBLE;
if (!ZERO_SSA_OPERANDS (stmt, SSA_OP_VIRTUAL_DEFS))
return MOVE_IMPOSSIBLE;
- if (stmt_ends_bb_p (stmt))
- return MOVE_IMPOSSIBLE;
-
- if (stmt_ann (stmt)->has_volatile_ops)
- return MOVE_IMPOSSIBLE;
-
- lhs = GIMPLE_STMT_OPERAND (stmt, 0);
- if (TREE_CODE (lhs) == SSA_NAME
- && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs))
+ if (stmt_ends_bb_p (stmt)
+ || gimple_has_volatile_ops (stmt)
+ || gimple_has_side_effects (stmt)
+ || stmt_could_throw_p (stmt))
return MOVE_IMPOSSIBLE;
- rhs = GIMPLE_STMT_OPERAND (stmt, 1);
-
- if (TREE_SIDE_EFFECTS (rhs)
- || tree_could_throw_p (rhs))
- return MOVE_IMPOSSIBLE;
-
- if (TREE_CODE (lhs) != SSA_NAME
- || tree_could_trap_p (rhs))
- return MOVE_PRESERVE_EXECUTION;
-
- if (get_call_expr_in (stmt))
+ if (is_gimple_call (stmt))
{
/* While pure or const call is guaranteed to have no side effects, we
cannot move it arbitrarily. Consider code like
@@ -360,9 +391,23 @@ movement_possibility (tree stmt)
invalid arguments, moving out a function call that is not executed
may cause performance regressions in case the call is costly and
not executed at all. */
- return MOVE_PRESERVE_EXECUTION;
+ ret = MOVE_PRESERVE_EXECUTION;
+ lhs = gimple_call_lhs (stmt);
}
- return MOVE_POSSIBLE;
+ else if (is_gimple_assign (stmt))
+ lhs = gimple_assign_lhs (stmt);
+ else
+ return MOVE_IMPOSSIBLE;
+
+ if (TREE_CODE (lhs) == SSA_NAME
+ && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs))
+ return MOVE_IMPOSSIBLE;
+
+ if (TREE_CODE (lhs) != SSA_NAME
+ || gimple_could_trap_p (stmt))
+ return MOVE_PRESERVE_EXECUTION;
+
+ return ret;
}
/* Suppose that operand DEF is used inside the LOOP. Returns the outermost
@@ -373,23 +418,31 @@ movement_possibility (tree stmt)
static struct loop *
outermost_invariant_loop (tree def, struct loop *loop)
{
- tree def_stmt;
+ gimple def_stmt;
basic_block def_bb;
struct loop *max_loop;
+ struct lim_aux_data *lim_data;
- if (TREE_CODE (def) != SSA_NAME)
+ if (!def)
return superloop_at_depth (loop, 1);
+ if (TREE_CODE (def) != SSA_NAME)
+ {
+ gcc_assert (is_gimple_min_invariant (def));
+ return superloop_at_depth (loop, 1);
+ }
+
def_stmt = SSA_NAME_DEF_STMT (def);
- def_bb = bb_for_stmt (def_stmt);
+ def_bb = gimple_bb (def_stmt);
if (!def_bb)
return superloop_at_depth (loop, 1);
max_loop = find_common_loop (loop, def_bb->loop_father);
- if (LIM_DATA (def_stmt) && LIM_DATA (def_stmt)->max_loop)
+ lim_data = get_lim_data (def_stmt);
+ if (lim_data != NULL && lim_data->max_loop != NULL)
max_loop = find_common_loop (max_loop,
- loop_outer (LIM_DATA (def_stmt)->max_loop));
+ loop_outer (lim_data->max_loop));
if (max_loop == loop)
return NULL;
max_loop = superloop_at_depth (loop, loop_depth (max_loop) + 1);
@@ -397,42 +450,6 @@ outermost_invariant_loop (tree def, struct loop *loop)
return max_loop;
}
-/* Returns the outermost superloop of LOOP in that the expression EXPR is
- invariant. */
-
-static struct loop *
-outermost_invariant_loop_expr (tree expr, struct loop *loop)
-{
- enum tree_code_class codeclass = TREE_CODE_CLASS (TREE_CODE (expr));
- unsigned i, nops;
- struct loop *max_loop = superloop_at_depth (loop, 1), *aloop;
-
- if (TREE_CODE (expr) == SSA_NAME
- || TREE_CODE (expr) == INTEGER_CST
- || is_gimple_min_invariant (expr))
- return outermost_invariant_loop (expr, loop);
-
- if (codeclass != tcc_unary
- && codeclass != tcc_binary
- && codeclass != tcc_expression
- && codeclass != tcc_vl_exp
- && codeclass != tcc_comparison)
- return NULL;
-
- nops = TREE_OPERAND_LENGTH (expr);
- for (i = 0; i < nops; i++)
- {
- aloop = outermost_invariant_loop_expr (TREE_OPERAND (expr, i), loop);
- if (!aloop)
- return NULL;
-
- if (flow_loop_nested_p (max_loop, aloop))
- max_loop = aloop;
- }
-
- return max_loop;
-}
-
/* DATA is a structure containing information associated with a statement
inside LOOP. DEF is one of the operands of this statement.
@@ -449,10 +466,11 @@ static bool
add_dependency (tree def, struct lim_aux_data *data, struct loop *loop,
bool add_cost)
{
- tree def_stmt = SSA_NAME_DEF_STMT (def);
- basic_block def_bb = bb_for_stmt (def_stmt);
+ gimple def_stmt = SSA_NAME_DEF_STMT (def);
+ basic_block def_bb = gimple_bb (def_stmt);
struct loop *max_loop;
struct depend *dep;
+ struct lim_aux_data *def_data;
if (!def_bb)
return true;
@@ -464,7 +482,8 @@ add_dependency (tree def, struct lim_aux_data *data, struct loop *loop,
if (flow_loop_nested_p (data->max_loop, max_loop))
data->max_loop = max_loop;
- if (!LIM_DATA (def_stmt))
+ def_data = get_lim_data (def_stmt);
+ if (!def_data)
return true;
if (add_cost
@@ -473,7 +492,7 @@ add_dependency (tree def, struct lim_aux_data *data, struct loop *loop,
on it, we will be able to avoid creating a new register for
it (since it will be only used in these dependent invariants). */
&& def_bb->loop_father == loop)
- data->cost += LIM_DATA (def_stmt)->cost;
+ data->cost += def_data->cost;
dep = XNEW (struct depend);
dep->stmt = def_stmt;
@@ -488,36 +507,39 @@ add_dependency (tree def, struct lim_aux_data *data, struct loop *loop,
values. */
static unsigned
-stmt_cost (tree stmt)
+stmt_cost (gimple stmt)
{
- tree rhs;
+ tree fndecl;
unsigned cost = 1;
/* Always try to create possibilities for unswitching. */
- if (TREE_CODE (stmt) == COND_EXPR)
+ if (gimple_code (stmt) == GIMPLE_COND)
return LIM_EXPENSIVE;
- rhs = GENERIC_TREE_OPERAND (stmt, 1);
-
/* Hoisting memory references out should almost surely be a win. */
- if (stmt_references_memory_p (stmt))
+ if (gimple_references_memory_p (stmt))
cost += 20;
- switch (TREE_CODE (rhs))
+ if (is_gimple_call (stmt))
{
- case CALL_EXPR:
/* We should be hoisting calls if possible. */
/* Unless the call is a builtin_constant_p; this always folds to a
constant, so moving it is useless. */
- rhs = get_callee_fndecl (rhs);
- if (DECL_BUILT_IN_CLASS (rhs) == BUILT_IN_NORMAL
- && DECL_FUNCTION_CODE (rhs) == BUILT_IN_CONSTANT_P)
+ fndecl = gimple_call_fndecl (stmt);
+ if (fndecl
+ && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
+ && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CONSTANT_P)
return 0;
- cost += 20;
- break;
+ return cost + 20;
+ }
+
+ if (gimple_code (stmt) != GIMPLE_ASSIGN)
+ return cost;
+ switch (gimple_assign_rhs_code (stmt))
+ {
case MULT_EXPR:
case TRUNC_DIV_EXPR:
case CEIL_DIV_EXPR:
@@ -575,27 +597,31 @@ outermost_indep_loop (struct loop *outer, struct loop *loop, mem_ref_p ref)
it is a store or load. Otherwise, returns NULL. */
static tree *
-simple_mem_ref_in_stmt (tree stmt, bool *is_store)
+simple_mem_ref_in_stmt (gimple stmt, bool *is_store)
{
- tree *lhs, *rhs;
+ tree *lhs;
+ enum tree_code code;
/* Recognize MEM = (SSA_NAME | invariant) and SSA_NAME = MEM patterns. */
- if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT)
+ if (gimple_code (stmt) != GIMPLE_ASSIGN)
return NULL;
- lhs = &GIMPLE_STMT_OPERAND (stmt, 0);
- rhs = &GIMPLE_STMT_OPERAND (stmt, 1);
+ code = gimple_assign_rhs_code (stmt);
+
+ lhs = gimple_assign_lhs_ptr (stmt);
if (TREE_CODE (*lhs) == SSA_NAME)
{
- if (!is_gimple_addressable (*rhs))
+ if (get_gimple_rhs_class (code) != GIMPLE_SINGLE_RHS
+ || !is_gimple_addressable (gimple_assign_rhs1 (stmt)))
return NULL;
*is_store = false;
- return rhs;
+ return gimple_assign_rhs1_ptr (stmt);
}
- else if (TREE_CODE (*rhs) == SSA_NAME
- || is_gimple_min_invariant (*rhs))
+ else if (code == SSA_NAME
+ || (get_gimple_rhs_class (code) == GIMPLE_SINGLE_RHS
+ && is_gimple_min_invariant (gimple_assign_rhs1 (stmt))))
{
*is_store = true;
return lhs;
@@ -607,7 +633,7 @@ simple_mem_ref_in_stmt (tree stmt, bool *is_store)
/* Returns the memory reference contained in STMT. */
static mem_ref_p
-mem_ref_in_stmt (tree stmt)
+mem_ref_in_stmt (gimple stmt)
{
bool store;
tree *mem = simple_mem_ref_in_stmt (stmt, &store);
@@ -636,12 +662,12 @@ mem_ref_in_stmt (tree stmt)
is defined in, and true otherwise. */
static bool
-determine_max_movement (tree stmt, bool must_preserve_exec)
+determine_max_movement (gimple stmt, bool must_preserve_exec)
{
- basic_block bb = bb_for_stmt (stmt);
+ basic_block bb = gimple_bb (stmt);
struct loop *loop = bb->loop_father;
struct loop *level;
- struct lim_aux_data *lim_data = LIM_DATA (stmt);
+ struct lim_aux_data *lim_data = get_lim_data (stmt);
tree val;
ssa_op_iter iter;
@@ -687,24 +713,25 @@ determine_max_movement (tree stmt, bool must_preserve_exec)
operands) is hoisted at least out of the loop LEVEL. */
static void
-set_level (tree stmt, struct loop *orig_loop, struct loop *level)
+set_level (gimple stmt, struct loop *orig_loop, struct loop *level)
{
- struct loop *stmt_loop = bb_for_stmt (stmt)->loop_father;
+ struct loop *stmt_loop = gimple_bb (stmt)->loop_father;
struct depend *dep;
+ struct lim_aux_data *lim_data;
stmt_loop = find_common_loop (orig_loop, stmt_loop);
- if (LIM_DATA (stmt) && LIM_DATA (stmt)->tgt_loop)
+ lim_data = get_lim_data (stmt);
+ if (lim_data != NULL && lim_data->tgt_loop != NULL)
stmt_loop = find_common_loop (stmt_loop,
- loop_outer (LIM_DATA (stmt)->tgt_loop));
+ loop_outer (lim_data->tgt_loop));
if (flow_loop_nested_p (stmt_loop, level))
return;
- gcc_assert (LIM_DATA (stmt));
- gcc_assert (level == LIM_DATA (stmt)->max_loop
- || flow_loop_nested_p (LIM_DATA (stmt)->max_loop, level));
+ gcc_assert (level == lim_data->max_loop
+ || flow_loop_nested_p (lim_data->max_loop, level));
- LIM_DATA (stmt)->tgt_loop = level;
- for (dep = LIM_DATA (stmt)->depends; dep; dep = dep->next)
+ lim_data->tgt_loop = level;
+ for (dep = lim_data->depends; dep; dep = dep->next)
set_level (dep->stmt, orig_loop, level);
}
@@ -713,70 +740,50 @@ set_level (tree stmt, struct loop *orig_loop, struct loop *level)
information to set it more sanely. */
static void
-set_profitable_level (tree stmt)
+set_profitable_level (gimple stmt)
{
- set_level (stmt, bb_for_stmt (stmt)->loop_father, LIM_DATA (stmt)->max_loop);
+ set_level (stmt, gimple_bb (stmt)->loop_father, get_lim_data (stmt)->max_loop);
}
-/* Returns true if STMT is not a pure call. */
+/* Returns true if STMT is a call that has side effects. */
static bool
-nonpure_call_p (tree stmt)
+nonpure_call_p (gimple stmt)
{
- tree call = get_call_expr_in (stmt);
-
- if (!call)
+ if (gimple_code (stmt) != GIMPLE_CALL)
return false;
- return TREE_SIDE_EFFECTS (call) != 0;
-}
-
-/* Releases the memory occupied by DATA. */
-
-static void
-free_lim_aux_data (struct lim_aux_data *data)
-{
- struct depend *dep, *next;
-
- for (dep = data->depends; dep; dep = next)
- {
- next = dep->next;
- free (dep);
- }
- free (data);
+ return gimple_has_side_effects (stmt);
}
/* Rewrite a/b to a*(1/b). Return the invariant stmt to process. */
-static tree
-rewrite_reciprocal (block_stmt_iterator *bsi)
+static gimple
+rewrite_reciprocal (gimple_stmt_iterator *bsi)
{
- tree stmt, lhs, rhs, stmt1, stmt2, var, name, tmp;
+ gimple stmt, stmt1, stmt2;
+ tree var, name, lhs, type;
- stmt = bsi_stmt (*bsi);
- lhs = GENERIC_TREE_OPERAND (stmt, 0);
- rhs = GENERIC_TREE_OPERAND (stmt, 1);
+ stmt = gsi_stmt (*bsi);
+ lhs = gimple_assign_lhs (stmt);
+ type = TREE_TYPE (lhs);
- /* stmt must be GIMPLE_MODIFY_STMT. */
- var = create_tmp_var (TREE_TYPE (rhs), "reciptmp");
+ var = create_tmp_var (type, "reciptmp");
add_referenced_var (var);
- tmp = build2 (RDIV_EXPR, TREE_TYPE (rhs),
- build_real (TREE_TYPE (rhs), dconst1),
- TREE_OPERAND (rhs, 1));
- stmt1 = build_gimple_modify_stmt (var, tmp);
+ stmt1 = gimple_build_assign_with_ops (RDIV_EXPR,
+ var, build_real (type, dconst1), gimple_assign_rhs2 (stmt));
name = make_ssa_name (var, stmt1);
- GIMPLE_STMT_OPERAND (stmt1, 0) = name;
- tmp = build2 (MULT_EXPR, TREE_TYPE (rhs),
- name, TREE_OPERAND (rhs, 0));
- stmt2 = build_gimple_modify_stmt (lhs, tmp);
+ gimple_assign_set_lhs (stmt1, name);
+
+ stmt2 = gimple_build_assign_with_ops (MULT_EXPR, lhs, name,
+ gimple_assign_rhs1 (stmt));
/* Replace division stmt with reciprocal and multiply stmts.
The multiply stmt is not invariant, so update iterator
and avoid rescanning. */
- bsi_replace (bsi, stmt1, true);
- bsi_insert_after (bsi, stmt2, BSI_NEW_STMT);
- SSA_NAME_DEF_STMT (lhs) = stmt2;
+ gsi_replace (bsi, stmt1, true);
+ gsi_insert_after (bsi, stmt2, GSI_NEW_STMT);
/* Continue processing with invariant reciprocal statement. */
return stmt1;
@@ -785,82 +792,79 @@ rewrite_reciprocal (block_stmt_iterator *bsi)
/* Check if the pattern at *BSI is a bittest of the form
(A >> B) & 1 != 0 and in this case rewrite it to A & (1 << B) != 0. */
-static tree
-rewrite_bittest (block_stmt_iterator *bsi)
+static gimple
+rewrite_bittest (gimple_stmt_iterator *bsi)
{
- tree stmt, lhs, rhs, var, name, use_stmt, stmt1, stmt2, t;
+ gimple stmt, use_stmt, stmt1, stmt2;
+ tree lhs, var, name, t, a, b;
use_operand_p use;
- stmt = bsi_stmt (*bsi);
- lhs = GENERIC_TREE_OPERAND (stmt, 0);
- rhs = GENERIC_TREE_OPERAND (stmt, 1);
+ stmt = gsi_stmt (*bsi);
+ lhs = gimple_assign_lhs (stmt);
/* Verify that the single use of lhs is a comparison against zero. */
if (TREE_CODE (lhs) != SSA_NAME
|| !single_imm_use (lhs, &use, &use_stmt)
- || TREE_CODE (use_stmt) != COND_EXPR)
+ || gimple_code (use_stmt) != GIMPLE_COND)
return stmt;
- t = COND_EXPR_COND (use_stmt);
- if (TREE_OPERAND (t, 0) != lhs
- || (TREE_CODE (t) != NE_EXPR
- && TREE_CODE (t) != EQ_EXPR)
- || !integer_zerop (TREE_OPERAND (t, 1)))
+ if (gimple_cond_lhs (use_stmt) != lhs
+ || (gimple_cond_code (use_stmt) != NE_EXPR
+ && gimple_cond_code (use_stmt) != EQ_EXPR)
+ || !integer_zerop (gimple_cond_rhs (use_stmt)))
return stmt;
/* Get at the operands of the shift. The rhs is TMP1 & 1. */
- stmt1 = SSA_NAME_DEF_STMT (TREE_OPERAND (rhs, 0));
- if (TREE_CODE (stmt1) != GIMPLE_MODIFY_STMT)
+ stmt1 = SSA_NAME_DEF_STMT (gimple_assign_rhs1 (stmt));
+ if (gimple_code (stmt1) != GIMPLE_ASSIGN)
return stmt;
/* There is a conversion in between possibly inserted by fold. */
- t = GIMPLE_STMT_OPERAND (stmt1, 1);
- if (CONVERT_EXPR_P (t))
+ if (gimple_assign_rhs_code (stmt1) == NOP_EXPR
+ || gimple_assign_rhs_code (stmt1) == CONVERT_EXPR)
{
- t = TREE_OPERAND (t, 0);
+ t = gimple_assign_rhs1 (stmt1);
if (TREE_CODE (t) != SSA_NAME
|| !has_single_use (t))
return stmt;
stmt1 = SSA_NAME_DEF_STMT (t);
- if (TREE_CODE (stmt1) != GIMPLE_MODIFY_STMT)
+ if (gimple_code (stmt1) != GIMPLE_ASSIGN)
return stmt;
- t = GIMPLE_STMT_OPERAND (stmt1, 1);
}
/* Verify that B is loop invariant but A is not. Verify that with
all the stmt walking we are still in the same loop. */
- if (TREE_CODE (t) == RSHIFT_EXPR
- && loop_containing_stmt (stmt1) == loop_containing_stmt (stmt)
- && outermost_invariant_loop_expr (TREE_OPERAND (t, 1),
- loop_containing_stmt (stmt1)) != NULL
- && outermost_invariant_loop_expr (TREE_OPERAND (t, 0),
- loop_containing_stmt (stmt1)) == NULL)
- {
- tree a = TREE_OPERAND (t, 0);
- tree b = TREE_OPERAND (t, 1);
+ if (gimple_assign_rhs_code (stmt1) != RSHIFT_EXPR
+ || loop_containing_stmt (stmt1) != loop_containing_stmt (stmt))
+ return stmt;
+ a = gimple_assign_rhs1 (stmt1);
+ b = gimple_assign_rhs2 (stmt1);
+
+ if (outermost_invariant_loop (b, loop_containing_stmt (stmt1)) != NULL
+ && outermost_invariant_loop (a, loop_containing_stmt (stmt1)) == NULL)
+ {
/* 1 << B */
var = create_tmp_var (TREE_TYPE (a), "shifttmp");
add_referenced_var (var);
t = fold_build2 (LSHIFT_EXPR, TREE_TYPE (a),
build_int_cst (TREE_TYPE (a), 1), b);
- stmt1 = build_gimple_modify_stmt (var, t);
+ stmt1 = gimple_build_assign (var, t);
name = make_ssa_name (var, stmt1);
- GIMPLE_STMT_OPERAND (stmt1, 0) = name;
+ gimple_assign_set_lhs (stmt1, name);
/* A & (1 << B) */
t = fold_build2 (BIT_AND_EXPR, TREE_TYPE (a), a, name);
- stmt2 = build_gimple_modify_stmt (var, t);
+ stmt2 = gimple_build_assign (var, t);
name = make_ssa_name (var, stmt2);
- GIMPLE_STMT_OPERAND (stmt2, 0) = name;
+ gimple_assign_set_lhs (stmt2, name);
/* Replace the SSA_NAME we compare against zero. Adjust
the type of zero accordingly. */
SET_USE (use, name);
- TREE_OPERAND (COND_EXPR_COND (use_stmt), 1)
- = build_int_cst_type (TREE_TYPE (name), 0);
+ gimple_cond_set_rhs (use_stmt, build_int_cst_type (TREE_TYPE (name), 0));
- bsi_insert_before (bsi, stmt1, BSI_SAME_STMT);
- bsi_replace (bsi, stmt2, true);
+ gsi_insert_before (bsi, stmt1, GSI_SAME_STMT);
+ gsi_replace (bsi, stmt2, true);
return stmt1;
}
@@ -878,10 +882,11 @@ determine_invariantness_stmt (struct dom_walk_data *dw_data ATTRIBUTE_UNUSED,
basic_block bb)
{
enum move_pos pos;
- block_stmt_iterator bsi;
- tree stmt, rhs;
+ gimple_stmt_iterator bsi;
+ gimple stmt;
bool maybe_never = ALWAYS_EXECUTED_IN (bb) == NULL;
struct loop *outermost = ALWAYS_EXECUTED_IN (bb);
+ struct lim_aux_data *lim_data;
if (!loop_outer (bb->loop_father))
return;
@@ -890,9 +895,9 @@ determine_invariantness_stmt (struct dom_walk_data *dw_data ATTRIBUTE_UNUSED,
fprintf (dump_file, "Basic block %d (loop %d -- depth %d):\n\n",
bb->index, bb->loop_father->num, loop_depth (bb->loop_father));
- for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
+ for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi))
{
- stmt = bsi_stmt (bsi);
+ stmt = gsi_stmt (bsi);
pos = movement_possibility (stmt);
if (pos == MOVE_IMPOSSIBLE)
@@ -906,61 +911,63 @@ determine_invariantness_stmt (struct dom_walk_data *dw_data ATTRIBUTE_UNUSED,
store-motion work. */
else if (stmt_makes_single_store (stmt))
{
- stmt_ann (stmt)->common.aux
- = xcalloc (1, sizeof (struct lim_aux_data));
- LIM_DATA (stmt)->always_executed_in = outermost;
+ struct lim_aux_data *lim_data = init_lim_data (stmt);
+ lim_data->always_executed_in = outermost;
}
continue;
}
- if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT)
+ if (is_gimple_assign (stmt)
+ && (get_gimple_rhs_class (gimple_assign_rhs_code (stmt))
+ == GIMPLE_BINARY_RHS))
{
- rhs = GIMPLE_STMT_OPERAND (stmt, 1);
+ tree op0 = gimple_assign_rhs1 (stmt);
+ tree op1 = gimple_assign_rhs2 (stmt);
+ struct loop *ol1 = outermost_invariant_loop (op1,
+ loop_containing_stmt (stmt));
/* If divisor is invariant, convert a/b to a*(1/b), allowing reciprocal
to be hoisted out of loop, saving expensive divide. */
if (pos == MOVE_POSSIBLE
- && TREE_CODE (rhs) == RDIV_EXPR
+ && gimple_assign_rhs_code (stmt) == RDIV_EXPR
&& flag_unsafe_math_optimizations
&& !flag_trapping_math
- && outermost_invariant_loop_expr (TREE_OPERAND (rhs, 1),
- loop_containing_stmt (stmt)) != NULL
- && outermost_invariant_loop_expr (rhs,
- loop_containing_stmt (stmt)) == NULL)
+ && ol1 != NULL
+ && outermost_invariant_loop (op0, ol1) == NULL)
stmt = rewrite_reciprocal (&bsi);
/* If the shift count is invariant, convert (A >> B) & 1 to
A & (1 << B) allowing the bit mask to be hoisted out of the loop
saving an expensive shift. */
if (pos == MOVE_POSSIBLE
- && TREE_CODE (rhs) == BIT_AND_EXPR
- && integer_onep (TREE_OPERAND (rhs, 1))
- && TREE_CODE (TREE_OPERAND (rhs, 0)) == SSA_NAME
- && has_single_use (TREE_OPERAND (rhs, 0)))
+ && gimple_assign_rhs_code (stmt) == BIT_AND_EXPR
+ && integer_onep (op1)
+ && TREE_CODE (op0) == SSA_NAME
+ && has_single_use (op0))
stmt = rewrite_bittest (&bsi);
}
- stmt_ann (stmt)->common.aux = xcalloc (1, sizeof (struct lim_aux_data));
- LIM_DATA (stmt)->always_executed_in = outermost;
+ lim_data = init_lim_data (stmt);
+ lim_data->always_executed_in = outermost;
if (maybe_never && pos == MOVE_PRESERVE_EXECUTION)
continue;
if (!determine_max_movement (stmt, pos == MOVE_PRESERVE_EXECUTION))
{
- LIM_DATA (stmt)->max_loop = NULL;
+ lim_data->max_loop = NULL;
continue;
}
if (dump_file && (dump_flags & TDF_DETAILS))
{
- print_generic_stmt_indented (dump_file, stmt, 0, 2);
+ print_gimple_stmt (dump_file, stmt, 2, 0);
fprintf (dump_file, " invariant up to level %d, cost %d.\n\n",
- loop_depth (LIM_DATA (stmt)->max_loop),
- LIM_DATA (stmt)->cost);
+ loop_depth (lim_data->max_loop),
+ lim_data->cost);
}
- if (LIM_DATA (stmt)->cost >= LIM_EXPENSIVE)
+ if (lim_data->cost >= LIM_EXPENSIVE)
set_profitable_level (stmt);
}
}
@@ -993,50 +1000,51 @@ move_computations_stmt (struct dom_walk_data *dw_data ATTRIBUTE_UNUSED,
basic_block bb)
{
struct loop *level;
- block_stmt_iterator bsi;
- tree stmt;
+ gimple_stmt_iterator bsi;
+ gimple stmt;
unsigned cost = 0;
+ struct lim_aux_data *lim_data;
if (!loop_outer (bb->loop_father))
return;
- for (bsi = bsi_start (bb); !bsi_end_p (bsi); )
+ for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); )
{
- stmt = bsi_stmt (bsi);
+ stmt = gsi_stmt (bsi);
- if (!LIM_DATA (stmt))
+ lim_data = get_lim_data (stmt);
+ if (lim_data == NULL)
{
- bsi_next (&bsi);
+ gsi_next (&bsi);
continue;
}
- cost = LIM_DATA (stmt)->cost;
- level = LIM_DATA (stmt)->tgt_loop;
- free_lim_aux_data (LIM_DATA (stmt));
- stmt_ann (stmt)->common.aux = NULL;
+ cost = lim_data->cost;
+ level = lim_data->tgt_loop;
+ clear_lim_data (stmt);
if (!level)
{
- bsi_next (&bsi);
+ gsi_next (&bsi);
continue;
}
/* We do not really want to move conditionals out of the loop; we just
placed it here to force its operands to be moved if necessary. */
- if (TREE_CODE (stmt) == COND_EXPR)
+ if (gimple_code (stmt) == GIMPLE_COND)
continue;
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "Moving statement\n");
- print_generic_stmt (dump_file, stmt, 0);
+ print_gimple_stmt (dump_file, stmt, 0, 0);
fprintf (dump_file, "(cost %u) out of loop %d.\n\n",
cost, level->num);
}
mark_virtual_ops_for_renaming (stmt);
- bsi_insert_on_edge (loop_preheader_edge (level), stmt);
- bsi_remove (&bsi, false);
+ gsi_insert_on_edge (loop_preheader_edge (level), stmt);
+ gsi_remove (&bsi, false);
}
}
@@ -1056,7 +1064,7 @@ move_computations (void)
walk_dominator_tree (&walk_data, ENTRY_BLOCK_PTR);
fini_walk_dominator_tree (&walk_data);
- bsi_commit_edge_inserts ();
+ gsi_commit_edge_inserts ();
if (need_ssa_update_p ())
rewrite_into_loop_closed_ssa (NULL, TODO_update_ssa);
}
@@ -1067,20 +1075,20 @@ move_computations (void)
static bool
may_move_till (tree ref, tree *index, void *data)
{
- struct loop *loop = (struct loop*) data, *max_loop;
+ struct loop *loop = (struct loop *) data, *max_loop;
/* If REF is an array reference, check also that the step and the lower
bound is invariant in LOOP. */
if (TREE_CODE (ref) == ARRAY_REF)
{
- tree step = array_ref_element_size (ref);
- tree lbound = array_ref_low_bound (ref);
+ tree step = TREE_OPERAND (ref, 3);
+ tree lbound = TREE_OPERAND (ref, 2);
- max_loop = outermost_invariant_loop_expr (step, loop);
+ max_loop = outermost_invariant_loop (step, loop);
if (!max_loop)
return false;
- max_loop = outermost_invariant_loop_expr (lbound, loop);
+ max_loop = outermost_invariant_loop (lbound, loop);
if (!max_loop)
return false;
}
@@ -1092,35 +1100,25 @@ may_move_till (tree ref, tree *index, void *data)
return true;
}
-/* Forces statements defining (invariant) SSA names in expression EXPR to be
+/* If OP is SSA NAME, force the statement that defines it to be
moved out of the LOOP. ORIG_LOOP is the loop in that EXPR is used. */
static void
-force_move_till_expr (tree expr, struct loop *orig_loop, struct loop *loop)
+force_move_till_op (tree op, struct loop *orig_loop, struct loop *loop)
{
- enum tree_code_class codeclass = TREE_CODE_CLASS (TREE_CODE (expr));
- unsigned i, nops;
-
- if (TREE_CODE (expr) == SSA_NAME)
- {
- tree stmt = SSA_NAME_DEF_STMT (expr);
- if (IS_EMPTY_STMT (stmt))
- return;
+ gimple stmt;
- set_level (stmt, orig_loop, loop);
- return;
- }
+ if (!op
+ || is_gimple_min_invariant (op))
+ return;
- if (codeclass != tcc_unary
- && codeclass != tcc_binary
- && codeclass != tcc_expression
- && codeclass != tcc_vl_exp
- && codeclass != tcc_comparison)
+ gcc_assert (TREE_CODE (op) == SSA_NAME);
+
+ stmt = SSA_NAME_DEF_STMT (op);
+ if (gimple_nop_p (stmt))
return;
- nops = TREE_OPERAND_LENGTH (expr);
- for (i = 0; i < nops; i++)
- force_move_till_expr (TREE_OPERAND (expr, i), orig_loop, loop);
+ set_level (stmt, orig_loop, loop);
}
/* Forces statement defining invariants in REF (and *INDEX) to be moved out of
@@ -1136,26 +1134,18 @@ struct fmt_data
static bool
force_move_till (tree ref, tree *index, void *data)
{
- tree stmt;
struct fmt_data *fmt_data = (struct fmt_data *) data;
if (TREE_CODE (ref) == ARRAY_REF)
{
- tree step = array_ref_element_size (ref);
- tree lbound = array_ref_low_bound (ref);
+ tree step = TREE_OPERAND (ref, 3);
+ tree lbound = TREE_OPERAND (ref, 2);
- force_move_till_expr (step, fmt_data->orig_loop, fmt_data->loop);
- force_move_till_expr (lbound, fmt_data->orig_loop, fmt_data->loop);
+ force_move_till_op (step, fmt_data->orig_loop, fmt_data->loop);
+ force_move_till_op (lbound, fmt_data->orig_loop, fmt_data->loop);
}
- if (TREE_CODE (*index) != SSA_NAME)
- return true;
-
- stmt = SSA_NAME_DEF_STMT (*index);
- if (IS_EMPTY_STMT (stmt))
- return true;
-
- set_level (stmt, fmt_data->orig_loop, fmt_data->loop);
+ force_move_till_op (*index, fmt_data->orig_loop, fmt_data->loop);
return true;
}
@@ -1256,7 +1246,7 @@ mem_ref_locs_alloc (void)
description REF. The reference occurs in statement STMT. */
static void
-record_mem_ref_loc (mem_ref_p ref, struct loop *loop, tree stmt, tree *loc)
+record_mem_ref_loc (mem_ref_p ref, struct loop *loop, gimple stmt, tree *loc)
{
mem_ref_loc_p aref = XNEW (struct mem_ref_loc);
mem_ref_locs_p accs;
@@ -1298,7 +1288,7 @@ mark_ref_stored (mem_ref_p ref, struct loop *loop)
well. */
static void
-gather_mem_refs_stmt (struct loop *loop, tree stmt)
+gather_mem_refs_stmt (struct loop *loop, gimple stmt)
{
tree *mem = NULL;
hashval_t hash;
@@ -1358,7 +1348,7 @@ fail:
static void
gather_mem_refs_in_loops (void)
{
- block_stmt_iterator bsi;
+ gimple_stmt_iterator bsi;
basic_block bb;
struct loop *loop;
loop_iterator li;
@@ -1371,8 +1361,8 @@ gather_mem_refs_in_loops (void)
if (loop == current_loops->tree_root)
continue;
- for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
- gather_mem_refs_stmt (loop, bsi_stmt (bsi));
+ for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi))
+ gather_mem_refs_stmt (loop, gsi_stmt (bsi));
}
/* Propagate the information about clobbered vops and accessed memory
@@ -1826,9 +1816,10 @@ execute_sm (struct loop *loop, VEC (edge, heap) *exits, mem_ref_p ref)
{
tree tmp_var;
unsigned i;
- tree load, store;
+ gimple load, store;
struct fmt_data fmt_data;
edge ex;
+ struct lim_aux_data *lim_data;
if (dump_file && (dump_flags & TDF_DETAILS))
{
@@ -1847,19 +1838,19 @@ execute_sm (struct loop *loop, VEC (edge, heap) *exits, mem_ref_p ref)
rewrite_mem_refs (loop, ref, tmp_var);
/* Emit the load & stores. */
- load = build_gimple_modify_stmt (tmp_var, unshare_expr (ref->mem));
- get_stmt_ann (load)->common.aux = xcalloc (1, sizeof (struct lim_aux_data));
- LIM_DATA (load)->max_loop = loop;
- LIM_DATA (load)->tgt_loop = loop;
+ load = gimple_build_assign (tmp_var, unshare_expr (ref->mem));
+ lim_data = init_lim_data (load);
+ lim_data->max_loop = loop;
+ lim_data->tgt_loop = loop;
/* Put this into the latch, so that we are sure it will be processed after
all dependencies. */
- bsi_insert_on_edge (loop_latch_edge (loop), load);
+ gsi_insert_on_edge (loop_latch_edge (loop), load);
for (i = 0; VEC_iterate (edge, exits, i, ex); i++)
{
- store = build_gimple_modify_stmt (unshare_expr (ref->mem), tmp_var);
- bsi_insert_on_edge (ex, store);
+ store = gimple_build_assign (unshare_expr (ref->mem), tmp_var);
+ gsi_insert_on_edge (ex, store);
}
}
@@ -1895,10 +1886,10 @@ ref_always_accessed_p (struct loop *loop, mem_ref_p ref)
get_all_locs_in_loop (loop, ref, &locs);
for (i = 0; VEC_iterate (mem_ref_loc_p, locs, i, loc); i++)
{
- if (!LIM_DATA (loc->stmt))
+ if (!get_lim_data (loc->stmt))
continue;
- must_exec = LIM_DATA (loc->stmt)->always_executed_in;
+ must_exec = get_lim_data (loc->stmt)->always_executed_in;
if (!must_exec)
continue;
@@ -2135,7 +2126,7 @@ store_motion (void)
store_motion_loop (loop, sm_executed);
BITMAP_FREE (sm_executed);
- bsi_commit_edge_inserts ();
+ gsi_commit_edge_inserts ();
}
/* Fills ALWAYS_EXECUTED_IN information for basic blocks of LOOP, i.e.
@@ -2212,20 +2203,20 @@ static void
tree_ssa_lim_initialize (void)
{
sbitmap contains_call = sbitmap_alloc (last_basic_block);
- block_stmt_iterator bsi;
+ gimple_stmt_iterator bsi;
struct loop *loop;
basic_block bb;
sbitmap_zero (contains_call);
FOR_EACH_BB (bb)
{
- for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
+ for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi))
{
- if (nonpure_call_p (bsi_stmt (bsi)))
+ if (nonpure_call_p (gsi_stmt (bsi)))
break;
}
- if (!bsi_end_p (bsi))
+ if (!gsi_end_p (bsi))
SET_BIT (contains_call, bb->index);
}
@@ -2233,6 +2224,8 @@ tree_ssa_lim_initialize (void)
fill_always_executed_in (loop, contains_call);
sbitmap_free (contains_call);
+
+ lim_aux_data_map = pointer_map_create ();
}
/* Cleans up after the invariant motion pass. */
@@ -2250,6 +2243,8 @@ tree_ssa_lim_finalize (void)
bb->aux = NULL;
}
+ pointer_map_destroy (lim_aux_data_map);
+
VEC_free (mem_ref_p, heap, memory_accesses.refs_list);
htab_delete (memory_accesses.refs);
diff --git a/gcc/tree-ssa-loop-ivcanon.c b/gcc/tree-ssa-loop-ivcanon.c
index 67af0b374d6..dc863f8b8a5 100644
--- a/gcc/tree-ssa-loop-ivcanon.c
+++ b/gcc/tree-ssa-loop-ivcanon.c
@@ -1,5 +1,5 @@
/* Induction variable canonicalization.
- Copyright (C) 2004, 2005, 2007 Free Software Foundation, Inc.
+ Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
This file is part of GCC.
@@ -72,8 +72,9 @@ static void
create_canonical_iv (struct loop *loop, edge exit, tree niter)
{
edge in;
- tree cond, type, var;
- block_stmt_iterator incr_at;
+ tree type, var;
+ gimple cond;
+ gimple_stmt_iterator incr_at;
enum tree_code cmp;
if (dump_file && (dump_flags & TDF_DETAILS))
@@ -97,16 +98,16 @@ create_canonical_iv (struct loop *loop, edge exit, tree niter)
niter = fold_build2 (PLUS_EXPR, type,
niter,
build_int_cst (type, 1));
- incr_at = bsi_last (in->src);
+ incr_at = gsi_last_bb (in->src);
create_iv (niter,
build_int_cst (type, -1),
NULL_TREE, loop,
&incr_at, false, NULL, &var);
cmp = (exit->flags & EDGE_TRUE_VALUE) ? EQ_EXPR : NE_EXPR;
- COND_EXPR_COND (cond) = build2 (cmp, boolean_type_node,
- var,
- build_int_cst (type, 0));
+ gimple_cond_set_code (cond, cmp);
+ gimple_cond_set_lhs (cond, var);
+ gimple_cond_set_rhs (cond, build_int_cst (type, 0));
update_stmt (cond);
}
@@ -116,12 +117,12 @@ unsigned
tree_num_loop_insns (struct loop *loop, eni_weights *weights)
{
basic_block *body = get_loop_body (loop);
- block_stmt_iterator bsi;
+ gimple_stmt_iterator gsi;
unsigned size = 1, i;
for (i = 0; i < loop->num_nodes; i++)
- for (bsi = bsi_start (body[i]); !bsi_end_p (bsi); bsi_next (&bsi))
- size += estimate_num_insns (bsi_stmt (bsi), weights);
+ for (gsi = gsi_start_bb (body[i]); !gsi_end_p (gsi); gsi_next (&gsi))
+ size += estimate_num_insns (gsi_stmt (gsi), weights);
free (body);
return size;
@@ -163,7 +164,7 @@ try_unroll_loop_completely (struct loop *loop,
enum unroll_level ul)
{
unsigned HOST_WIDE_INT n_unroll, ninsns, max_unroll, unr_insns;
- tree cond;
+ gimple cond;
if (loop->inner)
return false;
@@ -216,11 +217,11 @@ try_unroll_loop_completely (struct loop *loop,
sbitmap_ones (wont_exit);
RESET_BIT (wont_exit, 0);
- if (!tree_duplicate_loop_to_header_edge (loop, loop_preheader_edge (loop),
- n_unroll, wont_exit,
- exit, &to_remove,
- DLTHE_FLAG_UPDATE_FREQ
- | DLTHE_FLAG_COMPLETTE_PEEL))
+ if (!gimple_duplicate_loop_to_header_edge (loop, loop_preheader_edge (loop),
+ n_unroll, wont_exit,
+ exit, &to_remove,
+ DLTHE_FLAG_UPDATE_FREQ
+ | DLTHE_FLAG_COMPLETTE_PEEL))
{
free_original_copy_tables ();
free (wont_exit);
@@ -239,8 +240,10 @@ try_unroll_loop_completely (struct loop *loop,
}
cond = last_stmt (exit->src);
- COND_EXPR_COND (cond) = (exit->flags & EDGE_TRUE_VALUE) ? boolean_true_node
- : boolean_false_node;
+ if (exit->flags & EDGE_TRUE_VALUE)
+ gimple_cond_make_true (cond);
+ else
+ gimple_cond_make_false (cond);
update_stmt (cond);
update_ssa (TODO_update_ssa);
@@ -386,11 +389,9 @@ empty_loop_p (struct loop *loop)
{
edge exit;
struct tree_niter_desc niter;
- tree phi, def;
basic_block *body;
- block_stmt_iterator bsi;
+ gimple_stmt_iterator gsi;
unsigned i;
- tree stmt;
/* If the loop has multiple exits, it is too hard for us to handle.
Similarly, if the exit is not dominating, we cannot determine
@@ -404,8 +405,11 @@ empty_loop_p (struct loop *loop)
return false;
/* Values of all loop exit phi nodes must be invariants. */
- for (phi = phi_nodes (exit->dest); phi; phi = PHI_CHAIN (phi))
+ for (gsi = gsi_start(phi_nodes (exit->dest)); !gsi_end_p (gsi); gsi_next (&gsi))
{
+ gimple phi = gsi_stmt (gsi);
+ tree def;
+
if (!is_gimple_reg (PHI_RESULT (phi)))
continue;
@@ -427,11 +431,12 @@ empty_loop_p (struct loop *loop)
return false;
}
- for (bsi = bsi_start (body[i]); !bsi_end_p (bsi); bsi_next (&bsi))
+ for (gsi = gsi_start_bb (body[i]); !gsi_end_p (gsi); gsi_next (&gsi))
{
- stmt = bsi_stmt (bsi);
+ gimple stmt = gsi_stmt (gsi);
+
if (!ZERO_SSA_OPERANDS (stmt, SSA_OP_VIRTUAL_DEFS)
- || stmt_ann (stmt)->has_volatile_ops)
+ || gimple_has_volatile_ops (stmt))
{
free (body);
return false;
@@ -439,25 +444,19 @@ empty_loop_p (struct loop *loop)
/* Also, asm statements and calls may have side effects and we
cannot change the number of times they are executed. */
- switch (TREE_CODE (stmt))
+ switch (gimple_code (stmt))
{
- case RETURN_EXPR:
- case GIMPLE_MODIFY_STMT:
- stmt = get_call_expr_in (stmt);
- if (!stmt)
- break;
-
- case CALL_EXPR:
- if (TREE_SIDE_EFFECTS (stmt))
+ case GIMPLE_CALL:
+ if (gimple_has_side_effects (stmt))
{
free (body);
return false;
}
break;
- case ASM_EXPR:
+ case GIMPLE_ASM:
/* We cannot remove volatile assembler. */
- if (ASM_VOLATILE_P (stmt))
+ if (gimple_asm_volatile_p (stmt))
{
free (body);
return false;
@@ -480,8 +479,7 @@ static void
remove_empty_loop (struct loop *loop)
{
edge exit = single_dom_exit (loop), non_exit;
- tree cond_stmt = last_stmt (exit->src);
- tree do_exit;
+ gimple cond_stmt = last_stmt (exit->src);
basic_block *body;
unsigned n_before, freq_in, freq_h;
gcov_type exit_count = exit->count;
@@ -494,11 +492,9 @@ remove_empty_loop (struct loop *loop)
non_exit = EDGE_SUCC (exit->src, 1);
if (exit->flags & EDGE_TRUE_VALUE)
- do_exit = boolean_true_node;
+ gimple_cond_make_true (cond_stmt);
else
- do_exit = boolean_false_node;
-
- COND_EXPR_COND (cond_stmt) = do_exit;
+ gimple_cond_make_false (cond_stmt);
update_stmt (cond_stmt);
/* Let us set the probabilities of the edges coming from the exit block. */
@@ -569,3 +565,4 @@ remove_empty_loops (void)
}
return 0;
}
+
diff --git a/gcc/tree-ssa-loop-ivopts.c b/gcc/tree-ssa-loop-ivopts.c
index ce5c05cd88f..c314da49f94 100644
--- a/gcc/tree-ssa-loop-ivopts.c
+++ b/gcc/tree-ssa-loop-ivopts.c
@@ -163,7 +163,7 @@ struct iv_use
unsigned id; /* The id of the use. */
enum use_type type; /* Type of the use. */
struct iv *iv; /* The induction variable it is based on. */
- tree stmt; /* Statement in that it occurs. */
+ gimple stmt; /* Statement in that it occurs. */
tree *op_p; /* The place where it occurs. */
bitmap related_cands; /* The set of "related" iv candidates, plus the common
important ones. */
@@ -191,7 +191,7 @@ struct iv_cand
bool important; /* Whether this is an "important" candidate, i.e. such
that it should be considered by all uses. */
enum iv_position pos; /* Where it is computed. */
- tree incremented_at; /* For original biv, the statement where it is
+ gimple incremented_at;/* For original biv, the statement where it is
incremented. */
tree var_before; /* The variable used for it before increment. */
tree var_after; /* The variable used for it after increment. */
@@ -448,7 +448,7 @@ dump_use (FILE *file, struct iv_use *use)
}
fprintf (file, " in statement ");
- print_generic_expr (file, use->stmt, TDF_SLIM);
+ print_gimple_stmt (file, use->stmt, 0, 0);
fprintf (file, "\n");
fprintf (file, " at position ");
@@ -544,9 +544,9 @@ name_info (struct ivopts_data *data, tree name)
emitted in LOOP. */
static bool
-stmt_after_ip_normal_pos (struct loop *loop, tree stmt)
+stmt_after_ip_normal_pos (struct loop *loop, gimple stmt)
{
- basic_block bb = ip_normal_pos (loop), sbb = bb_for_stmt (stmt);
+ basic_block bb = ip_normal_pos (loop), sbb = gimple_bb (stmt);
gcc_assert (bb);
@@ -563,11 +563,11 @@ stmt_after_ip_normal_pos (struct loop *loop, tree stmt)
variable CAND is incremented. */
static bool
-stmt_after_ip_original_pos (struct iv_cand *cand, tree stmt)
+stmt_after_ip_original_pos (struct iv_cand *cand, gimple stmt)
{
- basic_block cand_bb = bb_for_stmt (cand->incremented_at);
- basic_block stmt_bb = bb_for_stmt (stmt);
- block_stmt_iterator bsi;
+ basic_block cand_bb = gimple_bb (cand->incremented_at);
+ basic_block stmt_bb = gimple_bb (stmt);
+ gimple_stmt_iterator bsi;
if (!dominated_by_p (CDI_DOMINATORS, stmt_bb, cand_bb))
return false;
@@ -577,11 +577,11 @@ stmt_after_ip_original_pos (struct iv_cand *cand, tree stmt)
/* Scan the block from the end, since the original ivs are usually
incremented at the end of the loop body. */
- for (bsi = bsi_last (stmt_bb); ; bsi_prev (&bsi))
+ for (bsi = gsi_last_bb (stmt_bb); ; gsi_prev (&bsi))
{
- if (bsi_stmt (bsi) == cand->incremented_at)
+ if (gsi_stmt (bsi) == cand->incremented_at)
return false;
- if (bsi_stmt (bsi) == stmt)
+ if (gsi_stmt (bsi) == stmt)
return true;
}
}
@@ -590,7 +590,7 @@ stmt_after_ip_original_pos (struct iv_cand *cand, tree stmt)
CAND is incremented in LOOP. */
static bool
-stmt_after_increment (struct loop *loop, struct iv_cand *cand, tree stmt)
+stmt_after_increment (struct loop *loop, struct iv_cand *cand, gimple stmt)
{
switch (cand->pos)
{
@@ -858,7 +858,7 @@ get_iv (struct ivopts_data *data, tree var)
if (!name_info (data, var)->iv)
{
- bb = bb_for_stmt (SSA_NAME_DEF_STMT (var));
+ bb = gimple_bb (SSA_NAME_DEF_STMT (var));
if (!bb
|| !flow_bb_inside_loop_p (data->current_loop, bb))
@@ -872,9 +872,9 @@ get_iv (struct ivopts_data *data, tree var)
not define a simple affine biv with nonzero step. */
static tree
-determine_biv_step (tree phi)
+determine_biv_step (gimple phi)
{
- struct loop *loop = bb_for_stmt (phi)->loop_father;
+ struct loop *loop = gimple_bb (phi)->loop_father;
tree name = PHI_RESULT (phi);
affine_iv iv;
@@ -892,12 +892,16 @@ determine_biv_step (tree phi)
static bool
find_bivs (struct ivopts_data *data)
{
- tree phi, step, type, base;
+ gimple phi;
+ tree step, type, base;
bool found = false;
struct loop *loop = data->current_loop;
+ gimple_stmt_iterator psi;
- for (phi = phi_nodes (loop->header); phi; phi = PHI_CHAIN (phi))
+ for (psi = gsi_start_phis (loop->header); !gsi_end_p (psi); gsi_next (&psi))
{
+ phi = gsi_stmt (psi);
+
if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (PHI_RESULT (phi)))
continue;
@@ -933,13 +937,17 @@ find_bivs (struct ivopts_data *data)
static void
mark_bivs (struct ivopts_data *data)
{
- tree phi, var;
+ gimple phi;
+ tree var;
struct iv *iv, *incr_iv;
struct loop *loop = data->current_loop;
basic_block incr_bb;
+ gimple_stmt_iterator psi;
- for (phi = phi_nodes (loop->header); phi; phi = PHI_CHAIN (phi))
+ for (psi = gsi_start_phis (loop->header); !gsi_end_p (psi); gsi_next (&psi))
{
+ phi = gsi_stmt (psi);
+
iv = get_iv (data, PHI_RESULT (phi));
if (!iv)
continue;
@@ -950,7 +958,7 @@ mark_bivs (struct ivopts_data *data)
continue;
/* If the increment is in the subloop, ignore it. */
- incr_bb = bb_for_stmt (SSA_NAME_DEF_STMT (var));
+ incr_bb = gimple_bb (SSA_NAME_DEF_STMT (var));
if (incr_bb->loop_father != data->current_loop
|| (incr_bb->flags & BB_IRREDUCIBLE_LOOP))
continue;
@@ -964,7 +972,7 @@ mark_bivs (struct ivopts_data *data)
parameters to IV. */
static bool
-find_givs_in_stmt_scev (struct ivopts_data *data, tree stmt, affine_iv *iv)
+find_givs_in_stmt_scev (struct ivopts_data *data, gimple stmt, affine_iv *iv)
{
tree lhs;
struct loop *loop = data->current_loop;
@@ -972,14 +980,14 @@ find_givs_in_stmt_scev (struct ivopts_data *data, tree stmt, affine_iv *iv)
iv->base = NULL_TREE;
iv->step = NULL_TREE;
- if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT)
+ if (gimple_code (stmt) != GIMPLE_ASSIGN)
return false;
- lhs = GIMPLE_STMT_OPERAND (stmt, 0);
+ lhs = gimple_assign_lhs (stmt);
if (TREE_CODE (lhs) != SSA_NAME)
return false;
- if (!simple_iv (loop, stmt, GIMPLE_STMT_OPERAND (stmt, 1), iv, true))
+ if (!simple_iv (loop, stmt, lhs, iv, true))
return false;
iv->base = expand_simple_operations (iv->base);
@@ -993,14 +1001,14 @@ find_givs_in_stmt_scev (struct ivopts_data *data, tree stmt, affine_iv *iv)
/* Finds general ivs in statement STMT. */
static void
-find_givs_in_stmt (struct ivopts_data *data, tree stmt)
+find_givs_in_stmt (struct ivopts_data *data, gimple stmt)
{
affine_iv iv;
if (!find_givs_in_stmt_scev (data, stmt, &iv))
return;
- set_iv (data, GIMPLE_STMT_OPERAND (stmt, 0), iv.base, iv.step);
+ set_iv (data, gimple_assign_lhs (stmt), iv.base, iv.step);
}
/* Finds general ivs in basic block BB. */
@@ -1008,10 +1016,10 @@ find_givs_in_stmt (struct ivopts_data *data, tree stmt)
static void
find_givs_in_bb (struct ivopts_data *data, basic_block bb)
{
- block_stmt_iterator bsi;
+ gimple_stmt_iterator bsi;
- for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
- find_givs_in_stmt (data, bsi_stmt (bsi));
+ for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi))
+ find_givs_in_stmt (data, gsi_stmt (bsi));
}
/* Finds general ivs. */
@@ -1070,7 +1078,7 @@ find_induction_variables (struct ivopts_data *data)
static struct iv_use *
record_use (struct ivopts_data *data, tree *use_p, struct iv *iv,
- tree stmt, enum use_type use_type)
+ gimple stmt, enum use_type use_type)
{
struct iv_use *use = XCNEW (struct iv_use);
@@ -1107,7 +1115,7 @@ record_invariant (struct ivopts_data *data, tree op, bool nonlinear_use)
|| !is_gimple_reg (op))
return;
- bb = bb_for_stmt (SSA_NAME_DEF_STMT (op));
+ bb = gimple_bb (SSA_NAME_DEF_STMT (op));
if (bb
&& flow_bb_inside_loop_p (data->current_loop, bb))
return;
@@ -1127,7 +1135,7 @@ find_interesting_uses_op (struct ivopts_data *data, tree op)
{
struct iv *iv;
struct iv *civ;
- tree stmt;
+ gimple stmt;
struct iv_use *use;
if (TREE_CODE (op) != SSA_NAME)
@@ -1156,8 +1164,8 @@ find_interesting_uses_op (struct ivopts_data *data, tree op)
*civ = *iv;
stmt = SSA_NAME_DEF_STMT (op);
- gcc_assert (TREE_CODE (stmt) == PHI_NODE
- || TREE_CODE (stmt) == GIMPLE_MODIFY_STMT);
+ gcc_assert (gimple_code (stmt) == GIMPLE_PHI
+ || is_gimple_assign (stmt));
use = record_use (data, NULL, civ, stmt, USE_NONLINEAR_EXPR);
iv->use_id = use->id;
@@ -1165,47 +1173,40 @@ find_interesting_uses_op (struct ivopts_data *data, tree op)
return use;
}
-/* Given a condition *COND_P, checks whether it is a compare of an induction
- variable and an invariant. If this is the case, CONTROL_VAR is set
- to location of the iv, BOUND to the location of the invariant,
- IV_VAR and IV_BOUND are set to the corresponding induction variable
- descriptions, and true is returned. If this is not the case,
- CONTROL_VAR and BOUND are set to the arguments of the condition and
- false is returned. */
+/* Given a condition in statement STMT, checks whether it is a compare
+ of an induction variable and an invariant. If this is the case,
+ CONTROL_VAR is set to location of the iv, BOUND to the location of
+ the invariant, IV_VAR and IV_BOUND are set to the corresponding
+ induction variable descriptions, and true is returned. If this is not
+ the case, CONTROL_VAR and BOUND are set to the arguments of the
+ condition and false is returned. */
static bool
-extract_cond_operands (struct ivopts_data *data, tree *cond_p,
+extract_cond_operands (struct ivopts_data *data, gimple stmt,
tree **control_var, tree **bound,
struct iv **iv_var, struct iv **iv_bound)
{
- /* The nodes returned when COND has just one operand. Note that you should
- not modify anything in BOUND or IV_BOUND because of this. */
+ /* The objects returned when COND has constant operands. */
static struct iv const_iv;
static tree zero;
- tree cond = *cond_p;
tree *op0 = &zero, *op1 = &zero, *tmp_op;
struct iv *iv0 = &const_iv, *iv1 = &const_iv, *tmp_iv;
bool ret = false;
- zero = integer_zero_node;
- const_iv.step = integer_zero_node;
-
- if (TREE_CODE (cond) == SSA_NAME)
+ if (gimple_code (stmt) == GIMPLE_COND)
{
- op0 = cond_p;
- iv0 = get_iv (data, cond);
- ret = (iv0 && !integer_zerop (iv0->step));
- goto end;
+ op0 = gimple_cond_lhs_ptr (stmt);
+ op1 = gimple_cond_rhs_ptr (stmt);
}
-
- if (!COMPARISON_CLASS_P (cond))
+ else
{
- op0 = cond_p;
- goto end;
+ op0 = gimple_assign_rhs1_ptr (stmt);
+ op1 = gimple_assign_rhs2_ptr (stmt);
}
- op0 = &TREE_OPERAND (cond, 0);
- op1 = &TREE_OPERAND (cond, 1);
+ zero = integer_zero_node;
+ const_iv.step = integer_zero_node;
+
if (TREE_CODE (*op0) == SSA_NAME)
iv0 = get_iv (data, *op0);
if (TREE_CODE (*op1) == SSA_NAME)
@@ -1237,16 +1238,16 @@ end:
return ret;
}
-/* Checks whether the condition *COND_P in STMT is interesting
- and if so, records it. */
+/* Checks whether the condition in STMT is interesting and if so,
+ records it. */
static void
-find_interesting_uses_cond (struct ivopts_data *data, tree stmt, tree *cond_p)
+find_interesting_uses_cond (struct ivopts_data *data, gimple stmt)
{
tree *var_p, *bound_p;
struct iv *var_iv, *civ;
- if (!extract_cond_operands (data, cond_p, &var_p, &bound_p, &var_iv, NULL))
+ if (!extract_cond_operands (data, stmt, &var_p, &bound_p, &var_iv, NULL))
{
find_interesting_uses_op (data, *var_p);
find_interesting_uses_op (data, *bound_p);
@@ -1255,7 +1256,7 @@ find_interesting_uses_cond (struct ivopts_data *data, tree stmt, tree *cond_p)
civ = XNEW (struct iv);
*civ = *var_iv;
- record_use (data, cond_p, civ, stmt, USE_COMPARE);
+ record_use (data, NULL, civ, stmt, USE_COMPARE);
}
/* Returns true if expression EXPR is obviously invariant in LOOP,
@@ -1275,7 +1276,7 @@ expr_invariant_in_loop_p (struct loop *loop, tree expr)
if (TREE_CODE (expr) == SSA_NAME)
{
- def_bb = bb_for_stmt (SSA_NAME_DEF_STMT (expr));
+ def_bb = gimple_bb (SSA_NAME_DEF_STMT (expr));
if (def_bb
&& flow_bb_inside_loop_p (loop, def_bb))
return false;
@@ -1283,7 +1284,7 @@ expr_invariant_in_loop_p (struct loop *loop, tree expr)
return true;
}
- if (!EXPR_P (expr) && !GIMPLE_STMT_P (expr))
+ if (!EXPR_P (expr))
return false;
len = TREE_OPERAND_LENGTH (expr);
@@ -1294,6 +1295,29 @@ expr_invariant_in_loop_p (struct loop *loop, tree expr)
return true;
}
+/* Returns true if statement STMT is obviously invariant in LOOP,
+ i.e. if all its operands on the RHS are defined outside of the LOOP.
+ LOOP should not be the function body. */
+
+bool
+stmt_invariant_in_loop_p (struct loop *loop, gimple stmt)
+{
+ unsigned i;
+ tree lhs;
+
+ gcc_assert (loop_depth (loop) > 0);
+
+ lhs = gimple_get_lhs (stmt);
+ for (i = 0; i < gimple_num_ops (stmt); i++)
+ {
+ tree op = gimple_op (stmt, i);
+ if (op != lhs && !expr_invariant_in_loop_p (loop, op))
+ return false;
+ }
+
+ return true;
+}
+
/* Cumulates the steps of indices into DATA and replaces their values with the
initial ones. Returns false when the value of the index cannot be determined.
Callback for for_each_index. */
@@ -1301,7 +1325,7 @@ expr_invariant_in_loop_p (struct loop *loop, tree expr)
struct ifs_ivopts_data
{
struct ivopts_data *ivopts_data;
- tree stmt;
+ gimple stmt;
tree step;
};
@@ -1553,7 +1577,7 @@ may_be_nonaddressable_p (tree expr)
/* Finds addresses in *OP_P inside STMT. */
static void
-find_interesting_uses_address (struct ivopts_data *data, tree stmt, tree *op_p)
+find_interesting_uses_address (struct ivopts_data *data, gimple stmt, tree *op_p)
{
tree base = *op_p, step = build_int_cst (sizetype, 0);
struct iv *civ;
@@ -1561,7 +1585,7 @@ find_interesting_uses_address (struct ivopts_data *data, tree stmt, tree *op_p)
/* Do not play with volatile memory references. A bit too conservative,
perhaps, but safe. */
- if (stmt_ann (stmt)->has_volatile_ops)
+ if (gimple_has_volatile_ops (stmt))
goto fail;
/* Ignore bitfields for now. Not really something terribly complicated
@@ -1657,7 +1681,7 @@ fail:
/* Finds and records invariants used in STMT. */
static void
-find_invariants_stmt (struct ivopts_data *data, tree stmt)
+find_invariants_stmt (struct ivopts_data *data, gimple stmt)
{
ssa_op_iter iter;
use_operand_p use_p;
@@ -1673,61 +1697,55 @@ find_invariants_stmt (struct ivopts_data *data, tree stmt)
/* Finds interesting uses of induction variables in the statement STMT. */
static void
-find_interesting_uses_stmt (struct ivopts_data *data, tree stmt)
+find_interesting_uses_stmt (struct ivopts_data *data, gimple stmt)
{
struct iv *iv;
- tree op, lhs, rhs;
+ tree op, *lhs, *rhs;
ssa_op_iter iter;
use_operand_p use_p;
+ enum tree_code code;
find_invariants_stmt (data, stmt);
- if (TREE_CODE (stmt) == COND_EXPR)
+ if (gimple_code (stmt) == GIMPLE_COND)
{
- find_interesting_uses_cond (data, stmt, &COND_EXPR_COND (stmt));
+ find_interesting_uses_cond (data, stmt);
return;
}
- if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT)
+ if (is_gimple_assign (stmt))
{
- lhs = GIMPLE_STMT_OPERAND (stmt, 0);
- rhs = GIMPLE_STMT_OPERAND (stmt, 1);
+ lhs = gimple_assign_lhs_ptr (stmt);
+ rhs = gimple_assign_rhs1_ptr (stmt);
- if (TREE_CODE (lhs) == SSA_NAME)
+ if (TREE_CODE (*lhs) == SSA_NAME)
{
/* If the statement defines an induction variable, the uses are not
interesting by themselves. */
- iv = get_iv (data, lhs);
+ iv = get_iv (data, *lhs);
if (iv && !integer_zerop (iv->step))
return;
}
- switch (TREE_CODE_CLASS (TREE_CODE (rhs)))
+ code = gimple_assign_rhs_code (stmt);
+ if (get_gimple_rhs_class (code) == GIMPLE_SINGLE_RHS
+ && (REFERENCE_CLASS_P (*rhs)
+ || is_gimple_val (*rhs)))
{
- case tcc_comparison:
- find_interesting_uses_cond (data, stmt,
- &GIMPLE_STMT_OPERAND (stmt, 1));
- return;
+ if (REFERENCE_CLASS_P (*rhs))
+ find_interesting_uses_address (data, stmt, rhs);
+ else
+ find_interesting_uses_op (data, *rhs);
- case tcc_reference:
- find_interesting_uses_address (data, stmt,
- &GIMPLE_STMT_OPERAND (stmt, 1));
- if (REFERENCE_CLASS_P (lhs))
- find_interesting_uses_address (data, stmt,
- &GIMPLE_STMT_OPERAND (stmt, 0));
+ if (REFERENCE_CLASS_P (*lhs))
+ find_interesting_uses_address (data, stmt, lhs);
return;
-
- default: ;
}
-
- if (REFERENCE_CLASS_P (lhs)
- && is_gimple_val (rhs))
+ else if (TREE_CODE_CLASS (code) == tcc_comparison)
{
- find_interesting_uses_address (data, stmt,
- &GIMPLE_STMT_OPERAND (stmt, 0));
- find_interesting_uses_op (data, rhs);
+ find_interesting_uses_cond (data, stmt);
return;
}
@@ -1740,11 +1758,10 @@ find_interesting_uses_stmt (struct ivopts_data *data, tree stmt)
call (memory). */
}
- if (TREE_CODE (stmt) == PHI_NODE
- && bb_for_stmt (stmt) == data->current_loop->header)
+ if (gimple_code (stmt) == GIMPLE_PHI
+ && gimple_bb (stmt) == data->current_loop->header)
{
- lhs = PHI_RESULT (stmt);
- iv = get_iv (data, lhs);
+ iv = get_iv (data, PHI_RESULT (stmt));
if (iv && !integer_zerop (iv->step))
return;
@@ -1771,10 +1788,13 @@ find_interesting_uses_stmt (struct ivopts_data *data, tree stmt)
static void
find_interesting_uses_outside (struct ivopts_data *data, edge exit)
{
- tree phi, def;
+ gimple phi;
+ gimple_stmt_iterator psi;
+ tree def;
- for (phi = phi_nodes (exit->dest); phi; phi = PHI_CHAIN (phi))
+ for (psi = gsi_start_phis (exit->dest); !gsi_end_p (psi); gsi_next (&psi))
{
+ phi = gsi_stmt (psi);
def = PHI_ARG_DEF_FROM_EDGE (phi, exit);
if (is_gimple_reg (def))
find_interesting_uses_op (data, def);
@@ -1787,8 +1807,7 @@ static void
find_interesting_uses (struct ivopts_data *data)
{
basic_block bb;
- block_stmt_iterator bsi;
- tree phi;
+ gimple_stmt_iterator bsi;
basic_block *body = get_loop_body (data->current_loop);
unsigned i;
struct version_info *info;
@@ -1807,10 +1826,10 @@ find_interesting_uses (struct ivopts_data *data)
&& !flow_bb_inside_loop_p (data->current_loop, e->dest))
find_interesting_uses_outside (data, e);
- for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
- find_interesting_uses_stmt (data, phi);
- for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
- find_interesting_uses_stmt (data, bsi_stmt (bsi));
+ for (bsi = gsi_start_phis (bb); !gsi_end_p (bsi); gsi_next (&bsi))
+ find_interesting_uses_stmt (data, gsi_stmt (bsi));
+ for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi))
+ find_interesting_uses_stmt (data, gsi_stmt (bsi));
}
if (dump_file && (dump_flags & TDF_DETAILS))
@@ -2033,7 +2052,7 @@ find_depends (tree *expr_p, int *ws ATTRIBUTE_UNUSED, void *data)
static struct iv_cand *
add_candidate_1 (struct ivopts_data *data,
tree base, tree step, bool important, enum iv_position pos,
- struct iv_use *use, tree incremented_at)
+ struct iv_use *use, gimple incremented_at)
{
unsigned i;
struct iv_cand *cand = NULL;
@@ -2157,10 +2176,10 @@ add_candidate (struct ivopts_data *data,
tree base, tree step, bool important, struct iv_use *use)
{
if (ip_normal_pos (data->current_loop))
- add_candidate_1 (data, base, step, important, IP_NORMAL, use, NULL_TREE);
+ add_candidate_1 (data, base, step, important, IP_NORMAL, use, NULL);
if (ip_end_pos (data->current_loop)
&& allow_ip_end_pos_p (data->current_loop))
- add_candidate_1 (data, base, step, important, IP_END, use, NULL_TREE);
+ add_candidate_1 (data, base, step, important, IP_END, use, NULL);
}
/* Add a standard "0 + 1 * iteration" iv candidate for a
@@ -2193,7 +2212,8 @@ add_standard_iv_candidates (struct ivopts_data *data)
static void
add_old_iv_candidates (struct ivopts_data *data, struct iv *iv)
{
- tree phi, def;
+ gimple phi;
+ tree def;
struct iv_cand *cand;
add_candidate (data, iv->base, iv->step, true, NULL);
@@ -2204,7 +2224,7 @@ add_old_iv_candidates (struct ivopts_data *data, struct iv *iv)
iv->step, true, NULL);
phi = SSA_NAME_DEF_STMT (iv->ssa_name);
- if (TREE_CODE (phi) == PHI_NODE)
+ if (gimple_code (phi) == GIMPLE_PHI)
{
/* Additionally record the possibility of leaving the original iv
untouched. */
@@ -2643,7 +2663,7 @@ computation_cost (tree expr)
/* Returns variable containing the value of candidate CAND at statement AT. */
static tree
-var_at_stmt (struct loop *loop, struct iv_cand *cand, tree stmt)
+var_at_stmt (struct loop *loop, struct iv_cand *cand, gimple stmt)
{
if (stmt_after_increment (loop, cand, stmt))
return cand->var_after;
@@ -2713,7 +2733,7 @@ determine_common_wider_type (tree *a, tree *b)
static bool
get_computation_aff (struct loop *loop,
- struct iv_use *use, struct iv_cand *cand, tree at,
+ struct iv_use *use, struct iv_cand *cand, gimple at,
struct affine_tree_combination *aff)
{
tree ubase = use->iv->base;
@@ -2788,7 +2808,7 @@ get_computation_aff (struct loop *loop,
static tree
get_computation_at (struct loop *loop,
- struct iv_use *use, struct iv_cand *cand, tree at)
+ struct iv_use *use, struct iv_cand *cand, gimple at)
{
aff_tree aff;
tree type = TREE_TYPE (use->iv->base);
@@ -3458,7 +3478,7 @@ difference_cost (struct ivopts_data *data,
static comp_cost
get_computation_cost_at (struct ivopts_data *data,
struct iv_use *use, struct iv_cand *cand,
- bool address_p, bitmap *depends_on, tree at)
+ bool address_p, bitmap *depends_on, gimple at)
{
tree ubase = use->iv->base, ustep = use->iv->step;
tree cbase, cstep;
@@ -3672,7 +3692,7 @@ determine_use_iv_cost_address (struct ivopts_data *data,
stores it to VAL. */
static void
-cand_value_at (struct loop *loop, struct iv_cand *cand, tree at, tree niter,
+cand_value_at (struct loop *loop, struct iv_cand *cand, gimple at, tree niter,
aff_tree *val)
{
aff_tree step, delta, nit;
@@ -3725,7 +3745,7 @@ iv_elimination_compare (struct ivopts_data *data, struct iv_use *use)
basic_block ex_bb;
edge exit;
- ex_bb = bb_for_stmt (use->stmt);
+ ex_bb = gimple_bb (use->stmt);
exit = EDGE_SUCC (ex_bb, 0);
if (flow_bb_inside_loop_p (loop, exit->dest))
exit = EDGE_SUCC (ex_bb, 1);
@@ -3751,11 +3771,10 @@ may_eliminate_iv (struct ivopts_data *data,
/* For now works only for exits that dominate the loop latch.
TODO: extend to other conditions inside loop body. */
- ex_bb = bb_for_stmt (use->stmt);
+ ex_bb = gimple_bb (use->stmt);
if (use->stmt != last_stmt (ex_bb)
- || TREE_CODE (use->stmt) != COND_EXPR)
- return false;
- if (!dominated_by_p (CDI_DOMINATORS, loop->latch, ex_bb))
+ || gimple_code (use->stmt) != GIMPLE_COND
+ || !dominated_by_p (CDI_DOMINATORS, loop->latch, ex_bb))
return false;
exit = EDGE_SUCC (ex_bb, 0);
@@ -3834,7 +3853,7 @@ determine_use_iv_cost_condition (struct ivopts_data *data,
/* Try expressing the original giv. If it is compared with an invariant,
note that we cannot get rid of it. */
- ok = extract_cond_operands (data, use->op_p, NULL, NULL, NULL, &cmp_iv);
+ ok = extract_cond_operands (data, use->stmt, NULL, NULL, NULL, &cmp_iv);
gcc_assert (ok);
express_cost = get_computation_cost (data, use, cand, false,
@@ -4050,7 +4069,9 @@ static void
determine_set_costs (struct ivopts_data *data)
{
unsigned j, n;
- tree phi, op;
+ gimple phi;
+ gimple_stmt_iterator psi;
+ tree op;
struct loop *loop = data->current_loop;
bitmap_iterator bi;
@@ -4083,8 +4104,9 @@ determine_set_costs (struct ivopts_data *data)
}
n = 0;
- for (phi = phi_nodes (loop->header); phi; phi = PHI_CHAIN (phi))
+ for (psi = gsi_start_phis (loop->header); !gsi_end_p (psi); gsi_next (&psi))
{
+ phi = gsi_stmt (psi);
op = PHI_RESULT (phi);
if (!is_gimple_reg (op))
@@ -4925,7 +4947,7 @@ find_optimal_iv_set (struct ivopts_data *data)
static void
create_new_iv (struct ivopts_data *data, struct iv_cand *cand)
{
- block_stmt_iterator incr_pos;
+ gimple_stmt_iterator incr_pos;
tree base;
bool after = false;
@@ -4935,11 +4957,11 @@ create_new_iv (struct ivopts_data *data, struct iv_cand *cand)
switch (cand->pos)
{
case IP_NORMAL:
- incr_pos = bsi_last (ip_normal_pos (data->current_loop));
+ incr_pos = gsi_last_bb (ip_normal_pos (data->current_loop));
break;
case IP_END:
- incr_pos = bsi_last (ip_end_pos (data->current_loop));
+ incr_pos = gsi_last_bb (ip_end_pos (data->current_loop));
after = true;
break;
@@ -4984,17 +5006,15 @@ create_new_ivs (struct ivopts_data *data, struct iv_ca *set)
is true, remove also the ssa name defined by the statement. */
static void
-remove_statement (tree stmt, bool including_defined_name)
+remove_statement (gimple stmt, bool including_defined_name)
{
- if (TREE_CODE (stmt) == PHI_NODE)
- {
- remove_phi_node (stmt, NULL_TREE, including_defined_name);
- }
+ gimple_stmt_iterator bsi = gsi_for_stmt (stmt);
+
+ if (gimple_code (stmt) == GIMPLE_PHI)
+ remove_phi_node (&bsi, including_defined_name);
else
{
- block_stmt_iterator bsi = bsi_for_stmt (stmt);
-
- bsi_remove (&bsi, true);
+ gsi_remove (&bsi, true);
release_defs (stmt);
}
}
@@ -5007,8 +5027,9 @@ rewrite_use_nonlinear_expr (struct ivopts_data *data,
struct iv_use *use, struct iv_cand *cand)
{
tree comp;
- tree op, tgt, ass;
- block_stmt_iterator bsi;
+ tree op, tgt;
+ gimple ass;
+ gimple_stmt_iterator bsi;
/* An important special case -- if we are asked to express value of
the original iv by itself, just exit; there is no need to
@@ -5018,10 +5039,10 @@ rewrite_use_nonlinear_expr (struct ivopts_data *data,
&& cand->incremented_at == use->stmt)
{
tree step, ctype, utype;
- enum tree_code incr_code = PLUS_EXPR;
+ enum tree_code incr_code = PLUS_EXPR, old_code;
- gcc_assert (TREE_CODE (use->stmt) == GIMPLE_MODIFY_STMT);
- gcc_assert (GIMPLE_STMT_OPERAND (use->stmt, 0) == cand->var_after);
+ gcc_assert (is_gimple_assign (use->stmt));
+ gcc_assert (gimple_assign_lhs (use->stmt) == cand->var_after);
step = cand->iv->step;
ctype = TREE_TYPE (step);
@@ -5037,16 +5058,16 @@ rewrite_use_nonlinear_expr (struct ivopts_data *data,
computations in the loop -- otherwise, the computation
we rely upon may be removed in remove_unused_ivs,
thus leading to ICE. */
- op = GIMPLE_STMT_OPERAND (use->stmt, 1);
- if (TREE_CODE (op) == PLUS_EXPR
- || TREE_CODE (op) == MINUS_EXPR
- || TREE_CODE (op) == POINTER_PLUS_EXPR)
+ old_code = gimple_assign_rhs_code (use->stmt);
+ if (old_code == PLUS_EXPR
+ || old_code == MINUS_EXPR
+ || old_code == POINTER_PLUS_EXPR)
{
- if (TREE_OPERAND (op, 0) == cand->var_before)
- op = TREE_OPERAND (op, 1);
- else if (TREE_CODE (op) != MINUS_EXPR
- && TREE_OPERAND (op, 1) == cand->var_before)
- op = TREE_OPERAND (op, 0);
+ if (gimple_assign_rhs1 (use->stmt) == cand->var_before)
+ op = gimple_assign_rhs2 (use->stmt);
+ else if (old_code != MINUS_EXPR
+ && gimple_assign_rhs2 (use->stmt) == cand->var_before)
+ op = gimple_assign_rhs1 (use->stmt);
else
op = NULL_TREE;
}
@@ -5071,39 +5092,41 @@ rewrite_use_nonlinear_expr (struct ivopts_data *data,
gcc_assert (comp != NULL_TREE);
}
- switch (TREE_CODE (use->stmt))
+ switch (gimple_code (use->stmt))
{
- case PHI_NODE:
+ case GIMPLE_PHI:
tgt = PHI_RESULT (use->stmt);
/* If we should keep the biv, do not replace it. */
if (name_info (data, tgt)->preserve_biv)
return;
- bsi = bsi_after_labels (bb_for_stmt (use->stmt));
+ bsi = gsi_after_labels (gimple_bb (use->stmt));
break;
- case GIMPLE_MODIFY_STMT:
- tgt = GIMPLE_STMT_OPERAND (use->stmt, 0);
- bsi = bsi_for_stmt (use->stmt);
+ case GIMPLE_ASSIGN:
+ tgt = gimple_assign_lhs (use->stmt);
+ bsi = gsi_for_stmt (use->stmt);
break;
default:
gcc_unreachable ();
}
- op = force_gimple_operand_bsi (&bsi, comp, false, SSA_NAME_VAR (tgt),
- true, BSI_SAME_STMT);
+ op = force_gimple_operand_gsi (&bsi, comp, false, SSA_NAME_VAR (tgt),
+ true, GSI_SAME_STMT);
- if (TREE_CODE (use->stmt) == PHI_NODE)
+ if (gimple_code (use->stmt) == GIMPLE_PHI)
{
- ass = build_gimple_modify_stmt (tgt, op);
- bsi_insert_before (&bsi, ass, BSI_SAME_STMT);
+ ass = gimple_build_assign (tgt, op);
+ gsi_insert_before (&bsi, ass, GSI_SAME_STMT);
remove_statement (use->stmt, false);
- SSA_NAME_DEF_STMT (tgt) = ass;
}
else
- GIMPLE_STMT_OPERAND (use->stmt, 1) = op;
+ {
+ gimple_assign_set_rhs_from_tree (&bsi, op);
+ use->stmt = gsi_stmt (bsi);
+ }
}
/* Replaces ssa name in index IDX by its basic variable. Callback for
@@ -5222,7 +5245,7 @@ rewrite_use_address (struct ivopts_data *data,
struct iv_use *use, struct iv_cand *cand)
{
aff_tree aff;
- block_stmt_iterator bsi = bsi_for_stmt (use->stmt);
+ gimple_stmt_iterator bsi = gsi_for_stmt (use->stmt);
tree ref;
bool ok;
@@ -5243,7 +5266,7 @@ rewrite_use_compare (struct ivopts_data *data,
struct iv_use *use, struct iv_cand *cand)
{
tree comp, *var_p, op, bound;
- block_stmt_iterator bsi = bsi_for_stmt (use->stmt);
+ gimple_stmt_iterator bsi = gsi_for_stmt (use->stmt);
enum tree_code compare;
struct cost_pair *cp = get_use_iv_cost (data, use, cand);
bool ok;
@@ -5256,10 +5279,12 @@ rewrite_use_compare (struct ivopts_data *data,
compare = iv_elimination_compare (data, use);
bound = unshare_expr (fold_convert (var_type, bound));
- op = force_gimple_operand_bsi (&bsi, bound, true, NULL_TREE,
- true, BSI_SAME_STMT);
+ op = force_gimple_operand_gsi (&bsi, bound, true, NULL_TREE,
+ true, GSI_SAME_STMT);
- *use->op_p = build2 (compare, boolean_type_node, var, op);
+ gimple_cond_set_lhs (use->stmt, var);
+ gimple_cond_set_code (use->stmt, compare);
+ gimple_cond_set_rhs (use->stmt, op);
return;
}
@@ -5268,11 +5293,11 @@ rewrite_use_compare (struct ivopts_data *data,
comp = get_computation (data->current_loop, use, cand);
gcc_assert (comp != NULL_TREE);
- ok = extract_cond_operands (data, use->op_p, &var_p, NULL, NULL, NULL);
+ ok = extract_cond_operands (data, use->stmt, &var_p, NULL, NULL, NULL);
gcc_assert (ok);
- *var_p = force_gimple_operand_bsi (&bsi, comp, true, SSA_NAME_VAR (*var_p),
- true, BSI_SAME_STMT);
+ *var_p = force_gimple_operand_gsi (&bsi, comp, true, SSA_NAME_VAR (*var_p),
+ true, GSI_SAME_STMT);
}
/* Rewrites USE using candidate CAND. */
@@ -5452,7 +5477,7 @@ tree_ssa_iv_optimize_loop (struct ivopts_data *data, struct loop *loop)
{
fprintf (dump_file, " single exit %d -> %d, exit condition ",
exit->src->index, exit->dest->index);
- print_generic_expr (dump_file, last_stmt (exit->src), TDF_SLIM);
+ print_gimple_stmt (dump_file, last_stmt (exit->src), 0, TDF_SLIM);
fprintf (dump_file, "\n");
}
diff --git a/gcc/tree-ssa-loop-manip.c b/gcc/tree-ssa-loop-manip.c
index 1ff6254c0b1..05e87d241cd 100644
--- a/gcc/tree-ssa-loop-manip.c
+++ b/gcc/tree-ssa-loop-manip.c
@@ -49,10 +49,12 @@ along with GCC; see the file COPYING3. If not see
void
create_iv (tree base, tree step, tree var, struct loop *loop,
- block_stmt_iterator *incr_pos, bool after,
+ gimple_stmt_iterator *incr_pos, bool after,
tree *var_before, tree *var_after)
{
- tree stmt, initial, step1, stmts;
+ gimple stmt;
+ tree initial, step1;
+ gimple_seq stmts;
tree vb, va;
enum tree_code incr_op = PLUS_EXPR;
edge pe = loop_preheader_edge (loop);
@@ -63,10 +65,10 @@ create_iv (tree base, tree step, tree var, struct loop *loop,
add_referenced_var (var);
}
- vb = make_ssa_name (var, NULL_TREE);
+ vb = make_ssa_name (var, NULL);
if (var_before)
*var_before = vb;
- va = make_ssa_name (var, NULL_TREE);
+ va = make_ssa_name (var, NULL);
if (var_after)
*var_after = va;
@@ -106,20 +108,17 @@ create_iv (tree base, tree step, tree var, struct loop *loop,
loop (i.e. the step should be loop invariant). */
step = force_gimple_operand (step, &stmts, true, NULL_TREE);
if (stmts)
- bsi_insert_on_edge_immediate (pe, stmts);
+ gsi_insert_seq_on_edge_immediate (pe, stmts);
- stmt = build_gimple_modify_stmt (va,
- build2 (incr_op, TREE_TYPE (base),
- vb, step));
- SSA_NAME_DEF_STMT (va) = stmt;
+ stmt = gimple_build_assign_with_ops (incr_op, va, vb, step);
if (after)
- bsi_insert_after (incr_pos, stmt, BSI_NEW_STMT);
+ gsi_insert_after (incr_pos, stmt, GSI_NEW_STMT);
else
- bsi_insert_before (incr_pos, stmt, BSI_NEW_STMT);
+ gsi_insert_before (incr_pos, stmt, GSI_NEW_STMT);
initial = force_gimple_operand (base, &stmts, true, var);
if (stmts)
- bsi_insert_on_edge_immediate (pe, stmts);
+ gsi_insert_seq_on_edge_immediate (pe, stmts);
stmt = create_phi_node (vb, loop->header);
SSA_NAME_DEF_STMT (vb) = stmt;
@@ -132,8 +131,8 @@ create_iv (tree base, tree step, tree var, struct loop *loop,
static void
add_exit_phis_edge (basic_block exit, tree use)
{
- tree phi, def_stmt = SSA_NAME_DEF_STMT (use);
- basic_block def_bb = bb_for_stmt (def_stmt);
+ gimple phi, def_stmt = SSA_NAME_DEF_STMT (use);
+ basic_block def_bb = gimple_bb (def_stmt);
struct loop *def_loop;
edge e;
edge_iterator ei;
@@ -151,7 +150,8 @@ add_exit_phis_edge (basic_block exit, tree use)
return;
phi = create_phi_node (use, exit);
- create_new_def_for (PHI_RESULT (phi), phi, PHI_RESULT_PTR (phi));
+ create_new_def_for (gimple_phi_result (phi), phi,
+ gimple_phi_result_ptr (phi));
FOR_EACH_EDGE (e, ei, exit->preds)
add_phi_arg (phi, use, e);
}
@@ -164,7 +164,7 @@ add_exit_phis_var (tree var, bitmap livein, bitmap exits)
{
bitmap def;
unsigned index;
- basic_block def_bb = bb_for_stmt (SSA_NAME_DEF_STMT (var));
+ basic_block def_bb = gimple_bb (SSA_NAME_DEF_STMT (var));
bitmap_iterator bi;
if (is_gimple_reg (var))
@@ -243,7 +243,7 @@ find_uses_to_rename_use (basic_block bb, tree use, bitmap *use_blocks,
return;
ver = SSA_NAME_VERSION (use);
- def_bb = bb_for_stmt (SSA_NAME_DEF_STMT (use));
+ def_bb = gimple_bb (SSA_NAME_DEF_STMT (use));
if (!def_bb)
return;
def_loop = def_bb->loop_father;
@@ -270,11 +270,11 @@ find_uses_to_rename_use (basic_block bb, tree use, bitmap *use_blocks,
NEED_PHIS. */
static void
-find_uses_to_rename_stmt (tree stmt, bitmap *use_blocks, bitmap need_phis)
+find_uses_to_rename_stmt (gimple stmt, bitmap *use_blocks, bitmap need_phis)
{
ssa_op_iter iter;
tree var;
- basic_block bb = bb_for_stmt (stmt);
+ basic_block bb = gimple_bb (stmt);
FOR_EACH_SSA_TREE_OPERAND (var, stmt, iter, SSA_OP_ALL_USES)
find_uses_to_rename_use (bb, var, use_blocks, need_phis);
@@ -288,18 +288,17 @@ find_uses_to_rename_stmt (tree stmt, bitmap *use_blocks, bitmap need_phis)
static void
find_uses_to_rename_bb (basic_block bb, bitmap *use_blocks, bitmap need_phis)
{
- block_stmt_iterator bsi;
+ gimple_stmt_iterator bsi;
edge e;
edge_iterator ei;
- tree phi;
FOR_EACH_EDGE (e, ei, bb->succs)
- for (phi = phi_nodes (e->dest); phi; phi = PHI_CHAIN (phi))
- find_uses_to_rename_use (bb, PHI_ARG_DEF_FROM_EDGE (phi, e),
+ for (bsi = gsi_start_phis (e->dest); !gsi_end_p (bsi); gsi_next (&bsi))
+ find_uses_to_rename_use (bb, PHI_ARG_DEF_FROM_EDGE (gsi_stmt (bsi), e),
use_blocks, need_phis);
- for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
- find_uses_to_rename_stmt (bsi_stmt (bsi), use_blocks, need_phis);
+ for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi))
+ find_uses_to_rename_stmt (gsi_stmt (bsi), use_blocks, need_phis);
}
/* Marks names that are used outside of the loop they are defined in
@@ -407,14 +406,14 @@ rewrite_into_loop_closed_ssa (bitmap changed_bbs, unsigned update_flag)
static void
check_loop_closed_ssa_use (basic_block bb, tree use)
{
- tree def;
+ gimple def;
basic_block def_bb;
if (TREE_CODE (use) != SSA_NAME || !is_gimple_reg (use))
return;
def = SSA_NAME_DEF_STMT (use);
- def_bb = bb_for_stmt (def);
+ def_bb = gimple_bb (def);
gcc_assert (!def_bb
|| flow_bb_inside_loop_p (def_bb->loop_father, bb));
}
@@ -422,7 +421,7 @@ check_loop_closed_ssa_use (basic_block bb, tree use)
/* Checks invariants of loop closed ssa form in statement STMT in BB. */
static void
-check_loop_closed_ssa_stmt (basic_block bb, tree stmt)
+check_loop_closed_ssa_stmt (basic_block bb, gimple stmt)
{
ssa_op_iter iter;
tree var;
@@ -437,9 +436,10 @@ void
verify_loop_closed_ssa (void)
{
basic_block bb;
- block_stmt_iterator bsi;
- tree phi;
- unsigned i;
+ gimple_stmt_iterator bsi;
+ gimple phi;
+ edge e;
+ edge_iterator ei;
if (number_of_loops () <= 1)
return;
@@ -448,13 +448,16 @@ verify_loop_closed_ssa (void)
FOR_EACH_BB (bb)
{
- for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
- for (i = 0; i < (unsigned) PHI_NUM_ARGS (phi); i++)
- check_loop_closed_ssa_use (PHI_ARG_EDGE (phi, i)->src,
- PHI_ARG_DEF (phi, i));
+ for (bsi = gsi_start_phis (bb); !gsi_end_p (bsi); gsi_next (&bsi))
+ {
+ phi = gsi_stmt (bsi);
+ FOR_EACH_EDGE (e, ei, bb->preds)
+ check_loop_closed_ssa_use (e->src,
+ PHI_ARG_DEF_FROM_EDGE (phi, e));
+ }
- for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
- check_loop_closed_ssa_stmt (bb, bsi_stmt (bsi));
+ for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi))
+ check_loop_closed_ssa_stmt (bb, gsi_stmt (bsi));
}
}
@@ -466,11 +469,14 @@ split_loop_exit_edge (edge exit)
{
basic_block dest = exit->dest;
basic_block bb = split_edge (exit);
- tree phi, new_phi, new_name, name;
+ gimple phi, new_phi;
+ tree new_name, name;
use_operand_p op_p;
+ gimple_stmt_iterator psi;
- for (phi = phi_nodes (dest); phi; phi = PHI_CHAIN (phi))
+ for (psi = gsi_start_phis (dest); !gsi_end_p (psi); gsi_next (&psi))
{
+ phi = gsi_stmt (psi);
op_p = PHI_ARG_DEF_PTR_FROM_EDGE (phi, single_succ_edge (bb));
name = USE_FROM_PTR (op_p);
@@ -507,7 +513,7 @@ ip_end_pos (struct loop *loop)
basic_block
ip_normal_pos (struct loop *loop)
{
- tree last;
+ gimple last;
basic_block bb;
edge exit;
@@ -517,7 +523,7 @@ ip_normal_pos (struct loop *loop)
bb = single_pred (loop->latch);
last = last_stmt (bb);
if (!last
- || TREE_CODE (last) != COND_EXPR)
+ || gimple_code (last) != GIMPLE_COND)
return NULL;
exit = EDGE_SUCC (bb, 0);
@@ -536,21 +542,21 @@ ip_normal_pos (struct loop *loop)
the increment should be inserted after *BSI. */
void
-standard_iv_increment_position (struct loop *loop, block_stmt_iterator *bsi,
+standard_iv_increment_position (struct loop *loop, gimple_stmt_iterator *bsi,
bool *insert_after)
{
basic_block bb = ip_normal_pos (loop), latch = ip_end_pos (loop);
- tree last = last_stmt (latch);
+ gimple last = last_stmt (latch);
if (!bb
- || (last && TREE_CODE (last) != LABEL_EXPR))
+ || (last && gimple_code (last) != GIMPLE_LABEL))
{
- *bsi = bsi_last (latch);
+ *bsi = gsi_last_bb (latch);
*insert_after = true;
}
else
{
- *bsi = bsi_last (bb);
+ *bsi = gsi_last_bb (bb);
*insert_after = false;
}
}
@@ -584,7 +590,7 @@ copy_phi_node_args (unsigned first_new_block)
after the loop has been duplicated. */
bool
-tree_duplicate_loop_to_header_edge (struct loop *loop, edge e,
+gimple_duplicate_loop_to_header_edge (struct loop *loop, edge e,
unsigned int ndupl, sbitmap wont_exit,
edge orig, VEC (edge, heap) **to_remove,
int flags)
@@ -673,7 +679,7 @@ determine_exit_conditions (struct loop *loop, struct tree_niter_desc *desc,
tree *exit_base, tree *exit_step,
enum tree_code *exit_cmp, tree *exit_bound)
{
- tree stmts;
+ gimple_seq stmts;
tree base = desc->control.base;
tree step = desc->control.step;
tree bound = desc->bound;
@@ -748,7 +754,7 @@ determine_exit_conditions (struct loop *loop, struct tree_niter_desc *desc,
cond = force_gimple_operand (unshare_expr (cond), &stmts, false, NULL_TREE);
if (stmts)
- bsi_insert_on_edge_immediate (loop_preheader_edge (loop), stmts);
+ gsi_insert_seq_on_edge_immediate (loop_preheader_edge (loop), stmts);
/* cond now may be a gimple comparison, which would be OK, but also any
other gimple rhs (say a && b). In this case we need to force it to
operand. */
@@ -756,16 +762,16 @@ determine_exit_conditions (struct loop *loop, struct tree_niter_desc *desc,
{
cond = force_gimple_operand (cond, &stmts, true, NULL_TREE);
if (stmts)
- bsi_insert_on_edge_immediate (loop_preheader_edge (loop), stmts);
+ gsi_insert_seq_on_edge_immediate (loop_preheader_edge (loop), stmts);
}
*enter_cond = cond;
base = force_gimple_operand (unshare_expr (base), &stmts, true, NULL_TREE);
if (stmts)
- bsi_insert_on_edge_immediate (loop_preheader_edge (loop), stmts);
+ gsi_insert_seq_on_edge_immediate (loop_preheader_edge (loop), stmts);
bound = force_gimple_operand (unshare_expr (bound), &stmts, true, NULL_TREE);
if (stmts)
- bsi_insert_on_edge_immediate (loop_preheader_edge (loop), stmts);
+ gsi_insert_seq_on_edge_immediate (loop_preheader_edge (loop), stmts);
*exit_base = base;
*exit_step = bigstep;
@@ -859,15 +865,18 @@ tree_transform_and_unroll_loop (struct loop *loop, unsigned factor,
transform_callback transform,
void *data)
{
- tree exit_if, ctr_before, ctr_after;
+ gimple exit_if;
+ tree ctr_before, ctr_after;
tree enter_main_cond, exit_base, exit_step, exit_bound;
enum tree_code exit_cmp;
- tree phi_old_loop, phi_new_loop, phi_rest, init, next, new_init, var;
+ gimple phi_old_loop, phi_new_loop, phi_rest;
+ gimple_stmt_iterator psi_old_loop, psi_new_loop;
+ tree init, next, new_init, var;
struct loop *new_loop;
basic_block rest, exit_bb;
edge old_entry, new_entry, old_latch, precond_edge, new_exit;
edge new_nonexit, e;
- block_stmt_iterator bsi;
+ gimple_stmt_iterator bsi;
use_operand_p op;
bool ok;
unsigned est_niter, prob_entry, scale_unrolled, scale_rest, freq_e, freq_h;
@@ -937,11 +946,12 @@ tree_transform_and_unroll_loop (struct loop *loop, unsigned factor,
REG_BR_PROB_BASE,
REG_BR_PROB_BASE - exit->probability);
- bsi = bsi_last (exit_bb);
- exit_if = build3 (COND_EXPR, void_type_node, boolean_true_node,
- NULL_TREE, NULL_TREE);
+ bsi = gsi_last_bb (exit_bb);
+ exit_if = gimple_build_cond (EQ_EXPR, integer_zero_node,
+ integer_zero_node,
+ NULL_TREE, NULL_TREE);
- bsi_insert_after (&bsi, exit_if, BSI_NEW_STMT);
+ gsi_insert_after (&bsi, exit_if, GSI_NEW_STMT);
new_exit = make_edge (exit_bb, rest, EDGE_FALSE_VALUE | irr);
rescan_loop_exit (new_exit, true, false);
@@ -962,12 +972,14 @@ tree_transform_and_unroll_loop (struct loop *loop, unsigned factor,
old_entry = loop_preheader_edge (loop);
new_entry = loop_preheader_edge (new_loop);
old_latch = loop_latch_edge (loop);
- for (phi_old_loop = phi_nodes (loop->header),
- phi_new_loop = phi_nodes (new_loop->header);
- phi_old_loop;
- phi_old_loop = PHI_CHAIN (phi_old_loop),
- phi_new_loop = PHI_CHAIN (phi_new_loop))
+ for (psi_old_loop = gsi_start_phis (loop->header),
+ psi_new_loop = gsi_start_phis (new_loop->header);
+ !gsi_end_p (psi_old_loop);
+ gsi_next (&psi_old_loop), gsi_next (&psi_new_loop))
{
+ phi_old_loop = gsi_stmt (psi_old_loop);
+ phi_new_loop = gsi_stmt (psi_new_loop);
+
init = PHI_ARG_DEF_FROM_EDGE (phi_old_loop, old_entry);
op = PHI_ARG_DEF_PTR_FROM_EDGE (phi_new_loop, new_entry);
gcc_assert (operand_equal_for_phi_arg_p (init, USE_FROM_PTR (op)));
@@ -986,7 +998,7 @@ tree_transform_and_unroll_loop (struct loop *loop, unsigned factor,
add_referenced_var (var);
}
- new_init = make_ssa_name (var, NULL_TREE);
+ new_init = make_ssa_name (var, NULL);
phi_rest = create_phi_node (new_init, rest);
SSA_NAME_DEF_STMT (new_init) = phi_rest;
@@ -1007,7 +1019,7 @@ tree_transform_and_unroll_loop (struct loop *loop, unsigned factor,
sbitmap_ones (wont_exit);
RESET_BIT (wont_exit, factor - 1);
- ok = tree_duplicate_loop_to_header_edge
+ ok = gimple_duplicate_loop_to_header_edge
(loop, loop_latch_edge (loop), factor - 1,
wont_exit, new_exit, &to_remove, DLTHE_FLAG_UPDATE_FREQ);
free (wont_exit);
@@ -1049,12 +1061,13 @@ tree_transform_and_unroll_loop (struct loop *loop, unsigned factor,
/* Finally create the new counter for number of iterations and add the new
exit instruction. */
- bsi = bsi_last (exit_bb);
- exit_if = bsi_stmt (bsi);
+ bsi = gsi_last_bb (exit_bb);
+ exit_if = gsi_stmt (bsi);
create_iv (exit_base, exit_step, NULL_TREE, loop,
&bsi, false, &ctr_before, &ctr_after);
- COND_EXPR_COND (exit_if) = build2 (exit_cmp, boolean_type_node, ctr_after,
- exit_bound);
+ gimple_cond_set_code (exit_if, exit_cmp);
+ gimple_cond_set_lhs (exit_if, ctr_after);
+ gimple_cond_set_rhs (exit_if, exit_bound);
update_stmt (exit_if);
#ifdef ENABLE_CHECKING
diff --git a/gcc/tree-ssa-loop-niter.c b/gcc/tree-ssa-loop-niter.c
index 80b45c298b7..83baae7828a 100644
--- a/gcc/tree-ssa-loop-niter.c
+++ b/gcc/tree-ssa-loop-niter.c
@@ -368,7 +368,8 @@ bound_difference (struct loop *loop, tree x, tree y, bounds *bnds)
int cnt = 0;
edge e;
basic_block bb;
- tree cond, c0, c1;
+ tree c0, c1;
+ gimple cond;
enum tree_code cmp;
/* Get rid of unnecessary casts, but preserve the value of
@@ -427,12 +428,10 @@ bound_difference (struct loop *loop, tree x, tree y, bounds *bnds)
if (!(e->flags & (EDGE_TRUE_VALUE | EDGE_FALSE_VALUE)))
continue;
- cond = COND_EXPR_COND (last_stmt (e->src));
- if (!COMPARISON_CLASS_P (cond))
- continue;
- c0 = TREE_OPERAND (cond, 0);
- cmp = TREE_CODE (cond);
- c1 = TREE_OPERAND (cond, 1);
+ cond = last_stmt (e->src);
+ c0 = gimple_cond_lhs (cond);
+ cmp = gimple_cond_code (cond);
+ c1 = gimple_cond_rhs (cond);
if (e->flags & EDGE_FALSE_VALUE)
cmp = invert_tree_comparison (cmp, false);
@@ -1349,7 +1348,7 @@ simplify_replace_tree (tree expr, tree old, tree new_tree)
|| operand_equal_p (expr, old, 0))
return unshare_expr (new_tree);
- if (!EXPR_P (expr) && !GIMPLE_STMT_P (expr))
+ if (!EXPR_P (expr))
return expr;
n = TREE_OPERAND_LENGTH (expr);
@@ -1376,8 +1375,9 @@ tree
expand_simple_operations (tree expr)
{
unsigned i, n;
- tree ret = NULL_TREE, e, ee, stmt;
+ tree ret = NULL_TREE, e, ee, e1;
enum tree_code code;
+ gimple stmt;
if (expr == NULL_TREE)
return expr;
@@ -1415,17 +1415,17 @@ expand_simple_operations (tree expr)
return expr;
stmt = SSA_NAME_DEF_STMT (expr);
- if (TREE_CODE (stmt) == PHI_NODE)
+ if (gimple_code (stmt) == GIMPLE_PHI)
{
basic_block src, dest;
- if (PHI_NUM_ARGS (stmt) != 1)
+ if (gimple_phi_num_args (stmt) != 1)
return expr;
e = PHI_ARG_DEF (stmt, 0);
/* Avoid propagating through loop exit phi nodes, which
could break loop-closed SSA form restrictions. */
- dest = bb_for_stmt (stmt);
+ dest = gimple_bb (stmt);
src = single_pred (dest);
if (TREE_CODE (e) == SSA_NAME
&& src->loop_father != dest->loop_father)
@@ -1433,24 +1433,44 @@ expand_simple_operations (tree expr)
return expand_simple_operations (e);
}
- if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT)
+ if (gimple_code (stmt) != GIMPLE_ASSIGN)
return expr;
- e = GIMPLE_STMT_OPERAND (stmt, 1);
- if (/* Casts are simple. */
- !CONVERT_EXPR_P (e)
- /* Copies are simple. */
- && TREE_CODE (e) != SSA_NAME
- /* Assignments of invariants are simple. */
- && !is_gimple_min_invariant (e)
+ e = gimple_assign_rhs1 (stmt);
+ code = gimple_assign_rhs_code (stmt);
+ if (get_gimple_rhs_class (code) == GIMPLE_SINGLE_RHS)
+ {
+ if (is_gimple_min_invariant (e))
+ return e;
+
+ if (code == SSA_NAME)
+ return expand_simple_operations (e);
+
+ return expr;
+ }
+
+ switch (code)
+ {
+ case NOP_EXPR:
+ case CONVERT_EXPR:
+ /* Casts are simple. */
+ ee = expand_simple_operations (e);
+ return fold_build1 (code, TREE_TYPE (expr), ee);
+
+ case PLUS_EXPR:
+ case MINUS_EXPR:
+ case POINTER_PLUS_EXPR:
/* And increments and decrements by a constant are simple. */
- && !((TREE_CODE (e) == PLUS_EXPR
- || TREE_CODE (e) == MINUS_EXPR
- || TREE_CODE (e) == POINTER_PLUS_EXPR)
- && is_gimple_min_invariant (TREE_OPERAND (e, 1))))
- return expr;
+ e1 = gimple_assign_rhs2 (stmt);
+ if (!is_gimple_min_invariant (e1))
+ return expr;
+
+ ee = expand_simple_operations (e);
+ return fold_build2 (code, TREE_TYPE (expr), ee, e1);
- return expand_simple_operations (e);
+ default:
+ return expr;
+ }
}
/* Tries to simplify EXPR using the condition COND. Returns the simplified
@@ -1585,6 +1605,7 @@ simplify_using_initial_conditions (struct loop *loop, tree expr)
{
edge e;
basic_block bb;
+ gimple stmt;
tree cond;
int cnt = 0;
@@ -1605,7 +1626,11 @@ simplify_using_initial_conditions (struct loop *loop, tree expr)
if (!(e->flags & (EDGE_TRUE_VALUE | EDGE_FALSE_VALUE)))
continue;
- cond = COND_EXPR_COND (last_stmt (e->src));
+ stmt = last_stmt (e->src);
+ cond = fold_build2 (gimple_cond_code (stmt),
+ boolean_type_node,
+ gimple_cond_lhs (stmt),
+ gimple_cond_rhs (stmt));
if (e->flags & EDGE_FALSE_VALUE)
cond = invert_truthvalue (cond);
expr = tree_simplify_using_condition (cond, expr);
@@ -1676,9 +1701,9 @@ bool
loop_only_exit_p (const struct loop *loop, const_edge exit)
{
basic_block *body;
- block_stmt_iterator bsi;
+ gimple_stmt_iterator bsi;
unsigned i;
- tree call;
+ gimple call;
if (exit != single_exit (loop))
return false;
@@ -1686,10 +1711,13 @@ loop_only_exit_p (const struct loop *loop, const_edge exit)
body = get_loop_body (loop);
for (i = 0; i < loop->num_nodes; i++)
{
- for (bsi = bsi_start (body[0]); !bsi_end_p (bsi); bsi_next (&bsi))
+ for (bsi = gsi_start_bb (body[i]); !gsi_end_p (bsi); gsi_next (&bsi))
{
- call = get_call_expr_in (bsi_stmt (bsi));
- if (call && TREE_SIDE_EFFECTS (call))
+ call = gsi_stmt (bsi);
+ if (gimple_code (call) != GIMPLE_CALL)
+ continue;
+
+ if (gimple_has_side_effects (call))
{
free (body);
return false;
@@ -1714,7 +1742,8 @@ number_of_iterations_exit (struct loop *loop, edge exit,
struct tree_niter_desc *niter,
bool warn)
{
- tree stmt, cond, type;
+ gimple stmt;
+ tree type;
tree op0, op1;
enum tree_code code;
affine_iv iv0, iv1;
@@ -1724,15 +1753,14 @@ number_of_iterations_exit (struct loop *loop, edge exit,
niter->assumptions = boolean_false_node;
stmt = last_stmt (exit->src);
- if (!stmt || TREE_CODE (stmt) != COND_EXPR)
+ if (!stmt || gimple_code (stmt) != GIMPLE_COND)
return false;
/* We want the condition for staying inside loop. */
- cond = COND_EXPR_COND (stmt);
+ code = gimple_cond_code (stmt);
if (exit->flags & EDGE_TRUE_VALUE)
- cond = invert_truthvalue (cond);
+ code = invert_tree_comparison (code, false);
- code = TREE_CODE (cond);
switch (code)
{
case GT_EXPR:
@@ -1746,8 +1774,8 @@ number_of_iterations_exit (struct loop *loop, edge exit,
return false;
}
- op0 = TREE_OPERAND (cond, 0);
- op1 = TREE_OPERAND (cond, 1);
+ op0 = gimple_cond_lhs (stmt);
+ op1 = gimple_cond_rhs (stmt);
type = TREE_TYPE (op0);
if (TREE_CODE (type) != INTEGER_TYPE
@@ -1805,7 +1833,7 @@ number_of_iterations_exit (struct loop *loop, edge exit,
if (warn)
{
const char *wording;
- location_t loc = EXPR_LOCATION (stmt);
+ location_t loc = gimple_location (stmt);
/* We can provide a more specific warning if one of the operator is
constant and the other advances by +1 or -1. */
@@ -1915,36 +1943,43 @@ find_loop_niter (struct loop *loop, edge *exit)
result by a chain of operations such that all but exactly one of their
operands are constants. */
-static tree
+static gimple
chain_of_csts_start (struct loop *loop, tree x)
{
- tree stmt = SSA_NAME_DEF_STMT (x);
+ gimple stmt = SSA_NAME_DEF_STMT (x);
tree use;
- basic_block bb = bb_for_stmt (stmt);
+ basic_block bb = gimple_bb (stmt);
+ enum tree_code code;
if (!bb
|| !flow_bb_inside_loop_p (loop, bb))
- return NULL_TREE;
+ return NULL;
- if (TREE_CODE (stmt) == PHI_NODE)
+ if (gimple_code (stmt) == GIMPLE_PHI)
{
if (bb == loop->header)
return stmt;
- return NULL_TREE;
+ return NULL;
}
- if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT)
- return NULL_TREE;
+ if (gimple_code (stmt) != GIMPLE_ASSIGN)
+ return NULL;
- if (!ZERO_SSA_OPERANDS (stmt, SSA_OP_ALL_VIRTUALS))
- return NULL_TREE;
- if (SINGLE_SSA_DEF_OPERAND (stmt, SSA_OP_DEF) == NULL_DEF_OPERAND_P)
- return NULL_TREE;
+ code = gimple_assign_rhs_code (stmt);
+ if (gimple_references_memory_p (stmt)
+ /* Before alias information is computed, operand scanning marks
+ statements that write memory volatile. However, the statements
+ that only read memory are not marked, thus gimple_references_memory_p
+ returns false for them. */
+ || TREE_CODE_CLASS (code) == tcc_reference
+ || TREE_CODE_CLASS (code) == tcc_declaration
+ || SINGLE_SSA_DEF_OPERAND (stmt, SSA_OP_DEF) == NULL_DEF_OPERAND_P)
+ return NULL;
use = SINGLE_SSA_TREE_OPERAND (stmt, SSA_OP_USE);
if (use == NULL_USE_OPERAND_P)
- return NULL_TREE;
+ return NULL;
return chain_of_csts_start (loop, use);
}
@@ -1957,32 +1992,32 @@ chain_of_csts_start (struct loop *loop, tree x)
* the value of the phi node in the next iteration can be derived from the
value in the current iteration by a chain of operations with constants.
- If such phi node exists, it is returned. If X is a constant, X is returned
- unchanged. Otherwise NULL_TREE is returned. */
+ If such phi node exists, it is returned, otherwise NULL is returned. */
-static tree
+static gimple
get_base_for (struct loop *loop, tree x)
{
- tree phi, init, next;
+ gimple phi;
+ tree init, next;
if (is_gimple_min_invariant (x))
- return x;
+ return NULL;
phi = chain_of_csts_start (loop, x);
if (!phi)
- return NULL_TREE;
+ return NULL;
init = PHI_ARG_DEF_FROM_EDGE (phi, loop_preheader_edge (loop));
next = PHI_ARG_DEF_FROM_EDGE (phi, loop_latch_edge (loop));
if (TREE_CODE (next) != SSA_NAME)
- return NULL_TREE;
+ return NULL;
if (!is_gimple_min_invariant (init))
- return NULL_TREE;
+ return NULL;
if (chain_of_csts_start (loop, next) != phi)
- return NULL_TREE;
+ return NULL;
return phi;
}
@@ -1998,9 +2033,8 @@ get_base_for (struct loop *loop, tree x)
static tree
get_val_for (tree x, tree base)
{
- tree stmt, nx, val;
- use_operand_p op;
- ssa_op_iter iter;
+ gimple stmt;
+ tree nx, val, retval, rhs1, rhs2;
gcc_assert (is_gimple_min_invariant (base));
@@ -2008,24 +2042,44 @@ get_val_for (tree x, tree base)
return base;
stmt = SSA_NAME_DEF_STMT (x);
- if (TREE_CODE (stmt) == PHI_NODE)
+ if (gimple_code (stmt) == GIMPLE_PHI)
return base;
- FOR_EACH_SSA_USE_OPERAND (op, stmt, iter, SSA_OP_USE)
- {
- nx = USE_FROM_PTR (op);
- val = get_val_for (nx, base);
- SET_USE (op, val);
- val = fold (GIMPLE_STMT_OPERAND (stmt, 1));
- SET_USE (op, nx);
- /* only iterate loop once. */
- return val;
+ gcc_assert (is_gimple_assign (stmt));
+
+ /* STMT must be either an assignment of a single SSA name or an
+ expression involving an SSA name and a constant. Try to fold that
+ expression using the value for the SSA name. */
+ rhs1 = gimple_assign_rhs1 (stmt);
+ rhs2 = gimple_assign_rhs2 (stmt);
+ if (TREE_CODE (rhs1) == SSA_NAME)
+ nx = rhs1;
+ else if (rhs2 && TREE_CODE (rhs2) == SSA_NAME)
+ nx = rhs2;
+ else
+ gcc_unreachable ();
+
+ /* NX is now the SSA name for which we want to discover the base value. */
+ val = get_val_for (nx, base);
+ if (rhs2)
+ {
+ /* If this is a binary expression, fold it. If folding is
+ not possible, return a tree expression with the RHS of STMT. */
+ rhs1 = (nx == rhs1) ? val : rhs1;
+ rhs2 = (nx == rhs2) ? val : rhs2;
+ retval = fold_binary (gimple_assign_rhs_code (stmt),
+ gimple_expr_type (stmt), rhs1, rhs2);
+ if (retval == NULL_TREE)
+ retval= build2 (gimple_assign_rhs_code (stmt),
+ gimple_expr_type (stmt), rhs1, rhs2);
}
-
- /* Should never reach here. */
- gcc_unreachable ();
+ else
+ retval = val;
+
+ return retval;
}
+
/* Tries to count the number of iterations of LOOP till it exits by EXIT
by brute force -- i.e. by determining the value of the operands of the
condition at EXIT in first few iterations of the loop (assuming that
@@ -2036,20 +2090,20 @@ get_val_for (tree x, tree base)
tree
loop_niter_by_eval (struct loop *loop, edge exit)
{
- tree cond, cnd, acnd;
- tree op[2], val[2], next[2], aval[2], phi[2];
+ tree acnd;
+ tree op[2], val[2], next[2], aval[2];
+ gimple phi, cond;
unsigned i, j;
enum tree_code cmp;
cond = last_stmt (exit->src);
- if (!cond || TREE_CODE (cond) != COND_EXPR)
+ if (!cond || gimple_code (cond) != GIMPLE_COND)
return chrec_dont_know;
- cnd = COND_EXPR_COND (cond);
+ cmp = gimple_cond_code (cond);
if (exit->flags & EDGE_TRUE_VALUE)
- cnd = invert_truthvalue (cnd);
+ cmp = invert_tree_comparison (cmp, false);
- cmp = TREE_CODE (cnd);
switch (cmp)
{
case EQ_EXPR:
@@ -2058,8 +2112,8 @@ loop_niter_by_eval (struct loop *loop, edge exit)
case GE_EXPR:
case LT_EXPR:
case LE_EXPR:
- for (j = 0; j < 2; j++)
- op[j] = TREE_OPERAND (cnd, j);
+ op[0] = gimple_cond_lhs (cond);
+ op[1] = gimple_cond_rhs (cond);
break;
default:
@@ -2068,23 +2122,19 @@ loop_niter_by_eval (struct loop *loop, edge exit)
for (j = 0; j < 2; j++)
{
- phi[j] = get_base_for (loop, op[j]);
- if (!phi[j])
- return chrec_dont_know;
- }
-
- for (j = 0; j < 2; j++)
- {
- if (TREE_CODE (phi[j]) == PHI_NODE)
+ if (is_gimple_min_invariant (op[j]))
{
- val[j] = PHI_ARG_DEF_FROM_EDGE (phi[j], loop_preheader_edge (loop));
- next[j] = PHI_ARG_DEF_FROM_EDGE (phi[j], loop_latch_edge (loop));
+ val[j] = op[j];
+ next[j] = NULL_TREE;
+ op[j] = NULL_TREE;
}
else
{
- val[j] = phi[j];
- next[j] = NULL_TREE;
- op[j] = NULL_TREE;
+ phi = get_base_for (loop, op[j]);
+ if (!phi)
+ return chrec_dont_know;
+ val[j] = PHI_ARG_DEF_FROM_EDGE (phi, loop_preheader_edge (loop));
+ next[j] = PHI_ARG_DEF_FROM_EDGE (phi, loop_latch_edge (loop));
}
}
@@ -2166,17 +2216,48 @@ find_loop_niter_by_eval (struct loop *loop, edge *exit)
*/
+static double_int derive_constant_upper_bound_ops (tree, tree,
+ enum tree_code, tree);
+
+/* Returns a constant upper bound on the value of the right-hand side of
+ an assignment statement STMT. */
+
+static double_int
+derive_constant_upper_bound_assign (gimple stmt)
+{
+ enum tree_code code = gimple_assign_rhs_code (stmt);
+ tree op0 = gimple_assign_rhs1 (stmt);
+ tree op1 = gimple_assign_rhs2 (stmt);
+
+ return derive_constant_upper_bound_ops (TREE_TYPE (gimple_assign_lhs (stmt)),
+ op0, code, op1);
+}
+
/* Returns a constant upper bound on the value of expression VAL. VAL
is considered to be unsigned. If its type is signed, its value must
be nonnegative. */
static double_int
-derive_constant_upper_bound (const_tree val)
+derive_constant_upper_bound (tree val)
+{
+ enum tree_code code;
+ tree op0, op1;
+
+ extract_ops_from_tree (val, &code, &op0, &op1);
+ return derive_constant_upper_bound_ops (TREE_TYPE (val), op0, code, op1);
+}
+
+/* Returns a constant upper bound on the value of expression OP0 CODE OP1,
+ whose type is TYPE. The expression is considered to be unsigned. If
+ its type is signed, its value must be nonnegative. */
+
+static double_int
+derive_constant_upper_bound_ops (tree type, tree op0,
+ enum tree_code code, tree op1)
{
- tree type = TREE_TYPE (val);
- tree op0, op1, subtype, maxt;
+ tree subtype, maxt;
double_int bnd, max, mmax, cst;
- tree stmt;
+ gimple stmt;
if (INTEGRAL_TYPE_P (type))
maxt = TYPE_MAX_VALUE (type);
@@ -2185,13 +2266,12 @@ derive_constant_upper_bound (const_tree val)
max = tree_to_double_int (maxt);
- switch (TREE_CODE (val))
+ switch (code)
{
case INTEGER_CST:
- return tree_to_double_int (val);
+ return tree_to_double_int (op0);
CASE_CONVERT:
- op0 = TREE_OPERAND (val, 0);
subtype = TREE_TYPE (op0);
if (!TYPE_UNSIGNED (subtype)
/* If TYPE is also signed, the fact that VAL is nonnegative implies
@@ -2219,9 +2299,6 @@ derive_constant_upper_bound (const_tree val)
case PLUS_EXPR:
case POINTER_PLUS_EXPR:
case MINUS_EXPR:
- op0 = TREE_OPERAND (val, 0);
- op1 = TREE_OPERAND (val, 1);
-
if (TREE_CODE (op1) != INTEGER_CST
|| !tree_expr_nonnegative_p (op0))
return max;
@@ -2231,7 +2308,7 @@ derive_constant_upper_bound (const_tree val)
of the signedness of the type. */
cst = tree_to_double_int (op1);
cst = double_int_sext (cst, TYPE_PRECISION (type));
- if (TREE_CODE (val) == PLUS_EXPR)
+ if (code != MINUS_EXPR)
cst = double_int_neg (cst);
bnd = derive_constant_upper_bound (op0);
@@ -2285,8 +2362,6 @@ derive_constant_upper_bound (const_tree val)
case FLOOR_DIV_EXPR:
case EXACT_DIV_EXPR:
- op0 = TREE_OPERAND (val, 0);
- op1 = TREE_OPERAND (val, 1);
if (TREE_CODE (op1) != INTEGER_CST
|| tree_int_cst_sign_bit (op1))
return max;
@@ -2295,18 +2370,17 @@ derive_constant_upper_bound (const_tree val)
return double_int_udiv (bnd, tree_to_double_int (op1), FLOOR_DIV_EXPR);
case BIT_AND_EXPR:
- op1 = TREE_OPERAND (val, 1);
if (TREE_CODE (op1) != INTEGER_CST
|| tree_int_cst_sign_bit (op1))
return max;
return tree_to_double_int (op1);
case SSA_NAME:
- stmt = SSA_NAME_DEF_STMT (val);
- if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT
- || GIMPLE_STMT_OPERAND (stmt, 0) != val)
+ stmt = SSA_NAME_DEF_STMT (op0);
+ if (gimple_code (stmt) != GIMPLE_ASSIGN
+ || gimple_assign_lhs (stmt) != op0)
return max;
- return derive_constant_upper_bound (GIMPLE_STMT_OPERAND (stmt, 1));
+ return derive_constant_upper_bound_assign (stmt);
default:
return max;
@@ -2349,7 +2423,7 @@ record_niter_bound (struct loop *loop, double_int i_bound, bool realistic,
static void
record_estimate (struct loop *loop, tree bound, double_int i_bound,
- tree at_stmt, bool is_exit, bool realistic, bool upper)
+ gimple at_stmt, bool is_exit, bool realistic, bool upper)
{
double_int delta;
edge exit;
@@ -2357,7 +2431,7 @@ record_estimate (struct loop *loop, tree bound, double_int i_bound,
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "Statement %s", is_exit ? "(exit)" : "");
- print_generic_expr (dump_file, at_stmt, TDF_SLIM);
+ print_gimple_stmt (dump_file, at_stmt, 0, TDF_SLIM);
fprintf (dump_file, " is %sexecuted at most ",
upper ? "" : "probably ");
print_generic_expr (dump_file, bound, TDF_SLIM);
@@ -2395,7 +2469,7 @@ record_estimate (struct loop *loop, tree bound, double_int i_bound,
if (is_exit
|| (exit != NULL
&& dominated_by_p (CDI_DOMINATORS,
- exit->src, bb_for_stmt (at_stmt))))
+ exit->src, gimple_bb (at_stmt))))
delta = double_int_one;
else
delta = double_int_two;
@@ -2415,7 +2489,7 @@ record_estimate (struct loop *loop, tree bound, double_int i_bound,
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, tree stmt,
+record_nonwrapping_iv (struct loop *loop, tree base, tree step, gimple stmt,
tree low, tree high, bool realistic, bool upper)
{
tree niter_bound, extreme, delta;
@@ -2434,7 +2508,7 @@ record_nonwrapping_iv (struct loop *loop, tree base, tree step, tree stmt,
fprintf (dump_file, " + ");
print_generic_expr (dump_file, step, TDF_SLIM);
fprintf (dump_file, " * iteration does not wrap in statement ");
- print_generic_expr (dump_file, stmt, TDF_SLIM);
+ print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
fprintf (dump_file, " in loop %d.\n", loop->num);
}
@@ -2515,7 +2589,7 @@ array_at_struct_end_p (tree ref)
struct ilb_data
{
struct loop *loop;
- tree stmt;
+ gimple stmt;
bool reliable;
};
@@ -2602,7 +2676,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, tree stmt, tree ref,
+infer_loop_bounds_from_ref (struct loop *loop, gimple stmt, tree ref,
bool reliable)
{
struct ilb_data data;
@@ -2618,14 +2692,12 @@ infer_loop_bounds_from_ref (struct loop *loop, tree stmt, tree ref,
executed in every iteration of LOOP. */
static void
-infer_loop_bounds_from_array (struct loop *loop, tree stmt, bool reliable)
+infer_loop_bounds_from_array (struct loop *loop, gimple stmt, bool reliable)
{
- tree call;
-
- if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT)
+ if (is_gimple_assign (stmt))
{
- tree op0 = GIMPLE_STMT_OPERAND (stmt, 0);
- tree op1 = GIMPLE_STMT_OPERAND (stmt, 1);
+ tree op0 = gimple_assign_lhs (stmt);
+ tree op1 = gimple_assign_rhs1 (stmt);
/* For each memory access, analyze its access function
and record a bound on the loop iteration domain. */
@@ -2635,17 +2707,21 @@ infer_loop_bounds_from_array (struct loop *loop, tree stmt, bool reliable)
if (REFERENCE_CLASS_P (op1))
infer_loop_bounds_from_ref (loop, stmt, op1, reliable);
}
-
-
- call = get_call_expr_in (stmt);
- if (call)
+ else if (is_gimple_call (stmt))
{
- tree arg;
- call_expr_arg_iterator iter;
+ tree arg, lhs;
+ unsigned i, n = gimple_call_num_args (stmt);
- FOR_EACH_CALL_EXPR_ARG (arg, iter, call)
- if (REFERENCE_CLASS_P (arg))
- infer_loop_bounds_from_ref (loop, stmt, arg, reliable);
+ lhs = gimple_call_lhs (stmt);
+ if (lhs && REFERENCE_CLASS_P (lhs))
+ infer_loop_bounds_from_ref (loop, stmt, lhs, reliable);
+
+ for (i = 0; i < n; i++)
+ {
+ arg = gimple_call_arg (stmt, i);
+ if (REFERENCE_CLASS_P (arg))
+ infer_loop_bounds_from_ref (loop, stmt, arg, reliable);
+ }
}
}
@@ -2653,14 +2729,14 @@ infer_loop_bounds_from_array (struct loop *loop, tree stmt, bool reliable)
that signed arithmetics in STMT does not overflow. */
static void
-infer_loop_bounds_from_signedness (struct loop *loop, tree stmt)
+infer_loop_bounds_from_signedness (struct loop *loop, gimple stmt)
{
tree def, base, step, scev, type, low, high;
- if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT)
+ if (gimple_code (stmt) != GIMPLE_ASSIGN)
return;
- def = GIMPLE_STMT_OPERAND (stmt, 0);
+ def = gimple_assign_lhs (stmt);
if (TREE_CODE (def) != SSA_NAME)
return;
@@ -2703,7 +2779,7 @@ infer_loop_bounds_from_undefined (struct loop *loop)
{
unsigned i;
basic_block *bbs;
- block_stmt_iterator bsi;
+ gimple_stmt_iterator bsi;
basic_block bb;
bool reliable;
@@ -2718,9 +2794,9 @@ infer_loop_bounds_from_undefined (struct loop *loop)
# of iterations of the loop. However, we can use it as a guess. */
reliable = dominated_by_p (CDI_DOMINATORS, loop->latch, bb);
- for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
+ for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi))
{
- tree stmt = bsi_stmt (bsi);
+ gimple stmt = gsi_stmt (bsi);
infer_loop_bounds_from_array (loop, stmt, reliable);
@@ -2830,9 +2906,9 @@ estimate_numbers_of_iterations (void)
/* Returns true if statement S1 dominates statement S2. */
bool
-stmt_dominates_stmt_p (tree s1, tree s2)
+stmt_dominates_stmt_p (gimple s1, gimple s2)
{
- basic_block bb1 = bb_for_stmt (s1), bb2 = bb_for_stmt (s2);
+ basic_block bb1 = gimple_bb (s1), bb2 = gimple_bb (s2);
if (!bb1
|| s1 == s2)
@@ -2840,10 +2916,10 @@ stmt_dominates_stmt_p (tree s1, tree s2)
if (bb1 == bb2)
{
- block_stmt_iterator bsi;
+ gimple_stmt_iterator bsi;
- for (bsi = bsi_start (bb1); bsi_stmt (bsi) != s2; bsi_next (&bsi))
- if (bsi_stmt (bsi) == s1)
+ for (bsi = gsi_start_bb (bb1); gsi_stmt (bsi) != s2; gsi_next (&bsi))
+ if (gsi_stmt (bsi) == s1)
return true;
return false;
@@ -2859,7 +2935,7 @@ stmt_dominates_stmt_p (tree s1, tree s2)
statements in the loop. */
static bool
-n_of_executions_at_most (tree stmt,
+n_of_executions_at_most (gimple stmt,
struct nb_iter_bound *niter_bound,
tree niter)
{
@@ -2900,7 +2976,7 @@ n_of_executions_at_most (tree stmt,
else
{
if (!stmt
- || (bb_for_stmt (stmt) != bb_for_stmt (niter_bound->stmt)
+ || (gimple_bb (stmt) != gimple_bb (niter_bound->stmt)
&& !stmt_dominates_stmt_p (niter_bound->stmt, stmt)))
{
bound = double_int_add (bound, double_int_one);
@@ -2943,7 +3019,7 @@ nowrap_type_p (tree type)
bool
scev_probably_wraps_p (tree base, tree step,
- tree at_stmt, struct loop *loop,
+ gimple at_stmt, struct loop *loop,
bool use_overflow_semantics)
{
struct nb_iter_bound *bound;
diff --git a/gcc/tree-ssa-loop-prefetch.c b/gcc/tree-ssa-loop-prefetch.c
index 14044c407d7..02b4d7347df 100644
--- a/gcc/tree-ssa-loop-prefetch.c
+++ b/gcc/tree-ssa-loop-prefetch.c
@@ -201,7 +201,7 @@ struct mem_ref_group
struct mem_ref
{
- tree stmt; /* Statement in that the reference appears. */
+ gimple stmt; /* Statement in that the reference appears. */
tree mem; /* The reference. */
HOST_WIDE_INT delta; /* Constant offset of the reference. */
struct mem_ref_group *group; /* The group of references it belongs to. */
@@ -278,7 +278,7 @@ find_or_create_group (struct mem_ref_group **groups, tree base,
WRITE_P. The reference occurs in statement STMT. */
static void
-record_ref (struct mem_ref_group *group, tree stmt, tree mem,
+record_ref (struct mem_ref_group *group, gimple stmt, tree mem,
HOST_WIDE_INT delta, bool write_p)
{
struct mem_ref **aref;
@@ -344,7 +344,7 @@ release_mem_refs (struct mem_ref_group *groups)
struct ar_data
{
struct loop *loop; /* Loop of the reference. */
- tree stmt; /* Statement of the reference. */
+ gimple stmt; /* Statement of the reference. */
HOST_WIDE_INT *step; /* Step of the memory reference. */
HOST_WIDE_INT *delta; /* Offset of the memory reference. */
};
@@ -411,7 +411,7 @@ idx_analyze_ref (tree base, tree *index, void *data)
static bool
analyze_ref (struct loop *loop, tree *ref_p, tree *base,
HOST_WIDE_INT *step, HOST_WIDE_INT *delta,
- tree stmt)
+ gimple stmt)
{
struct ar_data ar_data;
tree off;
@@ -451,7 +451,7 @@ analyze_ref (struct loop *loop, tree *ref_p, tree *base,
static bool
gather_memory_references_ref (struct loop *loop, struct mem_ref_group **refs,
- tree ref, bool write_p, tree stmt)
+ tree ref, bool write_p, gimple stmt)
{
tree base;
HOST_WIDE_INT step, delta;
@@ -480,8 +480,9 @@ gather_memory_references (struct loop *loop, bool *no_other_refs)
basic_block *body = get_loop_body_in_dom_order (loop);
basic_block bb;
unsigned i;
- block_stmt_iterator bsi;
- tree stmt, lhs, rhs, call;
+ gimple_stmt_iterator bsi;
+ gimple stmt;
+ tree lhs, rhs;
struct mem_ref_group *refs = NULL;
*no_other_refs = true;
@@ -494,22 +495,21 @@ gather_memory_references (struct loop *loop, bool *no_other_refs)
if (bb->loop_father != loop)
continue;
- for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
+ for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi))
{
- stmt = bsi_stmt (bsi);
- call = get_call_expr_in (stmt);
- if (call && !(call_expr_flags (call) & ECF_CONST))
- *no_other_refs = false;
+ stmt = gsi_stmt (bsi);
- if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT)
+ if (gimple_code (stmt) != GIMPLE_ASSIGN)
{
- if (!ZERO_SSA_OPERANDS (stmt, SSA_OP_ALL_VIRTUALS))
+ if (!ZERO_SSA_OPERANDS (stmt, SSA_OP_ALL_VIRTUALS)
+ || (is_gimple_call (stmt)
+ && !(gimple_call_flags (stmt) & ECF_CONST)))
*no_other_refs = false;
continue;
}
- lhs = GIMPLE_STMT_OPERAND (stmt, 0);
- rhs = GIMPLE_STMT_OPERAND (stmt, 1);
+ lhs = gimple_assign_lhs (stmt);
+ rhs = gimple_assign_rhs1 (stmt);
if (REFERENCE_CLASS_P (rhs))
*no_other_refs &= gather_memory_references_ref (loop, &refs,
@@ -869,8 +869,9 @@ static void
issue_prefetch_ref (struct mem_ref *ref, unsigned unroll_factor, unsigned ahead)
{
HOST_WIDE_INT delta;
- tree addr, addr_base, prefetch, write_p, local;
- block_stmt_iterator bsi;
+ tree addr, addr_base, write_p, local;
+ gimple prefetch;
+ gimple_stmt_iterator bsi;
unsigned n_prefetches, ap;
bool nontemporal = ref->reuse_distance >= L2_CACHE_SIZE_BYTES;
@@ -879,13 +880,13 @@ issue_prefetch_ref (struct mem_ref *ref, unsigned unroll_factor, unsigned ahead)
nontemporal ? " nontemporal" : "",
(void *) ref);
- bsi = bsi_for_stmt (ref->stmt);
+ bsi = gsi_for_stmt (ref->stmt);
n_prefetches = ((unroll_factor + ref->prefetch_mod - 1)
/ ref->prefetch_mod);
addr_base = build_fold_addr_expr_with_type (ref->mem, ptr_type_node);
- addr_base = force_gimple_operand_bsi (&bsi, unshare_expr (addr_base),
- true, NULL, true, BSI_SAME_STMT);
+ addr_base = force_gimple_operand_gsi (&bsi, unshare_expr (addr_base),
+ true, NULL, true, GSI_SAME_STMT);
write_p = ref->write_p ? integer_one_node : integer_zero_node;
local = build_int_cst (integer_type_node, nontemporal ? 0 : 3);
@@ -895,13 +896,13 @@ issue_prefetch_ref (struct mem_ref *ref, unsigned unroll_factor, unsigned ahead)
delta = (ahead + ap * ref->prefetch_mod) * ref->group->step;
addr = fold_build2 (POINTER_PLUS_EXPR, ptr_type_node,
addr_base, size_int (delta));
- addr = force_gimple_operand_bsi (&bsi, unshare_expr (addr), true, NULL,
- true, BSI_SAME_STMT);
+ addr = force_gimple_operand_gsi (&bsi, unshare_expr (addr), true, NULL,
+ true, GSI_SAME_STMT);
/* Create the prefetch instruction. */
- prefetch = build_call_expr (built_in_decls[BUILT_IN_PREFETCH],
- 3, addr, write_p, local);
- bsi_insert_before (&bsi, prefetch, BSI_SAME_STMT);
+ prefetch = gimple_build_call (built_in_decls[BUILT_IN_PREFETCH],
+ 3, addr, write_p, local);
+ gsi_insert_before (&bsi, prefetch, GSI_SAME_STMT);
}
}
@@ -960,7 +961,7 @@ mark_nontemporal_store (struct mem_ref *ref)
fprintf (dump_file, "Marked reference %p as a nontemporal store.\n",
(void *) ref);
- MOVE_NONTEMPORAL (ref->stmt) = true;
+ gimple_assign_set_nontemporal_move (ref->stmt, true);
ref->storent_p = true;
return true;
@@ -973,22 +974,22 @@ emit_mfence_after_loop (struct loop *loop)
{
VEC (edge, heap) *exits = get_loop_exit_edges (loop);
edge exit;
- tree call;
- block_stmt_iterator bsi;
+ gimple call;
+ gimple_stmt_iterator bsi;
unsigned i;
for (i = 0; VEC_iterate (edge, exits, i, exit); i++)
{
- call = build_function_call_expr (FENCE_FOLLOWING_MOVNT, NULL_TREE);
+ call = gimple_build_call (FENCE_FOLLOWING_MOVNT, 0);
if (!single_pred_p (exit->dest)
/* If possible, we prefer not to insert the fence on other paths
in cfg. */
&& !(exit->flags & EDGE_ABNORMAL))
split_loop_exit_edge (exit);
- bsi = bsi_after_labels (exit->dest);
+ bsi = gsi_after_labels (exit->dest);
- bsi_insert_before (&bsi, call, BSI_NEW_STMT);
+ gsi_insert_before (&bsi, call, GSI_NEW_STMT);
mark_virtual_ops_for_renaming (call);
}
diff --git a/gcc/tree-ssa-loop-unswitch.c b/gcc/tree-ssa-loop-unswitch.c
index b63c2095df4..8ece4aca4ab 100644
--- a/gcc/tree-ssa-loop-unswitch.c
+++ b/gcc/tree-ssa-loop-unswitch.c
@@ -103,26 +103,29 @@ tree_ssa_unswitch_loops (void)
static tree
tree_may_unswitch_on (basic_block bb, struct loop *loop)
{
- tree stmt, def, cond, use;
+ gimple stmt, def;
+ tree cond, use;
basic_block def_bb;
ssa_op_iter iter;
/* BB must end in a simple conditional jump. */
stmt = last_stmt (bb);
- if (!stmt || TREE_CODE (stmt) != COND_EXPR)
+ if (!stmt || gimple_code (stmt) != GIMPLE_COND)
return NULL_TREE;
/* Condition must be invariant. */
FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_USE)
{
def = SSA_NAME_DEF_STMT (use);
- def_bb = bb_for_stmt (def);
+ def_bb = gimple_bb (def);
if (def_bb
&& flow_bb_inside_loop_p (loop, def_bb))
return NULL_TREE;
}
- cond = COND_EXPR_COND (stmt);
+ cond = fold_build2 (gimple_cond_code (stmt), boolean_type_node,
+ gimple_cond_lhs (stmt), gimple_cond_rhs (stmt));
+
/* To keep the things simple, we do not directly remove the conditions,
but just replace tests with 0/1. Prevent the infinite loop where we
would unswitch again on such a condition. */
@@ -140,14 +143,18 @@ static tree
simplify_using_entry_checks (struct loop *loop, tree cond)
{
edge e = loop_preheader_edge (loop);
- tree stmt;
+ gimple stmt;
while (1)
{
stmt = last_stmt (e->src);
if (stmt
- && TREE_CODE (stmt) == COND_EXPR
- && operand_equal_p (COND_EXPR_COND (stmt), cond, 0))
+ && gimple_code (stmt) == GIMPLE_COND
+ && gimple_cond_code (stmt) == TREE_CODE (cond)
+ && operand_equal_p (gimple_cond_lhs (stmt),
+ TREE_OPERAND (cond, 0), 0)
+ && operand_equal_p (gimple_cond_rhs (stmt),
+ TREE_OPERAND (cond, 1), 0))
return (e->flags & EDGE_TRUE_VALUE
? boolean_true_node
: boolean_false_node);
@@ -171,7 +178,8 @@ tree_unswitch_single_loop (struct loop *loop, int num)
basic_block *bbs;
struct loop *nloop;
unsigned i;
- tree cond = NULL_TREE, stmt;
+ tree cond = NULL_TREE;
+ gimple stmt;
bool changed = false;
/* Do not unswitch too much. */
@@ -220,13 +228,13 @@ tree_unswitch_single_loop (struct loop *loop, int num)
if (integer_nonzerop (cond))
{
/* Remove false path. */
- COND_EXPR_COND (stmt) = boolean_true_node;
+ gimple_cond_set_condition_from_tree (stmt, boolean_true_node);
changed = true;
}
else if (integer_zerop (cond))
{
/* Remove true path. */
- COND_EXPR_COND (stmt) = boolean_false_node;
+ gimple_cond_set_condition_from_tree (stmt, boolean_false_node);
changed = true;
}
else
diff --git a/gcc/tree-ssa-loop.c b/gcc/tree-ssa-loop.c
index 52f5a7f58f8..ec3782a5450 100644
--- a/gcc/tree-ssa-loop.c
+++ b/gcc/tree-ssa-loop.c
@@ -37,16 +37,6 @@ along with GCC; see the file COPYING3. If not see
#include "tree-inline.h"
#include "tree-scalar-evolution.h"
-/* Initializes the loop structures. */
-
-static void
-tree_loop_optimizer_init (void)
-{
- loop_optimizer_init (LOOPS_NORMAL
- | LOOPS_HAVE_RECORDED_EXITS);
- rewrite_into_loop_closed_ssa (NULL, TODO_update_ssa);
-}
-
/* The loop superpass. */
static bool
@@ -79,7 +69,10 @@ struct gimple_opt_pass pass_tree_loop =
static unsigned int
tree_ssa_loop_init (void)
{
- tree_loop_optimizer_init ();
+ loop_optimizer_init (LOOPS_NORMAL
+ | LOOPS_HAVE_RECORDED_EXITS);
+ rewrite_into_loop_closed_ssa (NULL, TODO_update_ssa);
+
if (number_of_loops () <= 1)
return 0;
diff --git a/gcc/tree-ssa-math-opts.c b/gcc/tree-ssa-math-opts.c
index 49fd1707d1e..dfc00bcdd12 100644
--- a/gcc/tree-ssa-math-opts.c
+++ b/gcc/tree-ssa-math-opts.c
@@ -110,9 +110,9 @@ struct occurrence {
inserted in BB. */
tree recip_def;
- /* If non-NULL, the GIMPLE_MODIFY_STMT for a reciprocal computation that
+ /* If non-NULL, the GIMPLE_ASSIGN for a reciprocal computation that
was inserted in BB. */
- tree recip_def_stmt;
+ gimple recip_def_stmt;
/* Pointer to a list of "struct occurrence"s for blocks dominated
by BB. */
@@ -271,15 +271,15 @@ compute_merit (struct occurrence *occ)
/* Return whether USE_STMT is a floating-point division by DEF. */
static inline bool
-is_division_by (tree use_stmt, tree def)
+is_division_by (gimple use_stmt, tree def)
{
- return TREE_CODE (use_stmt) == GIMPLE_MODIFY_STMT
- && TREE_CODE (GIMPLE_STMT_OPERAND (use_stmt, 1)) == RDIV_EXPR
- && TREE_OPERAND (GIMPLE_STMT_OPERAND (use_stmt, 1), 1) == def
+ return is_gimple_assign (use_stmt)
+ && gimple_assign_rhs_code (use_stmt) == RDIV_EXPR
+ && gimple_assign_rhs2 (use_stmt) == def
/* Do not recognize x / x as valid division, as we are getting
confused later by replacing all immediate uses x in such
a stmt. */
- && TREE_OPERAND (GIMPLE_STMT_OPERAND (use_stmt, 1), 0) != def;
+ && gimple_assign_rhs1 (use_stmt) != def;
}
/* Walk the subset of the dominator tree rooted at OCC, setting the
@@ -292,11 +292,12 @@ is_division_by (tree use_stmt, tree def)
be used. */
static void
-insert_reciprocals (block_stmt_iterator *def_bsi, struct occurrence *occ,
+insert_reciprocals (gimple_stmt_iterator *def_gsi, struct occurrence *occ,
tree def, tree recip_def, int threshold)
{
- tree type, new_stmt;
- block_stmt_iterator bsi;
+ tree type;
+ gimple new_stmt;
+ gimple_stmt_iterator gsi;
struct occurrence *occ_child;
if (!recip_def
@@ -306,34 +307,31 @@ insert_reciprocals (block_stmt_iterator *def_bsi, struct occurrence *occ,
/* Make a variable with the replacement and substitute it. */
type = TREE_TYPE (def);
recip_def = make_rename_temp (type, "reciptmp");
- new_stmt = build_gimple_modify_stmt (recip_def,
- fold_build2 (RDIV_EXPR, type,
- build_one_cst (type),
- def));
-
+ new_stmt = gimple_build_assign_with_ops (RDIV_EXPR, recip_def,
+ build_one_cst (type), def);
if (occ->bb_has_division)
{
/* Case 1: insert before an existing division. */
- bsi = bsi_after_labels (occ->bb);
- while (!bsi_end_p (bsi) && !is_division_by (bsi_stmt (bsi), def))
- bsi_next (&bsi);
+ gsi = gsi_after_labels (occ->bb);
+ while (!gsi_end_p (gsi) && !is_division_by (gsi_stmt (gsi), def))
+ gsi_next (&gsi);
- bsi_insert_before (&bsi, new_stmt, BSI_SAME_STMT);
+ gsi_insert_before (&gsi, new_stmt, GSI_SAME_STMT);
}
- else if (def_bsi && occ->bb == def_bsi->bb)
+ else if (def_gsi && occ->bb == def_gsi->bb)
{
/* Case 2: insert right after the definition. Note that this will
never happen if the definition statement can throw, because in
that case the sole successor of the statement's basic block will
dominate all the uses as well. */
- bsi_insert_after (def_bsi, new_stmt, BSI_NEW_STMT);
+ gsi_insert_after (def_gsi, new_stmt, GSI_NEW_STMT);
}
else
{
/* Case 3: insert in a basic block not containing defs/uses. */
- bsi = bsi_after_labels (occ->bb);
- bsi_insert_before (&bsi, new_stmt, BSI_SAME_STMT);
+ gsi = gsi_after_labels (occ->bb);
+ gsi_insert_before (&gsi, new_stmt, GSI_SAME_STMT);
}
occ->recip_def_stmt = new_stmt;
@@ -341,7 +339,7 @@ insert_reciprocals (block_stmt_iterator *def_bsi, struct occurrence *occ,
occ->recip_def = recip_def;
for (occ_child = occ->children; occ_child; occ_child = occ_child->next)
- insert_reciprocals (def_bsi, occ_child, def, recip_def, threshold);
+ insert_reciprocals (def_gsi, occ_child, def, recip_def, threshold);
}
@@ -351,13 +349,13 @@ insert_reciprocals (block_stmt_iterator *def_bsi, struct occurrence *occ,
static inline void
replace_reciprocal (use_operand_p use_p)
{
- tree use_stmt = USE_STMT (use_p);
- basic_block bb = bb_for_stmt (use_stmt);
+ gimple use_stmt = USE_STMT (use_p);
+ basic_block bb = gimple_bb (use_stmt);
struct occurrence *occ = (struct occurrence *) bb->aux;
if (occ->recip_def && use_stmt != occ->recip_def_stmt)
{
- TREE_SET_CODE (GIMPLE_STMT_OPERAND (use_stmt, 1), MULT_EXPR);
+ gimple_assign_set_rhs_code (use_stmt, MULT_EXPR);
SET_USE (use_p, occ->recip_def);
fold_stmt_inplace (use_stmt);
update_stmt (use_stmt);
@@ -398,7 +396,7 @@ free_bb (struct occurrence *occ)
DEF must be a GIMPLE register of a floating-point type. */
static void
-execute_cse_reciprocals_1 (block_stmt_iterator *def_bsi, tree def)
+execute_cse_reciprocals_1 (gimple_stmt_iterator *def_gsi, tree def)
{
use_operand_p use_p;
imm_use_iterator use_iter;
@@ -409,10 +407,10 @@ execute_cse_reciprocals_1 (block_stmt_iterator *def_bsi, tree def)
FOR_EACH_IMM_USE_FAST (use_p, use_iter, def)
{
- tree use_stmt = USE_STMT (use_p);
+ gimple use_stmt = USE_STMT (use_p);
if (is_division_by (use_stmt, def))
{
- register_division_in (bb_for_stmt (use_stmt));
+ register_division_in (gimple_bb (use_stmt));
count++;
}
}
@@ -421,11 +419,11 @@ execute_cse_reciprocals_1 (block_stmt_iterator *def_bsi, tree def)
threshold = targetm.min_divisions_for_recip_mul (TYPE_MODE (TREE_TYPE (def)));
if (count >= threshold)
{
- tree use_stmt;
+ gimple use_stmt;
for (occ = occ_head; occ; occ = occ->next)
{
compute_merit (occ);
- insert_reciprocals (def_bsi, occ, def, NULL, threshold);
+ insert_reciprocals (def_gsi, occ, def, NULL, threshold);
}
FOR_EACH_IMM_USE_STMT (use_stmt, use_iter, def)
@@ -478,56 +476,55 @@ execute_cse_reciprocals (void)
FOR_EACH_BB (bb)
{
- block_stmt_iterator bsi;
- tree phi, def;
+ gimple_stmt_iterator gsi;
+ gimple phi;
+ tree def;
- for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
+ for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
+ phi = gsi_stmt (gsi);
def = PHI_RESULT (phi);
if (FLOAT_TYPE_P (TREE_TYPE (def))
&& is_gimple_reg (def))
execute_cse_reciprocals_1 (NULL, def);
}
- for (bsi = bsi_after_labels (bb); !bsi_end_p (bsi); bsi_next (&bsi))
+ for (gsi = gsi_after_labels (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
- tree stmt = bsi_stmt (bsi);
+ gimple stmt = gsi_stmt (gsi);
- if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT
+ if (gimple_has_lhs (stmt)
&& (def = SINGLE_SSA_TREE_OPERAND (stmt, SSA_OP_DEF)) != NULL
&& FLOAT_TYPE_P (TREE_TYPE (def))
&& TREE_CODE (def) == SSA_NAME)
- execute_cse_reciprocals_1 (&bsi, def);
+ execute_cse_reciprocals_1 (&gsi, def);
}
/* Scan for a/func(b) and convert it to reciprocal a*rfunc(b). */
- for (bsi = bsi_after_labels (bb); !bsi_end_p (bsi); bsi_next (&bsi))
+ for (gsi = gsi_after_labels (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
- tree stmt = bsi_stmt (bsi);
+ gimple stmt = gsi_stmt (gsi);
tree fndecl;
- if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT
- && TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 1)) == RDIV_EXPR)
+ if (is_gimple_assign (stmt)
+ && gimple_assign_rhs_code (stmt) == RDIV_EXPR)
{
- tree arg1 = TREE_OPERAND (GIMPLE_STMT_OPERAND (stmt, 1), 1);
- tree stmt1;
+ tree arg1 = gimple_assign_rhs2 (stmt);
+ gimple stmt1;
if (TREE_CODE (arg1) != SSA_NAME)
continue;
stmt1 = SSA_NAME_DEF_STMT (arg1);
- if (TREE_CODE (stmt1) == GIMPLE_MODIFY_STMT
- && TREE_CODE (GIMPLE_STMT_OPERAND (stmt1, 1)) == CALL_EXPR
- && (fndecl
- = get_callee_fndecl (GIMPLE_STMT_OPERAND (stmt1, 1)))
+ if (is_gimple_call (stmt1)
+ && gimple_call_lhs (stmt1)
+ && (fndecl = gimple_call_fndecl (stmt1))
&& (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
|| DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD))
{
enum built_in_function code;
bool md_code;
- tree arg10;
- tree tmp;
code = DECL_FUNCTION_CODE (fndecl);
md_code = DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD;
@@ -536,12 +533,10 @@ execute_cse_reciprocals (void)
if (!fndecl)
continue;
- arg10 = CALL_EXPR_ARG (GIMPLE_STMT_OPERAND (stmt1, 1), 0);
- tmp = build_call_expr (fndecl, 1, arg10);
- GIMPLE_STMT_OPERAND (stmt1, 1) = tmp;
+ gimple_call_set_fn (stmt1, fndecl);
update_stmt (stmt1);
- TREE_SET_CODE (GIMPLE_STMT_OPERAND (stmt, 1), MULT_EXPR);
+ gimple_assign_set_rhs_code (stmt, MULT_EXPR);
fold_stmt_inplace (stmt);
update_stmt (stmt);
}
@@ -582,18 +577,18 @@ struct gimple_opt_pass pass_cse_reciprocals =
statements in the vector. */
static bool
-maybe_record_sincos (VEC(tree, heap) **stmts,
- basic_block *top_bb, tree use_stmt)
+maybe_record_sincos (VEC(gimple, heap) **stmts,
+ basic_block *top_bb, gimple use_stmt)
{
- basic_block use_bb = bb_for_stmt (use_stmt);
+ basic_block use_bb = gimple_bb (use_stmt);
if (*top_bb
&& (*top_bb == use_bb
|| dominated_by_p (CDI_DOMINATORS, use_bb, *top_bb)))
- VEC_safe_push (tree, heap, *stmts, use_stmt);
+ VEC_safe_push (gimple, heap, *stmts, use_stmt);
else if (!*top_bb
|| dominated_by_p (CDI_DOMINATORS, *top_bb, use_bb))
{
- VEC_safe_push (tree, heap, *stmts, use_stmt);
+ VEC_safe_push (gimple, heap, *stmts, use_stmt);
*top_bb = use_bb;
}
else
@@ -613,20 +608,21 @@ maybe_record_sincos (VEC(tree, heap) **stmts,
static void
execute_cse_sincos_1 (tree name)
{
- block_stmt_iterator bsi;
+ gimple_stmt_iterator gsi;
imm_use_iterator use_iter;
- tree def_stmt, use_stmt, fndecl, res, call, stmt, type;
+ tree fndecl, res, type;
+ gimple def_stmt, use_stmt, stmt;
int seen_cos = 0, seen_sin = 0, seen_cexpi = 0;
- VEC(tree, heap) *stmts = NULL;
+ VEC(gimple, heap) *stmts = NULL;
basic_block top_bb = NULL;
int i;
type = TREE_TYPE (name);
FOR_EACH_IMM_USE_STMT (use_stmt, use_iter, name)
{
- if (TREE_CODE (use_stmt) != GIMPLE_MODIFY_STMT
- || TREE_CODE (GIMPLE_STMT_OPERAND (use_stmt, 1)) != CALL_EXPR
- || !(fndecl = get_callee_fndecl (GIMPLE_STMT_OPERAND (use_stmt, 1)))
+ if (gimple_code (use_stmt) != GIMPLE_CALL
+ || !gimple_call_lhs (use_stmt)
+ || !(fndecl = gimple_call_fndecl (use_stmt))
|| DECL_BUILT_IN_CLASS (fndecl) != BUILT_IN_NORMAL)
continue;
@@ -650,7 +646,7 @@ execute_cse_sincos_1 (tree name)
if (seen_cos + seen_sin + seen_cexpi <= 1)
{
- VEC_free(tree, heap, stmts);
+ VEC_free(gimple, heap, stmts);
return;
}
@@ -660,51 +656,57 @@ execute_cse_sincos_1 (tree name)
if (!fndecl)
return;
res = make_rename_temp (TREE_TYPE (TREE_TYPE (fndecl)), "sincostmp");
- call = build_call_expr (fndecl, 1, name);
- stmt = build_gimple_modify_stmt (res, call);
+ stmt = gimple_build_call (fndecl, 1, name);
+ gimple_call_set_lhs (stmt, res);
+
def_stmt = SSA_NAME_DEF_STMT (name);
if (!SSA_NAME_IS_DEFAULT_DEF (name)
- && TREE_CODE (def_stmt) != PHI_NODE
- && bb_for_stmt (def_stmt) == top_bb)
+ && gimple_code (def_stmt) != GIMPLE_PHI
+ && gimple_bb (def_stmt) == top_bb)
{
- bsi = bsi_for_stmt (def_stmt);
- bsi_insert_after (&bsi, stmt, BSI_SAME_STMT);
+ gsi = gsi_for_stmt (def_stmt);
+ gsi_insert_after (&gsi, stmt, GSI_SAME_STMT);
}
else
{
- bsi = bsi_after_labels (top_bb);
- bsi_insert_before (&bsi, stmt, BSI_SAME_STMT);
+ gsi = gsi_after_labels (top_bb);
+ gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
}
update_stmt (stmt);
/* And adjust the recorded old call sites. */
- for (i = 0; VEC_iterate(tree, stmts, i, use_stmt); ++i)
+ for (i = 0; VEC_iterate(gimple, stmts, i, use_stmt); ++i)
{
- fndecl = get_callee_fndecl (GIMPLE_STMT_OPERAND (use_stmt, 1));
+ tree rhs = NULL;
+ fndecl = gimple_call_fndecl (use_stmt);
+
switch (DECL_FUNCTION_CODE (fndecl))
{
CASE_FLT_FN (BUILT_IN_COS):
- GIMPLE_STMT_OPERAND (use_stmt, 1) = fold_build1 (REALPART_EXPR,
- type, res);
+ rhs = fold_build1 (REALPART_EXPR, type, res);
break;
CASE_FLT_FN (BUILT_IN_SIN):
- GIMPLE_STMT_OPERAND (use_stmt, 1) = fold_build1 (IMAGPART_EXPR,
- type, res);
+ rhs = fold_build1 (IMAGPART_EXPR, type, res);
break;
CASE_FLT_FN (BUILT_IN_CEXPI):
- GIMPLE_STMT_OPERAND (use_stmt, 1) = res;
+ rhs = res;
break;
default:;
gcc_unreachable ();
}
- update_stmt (use_stmt);
+ /* Replace call with a copy. */
+ stmt = gimple_build_assign (gimple_call_lhs (use_stmt), rhs);
+
+ gsi = gsi_for_stmt (use_stmt);
+ gsi_insert_after (&gsi, stmt, GSI_SAME_STMT);
+ gsi_remove (&gsi, true);
}
- VEC_free(tree, heap, stmts);
+ VEC_free(gimple, heap, stmts);
}
/* Go through all calls to sin, cos and cexpi and call execute_cse_sincos_1
@@ -719,16 +721,16 @@ execute_cse_sincos (void)
FOR_EACH_BB (bb)
{
- block_stmt_iterator bsi;
+ gimple_stmt_iterator gsi;
- for (bsi = bsi_after_labels (bb); !bsi_end_p (bsi); bsi_next (&bsi))
+ for (gsi = gsi_after_labels (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
- tree stmt = bsi_stmt (bsi);
+ gimple stmt = gsi_stmt (gsi);
tree fndecl;
- if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT
- && TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 1)) == CALL_EXPR
- && (fndecl = get_callee_fndecl (GIMPLE_STMT_OPERAND (stmt, 1)))
+ if (is_gimple_call (stmt)
+ && gimple_call_lhs (stmt)
+ && (fndecl = gimple_call_fndecl (stmt))
&& DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
{
tree arg;
@@ -738,8 +740,7 @@ execute_cse_sincos (void)
CASE_FLT_FN (BUILT_IN_COS):
CASE_FLT_FN (BUILT_IN_SIN):
CASE_FLT_FN (BUILT_IN_CEXPI):
- arg = GIMPLE_STMT_OPERAND (stmt, 1);
- arg = CALL_EXPR_ARG (arg, 0);
+ arg = gimple_call_arg (stmt, 0);
if (TREE_CODE (arg) == SSA_NAME)
execute_cse_sincos_1 (arg);
break;
@@ -793,23 +794,23 @@ execute_convert_to_rsqrt (void)
FOR_EACH_BB (bb)
{
- block_stmt_iterator bsi;
+ gimple_stmt_iterator gsi;
- for (bsi = bsi_after_labels (bb); !bsi_end_p (bsi); bsi_next (&bsi))
+ for (gsi = gsi_after_labels (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
- tree stmt = bsi_stmt (bsi);
+ gimple stmt = gsi_stmt (gsi);
tree fndecl;
- if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT
- && TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 1)) == CALL_EXPR
- && (fndecl = get_callee_fndecl (GIMPLE_STMT_OPERAND (stmt, 1)))
+ if (is_gimple_call (stmt)
+ && gimple_call_lhs (stmt)
+ && (fndecl = gimple_call_fndecl (stmt))
&& (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
|| DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD))
{
enum built_in_function code;
bool md_code;
tree arg1;
- tree stmt1;
+ gimple stmt1;
code = DECL_FUNCTION_CODE (fndecl);
md_code = DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD;
@@ -818,30 +819,28 @@ execute_convert_to_rsqrt (void)
if (!fndecl)
continue;
- arg1 = CALL_EXPR_ARG (GIMPLE_STMT_OPERAND (stmt, 1), 0);
+ arg1 = gimple_call_arg (stmt, 0);
if (TREE_CODE (arg1) != SSA_NAME)
continue;
stmt1 = SSA_NAME_DEF_STMT (arg1);
- if (TREE_CODE (stmt1) == GIMPLE_MODIFY_STMT
- && TREE_CODE (GIMPLE_STMT_OPERAND (stmt1, 1)) == RDIV_EXPR)
+ if (is_gimple_assign (stmt1)
+ && gimple_assign_rhs_code (stmt1) == RDIV_EXPR)
{
tree arg10, arg11;
- tree tmp;
- arg10 = TREE_OPERAND (GIMPLE_STMT_OPERAND (stmt1, 1), 0);
- arg11 = TREE_OPERAND (GIMPLE_STMT_OPERAND (stmt1, 1), 1);
+ arg10 = gimple_assign_rhs1 (stmt1);
+ arg11 = gimple_assign_rhs2 (stmt1);
/* Swap operands of RDIV_EXPR. */
- TREE_OPERAND (GIMPLE_STMT_OPERAND (stmt1, 1), 0) = arg11;
- TREE_OPERAND (GIMPLE_STMT_OPERAND (stmt1, 1), 1) = arg10;
+ gimple_assign_set_rhs1 (stmt1, arg11);
+ gimple_assign_set_rhs2 (stmt1, arg10);
fold_stmt_inplace (stmt1);
update_stmt (stmt1);
- tmp = build_call_expr (fndecl, 1, arg1);
- GIMPLE_STMT_OPERAND (stmt, 1) = tmp;
+ gimple_call_set_fn (stmt, fndecl);
update_stmt (stmt);
}
}
diff --git a/gcc/tree-ssa-operands.c b/gcc/tree-ssa-operands.c
index 0aeea9f7f93..304df53863e 100644
--- a/gcc/tree-ssa-operands.c
+++ b/gcc/tree-ssa-operands.c
@@ -1,5 +1,6 @@
/* SSA operands management for trees.
- Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
+ Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008
+ Free Software Foundation, Inc.
This file is part of GCC.
@@ -74,6 +75,10 @@ along with GCC; see the file COPYING3. If not see
operand vector for VUSE, then the new vector will also be modified
such that it contains 'a_5' rather than 'a'. */
+/* Helper functions from gimple.c. These are GIMPLE manipulation
+ routines that only the operand scanner should need. */
+void gimple_set_stored_syms (gimple, bitmap, bitmap_obstack *);
+void gimple_set_loaded_syms (gimple, bitmap, bitmap_obstack *);
/* Structure storing statistics on how many call clobbers we have, and
how many where avoided. */
@@ -122,7 +127,7 @@ static struct
#define opf_no_vops (1 << 1)
/* Operand is an implicit reference. This is used to distinguish
- explicit assignments in the form of GIMPLE_MODIFY_STMT from
+ explicit assignments in the form of MODIFY_EXPR from
clobbering sites like function calls or ASM_EXPRs. */
#define opf_implicit (1 << 2)
@@ -148,7 +153,7 @@ static bitmap build_loads;
/* Set for building all the stored symbols. */
static bitmap build_stores;
-static void get_expr_operands (tree, tree *, int);
+static void get_expr_operands (gimple, tree *, int);
/* Number of functions with initialized ssa_operands. */
static int n_initialized = 0;
@@ -178,7 +183,7 @@ static int n_initialized = 0;
struct scb_d
{
/* Pointer to the statement being modified. */
- tree *stmt_p;
+ gimple *stmt_p;
/* If the statement references memory these are the sets of symbols
loaded and stored by the statement. */
@@ -256,12 +261,18 @@ operand_build_sort_virtual (VEC(tree,heap) *list)
operand_build_cmp);
}
-
/* Return true if the SSA operands cache is active. */
bool
ssa_operands_active (void)
{
+ /* This function may be invoked from contexts where CFUN is NULL
+ (IPA passes), return false for now. FIXME: operands may be
+ active in each individual function, maybe this function should
+ take CFUN as a parameter. */
+ if (cfun == NULL)
+ return false;
+
return cfun->gimple_df && gimple_ssa_operands (cfun)->ops_active;
}
@@ -430,6 +441,7 @@ fini_ssa_operands (void)
if (!n_initialized)
bitmap_obstack_release (&operands_bitmap_obstack);
+
if (dump_file && (dump_flags & TDF_STATS))
{
fprintf (dump_file, "Original clobbered vars: %d\n",
@@ -571,11 +583,11 @@ alloc_vop (int num)
sure the stmt pointer is set to the current stmt. */
static inline void
-set_virtual_use_link (use_operand_p ptr, tree stmt)
+set_virtual_use_link (use_operand_p ptr, gimple stmt)
{
/* fold_stmt may have changed the stmt pointers. */
- if (ptr->stmt != stmt)
- ptr->stmt = stmt;
+ if (ptr->loc.stmt != stmt)
+ ptr->loc.stmt = stmt;
/* If this use isn't in a list, add it to the correct list. */
if (!ptr->prev)
@@ -601,7 +613,7 @@ add_def_op (tree *op, def_optype_p last)
/* Adds OP to the list of uses of statement STMT after LAST. */
static inline use_optype_p
-add_use_op (tree stmt, tree *op, use_optype_p last)
+add_use_op (gimple stmt, tree *op, use_optype_p last)
{
use_optype_p new_use;
@@ -619,7 +631,7 @@ add_use_op (tree stmt, tree *op, use_optype_p last)
The new vop is appended after PREV. */
static inline voptype_p
-add_vop (tree stmt, tree op, int num, voptype_p prev)
+add_vop (gimple stmt, tree op, int num, voptype_p prev)
{
voptype_p new_vop;
int x;
@@ -645,7 +657,7 @@ add_vop (tree stmt, tree op, int num, voptype_p prev)
LAST to the new element. */
static inline voptype_p
-add_vuse_op (tree stmt, tree op, int num, voptype_p last)
+add_vuse_op (gimple stmt, tree op, int num, voptype_p last)
{
voptype_p new_vop = add_vop (stmt, op, num, last);
VDEF_RESULT (new_vop) = NULL_TREE;
@@ -657,7 +669,7 @@ add_vuse_op (tree stmt, tree op, int num, voptype_p last)
LAST to the new element. */
static inline voptype_p
-add_vdef_op (tree stmt, tree op, int num, voptype_p last)
+add_vdef_op (gimple stmt, tree op, int num, voptype_p last)
{
voptype_p new_vop = add_vop (stmt, op, num, last);
VDEF_RESULT (new_vop) = op;
@@ -669,7 +681,7 @@ add_vdef_op (tree stmt, tree op, int num, voptype_p last)
TODO -- Make build_defs VEC of tree *. */
static inline void
-finalize_ssa_defs (tree stmt)
+finalize_ssa_defs (gimple stmt)
{
unsigned new_i;
struct def_optype_d new_list;
@@ -677,12 +689,12 @@ finalize_ssa_defs (tree stmt)
unsigned int num = VEC_length (tree, build_defs);
/* There should only be a single real definition per assignment. */
- gcc_assert ((stmt && TREE_CODE (stmt) != GIMPLE_MODIFY_STMT) || num <= 1);
+ gcc_assert ((stmt && gimple_code (stmt) != GIMPLE_ASSIGN) || num <= 1);
new_list.next = NULL;
last = &new_list;
- old_ops = DEF_OPS (stmt);
+ old_ops = gimple_def_ops (stmt);
new_i = 0;
@@ -703,13 +715,13 @@ finalize_ssa_defs (tree stmt)
last = add_def_op ((tree *) VEC_index (tree, build_defs, new_i), last);
/* Now set the stmt's operands. */
- DEF_OPS (stmt) = new_list.next;
+ gimple_set_def_ops (stmt, new_list.next);
#ifdef ENABLE_CHECKING
{
def_optype_p ptr;
unsigned x = 0;
- for (ptr = DEF_OPS (stmt); ptr; ptr = ptr->next)
+ for (ptr = gimple_def_ops (stmt); ptr; ptr = ptr->next)
x++;
gcc_assert (x == num);
@@ -722,30 +734,16 @@ finalize_ssa_defs (tree stmt)
TODO -- Make build_uses VEC of tree *. */
static inline void
-finalize_ssa_uses (tree stmt)
+finalize_ssa_uses (gimple stmt)
{
unsigned new_i;
struct use_optype_d new_list;
use_optype_p old_ops, ptr, last;
-#ifdef ENABLE_CHECKING
- {
- unsigned x;
- unsigned num = VEC_length (tree, build_uses);
-
- /* If the pointer to the operand is the statement itself, something is
- wrong. It means that we are pointing to a local variable (the
- initial call to update_stmt_operands does not pass a pointer to a
- statement). */
- for (x = 0; x < num; x++)
- gcc_assert (*((tree *)VEC_index (tree, build_uses, x)) != stmt);
- }
-#endif
-
new_list.next = NULL;
last = &new_list;
- old_ops = USE_OPS (stmt);
+ old_ops = gimple_use_ops (stmt);
/* If there is anything in the old list, free it. */
if (old_ops)
@@ -763,12 +761,12 @@ finalize_ssa_uses (tree stmt)
last);
/* Now set the stmt's operands. */
- USE_OPS (stmt) = new_list.next;
+ gimple_set_use_ops (stmt, new_list.next);
#ifdef ENABLE_CHECKING
{
unsigned x = 0;
- for (ptr = USE_OPS (stmt); ptr; ptr = ptr->next)
+ for (ptr = gimple_use_ops (stmt); ptr; ptr = ptr->next)
x++;
gcc_assert (x == VEC_length (tree, build_uses));
@@ -778,27 +776,17 @@ finalize_ssa_uses (tree stmt)
/* Takes elements from BUILD_VDEFS and turns them into vdef operands of
- STMT. FIXME, for now VDEF operators should have a single operand
- in their RHS. */
+ STMT. */
static inline void
-finalize_ssa_vdefs (tree stmt)
+finalize_ssa_vdefs (gimple stmt)
{
unsigned new_i;
struct voptype_d new_list;
voptype_p old_ops, ptr, last;
- stmt_ann_t ann = stmt_ann (stmt);
/* Set the symbols referenced by STMT. */
- if (!bitmap_empty_p (build_stores))
- {
- if (ann->operands.stores == NULL)
- ann->operands.stores = BITMAP_ALLOC (&operands_bitmap_obstack);
-
- bitmap_copy (ann->operands.stores, build_stores);
- }
- else
- BITMAP_FREE (ann->operands.stores);
+ gimple_set_stored_syms (stmt, build_stores, &operands_bitmap_obstack);
/* If aliases have not been computed, do not instantiate a virtual
operator on STMT. Initially, we only compute the SSA form on
@@ -813,7 +801,7 @@ finalize_ssa_vdefs (tree stmt)
new_list.next = NULL;
last = &new_list;
- old_ops = VDEF_OPS (stmt);
+ old_ops = gimple_vdef_ops (stmt);
new_i = 0;
while (old_ops && new_i < VEC_length (tree, build_vdefs))
{
@@ -868,12 +856,12 @@ finalize_ssa_vdefs (tree stmt)
}
/* Now set STMT's operands. */
- VDEF_OPS (stmt) = new_list.next;
+ gimple_set_vdef_ops (stmt, new_list.next);
#ifdef ENABLE_CHECKING
{
unsigned x = 0;
- for (ptr = VDEF_OPS (stmt); ptr; ptr = ptr->next)
+ for (ptr = gimple_vdef_ops (stmt); ptr; ptr = ptr->next)
x++;
gcc_assert (x == VEC_length (tree, build_vdefs));
@@ -886,24 +874,14 @@ finalize_ssa_vdefs (tree stmt)
STMT. */
static inline void
-finalize_ssa_vuse_ops (tree stmt)
+finalize_ssa_vuse_ops (gimple stmt)
{
unsigned new_i, old_i;
voptype_p old_ops, last;
VEC(tree,heap) *new_ops;
- stmt_ann_t ann;
/* Set the symbols referenced by STMT. */
- ann = stmt_ann (stmt);
- if (!bitmap_empty_p (build_loads))
- {
- if (ann->operands.loads == NULL)
- ann->operands.loads = BITMAP_ALLOC (&operands_bitmap_obstack);
-
- bitmap_copy (ann->operands.loads, build_loads);
- }
- else
- BITMAP_FREE (ann->operands.loads);
+ gimple_set_loaded_syms (stmt, build_loads, &operands_bitmap_obstack);
/* If aliases have not been computed, do not instantiate a virtual
operator on STMT. Initially, we only compute the SSA form on
@@ -916,7 +894,7 @@ finalize_ssa_vuse_ops (tree stmt)
return;
/* STMT should have at most one VUSE operator. */
- old_ops = VUSE_OPS (stmt);
+ old_ops = gimple_vuse_ops (stmt);
gcc_assert (old_ops == NULL || old_ops->next == NULL);
new_ops = NULL;
@@ -961,7 +939,7 @@ finalize_ssa_vuse_ops (tree stmt)
for (old_i = 0; old_i < VUSE_NUM (old_ops); old_i++)
delink_imm_use (VUSE_OP_PTR (old_ops, old_i));
add_vop_to_freelist (old_ops);
- VUSE_OPS (stmt) = NULL;
+ gimple_set_vuse_ops (stmt, NULL);
}
/* If there are any operands, instantiate a VUSE operator for STMT. */
@@ -975,7 +953,7 @@ finalize_ssa_vuse_ops (tree stmt)
for (i = 0; VEC_iterate (tree, new_ops, i, op); i++)
SET_USE (VUSE_OP_PTR (last, (int) i), op);
- VUSE_OPS (stmt) = last;
+ gimple_set_vuse_ops (stmt, last);
VEC_free (tree, heap, new_ops);
}
@@ -983,10 +961,10 @@ finalize_ssa_vuse_ops (tree stmt)
{
unsigned x;
- if (VUSE_OPS (stmt))
+ if (gimple_vuse_ops (stmt))
{
- gcc_assert (VUSE_OPS (stmt)->next == NULL);
- x = VUSE_NUM (VUSE_OPS (stmt));
+ gcc_assert (gimple_vuse_ops (stmt)->next == NULL);
+ x = VUSE_NUM (gimple_vuse_ops (stmt));
}
else
x = 0;
@@ -999,7 +977,7 @@ finalize_ssa_vuse_ops (tree stmt)
/* Return a new VUSE operand vector for STMT. */
static void
-finalize_ssa_vuses (tree stmt)
+finalize_ssa_vuses (gimple stmt)
{
unsigned num, num_vdefs;
unsigned vuse_index;
@@ -1069,12 +1047,15 @@ cleanup_build_arrays (void)
/* Finalize all the build vectors, fill the new ones into INFO. */
static inline void
-finalize_ssa_stmt_operands (tree stmt)
+finalize_ssa_stmt_operands (gimple stmt)
{
finalize_ssa_defs (stmt);
finalize_ssa_uses (stmt);
- finalize_ssa_vdefs (stmt);
- finalize_ssa_vuses (stmt);
+ if (gimple_has_mem_ops (stmt))
+ {
+ finalize_ssa_vdefs (stmt);
+ finalize_ssa_vuses (stmt);
+ }
cleanup_build_arrays ();
}
@@ -1323,7 +1304,7 @@ access_can_touch_variable (tree ref, tree alias, HOST_WIDE_INT offset,
return true;
}
-/* Add VAR to the virtual operands array. FLAGS is as in
+/* Add VAR to the virtual operands for STMT. FLAGS is as in
get_expr_operands. FULL_REF is a tree that contains the entire
pointer dereference expression, if available, or NULL otherwise.
OFFSET and SIZE come from the memory access expression that
@@ -1331,7 +1312,7 @@ access_can_touch_variable (tree ref, tree alias, HOST_WIDE_INT offset,
affected statement is a call site. */
static void
-add_virtual_operand (tree var, stmt_ann_t s_ann, int flags,
+add_virtual_operand (tree var, gimple stmt, int flags,
tree full_ref, HOST_WIDE_INT offset,
HOST_WIDE_INT size, bool is_call_site)
{
@@ -1343,7 +1324,7 @@ add_virtual_operand (tree var, stmt_ann_t s_ann, int flags,
v_ann = var_ann (sym);
/* Mark the statement as having memory operands. */
- s_ann->references_memory = true;
+ gimple_set_references_memory (stmt, true);
/* If the variable cannot be modified and this is a VDEF change
it into a VUSE. This happens when read-only variables are marked
@@ -1351,7 +1332,7 @@ add_virtual_operand (tree var, stmt_ann_t s_ann, int flags,
check that this only happens on non-specific stores.
Note that if this is a specific store, i.e. associated with a
- GIMPLE_MODIFY_STMT, then we can't suppress the VDEF, lest we run
+ MODIFY_EXPR, then we can't suppress the VDEF, lest we run
into validation problems.
This can happen when programs cast away const, leaving us with a
@@ -1373,9 +1354,8 @@ add_virtual_operand (tree var, stmt_ann_t s_ann, int flags,
if (aliases == NULL)
{
- if (!gimple_aliases_computed_p (cfun)
- && (flags & opf_def))
- s_ann->has_volatile_ops = true;
+ if (!gimple_aliases_computed_p (cfun) && (flags & opf_def))
+ gimple_set_has_volatile_ops (stmt, true);
/* The variable is not aliased or it is an alias tag. */
if (flags & opf_def)
@@ -1449,18 +1429,18 @@ add_virtual_operand (tree var, stmt_ann_t s_ann, int flags,
}
-/* Add *VAR_P to the appropriate operand array for S_ANN. FLAGS is as in
- get_expr_operands. If *VAR_P is a GIMPLE register, it will be added to
- the statement's real operands, otherwise it is added to virtual
- operands. */
+/* Add *VAR_P to the appropriate operand array for statement STMT.
+ FLAGS is as in get_expr_operands. If *VAR_P is a GIMPLE register,
+ it will be added to the statement's real operands, otherwise it is
+ added to virtual operands. */
static void
-add_stmt_operand (tree *var_p, stmt_ann_t s_ann, int flags)
+add_stmt_operand (tree *var_p, gimple stmt, int flags)
{
tree var, sym;
var_ann_t v_ann;
- gcc_assert (SSA_VAR_P (*var_p) && s_ann);
+ gcc_assert (SSA_VAR_P (*var_p));
var = *var_p;
sym = (TREE_CODE (var) == SSA_NAME ? SSA_NAME_VAR (var) : var);
@@ -1468,7 +1448,7 @@ add_stmt_operand (tree *var_p, stmt_ann_t s_ann, int flags)
/* Mark statements with volatile operands. */
if (TREE_THIS_VOLATILE (sym))
- s_ann->has_volatile_ops = true;
+ gimple_set_has_volatile_ops (stmt, true);
if (is_gimple_reg (sym))
{
@@ -1479,7 +1459,7 @@ add_stmt_operand (tree *var_p, stmt_ann_t s_ann, int flags)
append_use (var_p);
}
else
- add_virtual_operand (var, s_ann, flags, NULL_TREE, 0, -1, false);
+ add_virtual_operand (var, stmt, flags, NULL_TREE, 0, -1, false);
}
/* Subroutine of get_indirect_ref_operands. ADDR is the address
@@ -1487,14 +1467,14 @@ add_stmt_operand (tree *var_p, stmt_ann_t s_ann, int flags)
is the same as in get_indirect_ref_operands. */
static void
-get_addr_dereference_operands (tree stmt, tree *addr, int flags, tree full_ref,
- HOST_WIDE_INT offset, HOST_WIDE_INT size,
- bool recurse_on_base)
+get_addr_dereference_operands (gimple stmt, tree *addr, int flags,
+ tree full_ref, HOST_WIDE_INT offset,
+ HOST_WIDE_INT size, bool recurse_on_base)
{
tree ptr = *addr;
- stmt_ann_t s_ann = stmt_ann (stmt);
- s_ann->references_memory = true;
+ /* Mark the statement as having memory operands. */
+ gimple_set_references_memory (stmt, true);
if (SSA_VAR_P (ptr))
{
@@ -1506,7 +1486,7 @@ get_addr_dereference_operands (tree stmt, tree *addr, int flags, tree full_ref,
&& pi->name_mem_tag)
{
/* PTR has its own memory tag. Use it. */
- add_virtual_operand (pi->name_mem_tag, s_ann, flags,
+ add_virtual_operand (pi->name_mem_tag, stmt, flags,
full_ref, offset, size, false);
}
else
@@ -1530,7 +1510,7 @@ get_addr_dereference_operands (tree stmt, tree *addr, int flags, tree full_ref,
"NOTE: no flow-sensitive alias info for ");
print_generic_expr (dump_file, ptr, dump_flags);
fprintf (dump_file, " in ");
- print_generic_stmt (dump_file, stmt, 0);
+ print_gimple_stmt (dump_file, stmt, 0, 0);
}
if (TREE_CODE (ptr) == SSA_NAME)
@@ -1542,7 +1522,7 @@ get_addr_dereference_operands (tree stmt, tree *addr, int flags, tree full_ref,
and size. */
if (v_ann->symbol_mem_tag)
{
- add_virtual_operand (v_ann->symbol_mem_tag, s_ann, flags,
+ add_virtual_operand (v_ann->symbol_mem_tag, stmt, flags,
full_ref, 0, -1, false);
/* Make sure we add the SMT itself. */
if (!(flags & opf_no_vops))
@@ -1558,7 +1538,7 @@ get_addr_dereference_operands (tree stmt, tree *addr, int flags, tree full_ref,
volatile so we won't optimize it out too actively. */
else if (!gimple_aliases_computed_p (cfun)
&& (flags & opf_def))
- s_ann->has_volatile_ops = true;
+ gimple_set_has_volatile_ops (stmt, true);
}
}
else if (TREE_CODE (ptr) == INTEGER_CST)
@@ -1566,7 +1546,7 @@ get_addr_dereference_operands (tree stmt, tree *addr, int flags, tree full_ref,
/* If a constant is used as a pointer, we can't generate a real
operand for it but we mark the statement volatile to prevent
optimizations from messing things up. */
- s_ann->has_volatile_ops = true;
+ gimple_set_has_volatile_ops (stmt, true);
return;
}
else
@@ -1600,15 +1580,14 @@ get_addr_dereference_operands (tree stmt, tree *addr, int flags, tree full_ref,
something else will do it for us. */
static void
-get_indirect_ref_operands (tree stmt, tree expr, int flags, tree full_ref,
+get_indirect_ref_operands (gimple stmt, tree expr, int flags, tree full_ref,
HOST_WIDE_INT offset, HOST_WIDE_INT size,
bool recurse_on_base)
{
tree *pptr = &TREE_OPERAND (expr, 0);
- stmt_ann_t s_ann = stmt_ann (stmt);
if (TREE_THIS_VOLATILE (expr))
- s_ann->has_volatile_ops = true;
+ gimple_set_has_volatile_ops (stmt, true);
get_addr_dereference_operands (stmt, pptr, flags, full_ref, offset, size,
recurse_on_base);
@@ -1618,26 +1597,25 @@ get_indirect_ref_operands (tree stmt, tree expr, int flags, tree full_ref,
/* A subroutine of get_expr_operands to handle TARGET_MEM_REF. */
static void
-get_tmr_operands (tree stmt, tree expr, int flags)
+get_tmr_operands (gimple stmt, tree expr, int flags)
{
tree tag;
- stmt_ann_t s_ann = stmt_ann (stmt);
- /* This statement references memory. */
- s_ann->references_memory = 1;
+ /* Mark the statement as having memory operands. */
+ gimple_set_references_memory (stmt, true);
/* First record the real operands. */
get_expr_operands (stmt, &TMR_BASE (expr), opf_use);
get_expr_operands (stmt, &TMR_INDEX (expr), opf_use);
if (TMR_SYMBOL (expr))
- add_to_addressable_set (TMR_SYMBOL (expr), &s_ann->addresses_taken);
+ gimple_add_to_addresses_taken (stmt, TMR_SYMBOL (expr));
tag = TMR_TAG (expr);
if (!tag)
{
/* Something weird, so ensure that we will be careful. */
- s_ann->has_volatile_ops = true;
+ gimple_set_has_volatile_ops (stmt, true);
return;
}
if (!MTAG_P (tag))
@@ -1646,7 +1624,7 @@ get_tmr_operands (tree stmt, tree expr, int flags)
return;
}
- add_virtual_operand (tag, s_ann, flags, expr, 0, -1, false);
+ add_virtual_operand (tag, stmt, flags, expr, 0, -1, false);
}
@@ -1654,21 +1632,19 @@ get_tmr_operands (tree stmt, tree expr, int flags)
clobbered variables in the function. */
static void
-add_call_clobber_ops (tree stmt, tree callee)
+add_call_clobber_ops (gimple stmt, tree callee ATTRIBUTE_UNUSED)
{
unsigned u;
bitmap_iterator bi;
- stmt_ann_t s_ann = stmt_ann (stmt);
bitmap not_read_b, not_written_b;
- tree call = get_call_expr_in (stmt);
- gcc_assert (!(call_expr_flags (call) & (ECF_PURE | ECF_CONST)));
+ gcc_assert (!(gimple_call_flags (stmt) & (ECF_PURE | ECF_CONST)));
/* If we created .GLOBAL_VAR earlier, just use it. */
if (gimple_global_var (cfun))
{
tree var = gimple_global_var (cfun);
- add_virtual_operand (var, s_ann, opf_def, NULL, 0, -1, true);
+ add_virtual_operand (var, stmt, opf_def, NULL, 0, -1, true);
return;
}
@@ -1676,7 +1652,8 @@ add_call_clobber_ops (tree stmt, tree callee)
set for each static if the call being processed does not read
or write that variable. */
not_read_b = callee ? ipa_reference_get_not_read_global (callee) : NULL;
- not_written_b = callee ? ipa_reference_get_not_written_global (callee) : NULL;
+ not_written_b = callee ? ipa_reference_get_not_written_global (callee) : NULL;
+
/* Add a VDEF operand for every call clobbered variable. */
EXECUTE_IF_SET_IN_BITMAP (gimple_call_clobbered_vars (cfun), 0, u, bi)
{
@@ -1702,12 +1679,12 @@ add_call_clobber_ops (tree stmt, tree callee)
{
clobber_stats.static_write_clobbers_avoided++;
if (!not_read)
- add_virtual_operand (var, s_ann, opf_use, NULL, 0, -1, true);
+ add_virtual_operand (var, stmt, opf_use, NULL, 0, -1, true);
else
clobber_stats.static_read_clobbers_avoided++;
}
else
- add_virtual_operand (var, s_ann, opf_def, NULL, 0, -1, true);
+ add_virtual_operand (var, stmt, opf_def, NULL, 0, -1, true);
}
}
@@ -1716,22 +1693,20 @@ add_call_clobber_ops (tree stmt, tree callee)
function. */
static void
-add_call_read_ops (tree stmt, tree callee)
+add_call_read_ops (gimple stmt, tree callee ATTRIBUTE_UNUSED)
{
unsigned u;
bitmap_iterator bi;
- stmt_ann_t s_ann = stmt_ann (stmt);
bitmap not_read_b;
- tree call = get_call_expr_in (stmt);
/* Const functions do not reference memory. */
- if (call_expr_flags (call) & ECF_CONST)
+ if (gimple_call_flags (stmt) & ECF_CONST)
return;
not_read_b = callee ? ipa_reference_get_not_read_global (callee) : NULL;
/* For pure functions we compute non-escaped uses separately. */
- if (call_expr_flags (call) & ECF_PURE)
+ if (gimple_call_flags (stmt) & ECF_PURE)
EXECUTE_IF_SET_IN_BITMAP (gimple_call_used_vars (cfun), 0, u, bi)
{
tree var = referenced_var_lookup (u);
@@ -1749,7 +1724,7 @@ add_call_read_ops (tree stmt, tree callee)
/* See if this variable is really used by this function. */
if (!not_read)
- add_virtual_operand (var, s_ann, opf_use, NULL, 0, -1, true);
+ add_virtual_operand (var, stmt, opf_use, NULL, 0, -1, true);
else
clobber_stats.static_readonly_clobbers_avoided++;
}
@@ -1760,7 +1735,7 @@ add_call_read_ops (tree stmt, tree callee)
if (gimple_global_var (cfun))
{
tree var = gimple_global_var (cfun);
- add_virtual_operand (var, s_ann, opf_use, NULL, 0, -1, true);
+ add_virtual_operand (var, stmt, opf_use, NULL, 0, -1, true);
return;
}
@@ -1782,67 +1757,55 @@ add_call_read_ops (tree stmt, tree callee)
continue;
}
- add_virtual_operand (var, s_ann, opf_use, NULL, 0, -1, true);
+ add_virtual_operand (var, stmt, opf_use, NULL, 0, -1, true);
}
}
-/* A subroutine of get_expr_operands to handle CALL_EXPR. */
+/* If STMT is a call that may clobber globals and other symbols that
+ escape, add them to the VDEF/VUSE lists for it. */
static void
-get_call_expr_operands (tree stmt, tree expr)
+maybe_add_call_clobbered_vops (gimple stmt)
{
- int call_flags = call_expr_flags (expr);
- int i, nargs;
- stmt_ann_t ann = stmt_ann (stmt);
+ int call_flags = gimple_call_flags (stmt);
- ann->references_memory = true;
+ /* Mark the statement as having memory operands. */
+ gimple_set_references_memory (stmt, true);
/* If aliases have been computed already, add VDEF or VUSE
operands for all the symbols that have been found to be
call-clobbered. */
- if (gimple_aliases_computed_p (cfun)
- && !(call_flags & ECF_NOVOPS))
+ if (gimple_aliases_computed_p (cfun) && !(call_flags & ECF_NOVOPS))
{
/* A 'pure' or a 'const' function never call-clobbers anything.
A 'noreturn' function might, but since we don't return anyway
there is no point in recording that. */
- if (TREE_SIDE_EFFECTS (expr)
- && !(call_flags & (ECF_PURE | ECF_CONST | ECF_NORETURN)))
- add_call_clobber_ops (stmt, get_callee_fndecl (expr));
+ if (!(call_flags & (ECF_PURE | ECF_CONST | ECF_NORETURN)))
+ add_call_clobber_ops (stmt, gimple_call_fndecl (stmt));
else if (!(call_flags & ECF_CONST))
- add_call_read_ops (stmt, get_callee_fndecl (expr));
+ add_call_read_ops (stmt, gimple_call_fndecl (stmt));
}
-
- /* Find uses in the called function. */
- get_expr_operands (stmt, &CALL_EXPR_FN (expr), opf_use);
- nargs = call_expr_nargs (expr);
- for (i = 0; i < nargs; i++)
- get_expr_operands (stmt, &CALL_EXPR_ARG (expr, i), opf_use);
-
- get_expr_operands (stmt, &CALL_EXPR_STATIC_CHAIN (expr), opf_use);
}
/* Scan operands in the ASM_EXPR stmt referred to in INFO. */
static void
-get_asm_expr_operands (tree stmt)
+get_asm_expr_operands (gimple stmt)
{
- stmt_ann_t s_ann;
- int i, noutputs;
+ size_t i, noutputs;
const char **oconstraints;
const char *constraint;
bool allows_mem, allows_reg, is_inout;
- tree link;
- s_ann = stmt_ann (stmt);
- noutputs = list_length (ASM_OUTPUTS (stmt));
+ noutputs = gimple_asm_noutputs (stmt);
oconstraints = (const char **) alloca ((noutputs) * sizeof (const char *));
/* Gather all output operands. */
- for (i = 0, link = ASM_OUTPUTS (stmt); link; i++, link = TREE_CHAIN (link))
+ for (i = 0; i < gimple_asm_noutputs (stmt); i++)
{
+ tree link = gimple_asm_output_op (stmt, i);
constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
oconstraints[i] = constraint;
parse_output_constraint (&constraint, i, 0, 0, &allows_mem,
@@ -1856,16 +1819,17 @@ get_asm_expr_operands (tree stmt)
if (!allows_reg && allows_mem)
{
tree t = get_base_address (TREE_VALUE (link));
- if (t && DECL_P (t) && s_ann)
- add_to_addressable_set (t, &s_ann->addresses_taken);
+ if (t && DECL_P (t))
+ gimple_add_to_addresses_taken (stmt, t);
}
get_expr_operands (stmt, &TREE_VALUE (link), opf_def);
}
/* Gather all input operands. */
- for (link = ASM_INPUTS (stmt); link; link = TREE_CHAIN (link))
+ for (i = 0; i < gimple_asm_ninputs (stmt); i++)
{
+ tree link = gimple_asm_input_op (stmt, i);
constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
parse_input_constraint (&constraint, 0, 0, noutputs, 0, oconstraints,
&allows_mem, &allows_reg);
@@ -1875,57 +1839,39 @@ get_asm_expr_operands (tree stmt)
if (!allows_reg && allows_mem)
{
tree t = get_base_address (TREE_VALUE (link));
- if (t && DECL_P (t) && s_ann)
- add_to_addressable_set (t, &s_ann->addresses_taken);
+ if (t && DECL_P (t))
+ gimple_add_to_addresses_taken (stmt, t);
}
get_expr_operands (stmt, &TREE_VALUE (link), 0);
}
/* Clobber all memory and addressable symbols for asm ("" : : : "memory"); */
- for (link = ASM_CLOBBERS (stmt); link; link = TREE_CHAIN (link))
- if (strcmp (TREE_STRING_POINTER (TREE_VALUE (link)), "memory") == 0)
- {
- unsigned i;
- bitmap_iterator bi;
-
- s_ann->references_memory = true;
-
- EXECUTE_IF_SET_IN_BITMAP (gimple_call_clobbered_vars (cfun), 0, i, bi)
- {
- tree var = referenced_var (i);
- add_stmt_operand (&var, s_ann, opf_def | opf_implicit);
- }
-
- EXECUTE_IF_SET_IN_BITMAP (gimple_addressable_vars (cfun), 0, i, bi)
- {
- tree var = referenced_var (i);
- add_stmt_operand (&var, s_ann, opf_def | opf_implicit);
- }
- break;
- }
-}
-
-
-/* Scan operands for the assignment expression EXPR in statement STMT. */
-
-static void
-get_modify_stmt_operands (tree stmt, tree expr)
-{
- /* First get operands from the RHS. */
- get_expr_operands (stmt, &GIMPLE_STMT_OPERAND (expr, 1), opf_use);
+ for (i = 0; i < gimple_asm_nclobbers (stmt); i++)
+ {
+ tree link = gimple_asm_clobber_op (stmt, i);
+ if (strcmp (TREE_STRING_POINTER (TREE_VALUE (link)), "memory") == 0)
+ {
+ unsigned i;
+ bitmap_iterator bi;
- /* For the LHS, use a regular definition (opf_def) for GIMPLE
- registers. If the LHS is a store to memory, we will need
- a preserving definition (VDEF).
+ /* Mark the statement as having memory operands. */
+ gimple_set_references_memory (stmt, true);
- Preserving definitions are those that modify a part of an
- aggregate object. Stores through a pointer are also represented
- with VDEF operators.
+ EXECUTE_IF_SET_IN_BITMAP (gimple_call_clobbered_vars (cfun), 0, i, bi)
+ {
+ tree var = referenced_var (i);
+ add_stmt_operand (&var, stmt, opf_def | opf_implicit);
+ }
- We used to distinguish between preserving and killing definitions.
- We always emit preserving definitions now. */
- get_expr_operands (stmt, &GIMPLE_STMT_OPERAND (expr, 0), opf_def);
+ EXECUTE_IF_SET_IN_BITMAP (gimple_addressable_vars (cfun), 0, i, bi)
+ {
+ tree var = referenced_var (i);
+ add_stmt_operand (&var, stmt, opf_def | opf_implicit);
+ }
+ break;
+ }
+ }
}
@@ -1934,12 +1880,11 @@ get_modify_stmt_operands (tree stmt, tree expr)
interpret the operands found. */
static void
-get_expr_operands (tree stmt, tree *expr_p, int flags)
+get_expr_operands (gimple stmt, tree *expr_p, int flags)
{
enum tree_code code;
enum tree_code_class codeclass;
tree expr = *expr_p;
- stmt_ann_t s_ann = stmt_ann (stmt);
if (expr == NULL)
return;
@@ -1954,7 +1899,7 @@ get_expr_operands (tree stmt, tree *expr_p, int flags)
reference to it, but the fact that the statement takes its
address will be of interest to some passes (e.g. alias
resolution). */
- add_to_addressable_set (TREE_OPERAND (expr, 0), &s_ann->addresses_taken);
+ gimple_add_to_addresses_taken (stmt, TREE_OPERAND (expr, 0));
/* If the address is invariant, there may be no interesting
variable references inside. */
@@ -1973,13 +1918,13 @@ get_expr_operands (tree stmt, tree *expr_p, int flags)
case SSA_NAME:
case SYMBOL_MEMORY_TAG:
case NAME_MEMORY_TAG:
- add_stmt_operand (expr_p, s_ann, flags);
+ add_stmt_operand (expr_p, stmt, flags);
return;
case VAR_DECL:
case PARM_DECL:
case RESULT_DECL:
- add_stmt_operand (expr_p, s_ann, flags);
+ add_stmt_operand (expr_p, stmt, flags);
return;
case MISALIGNED_INDIRECT_REF:
@@ -2005,7 +1950,7 @@ get_expr_operands (tree stmt, tree *expr_p, int flags)
HOST_WIDE_INT offset, size, maxsize;
if (TREE_THIS_VOLATILE (expr))
- s_ann->has_volatile_ops = true;
+ gimple_set_has_volatile_ops (stmt, true);
ref = get_ref_base_and_extent (expr, &offset, &size, &maxsize);
if (TREE_CODE (ref) == INDIRECT_REF)
@@ -2020,7 +1965,7 @@ get_expr_operands (tree stmt, tree *expr_p, int flags)
if (code == COMPONENT_REF)
{
if (TREE_THIS_VOLATILE (TREE_OPERAND (expr, 1)))
- s_ann->has_volatile_ops = true;
+ gimple_set_has_volatile_ops (stmt, true);
get_expr_operands (stmt, &TREE_OPERAND (expr, 2), opf_use);
}
else if (code == ARRAY_REF || code == ARRAY_RANGE_REF)
@@ -2040,10 +1985,6 @@ get_expr_operands (tree stmt, tree *expr_p, int flags)
get_expr_operands (stmt, &TREE_OPERAND (expr, 0), flags);
return;
- case CALL_EXPR:
- get_call_expr_operands (stmt, expr);
- return;
-
case COND_EXPR:
case VEC_COND_EXPR:
get_expr_operands (stmt, &TREE_OPERAND (expr, 0), opf_use);
@@ -2051,10 +1992,6 @@ get_expr_operands (tree stmt, tree *expr_p, int flags)
get_expr_operands (stmt, &TREE_OPERAND (expr, 2), opf_use);
return;
- case GIMPLE_MODIFY_STMT:
- get_modify_stmt_operands (stmt, expr);
- return;
-
case CONSTRUCTOR:
{
/* General aggregate CONSTRUCTORs have been decomposed, but they
@@ -2100,101 +2037,14 @@ get_expr_operands (tree stmt, tree *expr_p, int flags)
}
case CHANGE_DYNAMIC_TYPE_EXPR:
- get_expr_operands (stmt, &CHANGE_DYNAMIC_TYPE_LOCATION (expr), opf_use);
- return;
-
- case OMP_FOR:
- {
- tree c, clauses = OMP_FOR_CLAUSES (stmt);
- int i;
-
- for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (expr)); i++)
- {
- tree init = TREE_VEC_ELT (OMP_FOR_INIT (expr), i);
- tree cond = TREE_VEC_ELT (OMP_FOR_COND (expr), i);
- tree incr = TREE_VEC_ELT (OMP_FOR_INCR (expr), i);
-
- get_expr_operands (stmt, &GIMPLE_STMT_OPERAND (init, 0), opf_def);
- get_expr_operands (stmt, &GIMPLE_STMT_OPERAND (init, 1), opf_use);
- get_expr_operands (stmt, &TREE_OPERAND (cond, 1), opf_use);
- get_expr_operands (stmt,
- &TREE_OPERAND (GIMPLE_STMT_OPERAND (incr, 1),
- 1), opf_use);
- }
-
- c = find_omp_clause (clauses, OMP_CLAUSE_SCHEDULE);
- if (c)
- get_expr_operands (stmt, &OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c),
- opf_use);
- return;
- }
-
- case OMP_CONTINUE:
- {
- get_expr_operands (stmt, &TREE_OPERAND (expr, 0), opf_def);
- get_expr_operands (stmt, &TREE_OPERAND (expr, 1), opf_use);
- return;
- }
-
- case OMP_PARALLEL:
- {
- tree c, clauses = OMP_PARALLEL_CLAUSES (stmt);
-
- if (OMP_PARALLEL_DATA_ARG (stmt))
- {
- get_expr_operands (stmt, &OMP_PARALLEL_DATA_ARG (stmt), opf_use);
- add_to_addressable_set (OMP_PARALLEL_DATA_ARG (stmt),
- &s_ann->addresses_taken);
- }
-
- c = find_omp_clause (clauses, OMP_CLAUSE_IF);
- if (c)
- get_expr_operands (stmt, &OMP_CLAUSE_IF_EXPR (c), opf_use);
- c = find_omp_clause (clauses, OMP_CLAUSE_NUM_THREADS);
- if (c)
- get_expr_operands (stmt, &OMP_CLAUSE_NUM_THREADS_EXPR (c), opf_use);
- return;
- }
-
- case OMP_SECTIONS:
- {
- get_expr_operands (stmt, &OMP_SECTIONS_CONTROL (expr), opf_def);
- return;
- }
-
- case OMP_ATOMIC_LOAD:
- {
- tree *addr = &TREE_OPERAND (expr, 1);
- get_expr_operands (stmt, &TREE_OPERAND (expr, 0), opf_def);
-
- if (TREE_CODE (*addr) == ADDR_EXPR)
- get_expr_operands (stmt, &TREE_OPERAND (*addr, 0), opf_def);
- else
- get_addr_dereference_operands (stmt, addr, opf_def,
- NULL_TREE, 0, -1, true);
- return;
- }
-
- case OMP_ATOMIC_STORE:
- {
- get_expr_operands (stmt, &TREE_OPERAND (expr, 0), opf_use);
- return;
- }
+ gcc_unreachable ();
- case BLOCK:
case FUNCTION_DECL:
- case EXC_PTR_EXPR:
- case FILTER_EXPR:
case LABEL_DECL:
case CONST_DECL:
- case OMP_SINGLE:
- case OMP_MASTER:
- case OMP_ORDERED:
- case OMP_CRITICAL:
- case OMP_RETURN:
- case OMP_SECTION:
- case OMP_SECTIONS_SWITCH:
- case PREDICT_EXPR:
+ case CASE_LABEL_EXPR:
+ case FILTER_EXPR:
+ case EXC_PTR_EXPR:
/* Expressions that make no memory references. */
return;
@@ -2221,59 +2071,28 @@ get_expr_operands (tree stmt, tree *expr_p, int flags)
build_* operand vectors will have potential operands in them. */
static void
-parse_ssa_operands (tree stmt)
+parse_ssa_operands (gimple stmt)
{
- enum tree_code code;
+ enum gimple_code code = gimple_code (stmt);
- code = TREE_CODE (stmt);
- switch (code)
+ if (code == GIMPLE_ASM)
+ get_asm_expr_operands (stmt);
+ else
{
- case GIMPLE_MODIFY_STMT:
- get_modify_stmt_operands (stmt, stmt);
- break;
-
- case COND_EXPR:
- get_expr_operands (stmt, &COND_EXPR_COND (stmt), opf_use);
- break;
-
- case SWITCH_EXPR:
- get_expr_operands (stmt, &SWITCH_COND (stmt), opf_use);
- break;
-
- case ASM_EXPR:
- get_asm_expr_operands (stmt);
- break;
-
- case RETURN_EXPR:
- get_expr_operands (stmt, &TREE_OPERAND (stmt, 0), opf_use);
- break;
-
- case GOTO_EXPR:
- get_expr_operands (stmt, &GOTO_DESTINATION (stmt), opf_use);
- break;
+ size_t i, start = 0;
- case LABEL_EXPR:
- get_expr_operands (stmt, &LABEL_EXPR_LABEL (stmt), opf_use);
- break;
+ if (code == GIMPLE_ASSIGN || code == GIMPLE_CALL)
+ {
+ get_expr_operands (stmt, gimple_op_ptr (stmt, 0), opf_def);
+ start = 1;
+ }
- case BIND_EXPR:
- case CASE_LABEL_EXPR:
- case TRY_CATCH_EXPR:
- case TRY_FINALLY_EXPR:
- case EH_FILTER_EXPR:
- case CATCH_EXPR:
- case RESX_EXPR:
- /* These nodes contain no variable references. */
- break;
+ for (i = start; i < gimple_num_ops (stmt); i++)
+ get_expr_operands (stmt, gimple_op_ptr (stmt, i), opf_use);
- default:
- /* Notice that if get_expr_operands tries to use &STMT as the
- operand pointer (which may only happen for USE operands), we
- will fail in add_stmt_operand. This default will handle
- statements like empty statements, or CALL_EXPRs that may
- appear on the RHS of a statement or as statements themselves. */
- get_expr_operands (stmt, &stmt, opf_use);
- break;
+ /* Add call-clobbered operands, if needed. */
+ if (code == GIMPLE_CALL)
+ maybe_add_call_clobbered_vops (stmt);
}
}
@@ -2281,17 +2100,16 @@ parse_ssa_operands (tree stmt)
/* Create an operands cache for STMT. */
static void
-build_ssa_operands (tree stmt)
+build_ssa_operands (gimple stmt)
{
- stmt_ann_t ann = get_stmt_ann (stmt);
-
/* Initially assume that the statement has no volatile operands and
makes no memory references. */
- ann->has_volatile_ops = false;
- ann->references_memory = false;
+ gimple_set_has_volatile_ops (stmt, false);
+ gimple_set_references_memory (stmt, false);
+
/* Just clear the bitmap so we don't end up reallocating it over and over. */
- if (ann->addresses_taken)
- bitmap_clear (ann->addresses_taken);
+ if (gimple_addresses_taken (stmt))
+ bitmap_clear (gimple_addresses_taken (stmt));
start_ssa_stmt_operands ();
parse_ssa_operands (stmt);
@@ -2299,13 +2117,10 @@ build_ssa_operands (tree stmt)
operand_build_sort_virtual (build_vdefs);
finalize_ssa_stmt_operands (stmt);
- if (ann->addresses_taken && bitmap_empty_p (ann->addresses_taken))
- ann->addresses_taken = NULL;
-
/* For added safety, assume that statements with volatile operands
also reference memory. */
- if (ann->has_volatile_ops)
- ann->references_memory = true;
+ if (gimple_has_volatile_ops (stmt))
+ gimple_set_references_memory (stmt, true);
}
@@ -2313,12 +2128,12 @@ build_ssa_operands (tree stmt)
the stmt operand lists. */
void
-free_stmt_operands (tree stmt)
+free_stmt_operands (gimple stmt)
{
- def_optype_p defs = DEF_OPS (stmt), last_def;
- use_optype_p uses = USE_OPS (stmt), last_use;
- voptype_p vuses = VUSE_OPS (stmt);
- voptype_p vdefs = VDEF_OPS (stmt), vdef, next_vdef;
+ def_optype_p defs = gimple_def_ops (stmt), last_def;
+ use_optype_p uses = gimple_use_ops (stmt), last_use;
+ voptype_p vuses = gimple_vuse_ops (stmt);
+ voptype_p vdefs = gimple_vdef_ops (stmt), vdef, next_vdef;
unsigned i;
if (defs)
@@ -2327,7 +2142,7 @@ free_stmt_operands (tree stmt)
continue;
last_def->next = gimple_ssa_operands (cfun)->free_defs;
gimple_ssa_operands (cfun)->free_defs = defs;
- DEF_OPS (stmt) = NULL;
+ gimple_set_def_ops (stmt, NULL);
}
if (uses)
@@ -2337,7 +2152,7 @@ free_stmt_operands (tree stmt)
delink_imm_use (USE_OP_PTR (last_use));
last_use->next = gimple_ssa_operands (cfun)->free_uses;
gimple_ssa_operands (cfun)->free_uses = uses;
- USE_OPS (stmt) = NULL;
+ gimple_set_use_ops (stmt, NULL);
}
if (vuses)
@@ -2345,7 +2160,7 @@ free_stmt_operands (tree stmt)
for (i = 0; i < VUSE_NUM (vuses); i++)
delink_imm_use (VUSE_OP_PTR (vuses, i));
add_vop_to_freelist (vuses);
- VUSE_OPS (stmt) = NULL;
+ gimple_set_vuse_ops (stmt, NULL);
}
if (vdefs)
@@ -2356,46 +2171,35 @@ free_stmt_operands (tree stmt)
delink_imm_use (VDEF_OP_PTR (vdef, 0));
add_vop_to_freelist (vdef);
}
- VDEF_OPS (stmt) = NULL;
+ gimple_set_vdef_ops (stmt, NULL);
}
-}
-
-/* Free any operands vectors in OPS. */
+ if (gimple_has_ops (stmt))
+ gimple_set_addresses_taken (stmt, NULL);
-void
-free_ssa_operands (stmt_operands_p ops)
-{
- ops->def_ops = NULL;
- ops->use_ops = NULL;
- ops->vdef_ops = NULL;
- ops->vuse_ops = NULL;
- BITMAP_FREE (ops->loads);
- BITMAP_FREE (ops->stores);
+ if (gimple_has_mem_ops (stmt))
+ {
+ gimple_set_stored_syms (stmt, NULL, &operands_bitmap_obstack);
+ gimple_set_loaded_syms (stmt, NULL, &operands_bitmap_obstack);
+ }
}
/* Get the operands of statement STMT. */
void
-update_stmt_operands (tree stmt)
+update_stmt_operands (gimple stmt)
{
- stmt_ann_t ann = get_stmt_ann (stmt);
-
/* If update_stmt_operands is called before SSA is initialized, do
nothing. */
if (!ssa_operands_active ())
return;
- /* The optimizers cannot handle statements that are nothing but a
- _DECL. This indicates a bug in the gimplifier. */
- gcc_assert (!SSA_VAR_P (stmt));
-
timevar_push (TV_TREE_OPS);
- gcc_assert (ann->modified);
+ gcc_assert (gimple_modified_p (stmt));
build_ssa_operands (stmt);
- ann->modified = 0;
+ gimple_set_modified (stmt, false);
timevar_pop (TV_TREE_OPS);
}
@@ -2404,50 +2208,45 @@ update_stmt_operands (tree stmt)
/* Copies virtual operands from SRC to DST. */
void
-copy_virtual_operands (tree dest, tree src)
+copy_virtual_operands (gimple dest, gimple src)
{
unsigned int i, n;
voptype_p src_vuses, dest_vuses;
voptype_p src_vdefs, dest_vdefs;
struct voptype_d vuse;
struct voptype_d vdef;
- stmt_ann_t dest_ann;
- VDEF_OPS (dest) = NULL;
- VUSE_OPS (dest) = NULL;
+ if (!gimple_has_mem_ops (src))
+ return;
- dest_ann = get_stmt_ann (dest);
- BITMAP_FREE (dest_ann->operands.loads);
- BITMAP_FREE (dest_ann->operands.stores);
+ gimple_set_vdef_ops (dest, NULL);
+ gimple_set_vuse_ops (dest, NULL);
- if (LOADED_SYMS (src))
- {
- dest_ann->operands.loads = BITMAP_ALLOC (&operands_bitmap_obstack);
- bitmap_copy (dest_ann->operands.loads, LOADED_SYMS (src));
- }
-
- if (STORED_SYMS (src))
- {
- dest_ann->operands.stores = BITMAP_ALLOC (&operands_bitmap_obstack);
- bitmap_copy (dest_ann->operands.stores, STORED_SYMS (src));
- }
+ gimple_set_stored_syms (dest, gimple_stored_syms (src),
+ &operands_bitmap_obstack);
+ gimple_set_loaded_syms (dest, gimple_loaded_syms (src),
+ &operands_bitmap_obstack);
/* Copy all the VUSE operators and corresponding operands. */
dest_vuses = &vuse;
- for (src_vuses = VUSE_OPS (src); src_vuses; src_vuses = src_vuses->next)
+ for (src_vuses = gimple_vuse_ops (src);
+ src_vuses;
+ src_vuses = src_vuses->next)
{
n = VUSE_NUM (src_vuses);
dest_vuses = add_vuse_op (dest, NULL_TREE, n, dest_vuses);
for (i = 0; i < n; i++)
SET_USE (VUSE_OP_PTR (dest_vuses, i), VUSE_OP (src_vuses, i));
- if (VUSE_OPS (dest) == NULL)
- VUSE_OPS (dest) = vuse.next;
+ if (gimple_vuse_ops (dest) == NULL)
+ gimple_set_vuse_ops (dest, vuse.next);
}
/* Copy all the VDEF operators and corresponding operands. */
dest_vdefs = &vdef;
- for (src_vdefs = VDEF_OPS (src); src_vdefs; src_vdefs = src_vdefs->next)
+ for (src_vdefs = gimple_vdef_ops (src);
+ src_vdefs;
+ src_vdefs = src_vdefs->next)
{
n = VUSE_NUM (src_vdefs);
dest_vdefs = add_vdef_op (dest, NULL_TREE, n, dest_vdefs);
@@ -2455,8 +2254,8 @@ copy_virtual_operands (tree dest, tree src)
for (i = 0; i < n; i++)
SET_USE (VUSE_OP_PTR (dest_vdefs, i), VUSE_OP (src_vdefs, i));
- if (VDEF_OPS (dest) == NULL)
- VDEF_OPS (dest) = vdef.next;
+ if (gimple_vdef_ops (dest) == NULL)
+ gimple_set_vdef_ops (dest, vdef.next);
}
}
@@ -2469,19 +2268,15 @@ copy_virtual_operands (tree dest, tree src)
uses of this stmt will be de-linked. */
void
-create_ssa_artificial_load_stmt (tree new_stmt, tree old_stmt,
+create_ssa_artificial_load_stmt (gimple new_stmt, gimple old_stmt,
bool delink_imm_uses_p)
{
tree op;
ssa_op_iter iter;
use_operand_p use_p;
unsigned i;
- stmt_ann_t ann;
- /* Create the stmt annotation but make sure to not mark the stmt
- as modified as we will build operands ourselves. */
- ann = get_stmt_ann (new_stmt);
- ann->modified = 0;
+ gimple_set_modified (new_stmt, false);
/* Process NEW_STMT looking for operands. */
start_ssa_stmt_operands ();
@@ -2521,7 +2316,7 @@ create_ssa_artificial_load_stmt (tree new_stmt, tree old_stmt,
to test the validity of the swap operation. */
void
-swap_tree_operands (tree stmt, tree *exp0, tree *exp1)
+swap_tree_operands (gimple stmt, tree *exp0, tree *exp1)
{
tree op0, op1;
op0 = *exp0;
@@ -2536,14 +2331,14 @@ swap_tree_operands (tree stmt, tree *exp0, tree *exp1)
use0 = use1 = NULL;
/* Find the 2 operands in the cache, if they are there. */
- for (ptr = USE_OPS (stmt); ptr; ptr = ptr->next)
+ for (ptr = gimple_use_ops (stmt); ptr; ptr = ptr->next)
if (USE_OP_PTR (ptr)->use == exp0)
{
use0 = ptr;
break;
}
- for (ptr = USE_OPS (stmt); ptr; ptr = ptr->next)
+ for (ptr = gimple_use_ops (stmt); ptr; ptr = ptr->next)
if (USE_OP_PTR (ptr)->use == exp1)
{
use1 = ptr;
@@ -2565,19 +2360,13 @@ swap_tree_operands (tree stmt, tree *exp0, tree *exp1)
*exp1 = op0;
}
-
-/* Add the base address of REF to the set *ADDRESSES_TAKEN. If
- *ADDRESSES_TAKEN is NULL, a new set is created. REF may be
- a single variable whose address has been taken or any other valid
- GIMPLE memory reference (structure reference, array, etc). */
+/* Add the base address of REF to SET. */
void
-add_to_addressable_set (tree ref, bitmap *addresses_taken)
+add_to_addressable_set (tree ref, bitmap *set)
{
tree var;
- gcc_assert (addresses_taken);
-
/* Note that it is *NOT OKAY* to use the target of a COMPONENT_REF
as the only thing we take the address of. If VAR is a structure,
taking the address of a field means that the whole structure may
@@ -2586,14 +2375,29 @@ add_to_addressable_set (tree ref, bitmap *addresses_taken)
var = get_base_address (ref);
if (var && SSA_VAR_P (var))
{
- if (*addresses_taken == NULL)
- *addresses_taken = BITMAP_GGC_ALLOC ();
- bitmap_set_bit (*addresses_taken, DECL_UID (var));
+ if (*set == NULL)
+ *set = BITMAP_ALLOC (&operands_bitmap_obstack);
+
+ bitmap_set_bit (*set, DECL_UID (var));
TREE_ADDRESSABLE (var) = 1;
}
}
+/* Add the base address of REF to the set of addresses taken by STMT.
+ REF may be a single variable whose address has been taken or any
+ other valid GIMPLE memory reference (structure reference, array,
+ etc). If the base address of REF is a decl that has sub-variables,
+ also add all of its sub-variables. */
+
+void
+gimple_add_to_addresses_taken (gimple stmt, tree ref)
+{
+ gcc_assert (gimple_has_ops (stmt));
+ add_to_addressable_set (ref, gimple_addresses_taken_ptr (stmt));
+}
+
+
/* Scan the immediate_use list for VAR making sure its linked properly.
Return TRUE if there is a problem and emit an error message to F. */
@@ -2653,10 +2457,10 @@ verify_imm_links (FILE *f, tree var)
return false;
error:
- if (ptr->stmt && stmt_modified_p (ptr->stmt))
+ if (ptr->loc.stmt && gimple_modified_p (ptr->loc.stmt))
{
- fprintf (f, " STMT MODIFIED. - <%p> ", (void *)ptr->stmt);
- print_generic_stmt (f, ptr->stmt, TDF_SLIM);
+ fprintf (f, " STMT MODIFIED. - <%p> ", (void *)ptr->loc.stmt);
+ print_gimple_stmt (f, ptr->loc.stmt, 0, TDF_SLIM);
}
fprintf (f, " IMM ERROR : (use_p : tree - %p:%p)", (void *)ptr,
(void *)ptr->use);
@@ -2688,13 +2492,13 @@ dump_immediate_uses_for (FILE *file, tree var)
FOR_EACH_IMM_USE_FAST (use_p, iter, var)
{
- if (use_p->stmt == NULL && use_p->use == NULL)
+ if (use_p->loc.stmt == NULL && use_p->use == NULL)
fprintf (file, "***end of stmt iterator marker***\n");
else
if (!is_gimple_reg (USE_FROM_PTR (use_p)))
- print_generic_stmt (file, USE_STMT (use_p), TDF_VOPS|TDF_MEMSYMS);
+ print_gimple_stmt (file, USE_STMT (use_p), 0, TDF_VOPS|TDF_MEMSYMS);
else
- print_generic_stmt (file, USE_STMT (use_p), TDF_SLIM);
+ print_gimple_stmt (file, USE_STMT (use_p), 0, TDF_SLIM);
}
fprintf(file, "\n");
}
@@ -2745,15 +2549,15 @@ debug_immediate_uses_for (tree var)
needed to keep the SSA form up to date. */
void
-push_stmt_changes (tree *stmt_p)
+push_stmt_changes (gimple *stmt_p)
{
- tree stmt;
+ gimple stmt;
scb_t buf;
-
+
stmt = *stmt_p;
/* It makes no sense to keep track of PHI nodes. */
- if (TREE_CODE (stmt) == PHI_NODE)
+ if (gimple_code (stmt) == GIMPLE_PHI)
return;
buf = XNEW (struct scb_d);
@@ -2761,7 +2565,7 @@ push_stmt_changes (tree *stmt_p)
buf->stmt_p = stmt_p;
- if (stmt_references_memory_p (stmt))
+ if (gimple_references_memory_p (stmt))
{
tree op;
ssa_op_iter i;
@@ -2815,9 +2619,10 @@ mark_difference_for_renaming (bitmap s1, bitmap s2)
the statement. */
void
-pop_stmt_changes (tree *stmt_p)
+pop_stmt_changes (gimple *stmt_p)
{
- tree op, stmt;
+ tree op;
+ gimple stmt;
ssa_op_iter iter;
bitmap loads, stores;
scb_t buf;
@@ -2825,7 +2630,7 @@ pop_stmt_changes (tree *stmt_p)
stmt = *stmt_p;
/* It makes no sense to keep track of PHI nodes. */
- if (TREE_CODE (stmt) == PHI_NODE)
+ if (gimple_code (stmt) == GIMPLE_PHI)
return;
buf = VEC_pop (scb_t, scb_stack);
@@ -2843,7 +2648,7 @@ pop_stmt_changes (tree *stmt_p)
memory anymore, but we still need to act on the differences in
the sets of symbols. */
loads = stores = NULL;
- if (stmt_references_memory_p (stmt))
+ if (gimple_references_memory_p (stmt))
{
tree op;
ssa_op_iter i;
@@ -2906,14 +2711,14 @@ pop_stmt_changes (tree *stmt_p)
statement. It avoids the expensive operand re-scan. */
void
-discard_stmt_changes (tree *stmt_p)
+discard_stmt_changes (gimple *stmt_p)
{
scb_t buf;
- tree stmt;
+ gimple stmt;
/* It makes no sense to keep track of PHI nodes. */
stmt = *stmt_p;
- if (TREE_CODE (stmt) == PHI_NODE)
+ if (gimple_code (stmt) == GIMPLE_PHI)
return;
buf = VEC_pop (scb_t, scb_stack);
@@ -2925,15 +2730,3 @@ discard_stmt_changes (tree *stmt_p)
buf->stmt_p = NULL;
free (buf);
}
-
-
-/* Returns true if statement STMT may access memory. */
-
-bool
-stmt_references_memory_p (tree stmt)
-{
- if (!gimple_ssa_operands (cfun)->ops_active || TREE_CODE (stmt) == PHI_NODE)
- return false;
-
- return stmt_ann (stmt)->references_memory;
-}
diff --git a/gcc/tree-ssa-operands.h b/gcc/tree-ssa-operands.h
index ba9793d8346..cdbc050b579 100644
--- a/gcc/tree-ssa-operands.h
+++ b/gcc/tree-ssa-operands.h
@@ -157,15 +157,7 @@ typedef struct stmt_operands_d *stmt_operands_p;
#define SET_USE(USE, V) set_ssa_use_from_ptr (USE, V)
#define SET_DEF(DEF, V) ((*(DEF)) = (V))
-#define USE_STMT(USE) (USE)->stmt
-
-#define DEF_OPS(STMT) (stmt_ann (STMT)->operands.def_ops)
-#define USE_OPS(STMT) (stmt_ann (STMT)->operands.use_ops)
-#define VUSE_OPS(STMT) (stmt_ann (STMT)->operands.vuse_ops)
-#define VDEF_OPS(STMT) (stmt_ann (STMT)->operands.vdef_ops)
-
-#define LOADED_SYMS(STMT) (stmt_ann (STMT)->operands.loads)
-#define STORED_SYMS(STMT) (stmt_ann (STMT)->operands.stores)
+#define USE_STMT(USE) (USE)->loc.stmt
#define USE_OP_PTR(OP) (&((OP)->use_ptr))
#define USE_OP(OP) (USE_FROM_PTR (USE_OP_PTR (OP)))
@@ -187,11 +179,11 @@ typedef struct stmt_operands_d *stmt_operands_p;
#define VDEF_NUM(OP) VUSE_VECT_NUM_ELEM ((OP)->usev)
#define VDEF_VECT(OP) &((OP)->usev)
-#define PHI_RESULT_PTR(PHI) get_phi_result_ptr (PHI)
+#define PHI_RESULT_PTR(PHI) gimple_phi_result_ptr (PHI)
#define PHI_RESULT(PHI) DEF_FROM_PTR (PHI_RESULT_PTR (PHI))
#define SET_PHI_RESULT(PHI, V) SET_DEF (PHI_RESULT_PTR (PHI), (V))
-#define PHI_ARG_DEF_PTR(PHI, I) get_phi_arg_def_ptr ((PHI), (I))
+#define PHI_ARG_DEF_PTR(PHI, I) gimple_phi_arg_imm_use_ptr ((PHI), (I))
#define PHI_ARG_DEF(PHI, I) USE_FROM_PTR (PHI_ARG_DEF_PTR ((PHI), (I)))
#define SET_PHI_ARG_DEF(PHI, I, V) \
SET_USE (PHI_ARG_DEF_PTR ((PHI), (I)), (V))
@@ -204,14 +196,13 @@ typedef struct stmt_operands_d *stmt_operands_p;
extern void init_ssa_operands (void);
extern void fini_ssa_operands (void);
-extern void free_ssa_operands (stmt_operands_p);
-extern void update_stmt_operands (tree);
-extern void free_stmt_operands (tree);
+extern void update_stmt_operands (gimple);
+extern void free_stmt_operands (gimple);
extern bool verify_imm_links (FILE *f, tree var);
-extern void copy_virtual_operands (tree, tree);
+extern void copy_virtual_operands (gimple, gimple);
extern int operand_build_cmp (const void *, const void *);
-extern void create_ssa_artificial_load_stmt (tree, tree, bool);
+extern void create_ssa_artificial_load_stmt (gimple, gimple, bool);
extern void dump_immediate_uses (FILE *file);
extern void dump_immediate_uses_for (FILE *file, tree var);
@@ -222,10 +213,10 @@ extern void debug_decl_set (bitmap);
extern bool ssa_operands_active (void);
-extern void add_to_addressable_set (tree, bitmap *);
-extern void push_stmt_changes (tree *);
-extern void pop_stmt_changes (tree *);
-extern void discard_stmt_changes (tree *);
+extern void push_stmt_changes (gimple *);
+extern void pop_stmt_changes (gimple *);
+extern void discard_stmt_changes (gimple *);
+void add_to_addressable_set (tree, bitmap *);
enum ssa_op_iter_type {
ssa_op_iter_none = 0,
@@ -250,7 +241,7 @@ typedef struct ssa_operand_iterator_d
enum ssa_op_iter_type iter_type;
int phi_i;
int num_phi;
- tree phi_stmt;
+ gimple phi_stmt;
bool done;
unsigned int vuse_index;
unsigned int mayuse_index;
@@ -316,7 +307,7 @@ typedef struct ssa_operand_iterator_d
/* This macro will execute a loop over a stmt, regardless of whether it is
a real stmt or a PHI node, looking at the USE nodes matching FLAGS. */
#define FOR_EACH_PHI_OR_STMT_USE(USEVAR, STMT, ITER, FLAGS) \
- for ((USEVAR) = (TREE_CODE (STMT) == PHI_NODE \
+ for ((USEVAR) = (gimple_code (STMT) == GIMPLE_PHI \
? op_iter_init_phiuse (&(ITER), STMT, FLAGS) \
: op_iter_init_use (&(ITER), STMT, FLAGS)); \
!op_iter_done (&(ITER)); \
@@ -325,7 +316,7 @@ typedef struct ssa_operand_iterator_d
/* This macro will execute a loop over a stmt, regardless of whether it is
a real stmt or a PHI node, looking at the DEF nodes matching FLAGS. */
#define FOR_EACH_PHI_OR_STMT_DEF(DEFVAR, STMT, ITER, FLAGS) \
- for ((DEFVAR) = (TREE_CODE (STMT) == PHI_NODE \
+ for ((DEFVAR) = (gimple_code (STMT) == GIMPLE_PHI \
? op_iter_init_phidef (&(ITER), STMT, FLAGS) \
: op_iter_init_def (&(ITER), STMT, FLAGS)); \
!op_iter_done (&(ITER)); \
diff --git a/gcc/tree-ssa-phiopt.c b/gcc/tree-ssa-phiopt.c
index 80917a88525..72ba04a09b8 100644
--- a/gcc/tree-ssa-phiopt.c
+++ b/gcc/tree-ssa-phiopt.c
@@ -37,19 +37,20 @@ along with GCC; see the file COPYING3. If not see
#include "pointer-set.h"
#include "domwalk.h"
+static unsigned int tree_ssa_phiopt (void);
static unsigned int tree_ssa_phiopt_worker (bool);
static bool conditional_replacement (basic_block, basic_block,
- edge, edge, tree, tree, tree);
+ edge, edge, gimple, tree, tree);
static bool value_replacement (basic_block, basic_block,
- edge, edge, tree, tree, tree);
+ edge, edge, gimple, tree, tree);
static bool minmax_replacement (basic_block, basic_block,
- edge, edge, tree, tree, tree);
+ edge, edge, gimple, tree, tree);
static bool abs_replacement (basic_block, basic_block,
- edge, edge, tree, tree, tree);
+ edge, edge, gimple, tree, tree);
static bool cond_store_replacement (basic_block, basic_block, edge, edge,
struct pointer_set_t *);
static struct pointer_set_t * get_non_trapping (void);
-static void replace_phi_edge_with_variable (basic_block, edge, tree, tree);
+static void replace_phi_edge_with_variable (basic_block, edge, gimple, tree);
/* This pass tries to replaces an if-then-else block with an
assignment. We have four kinds of transformations. Some of these
@@ -208,18 +209,17 @@ tree_ssa_phiopt_worker (bool do_store_elim)
for (i = 0; i < n; i++)
{
- tree cond_expr;
- tree phi;
+ gimple cond_stmt, phi;
basic_block bb1, bb2;
edge e1, e2;
tree arg0, arg1;
bb = bb_order[i];
- cond_expr = last_stmt (bb);
- /* Check to see if the last statement is a COND_EXPR. */
- if (!cond_expr
- || TREE_CODE (cond_expr) != COND_EXPR)
+ cond_stmt = last_stmt (bb);
+ /* Check to see if the last statement is a GIMPLE_COND. */
+ if (!cond_stmt
+ || gimple_code (cond_stmt) != GIMPLE_COND)
continue;
e1 = EDGE_SUCC (bb, 0);
@@ -278,16 +278,17 @@ tree_ssa_phiopt_worker (bool do_store_elim)
}
else
{
- phi = phi_nodes (bb2);
+ gimple_seq phis = phi_nodes (bb2);
/* Check to make sure that there is only one PHI node.
TODO: we could do it with more than one iff the other PHI nodes
have the same elements for these two edges. */
- if (!phi || PHI_CHAIN (phi) != NULL)
+ if (! gimple_seq_singleton_p (phis))
continue;
- arg0 = PHI_ARG_DEF_TREE (phi, e1->dest_idx);
- arg1 = PHI_ARG_DEF_TREE (phi, e2->dest_idx);
+ phi = gsi_stmt (gsi_start (phis));
+ arg0 = gimple_phi_arg_def (phi, e1->dest_idx);
+ arg1 = gimple_phi_arg_def (phi, e2->dest_idx);
/* Something is wrong if we cannot find the arguments in the PHI
node. */
@@ -314,7 +315,7 @@ tree_ssa_phiopt_worker (bool do_store_elim)
{
/* In cond-store replacement we have added some loads on edges
and new VOPS (as we moved the store, and created a load). */
- bsi_commit_edge_inserts ();
+ gsi_commit_edge_inserts ();
return TODO_cleanup_cfg | TODO_update_ssa_only_virtuals;
}
else if (cfgchanged)
@@ -382,19 +383,8 @@ blocks_in_phiopt_order (void)
bool
empty_block_p (basic_block bb)
{
- block_stmt_iterator bsi;
-
/* BB must have no executable statements. */
- bsi = bsi_start (bb);
- while (!bsi_end_p (bsi)
- && (TREE_CODE (bsi_stmt (bsi)) == LABEL_EXPR
- || IS_EMPTY_STMT (bsi_stmt (bsi))))
- bsi_next (&bsi);
-
- if (!bsi_end_p (bsi))
- return false;
-
- return true;
+ return gsi_end_p (gsi_after_labels (bb));
}
/* Replace PHI node element whose edge is E in block BB with variable NEW.
@@ -403,11 +393,11 @@ empty_block_p (basic_block bb)
static void
replace_phi_edge_with_variable (basic_block cond_block,
- edge e, tree phi, tree new_tree)
+ edge e, gimple phi, tree new_tree)
{
- basic_block bb = bb_for_stmt (phi);
+ basic_block bb = gimple_bb (phi);
basic_block block_to_remove;
- block_stmt_iterator bsi;
+ gimple_stmt_iterator gsi;
/* Change the PHI argument to new. */
SET_USE (PHI_ARG_DEF_PTR (phi, e->dest_idx), new_tree);
@@ -435,8 +425,8 @@ replace_phi_edge_with_variable (basic_block cond_block,
delete_basic_block (block_to_remove);
/* Eliminate the COND_EXPR at the end of COND_BLOCK. */
- bsi = bsi_last (cond_block);
- bsi_remove (&bsi, true);
+ gsi = gsi_last_bb (cond_block);
+ gsi_remove (&gsi, true);
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file,
@@ -453,16 +443,15 @@ replace_phi_edge_with_variable (basic_block cond_block,
static bool
conditional_replacement (basic_block cond_bb, basic_block middle_bb,
- edge e0, edge e1, tree phi,
+ edge e0, edge e1, gimple phi,
tree arg0, tree arg1)
{
tree result;
- tree old_result = NULL;
- tree new_stmt, cond;
- block_stmt_iterator bsi;
+ gimple stmt, new_stmt;
+ tree cond;
+ gimple_stmt_iterator gsi;
edge true_edge, false_edge;
- tree new_var = NULL;
- tree new_var1;
+ tree new_var, new_var2;
/* FIXME: Gimplification of complex type is too hard for now. */
if (TREE_CODE (TREE_TYPE (arg0)) == COMPLEX_TYPE
@@ -480,61 +469,7 @@ conditional_replacement (basic_block cond_bb, basic_block middle_bb,
if (!empty_block_p (middle_bb))
return false;
- /* If the condition is not a naked SSA_NAME and its type does not
- match the type of the result, then we have to create a new
- variable to optimize this case as it would likely create
- non-gimple code when the condition was converted to the
- result's type. */
- cond = COND_EXPR_COND (last_stmt (cond_bb));
- result = PHI_RESULT (phi);
- if (TREE_CODE (cond) != SSA_NAME
- && !useless_type_conversion_p (TREE_TYPE (result), TREE_TYPE (cond)))
- {
- tree tmp;
-
- if (!COMPARISON_CLASS_P (cond))
- return false;
-
- tmp = create_tmp_var (TREE_TYPE (cond), NULL);
- add_referenced_var (tmp);
- new_var = make_ssa_name (tmp, NULL);
- old_result = cond;
- cond = new_var;
- }
-
- /* If the condition was a naked SSA_NAME and the type is not the
- same as the type of the result, then convert the type of the
- condition. */
- if (!useless_type_conversion_p (TREE_TYPE (result), TREE_TYPE (cond)))
- cond = fold_convert (TREE_TYPE (result), cond);
-
- /* We need to know which is the true edge and which is the false
- edge so that we know when to invert the condition below. */
- extract_true_false_edges_from_block (cond_bb, &true_edge, &false_edge);
-
- /* Insert our new statement at the end of conditional block before the
- COND_EXPR. */
- bsi = bsi_last (cond_bb);
- bsi_insert_before (&bsi, build_empty_stmt (), BSI_NEW_STMT);
-
- if (old_result)
- {
- tree new1;
-
- new1 = build2 (TREE_CODE (old_result), TREE_TYPE (old_result),
- TREE_OPERAND (old_result, 0),
- TREE_OPERAND (old_result, 1));
-
- new1 = build_gimple_modify_stmt (new_var, new1);
- SSA_NAME_DEF_STMT (new_var) = new1;
-
- bsi_insert_after (&bsi, new1, BSI_NEW_STMT);
- }
-
- new_var1 = duplicate_ssa_name (PHI_RESULT (phi), NULL);
-
-
- /* At this point we know we have a COND_EXPR with two successors.
+ /* At this point we know we have a GIMPLE_COND with two successors.
One successor is BB, the other successor is an empty block which
falls through into BB.
@@ -549,71 +484,46 @@ conditional_replacement (basic_block cond_bb, basic_block middle_bb,
We use the condition as-is if the argument associated with the
true edge has the value one or the argument associated with the
false edge as the value zero. Note that those conditions are not
- the same since only one of the outgoing edges from the COND_EXPR
+ the same since only one of the outgoing edges from the GIMPLE_COND
will directly reach BB and thus be associated with an argument. */
- if ((e0 == true_edge && integer_onep (arg0))
- || (e0 == false_edge && integer_zerop (arg0))
- || (e1 == true_edge && integer_onep (arg1))
- || (e1 == false_edge && integer_zerop (arg1)))
- {
- new_stmt = build_gimple_modify_stmt (new_var1, cond);
- }
- else
- {
- tree cond1 = invert_truthvalue (cond);
-
- cond = cond1;
-
- /* If what we get back is a conditional expression, there is no
- way that it can be gimple. */
- if (TREE_CODE (cond) == COND_EXPR)
- {
- release_ssa_name (new_var1);
- return false;
- }
- /* If COND is not something we can expect to be reducible to a GIMPLE
- condition, return early. */
- if (is_gimple_cast (cond))
- cond1 = TREE_OPERAND (cond, 0);
- if (TREE_CODE (cond1) == TRUTH_NOT_EXPR
- && !is_gimple_val (TREE_OPERAND (cond1, 0)))
- {
- release_ssa_name (new_var1);
- return false;
- }
+ stmt = last_stmt (cond_bb);
+ result = PHI_RESULT (phi);
- /* If what we get back is not gimple try to create it as gimple by
- using a temporary variable. */
- if (is_gimple_cast (cond)
- && !is_gimple_val (TREE_OPERAND (cond, 0)))
- {
- tree op0, tmp, cond_tmp;
-
- /* Only "real" casts are OK here, not everything that is
- acceptable to is_gimple_cast. Make sure we don't do
- anything stupid here. */
- gcc_assert (CONVERT_EXPR_P (cond));
-
- op0 = TREE_OPERAND (cond, 0);
- tmp = create_tmp_var (TREE_TYPE (op0), NULL);
- add_referenced_var (tmp);
- cond_tmp = make_ssa_name (tmp, NULL);
- new_stmt = build_gimple_modify_stmt (cond_tmp, op0);
- SSA_NAME_DEF_STMT (cond_tmp) = new_stmt;
-
- bsi_insert_after (&bsi, new_stmt, BSI_NEW_STMT);
- cond = fold_convert (TREE_TYPE (result), cond_tmp);
- }
+ /* To handle special cases like floating point comparison, it is easier and
+ less error-prone to build a tree and gimplify it on the fly though it is
+ less efficient. */
+ cond = fold_build2 (gimple_cond_code (stmt), boolean_type_node,
+ gimple_cond_lhs (stmt), gimple_cond_rhs (stmt));
- new_stmt = build_gimple_modify_stmt (new_var1, cond);
+ /* We need to know which is the true edge and which is the false
+ edge so that we know when to invert the condition below. */
+ extract_true_false_edges_from_block (cond_bb, &true_edge, &false_edge);
+ if ((e0 == true_edge && integer_zerop (arg0))
+ || (e0 == false_edge && integer_onep (arg0))
+ || (e1 == true_edge && integer_zerop (arg1))
+ || (e1 == false_edge && integer_onep (arg1)))
+ cond = fold_build1 (TRUTH_NOT_EXPR, TREE_TYPE (cond), cond);
+
+ /* Insert our new statements at the end of conditional block before the
+ COND_STMT. */
+ gsi = gsi_for_stmt (stmt);
+ new_var = force_gimple_operand_gsi (&gsi, cond, true, NULL, true,
+ GSI_SAME_STMT);
+
+ if (!useless_type_conversion_p (TREE_TYPE (result), TREE_TYPE (new_var)))
+ {
+ new_var2 = create_tmp_var (TREE_TYPE (result), NULL);
+ add_referenced_var (new_var2);
+ new_stmt = gimple_build_assign_with_ops (CONVERT_EXPR, new_var2,
+ new_var, NULL);
+ new_var2 = make_ssa_name (new_var2, new_stmt);
+ gimple_assign_set_lhs (new_stmt, new_var2);
+ gsi_insert_before (&gsi, new_stmt, GSI_SAME_STMT);
+ new_var = new_var2;
}
- bsi_insert_after (&bsi, new_stmt, BSI_NEW_STMT);
-
- SSA_NAME_DEF_STMT (new_var1) = new_stmt;
-
- replace_phi_edge_with_variable (cond_bb, e1, phi, new_var1);
+ replace_phi_edge_with_variable (cond_bb, e1, phi, new_var);
/* Note that we optimized this PHI. */
return true;
@@ -627,11 +537,12 @@ conditional_replacement (basic_block cond_bb, basic_block middle_bb,
static bool
value_replacement (basic_block cond_bb, basic_block middle_bb,
- edge e0, edge e1, tree phi,
+ edge e0, edge e1, gimple phi,
tree arg0, tree arg1)
{
- tree cond;
+ gimple cond;
edge true_edge, false_edge;
+ enum tree_code code;
/* If the type says honor signed zeros we cannot do this
optimization. */
@@ -641,10 +552,11 @@ value_replacement (basic_block cond_bb, basic_block middle_bb,
if (!empty_block_p (middle_bb))
return false;
- cond = COND_EXPR_COND (last_stmt (cond_bb));
+ cond = last_stmt (cond_bb);
+ code = gimple_cond_code (cond);
/* This transformation is only valid for equality comparisons. */
- if (TREE_CODE (cond) != NE_EXPR && TREE_CODE (cond) != EQ_EXPR)
+ if (code != NE_EXPR && code != EQ_EXPR)
return false;
/* We need to know which is the true edge and which is the false
@@ -662,10 +574,10 @@ value_replacement (basic_block cond_bb, basic_block middle_bb,
We now need to verify that the two arguments in the PHI node match
the two arguments to the equality comparison. */
- if ((operand_equal_for_phi_arg_p (arg0, TREE_OPERAND (cond, 0))
- && operand_equal_for_phi_arg_p (arg1, TREE_OPERAND (cond, 1)))
- || (operand_equal_for_phi_arg_p (arg1, TREE_OPERAND (cond, 0))
- && operand_equal_for_phi_arg_p (arg0, TREE_OPERAND (cond, 1))))
+ if ((operand_equal_for_phi_arg_p (arg0, gimple_cond_lhs (cond))
+ && operand_equal_for_phi_arg_p (arg1, gimple_cond_rhs (cond)))
+ || (operand_equal_for_phi_arg_p (arg1, gimple_cond_lhs (cond))
+ && operand_equal_for_phi_arg_p (arg0, gimple_cond_rhs (cond))))
{
edge e;
tree arg;
@@ -673,7 +585,7 @@ value_replacement (basic_block cond_bb, basic_block middle_bb,
/* For NE_EXPR, we want to build an assignment result = arg where
arg is the PHI argument associated with the true edge. For
EQ_EXPR we want the PHI argument associated with the false edge. */
- e = (TREE_CODE (cond) == NE_EXPR ? true_edge : false_edge);
+ e = (code == NE_EXPR ? true_edge : false_edge);
/* Unfortunately, E may not reach BB (it may instead have gone to
OTHER_BLOCK). If that is the case, then we want the single outgoing
@@ -705,15 +617,15 @@ value_replacement (basic_block cond_bb, basic_block middle_bb,
static bool
minmax_replacement (basic_block cond_bb, basic_block middle_bb,
- edge e0, edge e1, tree phi,
+ edge e0, edge e1, gimple phi,
tree arg0, tree arg1)
{
tree result, type;
- tree cond, new_stmt;
+ gimple cond, new_stmt;
edge true_edge, false_edge;
enum tree_code cmp, minmax, ass_code;
tree smaller, larger, arg_true, arg_false;
- block_stmt_iterator bsi, bsi_from;
+ gimple_stmt_iterator gsi, gsi_from;
type = TREE_TYPE (PHI_RESULT (phi));
@@ -721,21 +633,21 @@ minmax_replacement (basic_block cond_bb, basic_block middle_bb,
if (HONOR_NANS (TYPE_MODE (type)))
return false;
- cond = COND_EXPR_COND (last_stmt (cond_bb));
- cmp = TREE_CODE (cond);
+ cond = last_stmt (cond_bb);
+ cmp = gimple_cond_code (cond);
result = PHI_RESULT (phi);
/* This transformation is only valid for order comparisons. Record which
operand is smaller/larger if the result of the comparison is true. */
if (cmp == LT_EXPR || cmp == LE_EXPR)
{
- smaller = TREE_OPERAND (cond, 0);
- larger = TREE_OPERAND (cond, 1);
+ smaller = gimple_cond_lhs (cond);
+ larger = gimple_cond_rhs (cond);
}
else if (cmp == GT_EXPR || cmp == GE_EXPR)
{
- smaller = TREE_OPERAND (cond, 1);
- larger = TREE_OPERAND (cond, 0);
+ smaller = gimple_cond_rhs (cond);
+ larger = gimple_cond_lhs (cond);
}
else
return false;
@@ -796,20 +708,19 @@ minmax_replacement (basic_block cond_bb, basic_block middle_bb,
b = MAX (a, d);
x = MIN (b, u); */
- tree assign = last_and_only_stmt (middle_bb);
- tree lhs, rhs, op0, op1, bound;
+ gimple assign = last_and_only_stmt (middle_bb);
+ tree lhs, op0, op1, bound;
if (!assign
- || TREE_CODE (assign) != GIMPLE_MODIFY_STMT)
+ || gimple_code (assign) != GIMPLE_ASSIGN)
return false;
- lhs = GIMPLE_STMT_OPERAND (assign, 0);
- rhs = GIMPLE_STMT_OPERAND (assign, 1);
- ass_code = TREE_CODE (rhs);
+ lhs = gimple_assign_lhs (assign);
+ ass_code = gimple_assign_rhs_code (assign);
if (ass_code != MAX_EXPR && ass_code != MIN_EXPR)
return false;
- op0 = TREE_OPERAND (rhs, 0);
- op1 = TREE_OPERAND (rhs, 1);
+ op0 = gimple_assign_rhs1 (assign);
+ op1 = gimple_assign_rhs2 (assign);
if (true_edge->src == middle_bb)
{
@@ -931,17 +842,16 @@ minmax_replacement (basic_block cond_bb, basic_block middle_bb,
}
/* Move the statement from the middle block. */
- bsi = bsi_last (cond_bb);
- bsi_from = bsi_last (middle_bb);
- bsi_move_before (&bsi_from, &bsi);
+ gsi = gsi_last_bb (cond_bb);
+ gsi_from = gsi_last_bb (middle_bb);
+ gsi_move_before (&gsi_from, &gsi);
}
/* Emit the statement to compute min/max. */
result = duplicate_ssa_name (PHI_RESULT (phi), NULL);
- new_stmt = build_gimple_modify_stmt (result, build2 (minmax, type, arg0, arg1));
- SSA_NAME_DEF_STMT (result) = new_stmt;
- bsi = bsi_last (cond_bb);
- bsi_insert_before (&bsi, new_stmt, BSI_NEW_STMT);
+ new_stmt = gimple_build_assign_with_ops (minmax, result, arg0, arg1);
+ gsi = gsi_last_bb (cond_bb);
+ gsi_insert_before (&gsi, new_stmt, GSI_NEW_STMT);
replace_phi_edge_with_variable (cond_bb, e1, phi, result);
return true;
@@ -956,13 +866,13 @@ minmax_replacement (basic_block cond_bb, basic_block middle_bb,
static bool
abs_replacement (basic_block cond_bb, basic_block middle_bb,
edge e0 ATTRIBUTE_UNUSED, edge e1,
- tree phi, tree arg0, tree arg1)
+ gimple phi, tree arg0, tree arg1)
{
tree result;
- tree new_stmt, cond;
- block_stmt_iterator bsi;
+ gimple new_stmt, cond;
+ gimple_stmt_iterator gsi;
edge true_edge, false_edge;
- tree assign;
+ gimple assign;
edge e;
tree rhs, lhs;
bool negate;
@@ -985,38 +895,37 @@ abs_replacement (basic_block cond_bb, basic_block middle_bb,
/* If we got here, then we have found the only executable statement
in OTHER_BLOCK. If it is anything other than arg = -arg1 or
arg1 = -arg0, then we can not optimize. */
- if (TREE_CODE (assign) != GIMPLE_MODIFY_STMT)
+ if (gimple_code (assign) != GIMPLE_ASSIGN)
return false;
- lhs = GIMPLE_STMT_OPERAND (assign, 0);
- rhs = GIMPLE_STMT_OPERAND (assign, 1);
+ lhs = gimple_assign_lhs (assign);
- if (TREE_CODE (rhs) != NEGATE_EXPR)
+ if (gimple_assign_rhs_code (assign) != NEGATE_EXPR)
return false;
- rhs = TREE_OPERAND (rhs, 0);
+ rhs = gimple_assign_rhs1 (assign);
/* The assignment has to be arg0 = -arg1 or arg1 = -arg0. */
if (!(lhs == arg0 && rhs == arg1)
&& !(lhs == arg1 && rhs == arg0))
return false;
- cond = COND_EXPR_COND (last_stmt (cond_bb));
+ cond = last_stmt (cond_bb);
result = PHI_RESULT (phi);
/* Only relationals comparing arg[01] against zero are interesting. */
- cond_code = TREE_CODE (cond);
+ cond_code = gimple_cond_code (cond);
if (cond_code != GT_EXPR && cond_code != GE_EXPR
&& cond_code != LT_EXPR && cond_code != LE_EXPR)
return false;
/* Make sure the conditional is arg[01] OP y. */
- if (TREE_OPERAND (cond, 0) != rhs)
+ if (gimple_cond_lhs (cond) != rhs)
return false;
- if (FLOAT_TYPE_P (TREE_TYPE (TREE_OPERAND (cond, 1)))
- ? real_zerop (TREE_OPERAND (cond, 1))
- : integer_zerop (TREE_OPERAND (cond, 1)))
+ if (FLOAT_TYPE_P (TREE_TYPE (gimple_cond_rhs (cond)))
+ ? real_zerop (gimple_cond_rhs (cond))
+ : integer_zerop (gimple_cond_rhs (cond)))
;
else
return false;
@@ -1050,24 +959,19 @@ abs_replacement (basic_block cond_bb, basic_block middle_bb,
lhs = result;
/* Build the modify expression with abs expression. */
- new_stmt = build_gimple_modify_stmt (lhs,
- build1 (ABS_EXPR, TREE_TYPE (lhs), rhs));
- SSA_NAME_DEF_STMT (lhs) = new_stmt;
+ new_stmt = gimple_build_assign_with_ops (ABS_EXPR, lhs, rhs, NULL);
- bsi = bsi_last (cond_bb);
- bsi_insert_before (&bsi, new_stmt, BSI_NEW_STMT);
+ gsi = gsi_last_bb (cond_bb);
+ gsi_insert_before (&gsi, new_stmt, GSI_NEW_STMT);
if (negate)
{
- /* Get the right BSI. We want to insert after the recently
+ /* Get the right GSI. We want to insert after the recently
added ABS_EXPR statement (which we know is the first statement
in the block. */
- new_stmt = build_gimple_modify_stmt (result,
- build1 (NEGATE_EXPR, TREE_TYPE (lhs),
- lhs));
- SSA_NAME_DEF_STMT (result) = new_stmt;
+ new_stmt = gimple_build_assign_with_ops (NEGATE_EXPR, result, lhs, NULL);
- bsi_insert_after (&bsi, new_stmt, BSI_NEW_STMT);
+ gsi_insert_after (&gsi, new_stmt, GSI_NEW_STMT);
}
replace_phi_edge_with_variable (cond_bb, e1, phi, result);
@@ -1188,21 +1092,22 @@ add_or_mark_expr (basic_block bb, tree exp,
static void
nt_init_block (struct dom_walk_data *data ATTRIBUTE_UNUSED, basic_block bb)
{
- block_stmt_iterator bsi;
+ gimple_stmt_iterator gsi;
/* Mark this BB as being on the path to dominator root. */
bb->aux = (void*)1;
/* And walk the statements in order. */
- for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
- tree stmt = bsi_stmt (bsi);
+ gimple stmt = gsi_stmt (gsi);
- if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT)
+ if (is_gimple_assign (stmt))
{
- tree lhs = GIMPLE_STMT_OPERAND (stmt, 0);
- tree rhs = GIMPLE_STMT_OPERAND (stmt, 1);
- add_or_mark_expr (bb, rhs, nontrap_set, false);
- add_or_mark_expr (bb, lhs, nontrap_set, true);
+ add_or_mark_expr (bb, gimple_assign_lhs (stmt), nontrap_set, true);
+ add_or_mark_expr (bb, gimple_assign_rhs1 (stmt), nontrap_set, false);
+ if (get_gimple_rhs_num_ops (gimple_assign_rhs_code (stmt)) > 1)
+ add_or_mark_expr (bb, gimple_assign_rhs2 (stmt), nontrap_set,
+ false);
}
}
}
@@ -1274,21 +1179,26 @@ static bool
cond_store_replacement (basic_block middle_bb, basic_block join_bb,
edge e0, edge e1, struct pointer_set_t *nontrap)
{
- tree assign = last_and_only_stmt (middle_bb);
- tree lhs, rhs, newexpr, name;
- tree newphi;
- block_stmt_iterator bsi;
+ gimple assign = last_and_only_stmt (middle_bb);
+ tree lhs, rhs, name;
+ gimple newphi, new_stmt;
+ gimple_stmt_iterator gsi;
+ enum tree_code code;
/* Check if middle_bb contains of only one store. */
if (!assign
- || TREE_CODE (assign) != GIMPLE_MODIFY_STMT)
+ || gimple_code (assign) != GIMPLE_ASSIGN)
return false;
- lhs = GIMPLE_STMT_OPERAND (assign, 0);
+ lhs = gimple_assign_lhs (assign);
+ rhs = gimple_assign_rhs1 (assign);
if (!INDIRECT_REF_P (lhs))
return false;
- rhs = GIMPLE_STMT_OPERAND (assign, 1);
- if (TREE_CODE (rhs) != SSA_NAME && !is_gimple_min_invariant (rhs))
+
+ /* RHS is either a single SSA_NAME or a constant. */
+ code = gimple_assign_rhs_code (assign);
+ if (get_gimple_rhs_class (code) != GIMPLE_SINGLE_RHS
+ || (code != SSA_NAME && !is_gimple_min_invariant (rhs)))
return false;
/* Prove that we can move the store down. We could also check
TREE_THIS_NOTRAP here, but in that case we also could move stores,
@@ -1299,8 +1209,8 @@ cond_store_replacement (basic_block middle_bb, basic_block join_bb,
/* Now we've checked the constraints, so do the transformation:
1) Remove the single store. */
mark_symbols_for_renaming (assign);
- bsi = bsi_for_stmt (assign);
- bsi_remove (&bsi, true);
+ gsi = gsi_for_stmt (assign);
+ gsi_remove (&gsi, true);
/* 2) Create a temporary where we can store the old content
of the memory touched by the store, if we need to. */
@@ -1317,11 +1227,11 @@ cond_store_replacement (basic_block middle_bb, basic_block join_bb,
/* 3) Insert a load from the memory of the store to the temporary
on the edge which did not contain the store. */
lhs = unshare_expr (lhs);
- newexpr = build_gimple_modify_stmt (condstoretemp, lhs);
- name = make_ssa_name (condstoretemp, newexpr);
- GIMPLE_STMT_OPERAND (newexpr, 0) = name;
- mark_symbols_for_renaming (newexpr);
- bsi_insert_on_edge (e1, newexpr);
+ new_stmt = gimple_build_assign (condstoretemp, lhs);
+ name = make_ssa_name (condstoretemp, new_stmt);
+ gimple_assign_set_lhs (new_stmt, name);
+ mark_symbols_for_renaming (new_stmt);
+ gsi_insert_on_edge (e1, new_stmt);
/* 4) Create a PHI node at the join block, with one argument
holding the old RHS, and the other holding the temporary
@@ -1331,20 +1241,18 @@ cond_store_replacement (basic_block middle_bb, basic_block join_bb,
add_phi_arg (newphi, name, e1);
lhs = unshare_expr (lhs);
- newexpr = build_gimple_modify_stmt (lhs, PHI_RESULT (newphi));
- mark_symbols_for_renaming (newexpr);
+ new_stmt = gimple_build_assign (lhs, PHI_RESULT (newphi));
+ mark_symbols_for_renaming (new_stmt);
/* 5) Insert that PHI node. */
- bsi = bsi_start (join_bb);
- while (!bsi_end_p (bsi) && TREE_CODE (bsi_stmt (bsi)) == LABEL_EXPR)
- bsi_next (&bsi);
- if (bsi_end_p (bsi))
+ gsi = gsi_after_labels (join_bb);
+ if (gsi_end_p (gsi))
{
- bsi = bsi_last (join_bb);
- bsi_insert_after (&bsi, newexpr, BSI_NEW_STMT);
+ gsi = gsi_last_bb (join_bb);
+ gsi_insert_after (&gsi, new_stmt, GSI_NEW_STMT);
}
else
- bsi_insert_before (&bsi, newexpr, BSI_NEW_STMT);
+ gsi_insert_before (&gsi, new_stmt, GSI_NEW_STMT);
return true;
}
diff --git a/gcc/tree-ssa-phiprop.c b/gcc/tree-ssa-phiprop.c
index f408939b07d..ff3ee4a439f 100644
--- a/gcc/tree-ssa-phiprop.c
+++ b/gcc/tree-ssa-phiprop.c
@@ -95,7 +95,7 @@ along with GCC; see the file COPYING3. If not see
struct phiprop_d
{
tree value;
- tree vop_stmt;
+ gimple vop_stmt;
};
/* Verify if the value recorded for NAME in PHIVN is still valid at
@@ -104,7 +104,7 @@ struct phiprop_d
static bool
phivn_valid_p (struct phiprop_d *phivn, tree name, basic_block bb)
{
- tree vop_stmt = phivn[SSA_NAME_VERSION (name)].vop_stmt;
+ gimple vop_stmt = phivn[SSA_NAME_VERSION (name)].vop_stmt;
ssa_op_iter ui;
tree vuse;
@@ -112,17 +112,17 @@ phivn_valid_p (struct phiprop_d *phivn, tree name, basic_block bb)
by bb. */
FOR_EACH_SSA_TREE_OPERAND (vuse, vop_stmt, ui, SSA_OP_VUSE)
{
- tree use_stmt;
+ gimple use_stmt;
imm_use_iterator ui2;
bool ok = true;
FOR_EACH_IMM_USE_STMT (use_stmt, ui2, vuse)
{
/* If BB does not dominate a VDEF, the value is invalid. */
- if (((TREE_CODE (use_stmt) == GIMPLE_MODIFY_STMT
+ if (((is_gimple_assign (use_stmt)
&& !ZERO_SSA_OPERANDS (use_stmt, SSA_OP_VDEF))
- || TREE_CODE (use_stmt) == PHI_NODE)
- && !dominated_by_p (CDI_DOMINATORS, bb_for_stmt (use_stmt), bb))
+ || gimple_code (use_stmt) == GIMPLE_PHI)
+ && !dominated_by_p (CDI_DOMINATORS, gimple_bb (use_stmt), bb))
{
ok = false;
BREAK_FROM_IMM_USE_STMT (ui2);
@@ -139,31 +139,36 @@ phivn_valid_p (struct phiprop_d *phivn, tree name, basic_block bb)
BB with the virtual operands from USE_STMT. */
static tree
-phiprop_insert_phi (basic_block bb, tree phi, tree use_stmt,
+phiprop_insert_phi (basic_block bb, gimple phi, gimple use_stmt,
struct phiprop_d *phivn, size_t n)
{
- tree res, new_phi;
+ tree res;
+ gimple new_phi;
edge_iterator ei;
edge e;
+ gcc_assert (is_gimple_assign (use_stmt)
+ && gimple_assign_rhs_code (use_stmt) == INDIRECT_REF);
+
/* Build a new PHI node to replace the definition of
the indirect reference lhs. */
- res = GIMPLE_STMT_OPERAND (use_stmt, 0);
+ res = gimple_assign_lhs (use_stmt);
SSA_NAME_DEF_STMT (res) = new_phi = create_phi_node (res, bb);
/* Add PHI arguments for each edge inserting loads of the
addressable operands. */
FOR_EACH_EDGE (e, ei, bb->preds)
{
- tree old_arg, new_var, tmp;
+ tree old_arg, new_var;
+ gimple tmp;
old_arg = PHI_ARG_DEF_FROM_EDGE (phi, e);
while (TREE_CODE (old_arg) == SSA_NAME
&& (SSA_NAME_VERSION (old_arg) >= n
|| phivn[SSA_NAME_VERSION (old_arg)].value == NULL_TREE))
{
- tree def_stmt = SSA_NAME_DEF_STMT (old_arg);
- old_arg = GIMPLE_STMT_OPERAND (def_stmt, 1);
+ gimple def_stmt = SSA_NAME_DEF_STMT (old_arg);
+ old_arg = gimple_assign_rhs1 (def_stmt);
}
if (TREE_CODE (old_arg) == SSA_NAME)
@@ -171,18 +176,19 @@ phiprop_insert_phi (basic_block bb, tree phi, tree use_stmt,
new_var = phivn[SSA_NAME_VERSION (old_arg)].value;
else
{
+ gcc_assert (TREE_CODE (old_arg) == ADDR_EXPR);
old_arg = TREE_OPERAND (old_arg, 0);
new_var = create_tmp_var (TREE_TYPE (old_arg), NULL);
- tmp = build2 (GIMPLE_MODIFY_STMT, void_type_node,
- NULL_TREE, unshare_expr (old_arg));
+ tmp = gimple_build_assign (new_var, unshare_expr (old_arg));
if (TREE_CODE (TREE_TYPE (old_arg)) == COMPLEX_TYPE
|| TREE_CODE (TREE_TYPE (old_arg)) == VECTOR_TYPE)
DECL_GIMPLE_REG_P (new_var) = 1;
+ gcc_assert (is_gimple_reg (new_var));
add_referenced_var (new_var);
new_var = make_ssa_name (new_var, tmp);
- GIMPLE_STMT_OPERAND (tmp, 0) = new_var;
+ gimple_assign_set_lhs (tmp, new_var);
- bsi_insert_on_edge (e, tmp);
+ gsi_insert_on_edge (e, tmp);
update_stmt (tmp);
mark_symbols_for_renaming (tmp);
@@ -211,11 +217,13 @@ phiprop_insert_phi (basic_block bb, tree phi, tree use_stmt,
with aliasing issues as we are moving memory reads. */
static bool
-propagate_with_phi (basic_block bb, tree phi, struct phiprop_d *phivn, size_t n)
+propagate_with_phi (basic_block bb, gimple phi, struct phiprop_d *phivn,
+ size_t n)
{
tree ptr = PHI_RESULT (phi);
- tree use_stmt, res = NULL_TREE;
- block_stmt_iterator bsi;
+ gimple use_stmt;
+ tree res = NULL_TREE;
+ gimple_stmt_iterator gsi;
imm_use_iterator ui;
use_operand_p arg_p, use;
ssa_op_iter i;
@@ -238,10 +246,10 @@ propagate_with_phi (basic_block bb, tree phi, struct phiprop_d *phivn, size_t n)
&& (SSA_NAME_VERSION (arg) >= n
|| phivn[SSA_NAME_VERSION (arg)].value == NULL_TREE))
{
- tree def_stmt = SSA_NAME_DEF_STMT (arg);
- if (TREE_CODE (def_stmt) != GIMPLE_MODIFY_STMT)
+ gimple def_stmt = SSA_NAME_DEF_STMT (arg);
+ if (gimple_code (def_stmt) != GIMPLE_ASSIGN)
return false;
- arg = GIMPLE_STMT_OPERAND (def_stmt, 1);
+ arg = gimple_assign_rhs1 (def_stmt);
}
if ((TREE_CODE (arg) != ADDR_EXPR
/* Avoid to have to decay *&a to a[0] later. */
@@ -255,10 +263,8 @@ propagate_with_phi (basic_block bb, tree phi, struct phiprop_d *phivn, size_t n)
/* Find a dereferencing use. First follow (single use) ssa
copy chains for ptr. */
while (single_imm_use (ptr, &use, &use_stmt)
- && TREE_CODE (use_stmt) == GIMPLE_MODIFY_STMT
- && GIMPLE_STMT_OPERAND (use_stmt, 1) == ptr
- && TREE_CODE (GIMPLE_STMT_OPERAND (use_stmt, 0)) == SSA_NAME)
- ptr = GIMPLE_STMT_OPERAND (use_stmt, 0);
+ && gimple_assign_ssa_name_copy_p (use_stmt))
+ ptr = gimple_assign_lhs (use_stmt);
/* Replace the first dereference of *ptr if there is one and if we
can move the loads to the place of the ptr phi node. */
@@ -269,23 +275,23 @@ propagate_with_phi (basic_block bb, tree phi, struct phiprop_d *phivn, size_t n)
tree vuse;
/* Check whether this is a load of *ptr. */
- if (!(TREE_CODE (use_stmt) == GIMPLE_MODIFY_STMT
- && TREE_CODE (GIMPLE_STMT_OPERAND (use_stmt, 0)) == SSA_NAME
- && TREE_CODE (GIMPLE_STMT_OPERAND (use_stmt, 1)) == INDIRECT_REF
- && TREE_OPERAND (GIMPLE_STMT_OPERAND (use_stmt, 1), 0) == ptr
+ if (!(is_gimple_assign (use_stmt)
+ && TREE_CODE (gimple_assign_lhs (use_stmt)) == SSA_NAME
+ && gimple_assign_rhs_code (use_stmt) == INDIRECT_REF
+ && TREE_OPERAND (gimple_assign_rhs1 (use_stmt), 0) == ptr
/* We cannot replace a load that may throw or is volatile. */
- && !tree_can_throw_internal (use_stmt)))
+ && !stmt_can_throw_internal (use_stmt)))
continue;
/* Check if we can move the loads. The def stmts of all virtual uses
need to be post-dominated by bb. */
FOR_EACH_SSA_TREE_OPERAND (vuse, use_stmt, ui2, SSA_OP_VUSE)
{
- tree def_stmt = SSA_NAME_DEF_STMT (vuse);
+ gimple def_stmt = SSA_NAME_DEF_STMT (vuse);
if (!SSA_NAME_IS_DEFAULT_DEF (vuse)
- && (bb_for_stmt (def_stmt) == bb
+ && (gimple_bb (def_stmt) == bb
|| !dominated_by_p (CDI_DOMINATORS,
- bb, bb_for_stmt (def_stmt))))
+ bb, gimple_bb (def_stmt))))
goto next;
}
@@ -302,8 +308,8 @@ propagate_with_phi (basic_block bb, tree phi, struct phiprop_d *phivn, size_t n)
/* Remove old stmt. The phi is taken care of by DCE, if we
want to delete it here we also have to delete all intermediate
copies. */
- bsi = bsi_for_stmt (use_stmt);
- bsi_remove (&bsi, 0);
+ gsi = gsi_for_stmt (use_stmt);
+ gsi_remove (&gsi, false);
phi_inserted = true;
}
@@ -311,7 +317,7 @@ propagate_with_phi (basic_block bb, tree phi, struct phiprop_d *phivn, size_t n)
{
/* Further replacements are easy, just make a copy out of the
load. */
- GIMPLE_STMT_OPERAND (use_stmt, 1) = res;
+ gimple_assign_set_rhs1 (use_stmt, res);
update_stmt (use_stmt);
}
@@ -330,10 +336,10 @@ tree_ssa_phiprop_1 (basic_block bb, struct phiprop_d *phivn, size_t n)
{
bool did_something = false;
basic_block son;
- tree phi;
+ gimple_stmt_iterator gsi;
- for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
- did_something |= propagate_with_phi (bb, phi, phivn, n);
+ for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+ did_something |= propagate_with_phi (bb, gsi_stmt (gsi), phivn, n);
for (son = first_dom_son (CDI_DOMINATORS, bb);
son;
@@ -355,7 +361,7 @@ tree_ssa_phiprop (void)
phivn = XCNEWVEC (struct phiprop_d, num_ssa_names);
if (tree_ssa_phiprop_1 (ENTRY_BLOCK_PTR, phivn, num_ssa_names))
- bsi_commit_edge_inserts ();
+ gsi_commit_edge_inserts ();
free (phivn);
diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c
index 423afe04785..a8a39073d13 100644
--- a/gcc/tree-ssa-pre.c
+++ b/gcc/tree-ssa-pre.c
@@ -30,7 +30,7 @@ along with GCC; see the file COPYING3. If not see
#include "diagnostic.h"
#include "tree-inline.h"
#include "tree-flow.h"
-#include "tree-gimple.h"
+#include "gimple.h"
#include "tree-dump.h"
#include "timevar.h"
#include "fibheap.h"
@@ -46,6 +46,7 @@ along with GCC; see the file COPYING3. If not see
#include "cfgloop.h"
#include "tree-ssa-sccvn.h"
#include "params.h"
+#include "dbgcnt.h"
/* TODO:
@@ -59,7 +60,7 @@ along with GCC; see the file COPYING3. If not see
*/
/* For ease of terminology, "expression node" in the below refers to
- every expression node but GIMPLE_MODIFY_STMT, because GIMPLE_MODIFY_STMT's
+ every expression node but GIMPLE_ASSIGN, because GIMPLE_ASSIGNs
represent the actual statement containing the expressions we care about,
and we cache the value number by putting it in the expression. */
@@ -116,172 +117,211 @@ along with GCC; see the file COPYING3. If not see
/* Representations of value numbers:
- Value numbers are represented using the "value handle" approach.
- This means that each SSA_NAME (and for other reasons to be
- disclosed in a moment, expression nodes) has a value handle that
- can be retrieved through get_value_handle. This value handle *is*
- the value number of the SSA_NAME. You can pointer compare the
- value handles for equivalence purposes.
-
- For debugging reasons, the value handle is internally more than
- just a number, it is a VALUE_HANDLE named "VH.x", where x is a
- unique number for each value number in use. This allows
- expressions with SSA_NAMES replaced by value handles to still be
- pretty printed in a sane way. They simply print as "VH.3 *
- VH.5", etc.
-
- Expression nodes have value handles associated with them as a
- cache. Otherwise, we'd have to look them up again in the hash
- table. This makes significant difference (factor of two or more) on
- some test cases. They can be thrown away after the pass is
- finished. */
+ Value numbers are represented by a representative SSA_NAME. We
+ will create fake SSA_NAME's in situations where we need a
+ representative but do not have one (because it is a complex
+ expression). In order to facilitate storing the value numbers in
+ bitmaps, and keep the number of wasted SSA_NAME's down, we also
+ associate a value_id with each value number, and create full blown
+ ssa_name's only where we actually need them (IE in operands of
+ existing expressions).
+
+ Theoretically you could replace all the value_id's with
+ SSA_NAME_VERSION, but this would allocate a large number of
+ SSA_NAME's (which are each > 30 bytes) just to get a 4 byte number.
+ It would also require an additional indirection at each point we
+ use the value id. */
/* Representation of expressions on value numbers:
- In some portions of this code, you will notice we allocate "fake"
- analogues to the expression we are value numbering, and replace the
- operands with the values of the expression. Since we work on
- values, and not just names, we canonicalize expressions to value
- expressions for use in the ANTIC sets, the EXP_GEN set, etc.
+ Expressions consisting of value numbers are represented the same
+ way as our VN internally represents them, with an additional
+ "pre_expr" wrapping around them in order to facilitate storing all
+ of the expressions in the same sets. */
- This is theoretically unnecessary, it just saves a bunch of
- repeated get_value_handle and find_leader calls in the remainder of
- the code, trading off temporary memory usage for speed. The tree
- nodes aren't actually creating more garbage, since they are
- allocated in a special pools which are thrown away at the end of
- this pass.
+/* Representation of sets:
- All of this also means that if you print the EXP_GEN or ANTIC sets,
- you will see "VH.5 + VH.7" in the set, instead of "a_55 +
- b_66" or something. The only thing that actually cares about
- seeing the value leaders is phi translation, and it needs to be
- able to find the leader for a value in an arbitrary block, so this
- "value expression" form is perfect for it (otherwise you'd do
- get_value_handle->find_leader->translate->get_value_handle->find_leader).*/
+ The dataflow sets do not need to be sorted in any particular order
+ for the majority of their lifetime, are simply represented as two
+ bitmaps, one that keeps track of values present in the set, and one
+ that keeps track of expressions present in the set.
+ When we need them in topological order, we produce it on demand by
+ transforming the bitmap into an array and sorting it into topo
+ order. */
-/* Representation of sets:
+/* Type of expression, used to know which member of the PRE_EXPR union
+ is valid. */
- There are currently two types of sets used, hopefully to be unified soon.
- The AVAIL sets do not need to be sorted in any particular order,
- and thus, are simply represented as two bitmaps, one that keeps
- track of values present in the set, and one that keeps track of
- expressions present in the set.
+enum pre_expr_kind
+{
+ NAME,
+ NARY,
+ REFERENCE,
+ CONSTANT
+};
- The other sets are represented as doubly linked lists kept in topological
- order, with an optional supporting bitmap of values present in the
- set. The sets represent values, and the elements can be values or
- expressions. The elements can appear in different sets, but each
- element can only appear once in each set.
+typedef union pre_expr_union_d
+{
+ tree name;
+ tree constant;
+ vn_nary_op_t nary;
+ vn_reference_t reference;
+} pre_expr_union;
- Since each node in the set represents a value, we also want to be
- able to map expression, set pairs to something that tells us
- whether the value is present is a set. We use a per-set bitmap for
- that. The value handles also point to a linked list of the
- expressions they represent via a tree annotation. This is mainly
- useful only for debugging, since we don't do identity lookups. */
+typedef struct pre_expr_d
+{
+ enum pre_expr_kind kind;
+ unsigned int id;
+ pre_expr_union u;
+} *pre_expr;
+#define PRE_EXPR_NAME(e) (e)->u.name
+#define PRE_EXPR_NARY(e) (e)->u.nary
+#define PRE_EXPR_REFERENCE(e) (e)->u.reference
+#define PRE_EXPR_CONSTANT(e) (e)->u.constant
-/* Next global expression id number. */
-static unsigned int next_expression_id;
+static int
+pre_expr_eq (const void *p1, const void *p2)
+{
+ const struct pre_expr_d *e1 = (const struct pre_expr_d *) p1;
+ const struct pre_expr_d *e2 = (const struct pre_expr_d *) p2;
-typedef VEC(tree, gc) *vuse_vec;
-DEF_VEC_P (vuse_vec);
-DEF_VEC_ALLOC_P (vuse_vec, heap);
+ if (e1->kind != e2->kind)
+ return false;
-static VEC(vuse_vec, heap) *expression_vuses;
+ switch (e1->kind)
+ {
+ case CONSTANT:
+ return vn_constant_eq_with_type (PRE_EXPR_CONSTANT (e1),
+ PRE_EXPR_CONSTANT (e2));
+ case NAME:
+ return PRE_EXPR_NAME (e1) == PRE_EXPR_NAME (e2);
+ case NARY:
+ return vn_nary_op_eq (PRE_EXPR_NARY (e1), PRE_EXPR_NARY (e2));
+ case REFERENCE:
+ return vn_reference_eq (PRE_EXPR_REFERENCE (e1),
+ PRE_EXPR_REFERENCE (e2));
+ default:
+ abort();
+ }
+}
+
+static hashval_t
+pre_expr_hash (const void *p1)
+{
+ const struct pre_expr_d *e = (const struct pre_expr_d *) p1;
+ switch (e->kind)
+ {
+ case CONSTANT:
+ return vn_hash_constant_with_type (PRE_EXPR_CONSTANT (e));
+ case NAME:
+ return iterative_hash_expr (PRE_EXPR_NAME (e), 0);
+ case NARY:
+ return vn_nary_op_compute_hash (PRE_EXPR_NARY (e));
+ case REFERENCE:
+ return vn_reference_compute_hash (PRE_EXPR_REFERENCE (e));
+ default:
+ abort ();
+ }
+}
+
+
+/* Next global expression id number. */
+static unsigned int next_expression_id;
/* Mapping from expression to id number we can use in bitmap sets. */
-static VEC(tree, heap) *expressions;
+DEF_VEC_P (pre_expr);
+DEF_VEC_ALLOC_P (pre_expr, heap);
+static VEC(pre_expr, heap) *expressions;
+static htab_t expression_to_id;
/* Allocate an expression id for EXPR. */
static inline unsigned int
-alloc_expression_id (tree expr)
+alloc_expression_id (pre_expr expr)
{
- tree_ann_common_t ann;
-
- ann = get_tree_common_ann (expr);
-
+ void **slot;
/* Make sure we won't overflow. */
gcc_assert (next_expression_id + 1 > next_expression_id);
-
- ann->aux = XNEW (unsigned int);
- * ((unsigned int *)ann->aux) = next_expression_id++;
- VEC_safe_push (tree, heap, expressions, expr);
- VEC_safe_push (vuse_vec, heap, expression_vuses, NULL);
+ expr->id = next_expression_id++;
+ VEC_safe_push (pre_expr, heap, expressions, expr);
+ slot = htab_find_slot (expression_to_id, expr, INSERT);
+ gcc_assert (!*slot);
+ *slot = expr;
return next_expression_id - 1;
}
/* Return the expression id for tree EXPR. */
static inline unsigned int
-get_expression_id (tree expr)
+get_expression_id (const pre_expr expr)
+{
+ return expr->id;
+}
+
+static inline unsigned int
+lookup_expression_id (const pre_expr expr)
{
- tree_ann_common_t ann = tree_common_ann (expr);
- gcc_assert (ann);
- gcc_assert (ann->aux);
+ void **slot;
- return *((unsigned int *)ann->aux);
+ slot = htab_find_slot (expression_to_id, expr, NO_INSERT);
+ if (!slot)
+ return 0;
+ return ((pre_expr)*slot)->id;
}
/* Return the existing expression id for EXPR, or create one if one
does not exist yet. */
static inline unsigned int
-get_or_alloc_expression_id (tree expr)
+get_or_alloc_expression_id (pre_expr expr)
{
- tree_ann_common_t ann = tree_common_ann (expr);
-
- if (ann == NULL || !ann->aux)
+ unsigned int id = lookup_expression_id (expr);
+ if (id == 0)
return alloc_expression_id (expr);
-
- return get_expression_id (expr);
+ return expr->id = id;
}
/* Return the expression that has expression id ID */
-static inline tree
+static inline pre_expr
expression_for_id (unsigned int id)
{
- return VEC_index (tree, expressions, id);
+ return VEC_index (pre_expr, expressions, id);
}
-/* Return the expression vuses for EXPR, if there are any. */
-
-static inline vuse_vec
-get_expression_vuses (tree expr)
-{
- unsigned int expr_id = get_or_alloc_expression_id (expr);
- return VEC_index (vuse_vec, expression_vuses, expr_id);
-}
-
-/* Set the expression vuses for EXPR to VUSES. */
-
-static inline void
-set_expression_vuses (tree expr, vuse_vec vuses)
-{
- unsigned int expr_id = get_or_alloc_expression_id (expr);
- VEC_replace (vuse_vec, expression_vuses, expr_id, vuses);
-}
-
-
/* Free the expression id field in all of our expressions,
and then destroy the expressions array. */
static void
clear_expression_ids (void)
{
- int i;
- tree expr;
+ VEC_free (pre_expr, heap, expressions);
+}
- for (i = 0; VEC_iterate (tree, expressions, i, expr); i++)
+static alloc_pool pre_expr_pool;
+
+/* Given an SSA_NAME NAME, get or create a pre_expr to represent it. */
+
+static pre_expr
+get_or_alloc_expr_for_name (tree name)
+{
+ pre_expr result = (pre_expr) pool_alloc (pre_expr_pool);
+ unsigned int result_id;
+
+ result->kind = NAME;
+ result->id = 0;
+ PRE_EXPR_NAME (result) = name;
+ result_id = lookup_expression_id (result);
+ if (result_id != 0)
{
- free (tree_common_ann (expr)->aux);
- tree_common_ann (expr)->aux = NULL;
+ pool_free (pre_expr_pool, result);
+ result = expression_for_id (result_id);
+ return result;
}
- VEC_free (tree, heap, expressions);
- VEC_free (vuse_vec, heap, expression_vuses);
+ get_or_alloc_expression_id (result);
+ return result;
}
static bool in_fre = false;
@@ -295,7 +335,12 @@ typedef struct bitmap_set
} *bitmap_set_t;
#define FOR_EACH_EXPR_ID_IN_SET(set, id, bi) \
- EXECUTE_IF_SET_IN_BITMAP(set->expressions, 0, id, bi)
+ EXECUTE_IF_SET_IN_BITMAP((set)->expressions, 0, (id), (bi))
+
+/* Mapping from value id to expressions with that value_id. */
+DEF_VEC_P (bitmap_set_t);
+DEF_VEC_ALLOC_P (bitmap_set_t, heap);
+static VEC(bitmap_set_t, heap) *value_expressions;
/* Sets that we need to keep track of. */
typedef struct bb_bitmap_sets
@@ -347,6 +392,7 @@ typedef struct bb_bitmap_sets
#define BB_VISITED(BB) ((bb_value_sets_t) ((BB)->aux))->visited
#define BB_DEFERRED(BB) ((bb_value_sets_t) ((BB)->aux))->deferred
+
/* Maximal set of values, used to initialize the ANTIC problem, which
is an intersection problem. */
static bitmap_set_t maximal_set;
@@ -376,32 +422,25 @@ static struct
} pre_stats;
static bool do_partial_partial;
-static tree bitmap_find_leader (bitmap_set_t, tree, tree);
-static void bitmap_value_insert_into_set (bitmap_set_t, tree);
-static void bitmap_value_replace_in_set (bitmap_set_t, tree);
+static pre_expr bitmap_find_leader (bitmap_set_t, unsigned int, gimple);
+static void bitmap_value_insert_into_set (bitmap_set_t, pre_expr);
+static void bitmap_value_replace_in_set (bitmap_set_t, pre_expr);
static void bitmap_set_copy (bitmap_set_t, bitmap_set_t);
-static bool bitmap_set_contains_value (bitmap_set_t, tree);
-static void bitmap_insert_into_set (bitmap_set_t, tree);
+static bool bitmap_set_contains_value (bitmap_set_t, unsigned int);
+static void bitmap_insert_into_set (bitmap_set_t, pre_expr);
+static void bitmap_insert_into_set_1 (bitmap_set_t, pre_expr, bool);
static bitmap_set_t bitmap_set_new (void);
-static tree create_expression_by_pieces (basic_block, tree, tree, tree);
-static tree find_or_generate_expression (basic_block, tree, tree, tree);
+static tree create_expression_by_pieces (basic_block, pre_expr, gimple_seq *,
+ gimple, tree);
+static tree find_or_generate_expression (basic_block, pre_expr, gimple_seq *,
+ gimple);
/* We can add and remove elements and entries to and from sets
and hash tables, so we use alloc pools for them. */
static alloc_pool bitmap_set_pool;
-static alloc_pool binary_node_pool;
-static alloc_pool unary_node_pool;
-static alloc_pool reference_node_pool;
-static alloc_pool comparison_node_pool;
static bitmap_obstack grand_bitmap_obstack;
-/* We can't use allocation pools to hold temporary CALL_EXPR objects, since
- they are not of fixed size. Instead, use an obstack. */
-
-static struct obstack temp_call_expr_obstack;
-
-
/* To avoid adding 300 temporary variables when we only need one, we
only create one temporary variable, on demand, and build ssa names
off that. We do have to change the variable if the types don't
@@ -428,16 +467,13 @@ static htab_t phi_translate_table;
typedef struct expr_pred_trans_d
{
/* The expression. */
- tree e;
+ pre_expr e;
/* The predecessor block along which we translated the expression. */
basic_block pred;
- /* vuses associated with the expression. */
- VEC (tree, gc) *vuses;
-
/* The value that resulted from the translation. */
- tree v;
+ pre_expr v;
/* The hashcode for the expression, pred pair. This is cached for
speed reasons. */
@@ -464,50 +500,27 @@ expr_pred_trans_eq (const void *p1, const void *p2)
const_expr_pred_trans_t const ve2 = (const_expr_pred_trans_t) p2;
basic_block b1 = ve1->pred;
basic_block b2 = ve2->pred;
- int i;
- tree vuse1;
/* If they are not translations for the same basic block, they can't
be equal. */
if (b1 != b2)
return false;
-
-
- /* If they are for the same basic block, determine if the
- expressions are equal. */
- if (!expressions_equal_p (ve1->e, ve2->e))
- return false;
-
- /* Make sure the vuses are equivalent. */
- if (ve1->vuses == ve2->vuses)
- return true;
-
- if (VEC_length (tree, ve1->vuses) != VEC_length (tree, ve2->vuses))
- return false;
-
- for (i = 0; VEC_iterate (tree, ve1->vuses, i, vuse1); i++)
- {
- if (VEC_index (tree, ve2->vuses, i) != vuse1)
- return false;
- }
-
- return true;
+ return pre_expr_eq (ve1->e, ve2->e);
}
/* Search in the phi translation table for the translation of
- expression E in basic block PRED with vuses VUSES.
+ expression E in basic block PRED.
Return the translated value, if found, NULL otherwise. */
-static inline tree
-phi_trans_lookup (tree e, basic_block pred, VEC (tree, gc) *vuses)
+static inline pre_expr
+phi_trans_lookup (pre_expr e, basic_block pred)
{
void **slot;
struct expr_pred_trans_d ept;
ept.e = e;
ept.pred = pred;
- ept.vuses = vuses;
- ept.hashcode = iterative_hash_expr (e, (unsigned long) pred);
+ ept.hashcode = iterative_hash_hashval_t (pre_expr_hash (e), pred->index);
slot = htab_find_slot_with_hash (phi_translate_table, &ept, ept.hashcode,
NO_INSERT);
if (!slot)
@@ -517,19 +530,20 @@ phi_trans_lookup (tree e, basic_block pred, VEC (tree, gc) *vuses)
}
-/* Add the tuple mapping from {expression E, basic block PRED, vuses VUSES} to
+/* Add the tuple mapping from {expression E, basic block PRED} to
value V, to the phi translation table. */
static inline void
-phi_trans_add (tree e, tree v, basic_block pred, VEC (tree, gc) *vuses)
+phi_trans_add (pre_expr e, pre_expr v, basic_block pred)
{
void **slot;
expr_pred_trans_t new_pair = XNEW (struct expr_pred_trans_d);
new_pair->e = e;
new_pair->pred = pred;
- new_pair->vuses = vuses;
new_pair->v = v;
- new_pair->hashcode = iterative_hash_expr (e, (unsigned long) pred);
+ new_pair->hashcode = iterative_hash_hashval_t (pre_expr_hash (e),
+ pred->index);
+
slot = htab_find_slot_with_hash (phi_translate_table, new_pair,
new_pair->hashcode, INSERT);
if (*slot)
@@ -538,29 +552,27 @@ phi_trans_add (tree e, tree v, basic_block pred, VEC (tree, gc) *vuses)
}
-/* Return true if V is a value expression that represents itself.
- In our world, this is *only* non-value handles. */
-
-static inline bool
-constant_expr_p (tree v)
-{
- return TREE_CODE (v) != VALUE_HANDLE &&
- (TREE_CODE (v) == FIELD_DECL || is_gimple_min_invariant (v));
-}
-
-/* Add expression E to the expression set of value V. */
+/* Add expression E to the expression set of value id V. */
void
-add_to_value (tree v, tree e)
+add_to_value (unsigned int v, pre_expr e)
{
- /* Constants have no expression sets. */
- if (constant_expr_p (v))
- return;
+ bitmap_set_t set;
- if (VALUE_HANDLE_EXPR_SET (v) == NULL)
- VALUE_HANDLE_EXPR_SET (v) = bitmap_set_new ();
+ if (v >= VEC_length (bitmap_set_t, value_expressions))
+ {
+ VEC_safe_grow_cleared (bitmap_set_t, heap, value_expressions,
+ v + 1);
+ }
+
+ set = VEC_index (bitmap_set_t, value_expressions, v);
+ if (!set)
+ {
+ set = bitmap_set_new ();
+ VEC_replace (bitmap_set_t, value_expressions, v, set);
+ }
- bitmap_insert_into_set (VALUE_HANDLE_EXPR_SET (v), e);
+ bitmap_insert_into_set_1 (set, e, true);
}
/* Create a new bitmap set and return it. */
@@ -574,36 +586,70 @@ bitmap_set_new (void)
return ret;
}
+/* Return the value id for a PRE expression EXPR. */
+
+static unsigned int
+get_expr_value_id (pre_expr expr)
+{
+ switch (expr->kind)
+ {
+ case CONSTANT:
+ {
+ unsigned int id;
+ id = get_constant_value_id (PRE_EXPR_CONSTANT (expr));
+ if (id == 0)
+ {
+ id = get_or_alloc_constant_value_id (PRE_EXPR_CONSTANT (expr));
+ add_to_value (id, expr);
+ }
+ return id;
+ }
+ case NAME:
+ return VN_INFO (PRE_EXPR_NAME (expr))->value_id;
+ case NARY:
+ return PRE_EXPR_NARY (expr)->value_id;
+ case REFERENCE:
+ return PRE_EXPR_REFERENCE (expr)->value_id;
+ default:
+ gcc_unreachable ();
+ }
+}
+
/* Remove an expression EXPR from a bitmapped set. */
static void
-bitmap_remove_from_set (bitmap_set_t set, tree expr)
+bitmap_remove_from_set (bitmap_set_t set, pre_expr expr)
{
- tree val = get_value_handle (expr);
-
- gcc_assert (val);
- if (!constant_expr_p (val))
+ unsigned int val = get_expr_value_id (expr);
+ if (!value_id_constant_p (val))
{
- bitmap_clear_bit (set->values, VALUE_HANDLE_ID (val));
+ bitmap_clear_bit (set->values, val);
bitmap_clear_bit (set->expressions, get_expression_id (expr));
}
}
-/* Insert an expression EXPR into a bitmapped set. */
-
static void
-bitmap_insert_into_set (bitmap_set_t set, tree expr)
+bitmap_insert_into_set_1 (bitmap_set_t set, pre_expr expr,
+ bool allow_constants)
{
- tree val = get_value_handle (expr);
-
- gcc_assert (val);
- if (!constant_expr_p (val))
+ unsigned int val = get_expr_value_id (expr);
+ if (allow_constants || !value_id_constant_p (val))
{
- bitmap_set_bit (set->values, VALUE_HANDLE_ID (val));
+ /* We specifically expect this and only this function to be able to
+ insert constants into a set. */
+ bitmap_set_bit (set->values, val);
bitmap_set_bit (set->expressions, get_or_alloc_expression_id (expr));
}
}
+/* Insert an expression EXPR into a bitmapped set. */
+
+static void
+bitmap_insert_into_set (bitmap_set_t set, pre_expr expr)
+{
+ bitmap_insert_into_set_1 (set, expr, false);
+}
+
/* Copy a bitmapped set ORIG, into bitmapped set DEST. */
static void
@@ -624,40 +670,32 @@ bitmap_set_free (bitmap_set_t set)
/* A comparison function for use in qsort to top sort a bitmap set. Simply
- subtracts value handle ids, since they are created in topo-order. */
+ subtracts value ids, since they are created with leaves before
+ their parent users (IE topological order). */
static int
-vh_compare (const void *pa, const void *pb)
+value_id_compare (const void *pa, const void *pb)
{
- const tree vha = get_value_handle (*((const tree *)pa));
- const tree vhb = get_value_handle (*((const tree *)pb));
+ const unsigned int vha = get_expr_value_id (*((const pre_expr *)pa));
+ const unsigned int vhb = get_expr_value_id (*((const pre_expr *)pb));
- /* This can happen when we constify things. */
- if (constant_expr_p (vha))
- {
- if (constant_expr_p (vhb))
- return -1;
- return -1;
- }
- else if (constant_expr_p (vhb))
- return 1;
- return VALUE_HANDLE_ID (vha) - VALUE_HANDLE_ID (vhb);
+ return vha - vhb;
}
/* Generate an topological-ordered array of bitmap set SET. */
-static VEC(tree, heap) *
+static VEC(pre_expr, heap) *
sorted_array_from_bitmap_set (bitmap_set_t set)
{
unsigned int i;
bitmap_iterator bi;
- VEC(tree, heap) *result = NULL;
+ VEC(pre_expr, heap) *result = NULL;
FOR_EACH_EXPR_ID_IN_SET (set, i, bi)
- VEC_safe_push (tree, heap, result, expression_for_id (i));
+ VEC_safe_push (pre_expr, heap, result, expression_for_id (i));
- qsort (VEC_address (tree, result), VEC_length (tree, result),
- sizeof (tree), vh_compare);
+ qsort (VEC_address (pre_expr, result), VEC_length (pre_expr, result),
+ sizeof (pre_expr), value_id_compare);
return result;
}
@@ -678,9 +716,9 @@ bitmap_set_and (bitmap_set_t dest, bitmap_set_t orig)
bitmap_copy (temp, dest->expressions);
EXECUTE_IF_SET_IN_BITMAP (temp, 0, i, bi)
{
- tree expr = expression_for_id (i);
- tree val = get_value_handle (expr);
- if (!bitmap_bit_p (dest->values, VALUE_HANDLE_ID (val)))
+ pre_expr expr = expression_for_id (i);
+ unsigned int value_id = get_expr_value_id (expr);
+ if (!bitmap_bit_p (dest->values, value_id))
bitmap_clear_bit (dest->expressions, i);
}
BITMAP_FREE (temp);
@@ -701,9 +739,9 @@ bitmap_set_subtract (bitmap_set_t dest, bitmap_set_t orig)
FOR_EACH_EXPR_ID_IN_SET (result, i, bi)
{
- tree expr = expression_for_id (i);
- tree val = get_value_handle (expr);
- bitmap_set_bit (result->values, VALUE_HANDLE_ID (val));
+ pre_expr expr = expression_for_id (i);
+ unsigned int value_id = get_expr_value_id (expr);
+ bitmap_set_bit (result->values, value_id);
}
return result;
@@ -721,30 +759,30 @@ bitmap_set_subtract_values (bitmap_set_t a, bitmap_set_t b)
bitmap_copy (temp, a->expressions);
EXECUTE_IF_SET_IN_BITMAP (temp, 0, i, bi)
{
- tree expr = expression_for_id (i);
- if (bitmap_set_contains_value (b, get_value_handle (expr)))
+ pre_expr expr = expression_for_id (i);
+ if (bitmap_set_contains_value (b, get_expr_value_id (expr)))
bitmap_remove_from_set (a, expr);
}
BITMAP_FREE (temp);
}
-/* Return true if bitmapped set SET contains the value VAL. */
+/* Return true if bitmapped set SET contains the value VALUE_ID. */
static bool
-bitmap_set_contains_value (bitmap_set_t set, tree val)
+bitmap_set_contains_value (bitmap_set_t set, unsigned int value_id)
{
- if (constant_expr_p (val))
+ if (value_id_constant_p (value_id))
return true;
if (!set || bitmap_empty_p (set->expressions))
return false;
- return bitmap_bit_p (set->values, VALUE_HANDLE_ID (val));
+ return bitmap_bit_p (set->values, value_id);
}
static inline bool
-bitmap_set_contains_expr (bitmap_set_t set, tree expr)
+bitmap_set_contains_expr (bitmap_set_t set, const pre_expr expr)
{
return bitmap_bit_p (set->expressions, get_expression_id (expr));
}
@@ -752,13 +790,14 @@ bitmap_set_contains_expr (bitmap_set_t set, tree expr)
/* Replace an instance of value LOOKFOR with expression EXPR in SET. */
static void
-bitmap_set_replace_value (bitmap_set_t set, tree lookfor, tree expr)
+bitmap_set_replace_value (bitmap_set_t set, unsigned int lookfor,
+ const pre_expr expr)
{
bitmap_set_t exprset;
unsigned int i;
bitmap_iterator bi;
- if (constant_expr_p (lookfor))
+ if (value_id_constant_p (lookfor))
return;
if (!bitmap_set_contains_value (set, lookfor))
@@ -773,7 +812,7 @@ bitmap_set_replace_value (bitmap_set_t set, tree lookfor, tree expr)
5-10x faster than walking the bitmap. If this is somehow a
significant lose for some cases, we can choose which set to walk
based on the set size. */
- exprset = VALUE_HANDLE_EXPR_SET (lookfor);
+ exprset = VEC_index (bitmap_set_t, value_expressions, lookfor);
FOR_EACH_EXPR_ID_IN_SET (exprset, i, bi)
{
if (bitmap_bit_p (set->expressions, i))
@@ -797,9 +836,9 @@ bitmap_set_equal (bitmap_set_t a, bitmap_set_t b)
and add it otherwise. */
static void
-bitmap_value_replace_in_set (bitmap_set_t set, tree expr)
+bitmap_value_replace_in_set (bitmap_set_t set, pre_expr expr)
{
- tree val = get_value_handle (expr);
+ unsigned int val = get_expr_value_id (expr);
if (bitmap_set_contains_value (set, val))
bitmap_set_replace_value (set, val, expr);
@@ -811,17 +850,89 @@ bitmap_value_replace_in_set (bitmap_set_t set, tree expr)
SET. */
static void
-bitmap_value_insert_into_set (bitmap_set_t set, tree expr)
+bitmap_value_insert_into_set (bitmap_set_t set, pre_expr expr)
{
- tree val = get_value_handle (expr);
+ unsigned int val = get_expr_value_id (expr);
- if (constant_expr_p (val))
+ if (value_id_constant_p (val))
return;
if (!bitmap_set_contains_value (set, val))
bitmap_insert_into_set (set, expr);
}
+/* Print out EXPR to outfile. */
+
+static void
+print_pre_expr (FILE *outfile, const pre_expr expr)
+{
+ switch (expr->kind)
+ {
+ case CONSTANT:
+ print_generic_expr (outfile, PRE_EXPR_CONSTANT (expr), 0);
+ break;
+ case NAME:
+ print_generic_expr (outfile, PRE_EXPR_NAME (expr), 0);
+ break;
+ case NARY:
+ {
+ unsigned int i;
+ vn_nary_op_t nary = PRE_EXPR_NARY (expr);
+ fprintf (outfile, "{%s,", tree_code_name [nary->opcode]);
+ for (i = 0; i < nary->length; i++)
+ {
+ print_generic_expr (outfile, nary->op[i], 0);
+ if (i != (unsigned) nary->length - 1)
+ fprintf (outfile, ",");
+ }
+ fprintf (outfile, "}");
+ }
+ break;
+
+ case REFERENCE:
+ {
+ vn_reference_op_t vro;
+ unsigned int i;
+ vn_reference_t ref = PRE_EXPR_REFERENCE (expr);
+ fprintf (outfile, "{");
+ for (i = 0;
+ VEC_iterate (vn_reference_op_s, ref->operands, i, vro);
+ i++)
+ {
+ if (vro->opcode != SSA_NAME
+ && TREE_CODE_CLASS (vro->opcode) != tcc_declaration)
+ fprintf (outfile, "%s ", tree_code_name [vro->opcode]);
+ if (vro->op0)
+ {
+ if (vro->op1)
+ fprintf (outfile, "<");
+ print_generic_expr (outfile, vro->op0, 0);
+ if (vro->op1)
+ {
+ fprintf (outfile, ",");
+ print_generic_expr (outfile, vro->op1, 0);
+ }
+ if (vro->op1)
+ fprintf (outfile, ">");
+ }
+ if (i != VEC_length (vn_reference_op_s, ref->operands) - 1)
+ fprintf (outfile, ",");
+ }
+ fprintf (outfile, "}");
+ }
+ break;
+ }
+}
+void debug_pre_expr (pre_expr);
+
+/* Like print_pre_expr but always prints to stderr. */
+void
+debug_pre_expr (pre_expr e)
+{
+ print_pre_expr (stderr, e);
+ fprintf (stderr, "\n");
+}
+
/* Print out SET to OUTFILE. */
static void
@@ -837,16 +948,14 @@ print_bitmap_set (FILE *outfile, bitmap_set_t set,
FOR_EACH_EXPR_ID_IN_SET (set, i, bi)
{
- tree expr = expression_for_id (i);
+ const pre_expr expr = expression_for_id (i);
if (!first)
fprintf (outfile, ", ");
first = false;
- print_generic_expr (outfile, expr, 0);
+ print_pre_expr (outfile, expr);
- fprintf (outfile, " (");
- print_generic_expr (outfile, get_value_handle (expr), 0);
- fprintf (outfile, ") ");
+ fprintf (outfile, " (%04d)", get_expr_value_id (expr));
}
}
fprintf (outfile, " }\n");
@@ -863,42 +972,193 @@ debug_bitmap_set (bitmap_set_t set)
/* Print out the expressions that have VAL to OUTFILE. */
void
-print_value_expressions (FILE *outfile, tree val)
+print_value_expressions (FILE *outfile, unsigned int val)
{
- if (VALUE_HANDLE_EXPR_SET (val))
+ bitmap_set_t set = VEC_index (bitmap_set_t, value_expressions, val);
+ if (set)
{
char s[10];
- sprintf (s, "VH.%04d", VALUE_HANDLE_ID (val));
- print_bitmap_set (outfile, VALUE_HANDLE_EXPR_SET (val), s, 0);
+ sprintf (s, "%04d", val);
+ print_bitmap_set (outfile, set, s, 0);
}
}
void
-debug_value_expressions (tree val)
+debug_value_expressions (unsigned int val)
{
print_value_expressions (stderr, val);
}
-/* Return the folded version of T if T, when folded, is a gimple
- min_invariant. Otherwise, return T. */
+/* Given a CONSTANT, allocate a new CONSTANT type PRE_EXPR to
+ represent it. */
-static tree
-fully_constant_expression (tree t)
+static pre_expr
+get_or_alloc_expr_for_constant (tree constant)
{
- tree folded;
- folded = fold (t);
- if (folded && is_gimple_min_invariant (folded))
- return folded;
- return t;
+ unsigned int result_id;
+ unsigned int value_id;
+ pre_expr newexpr = (pre_expr) pool_alloc (pre_expr_pool);
+ newexpr->kind = CONSTANT;
+ PRE_EXPR_CONSTANT (newexpr) = constant;
+ result_id = lookup_expression_id (newexpr);
+ if (result_id != 0)
+ {
+ pool_free (pre_expr_pool, newexpr);
+ newexpr = expression_for_id (result_id);
+ return newexpr;
+ }
+ value_id = get_or_alloc_constant_value_id (constant);
+ get_or_alloc_expression_id (newexpr);
+ add_to_value (value_id, newexpr);
+ return newexpr;
}
-/* Make a temporary copy of a CALL_EXPR object NODE. */
+/* Given a value id V, find the actual tree representing the constant
+ value if there is one, and return it. Return NULL if we can't find
+ a constant. */
static tree
-temp_copy_call_expr (tree node)
+get_constant_for_value_id (unsigned int v)
+{
+ if (value_id_constant_p (v))
+ {
+ unsigned int i;
+ bitmap_iterator bi;
+ bitmap_set_t exprset = VEC_index (bitmap_set_t, value_expressions, v);
+
+ FOR_EACH_EXPR_ID_IN_SET (exprset, i, bi)
+ {
+ pre_expr expr = expression_for_id (i);
+ if (expr->kind == CONSTANT)
+ return PRE_EXPR_CONSTANT (expr);
+ }
+ }
+ return NULL;
+}
+
+/* Get or allocate a pre_expr for a piece of GIMPLE, and return it.
+ Currently only supports constants and SSA_NAMES. */
+static pre_expr
+get_or_alloc_expr_for (tree t)
+{
+ if (TREE_CODE (t) == SSA_NAME)
+ return get_or_alloc_expr_for_name (t);
+ else if (is_gimple_min_invariant (t))
+ return get_or_alloc_expr_for_constant (t);
+ else
+ {
+ /* More complex expressions can result from SCCVN expression
+ simplification that inserts values for them. As they all
+ do not have VOPs the get handled by the nary ops struct. */
+ vn_nary_op_t result;
+ unsigned int result_id;
+ vn_nary_op_lookup (t, &result);
+ if (result != NULL)
+ {
+ pre_expr e = (pre_expr) pool_alloc (pre_expr_pool);
+ e->kind = NARY;
+ PRE_EXPR_NARY (e) = result;
+ result_id = lookup_expression_id (e);
+ if (result_id != 0)
+ {
+ pool_free (pre_expr_pool, e);
+ e = expression_for_id (result_id);
+ return e;
+ }
+ alloc_expression_id (e);
+ return e;
+ }
+ }
+ return NULL;
+}
+
+/* Return the folded version of T if T, when folded, is a gimple
+ min_invariant. Otherwise, return T. */
+
+static pre_expr
+fully_constant_expression (pre_expr e)
{
- return (tree) obstack_copy (&temp_call_expr_obstack, node, tree_size (node));
+ switch (e->kind)
+ {
+ case CONSTANT:
+ return e;
+ case NARY:
+ {
+ vn_nary_op_t nary = PRE_EXPR_NARY (e);
+ switch (TREE_CODE_CLASS (nary->opcode))
+ {
+ case tcc_binary:
+ {
+ /* We have to go from trees to pre exprs to value ids to
+ constants. */
+ tree naryop0 = nary->op[0];
+ tree naryop1 = nary->op[1];
+ tree const0, const1, result;
+ if (is_gimple_min_invariant (naryop0))
+ const0 = naryop0;
+ else
+ {
+ pre_expr rep0 = get_or_alloc_expr_for (naryop0);
+ unsigned int vrep0 = get_expr_value_id (rep0);
+ const0 = get_constant_for_value_id (vrep0);
+ }
+ if (is_gimple_min_invariant (naryop1))
+ const1 = naryop1;
+ else
+ {
+ pre_expr rep1 = get_or_alloc_expr_for (naryop1);
+ unsigned int vrep1 = get_expr_value_id (rep1);
+ const1 = get_constant_for_value_id (vrep1);
+ }
+ result = NULL;
+ if (const0 && const1)
+ {
+ tree type1 = TREE_TYPE (nary->op[0]);
+ tree type2 = TREE_TYPE (nary->op[1]);
+ const0 = fold_convert (type1, const0);
+ const1 = fold_convert (type2, const1);
+ result = fold_binary (nary->opcode, nary->type, const0,
+ const1);
+ }
+ if (result && is_gimple_min_invariant (result))
+ return get_or_alloc_expr_for_constant (result);
+ return e;
+ }
+ case tcc_unary:
+ {
+ /* We have to go from trees to pre exprs to value ids to
+ constants. */
+ tree naryop0 = nary->op[0];
+ tree const0, result;
+ if (is_gimple_min_invariant (naryop0))
+ const0 = naryop0;
+ else
+ {
+ pre_expr rep0 = get_or_alloc_expr_for (naryop0);
+ unsigned int vrep0 = get_expr_value_id (rep0);
+ const0 = get_constant_for_value_id (vrep0);
+ }
+ result = NULL;
+ if (const0)
+ {
+ tree type1 = TREE_TYPE (nary->op[0]);
+ const0 = fold_convert (type1, const0);
+ result = fold_unary (nary->opcode, nary->type, const0);
+ }
+
+ if (result && is_gimple_min_invariant (result))
+ return get_or_alloc_expr_for_constant (result);
+ return e;
+ }
+ default:
+ return e;
+ }
+ }
+ default:
+ return e;
+ }
+ return e;
}
/* Translate the vuses in the VUSES vector backwards through phi nodes
@@ -916,11 +1176,11 @@ translate_vuses_through_block (VEC (tree, gc) *vuses,
for (i = 0; VEC_iterate (tree, vuses, i, oldvuse); i++)
{
- tree phi = SSA_NAME_DEF_STMT (oldvuse);
- if (TREE_CODE (phi) == PHI_NODE
- && bb_for_stmt (phi) == phiblock)
+ gimple phi = SSA_NAME_DEF_STMT (oldvuse);
+ if (gimple_code (phi) == GIMPLE_PHI
+ && gimple_bb (phi) == phiblock)
{
- edge e = find_edge (block, bb_for_stmt (phi));
+ edge e = find_edge (block, gimple_bb (phi));
if (e)
{
tree def = PHI_ARG_DEF (phi, e->dest_idx);
@@ -949,44 +1209,156 @@ translate_vuses_through_block (VEC (tree, gc) *vuses,
SET2. This is used to avoid making a set consisting of the union
of PA_IN and ANTIC_IN during insert. */
-static inline tree
-find_leader_in_sets (tree expr, bitmap_set_t set1, bitmap_set_t set2)
+static inline pre_expr
+find_leader_in_sets (unsigned int val, bitmap_set_t set1, bitmap_set_t set2)
{
- tree result;
+ pre_expr result;
- result = bitmap_find_leader (set1, expr, NULL_TREE);
+ result = bitmap_find_leader (set1, val, NULL);
if (!result && set2)
- result = bitmap_find_leader (set2, expr, NULL_TREE);
+ result = bitmap_find_leader (set2, val, NULL);
return result;
}
+/* Get the tree type for our PRE expression e. */
+
+static tree
+get_expr_type (const pre_expr e)
+{
+ switch (e->kind)
+ {
+ case NAME:
+ return TREE_TYPE (PRE_EXPR_NAME (e));
+ case CONSTANT:
+ return TREE_TYPE (PRE_EXPR_CONSTANT (e));
+ case REFERENCE:
+ {
+ vn_reference_op_t vro;
+
+ gcc_assert (PRE_EXPR_REFERENCE (e)->operands);
+ vro = VEC_index (vn_reference_op_s,
+ PRE_EXPR_REFERENCE (e)->operands,
+ 0);
+ /* We don't store type along with COMPONENT_REF because it is
+ always the same as FIELD_DECL's type. */
+ if (!vro->type)
+ {
+ gcc_assert (vro->opcode == COMPONENT_REF);
+ return TREE_TYPE (vro->op0);
+ }
+ return vro->type;
+ }
+
+ case NARY:
+ return PRE_EXPR_NARY (e)->type;
+ }
+ gcc_unreachable();
+}
+
+/* Get a representative SSA_NAME for a given expression.
+ Since all of our sub-expressions are treated as values, we require
+ them to be SSA_NAME's for simplicity.
+ Prior versions of GVNPRE used to use "value handles" here, so that
+ an expression would be VH.11 + VH.10 instead of d_3 + e_6. In
+ either case, the operands are really values (IE we do not expect
+ them to be usable without finding leaders). */
+
+static tree
+get_representative_for (const pre_expr e)
+{
+ tree exprtype;
+ tree name;
+ unsigned int value_id = get_expr_value_id (e);
+
+ switch (e->kind)
+ {
+ case NAME:
+ return PRE_EXPR_NAME (e);
+ case CONSTANT:
+ return PRE_EXPR_CONSTANT (e);
+ case NARY:
+ case REFERENCE:
+ {
+ /* Go through all of the expressions representing this value
+ and pick out an SSA_NAME. */
+ unsigned int i;
+ bitmap_iterator bi;
+ bitmap_set_t exprs = VEC_index (bitmap_set_t, value_expressions,
+ value_id);
+ FOR_EACH_EXPR_ID_IN_SET (exprs, i, bi)
+ {
+ pre_expr rep = expression_for_id (i);
+ if (rep->kind == NAME)
+ return PRE_EXPR_NAME (rep);
+ }
+ }
+ break;
+ }
+ /* If we reached here we couldn't find an SSA_NAME. This can
+ happen when we've discovered a value that has never appeared in
+ the program as set to an SSA_NAME, most likely as the result of
+ phi translation. */
+ if (dump_file)
+ {
+ fprintf (dump_file,
+ "Could not find SSA_NAME representative for expression:");
+ print_pre_expr (dump_file, e);
+ fprintf (dump_file, "\n");
+ }
+
+ exprtype = get_expr_type (e);
+
+ /* Build and insert the assignment of the end result to the temporary
+ that we will return. */
+ if (!pretemp || exprtype != TREE_TYPE (pretemp))
+ {
+ pretemp = create_tmp_var (exprtype, "pretmp");
+ get_var_ann (pretemp);
+ }
+
+ name = make_ssa_name (pretemp, gimple_build_nop ());
+ VN_INFO_GET (name)->value_id = value_id;
+ if (e->kind == CONSTANT)
+ VN_INFO (name)->valnum = PRE_EXPR_CONSTANT (e);
+ else
+ VN_INFO (name)->valnum = name;
+
+ add_to_value (value_id, get_or_alloc_expr_for_name (name));
+ if (dump_file)
+ {
+ fprintf (dump_file, "Created SSA_NAME representative ");
+ print_generic_expr (dump_file, name, 0);
+ fprintf (dump_file, " for expression:");
+ print_pre_expr (dump_file, e);
+ fprintf (dump_file, "\n");
+ }
+
+ return name;
+}
+
+
+
+
/* Translate EXPR using phis in PHIBLOCK, so that it has the values of
the phis in PRED. SEEN is a bitmap saying which expression we have
translated since we started translation of the toplevel expression.
Return NULL if we can't find a leader for each part of the
translated expression. */
-static tree
-phi_translate_1 (tree expr, bitmap_set_t set1, bitmap_set_t set2,
+static pre_expr
+phi_translate_1 (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2,
basic_block pred, basic_block phiblock, bitmap seen)
{
- tree phitrans = NULL;
- tree oldexpr = expr;
+ pre_expr oldexpr = expr;
+ pre_expr phitrans;
- if (expr == NULL)
+ if (!expr)
return NULL;
- if (constant_expr_p (expr))
+ if (value_id_constant_p (get_expr_value_id (expr)))
return expr;
- /* Phi translations of a given expression don't change. */
- if (EXPR_P (expr) || GIMPLE_STMT_P (expr))
- {
- phitrans = phi_trans_lookup (expr, pred, get_expression_vuses (expr));
- }
- else
- phitrans = phi_trans_lookup (expr, pred, NULL);
-
+ phitrans = phi_trans_lookup (expr, pred);
if (phitrans)
return phitrans;
@@ -1000,338 +1372,265 @@ phi_translate_1 (tree expr, bitmap_set_t set1, bitmap_set_t set2,
bitmap_set_bit (seen, expr_id);
}
- switch (TREE_CODE_CLASS (TREE_CODE (expr)))
+ switch (expr->kind)
{
- case tcc_expression:
- return NULL;
+ /* Constants contain no values that need translation. */
+ case CONSTANT:
+ return expr;
- case tcc_vl_exp:
+ case NARY:
{
- if (TREE_CODE (expr) != CALL_EXPR)
- return NULL;
- else
+ unsigned int i;
+ bool changed = false;
+ vn_nary_op_t nary = PRE_EXPR_NARY (expr);
+ struct vn_nary_op_s newnary;
+ /* The NARY structure is only guaranteed to have been
+ allocated to the nary->length operands. */
+ memcpy (&newnary, nary, (sizeof (struct vn_nary_op_s)
+ - sizeof (tree) * (4 - nary->length)));
+
+ for (i = 0; i < newnary.length; i++)
{
- tree oldfn = CALL_EXPR_FN (expr);
- tree oldsc = CALL_EXPR_STATIC_CHAIN (expr);
- tree newfn, newsc = NULL;
- tree newexpr = NULL_TREE;
- bool invariantarg = false;
- int i, nargs;
- VEC (tree, gc) *vuses = get_expression_vuses (expr);
- VEC (tree, gc) *tvuses;
-
- newfn = phi_translate_1 (find_leader_in_sets (oldfn, set1, set2),
- set1, set2, pred, phiblock, seen);
- if (newfn == NULL)
- return NULL;
- if (newfn != oldfn)
- {
- newexpr = temp_copy_call_expr (expr);
- CALL_EXPR_FN (newexpr) = get_value_handle (newfn);
- }
- if (oldsc)
- {
- newsc = phi_translate_1 (find_leader_in_sets (oldsc, set1, set2),
- set1, set2, pred, phiblock, seen);
- if (newsc == NULL)
- return NULL;
- if (newsc != oldsc)
- {
- if (!newexpr)
- newexpr = temp_copy_call_expr (expr);
- CALL_EXPR_STATIC_CHAIN (newexpr) = get_value_handle (newsc);
- }
- }
-
- /* phi translate the argument list piece by piece. */
- nargs = call_expr_nargs (expr);
- for (i = 0; i < nargs; i++)
+ if (TREE_CODE (newnary.op[i]) != SSA_NAME)
+ continue;
+ else
{
- tree oldval = CALL_EXPR_ARG (expr, i);
- tree newval;
- if (oldval)
+ unsigned int op_val_id = VN_INFO (newnary.op[i])->value_id;
+ pre_expr leader = find_leader_in_sets (op_val_id, set1, set2);
+ pre_expr result = phi_translate_1 (leader, set1, set2,
+ pred, phiblock, seen);
+ if (result && result != leader)
{
- /* This may seem like a weird place for this
- check, but it's actually the easiest place to
- do it. We can't do it lower on in the
- recursion because it's valid for pieces of a
- component ref to be of AGGREGATE_TYPE, as long
- as the outermost one is not.
- To avoid *that* case, we have a check for
- AGGREGATE_TYPE_P in insert_aux. However, that
- check will *not* catch this case because here
- it occurs in the argument list. */
- if (AGGREGATE_TYPE_P (TREE_TYPE (oldval)))
+ tree name = get_representative_for (result);
+ if (!name)
return NULL;
- oldval = find_leader_in_sets (oldval, set1, set2);
- newval = phi_translate_1 (oldval, set1, set2, pred,
- phiblock, seen);
- if (newval == NULL)
- return NULL;
- if (newval != oldval)
- {
- invariantarg |= is_gimple_min_invariant (newval);
- if (!newexpr)
- newexpr = temp_copy_call_expr (expr);
- CALL_EXPR_ARG (newexpr, i) = get_value_handle (newval);
- }
+ newnary.op[i] = name;
}
- }
+ else if (!result)
+ return NULL;
- /* In case of new invariant args we might try to fold the call
- again. */
- if (invariantarg && !newsc)
- {
- tree tmp1 = build_call_array (TREE_TYPE (expr),
- newfn, call_expr_nargs (newexpr),
- CALL_EXPR_ARGP (newexpr));
- tree tmp2 = fold (tmp1);
- if (tmp2 != tmp1)
- {
- STRIP_TYPE_NOPS (tmp2);
- if (is_gimple_min_invariant (tmp2))
- return tmp2;
- }
+ changed |= newnary.op[i] != nary->op[i];
}
+ }
+ if (changed)
+ {
+ pre_expr constant;
+
+ tree result = vn_nary_op_lookup_pieces (newnary.length,
+ newnary.opcode,
+ newnary.type,
+ newnary.op[0],
+ newnary.op[1],
+ newnary.op[2],
+ newnary.op[3],
+ &nary);
+ unsigned int new_val_id;
+
+ expr = (pre_expr) pool_alloc (pre_expr_pool);
+ expr->kind = NARY;
+ expr->id = 0;
+ if (result && is_gimple_min_invariant (result))
+ return get_or_alloc_expr_for_constant (result);
+
+
+ if (nary)
+ {
+ PRE_EXPR_NARY (expr) = nary;
+ constant = fully_constant_expression (expr);
+ if (constant != expr)
+ return constant;
- tvuses = translate_vuses_through_block (vuses, phiblock, pred);
- if (vuses != tvuses && ! newexpr)
- newexpr = temp_copy_call_expr (expr);
-
- if (newexpr)
+ new_val_id = nary->value_id;
+ get_or_alloc_expression_id (expr);
+ }
+ else
{
- newexpr->base.ann = NULL;
- vn_lookup_or_add_with_vuses (newexpr, tvuses);
- expr = newexpr;
- set_expression_vuses (newexpr, tvuses);
+ new_val_id = get_next_value_id ();
+ VEC_safe_grow_cleared (bitmap_set_t, heap,
+ value_expressions,
+ get_max_value_id() + 1);
+ nary = vn_nary_op_insert_pieces (newnary.length,
+ newnary.opcode,
+ newnary.type,
+ newnary.op[0],
+ newnary.op[1],
+ newnary.op[2],
+ newnary.op[3],
+ result, new_val_id);
+ PRE_EXPR_NARY (expr) = nary;
+ constant = fully_constant_expression (expr);
+ if (constant != expr)
+ return constant;
+ get_or_alloc_expression_id (expr);
}
- phi_trans_add (oldexpr, expr, pred, tvuses);
- }
- }
- return expr;
-
- case tcc_declaration:
- {
- VEC (tree, gc) * oldvuses = NULL;
- VEC (tree, gc) * newvuses = NULL;
-
- oldvuses = get_expression_vuses (expr);
- if (oldvuses)
- newvuses = translate_vuses_through_block (oldvuses, phiblock,
- pred);
-
- if (oldvuses != newvuses)
- {
- vn_lookup_or_add_with_vuses (expr, newvuses);
- set_expression_vuses (expr, newvuses);
+ add_to_value (new_val_id, expr);
}
- phi_trans_add (oldexpr, expr, pred, newvuses);
+ phi_trans_add (oldexpr, expr, pred);
+ return expr;
}
- return expr;
-
- case tcc_reference:
+ break;
+ case REFERENCE:
{
- tree oldop0 = TREE_OPERAND (expr, 0);
- tree oldop1 = NULL;
- tree newop0;
- tree newop1 = NULL;
- tree oldop2 = NULL;
- tree newop2 = NULL;
- tree oldop3 = NULL;
- tree newop3 = NULL;
- tree newexpr;
- VEC (tree, gc) * oldvuses = NULL;
- VEC (tree, gc) * newvuses = NULL;
-
- if (TREE_CODE (expr) != INDIRECT_REF
- && TREE_CODE (expr) != COMPONENT_REF
- && TREE_CODE (expr) != ARRAY_REF)
- return NULL;
-
- oldop0 = find_leader_in_sets (oldop0, set1, set2);
- newop0 = phi_translate_1 (oldop0, set1, set2, pred, phiblock, seen);
- if (newop0 == NULL)
- return NULL;
-
- if (TREE_CODE (expr) == ARRAY_REF)
+ vn_reference_t ref = PRE_EXPR_REFERENCE (expr);
+ VEC (vn_reference_op_s, heap) *operands = ref->operands;
+ VEC (tree, gc) *vuses = ref->vuses;
+ VEC (tree, gc) *newvuses = vuses;
+ VEC (vn_reference_op_s, heap) *newoperands = NULL;
+ bool changed = false;
+ unsigned int i;
+ vn_reference_op_t operand;
+ vn_reference_t newref;
+
+ for (i = 0; VEC_iterate (vn_reference_op_s, operands, i, operand); i++)
{
- oldop1 = TREE_OPERAND (expr, 1);
- oldop1 = find_leader_in_sets (oldop1, set1, set2);
- newop1 = phi_translate_1 (oldop1, set1, set2, pred, phiblock, seen);
-
- if (newop1 == NULL)
- return NULL;
-
- oldop2 = TREE_OPERAND (expr, 2);
- if (oldop2)
+ pre_expr opresult;
+ pre_expr leader;
+ tree oldop0 = operand->op0;
+ tree oldop1 = operand->op1;
+ tree oldop2 = operand->op2;
+ tree op0 = oldop0;
+ tree op1 = oldop1;
+ tree op2 = oldop2;
+ tree type = operand->type;
+ vn_reference_op_s newop = *operand;
+
+ if (op0 && TREE_CODE (op0) == SSA_NAME)
{
- oldop2 = find_leader_in_sets (oldop2, set1, set2);
- newop2 = phi_translate_1 (oldop2, set1, set2, pred, phiblock, seen);
+ unsigned int op_val_id = VN_INFO (op0)->value_id;
+ leader = find_leader_in_sets (op_val_id, set1, set2);
+ opresult = phi_translate_1 (leader, set1, set2,
+ pred, phiblock, seen);
+ if (opresult && opresult != leader)
+ {
+ tree name = get_representative_for (opresult);
+ if (!name)
+ return NULL;
+ op0 = name;
+ }
+ else if (!opresult)
+ return NULL;
+ }
+ changed |= op0 != oldop0;
- if (newop2 == NULL)
+ if (op1 && TREE_CODE (op1) == SSA_NAME)
+ {
+ unsigned int op_val_id = VN_INFO (op1)->value_id;
+ leader = find_leader_in_sets (op_val_id, set1, set2);
+ opresult = phi_translate_1 (leader, set1, set2,
+ pred, phiblock, seen);
+ if (opresult && opresult != leader)
+ {
+ tree name = get_representative_for (opresult);
+ if (!name)
+ return NULL;
+ op1 = name;
+ }
+ else if (!opresult)
return NULL;
}
- oldop3 = TREE_OPERAND (expr, 3);
- if (oldop3)
+ changed |= op1 != oldop1;
+ if (op2 && TREE_CODE (op2) == SSA_NAME)
{
- oldop3 = find_leader_in_sets (oldop3, set1, set2);
- newop3 = phi_translate_1 (oldop3, set1, set2, pred, phiblock, seen);
-
- if (newop3 == NULL)
+ unsigned int op_val_id = VN_INFO (op2)->value_id;
+ leader = find_leader_in_sets (op_val_id, set1, set2);
+ opresult = phi_translate_1 (leader, set1, set2,
+ pred, phiblock, seen);
+ if (opresult && opresult != leader)
+ {
+ tree name = get_representative_for (opresult);
+ if (!name)
+ return NULL;
+ op2 = name;
+ }
+ else if (!opresult)
return NULL;
}
+ changed |= op2 != oldop2;
+
+ if (!newoperands)
+ newoperands = VEC_copy (vn_reference_op_s, heap, operands);
+ /* We may have changed from an SSA_NAME to a constant */
+ if (newop.opcode == SSA_NAME && TREE_CODE (op0) != SSA_NAME)
+ newop.opcode = TREE_CODE (op0);
+ newop.type = type;
+ newop.op0 = op0;
+ newop.op1 = op1;
+ newop.op2 = op2;
+ VEC_replace (vn_reference_op_s, newoperands, i, &newop);
}
- oldvuses = get_expression_vuses (expr);
- if (oldvuses)
- newvuses = translate_vuses_through_block (oldvuses, phiblock,
- pred);
+ newvuses = translate_vuses_through_block (vuses, phiblock, pred);
+ changed |= newvuses != vuses;
- if (newop0 != oldop0 || newvuses != oldvuses
- || newop1 != oldop1
- || newop2 != oldop2
- || newop3 != oldop3)
+ if (changed)
{
- tree t;
+ tree result = vn_reference_lookup_pieces (newvuses,
+ newoperands,
+ &newref);
+ unsigned int new_val_id;
- newexpr = (tree) pool_alloc (reference_node_pool);
- memcpy (newexpr, expr, tree_size (expr));
- TREE_OPERAND (newexpr, 0) = get_value_handle (newop0);
- if (TREE_CODE (expr) == ARRAY_REF)
- {
- TREE_OPERAND (newexpr, 1) = get_value_handle (newop1);
- if (newop2)
- TREE_OPERAND (newexpr, 2) = get_value_handle (newop2);
- if (newop3)
- TREE_OPERAND (newexpr, 3) = get_value_handle (newop3);
- }
+ if (newref)
+ VEC_free (vn_reference_op_s, heap, newoperands);
- t = fully_constant_expression (newexpr);
+ if (result && is_gimple_min_invariant (result))
+ return get_or_alloc_expr_for_constant (result);
- if (t != newexpr)
- {
- pool_free (reference_node_pool, newexpr);
- newexpr = t;
- }
- else
- {
- newexpr->base.ann = NULL;
- vn_lookup_or_add_with_vuses (newexpr, newvuses);
- set_expression_vuses (newexpr, newvuses);
- }
- expr = newexpr;
- }
- phi_trans_add (oldexpr, expr, pred, newvuses);
- }
- return expr;
- break;
+ expr = (pre_expr) pool_alloc (pre_expr_pool);
+ expr->kind = REFERENCE;
+ expr->id = 0;
- case tcc_binary:
- case tcc_comparison:
- {
- tree oldop1 = TREE_OPERAND (expr, 0);
- tree oldval1 = oldop1;
- tree oldop2 = TREE_OPERAND (expr, 1);
- tree oldval2 = oldop2;
- tree newop1;
- tree newop2;
- tree newexpr;
-
- oldop1 = find_leader_in_sets (oldop1, set1, set2);
- newop1 = phi_translate_1 (oldop1, set1, set2, pred, phiblock, seen);
- if (newop1 == NULL)
- return NULL;
-
- oldop2 = find_leader_in_sets (oldop2, set1, set2);
- newop2 = phi_translate_1 (oldop2, set1, set2, pred, phiblock, seen);
- if (newop2 == NULL)
- return NULL;
- if (newop1 != oldop1 || newop2 != oldop2)
- {
- tree t;
- newexpr = (tree) pool_alloc (binary_node_pool);
- memcpy (newexpr, expr, tree_size (expr));
- TREE_OPERAND (newexpr, 0) = newop1 == oldop1 ? oldval1 : get_value_handle (newop1);
- TREE_OPERAND (newexpr, 1) = newop2 == oldop2 ? oldval2 : get_value_handle (newop2);
- t = fully_constant_expression (newexpr);
- if (t != newexpr)
+ if (newref)
{
- pool_free (binary_node_pool, newexpr);
- newexpr = t;
+ PRE_EXPR_REFERENCE (expr) = newref;
+ new_val_id = newref->value_id;
+ get_or_alloc_expression_id (expr);
}
else
{
- newexpr->base.ann = NULL;
- vn_lookup_or_add (newexpr);
+ new_val_id = get_next_value_id ();
+ VEC_safe_grow_cleared (bitmap_set_t, heap, value_expressions,
+ get_max_value_id() + 1);
+ newref = vn_reference_insert_pieces (newvuses,
+ newoperands,
+ result, new_val_id);
+ PRE_EXPR_REFERENCE (expr) = newref;
+ get_or_alloc_expression_id (expr);
}
- expr = newexpr;
+ add_to_value (new_val_id, expr);
}
- phi_trans_add (oldexpr, expr, pred, NULL);
+ phi_trans_add (oldexpr, expr, pred);
+ return expr;
}
- return expr;
-
- case tcc_unary:
- {
- tree oldop1 = TREE_OPERAND (expr, 0);
- tree newop1;
- tree newexpr;
-
- oldop1 = find_leader_in_sets (oldop1, set1, set2);
- newop1 = phi_translate_1 (oldop1, set1, set2, pred, phiblock, seen);
- if (newop1 == NULL)
- return NULL;
- if (newop1 != oldop1)
- {
- tree t;
- newexpr = (tree) pool_alloc (unary_node_pool);
- memcpy (newexpr, expr, tree_size (expr));
- TREE_OPERAND (newexpr, 0) = get_value_handle (newop1);
- t = fully_constant_expression (newexpr);
- if (t != newexpr)
- {
- pool_free (unary_node_pool, newexpr);
- newexpr = t;
- }
- else
- {
- newexpr->base.ann = NULL;
- vn_lookup_or_add (newexpr);
- }
- expr = newexpr;
- }
- phi_trans_add (oldexpr, expr, pred, NULL);
- }
- return expr;
-
- case tcc_exceptional:
+ break;
+ case NAME:
{
- tree phi = NULL;
+ gimple phi = NULL;
edge e;
- tree def_stmt;
- gcc_assert (TREE_CODE (expr) == SSA_NAME);
+ gimple def_stmt;
+ tree name = PRE_EXPR_NAME (expr);
- def_stmt = SSA_NAME_DEF_STMT (expr);
- if (TREE_CODE (def_stmt) == PHI_NODE
- && bb_for_stmt (def_stmt) == phiblock)
+ def_stmt = SSA_NAME_DEF_STMT (name);
+ if (gimple_code (def_stmt) == GIMPLE_PHI
+ && gimple_bb (def_stmt) == phiblock)
phi = def_stmt;
else
return expr;
- e = find_edge (pred, bb_for_stmt (phi));
+ e = find_edge (pred, gimple_bb (phi));
if (e)
{
- tree val;
tree def = PHI_ARG_DEF (phi, e->dest_idx);
+ pre_expr newexpr;
+ /* Handle constant. */
if (is_gimple_min_invariant (def))
- return def;
+ return get_or_alloc_expr_for_constant (def);
if (TREE_CODE (def) == SSA_NAME && ssa_undefined_value_p (def))
return NULL;
- val = get_value_handle (def);
- gcc_assert (val);
- return def;
+ newexpr = get_or_alloc_expr_for_name (def);
+ return newexpr;
}
}
return expr;
@@ -1346,8 +1645,8 @@ phi_translate_1 (tree expr, bitmap_set_t set1, bitmap_set_t set2,
Return NULL if we can't find a leader for each part of the
translated expression. */
-static tree
-phi_translate (tree expr, bitmap_set_t set1, bitmap_set_t set2,
+static pre_expr
+phi_translate (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2,
basic_block pred, basic_block phiblock)
{
bitmap_clear (seen_during_translate);
@@ -1355,7 +1654,7 @@ phi_translate (tree expr, bitmap_set_t set1, bitmap_set_t set2,
seen_during_translate);
}
-/* For each expression in SET, translate the value handles through phi nodes
+/* For each expression in SET, translate the values through phi nodes
in PHIBLOCK using edge PHIBLOCK->PRED, and store the resulting
expressions in DEST. */
@@ -1363,8 +1662,8 @@ static void
phi_translate_set (bitmap_set_t dest, bitmap_set_t set, basic_block pred,
basic_block phiblock)
{
- VEC (tree, heap) *exprs;
- tree expr;
+ VEC (pre_expr, heap) *exprs;
+ pre_expr expr;
int i;
if (!phi_nodes (phiblock))
@@ -1374,23 +1673,20 @@ phi_translate_set (bitmap_set_t dest, bitmap_set_t set, basic_block pred,
}
exprs = sorted_array_from_bitmap_set (set);
- for (i = 0; VEC_iterate (tree, exprs, i, expr); i++)
+ for (i = 0; VEC_iterate (pre_expr, exprs, i, expr); i++)
{
- tree translated;
+ pre_expr translated;
translated = phi_translate (expr, set, NULL, pred, phiblock);
/* Don't add constants or empty translations to the cache, since
we won't look them up that way, or use the result, anyway. */
- if (translated && !is_gimple_min_invariant (translated))
- {
- phi_trans_add (expr, translated, pred,
- get_expression_vuses (translated));
- }
+ if (translated && !value_id_constant_p (get_expr_value_id (translated)))
+ phi_trans_add (expr, translated, pred);
if (translated != NULL)
bitmap_value_insert_into_set (dest, translated);
}
- VEC_free (tree, heap, exprs);
+ VEC_free (pre_expr, heap, exprs);
}
/* Find the leader for a value (i.e., the name representing that
@@ -1398,15 +1694,22 @@ phi_translate_set (bitmap_set_t dest, bitmap_set_t set, basic_block pred,
makes sure the defining statement for the leader dominates it.
Return NULL if no leader is found. */
-static tree
-bitmap_find_leader (bitmap_set_t set, tree val, tree stmt)
+static pre_expr
+bitmap_find_leader (bitmap_set_t set, unsigned int val, gimple stmt)
{
- if (val == NULL)
- return NULL;
-
- if (constant_expr_p (val))
- return val;
+ if (value_id_constant_p (val))
+ {
+ unsigned int i;
+ bitmap_iterator bi;
+ bitmap_set_t exprset = VEC_index (bitmap_set_t, value_expressions, val);
+ FOR_EACH_EXPR_ID_IN_SET (exprset, i, bi)
+ {
+ pre_expr expr = expression_for_id (i);
+ if (expr->kind == CONSTANT)
+ return expr;
+ }
+ }
if (bitmap_set_contains_value (set, val))
{
/* Rather than walk the entire bitmap of expressions, and see
@@ -1422,18 +1725,20 @@ bitmap_find_leader (bitmap_set_t set, tree val, tree stmt)
choose which set to walk based on which set is smaller. */
unsigned int i;
bitmap_iterator bi;
- bitmap_set_t exprset = VALUE_HANDLE_EXPR_SET (val);
+ bitmap_set_t exprset = VEC_index (bitmap_set_t, value_expressions, val);
EXECUTE_IF_AND_IN_BITMAP (exprset->expressions,
set->expressions, 0, i, bi)
{
- tree val = expression_for_id (i);
+ pre_expr val = expression_for_id (i);
+ /* At the point where stmt is not null, there should always
+ be an SSA_NAME first in the list of expressions. */
if (stmt)
{
- tree def_stmt = SSA_NAME_DEF_STMT (val);
- if (TREE_CODE (def_stmt) != PHI_NODE
- && bb_for_stmt (def_stmt) == bb_for_stmt (stmt)
- && stmt_ann (def_stmt)->uid >= stmt_ann (stmt)->uid)
+ gimple def_stmt = SSA_NAME_DEF_STMT (PRE_EXPR_NAME (val));
+ if (gimple_code (def_stmt) != GIMPLE_PHI
+ && gimple_bb (def_stmt) == gimple_bb (stmt)
+ && gimple_uid (def_stmt) >= gimple_uid (stmt))
continue;
}
return val;
@@ -1450,142 +1755,137 @@ bitmap_find_leader (bitmap_set_t set, tree val, tree stmt)
ANTIC_IN set already. */
static bool
-value_dies_in_block_x (tree expr, basic_block block)
+value_dies_in_block_x (pre_expr expr, basic_block block)
{
int i;
tree vuse;
- VEC (tree, gc) *vuses = get_expression_vuses (expr);
+ VEC (tree, gc) *vuses = PRE_EXPR_REFERENCE (expr)->vuses;
/* Conservatively, a value dies if it's vuses are defined in this
block, unless they come from phi nodes (which are merge operations,
rather than stores. */
for (i = 0; VEC_iterate (tree, vuses, i, vuse); i++)
{
- tree def = SSA_NAME_DEF_STMT (vuse);
+ gimple def = SSA_NAME_DEF_STMT (vuse);
- if (bb_for_stmt (def) != block)
+ if (gimple_bb (def) != block)
continue;
- if (TREE_CODE (def) == PHI_NODE)
+ if (gimple_code (def) == GIMPLE_PHI)
continue;
return true;
}
return false;
}
-/* Determine if the expression EXPR is valid in SET1 U SET2.
- ONLY SET2 CAN BE NULL.
- This means that we have a leader for each part of the expression
- (if it consists of values), or the expression is an SSA_NAME.
- For loads/calls, we also see if the vuses are killed in this block.
-
- NB: We never should run into a case where we have SSA_NAME +
- SSA_NAME or SSA_NAME + value. The sets valid_in_sets is called on,
- the ANTIC sets, will only ever have SSA_NAME's or value expressions
- (IE VALUE1 + VALUE2, *VALUE1, VALUE1 < VALUE2) */
#define union_contains_value(SET1, SET2, VAL) \
(bitmap_set_contains_value ((SET1), (VAL)) \
|| ((SET2) && bitmap_set_contains_value ((SET2), (VAL))))
+/* Determine if vn_reference_op_t VRO is legal in SET1 U SET2.
+ */
static bool
-valid_in_sets (bitmap_set_t set1, bitmap_set_t set2, tree expr,
- basic_block block)
+vro_valid_in_sets (bitmap_set_t set1, bitmap_set_t set2,
+ vn_reference_op_t vro)
{
- switch (TREE_CODE_CLASS (TREE_CODE (expr)))
+ if (vro->op0 && TREE_CODE (vro->op0) == SSA_NAME)
{
- case tcc_binary:
- case tcc_comparison:
- {
- tree op1 = TREE_OPERAND (expr, 0);
- tree op2 = TREE_OPERAND (expr, 1);
+ struct pre_expr_d temp;
+ temp.kind = NAME;
+ temp.id = 0;
+ PRE_EXPR_NAME (&temp) = vro->op0;
+ temp.id = lookup_expression_id (&temp);
+ if (temp.id == 0)
+ return false;
+ if (!union_contains_value (set1, set2,
+ get_expr_value_id (&temp)))
+ return false;
+ }
+ if (vro->op1 && TREE_CODE (vro->op1) == SSA_NAME)
+ {
+ struct pre_expr_d temp;
+ temp.kind = NAME;
+ temp.id = 0;
+ PRE_EXPR_NAME (&temp) = vro->op1;
+ temp.id = lookup_expression_id (&temp);
+ if (temp.id == 0)
+ return false;
+ if (!union_contains_value (set1, set2,
+ get_expr_value_id (&temp)))
+ return false;
+ }
- return union_contains_value (set1, set2, op1)
- && union_contains_value (set1, set2, op2);
- }
+ if (vro->op2 && TREE_CODE (vro->op2) == SSA_NAME)
+ {
+ struct pre_expr_d temp;
+ temp.kind = NAME;
+ temp.id = 0;
+ PRE_EXPR_NAME (&temp) = vro->op2;
+ temp.id = lookup_expression_id (&temp);
+ if (temp.id == 0)
+ return false;
+ if (!union_contains_value (set1, set2,
+ get_expr_value_id (&temp)))
+ return false;
+ }
- case tcc_unary:
- {
- tree op1 = TREE_OPERAND (expr, 0);
- return union_contains_value (set1, set2, op1);
- }
+ return true;
+}
- case tcc_expression:
- return false;
+/* Determine if the expression EXPR is valid in SET1 U SET2.
+ ONLY SET2 CAN BE NULL.
+ This means that we have a leader for each part of the expression
+ (if it consists of values), or the expression is an SSA_NAME.
+ For loads/calls, we also see if the vuses are killed in this block.
+*/
- case tcc_vl_exp:
+static bool
+valid_in_sets (bitmap_set_t set1, bitmap_set_t set2, pre_expr expr,
+ basic_block block)
+{
+ switch (expr->kind)
+ {
+ case NAME:
+ return bitmap_set_contains_expr (AVAIL_OUT (block), expr);
+ case NARY:
{
- if (TREE_CODE (expr) == CALL_EXPR)
+ unsigned int i;
+ vn_nary_op_t nary = PRE_EXPR_NARY (expr);
+ for (i = 0; i < nary->length; i++)
{
- tree fn = CALL_EXPR_FN (expr);
- tree sc = CALL_EXPR_STATIC_CHAIN (expr);
- tree arg;
- call_expr_arg_iterator iter;
-
- /* Check the non-argument operands first. */
- if (!union_contains_value (set1, set2, fn)
- || (sc && !union_contains_value (set1, set2, sc)))
- return false;
-
- /* Now check the operands. */
- FOR_EACH_CALL_EXPR_ARG (arg, iter, expr)
+ if (TREE_CODE (nary->op[i]) == SSA_NAME)
{
- if (!union_contains_value (set1, set2, arg))
+ struct pre_expr_d temp;
+ temp.kind = NAME;
+ temp.id = 0;
+ PRE_EXPR_NAME (&temp) = nary->op[i];
+ temp.id = lookup_expression_id (&temp);
+ if (temp.id == 0)
+ return false;
+ if (!union_contains_value (set1, set2,
+ get_expr_value_id (&temp)))
return false;
}
- return !value_dies_in_block_x (expr, block);
}
- return false;
+ return true;
}
-
- case tcc_reference:
+ break;
+ case REFERENCE:
{
- if (TREE_CODE (expr) == INDIRECT_REF
- || TREE_CODE (expr) == COMPONENT_REF
- || TREE_CODE (expr) == ARRAY_REF)
+ vn_reference_t ref = PRE_EXPR_REFERENCE (expr);
+ vn_reference_op_t vro;
+ unsigned int i;
+
+ for (i = 0; VEC_iterate (vn_reference_op_s, ref->operands, i, vro); i++)
{
- tree op0 = TREE_OPERAND (expr, 0);
- gcc_assert (is_gimple_min_invariant (op0)
- || TREE_CODE (op0) == VALUE_HANDLE);
- if (!union_contains_value (set1, set2, op0))
+ if (!vro_valid_in_sets (set1, set2, vro))
return false;
- if (TREE_CODE (expr) == ARRAY_REF)
- {
- tree op1 = TREE_OPERAND (expr, 1);
- tree op2 = TREE_OPERAND (expr, 2);
- tree op3 = TREE_OPERAND (expr, 3);
- gcc_assert (is_gimple_min_invariant (op1)
- || TREE_CODE (op1) == VALUE_HANDLE);
- if (!union_contains_value (set1, set2, op1))
- return false;
- gcc_assert (!op2 || is_gimple_min_invariant (op2)
- || TREE_CODE (op2) == VALUE_HANDLE);
- if (op2
- && !union_contains_value (set1, set2, op2))
- return false;
- gcc_assert (!op3 || is_gimple_min_invariant (op3)
- || TREE_CODE (op3) == VALUE_HANDLE);
- if (op3
- && !union_contains_value (set1, set2, op3))
- return false;
- }
- return !value_dies_in_block_x (expr, block);
}
+ return !value_dies_in_block_x (expr, block);
}
- return false;
-
- case tcc_exceptional:
- {
- gcc_assert (TREE_CODE (expr) == SSA_NAME);
- return bitmap_set_contains_expr (AVAIL_OUT (block), expr);
- }
-
- case tcc_declaration:
- return !value_dies_in_block_x (expr, block);
-
default:
- /* No other cases should be encountered. */
gcc_unreachable ();
- }
+ }
}
/* Clean the set of expressions that are no longer valid in SET1 or
@@ -1597,16 +1897,16 @@ valid_in_sets (bitmap_set_t set1, bitmap_set_t set2, tree expr,
static void
dependent_clean (bitmap_set_t set1, bitmap_set_t set2, basic_block block)
{
- VEC (tree, heap) *exprs = sorted_array_from_bitmap_set (set1);
- tree expr;
+ VEC (pre_expr, heap) *exprs = sorted_array_from_bitmap_set (set1);
+ pre_expr expr;
int i;
- for (i = 0; VEC_iterate (tree, exprs, i, expr); i++)
+ for (i = 0; VEC_iterate (pre_expr, exprs, i, expr); i++)
{
if (!valid_in_sets (set1, set2, expr, block))
bitmap_remove_from_set (set1, expr);
}
- VEC_free (tree, heap, exprs);
+ VEC_free (pre_expr, heap, exprs);
}
/* Clean the set of expressions that are no longer valid in SET. This
@@ -1616,16 +1916,16 @@ dependent_clean (bitmap_set_t set1, bitmap_set_t set2, basic_block block)
static void
clean (bitmap_set_t set, basic_block block)
{
- VEC (tree, heap) *exprs = sorted_array_from_bitmap_set (set);
- tree expr;
+ VEC (pre_expr, heap) *exprs = sorted_array_from_bitmap_set (set);
+ pre_expr expr;
int i;
- for (i = 0; VEC_iterate (tree, exprs, i, expr); i++)
+ for (i = 0; VEC_iterate (pre_expr, exprs, i, expr); i++)
{
if (!valid_in_sets (set, NULL, expr, block))
bitmap_remove_from_set (set, expr);
}
- VEC_free (tree, heap, exprs);
+ VEC_free (pre_expr, heap, exprs);
}
static sbitmap has_abnormal_preds;
@@ -1967,73 +2267,6 @@ compute_partial_antic_aux (basic_block block,
return changed;
}
-/* Initialize data structures used for ANTIC and AVAIL. */
-
-static void
-init_antic (void)
-{
- basic_block bb;
-
- next_expression_id = 0;
- expressions = NULL;
- expression_vuses = NULL;
-
- postorder = XNEWVEC (int, n_basic_blocks - NUM_FIXED_BLOCKS);
- post_order_compute (postorder, false, false);
-
- bitmap_obstack_initialize (&grand_bitmap_obstack);
- obstack_init (&temp_call_expr_obstack);
- seen_during_translate = BITMAP_ALLOC (&grand_bitmap_obstack);
-
- bitmap_set_pool = create_alloc_pool ("Bitmap sets",
- sizeof (struct bitmap_set), 30);
- binary_node_pool = create_alloc_pool ("Binary tree nodes",
- tree_code_size (PLUS_EXPR), 30);
- unary_node_pool = create_alloc_pool ("Unary tree nodes",
- tree_code_size (NEGATE_EXPR), 30);
- reference_node_pool = create_alloc_pool ("Reference tree nodes",
- tree_code_size (ARRAY_REF), 30);
- comparison_node_pool = create_alloc_pool ("Comparison tree nodes",
- tree_code_size (EQ_EXPR), 30);
-
- phi_translate_table = htab_create (5110, expr_pred_trans_hash,
- expr_pred_trans_eq, free);
- maximal_set = in_fre ? NULL : bitmap_set_new ();
-
- FOR_ALL_BB (bb)
- {
- bb->aux = xcalloc (1, sizeof (struct bb_bitmap_sets));
- EXP_GEN (bb) = bitmap_set_new ();
- PHI_GEN (bb) = bitmap_set_new ();
- TMP_GEN (bb) = bitmap_set_new ();
- AVAIL_OUT (bb) = bitmap_set_new ();
- }
-}
-
-/* Deinitialize data structures used for ANTIC and AVAIL. */
-
-static void
-fini_antic (void)
-{
- basic_block bb;
-
- if (maximal_set)
- bitmap_set_free (maximal_set);
- free (postorder);
- bitmap_obstack_release (&grand_bitmap_obstack);
- free_alloc_pool (bitmap_set_pool);
- free_alloc_pool (binary_node_pool);
- free_alloc_pool (reference_node_pool);
- free_alloc_pool (unary_node_pool);
- free_alloc_pool (comparison_node_pool);
-
- FOR_ALL_BB (bb)
- {
- free (bb->aux);
- bb->aux = NULL;
- }
-}
-
/* Compute ANTIC and partial ANTIC sets. */
static void
@@ -2142,11 +2375,9 @@ compute_antic (void)
if we have a pure or constant call. */
static bool
-can_value_number_call (tree stmt)
+can_value_number_call (gimple stmt)
{
- tree call = get_call_expr_in (stmt);
-
- if (call_expr_flags (call) & (ECF_PURE | ECF_CONST))
+ if (gimple_call_flags (stmt) & (ECF_PURE | ECF_CONST))
return true;
return false;
}
@@ -2155,27 +2386,13 @@ can_value_number_call (tree stmt)
FILTER_EXPR or EXC_PTR_EXPR. */
static bool
-is_exception_related (tree op)
+is_exception_related (gimple stmt)
{
- return TREE_CODE (op) == FILTER_EXPR || TREE_CODE (op) == EXC_PTR_EXPR;
+ return (is_gimple_assign (stmt)
+ && (gimple_assign_rhs_code (stmt) == FILTER_EXPR
+ || gimple_assign_rhs_code (stmt) == EXC_PTR_EXPR));
}
-/* Return true if OP is a tree which we can perform value numbering
- on. */
-
-static bool
-can_value_number_operation (tree op)
-{
- return (UNARY_CLASS_P (op)
- && !is_exception_related (TREE_OPERAND (op, 0)))
- || BINARY_CLASS_P (op)
- || COMPARISON_CLASS_P (op)
- || REFERENCE_CLASS_P (op)
- || (TREE_CODE (op) == CALL_EXPR
- && can_value_number_call (op));
-}
-
-
/* Return true if OP is a tree which we can perform PRE on
on. This may not match the operations we can value number, but in
a perfect world would. */
@@ -2197,12 +2414,12 @@ can_PRE_operation (tree op)
/* Inserted expressions are placed onto this worklist, which is used
for performing quick dead code elimination of insertions we made
that didn't turn out to be necessary. */
-static VEC(tree,heap) *inserted_exprs;
+static VEC(gimple,heap) *inserted_exprs;
/* Pool allocated fake store expressions are placed onto this
worklist, which, after performing dead code elimination, is walked
to see which expressions need to be put into GC'able memory */
-static VEC(tree, heap) *need_creation;
+static VEC(gimple, heap) *need_creation;
/* For COMPONENT_REF's and ARRAY_REF's, we can't have any intermediates for the
COMPONENT_REF or INDIRECT_REF or ARRAY_REF portion, because we'd end up with
@@ -2218,90 +2435,207 @@ static VEC(tree, heap) *need_creation;
are doing.
*/
static tree
-create_component_ref_by_pieces (basic_block block, tree expr, tree stmts,
- tree domstmt)
+create_component_ref_by_pieces (basic_block block, vn_reference_t ref,
+ unsigned int operand,
+ gimple_seq *stmts,
+ gimple domstmt,
+ bool in_call)
{
- tree genop = expr;
- tree folded;
-
- if (TREE_CODE (genop) == VALUE_HANDLE)
+ vn_reference_op_t currop = VEC_index (vn_reference_op_s, ref->operands,
+ operand);
+ tree genop;
+ switch (currop->opcode)
{
- tree found = bitmap_find_leader (AVAIL_OUT (block), expr, domstmt);
- if (found)
- return found;
- }
+ case CALL_EXPR:
+ {
+ tree folded;
+ unsigned int i;
+ vn_reference_op_t declop = VEC_index (vn_reference_op_s,
+ ref->operands, 1);
+ unsigned int nargs = VEC_length (vn_reference_op_s, ref->operands) - 2;
+ tree *args = XNEWVEC (tree, nargs);
- if (TREE_CODE (genop) == VALUE_HANDLE)
- {
- bitmap_set_t exprset = VALUE_HANDLE_EXPR_SET (expr);
- unsigned int firstbit = bitmap_first_set_bit (exprset->expressions);
- genop = expression_for_id (firstbit);
- }
+ for (i = 0; i < nargs; i++)
+ {
+ args[i] = create_component_ref_by_pieces (block, ref,
+ operand + 2 + i, stmts,
+ domstmt, true);
+ }
+ folded = build_call_array (currop->type,
+ TREE_CODE (declop->op0) == FUNCTION_DECL
+ ? build_fold_addr_expr (declop->op0)
+ : declop->op0,
+ nargs, args);
+ free (args);
+ return folded;
+ }
+ break;
+ case REALPART_EXPR:
+ case IMAGPART_EXPR:
+ case VIEW_CONVERT_EXPR:
+ {
+ tree folded;
+ tree genop0 = create_component_ref_by_pieces (block, ref,
+ operand + 1,
+ stmts, domstmt,
+ in_call);
+ if (!genop0)
+ return NULL_TREE;
+ folded = fold_build1 (currop->opcode, currop->type,
+ genop0);
+ return folded;
+ }
+ break;
+ case ALIGN_INDIRECT_REF:
+ case MISALIGNED_INDIRECT_REF:
+ case INDIRECT_REF:
+ {
+ /* Inside a CALL_EXPR op0 is the actual indirect_ref. */
+ if (in_call)
+ {
+ tree folded;
+ tree op0 = TREE_OPERAND (currop->op0, 0);
+ pre_expr op0expr = get_or_alloc_expr_for (op0);
+ tree genop0 = find_or_generate_expression (block, op0expr, stmts,
+ domstmt);
+ if (!genop0)
+ return NULL_TREE;
+ folded = fold_build1 (currop->opcode, currop->type,
+ genop0);
+ return folded;
+ }
+ else
+ {
- switch TREE_CODE (genop)
- {
- case ARRAY_REF:
+ tree folded;
+ tree genop1 = create_component_ref_by_pieces (block, ref,
+ operand + 1,
+ stmts, domstmt,
+ in_call);
+ if (!genop1)
+ return NULL_TREE;
+ genop1 = fold_convert (build_pointer_type (currop->type),
+ genop1);
+
+ folded = fold_build1 (currop->opcode, currop->type,
+ genop1);
+ return folded;
+ }
+ }
+ break;
+ case BIT_FIELD_REF:
{
- tree op0;
- tree op1, op2, op3;
- op0 = create_component_ref_by_pieces (block,
- TREE_OPERAND (genop, 0),
- stmts, domstmt);
- op1 = TREE_OPERAND (genop, 1);
- if (TREE_CODE (op1) == VALUE_HANDLE)
- op1 = find_or_generate_expression (block, op1, stmts, domstmt);
- op2 = TREE_OPERAND (genop, 2);
- if (op2 && TREE_CODE (op2) == VALUE_HANDLE)
- op2 = find_or_generate_expression (block, op2, stmts, domstmt);
- op3 = TREE_OPERAND (genop, 3);
- if (op3 && TREE_CODE (op3) == VALUE_HANDLE)
- op3 = find_or_generate_expression (block, op3, stmts, domstmt);
- if (!op0 || !op1)
+ tree folded;
+ tree genop0 = create_component_ref_by_pieces (block, ref, operand + 1,
+ stmts, domstmt,
+ in_call);
+ pre_expr op1expr = get_or_alloc_expr_for (currop->op0);
+ pre_expr op2expr = get_or_alloc_expr_for (currop->op1);
+ tree genop1;
+ tree genop2;
+
+ if (!genop0)
+ return NULL_TREE;
+ genop1 = find_or_generate_expression (block, op1expr, stmts, domstmt);
+ if (!genop1)
return NULL_TREE;
- folded = build4 (ARRAY_REF, TREE_TYPE (genop), op0, op1,
- op2, op3);
+ genop2 = find_or_generate_expression (block, op2expr, stmts, domstmt);
+ if (!genop2)
+ return NULL_TREE;
+ folded = fold_build3 (BIT_FIELD_REF, currop->type, genop0, genop1,
+ genop2);
return folded;
}
+
+ /* For array ref vn_reference_op's, operand 1 of the array ref
+ is op0 of the reference op and operand 3 of the array ref is
+ op1. */
+ case ARRAY_RANGE_REF:
+ case ARRAY_REF:
+ {
+ vn_reference_op_t op0expr;
+ tree genop0;
+ tree genop1 = currop->op0;
+ pre_expr op1expr;
+ tree genop2 = currop->op1;
+ pre_expr op2expr;
+ tree genop3;
+ op0expr = VEC_index (vn_reference_op_s, ref->operands, operand + 1);
+ genop0 = create_component_ref_by_pieces (block, ref, operand + 1,
+ stmts, domstmt,
+ in_call);
+ if (!genop0)
+ return NULL_TREE;
+ op1expr = get_or_alloc_expr_for (genop1);
+ genop1 = find_or_generate_expression (block, op1expr, stmts, domstmt);
+ if (!genop1)
+ return NULL_TREE;
+ if (genop2)
+ {
+ op2expr = get_or_alloc_expr_for (genop2);
+ genop2 = find_or_generate_expression (block, op2expr, stmts,
+ domstmt);
+ if (!genop2)
+ return NULL_TREE;
+ }
+
+ genop3 = currop->op2;
+ return build4 (currop->opcode, currop->type, genop0, genop1,
+ genop2, genop3);
+ }
case COMPONENT_REF:
{
tree op0;
tree op1;
- op0 = create_component_ref_by_pieces (block,
- TREE_OPERAND (genop, 0),
- stmts, domstmt);
+ tree genop2 = currop->op1;
+ pre_expr op2expr;
+ op0 = create_component_ref_by_pieces (block, ref, operand + 1,
+ stmts, domstmt, in_call);
if (!op0)
return NULL_TREE;
/* op1 should be a FIELD_DECL, which are represented by
themselves. */
- op1 = TREE_OPERAND (genop, 1);
- folded = fold_build3 (COMPONENT_REF, TREE_TYPE (genop), op0, op1,
- NULL_TREE);
- return folded;
+ op1 = currop->op0;
+ if (genop2)
+ {
+ op2expr = get_or_alloc_expr_for (genop2);
+ genop2 = find_or_generate_expression (block, op2expr, stmts,
+ domstmt);
+ if (!genop2)
+ return NULL_TREE;
+ }
+
+ return fold_build3 (COMPONENT_REF, TREE_TYPE (op1), op0, op1,
+ genop2);
}
break;
- case INDIRECT_REF:
+ case SSA_NAME:
{
- tree op1 = TREE_OPERAND (genop, 0);
- tree genop1 = find_or_generate_expression (block, op1, stmts, domstmt);
- if (!genop1)
- return NULL_TREE;
-
- folded = fold_build1 (TREE_CODE (genop), TREE_TYPE (genop),
- genop1);
- return folded;
+ pre_expr op0expr = get_or_alloc_expr_for (currop->op0);
+ genop = find_or_generate_expression (block, op0expr, stmts, domstmt);
+ return genop;
}
- break;
+ case STRING_CST:
+ case INTEGER_CST:
+ case COMPLEX_CST:
+ case VECTOR_CST:
+ case REAL_CST:
+ case CONSTRUCTOR:
case VAR_DECL:
case PARM_DECL:
+ case CONST_DECL:
case RESULT_DECL:
- case SSA_NAME:
- case STRING_CST:
- return genop;
+ case FUNCTION_DECL:
+ /* For ADDR_EXPR in a CALL_EXPR, op0 is actually the entire
+ ADDR_EXPR, not just it's operand. */
+ case ADDR_EXPR:
+ if (currop->opcode == ADDR_EXPR)
+ gcc_assert (currop->op0 != NULL);
+ return currop->op0;
+
default:
gcc_unreachable ();
}
-
- return NULL_TREE;
}
/* Find a leader for an expression, or generate one using
@@ -2318,31 +2652,40 @@ create_component_ref_by_pieces (basic_block block, tree expr, tree stmts,
on failure. */
static tree
-find_or_generate_expression (basic_block block, tree expr, tree stmts,
- tree domstmt)
+find_or_generate_expression (basic_block block, pre_expr expr,
+ gimple_seq *stmts, gimple domstmt)
{
- tree genop = bitmap_find_leader (AVAIL_OUT (block), expr, domstmt);
+ pre_expr leader = bitmap_find_leader (AVAIL_OUT (block),
+ get_expr_value_id (expr), domstmt);
+ tree genop = NULL;
+ if (leader)
+ {
+ if (leader->kind == NAME)
+ genop = PRE_EXPR_NAME (leader);
+ else if (leader->kind == CONSTANT)
+ genop = PRE_EXPR_CONSTANT (leader);
+ }
/* If it's still NULL, it must be a complex expression, so generate
it recursively. */
if (genop == NULL)
{
- bitmap_set_t exprset = VALUE_HANDLE_EXPR_SET (expr);
+ bitmap_set_t exprset;
+ unsigned int lookfor = get_expr_value_id (expr);
bool handled = false;
bitmap_iterator bi;
unsigned int i;
- /* We will hit cases where we have SSA_NAME's in exprset before
- other operations, because we may have come up with the SCCVN
- value before getting to the RHS of the expression. */
+ exprset = VEC_index (bitmap_set_t, value_expressions, lookfor);
FOR_EACH_EXPR_ID_IN_SET (exprset, i, bi)
{
- genop = expression_for_id (i);
- if (can_PRE_operation (genop))
+ pre_expr temp = expression_for_id (i);
+ if (temp->kind != NAME)
{
handled = true;
- genop = create_expression_by_pieces (block, genop, stmts,
- domstmt);
+ genop = create_expression_by_pieces (block, temp, stmts,
+ domstmt,
+ get_expr_type (expr));
break;
}
}
@@ -2354,7 +2697,8 @@ find_or_generate_expression (basic_block block, tree expr, tree stmts,
return genop;
}
-#define NECESSARY(stmt) stmt->base.asm_written_flag
+#define NECESSARY GF_PLF_1
+
/* Create an expression in pieces, so that we can handle very complex
expressions that may be ANTIC, but not necessary GIMPLE.
BLOCK is the basic block the expression will be inserted into,
@@ -2374,109 +2718,85 @@ find_or_generate_expression (basic_block block, tree expr, tree stmts,
can return NULL_TREE to signal failure. */
static tree
-create_expression_by_pieces (basic_block block, tree expr, tree stmts,
- tree domstmt)
+create_expression_by_pieces (basic_block block, pre_expr expr,
+ gimple_seq *stmts, gimple domstmt, tree type)
{
tree temp, name;
- tree folded, forced_stmts, newexpr;
- tree v;
- tree_stmt_iterator tsi;
-
- switch (TREE_CODE_CLASS (TREE_CODE (expr)))
+ tree folded, newexpr;
+ gimple_seq forced_stmts;
+ unsigned int value_id;
+ gimple_stmt_iterator gsi;
+ tree exprtype = type ? type : get_expr_type (expr);
+ pre_expr nameexpr;
+ gimple newstmt;
+
+ switch (expr->kind)
{
- case tcc_vl_exp:
+ /* We may hit the NAME/CONSTANT case if we have to convert types
+ that value numbering saw through. */
+ case NAME:
+ folded = PRE_EXPR_NAME (expr);
+ break;
+ case CONSTANT:
+ folded = PRE_EXPR_CONSTANT (expr);
+ break;
+ case REFERENCE:
{
- tree fn, sc;
- tree genfn;
- int i, nargs;
- tree *buffer;
-
- gcc_assert (TREE_CODE (expr) == CALL_EXPR);
-
- fn = CALL_EXPR_FN (expr);
- sc = CALL_EXPR_STATIC_CHAIN (expr);
-
- genfn = find_or_generate_expression (block, fn, stmts, domstmt);
- if (!genfn)
- return NULL_TREE;
-
- nargs = call_expr_nargs (expr);
- buffer = (tree*) alloca (nargs * sizeof (tree));
-
- for (i = 0; i < nargs; i++)
- {
- tree arg = CALL_EXPR_ARG (expr, i);
- buffer[i] = find_or_generate_expression (block, arg, stmts,
- domstmt);
- if (!buffer[i])
- return NULL_TREE;
- }
-
- folded = build_call_array (TREE_TYPE (expr), genfn, nargs, buffer);
- if (sc)
- {
- CALL_EXPR_STATIC_CHAIN (folded) =
- find_or_generate_expression (block, sc, stmts, domstmt);
- if (!CALL_EXPR_STATIC_CHAIN (folded))
- return NULL_TREE;
- }
- folded = fold (folded);
- break;
+ vn_reference_t ref = PRE_EXPR_REFERENCE (expr);
+ folded = create_component_ref_by_pieces (block, ref, 0, stmts,
+ domstmt, false);
}
break;
- case tcc_reference:
+ case NARY:
{
- if (TREE_CODE (expr) == COMPONENT_REF
- || TREE_CODE (expr) == ARRAY_REF)
- {
- folded = create_component_ref_by_pieces (block, expr, stmts,
- domstmt);
- if (!folded)
- return NULL_TREE;
- }
- else
+ vn_nary_op_t nary = PRE_EXPR_NARY (expr);
+ switch (nary->length)
{
- tree op1 = TREE_OPERAND (expr, 0);
- tree genop1 = find_or_generate_expression (block, op1, stmts,
- domstmt);
- if (!genop1)
- return NULL_TREE;
-
- folded = fold_build1 (TREE_CODE (expr), TREE_TYPE (expr),
- genop1);
+ case 2:
+ {
+ pre_expr op1 = get_or_alloc_expr_for (nary->op[0]);
+ pre_expr op2 = get_or_alloc_expr_for (nary->op[1]);
+ tree genop1 = find_or_generate_expression (block, op1,
+ stmts, domstmt);
+ tree genop2 = find_or_generate_expression (block, op2,
+ stmts, domstmt);
+ if (!genop1 || !genop2)
+ return NULL_TREE;
+ genop1 = fold_convert (TREE_TYPE (nary->op[0]),
+ genop1);
+ /* Ensure op2 is a sizetype for POINTER_PLUS_EXPR. It
+ may be a constant with the wrong type. */
+ if (nary->opcode == POINTER_PLUS_EXPR)
+ genop2 = fold_convert (sizetype, genop2);
+ else
+ genop2 = fold_convert (TREE_TYPE (nary->op[1]), genop2);
+
+ folded = fold_build2 (nary->opcode, nary->type,
+ genop1, genop2);
+ }
+ break;
+ case 1:
+ {
+ pre_expr op1 = get_or_alloc_expr_for (nary->op[0]);
+ tree genop1 = find_or_generate_expression (block, op1,
+ stmts, domstmt);
+ if (!genop1)
+ return NULL_TREE;
+ genop1 = fold_convert (TREE_TYPE (nary->op[0]), genop1);
+
+ folded = fold_build1 (nary->opcode, nary->type,
+ genop1);
+ }
+ break;
+ default:
+ return NULL_TREE;
}
- break;
- }
-
- case tcc_binary:
- case tcc_comparison:
- {
- tree op1 = TREE_OPERAND (expr, 0);
- tree op2 = TREE_OPERAND (expr, 1);
- tree genop1 = find_or_generate_expression (block, op1, stmts, domstmt);
- tree genop2 = find_or_generate_expression (block, op2, stmts, domstmt);
- if (!genop1 || !genop2)
- return NULL_TREE;
- folded = fold_build2 (TREE_CODE (expr), TREE_TYPE (expr),
- genop1, genop2);
- break;
}
-
- case tcc_unary:
- {
- tree op1 = TREE_OPERAND (expr, 0);
- tree genop1 = find_or_generate_expression (block, op1, stmts, domstmt);
- if (!genop1)
- return NULL_TREE;
- folded = fold_build1 (TREE_CODE (expr), TREE_TYPE (expr),
- genop1);
- break;
- }
-
+ break;
default:
- gcc_unreachable ();
+ return NULL_TREE;
}
-
+ folded = fold_convert (exprtype, folded);
/* Force the generated expression to be a sequence of GIMPLE
statements.
We have to call unshare_expr because force_gimple_operand may
@@ -2488,109 +2808,112 @@ create_expression_by_pieces (basic_block block, tree expr, tree stmts,
to the value sets and chain them in the instruction stream. */
if (forced_stmts)
{
- tsi = tsi_start (forced_stmts);
- for (; !tsi_end_p (tsi); tsi_next (&tsi))
+ gsi = gsi_start (forced_stmts);
+ for (; !gsi_end_p (gsi); gsi_next (&gsi))
{
- tree stmt = tsi_stmt (tsi);
- tree forcedname = GIMPLE_STMT_OPERAND (stmt, 0);
- tree forcedexpr = GIMPLE_STMT_OPERAND (stmt, 1);
- tree val = vn_lookup_or_add (forcedexpr);
-
- VEC_safe_push (tree, heap, inserted_exprs, stmt);
- VN_INFO_GET (forcedname)->valnum = forcedname;
- vn_add (forcedname, val);
- bitmap_value_replace_in_set (NEW_SETS (block), forcedname);
- bitmap_value_replace_in_set (AVAIL_OUT (block), forcedname);
+ gimple stmt = gsi_stmt (gsi);
+ tree forcedname = gimple_get_lhs (stmt);
+ pre_expr nameexpr;
+
+ VEC_safe_push (gimple, heap, inserted_exprs, stmt);
+ if (TREE_CODE (forcedname) == SSA_NAME)
+ {
+ VN_INFO_GET (forcedname)->valnum = forcedname;
+ VN_INFO (forcedname)->value_id = get_next_value_id ();
+ nameexpr = get_or_alloc_expr_for_name (forcedname);
+ add_to_value (VN_INFO (forcedname)->value_id, nameexpr);
+ bitmap_value_replace_in_set (NEW_SETS (block), nameexpr);
+ bitmap_value_replace_in_set (AVAIL_OUT (block), nameexpr);
+ }
mark_symbols_for_renaming (stmt);
}
- tsi = tsi_last (stmts);
- tsi_link_after (&tsi, forced_stmts, TSI_CONTINUE_LINKING);
+ gimple_seq_add_seq (stmts, forced_stmts);
}
/* Build and insert the assignment of the end result to the temporary
that we will return. */
- if (!pretemp || TREE_TYPE (expr) != TREE_TYPE (pretemp))
+ if (!pretemp || exprtype != TREE_TYPE (pretemp))
{
- pretemp = create_tmp_var (TREE_TYPE (expr), "pretmp");
+ pretemp = create_tmp_var (exprtype, "pretmp");
get_var_ann (pretemp);
}
temp = pretemp;
add_referenced_var (temp);
- if (TREE_CODE (TREE_TYPE (expr)) == COMPLEX_TYPE
- || TREE_CODE (TREE_TYPE (expr)) == VECTOR_TYPE)
+ if (TREE_CODE (exprtype) == COMPLEX_TYPE
+ || TREE_CODE (exprtype) == VECTOR_TYPE)
DECL_GIMPLE_REG_P (temp) = 1;
- newexpr = build_gimple_modify_stmt (temp, newexpr);
- name = make_ssa_name (temp, newexpr);
- GIMPLE_STMT_OPERAND (newexpr, 0) = name;
- NECESSARY (newexpr) = 0;
+ newstmt = gimple_build_assign (temp, newexpr);
+ name = make_ssa_name (temp, newstmt);
+ gimple_assign_set_lhs (newstmt, name);
+ gimple_set_plf (newstmt, NECESSARY, false);
- tsi = tsi_last (stmts);
- tsi_link_after (&tsi, newexpr, TSI_CONTINUE_LINKING);
- VEC_safe_push (tree, heap, inserted_exprs, newexpr);
+ gimple_seq_add_stmt (stmts, newstmt);
+ VEC_safe_push (gimple, heap, inserted_exprs, newstmt);
/* All the symbols in NEWEXPR should be put into SSA form. */
- mark_symbols_for_renaming (newexpr);
+ mark_symbols_for_renaming (newstmt);
- /* Add a value handle to the temporary.
+ /* Add a value number to the temporary.
The value may already exist in either NEW_SETS, or AVAIL_OUT, because
we are creating the expression by pieces, and this particular piece of
the expression may have been represented. There is no harm in replacing
here. */
- v = get_value_handle (expr);
- vn_add (name, v);
VN_INFO_GET (name)->valnum = name;
- get_or_alloc_expression_id (name);
+ value_id = get_expr_value_id (expr);
+ VN_INFO (name)->value_id = value_id;
+ nameexpr = get_or_alloc_expr_for_name (name);
+ add_to_value (value_id, nameexpr);
if (!in_fre)
- bitmap_value_replace_in_set (NEW_SETS (block), name);
- bitmap_value_replace_in_set (AVAIL_OUT (block), name);
+ bitmap_value_replace_in_set (NEW_SETS (block), nameexpr);
+ bitmap_value_replace_in_set (AVAIL_OUT (block), nameexpr);
pre_stats.insertions++;
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "Inserted ");
- print_generic_expr (dump_file, newexpr, 0);
+ print_gimple_stmt (dump_file, newstmt, 0, 0);
fprintf (dump_file, " in predecessor %d\n", block->index);
}
return name;
}
+
/* Insert the to-be-made-available values of expression EXPRNUM for each
predecessor, stored in AVAIL, into the predecessors of BLOCK, and
- merge the result with a phi node, given the same value handle as
+ merge the result with a phi node, given the same value number as
NODE. Return true if we have inserted new stuff. */
static bool
insert_into_preds_of_block (basic_block block, unsigned int exprnum,
- tree *avail)
+ pre_expr *avail)
{
- tree expr = expression_for_id (exprnum);
- tree val = get_value_handle (expr);
+ pre_expr expr = expression_for_id (exprnum);
+ pre_expr newphi;
+ unsigned int val = get_expr_value_id (expr);
edge pred;
bool insertions = false;
bool nophi = false;
basic_block bprime;
- tree eprime;
+ pre_expr eprime;
edge_iterator ei;
- tree type = TREE_TYPE (avail[EDGE_PRED (block, 0)->src->index]);
+ tree type = get_expr_type (expr);
tree temp;
+ gimple phi;
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "Found partial redundancy for expression ");
- print_generic_expr (dump_file, expr, 0);
- fprintf (dump_file, " (");
- print_generic_expr (dump_file, val, 0);
- fprintf (dump_file, ")");
- fprintf (dump_file, "\n");
+ print_pre_expr (dump_file, expr);
+ fprintf (dump_file, " (%04d)\n", val);
}
/* Make sure we aren't creating an induction variable. */
if (block->loop_depth > 0 && EDGE_COUNT (block->preds) == 2
- && TREE_CODE_CLASS (TREE_CODE (expr)) != tcc_reference )
+ && expr->kind != REFERENCE)
{
bool firstinsideloop = false;
bool secondinsideloop = false;
@@ -2611,21 +2934,109 @@ insert_into_preds_of_block (basic_block block, unsigned int exprnum,
/* Make the necessary insertions. */
FOR_EACH_EDGE (pred, ei, block->preds)
{
- tree stmts = alloc_stmt_list ();
+ gimple_seq stmts = NULL;
tree builtexpr;
bprime = pred->src;
eprime = avail[bprime->index];
- if (can_PRE_operation (eprime))
+ if (eprime->kind != NAME && eprime->kind != CONSTANT)
{
builtexpr = create_expression_by_pieces (bprime,
eprime,
- stmts, NULL_TREE);
+ &stmts, NULL,
+ type);
gcc_assert (!(pred->flags & EDGE_ABNORMAL));
- bsi_insert_on_edge (pred, stmts);
- avail[bprime->index] = builtexpr;
+ gsi_insert_seq_on_edge (pred, stmts);
+ avail[bprime->index] = get_or_alloc_expr_for_name (builtexpr);
insertions = true;
}
+ else if (eprime->kind == CONSTANT)
+ {
+ /* Constants may not have the right type, fold_convert
+ should give us back a constant with the right type.
+ */
+ tree constant = PRE_EXPR_CONSTANT (eprime);
+ if (TREE_TYPE (constant) != type)
+ {
+ tree builtexpr = fold_convert (type, constant);
+ if (is_gimple_min_invariant (builtexpr))
+ {
+ PRE_EXPR_CONSTANT (eprime) = builtexpr;
+ }
+ else
+ {
+ tree forcedexpr = force_gimple_operand (builtexpr,
+ &stmts, true,
+ NULL);
+ if (is_gimple_min_invariant (forcedexpr))
+ {
+ PRE_EXPR_CONSTANT (eprime) = forcedexpr;
+ }
+ else
+ {
+ if (forcedexpr != builtexpr)
+ {
+ VN_INFO_GET (forcedexpr)->valnum = PRE_EXPR_CONSTANT (eprime);
+ VN_INFO (forcedexpr)->value_id = get_expr_value_id (eprime);
+ }
+ if (stmts)
+ {
+ gimple_stmt_iterator gsi;
+ gsi = gsi_start (stmts);
+ for (; !gsi_end_p (gsi); gsi_next (&gsi))
+ {
+ gimple stmt = gsi_stmt (gsi);
+ VEC_safe_push (gimple, heap, inserted_exprs, stmt);
+ gimple_set_plf (stmt, NECESSARY, false);
+ }
+ gsi_insert_seq_on_edge (pred, stmts);
+ }
+ /* FIXME tuples
+ gimple_set_plf (forcedexpr, NECESSARY, false); */
+ avail[bprime->index] = get_or_alloc_expr_for_name (forcedexpr);
+ }
+ }
+ }
+ }
+ else if (eprime->kind == NAME)
+ {
+ /* We may have to do a conversion because our value
+ numbering can look through types in certain cases, but
+ our IL requires all operands of a phi node have the same
+ type. */
+ tree name = PRE_EXPR_NAME (eprime);
+ if (!useless_type_conversion_p (type, TREE_TYPE (name)))
+ {
+ tree builtexpr;
+ tree forcedexpr;
+ builtexpr = fold_convert (type, name);
+ forcedexpr = force_gimple_operand (builtexpr,
+ &stmts, true,
+ NULL);
+
+ if (forcedexpr != name)
+ {
+ VN_INFO_GET (forcedexpr)->valnum = VN_INFO (name)->valnum;
+ VN_INFO (forcedexpr)->value_id = VN_INFO (name)->value_id;
+ }
+
+ if (stmts)
+ {
+ gimple_stmt_iterator gsi;
+ gsi = gsi_start (stmts);
+ for (; !gsi_end_p (gsi); gsi_next (&gsi))
+ {
+ gimple stmt = gsi_stmt (gsi);
+ VEC_safe_push (gimple, heap, inserted_exprs, stmt);
+ gimple_set_plf (stmt, NECESSARY, false);
+ }
+ gsi_insert_seq_on_edge (pred, stmts);
+ }
+ /* FIXME tuples
+ gimple_set_plf (forcedexpr, NECESSARY, false); */
+ avail[bprime->index] = get_or_alloc_expr_for_name (forcedexpr);
+ }
+ }
}
/* If we didn't want a phi node, and we made insertions, we still have
inserted new stuff, and thus return true. If we didn't want a phi node,
@@ -2646,20 +3057,28 @@ insert_into_preds_of_block (basic_block block, unsigned int exprnum,
temp = prephitemp;
add_referenced_var (temp);
-
if (TREE_CODE (type) == COMPLEX_TYPE
|| TREE_CODE (type) == VECTOR_TYPE)
DECL_GIMPLE_REG_P (temp) = 1;
- temp = create_phi_node (temp, block);
+ phi = create_phi_node (temp, block);
- NECESSARY (temp) = 0;
- VN_INFO_GET (PHI_RESULT (temp))->valnum = PHI_RESULT (temp);
-
- VEC_safe_push (tree, heap, inserted_exprs, temp);
+ gimple_set_plf (phi, NECESSARY, false);
+ VN_INFO_GET (gimple_phi_result (phi))->valnum = gimple_phi_result (phi);
+ VN_INFO (gimple_phi_result (phi))->value_id = val;
+ VEC_safe_push (gimple, heap, inserted_exprs, phi);
FOR_EACH_EDGE (pred, ei, block->preds)
- add_phi_arg (temp, avail[pred->src->index], pred);
+ {
+ pre_expr ae = avail[pred->src->index];
+ gcc_assert (get_expr_type (ae) == type
+ || useless_type_conversion_p (type, get_expr_type (ae)));
+ if (ae->kind == CONSTANT)
+ add_phi_arg (phi, PRE_EXPR_CONSTANT (ae), pred);
+ else
+ add_phi_arg (phi, PRE_EXPR_NAME (avail[pred->src->index]), pred);
+ }
- vn_add (PHI_RESULT (temp), val);
+ newphi = get_or_alloc_expr_for_name (gimple_phi_result (phi));
+ add_to_value (val, newphi);
/* The value should *not* exist in PHI_GEN, or else we wouldn't be doing
this insertion, since we test for the existence of this value in PHI_GEN
@@ -2675,17 +3094,16 @@ insert_into_preds_of_block (basic_block block, unsigned int exprnum,
AVAIL_OUT, and would have been skipped due to the full redundancy check.
*/
- bitmap_insert_into_set (PHI_GEN (block),
- PHI_RESULT (temp));
+ bitmap_insert_into_set (PHI_GEN (block), newphi);
bitmap_value_replace_in_set (AVAIL_OUT (block),
- PHI_RESULT (temp));
+ newphi);
bitmap_insert_into_set (NEW_SETS (block),
- PHI_RESULT (temp));
+ newphi);
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "Created phi ");
- print_generic_expr (dump_file, temp, 0);
+ print_gimple_stmt (dump_file, phi, 0, 0);
fprintf (dump_file, " in block %d\n", block->index);
}
pre_stats.phis++;
@@ -2716,26 +3134,26 @@ static bool
do_regular_insertion (basic_block block, basic_block dom)
{
bool new_stuff = false;
- VEC (tree, heap) *exprs = sorted_array_from_bitmap_set (ANTIC_IN (block));
- tree expr;
+ VEC (pre_expr, heap) *exprs = sorted_array_from_bitmap_set (ANTIC_IN (block));
+ pre_expr expr;
int i;
- for (i = 0; VEC_iterate (tree, exprs, i, expr); i++)
+ for (i = 0; VEC_iterate (pre_expr, exprs, i, expr); i++)
{
- if (can_PRE_operation (expr) && !AGGREGATE_TYPE_P (TREE_TYPE (expr)))
+ if (expr->kind != NAME)
{
- tree *avail;
- tree val;
+ pre_expr *avail;
+ unsigned int val;
bool by_some = false;
bool cant_insert = false;
bool all_same = true;
- tree first_s = NULL;
+ pre_expr first_s = NULL;
edge pred;
basic_block bprime;
- tree eprime = NULL_TREE;
+ pre_expr eprime = NULL;
edge_iterator ei;
- val = get_value_handle (expr);
+ val = get_expr_value_id (expr);
if (bitmap_set_contains_value (PHI_GEN (block), val))
continue;
if (bitmap_set_contains_value (AVAIL_OUT (dom), val))
@@ -2745,11 +3163,11 @@ do_regular_insertion (basic_block block, basic_block dom)
continue;
}
- avail = XCNEWVEC (tree, last_basic_block);
+ avail = XCNEWVEC (pre_expr, last_basic_block);
FOR_EACH_EDGE (pred, ei, block->preds)
{
- tree vprime;
- tree edoubleprime;
+ unsigned int vprime;
+ pre_expr edoubleprime;
/* This can happen in the very weird case
that our fake infinite loop edges have caused a
@@ -2779,10 +3197,9 @@ do_regular_insertion (basic_block block, basic_block dom)
}
eprime = fully_constant_expression (eprime);
- vprime = get_value_handle (eprime);
- gcc_assert (vprime);
+ vprime = get_expr_value_id (eprime);
edoubleprime = bitmap_find_leader (AVAIL_OUT (bprime),
- vprime, NULL_TREE);
+ vprime, NULL);
if (edoubleprime == NULL)
{
avail[bprime->index] = eprime;
@@ -2794,8 +3211,7 @@ do_regular_insertion (basic_block block, basic_block dom)
by_some = true;
if (first_s == NULL)
first_s = edoubleprime;
- else if (!operand_equal_p (first_s, edoubleprime,
- 0))
+ else if (!pre_expr_eq (first_s, edoubleprime))
all_same = false;
}
}
@@ -2803,7 +3219,7 @@ do_regular_insertion (basic_block block, basic_block dom)
already existing along every predecessor, and
it's defined by some predecessor, it is
partially redundant. */
- if (!cant_insert && !all_same && by_some)
+ if (!cant_insert && !all_same && by_some && dbg_cnt (treepre_insert))
{
if (insert_into_preds_of_block (block, get_expression_id (expr),
avail))
@@ -2813,19 +3229,26 @@ do_regular_insertion (basic_block block, basic_block dom)
an invariant, then the PHI has the same value on all
edges. Note this. */
else if (!cant_insert && all_same && eprime
- && is_gimple_min_invariant (eprime)
- && !is_gimple_min_invariant (val))
+ && eprime->kind == CONSTANT
+ && !value_id_constant_p (val))
{
unsigned int j;
bitmap_iterator bi;
+ bitmap_set_t exprset = VEC_index (bitmap_set_t,
+ value_expressions, val);
- bitmap_set_t exprset = VALUE_HANDLE_EXPR_SET (val);
+ unsigned int new_val = get_expr_value_id (eprime);
FOR_EACH_EXPR_ID_IN_SET (exprset, j, bi)
{
- tree expr = expression_for_id (j);
- if (TREE_CODE (expr) == SSA_NAME)
+ pre_expr expr = expression_for_id (j);
+
+ if (expr->kind == NAME)
{
- vn_add (expr, eprime);
+ vn_ssa_aux_t info = VN_INFO (PRE_EXPR_NAME (expr));
+ /* Just reset the value id and valnum so it is
+ the same as the constant we have discovered. */
+ info->valnum = PRE_EXPR_CONSTANT (eprime);
+ info->value_id = new_val;
pre_stats.constified++;
}
}
@@ -2834,7 +3257,7 @@ do_regular_insertion (basic_block block, basic_block dom)
}
}
- VEC_free (tree, heap, exprs);
+ VEC_free (pre_expr, heap, exprs);
return new_stuff;
}
@@ -2850,34 +3273,34 @@ static bool
do_partial_partial_insertion (basic_block block, basic_block dom)
{
bool new_stuff = false;
- VEC (tree, heap) *exprs = sorted_array_from_bitmap_set (PA_IN (block));
- tree expr;
+ VEC (pre_expr, heap) *exprs = sorted_array_from_bitmap_set (PA_IN (block));
+ pre_expr expr;
int i;
- for (i = 0; VEC_iterate (tree, exprs, i, expr); i++)
+ for (i = 0; VEC_iterate (pre_expr, exprs, i, expr); i++)
{
- if (can_PRE_operation (expr) && !AGGREGATE_TYPE_P (TREE_TYPE (expr)))
+ if (expr->kind != NAME)
{
- tree *avail;
- tree val;
+ pre_expr *avail;
+ unsigned int val;
bool by_all = true;
bool cant_insert = false;
edge pred;
basic_block bprime;
- tree eprime = NULL_TREE;
+ pre_expr eprime = NULL;
edge_iterator ei;
- val = get_value_handle (expr);
+ val = get_expr_value_id (expr);
if (bitmap_set_contains_value (PHI_GEN (block), val))
continue;
if (bitmap_set_contains_value (AVAIL_OUT (dom), val))
continue;
- avail = XCNEWVEC (tree, last_basic_block);
+ avail = XCNEWVEC (pre_expr, last_basic_block);
FOR_EACH_EDGE (pred, ei, block->preds)
{
- tree vprime;
- tree edoubleprime;
+ unsigned int vprime;
+ pre_expr edoubleprime;
/* This can happen in the very weird case
that our fake infinite loop edges have caused a
@@ -2908,10 +3331,9 @@ do_partial_partial_insertion (basic_block block, basic_block dom)
}
eprime = fully_constant_expression (eprime);
- vprime = get_value_handle (eprime);
- gcc_assert (vprime);
+ vprime = get_expr_value_id (eprime);
edoubleprime = bitmap_find_leader (AVAIL_OUT (bprime),
- vprime, NULL_TREE);
+ vprime, NULL);
if (edoubleprime == NULL)
{
by_all = false;
@@ -2926,7 +3348,7 @@ do_partial_partial_insertion (basic_block block, basic_block dom)
already existing along every predecessor, and
it's defined by some predecessor, it is
partially redundant. */
- if (!cant_insert && by_all)
+ if (!cant_insert && by_all && dbg_cnt (treepre_insert))
{
pre_stats.pa_insert++;
if (insert_into_preds_of_block (block, get_expression_id (expr),
@@ -2937,7 +3359,7 @@ do_partial_partial_insertion (basic_block block, basic_block dom)
}
}
- VEC_free (tree, heap, exprs);
+ VEC_free (pre_expr, heap, exprs);
return new_stuff;
}
@@ -2964,7 +3386,7 @@ insert_aux (basic_block block)
to replace it with. */
FOR_EACH_EXPR_ID_IN_SET (newset, i, bi)
{
- tree expr = expression_for_id (i);
+ pre_expr expr = expression_for_id (i);
bitmap_value_replace_in_set (NEW_SETS (block), expr);
bitmap_value_replace_in_set (AVAIL_OUT (block), expr);
}
@@ -3019,163 +3441,19 @@ add_to_exp_gen (basic_block block, tree op)
{
if (!in_fre)
{
+ pre_expr result;
if (TREE_CODE (op) == SSA_NAME && ssa_undefined_value_p (op))
return;
- bitmap_value_insert_into_set (EXP_GEN (block), op);
+ result = get_or_alloc_expr_for_name (op);
+ bitmap_value_insert_into_set (EXP_GEN (block), result);
if (TREE_CODE (op) != SSA_NAME
- || TREE_CODE (SSA_NAME_DEF_STMT (op)) != PHI_NODE)
- bitmap_value_insert_into_set (maximal_set, op);
- }
-}
-
-
-/* Given an SSA variable VAR and an expression EXPR, compute the value
- number for EXPR and create a value handle (VAL) for it. If VAR and
- EXPR are not the same, associate VAL with VAR. Finally, add VAR to
- S1 and its value handle to S2, and to the maximal set if
- ADD_TO_MAXIMAL is true.
-
- VUSES represent the virtual use operands associated with EXPR (if
- any). */
-
-static inline void
-add_to_sets (tree var, tree expr, VEC(tree, gc) *vuses, bitmap_set_t s1,
- bitmap_set_t s2)
-{
- tree val;
- val = vn_lookup_or_add_with_vuses (expr, vuses);
-
- /* VAR and EXPR may be the same when processing statements for which
- we are not computing value numbers (e.g., non-assignments, or
- statements that make aliased stores). In those cases, we are
- only interested in making VAR available as its own value. */
- if (var != expr)
- vn_add (var, val);
-
- if (s1)
- bitmap_insert_into_set (s1, var);
-
- bitmap_value_insert_into_set (s2, var);
-}
-
-/* Find existing value expression that is the same as T,
- and return it if it exists. */
-
-static inline tree
-find_existing_value_expr (tree t, VEC (tree, gc) *vuses)
-{
- bitmap_iterator bi;
- unsigned int bii;
- tree vh;
- bitmap_set_t exprset;
-
- if (REFERENCE_CLASS_P (t) || TREE_CODE (t) == CALL_EXPR || DECL_P (t))
- vh = vn_lookup_with_vuses (t, vuses);
- else
- vh = vn_lookup (t);
-
- if (!vh)
- return NULL;
- exprset = VALUE_HANDLE_EXPR_SET (vh);
- FOR_EACH_EXPR_ID_IN_SET (exprset, bii, bi)
- {
- tree efi = expression_for_id (bii);
- if (expressions_equal_p (t, efi))
- return efi;
- }
- return NULL;
-}
-
-/* Given a unary or binary expression EXPR, create and return a new
- expression with the same structure as EXPR but with its operands
- replaced with the value handles of each of the operands of EXPR.
-
- VUSES represent the virtual use operands associated with EXPR (if
- any). Insert EXPR's operands into the EXP_GEN set for BLOCK.
-
- If CHECK_AVAIL is true, checks availability of each operand in
- BLOCKs AVAIL_OUT set. */
-
-static inline tree
-create_value_expr_from (tree expr, basic_block block, VEC (tree, gc) *vuses,
- bool check_avail)
-{
- int i;
- enum tree_code code = TREE_CODE (expr);
- tree vexpr;
- alloc_pool pool = NULL;
- tree efi;
-
- gcc_assert (TREE_CODE_CLASS (code) == tcc_unary
- || TREE_CODE_CLASS (code) == tcc_binary
- || TREE_CODE_CLASS (code) == tcc_comparison
- || TREE_CODE_CLASS (code) == tcc_reference
- || TREE_CODE_CLASS (code) == tcc_expression
- || TREE_CODE_CLASS (code) == tcc_vl_exp
- || TREE_CODE_CLASS (code) == tcc_exceptional
- || TREE_CODE_CLASS (code) == tcc_declaration);
-
- if (TREE_CODE_CLASS (code) == tcc_unary)
- pool = unary_node_pool;
- else if (TREE_CODE_CLASS (code) == tcc_reference)
- pool = reference_node_pool;
- else if (TREE_CODE_CLASS (code) == tcc_binary)
- pool = binary_node_pool;
- else if (TREE_CODE_CLASS (code) == tcc_comparison)
- pool = comparison_node_pool;
- else
- gcc_assert (code == CALL_EXPR);
-
- if (code == CALL_EXPR)
- vexpr = temp_copy_call_expr (expr);
- else
- {
- vexpr = (tree) pool_alloc (pool);
- memcpy (vexpr, expr, tree_size (expr));
+ || gimple_code (SSA_NAME_DEF_STMT (op)) != GIMPLE_PHI)
+ bitmap_value_insert_into_set (maximal_set, result);
}
-
- for (i = 0; i < TREE_OPERAND_LENGTH (expr); i++)
- {
- tree val = NULL_TREE;
- tree op;
-
- op = TREE_OPERAND (expr, i);
- if (op == NULL_TREE)
- continue;
-
- /* Recursively value-numberize reference ops and tree lists. */
- if (REFERENCE_CLASS_P (op))
- {
- tree tempop = create_value_expr_from (op, block, vuses, check_avail);
- op = tempop ? tempop : op;
- val = vn_lookup_or_add_with_vuses (op, vuses);
- set_expression_vuses (op, vuses);
- }
- else
- {
- val = vn_lookup_or_add (op);
- }
- if (TREE_CODE (op) != TREE_LIST)
- add_to_exp_gen (block, op);
-
- if (TREE_CODE (val) == VALUE_HANDLE)
- TREE_TYPE (val) = TREE_TYPE (TREE_OPERAND (vexpr, i));
-
- TREE_OPERAND (vexpr, i) = val;
-
- if (check_avail
- && TREE_CODE (val) == VALUE_HANDLE
- && !bitmap_set_contains_value (AVAIL_OUT (block), val))
- return NULL_TREE;
- }
- efi = find_existing_value_expr (vexpr, vuses);
- if (efi)
- return efi;
- get_or_alloc_expression_id (vexpr);
- return vexpr;
}
-
+/* FIXME tuples */
+#if 0
/* For each real store operation of the form
*a = <value> that we see, create a corresponding fake store of the
form storetmp_<version> = *a.
@@ -3195,10 +3473,10 @@ insert_fake_stores (void)
FOR_ALL_BB (block)
{
- block_stmt_iterator bsi;
- for (bsi = bsi_start (block); !bsi_end_p (bsi); bsi_next (&bsi))
+ gimple_stmt_iterator gsi;
+ for (gsi = gsi_start_bb (block); !gsi_end_p (gsi); gsi_next (&gsi))
{
- tree stmt = bsi_stmt (bsi);
+ gimple stmt = gsi_stmt (gsi);
/* We can't generate SSA names for stores that are complex
or aggregate. We also want to ignore things whose
@@ -3243,9 +3521,9 @@ insert_fake_stores (void)
GIMPLE_STMT_OPERAND (new_tree, 0) = new_lhs;
create_ssa_artificial_load_stmt (new_tree, stmt, false);
- NECESSARY (new_tree) = 0;
- VEC_safe_push (tree, heap, inserted_exprs, new_tree);
- VEC_safe_push (tree, heap, need_creation, new_tree);
+ gimple_set_plf (new_tree, NECESSARY, false);
+ VEC_safe_push (gimple, heap, inserted_exprs, new_tree);
+ VEC_safe_push (gimple, heap, need_creation, new_tree);
bsi_insert_after (&bsi, new_tree, BSI_NEW_STMT);
}
}
@@ -3262,9 +3540,9 @@ realify_fake_stores (void)
unsigned int i;
tree stmt;
- for (i = 0; VEC_iterate (tree, need_creation, i, stmt); i++)
+ for (i = 0; VEC_iterate (gimple, need_creation, i, stmt); i++)
{
- if (NECESSARY (stmt))
+ if (gimple_plf (stmt, NECESSARY))
{
block_stmt_iterator bsi, bsi2;
tree rhs;
@@ -3286,185 +3564,26 @@ realify_fake_stores (void)
release_defs (stmt);
}
}
+#endif
-/* Given an SSA_NAME, see if SCCVN has a value number for it, and if
- so, return the value handle for this value number, creating it if
- necessary.
- Return NULL if SCCVN has no info for us. */
-
-static tree
-get_sccvn_value (tree name)
-{
- if (TREE_CODE (name) == SSA_NAME
- && VN_INFO (name)->valnum != name
- && VN_INFO (name)->valnum != VN_TOP)
- {
- tree val = VN_INFO (name)->valnum;
- bool is_invariant = is_gimple_min_invariant (val);
- tree valvh = !is_invariant ? get_value_handle (val) : NULL_TREE;
-
- /* We may end up with situations where SCCVN has chosen a
- representative for the equivalence set that we have not
- visited yet. In this case, just create the value handle for
- it. */
- if (!valvh && !is_invariant)
- {
- /* We lookup with the LHS, so do not use vn_lookup_or_add_with_stmt
- here, as that will result in useless reference lookups. */
- valvh = vn_lookup_or_add (val);
- }
-
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file, "SCCVN says ");
- print_generic_expr (dump_file, name, 0);
- fprintf (dump_file, " value numbers to ");
- if (valvh && !is_invariant)
- {
- print_generic_expr (dump_file, val, 0);
- fprintf (dump_file, " (");
- print_generic_expr (dump_file, valvh, 0);
- fprintf (dump_file, ")\n");
- }
- else
- print_generic_stmt (dump_file, val, 0);
- }
- if (valvh)
- return valvh;
- else
- return val;
- }
- return NULL_TREE;
-}
-
-/* Create value handles for PHI in BLOCK. */
+/* Create value ids for PHI in BLOCK. */
static void
-make_values_for_phi (tree phi, basic_block block)
+make_values_for_phi (gimple phi, basic_block block)
{
- tree result = PHI_RESULT (phi);
+ tree result = gimple_phi_result (phi);
+
/* We have no need for virtual phis, as they don't represent
actual computations. */
if (is_gimple_reg (result))
{
- tree sccvnval = get_sccvn_value (result);
- if (sccvnval)
- {
- vn_add (result, sccvnval);
- bitmap_insert_into_set (PHI_GEN (block), result);
- bitmap_value_insert_into_set (AVAIL_OUT (block), result);
- }
- else
- add_to_sets (result, result, NULL,
- PHI_GEN (block), AVAIL_OUT (block));
+ pre_expr e = get_or_alloc_expr_for_name (result);
+ add_to_value (get_expr_value_id (e), e);
+ bitmap_insert_into_set (PHI_GEN (block), e);
+ bitmap_value_insert_into_set (AVAIL_OUT (block), e);
}
}
-/* Create value handles for STMT in BLOCK. Return true if we handled
- the statement. */
-
-static bool
-make_values_for_stmt (tree stmt, basic_block block)
-{
-
- tree lhs = GIMPLE_STMT_OPERAND (stmt, 0);
- tree rhs = GIMPLE_STMT_OPERAND (stmt, 1);
- tree valvh = NULL_TREE;
- tree lhsval;
- VEC (tree, gc) *vuses = NULL;
-
- valvh = get_sccvn_value (lhs);
-
- if (valvh)
- {
- vn_add (lhs, valvh);
- bitmap_value_insert_into_set (AVAIL_OUT (block), lhs);
- /* Shortcut for FRE. We have no need to create value expressions,
- just want to know what values are available where. */
- if (in_fre)
- return true;
-
- }
- else if (in_fre)
- {
- /* For FRE, if SCCVN didn't find anything, we aren't going to
- either, so just make up a new value number if necessary and
- call it a day */
- if (get_value_handle (lhs) == NULL)
- vn_lookup_or_add (lhs);
- bitmap_value_insert_into_set (AVAIL_OUT (block), lhs);
- return true;
- }
-
- lhsval = valvh ? valvh : get_value_handle (lhs);
- vuses = copy_vuses_from_stmt (stmt);
- STRIP_USELESS_TYPE_CONVERSION (rhs);
- if (can_value_number_operation (rhs)
- && (!lhsval || !is_gimple_min_invariant (lhsval))
- && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs))
- {
- /* For value numberable operation, create a
- duplicate expression with the operands replaced
- with the value handles of the original RHS. */
- tree newt = create_value_expr_from (rhs, block, vuses, false);
- if (newt)
- {
- set_expression_vuses (newt, vuses);
- /* If we already have a value number for the LHS, reuse
- it rather than creating a new one. */
- if (lhsval)
- {
- set_value_handle (newt, lhsval);
- if (!is_gimple_min_invariant (lhsval))
- add_to_value (lhsval, newt);
- }
- else
- {
- tree val = vn_lookup_or_add_with_vuses (newt, vuses);
- vn_add (lhs, val);
- }
-
- add_to_exp_gen (block, newt);
- }
-
- bitmap_insert_into_set (TMP_GEN (block), lhs);
- bitmap_value_insert_into_set (AVAIL_OUT (block), lhs);
- return true;
- }
- else if ((TREE_CODE (rhs) == SSA_NAME
- && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs))
- || is_gimple_min_invariant (rhs)
- || TREE_CODE (rhs) == ADDR_EXPR
- || DECL_P (rhs))
- {
-
- if (lhsval)
- {
- set_expression_vuses (rhs, vuses);
- set_value_handle (rhs, lhsval);
- if (!is_gimple_min_invariant (lhsval))
- add_to_value (lhsval, rhs);
- bitmap_insert_into_set (TMP_GEN (block), lhs);
- bitmap_value_insert_into_set (AVAIL_OUT (block), lhs);
- }
- else
- {
- /* Compute a value number for the RHS of the statement
- and add its value to the AVAIL_OUT set for the block.
- Add the LHS to TMP_GEN. */
- set_expression_vuses (rhs, vuses);
- add_to_sets (lhs, rhs, vuses, TMP_GEN (block),
- AVAIL_OUT (block));
- }
- /* None of the rest of these can be PRE'd. */
- if (TREE_CODE (rhs) == SSA_NAME && !ssa_undefined_value_p (rhs))
- add_to_exp_gen (block, rhs);
- return true;
- }
- return false;
-
-}
-
/* Compute the AVAIL set for all basic blocks.
This function performs value numbering of the statements in each basic
@@ -3478,6 +3597,7 @@ make_values_for_stmt (tree stmt, basic_block block)
static void
compute_avail (void)
{
+
basic_block block, son;
basic_block *worklist;
size_t sp = 0;
@@ -3492,14 +3612,15 @@ compute_avail (void)
if (gimple_default_def (cfun, param) != NULL)
{
tree def = gimple_default_def (cfun, param);
+ pre_expr e = get_or_alloc_expr_for_name (def);
- vn_lookup_or_add (def);
+ add_to_value (get_expr_value_id (e), e);
if (!in_fre)
{
- bitmap_insert_into_set (TMP_GEN (ENTRY_BLOCK_PTR), def);
- bitmap_value_insert_into_set (maximal_set, def);
+ bitmap_insert_into_set (TMP_GEN (ENTRY_BLOCK_PTR), e);
+ bitmap_value_insert_into_set (maximal_set, e);
}
- bitmap_value_insert_into_set (AVAIL_OUT (ENTRY_BLOCK_PTR), def);
+ bitmap_value_insert_into_set (AVAIL_OUT (ENTRY_BLOCK_PTR), e);
}
}
@@ -3510,14 +3631,15 @@ compute_avail (void)
if (gimple_default_def (cfun, param) != NULL)
{
tree def = gimple_default_def (cfun, param);
+ pre_expr e = get_or_alloc_expr_for_name (def);
- vn_lookup_or_add (def);
+ add_to_value (get_expr_value_id (e), e);
if (!in_fre)
{
- bitmap_insert_into_set (TMP_GEN (ENTRY_BLOCK_PTR), def);
- bitmap_value_insert_into_set (maximal_set, def);
+ bitmap_insert_into_set (TMP_GEN (ENTRY_BLOCK_PTR), e);
+ bitmap_value_insert_into_set (maximal_set, e);
}
- bitmap_value_insert_into_set (AVAIL_OUT (ENTRY_BLOCK_PTR), def);
+ bitmap_value_insert_into_set (AVAIL_OUT (ENTRY_BLOCK_PTR), e);
}
}
@@ -3534,8 +3656,8 @@ compute_avail (void)
/* Loop until the worklist is empty. */
while (sp)
{
- block_stmt_iterator bsi;
- tree stmt, phi;
+ gimple_stmt_iterator gsi;
+ gimple stmt;
basic_block dom;
unsigned int stmt_uid = 1;
@@ -3549,81 +3671,171 @@ compute_avail (void)
bitmap_set_copy (AVAIL_OUT (block), AVAIL_OUT (dom));
/* Generate values for PHI nodes. */
- for (phi = phi_nodes (block); phi; phi = PHI_CHAIN (phi))
- make_values_for_phi (phi, block);
+ for (gsi = gsi_start_phis (block); !gsi_end_p (gsi); gsi_next (&gsi))
+ make_values_for_phi (gsi_stmt (gsi), block);
/* Now compute value numbers and populate value sets with all
the expressions computed in BLOCK. */
- for (bsi = bsi_start (block); !bsi_end_p (bsi); bsi_next (&bsi))
+ for (gsi = gsi_start_bb (block); !gsi_end_p (gsi); gsi_next (&gsi))
{
- stmt_ann_t ann;
ssa_op_iter iter;
tree op;
- stmt = bsi_stmt (bsi);
- ann = stmt_ann (stmt);
-
- set_gimple_stmt_uid (stmt, stmt_uid++);
+ stmt = gsi_stmt (gsi);
+ gimple_set_uid (stmt, stmt_uid++);
- /* For regular value numbering, we are only interested in
- assignments of the form X_i = EXPR, where EXPR represents
- an "interesting" computation, it has no volatile operands
- and X_i doesn't flow through an abnormal edge. */
- if (TREE_CODE (stmt) == RETURN_EXPR
- && !ann->has_volatile_ops)
+ FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_DEF)
{
- tree realstmt = stmt;
- tree lhs;
- tree rhs;
+ pre_expr e = get_or_alloc_expr_for_name (op);
- stmt = TREE_OPERAND (stmt, 0);
- if (stmt && TREE_CODE (stmt) == GIMPLE_MODIFY_STMT)
+ add_to_value (get_expr_value_id (e), e);
+ if (!in_fre)
{
- lhs = GIMPLE_STMT_OPERAND (stmt, 0);
- rhs = GIMPLE_STMT_OPERAND (stmt, 1);
- if (TREE_CODE (lhs) == SSA_NAME
- && is_gimple_min_invariant (VN_INFO (lhs)->valnum))
+ bitmap_insert_into_set (TMP_GEN (block), e);
+ bitmap_value_insert_into_set (maximal_set, e);
+ }
+ bitmap_value_insert_into_set (AVAIL_OUT (block), e);
+ }
+
+ if (gimple_has_volatile_ops (stmt)
+ || stmt_could_throw_p (stmt))
+ continue;
+
+ switch (gimple_code (stmt))
+ {
+ case GIMPLE_RETURN:
+ FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_USE)
+ add_to_exp_gen (block, op);
+ continue;
+
+ case GIMPLE_CALL:
+ {
+ vn_reference_t ref;
+ unsigned int i;
+ vn_reference_op_t vro;
+ pre_expr result = NULL;
+ VEC(vn_reference_op_s, heap) *ops = NULL;
+
+ if (!can_value_number_call (stmt))
+ continue;
+
+ copy_reference_ops_from_call (stmt, &ops);
+ vn_reference_lookup_pieces (shared_vuses_from_stmt (stmt),
+ ops, &ref);
+ VEC_free (vn_reference_op_s, heap, ops);
+ if (!ref)
+ continue;
+
+ for (i = 0; VEC_iterate (vn_reference_op_s,
+ ref->operands, i,
+ vro); i++)
+ {
+ if (vro->op0 && TREE_CODE (vro->op0) == SSA_NAME)
+ add_to_exp_gen (block, vro->op0);
+ if (vro->op1 && TREE_CODE (vro->op1) == SSA_NAME)
+ add_to_exp_gen (block, vro->op1);
+ }
+ result = (pre_expr) pool_alloc (pre_expr_pool);
+ result->kind = REFERENCE;
+ result->id = 0;
+ PRE_EXPR_REFERENCE (result) = ref;
+
+ get_or_alloc_expression_id (result);
+ add_to_value (get_expr_value_id (result), result);
+ if (!in_fre)
+ {
+ bitmap_value_insert_into_set (EXP_GEN (block),
+ result);
+ bitmap_value_insert_into_set (maximal_set, result);
+ }
+ continue;
+ }
+
+ case GIMPLE_ASSIGN:
+ {
+ pre_expr result = NULL;
+ switch (TREE_CODE_CLASS (gimple_assign_rhs_code (stmt)))
+ {
+ case tcc_unary:
+ if (is_exception_related (stmt))
+ continue;
+ case tcc_binary:
{
- if (dump_file && (dump_flags & TDF_DETAILS))
+ vn_nary_op_t nary;
+ unsigned int i;
+
+ vn_nary_op_lookup_pieces (gimple_num_ops (stmt) - 1,
+ gimple_assign_rhs_code (stmt),
+ gimple_expr_type (stmt),
+ gimple_assign_rhs1 (stmt),
+ gimple_assign_rhs2 (stmt),
+ NULL_TREE, NULL_TREE, &nary);
+
+ if (!nary)
+ continue;
+
+ for (i = 0; i < nary->length; i++)
+ if (TREE_CODE (nary->op[i]) == SSA_NAME)
+ add_to_exp_gen (block, nary->op[i]);
+
+ result = (pre_expr) pool_alloc (pre_expr_pool);
+ result->kind = NARY;
+ result->id = 0;
+ PRE_EXPR_NARY (result) = nary;
+ break;
+ }
+
+ case tcc_declaration:
+ case tcc_reference:
+ {
+ vn_reference_t ref;
+ unsigned int i;
+ vn_reference_op_t vro;
+
+ vn_reference_lookup (gimple_assign_rhs1 (stmt),
+ shared_vuses_from_stmt (stmt),
+ false, &ref);
+ if (!ref)
+ continue;
+
+ for (i = 0; VEC_iterate (vn_reference_op_s,
+ ref->operands, i,
+ vro); i++)
{
- fprintf (dump_file, "SCCVN says ");
- print_generic_expr (dump_file, lhs, 0);
- fprintf (dump_file, " value numbers to ");
- print_generic_stmt (dump_file, VN_INFO (lhs)->valnum,
- 0);
+ if (vro->op0 && TREE_CODE (vro->op0) == SSA_NAME)
+ add_to_exp_gen (block, vro->op0);
+ if (vro->op1 && TREE_CODE (vro->op1) == SSA_NAME)
+ add_to_exp_gen (block, vro->op1);
}
- vn_add (lhs, VN_INFO (lhs)->valnum);
- continue;
+ result = (pre_expr) pool_alloc (pre_expr_pool);
+ result->kind = REFERENCE;
+ result->id = 0;
+ PRE_EXPR_REFERENCE (result) = ref;
+ break;
}
- if (TREE_CODE (rhs) == SSA_NAME)
- add_to_exp_gen (block, rhs);
+ default:
+ /* For any other statement that we don't
+ recognize, simply add all referenced
+ SSA_NAMEs to EXP_GEN. */
+ FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_USE)
+ add_to_exp_gen (block, op);
+ continue;
+ }
- FOR_EACH_SSA_TREE_OPERAND (op, realstmt, iter, SSA_OP_DEF)
- add_to_sets (op, op, NULL, TMP_GEN (block),
- AVAIL_OUT (block));
- }
- continue;
- }
+ get_or_alloc_expression_id (result);
+ add_to_value (get_expr_value_id (result), result);
+ if (!in_fre)
+ {
+ bitmap_value_insert_into_set (EXP_GEN (block), result);
+ bitmap_value_insert_into_set (maximal_set, result);
+ }
- else if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT
- && !ann->has_volatile_ops
- && TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 0)) == SSA_NAME
- && !tree_could_throw_p (stmt))
- {
- if (make_values_for_stmt (stmt, block))
continue;
+ }
+ default:
+ break;
}
-
- /* For any other statement that we don't recognize, simply
- make the names generated by the statement available in
- AVAIL_OUT and TMP_GEN. */
- FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_DEF)
- add_to_sets (op, op, NULL, TMP_GEN (block), AVAIL_OUT (block));
-
- /* Also add all referenced SSA_NAMEs to EXP_GEN. */
- FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_USE)
- add_to_exp_gen (block, op);
}
/* Put the dominator children of BLOCK on the worklist of blocks
@@ -3643,27 +3855,27 @@ compute_avail (void)
be used for replacement. */
static tree
-do_SCCVN_insertion (tree stmt, tree ssa_vn)
+do_SCCVN_insertion (gimple stmt, tree ssa_vn)
{
- basic_block bb = bb_for_stmt (stmt);
- block_stmt_iterator bsi;
- tree expr, stmts;
+ basic_block bb = gimple_bb (stmt);
+ gimple_stmt_iterator gsi;
+ gimple_seq stmts = NULL;
+ tree expr;
+ pre_expr e;
/* First create a value expression from the expression we want
to insert and associate it with the value handle for SSA_VN. */
- expr = create_value_expr_from (VN_INFO (ssa_vn)->expr, bb, NULL, true);
- if (expr == NULL_TREE)
+ e = get_or_alloc_expr_for (vn_get_expr_for (ssa_vn));
+ if (e == NULL)
return NULL_TREE;
- set_value_handle (expr, get_value_handle (ssa_vn));
/* Then use create_expression_by_pieces to generate a valid
expression to insert at this point of the IL stream. */
- stmts = alloc_stmt_list ();
- expr = create_expression_by_pieces (bb, expr, stmts, stmt);
+ expr = create_expression_by_pieces (bb, e, &stmts, stmt, NULL);
if (expr == NULL_TREE)
return NULL_TREE;
- bsi = bsi_for_stmt (stmt);
- bsi_insert_before (&bsi, stmts, BSI_SAME_STMT);
+ gsi = gsi_for_stmt (stmt);
+ gsi_insert_seq_before (&gsi, stmts, GSI_SAME_STMT);
return expr;
}
@@ -3678,70 +3890,113 @@ eliminate (void)
FOR_EACH_BB (b)
{
- block_stmt_iterator i;
+ gimple_stmt_iterator i;
- for (i = bsi_start (b); !bsi_end_p (i); bsi_next (&i))
+ for (i = gsi_start_bb (b); !gsi_end_p (i); gsi_next (&i))
{
- tree stmt = bsi_stmt (i);
+ gimple stmt = gsi_stmt (i);
/* Lookup the RHS of the expression, see if we have an
available computation for it. If so, replace the RHS with
the available computation. */
- if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT
- && TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 0)) == SSA_NAME
- && TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 1)) != SSA_NAME
- && !is_gimple_min_invariant (GIMPLE_STMT_OPERAND (stmt, 1))
- && !stmt_ann (stmt)->has_volatile_ops)
+ if (gimple_has_lhs (stmt)
+ && TREE_CODE (gimple_get_lhs (stmt)) == SSA_NAME
+ && !gimple_assign_ssa_name_copy_p (stmt)
+ && (!gimple_assign_single_p (stmt)
+ || !is_gimple_min_invariant (gimple_assign_rhs1 (stmt)))
+ && !gimple_has_volatile_ops (stmt)
+ && !has_zero_uses (gimple_get_lhs (stmt)))
{
- tree lhs = GIMPLE_STMT_OPERAND (stmt, 0);
- tree *rhs_p = &GIMPLE_STMT_OPERAND (stmt, 1);
- tree sprime;
+ tree lhs = gimple_get_lhs (stmt);
+ tree rhs = NULL_TREE;
+ tree sprime = NULL;
+ pre_expr lhsexpr = get_or_alloc_expr_for_name (lhs);
+ pre_expr sprimeexpr;
- sprime = bitmap_find_leader (AVAIL_OUT (b),
- get_value_handle (lhs), NULL_TREE);
+ if (gimple_assign_single_p (stmt))
+ rhs = gimple_assign_rhs1 (stmt);
+
+ sprimeexpr = bitmap_find_leader (AVAIL_OUT (b),
+ get_expr_value_id (lhsexpr),
+ NULL);
+
+ if (sprimeexpr)
+ {
+ if (sprimeexpr->kind == CONSTANT)
+ sprime = PRE_EXPR_CONSTANT (sprimeexpr);
+ else if (sprimeexpr->kind == NAME)
+ sprime = PRE_EXPR_NAME (sprimeexpr);
+ else
+ gcc_unreachable ();
+ }
+
+ /* If there is no existing leader but SCCVN knows this
+ value is constant, use that constant. */
+ if (!sprime && is_gimple_min_invariant (VN_INFO (lhs)->valnum))
+ {
+ sprime = fold_convert (TREE_TYPE (lhs),
+ VN_INFO (lhs)->valnum);
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "Replaced ");
+ print_gimple_expr (dump_file, stmt, 0, 0);
+ fprintf (dump_file, " with ");
+ print_generic_expr (dump_file, sprime, 0);
+ fprintf (dump_file, " in ");
+ print_gimple_stmt (dump_file, stmt, 0, 0);
+ }
+ pre_stats.eliminations++;
+ propagate_tree_value_into_stmt (&i, sprime);
+ stmt = gsi_stmt (i);
+ update_stmt (stmt);
+ continue;
+ }
/* If there is no existing usable leader but SCCVN thinks
it has an expression it wants to use as replacement,
insert that. */
- if (!sprime
- || sprime == lhs)
+ if (!sprime || sprime == lhs)
{
tree val = VN_INFO (lhs)->valnum;
if (val != VN_TOP
+ && TREE_CODE (val) == SSA_NAME
&& VN_INFO (val)->needs_insertion
- && can_PRE_operation (VN_INFO (val)->expr))
+ && can_PRE_operation (vn_get_expr_for (val)))
sprime = do_SCCVN_insertion (stmt, val);
}
-
if (sprime
&& sprime != lhs
- && (TREE_CODE (*rhs_p) != SSA_NAME
- || may_propagate_copy (*rhs_p, sprime)))
+ && (rhs == NULL_TREE
+ || TREE_CODE (rhs) != SSA_NAME
+ || may_propagate_copy (rhs, sprime)))
{
- gcc_assert (sprime != *rhs_p);
+ gcc_assert (sprime != rhs);
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "Replaced ");
- print_generic_expr (dump_file, *rhs_p, 0);
+ print_gimple_expr (dump_file, stmt, 0, 0);
fprintf (dump_file, " with ");
print_generic_expr (dump_file, sprime, 0);
fprintf (dump_file, " in ");
- print_generic_stmt (dump_file, stmt, 0);
+ print_gimple_stmt (dump_file, stmt, 0, 0);
}
if (TREE_CODE (sprime) == SSA_NAME)
- NECESSARY (SSA_NAME_DEF_STMT (sprime)) = 1;
+ gimple_set_plf (SSA_NAME_DEF_STMT (sprime),
+ NECESSARY, true);
/* We need to make sure the new and old types actually match,
which may require adding a simple cast, which fold_convert
will do for us. */
- if (TREE_CODE (*rhs_p) != SSA_NAME
- && !useless_type_conversion_p (TREE_TYPE (*rhs_p),
- TREE_TYPE (sprime)))
- sprime = fold_convert (TREE_TYPE (*rhs_p), sprime);
+ if ((!rhs || TREE_CODE (rhs) != SSA_NAME)
+ && !useless_type_conversion_p (gimple_expr_type (stmt),
+ TREE_TYPE (sprime)))
+ sprime = fold_convert (gimple_expr_type (stmt), sprime);
pre_stats.eliminations++;
- propagate_tree_value (rhs_p, sprime);
+ propagate_tree_value_into_stmt (&i, sprime);
+ stmt = gsi_stmt (i);
update_stmt (stmt);
/* If we removed EH side effects from the statement, clean
@@ -3749,7 +4004,7 @@ eliminate (void)
if (maybe_clean_or_replace_eh_stmt (stmt, stmt))
{
bitmap_set_bit (need_eh_cleanup,
- bb_for_stmt (stmt)->index);
+ gimple_bb (stmt)->index);
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, " Removed EH side effects.\n");
}
@@ -3757,36 +4012,24 @@ eliminate (void)
}
/* Visit COND_EXPRs and fold the comparison with the
available value-numbers. */
- else if (TREE_CODE (stmt) == COND_EXPR
- && COMPARISON_CLASS_P (COND_EXPR_COND (stmt)))
+ else if (gimple_code (stmt) == GIMPLE_COND)
{
- tree cond = COND_EXPR_COND (stmt);
- tree op0 = TREE_OPERAND (cond, 0);
- tree op1 = TREE_OPERAND (cond, 1);
+ tree op0 = gimple_cond_lhs (stmt);
+ tree op1 = gimple_cond_rhs (stmt);
tree result;
if (TREE_CODE (op0) == SSA_NAME)
op0 = VN_INFO (op0)->valnum;
if (TREE_CODE (op1) == SSA_NAME)
op1 = VN_INFO (op1)->valnum;
- result = fold_binary (TREE_CODE (cond), TREE_TYPE (cond),
+ result = fold_binary (gimple_cond_code (stmt), boolean_type_node,
op0, op1);
if (result && TREE_CODE (result) == INTEGER_CST)
{
- COND_EXPR_COND (stmt) = result;
- update_stmt (stmt);
- todo = TODO_cleanup_cfg;
- }
- }
- else if (TREE_CODE (stmt) == COND_EXPR
- && TREE_CODE (COND_EXPR_COND (stmt)) == SSA_NAME)
- {
- tree op = COND_EXPR_COND (stmt);
- op = VN_INFO (op)->valnum;
- if (TREE_CODE (op) == INTEGER_CST)
- {
- COND_EXPR_COND (stmt) = integer_zerop (op)
- ? boolean_false_node : boolean_true_node;
+ if (integer_zerop (result))
+ gimple_cond_make_false (stmt);
+ else
+ gimple_cond_make_true (stmt);
update_stmt (stmt);
todo = TODO_cleanup_cfg;
}
@@ -3805,10 +4048,10 @@ eliminate (void)
mark that statement necessary. Return the stmt, if it is newly
necessary. */
-static inline tree
+static inline gimple
mark_operand_necessary (tree op)
{
- tree stmt;
+ gimple stmt;
gcc_assert (op);
@@ -3818,11 +4061,11 @@ mark_operand_necessary (tree op)
stmt = SSA_NAME_DEF_STMT (op);
gcc_assert (stmt);
- if (NECESSARY (stmt)
- || IS_EMPTY_STMT (stmt))
+ if (gimple_plf (stmt, NECESSARY)
+ || gimple_nop_p (stmt))
return NULL;
- NECESSARY (stmt) = 1;
+ gimple_set_plf (stmt, NECESSARY, true);
return stmt;
}
@@ -3834,36 +4077,36 @@ mark_operand_necessary (tree op)
static void
remove_dead_inserted_code (void)
{
- VEC(tree,heap) *worklist = NULL;
+ VEC(gimple,heap) *worklist = NULL;
int i;
- tree t;
+ gimple t;
- worklist = VEC_alloc (tree, heap, VEC_length (tree, inserted_exprs));
- for (i = 0; VEC_iterate (tree, inserted_exprs, i, t); i++)
+ worklist = VEC_alloc (gimple, heap, VEC_length (gimple, inserted_exprs));
+ for (i = 0; VEC_iterate (gimple, inserted_exprs, i, t); i++)
{
- if (NECESSARY (t))
- VEC_quick_push (tree, worklist, t);
+ if (gimple_plf (t, NECESSARY))
+ VEC_quick_push (gimple, worklist, t);
}
- while (VEC_length (tree, worklist) > 0)
+ while (VEC_length (gimple, worklist) > 0)
{
- t = VEC_pop (tree, worklist);
+ t = VEC_pop (gimple, worklist);
/* PHI nodes are somewhat special in that each PHI alternative has
data and control dependencies. All the statements feeding the
PHI node's arguments are always necessary. */
- if (TREE_CODE (t) == PHI_NODE)
+ if (gimple_code (t) == GIMPLE_PHI)
{
- int k;
+ unsigned k;
- VEC_reserve (tree, heap, worklist, PHI_NUM_ARGS (t));
- for (k = 0; k < PHI_NUM_ARGS (t); k++)
+ VEC_reserve (gimple, heap, worklist, gimple_phi_num_args (t));
+ for (k = 0; k < gimple_phi_num_args (t); k++)
{
tree arg = PHI_ARG_DEF (t, k);
if (TREE_CODE (arg) == SSA_NAME)
{
- arg = mark_operand_necessary (arg);
- if (arg)
- VEC_quick_push (tree, worklist, arg);
+ gimple n = mark_operand_necessary (arg);
+ if (n)
+ VEC_quick_push (gimple, worklist, n);
}
}
}
@@ -3882,38 +4125,34 @@ remove_dead_inserted_code (void)
FOR_EACH_SSA_TREE_OPERAND (use, t, iter, SSA_OP_ALL_USES)
{
- tree n = mark_operand_necessary (use);
+ gimple n = mark_operand_necessary (use);
if (n)
- VEC_safe_push (tree, heap, worklist, n);
+ VEC_safe_push (gimple, heap, worklist, n);
}
}
}
- for (i = 0; VEC_iterate (tree, inserted_exprs, i, t); i++)
+ for (i = 0; VEC_iterate (gimple, inserted_exprs, i, t); i++)
{
- if (!NECESSARY (t))
+ if (!gimple_plf (t, NECESSARY))
{
- block_stmt_iterator bsi;
+ gimple_stmt_iterator gsi;
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "Removing unnecessary insertion:");
- print_generic_stmt (dump_file, t, 0);
+ print_gimple_stmt (dump_file, t, 0, 0);
}
- if (TREE_CODE (t) == PHI_NODE)
- {
- remove_phi_node (t, NULL_TREE, true);
- }
+ gsi = gsi_for_stmt (t);
+ if (gimple_code (t) == GIMPLE_PHI)
+ remove_phi_node (&gsi, true);
else
- {
- bsi = bsi_for_stmt (t);
- bsi_remove (&bsi, true);
- release_defs (t);
- }
+ gsi_remove (&gsi, true);
+ release_defs (t);
}
}
- VEC_free (tree, heap, worklist);
+ VEC_free (gimple, heap, worklist);
}
/* Initialize data structures used by PRE. */
@@ -3921,6 +4160,15 @@ remove_dead_inserted_code (void)
static void
init_pre (bool do_fre)
{
+ basic_block bb;
+
+ next_expression_id = 1;
+ expressions = NULL;
+ VEC_safe_push (pre_expr, heap, expressions, NULL);
+ value_expressions = VEC_alloc (bitmap_set_t, heap, get_max_value_id () + 1);
+ VEC_safe_grow_cleared (bitmap_set_t, heap, value_expressions,
+ get_max_value_id() + 1);
+
in_fre = do_fre;
inserted_exprs = NULL;
@@ -3929,16 +4177,38 @@ init_pre (bool do_fre)
storetemp = NULL_TREE;
prephitemp = NULL_TREE;
- if (!do_fre)
- loop_optimizer_init (LOOPS_NORMAL);
-
connect_infinite_loops_to_exit ();
memset (&pre_stats, 0, sizeof (pre_stats));
+
+ postorder = XNEWVEC (int, n_basic_blocks - NUM_FIXED_BLOCKS);
+ post_order_compute (postorder, false, false);
+
+ FOR_ALL_BB (bb)
+ bb->aux = XCNEWVEC (struct bb_bitmap_sets, 1);
+
calculate_dominance_info (CDI_POST_DOMINATORS);
calculate_dominance_info (CDI_DOMINATORS);
- init_antic ();
+ bitmap_obstack_initialize (&grand_bitmap_obstack);
+ phi_translate_table = htab_create (5110, expr_pred_trans_hash,
+ expr_pred_trans_eq, free);
+ expression_to_id = htab_create (num_ssa_names * 3,
+ pre_expr_hash,
+ pre_expr_eq, NULL);
+ seen_during_translate = BITMAP_ALLOC (&grand_bitmap_obstack);
+ bitmap_set_pool = create_alloc_pool ("Bitmap sets",
+ sizeof (struct bitmap_set), 30);
+ pre_expr_pool = create_alloc_pool ("pre_expr nodes",
+ sizeof (struct pre_expr_d), 30);
+ FOR_ALL_BB (bb)
+ {
+ EXP_GEN (bb) = bitmap_set_new ();
+ PHI_GEN (bb) = bitmap_set_new ();
+ TMP_GEN (bb) = bitmap_set_new ();
+ AVAIL_OUT (bb) = bitmap_set_new ();
+ }
+ maximal_set = in_fre ? NULL : bitmap_set_new ();
need_eh_cleanup = BITMAP_ALLOC (NULL);
}
@@ -3949,38 +4219,35 @@ init_pre (bool do_fre)
static void
fini_pre (void)
{
- unsigned int i;
+ basic_block bb;
- VEC_free (tree, heap, inserted_exprs);
- VEC_free (tree, heap, need_creation);
+ free (postorder);
+ VEC_free (bitmap_set_t, heap, value_expressions);
+ VEC_free (gimple, heap, inserted_exprs);
+ VEC_free (gimple, heap, need_creation);
+ bitmap_obstack_release (&grand_bitmap_obstack);
+ free_alloc_pool (bitmap_set_pool);
+ free_alloc_pool (pre_expr_pool);
htab_delete (phi_translate_table);
+ htab_delete (expression_to_id);
remove_fake_exit_edges ();
- fini_antic ();
+ FOR_ALL_BB (bb)
+ {
+ free (bb->aux);
+ bb->aux = NULL;
+ }
free_dominance_info (CDI_POST_DOMINATORS);
if (!bitmap_empty_p (need_eh_cleanup))
{
- tree_purge_all_dead_eh_edges (need_eh_cleanup);
+ gimple_purge_all_dead_eh_edges (need_eh_cleanup);
cleanup_tree_cfg ();
}
BITMAP_FREE (need_eh_cleanup);
- /* Wipe out pointers to VALUE_HANDLEs. In the not terribly distant
- future we will want them to be persistent though. */
- for (i = 0; i < num_ssa_names; i++)
- {
- tree name = ssa_name (i);
-
- if (!name)
- continue;
-
- if (SSA_NAME_VALUE (name)
- && TREE_CODE (SSA_NAME_VALUE (name)) == VALUE_HANDLE)
- SSA_NAME_VALUE (name) = NULL;
- }
if (current_loops != NULL)
loop_optimizer_finalize ();
}
@@ -3989,25 +4256,36 @@ fini_pre (void)
only wants to do full redundancy elimination. */
static unsigned int
-execute_pre (bool do_fre)
+execute_pre (bool do_fre ATTRIBUTE_UNUSED)
{
unsigned int todo = 0;
do_partial_partial = optimize > 2;
- init_pre (do_fre);
+ /* This has to happen before SCCVN runs because
+ loop_optimizer_init may create new phis, etc. */
if (!do_fre)
+ loop_optimizer_init (LOOPS_NORMAL);
+ /* FIXME tuples */
+#if 0
+ if (0 && !do_fre)
insert_fake_stores ();
+#endif
- /* Collect and value number expressions computed in each basic block. */
if (!run_scc_vn (do_fre))
{
if (!do_fre)
- remove_dead_inserted_code ();
- fini_pre ();
+ {
+ remove_dead_inserted_code ();
+ loop_optimizer_finalize ();
+ }
+
return 0;
}
- switch_to_PRE_table ();
+ init_pre (do_fre);
+
+
+ /* Collect and value number expressions computed in each basic block. */
compute_avail ();
if (dump_file && (dump_flags & TDF_DETAILS))
@@ -4032,16 +4310,6 @@ execute_pre (bool do_fre)
if (!do_fre && n_basic_blocks < 4000)
{
compute_antic ();
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- basic_block bb;
-
- FOR_ALL_BB (bb)
- {
- print_bitmap_set (dump_file, ANTIC_IN (bb), "antic_in", bb->index);
- }
- }
-
insert ();
}
@@ -4053,14 +4321,18 @@ execute_pre (bool do_fre)
statistics_counter_event (cfun, "New PHIs", pre_stats.phis);
statistics_counter_event (cfun, "Eliminated", pre_stats.eliminations);
statistics_counter_event (cfun, "Constified", pre_stats.constified);
- bsi_commit_edge_inserts ();
+ gsi_commit_edge_inserts ();
clear_expression_ids ();
free_scc_vn ();
if (!do_fre)
{
remove_dead_inserted_code ();
- realify_fake_stores ();
+ /* FIXME tuples */
+#if 0
+ if (0)
+ realify_fake_stores ();
+#endif
}
fini_pre ();
diff --git a/gcc/tree-ssa-propagate.c b/gcc/tree-ssa-propagate.c
index b0371805568..611f2b2847d 100644
--- a/gcc/tree-ssa-propagate.c
+++ b/gcc/tree-ssa-propagate.c
@@ -41,6 +41,7 @@
#include "varray.h"
#include "vec.h"
#include "value-prof.h"
+#include "gimple.h"
/* This file implements a generic value propagation engine based on
the same propagation used by the SSA-CCP algorithm [1].
@@ -96,7 +97,7 @@
5- Simulation terminates when all three work lists are drained.
Before calling ssa_propagate, it is important to clear
- DONT_SIMULATE_AGAIN for all the statements in the program that
+ prop_simulate_again_p for all the statements in the program that
should be simulated. This initialization allows an implementation
to specify which statements should never be simulated.
@@ -118,13 +119,16 @@
static ssa_prop_visit_stmt_fn ssa_prop_visit_stmt;
static ssa_prop_visit_phi_fn ssa_prop_visit_phi;
-/* Use the deprecated flag to mark statements that have been
- added to one of the SSA edges worklists. This flag is used to
- avoid visiting statements unnecessarily when draining an SSA edge
- worklist. If while simulating a basic block, we find a statement with
+/* Keep track of statements that have been added to one of the SSA
+ edges worklists. This flag is used to avoid visiting statements
+ unnecessarily when draining an SSA edge worklist. If while
+ simulating a basic block, we find a statement with
STMT_IN_SSA_EDGE_WORKLIST set, we clear it to prevent SSA edge
- processing from visiting it again. */
-#define STMT_IN_SSA_EDGE_WORKLIST(T) ((T)->base.deprecated_flag)
+ processing from visiting it again.
+
+ NOTE: users of the propagation engine are not allowed to use
+ the GF_PLF_1 flag. */
+#define STMT_IN_SSA_EDGE_WORKLIST GF_PLF_1
/* A bitmap to keep track of executable blocks in the CFG. */
static sbitmap executable_blocks;
@@ -142,7 +146,7 @@ static sbitmap bb_in_list;
definition has changed. SSA edges are def-use edges in the SSA
web. For each D-U edge, we store the target statement or PHI node
U. */
-static GTY(()) VEC(tree,gc) *interesting_ssa_edges;
+static GTY(()) VEC(gimple,gc) *interesting_ssa_edges;
/* Identical to INTERESTING_SSA_EDGES. For performance reasons, the
list of SSA edges is split into two. One contains all SSA edges
@@ -158,7 +162,7 @@ static GTY(()) VEC(tree,gc) *interesting_ssa_edges;
don't use a separate worklist for VARYING edges, we end up with
situations where lattice values move from
UNDEFINED->INTERESTING->VARYING instead of UNDEFINED->VARYING. */
-static GTY(()) VEC(tree,gc) *varying_ssa_edges;
+static GTY(()) VEC(gimple,gc) *varying_ssa_edges;
/* Return true if the block worklist empty. */
@@ -257,16 +261,16 @@ add_ssa_edge (tree var, bool is_varying)
FOR_EACH_IMM_USE_FAST (use_p, iter, var)
{
- tree use_stmt = USE_STMT (use_p);
+ gimple use_stmt = USE_STMT (use_p);
- if (!DONT_SIMULATE_AGAIN (use_stmt)
- && !STMT_IN_SSA_EDGE_WORKLIST (use_stmt))
+ if (prop_simulate_again_p (use_stmt)
+ && !gimple_plf (use_stmt, STMT_IN_SSA_EDGE_WORKLIST))
{
- STMT_IN_SSA_EDGE_WORKLIST (use_stmt) = 1;
+ gimple_set_plf (use_stmt, STMT_IN_SSA_EDGE_WORKLIST, true);
if (is_varying)
- VEC_safe_push (tree, gc, varying_ssa_edges, use_stmt);
+ VEC_safe_push (gimple, gc, varying_ssa_edges, use_stmt);
else
- VEC_safe_push (tree, gc, interesting_ssa_edges, use_stmt);
+ VEC_safe_push (gimple, gc, interesting_ssa_edges, use_stmt);
}
}
}
@@ -302,7 +306,7 @@ add_control_edge (edge e)
/* Simulate the execution of STMT and update the work lists accordingly. */
static void
-simulate_stmt (tree stmt)
+simulate_stmt (gimple stmt)
{
enum ssa_prop_result val = SSA_PROP_NOT_INTERESTING;
edge taken_edge = NULL;
@@ -310,20 +314,20 @@ simulate_stmt (tree stmt)
/* Don't bother visiting statements that are already
considered varying by the propagator. */
- if (DONT_SIMULATE_AGAIN (stmt))
+ if (!prop_simulate_again_p (stmt))
return;
- if (TREE_CODE (stmt) == PHI_NODE)
+ if (gimple_code (stmt) == GIMPLE_PHI)
{
val = ssa_prop_visit_phi (stmt);
- output_name = PHI_RESULT (stmt);
+ output_name = gimple_phi_result (stmt);
}
else
val = ssa_prop_visit_stmt (stmt, &taken_edge, &output_name);
if (val == SSA_PROP_VARYING)
{
- DONT_SIMULATE_AGAIN (stmt) = 1;
+ prop_set_simulate_again (stmt, false);
/* If the statement produced a new varying value, add the SSA
edges coming out of OUTPUT_NAME. */
@@ -336,7 +340,7 @@ simulate_stmt (tree stmt)
{
edge e;
edge_iterator ei;
- basic_block bb = bb_for_stmt (stmt);
+ basic_block bb = gimple_bb (stmt);
FOR_EACH_EDGE (e, ei, bb->succs)
add_control_edge (e);
}
@@ -362,36 +366,36 @@ simulate_stmt (tree stmt)
SSA edge is added to it in simulate_stmt. */
static void
-process_ssa_edge_worklist (VEC(tree,gc) **worklist)
+process_ssa_edge_worklist (VEC(gimple,gc) **worklist)
{
/* Drain the entire worklist. */
- while (VEC_length (tree, *worklist) > 0)
+ while (VEC_length (gimple, *worklist) > 0)
{
basic_block bb;
/* Pull the statement to simulate off the worklist. */
- tree stmt = VEC_pop (tree, *worklist);
+ gimple stmt = VEC_pop (gimple, *worklist);
/* If this statement was already visited by simulate_block, then
we don't need to visit it again here. */
- if (!STMT_IN_SSA_EDGE_WORKLIST (stmt))
+ if (!gimple_plf (stmt, STMT_IN_SSA_EDGE_WORKLIST))
continue;
/* STMT is no longer in a worklist. */
- STMT_IN_SSA_EDGE_WORKLIST (stmt) = 0;
+ gimple_set_plf (stmt, STMT_IN_SSA_EDGE_WORKLIST, false);
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "\nSimulating statement (from ssa_edges): ");
- print_generic_stmt (dump_file, stmt, dump_flags);
+ print_gimple_stmt (dump_file, stmt, 0, dump_flags);
}
- bb = bb_for_stmt (stmt);
+ bb = gimple_bb (stmt);
/* PHI nodes are always visited, regardless of whether or not
the destination block is executable. Otherwise, visit the
statement only if its block is marked executable. */
- if (TREE_CODE (stmt) == PHI_NODE
+ if (gimple_code (stmt) == GIMPLE_PHI
|| TEST_BIT (executable_blocks, bb->index))
simulate_stmt (stmt);
}
@@ -404,7 +408,7 @@ process_ssa_edge_worklist (VEC(tree,gc) **worklist)
static void
simulate_block (basic_block block)
{
- tree phi;
+ gimple_stmt_iterator gsi;
/* There is nothing to do for the exit block. */
if (block == EXIT_BLOCK_PTR)
@@ -415,14 +419,14 @@ simulate_block (basic_block block)
/* Always simulate PHI nodes, even if we have simulated this block
before. */
- for (phi = phi_nodes (block); phi; phi = PHI_CHAIN (phi))
- simulate_stmt (phi);
+ for (gsi = gsi_start_phis (block); !gsi_end_p (gsi); gsi_next (&gsi))
+ simulate_stmt (gsi_stmt (gsi));
/* If this is the first time we've simulated this block, then we
must simulate each of its statements. */
if (!TEST_BIT (executable_blocks, block->index))
{
- block_stmt_iterator j;
+ gimple_stmt_iterator j;
unsigned int normal_edge_count;
edge e, normal_edge;
edge_iterator ei;
@@ -430,17 +434,17 @@ simulate_block (basic_block block)
/* Note that we have simulated this block. */
SET_BIT (executable_blocks, block->index);
- for (j = bsi_start (block); !bsi_end_p (j); bsi_next (&j))
+ for (j = gsi_start_bb (block); !gsi_end_p (j); gsi_next (&j))
{
- tree stmt = bsi_stmt (j);
+ gimple stmt = gsi_stmt (j);
/* If this statement is already in the worklist then
"cancel" it. The reevaluation implied by the worklist
entry will produce the same value we generate here and
thus reevaluating it again from the worklist is
pointless. */
- if (STMT_IN_SSA_EDGE_WORKLIST (stmt))
- STMT_IN_SSA_EDGE_WORKLIST (stmt) = 0;
+ if (gimple_plf (stmt, STMT_IN_SSA_EDGE_WORKLIST))
+ gimple_set_plf (stmt, STMT_IN_SSA_EDGE_WORKLIST, false);
simulate_stmt (stmt);
}
@@ -482,8 +486,8 @@ ssa_prop_init (void)
size_t i;
/* Worklists of SSA edges. */
- interesting_ssa_edges = VEC_alloc (tree, gc, 20);
- varying_ssa_edges = VEC_alloc (tree, gc, 20);
+ interesting_ssa_edges = VEC_alloc (gimple, gc, 20);
+ varying_ssa_edges = VEC_alloc (gimple, gc, 20);
executable_blocks = sbitmap_alloc (last_basic_block);
sbitmap_zero (executable_blocks);
@@ -506,10 +510,13 @@ ssa_prop_init (void)
(including the edges coming out of ENTRY_BLOCK_PTR). */
FOR_ALL_BB (bb)
{
- block_stmt_iterator si;
+ gimple_stmt_iterator si;
- for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
- STMT_IN_SSA_EDGE_WORKLIST (bsi_stmt (si)) = 0;
+ for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
+ gimple_set_plf (gsi_stmt (si), STMT_IN_SSA_EDGE_WORKLIST, false);
+
+ for (si = gsi_start_phis (bb); !gsi_end_p (si); gsi_next (&si))
+ gimple_set_plf (gsi_stmt (si), STMT_IN_SSA_EDGE_WORKLIST, false);
FOR_EACH_EDGE (e, ei, bb->succs)
e->flags &= ~EDGE_EXECUTABLE;
@@ -527,8 +534,8 @@ ssa_prop_init (void)
static void
ssa_prop_fini (void)
{
- VEC_free (tree, gc, interesting_ssa_edges);
- VEC_free (tree, gc, varying_ssa_edges);
+ VEC_free (gimple, gc, interesting_ssa_edges);
+ VEC_free (gimple, gc, varying_ssa_edges);
VEC_free (basic_block, heap, cfg_blocks);
cfg_blocks = NULL;
sbitmap_free (bb_in_list);
@@ -536,47 +543,20 @@ ssa_prop_fini (void)
}
-/* Get the main expression from statement STMT. */
-
-tree
-get_rhs (tree stmt)
-{
- enum tree_code code = TREE_CODE (stmt);
-
- switch (code)
- {
- case RETURN_EXPR:
- stmt = TREE_OPERAND (stmt, 0);
- if (!stmt || TREE_CODE (stmt) != GIMPLE_MODIFY_STMT)
- return stmt;
- /* FALLTHRU */
-
- case GIMPLE_MODIFY_STMT:
- stmt = GENERIC_TREE_OPERAND (stmt, 1);
- if (TREE_CODE (stmt) == WITH_SIZE_EXPR)
- return TREE_OPERAND (stmt, 0);
- else
- return stmt;
-
- case COND_EXPR:
- return COND_EXPR_COND (stmt);
- case SWITCH_EXPR:
- return SWITCH_COND (stmt);
- case GOTO_EXPR:
- return GOTO_DESTINATION (stmt);
- case LABEL_EXPR:
- return LABEL_EXPR_LABEL (stmt);
-
- default:
- return stmt;
- }
-}
-
-
-/* Return true if EXPR is a valid GIMPLE expression. */
+/* Return true if EXPR is an acceptable right-hand-side for a
+ GIMPLE assignment. We validate the entire tree, not just
+ the root node, thus catching expressions that embed complex
+ operands that are not permitted in GIMPLE. This function
+ is needed because the folding routines in fold-const.c
+ may return such expressions in some cases, e.g., an array
+ access with an embedded index addition. It may make more
+ sense to have folding routines that are sensitive to the
+ constraints on GIMPLE operands, rather than abandoning any
+ any attempt to fold if the usual folding turns out to be too
+ aggressive. */
bool
-valid_gimple_expression_p (tree expr)
+valid_gimple_rhs_p (tree expr)
{
enum tree_code code = TREE_CODE (expr);
@@ -588,6 +568,7 @@ valid_gimple_expression_p (tree expr)
break;
case tcc_constant:
+ /* All constants are ok. */
break;
case tcc_binary:
@@ -604,23 +585,26 @@ valid_gimple_expression_p (tree expr)
case tcc_expression:
switch (code)
- {
- case ADDR_EXPR:
- {
- tree t = TREE_OPERAND (expr, 0);
- while (handled_component_p (t))
- {
- /* ??? More checks needed, see the GIMPLE verifier. */
- if ((TREE_CODE (t) == ARRAY_REF
- || TREE_CODE (t) == ARRAY_RANGE_REF)
- && !is_gimple_val (TREE_OPERAND (t, 1)))
- return false;
- t = TREE_OPERAND (t, 0);
- }
- if (!is_gimple_id (t))
- return false;
- break;
- }
+ {
+ case ADDR_EXPR:
+ {
+ tree t;
+ if (is_gimple_min_invariant (expr))
+ return true;
+ t = TREE_OPERAND (expr, 0);
+ while (handled_component_p (t))
+ {
+ /* ??? More checks needed, see the GIMPLE verifier. */
+ if ((TREE_CODE (t) == ARRAY_REF
+ || TREE_CODE (t) == ARRAY_RANGE_REF)
+ && !is_gimple_val (TREE_OPERAND (t, 1)))
+ return false;
+ t = TREE_OPERAND (t, 0);
+ }
+ if (!is_gimple_id (t))
+ return false;
+ }
+ break;
case TRUTH_NOT_EXPR:
if (!is_gimple_val (TREE_OPERAND (expr, 0)))
@@ -645,24 +629,11 @@ valid_gimple_expression_p (tree expr)
break;
case tcc_vl_exp:
- switch (code)
- {
- case CALL_EXPR:
- break;
- default:
- return false;
- }
- break;
+ return false;
case tcc_exceptional:
- switch (code)
- {
- case SSA_NAME:
- break;
-
- default:
- return false;
- }
+ if (code != SSA_NAME)
+ return false;
break;
default:
@@ -673,101 +644,144 @@ valid_gimple_expression_p (tree expr)
}
-/* Set the main expression of *STMT_P to EXPR. If EXPR is not a valid
- GIMPLE expression no changes are done and the function returns
- false. */
+/* Return true if EXPR is a CALL_EXPR suitable for representation
+ as a single GIMPLE_CALL statement. If the arguments require
+ further gimplification, return false. */
bool
-set_rhs (tree *stmt_p, tree expr)
+valid_gimple_call_p (tree expr)
{
- tree stmt = *stmt_p, op;
- tree new_stmt;
- tree var;
- ssa_op_iter iter;
- int eh_region;
+ unsigned i, nargs;
- if (!valid_gimple_expression_p (expr))
+ if (TREE_CODE (expr) != CALL_EXPR)
return false;
- if (EXPR_HAS_LOCATION (stmt)
- && (EXPR_P (expr)
- || GIMPLE_STMT_P (expr))
- && ! EXPR_HAS_LOCATION (expr)
- && TREE_SIDE_EFFECTS (expr)
- && TREE_CODE (expr) != LABEL_EXPR)
- SET_EXPR_LOCATION (expr, EXPR_LOCATION (stmt));
+ nargs = call_expr_nargs (expr);
+ for (i = 0; i < nargs; i++)
+ if (! is_gimple_operand (CALL_EXPR_ARG (expr, i)))
+ return false;
- switch (TREE_CODE (stmt))
- {
- case RETURN_EXPR:
- op = TREE_OPERAND (stmt, 0);
- if (TREE_CODE (op) != GIMPLE_MODIFY_STMT)
- {
- GIMPLE_STMT_OPERAND (stmt, 0) = expr;
- break;
- }
- stmt = op;
- /* FALLTHRU */
+ return true;
+}
- case GIMPLE_MODIFY_STMT:
- op = GIMPLE_STMT_OPERAND (stmt, 1);
- if (TREE_CODE (op) == WITH_SIZE_EXPR)
- TREE_OPERAND (op, 0) = expr;
- else
- GIMPLE_STMT_OPERAND (stmt, 1) = expr;
- break;
- case COND_EXPR:
- if (!is_gimple_condexpr (expr))
- return false;
- COND_EXPR_COND (stmt) = expr;
- break;
- case SWITCH_EXPR:
- SWITCH_COND (stmt) = expr;
- break;
- case GOTO_EXPR:
- GOTO_DESTINATION (stmt) = expr;
- break;
- case LABEL_EXPR:
- LABEL_EXPR_LABEL (stmt) = expr;
- break;
+/* Make SSA names defined by OLD_STMT point to NEW_STMT
+ as their defining statement. */
- default:
- /* Replace the whole statement with EXPR. If EXPR has no side
- effects, then replace *STMT_P with an empty statement. */
- new_stmt = TREE_SIDE_EFFECTS (expr) ? expr : build_empty_stmt ();
- *stmt_p = new_stmt;
-
- /* Preserve the annotation, the histograms and the EH region information
- associated with the original statement. The EH information
- needs to be preserved only if the new statement still can throw. */
- new_stmt->base.ann = (tree_ann_t) stmt_ann (stmt);
- gimple_move_stmt_histograms (cfun, new_stmt, stmt);
- if (tree_could_throw_p (new_stmt))
- {
- eh_region = lookup_stmt_eh_region (stmt);
- /* We couldn't possibly turn a nothrow into a throw statement. */
- gcc_assert (eh_region >= 0);
- remove_stmt_from_eh_region (stmt);
- add_stmt_to_eh_region (new_stmt, eh_region);
- }
+void
+move_ssa_defining_stmt_for_defs (gimple new_stmt, gimple old_stmt)
+{
+ tree var;
+ ssa_op_iter iter;
- if (gimple_in_ssa_p (cfun)
- && TREE_SIDE_EFFECTS (expr))
- {
- /* Fix all the SSA_NAMEs created by *STMT_P to point to its new
- replacement. */
- FOR_EACH_SSA_TREE_OPERAND (var, stmt, iter, SSA_OP_ALL_DEFS)
- {
- if (TREE_CODE (var) == SSA_NAME)
- SSA_NAME_DEF_STMT (var) = *stmt_p;
- }
- }
- stmt->base.ann = NULL;
- break;
+ if (gimple_in_ssa_p (cfun))
+ {
+ /* Make defined SSA_NAMEs point to the new
+ statement as their definition. */
+ FOR_EACH_SSA_TREE_OPERAND (var, old_stmt, iter, SSA_OP_ALL_DEFS)
+ {
+ if (TREE_CODE (var) == SSA_NAME)
+ SSA_NAME_DEF_STMT (var) = new_stmt;
+ }
}
+}
- return true;
+
+/* Update a GIMPLE_CALL statement at iterator *SI_P to reflect the
+ value of EXPR, which is expected to be the result of folding the
+ call. This can only be done if EXPR is a CALL_EXPR with valid
+ GIMPLE operands as arguments, or if it is a suitable RHS expression
+ for a GIMPLE_ASSIGN. More complex expressions will require
+ gimplification, which will introduce addtional statements. In this
+ event, no update is performed, and the function returns false.
+ Note that we cannot mutate a GIMPLE_CALL in-place, so we always
+ replace the statement at *SI_P with an entirely new statement.
+ The new statement need not be a call, e.g., if the original call
+ folded to a constant. */
+
+bool
+update_call_from_tree (gimple_stmt_iterator *si_p, tree expr)
+{
+ tree lhs;
+
+ gimple stmt = gsi_stmt (*si_p);
+
+ gcc_assert (is_gimple_call (stmt));
+
+ lhs = gimple_call_lhs (stmt);
+
+ if (valid_gimple_call_p (expr))
+ {
+ /* The call has simplified to another call. */
+ tree fn = CALL_EXPR_FN (expr);
+ unsigned i;
+ unsigned nargs = call_expr_nargs (expr);
+ VEC(tree, heap) *args = NULL;
+ gimple new_stmt;
+
+ if (nargs > 0)
+ {
+ args = VEC_alloc (tree, heap, nargs);
+ VEC_safe_grow (tree, heap, args, nargs);
+
+ for (i = 0; i < nargs; i++)
+ VEC_replace (tree, args, i, CALL_EXPR_ARG (expr, i));
+ }
+
+ new_stmt = gimple_build_call_vec (fn, args);
+ gimple_call_set_lhs (new_stmt, lhs);
+ copy_virtual_operands (new_stmt, stmt);
+ move_ssa_defining_stmt_for_defs (new_stmt, stmt);
+ gimple_set_location (new_stmt, gimple_location (stmt));
+ gsi_replace (si_p, new_stmt, false);
+ VEC_free (tree, heap, args);
+
+ return true;
+ }
+ else if (valid_gimple_rhs_p (expr))
+ {
+ gimple new_stmt;
+
+ /* The call has simplified to an expression
+ that cannot be represented as a GIMPLE_CALL. */
+ if (lhs)
+ {
+ /* A value is expected.
+ Introduce a new GIMPLE_ASSIGN statement. */
+ STRIP_USELESS_TYPE_CONVERSION (expr);
+ new_stmt = gimple_build_assign (lhs, expr);
+ copy_virtual_operands (new_stmt, stmt);
+ move_ssa_defining_stmt_for_defs (new_stmt, stmt);
+ }
+ else if (!TREE_SIDE_EFFECTS (expr))
+ {
+ /* No value is expected, and EXPR has no effect.
+ Replace it with an empty statement. */
+ new_stmt = gimple_build_nop ();
+ }
+ else
+ {
+ /* No value is expected, but EXPR has an effect,
+ e.g., it could be a reference to a volatile
+ variable. Create an assignment statement
+ with a dummy (unused) lhs variable. */
+ STRIP_USELESS_TYPE_CONVERSION (expr);
+ lhs = create_tmp_var (TREE_TYPE (expr), NULL);
+ new_stmt = gimple_build_assign (lhs, expr);
+ add_referenced_var (lhs);
+ lhs = make_ssa_name (lhs, new_stmt);
+ gimple_assign_set_lhs (new_stmt, lhs);
+ copy_virtual_operands (new_stmt, stmt);
+ move_ssa_defining_stmt_for_defs (new_stmt, stmt);
+ }
+ gimple_set_location (new_stmt, gimple_location (stmt));
+ gsi_replace (si_p, new_stmt, false);
+ return true;
+ }
+ else
+ /* The call simplified to an expression that is
+ not a valid GIMPLE RHS. */
+ return false;
}
@@ -787,8 +801,8 @@ ssa_propagate (ssa_prop_visit_stmt_fn visit_stmt,
/* Iterate until the worklists are empty. */
while (!cfg_blocks_empty_p ()
- || VEC_length (tree, interesting_ssa_edges) > 0
- || VEC_length (tree, varying_ssa_edges) > 0)
+ || VEC_length (gimple, interesting_ssa_edges) > 0
+ || VEC_length (gimple, varying_ssa_edges) > 0)
{
if (!cfg_blocks_empty_p ())
{
@@ -812,7 +826,7 @@ ssa_propagate (ssa_prop_visit_stmt_fn visit_stmt,
/* Return the first VDEF operand for STMT. */
tree
-first_vdef (tree stmt)
+first_vdef (gimple stmt)
{
ssa_op_iter iter;
tree op;
@@ -831,18 +845,23 @@ first_vdef (tree stmt)
because they are not interesting for the optimizers. */
bool
-stmt_makes_single_load (tree stmt)
+stmt_makes_single_load (gimple stmt)
{
tree rhs;
- if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT)
+ if (gimple_code (stmt) != GIMPLE_ASSIGN)
+ return false;
+
+ /* Only a GIMPLE_SINGLE_RHS assignment may have a
+ declaration or reference as its RHS. */
+ if (get_gimple_rhs_class (gimple_assign_rhs_code (stmt))
+ != GIMPLE_SINGLE_RHS)
return false;
if (ZERO_SSA_OPERANDS (stmt, SSA_OP_VDEF|SSA_OP_VUSE))
return false;
- rhs = GIMPLE_STMT_OPERAND (stmt, 1);
- STRIP_NOPS (rhs);
+ rhs = gimple_assign_rhs1 (stmt);
return (!TREE_THIS_VOLATILE (rhs)
&& (DECL_P (rhs)
@@ -856,18 +875,22 @@ stmt_makes_single_load (tree stmt)
because they are not interesting for the optimizers. */
bool
-stmt_makes_single_store (tree stmt)
+stmt_makes_single_store (gimple stmt)
{
tree lhs;
- if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT)
+ if (gimple_code (stmt) != GIMPLE_ASSIGN
+ && gimple_code (stmt) != GIMPLE_CALL)
return false;
if (ZERO_SSA_OPERANDS (stmt, SSA_OP_VDEF))
return false;
- lhs = GIMPLE_STMT_OPERAND (stmt, 0);
- STRIP_NOPS (lhs);
+ lhs = gimple_get_lhs (stmt);
+
+ /* A call statement may have a null LHS. */
+ if (!lhs)
+ return false;
return (!TREE_THIS_VOLATILE (lhs)
&& (DECL_P (lhs)
@@ -880,7 +903,7 @@ stmt_makes_single_store (tree stmt)
NULL. */
prop_value_t *
-get_value_loaded_by (tree stmt, prop_value_t *values)
+get_value_loaded_by (gimple stmt, prop_value_t *values)
{
ssa_op_iter i;
tree vuse;
@@ -911,13 +934,10 @@ struct prop_stats_d
static struct prop_stats_d prop_stats;
/* Replace USE references in statement STMT with the values stored in
- PROP_VALUE. Return true if at least one reference was replaced. If
- REPLACED_ADDRESSES_P is given, it will be set to true if an address
- constant was replaced. */
+ PROP_VALUE. Return true if at least one reference was replaced. */
-bool
-replace_uses_in (tree stmt, bool *replaced_addresses_p,
- prop_value_t *prop_value)
+static bool
+replace_uses_in (gimple stmt, prop_value_t *prop_value)
{
bool replaced = false;
use_operand_p use;
@@ -931,7 +951,7 @@ replace_uses_in (tree stmt, bool *replaced_addresses_p,
if (val == tuse || val == NULL_TREE)
continue;
- if (TREE_CODE (stmt) == ASM_EXPR
+ if (gimple_code (stmt) == GIMPLE_ASM
&& !may_propagate_copy_into_asm (tuse))
continue;
@@ -946,8 +966,6 @@ replace_uses_in (tree stmt, bool *replaced_addresses_p,
propagate_value (use, val);
replaced = true;
- if (POINTER_TYPE_P (TREE_TYPE (tuse)) && replaced_addresses_p)
- *replaced_addresses_p = true;
}
return replaced;
@@ -955,9 +973,7 @@ replace_uses_in (tree stmt, bool *replaced_addresses_p,
/* Replace the VUSE references in statement STMT with the values
- stored in PROP_VALUE. Return true if a reference was replaced. If
- REPLACED_ADDRESSES_P is given, it will be set to true if an address
- constant was replaced.
+ stored in PROP_VALUE. Return true if a reference was replaced.
Replacing VUSE operands is slightly more complex than replacing
regular USEs. We are only interested in two types of replacements
@@ -1016,8 +1032,7 @@ replace_uses_in (tree stmt, bool *replaced_addresses_p,
replace_uses_in. */
static bool
-replace_vuses_in (tree stmt, bool *replaced_addresses_p,
- prop_value_t *prop_value)
+replace_vuses_in (gimple stmt, prop_value_t *prop_value)
{
bool replaced = false;
ssa_op_iter iter;
@@ -1029,29 +1044,21 @@ replace_vuses_in (tree stmt, bool *replaced_addresses_p,
see if we are trying to propagate a constant or a GIMPLE
register (case #1 above). */
prop_value_t *val = get_value_loaded_by (stmt, prop_value);
- tree rhs = GIMPLE_STMT_OPERAND (stmt, 1);
+ tree rhs = gimple_assign_rhs1 (stmt);
if (val
&& val->value
&& (is_gimple_reg (val->value)
|| is_gimple_min_invariant (val->value))
&& simple_cst_equal (rhs, val->mem_ref) == 1)
-
{
- /* If we are replacing a constant address, inform our
- caller. */
- if (TREE_CODE (val->value) != SSA_NAME
- && POINTER_TYPE_P (TREE_TYPE (GIMPLE_STMT_OPERAND (stmt, 1)))
- && replaced_addresses_p)
- *replaced_addresses_p = true;
-
/* We can only perform the substitution if the load is done
from the same memory location as the original store.
Since we already know that there are no intervening
stores between DEF_STMT and STMT, we only need to check
that the RHS of STMT is the same as the memory reference
propagated together with the value. */
- GIMPLE_STMT_OPERAND (stmt, 1) = val->value;
+ gimple_assign_set_rhs1 (stmt, val->value);
if (TREE_CODE (val->value) != SSA_NAME)
prop_stats.num_const_prop++;
@@ -1094,18 +1101,20 @@ replace_vuses_in (tree stmt, bool *replaced_addresses_p,
values from PROP_VALUE. */
static void
-replace_phi_args_in (tree phi, prop_value_t *prop_value)
+replace_phi_args_in (gimple phi, prop_value_t *prop_value)
{
- int i;
+ size_t i;
bool replaced = false;
- tree prev_phi = NULL;
if (dump_file && (dump_flags & TDF_DETAILS))
- prev_phi = unshare_expr (phi);
+ {
+ fprintf (dump_file, "Folding PHI node: ");
+ print_gimple_stmt (dump_file, phi, 0, TDF_SLIM);
+ }
- for (i = 0; i < PHI_NUM_ARGS (phi); i++)
+ for (i = 0; i < gimple_phi_num_args (phi); i++)
{
- tree arg = PHI_ARG_DEF (phi, i);
+ tree arg = gimple_phi_arg_def (phi, i);
if (TREE_CODE (arg) == SSA_NAME)
{
@@ -1125,72 +1134,84 @@ replace_phi_args_in (tree phi, prop_value_t *prop_value)
through an abnormal edge, update the replacement
accordingly. */
if (TREE_CODE (val) == SSA_NAME
- && PHI_ARG_EDGE (phi, i)->flags & EDGE_ABNORMAL)
+ && gimple_phi_arg_edge (phi, i)->flags & EDGE_ABNORMAL)
SSA_NAME_OCCURS_IN_ABNORMAL_PHI (val) = 1;
}
}
}
- if (replaced && dump_file && (dump_flags & TDF_DETAILS))
+ if (dump_file && (dump_flags & TDF_DETAILS))
{
- fprintf (dump_file, "Folded PHI node: ");
- print_generic_stmt (dump_file, prev_phi, TDF_SLIM);
- fprintf (dump_file, " into: ");
- print_generic_stmt (dump_file, phi, TDF_SLIM);
- fprintf (dump_file, "\n");
+ if (!replaced)
+ fprintf (dump_file, "No folding possible\n");
+ else
+ {
+ fprintf (dump_file, "Folded into: ");
+ print_gimple_stmt (dump_file, phi, 0, TDF_SLIM);
+ fprintf (dump_file, "\n");
+ }
}
}
-/* If STMT has a predicate whose value can be computed using the value
- range information computed by VRP, compute its value and return true.
- Otherwise, return false. */
+/* If the statement pointed by SI has a predicate whose value can be
+ computed using the value range information computed by VRP, compute
+ its value and return true. Otherwise, return false. */
static bool
-fold_predicate_in (tree stmt)
+fold_predicate_in (gimple_stmt_iterator *si)
{
- tree *pred_p = NULL;
- bool modify_stmt_p = false;
+ bool assignment_p = false;
tree val;
+ gimple stmt = gsi_stmt (*si);
- if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT
- && COMPARISON_CLASS_P (GIMPLE_STMT_OPERAND (stmt, 1)))
+ if (is_gimple_assign (stmt)
+ && TREE_CODE_CLASS (gimple_assign_rhs_code (stmt)) == tcc_comparison)
{
- modify_stmt_p = true;
- pred_p = &GIMPLE_STMT_OPERAND (stmt, 1);
+ assignment_p = true;
+ val = vrp_evaluate_conditional (gimple_assign_rhs_code (stmt),
+ gimple_assign_rhs1 (stmt),
+ gimple_assign_rhs2 (stmt),
+ stmt);
}
- else if (TREE_CODE (stmt) == COND_EXPR)
- pred_p = &COND_EXPR_COND (stmt);
+ else if (gimple_code (stmt) == GIMPLE_COND)
+ val = vrp_evaluate_conditional (gimple_cond_code (stmt),
+ gimple_cond_lhs (stmt),
+ gimple_cond_rhs (stmt),
+ stmt);
else
return false;
- if (TREE_CODE (*pred_p) == SSA_NAME)
- val = vrp_evaluate_conditional (EQ_EXPR,
- *pred_p,
- boolean_true_node,
- stmt);
- else
- val = vrp_evaluate_conditional (TREE_CODE (*pred_p),
- TREE_OPERAND (*pred_p, 0),
- TREE_OPERAND (*pred_p, 1),
- stmt);
if (val)
{
- if (modify_stmt_p)
- val = fold_convert (TREE_TYPE (*pred_p), val);
+ if (assignment_p)
+ val = fold_convert (gimple_expr_type (stmt), val);
if (dump_file)
{
fprintf (dump_file, "Folding predicate ");
- print_generic_expr (dump_file, *pred_p, 0);
+ print_gimple_expr (dump_file, stmt, 0, 0);
fprintf (dump_file, " to ");
print_generic_expr (dump_file, val, 0);
fprintf (dump_file, "\n");
}
prop_stats.num_pred_folded++;
- *pred_p = val;
+
+ if (is_gimple_assign (stmt))
+ gimple_assign_set_rhs_from_tree (si, val);
+ else
+ {
+ gcc_assert (gimple_code (stmt) == GIMPLE_COND);
+ if (integer_zerop (val))
+ gimple_cond_make_false (stmt);
+ else if (integer_onep (val))
+ gimple_cond_make_true (stmt);
+ else
+ gcc_unreachable ();
+ }
+
return true;
}
@@ -1222,78 +1243,83 @@ substitute_and_fold (prop_value_t *prop_value, bool use_ranges_p)
return false;
if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file, "\nSubstituing values and folding statements\n\n");
+ fprintf (dump_file, "\nSubstituting values and folding statements\n\n");
memset (&prop_stats, 0, sizeof (prop_stats));
/* Substitute values in every statement of every basic block. */
FOR_EACH_BB (bb)
{
- block_stmt_iterator i;
- tree phi;
+ gimple_stmt_iterator i;
/* Propagate known values into PHI nodes. */
if (prop_value)
- for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
- replace_phi_args_in (phi, prop_value);
+ for (i = gsi_start_phis (bb); !gsi_end_p (i); gsi_next (&i))
+ replace_phi_args_in (gsi_stmt (i), prop_value);
/* Propagate known values into stmts. Do a backward walk to expose
more trivially deletable stmts. */
- for (i = bsi_last (bb); !bsi_end_p (i);)
+ for (i = gsi_last_bb (bb); !gsi_end_p (i);)
{
- bool replaced_address, did_replace;
- tree call, prev_stmt = NULL;
- tree stmt = bsi_stmt (i);
+ bool did_replace;
+ gimple stmt = gsi_stmt (i);
+ enum gimple_code code = gimple_code (stmt);
/* Ignore ASSERT_EXPRs. They are used by VRP to generate
range information for names and they are discarded
afterwards. */
- if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT
- && TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 1)) == ASSERT_EXPR)
+
+ if (code == GIMPLE_ASSIGN
+ && TREE_CODE (gimple_assign_rhs1 (stmt)) == ASSERT_EXPR)
{
- bsi_prev (&i);
+ gsi_prev (&i);
continue;
}
/* No point propagating into a stmt whose result is not used,
but instead we might be able to remove a trivially dead stmt. */
- if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT
- && TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 0)) == SSA_NAME
- && !stmt_ann (stmt)->has_volatile_ops
- && has_zero_uses (GIMPLE_STMT_OPERAND (stmt, 0))
- && !tree_could_throw_p (stmt)
- && (!(call = get_call_expr_in (stmt))
- || !TREE_SIDE_EFFECTS (call)))
+ if (gimple_get_lhs (stmt)
+ && TREE_CODE (gimple_get_lhs (stmt)) == SSA_NAME
+ && has_zero_uses (gimple_get_lhs (stmt))
+ && !stmt_could_throw_p (stmt)
+ && !gimple_has_side_effects (stmt))
{
- block_stmt_iterator i2;
+ gimple_stmt_iterator i2;
+
if (dump_file && dump_flags & TDF_DETAILS)
{
fprintf (dump_file, "Removing dead stmt ");
- print_generic_expr (dump_file, stmt, 0);
+ print_gimple_stmt (dump_file, stmt, 0, 0);
fprintf (dump_file, "\n");
}
prop_stats.num_dce++;
- bsi_prev (&i);
- i2 = bsi_for_stmt (stmt);
- bsi_remove (&i2, true);
+ gsi_prev (&i);
+ i2 = gsi_for_stmt (stmt);
+ gsi_remove (&i2, true);
release_defs (stmt);
continue;
}
/* Record the state of the statement before replacements. */
- push_stmt_changes (bsi_stmt_ptr (i));
+ push_stmt_changes (gsi_stmt_ptr (&i));
/* Replace the statement with its folded version and mark it
folded. */
did_replace = false;
- replaced_address = false;
if (dump_file && (dump_flags & TDF_DETAILS))
- prev_stmt = unshare_expr (stmt);
+ {
+ fprintf (dump_file, "Folding statement: ");
+ print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
+ }
/* If we have range information, see if we can fold
predicate expressions. */
if (use_ranges_p)
- did_replace = fold_predicate_in (stmt);
+ {
+ did_replace = fold_predicate_in (&i);
+ /* fold_predicate_in should not have reallocated STMT. */
+ gcc_assert (gsi_stmt (i) == stmt);
+ }
if (prop_value)
{
@@ -1302,48 +1328,54 @@ substitute_and_fold (prop_value_t *prop_value, bool use_ranges_p)
information is not collected on virtuals, so we only
need to check this for real uses). */
if (!did_replace)
- did_replace |= replace_uses_in (stmt, &replaced_address,
- prop_value);
+ did_replace |= replace_uses_in (stmt, prop_value);
- did_replace |= replace_vuses_in (stmt, &replaced_address,
- prop_value);
+ did_replace |= replace_vuses_in (stmt, prop_value);
}
/* If we made a replacement, fold and cleanup the statement. */
if (did_replace)
{
- tree old_stmt = stmt;
- tree rhs;
+ gimple old_stmt = stmt;
- fold_stmt (bsi_stmt_ptr (i));
- stmt = bsi_stmt (i);
+ fold_stmt (&i);
+ stmt = gsi_stmt (i);
/* If we cleaned up EH information from the statement,
remove EH edges. */
if (maybe_clean_or_replace_eh_stmt (old_stmt, stmt))
- tree_purge_dead_eh_edges (bb);
-
- rhs = get_rhs (stmt);
- if (TREE_CODE (rhs) == ADDR_EXPR)
- recompute_tree_invariant_for_addr_expr (rhs);
-
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file, "Folded statement: ");
- print_generic_stmt (dump_file, prev_stmt, TDF_SLIM);
- fprintf (dump_file, " into: ");
- print_generic_stmt (dump_file, stmt, TDF_SLIM);
- fprintf (dump_file, "\n");
- }
+ gimple_purge_dead_eh_edges (bb);
+
+ if (is_gimple_assign (stmt)
+ && (get_gimple_rhs_class (gimple_assign_rhs_code (stmt))
+ == GIMPLE_SINGLE_RHS))
+ {
+ tree rhs = gimple_assign_rhs1 (stmt);
+
+ if (TREE_CODE (rhs) == ADDR_EXPR)
+ recompute_tree_invariant_for_addr_expr (rhs);
+ }
/* Determine what needs to be done to update the SSA form. */
- pop_stmt_changes (bsi_stmt_ptr (i));
+ pop_stmt_changes (gsi_stmt_ptr (&i));
something_changed = true;
}
else
{
/* The statement was not modified, discard the change buffer. */
- discard_stmt_changes (bsi_stmt_ptr (i));
+ discard_stmt_changes (gsi_stmt_ptr (&i));
+ }
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ if (did_replace)
+ {
+ fprintf (dump_file, "Folded into: ");
+ print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
+ fprintf (dump_file, "\n");
+ }
+ else
+ fprintf (dump_file, "Not folded\n");
}
/* Some statements may be simplified using ranges. For
@@ -1355,7 +1387,7 @@ substitute_and_fold (prop_value_t *prop_value, bool use_ranges_p)
if (use_ranges_p)
simplify_stmt_using_ranges (stmt);
- bsi_prev (&i);
+ gsi_prev (&i);
}
}
diff --git a/gcc/tree-ssa-propagate.h b/gcc/tree-ssa-propagate.h
index 18133788309..e472baca7c7 100644
--- a/gcc/tree-ssa-propagate.h
+++ b/gcc/tree-ssa-propagate.h
@@ -22,9 +22,21 @@ along with GCC; see the file COPYING3. If not see
#ifndef _TREE_SSA_PROPAGATE_H
#define _TREE_SSA_PROPAGATE_H 1
-/* Use the TREE_VISITED bitflag to mark statements and PHI nodes that
- have been deemed varying and should not be simulated again. */
-#define DONT_SIMULATE_AGAIN(T) TREE_VISITED (T)
+/* If SIM_P is true, statement S will be simulated again. */
+
+static inline void
+prop_set_simulate_again (gimple s, bool visit_p)
+{
+ gimple_set_visited (s, visit_p);
+}
+
+/* Return true if statement T should be simulated again. */
+
+static inline bool
+prop_simulate_again_p (gimple s)
+{
+ return gimple_visited_p (s);
+}
/* Lattice values used for propagation purposes. Specific instances
of a propagation engine must return these values from the statement
@@ -106,20 +118,20 @@ typedef struct value_range_d value_range_t;
/* Call-back functions used by the value propagation engine. */
-typedef enum ssa_prop_result (*ssa_prop_visit_stmt_fn) (tree, edge *, tree *);
-typedef enum ssa_prop_result (*ssa_prop_visit_phi_fn) (tree);
+typedef enum ssa_prop_result (*ssa_prop_visit_stmt_fn) (gimple, edge *, tree *);
+typedef enum ssa_prop_result (*ssa_prop_visit_phi_fn) (gimple);
/* In tree-ssa-propagate.c */
void ssa_propagate (ssa_prop_visit_stmt_fn, ssa_prop_visit_phi_fn);
-tree get_rhs (tree);
-bool valid_gimple_expression_p (tree expr);
-bool set_rhs (tree *, tree);
-tree first_vdef (tree);
-bool stmt_makes_single_load (tree);
-bool stmt_makes_single_store (tree);
-prop_value_t *get_value_loaded_by (tree, prop_value_t *);
-bool replace_uses_in (tree, bool *, prop_value_t *);
+bool valid_gimple_rhs_p (tree);
+bool valid_gimple_call_p (tree);
+void move_ssa_defining_stmt_for_defs (gimple, gimple);
+bool update_call_from_tree (gimple_stmt_iterator *, tree);
+tree first_vdef (gimple);
+bool stmt_makes_single_load (gimple);
+bool stmt_makes_single_store (gimple);
+prop_value_t *get_value_loaded_by (gimple, prop_value_t *);
bool substitute_and_fold (prop_value_t *, bool);
#endif /* _TREE_SSA_PROPAGATE_H */
diff --git a/gcc/tree-ssa-reassoc.c b/gcc/tree-ssa-reassoc.c
index 5fcaa7bbb16..a3facd8baa1 100644
--- a/gcc/tree-ssa-reassoc.c
+++ b/gcc/tree-ssa-reassoc.c
@@ -29,7 +29,7 @@ along with GCC; see the file COPYING3. If not see
#include "diagnostic.h"
#include "tree-inline.h"
#include "tree-flow.h"
-#include "tree-gimple.h"
+#include "gimple.h"
#include "tree-dump.h"
#include "timevar.h"
#include "tree-iterator.h"
@@ -230,23 +230,21 @@ get_rank (tree e)
if (TREE_CODE (e) == SSA_NAME)
{
- tree stmt;
- tree rhs;
+ gimple stmt;
long rank, maxrank;
- int i;
- int n;
+ int i, n;
if (TREE_CODE (SSA_NAME_VAR (e)) == PARM_DECL
&& SSA_NAME_IS_DEFAULT_DEF (e))
return find_operand_rank (e);
stmt = SSA_NAME_DEF_STMT (e);
- if (bb_for_stmt (stmt) == NULL)
+ if (gimple_bb (stmt) == NULL)
return 0;
- if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT
+ if (!is_gimple_assign (stmt)
|| !ZERO_SSA_OPERANDS (stmt, SSA_OP_VIRTUAL_DEFS))
- return bb_rank[bb_for_stmt (stmt)->index];
+ return bb_rank[gimple_bb (stmt)->index];
/* If we already have a rank for this expression, use that. */
rank = find_operand_rank (e);
@@ -256,19 +254,28 @@ get_rank (tree e)
/* Otherwise, find the maximum rank for the operands, or the bb
rank, whichever is less. */
rank = 0;
- maxrank = bb_rank[bb_for_stmt(stmt)->index];
- rhs = GIMPLE_STMT_OPERAND (stmt, 1);
- n = TREE_OPERAND_LENGTH (rhs);
- if (n == 0)
- rank = MAX (rank, get_rank (rhs));
+ maxrank = bb_rank[gimple_bb(stmt)->index];
+ if (gimple_assign_single_p (stmt))
+ {
+ tree rhs = gimple_assign_rhs1 (stmt);
+ n = TREE_OPERAND_LENGTH (rhs);
+ if (n == 0)
+ rank = MAX (rank, get_rank (rhs));
+ else
+ {
+ for (i = 0;
+ i < n && TREE_OPERAND (rhs, i) && rank != maxrank; i++)
+ rank = MAX(rank, get_rank (TREE_OPERAND (rhs, i)));
+ }
+ }
else
{
- for (i = 0;
- i < n
- && TREE_OPERAND (rhs, i)
- && rank != maxrank;
- i++)
- rank = MAX(rank, get_rank (TREE_OPERAND (rhs, i)));
+ n = gimple_num_ops (stmt);
+ for (i = 1; i < n && rank != maxrank; i++)
+ {
+ gcc_assert (gimple_op (stmt, i));
+ rank = MAX(rank, get_rank (gimple_op (stmt, i)));
+ }
}
if (dump_file && (dump_flags & TDF_DETAILS))
@@ -349,21 +356,21 @@ add_to_ops_vec (VEC(operand_entry_t, heap) **ops, tree op)
operation with tree code CODE, and is inside LOOP. */
static bool
-is_reassociable_op (tree stmt, enum tree_code code, struct loop *loop)
+is_reassociable_op (gimple stmt, enum tree_code code, struct loop *loop)
{
- basic_block bb;
+ basic_block bb = gimple_bb (stmt);
- if (IS_EMPTY_STMT (stmt))
+ if (gimple_bb (stmt) == NULL)
return false;
- bb = bb_for_stmt (stmt);
if (!flow_bb_inside_loop_p (loop, bb))
return false;
- if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT
- && TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 1)) == code
- && has_single_use (GIMPLE_STMT_OPERAND (stmt, 0)))
+ if (is_gimple_assign (stmt)
+ && gimple_assign_rhs_code (stmt) == code
+ && has_single_use (gimple_assign_lhs (stmt)))
return true;
+
return false;
}
@@ -374,15 +381,13 @@ is_reassociable_op (tree stmt, enum tree_code code, struct loop *loop)
static tree
get_unary_op (tree name, enum tree_code opcode)
{
- tree stmt = SSA_NAME_DEF_STMT (name);
- tree rhs;
+ gimple stmt = SSA_NAME_DEF_STMT (name);
- if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT)
+ if (!is_gimple_assign (stmt))
return NULL_TREE;
- rhs = GIMPLE_STMT_OPERAND (stmt, 1);
- if (TREE_CODE (rhs) == opcode)
- return TREE_OPERAND (rhs, 0);
+ if (gimple_assign_rhs_code (stmt) == opcode)
+ return gimple_assign_rhs1 (stmt);
return NULL_TREE;
}
@@ -806,18 +811,20 @@ optimize_ops_list (enum tree_code opcode,
update" operation. */
static bool
-is_phi_for_stmt (tree stmt, tree operand)
+is_phi_for_stmt (gimple stmt, tree operand)
{
- tree def_stmt;
- tree lhs = GIMPLE_STMT_OPERAND (stmt, 0);
+ gimple def_stmt;
+ tree lhs;
use_operand_p arg_p;
ssa_op_iter i;
if (TREE_CODE (operand) != SSA_NAME)
return false;
+ lhs = gimple_assign_lhs (stmt);
+
def_stmt = SSA_NAME_DEF_STMT (operand);
- if (TREE_CODE (def_stmt) != PHI_NODE)
+ if (gimple_code (def_stmt) != GIMPLE_PHI)
return false;
FOR_EACH_PHI_ARG (arg_p, def_stmt, i, SSA_OP_USE)
@@ -831,10 +838,11 @@ is_phi_for_stmt (tree stmt, tree operand)
order. */
static void
-rewrite_expr_tree (tree stmt, unsigned int opindex,
+rewrite_expr_tree (gimple stmt, unsigned int opindex,
VEC(operand_entry_t, heap) * ops)
{
- tree rhs = GIMPLE_STMT_OPERAND (stmt, 1);
+ tree rhs1 = gimple_assign_rhs1 (stmt);
+ tree rhs2 = gimple_assign_rhs2 (stmt);
operand_entry_t oe;
/* If we have three operands left, then we want to make sure the one
@@ -897,24 +905,22 @@ rewrite_expr_tree (tree stmt, unsigned int opindex,
oe1 = VEC_index (operand_entry_t, ops, opindex);
oe2 = VEC_index (operand_entry_t, ops, opindex + 1);
- if (TREE_OPERAND (rhs, 0) != oe1->op
- || TREE_OPERAND (rhs, 1) != oe2->op)
+ if (rhs1 != oe1->op || rhs2 != oe2->op)
{
-
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "Transforming ");
- print_generic_expr (dump_file, rhs, 0);
+ print_gimple_stmt (dump_file, stmt, 0, 0);
}
- TREE_OPERAND (rhs, 0) = oe1->op;
- TREE_OPERAND (rhs, 1) = oe2->op;
+ gimple_assign_set_rhs1 (stmt, oe1->op);
+ gimple_assign_set_rhs2 (stmt, oe2->op);
update_stmt (stmt);
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, " into ");
- print_generic_stmt (dump_file, rhs, 0);
+ print_gimple_stmt (dump_file, stmt, 0, 0);
}
}
@@ -927,28 +933,27 @@ rewrite_expr_tree (tree stmt, unsigned int opindex,
/* Rewrite the next operator. */
oe = VEC_index (operand_entry_t, ops, opindex);
- if (oe->op != TREE_OPERAND (rhs, 1))
+ if (oe->op != rhs2)
{
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "Transforming ");
- print_generic_expr (dump_file, rhs, 0);
+ print_gimple_stmt (dump_file, stmt, 0, 0);
}
- TREE_OPERAND (rhs, 1) = oe->op;
+ gimple_assign_set_rhs2 (stmt, oe->op);
update_stmt (stmt);
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, " into ");
- print_generic_stmt (dump_file, rhs, 0);
+ print_gimple_stmt (dump_file, stmt, 0, 0);
}
}
/* Recurse on the LHS of the binary operator, which is guaranteed to
be the non-leaf side. */
- rewrite_expr_tree (SSA_NAME_DEF_STMT (TREE_OPERAND (rhs, 0)),
- opindex + 1, ops);
+ rewrite_expr_tree (SSA_NAME_DEF_STMT (rhs1), opindex + 1, ops);
}
/* Transform STMT, which is really (A +B) + (C + D) into the left
@@ -956,114 +961,114 @@ rewrite_expr_tree (tree stmt, unsigned int opindex,
Recurse on D if necessary. */
static void
-linearize_expr (tree stmt)
+linearize_expr (gimple stmt)
{
- block_stmt_iterator bsinow, bsirhs;
- tree rhs = GIMPLE_STMT_OPERAND (stmt, 1);
- enum tree_code rhscode = TREE_CODE (rhs);
- tree binrhs = SSA_NAME_DEF_STMT (TREE_OPERAND (rhs, 1));
- tree binlhs = SSA_NAME_DEF_STMT (TREE_OPERAND (rhs, 0));
- tree newbinrhs = NULL_TREE;
+ gimple_stmt_iterator gsinow, gsirhs;
+ gimple binlhs = SSA_NAME_DEF_STMT (gimple_assign_rhs1 (stmt));
+ gimple binrhs = SSA_NAME_DEF_STMT (gimple_assign_rhs2 (stmt));
+ enum tree_code rhscode = gimple_assign_rhs_code (stmt);
+ gimple newbinrhs = NULL;
struct loop *loop = loop_containing_stmt (stmt);
- gcc_assert (is_reassociable_op (binlhs, TREE_CODE (rhs), loop)
- && is_reassociable_op (binrhs, TREE_CODE (rhs), loop));
+ gcc_assert (is_reassociable_op (binlhs, rhscode, loop)
+ && is_reassociable_op (binrhs, rhscode, loop));
+
+ gsinow = gsi_for_stmt (stmt);
+ gsirhs = gsi_for_stmt (binrhs);
+ gsi_move_before (&gsirhs, &gsinow);
- bsinow = bsi_for_stmt (stmt);
- bsirhs = bsi_for_stmt (binrhs);
- bsi_move_before (&bsirhs, &bsinow);
+ gimple_assign_set_rhs2 (stmt, gimple_assign_rhs1 (binrhs));
+ gimple_assign_set_rhs1 (binrhs, gimple_assign_lhs (binlhs));
+ gimple_assign_set_rhs1 (stmt, gimple_assign_lhs (binrhs));
- TREE_OPERAND (rhs, 1) = TREE_OPERAND (GIMPLE_STMT_OPERAND (binrhs, 1), 0);
- if (TREE_CODE (TREE_OPERAND (rhs, 1)) == SSA_NAME)
- newbinrhs = SSA_NAME_DEF_STMT (TREE_OPERAND (rhs, 1));
- TREE_OPERAND (GIMPLE_STMT_OPERAND (binrhs, 1), 0)
- = GIMPLE_STMT_OPERAND (binlhs, 0);
- TREE_OPERAND (rhs, 0) = GIMPLE_STMT_OPERAND (binrhs, 0);
+ if (TREE_CODE (gimple_assign_rhs2 (stmt)) == SSA_NAME)
+ newbinrhs = SSA_NAME_DEF_STMT (gimple_assign_rhs2 (stmt));
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "Linearized: ");
- print_generic_stmt (dump_file, rhs, 0);
+ print_gimple_stmt (dump_file, stmt, 0, 0);
}
reassociate_stats.linearized++;
update_stmt (binrhs);
update_stmt (binlhs);
update_stmt (stmt);
- TREE_VISITED (binrhs) = 1;
- TREE_VISITED (binlhs) = 1;
- TREE_VISITED (stmt) = 1;
+
+ gimple_set_visited (stmt, true);
+ gimple_set_visited (binlhs, true);
+ gimple_set_visited (binrhs, true);
/* Tail recurse on the new rhs if it still needs reassociation. */
if (newbinrhs && is_reassociable_op (newbinrhs, rhscode, loop))
+ /* ??? This should probably be linearize_expr (newbinrhs) but I don't
+ want to change the algorithm while converting to tuples. */
linearize_expr (stmt);
}
-/* If LHS has a single immediate use that is a GIMPLE_MODIFY_STMT, return
+/* If LHS has a single immediate use that is a GIMPLE_ASSIGN statement, return
it. Otherwise, return NULL. */
-static tree
+static gimple
get_single_immediate_use (tree lhs)
{
use_operand_p immuse;
- tree immusestmt;
+ gimple immusestmt;
if (TREE_CODE (lhs) == SSA_NAME
- && single_imm_use (lhs, &immuse, &immusestmt))
- {
- if (TREE_CODE (immusestmt) == RETURN_EXPR)
- immusestmt = TREE_OPERAND (immusestmt, 0);
- if (TREE_CODE (immusestmt) == GIMPLE_MODIFY_STMT)
- return immusestmt;
- }
- return NULL_TREE;
+ && single_imm_use (lhs, &immuse, &immusestmt)
+ && is_gimple_assign (immusestmt))
+ return immusestmt;
+
+ return NULL;
}
-static VEC(tree, heap) *broken_up_subtracts;
+static VEC(tree, heap) *broken_up_subtracts;
/* Recursively negate the value of TONEGATE, and return the SSA_NAME
representing the negated value. Insertions of any necessary
- instructions go before BSI.
+ instructions go before GSI.
This function is recursive in that, if you hand it "a_5" as the
value to negate, and a_5 is defined by "a_5 = b_3 + b_4", it will
transform b_3 + b_4 into a_5 = -b_3 + -b_4. */
static tree
-negate_value (tree tonegate, block_stmt_iterator *bsi)
+negate_value (tree tonegate, gimple_stmt_iterator *gsi)
{
- tree negatedef = tonegate;
+ gimple negatedefstmt= NULL;
tree resultofnegate;
- if (TREE_CODE (tonegate) == SSA_NAME)
- negatedef = SSA_NAME_DEF_STMT (tonegate);
-
/* If we are trying to negate a name, defined by an add, negate the
add operands instead. */
+ if (TREE_CODE (tonegate) == SSA_NAME)
+ negatedefstmt = SSA_NAME_DEF_STMT (tonegate);
if (TREE_CODE (tonegate) == SSA_NAME
- && TREE_CODE (negatedef) == GIMPLE_MODIFY_STMT
- && TREE_CODE (GIMPLE_STMT_OPERAND (negatedef, 0)) == SSA_NAME
- && has_single_use (GIMPLE_STMT_OPERAND (negatedef, 0))
- && TREE_CODE (GIMPLE_STMT_OPERAND (negatedef, 1)) == PLUS_EXPR)
+ && is_gimple_assign (negatedefstmt)
+ && TREE_CODE (gimple_assign_lhs (negatedefstmt)) == SSA_NAME
+ && has_single_use (gimple_assign_lhs (negatedefstmt))
+ && gimple_assign_rhs_code (negatedefstmt) == PLUS_EXPR)
{
- block_stmt_iterator bsi;
- tree binop = GIMPLE_STMT_OPERAND (negatedef, 1);
-
- bsi = bsi_for_stmt (negatedef);
- TREE_OPERAND (binop, 0) = negate_value (TREE_OPERAND (binop, 0),
- &bsi);
- bsi = bsi_for_stmt (negatedef);
- TREE_OPERAND (binop, 1) = negate_value (TREE_OPERAND (binop, 1),
- &bsi);
- update_stmt (negatedef);
- return GIMPLE_STMT_OPERAND (negatedef, 0);
+ gimple_stmt_iterator gsi;
+ tree rhs1 = gimple_assign_rhs1 (negatedefstmt);
+ tree rhs2 = gimple_assign_rhs2 (negatedefstmt);
+
+ gsi = gsi_for_stmt (negatedefstmt);
+ rhs1 = negate_value (rhs1, &gsi);
+ gimple_assign_set_rhs1 (negatedefstmt, rhs1);
+
+ gsi = gsi_for_stmt (negatedefstmt);
+ rhs2 = negate_value (rhs2, &gsi);
+ gimple_assign_set_rhs2 (negatedefstmt, rhs2);
+
+ update_stmt (negatedefstmt);
+ return gimple_assign_lhs (negatedefstmt);
}
tonegate = fold_build1 (NEGATE_EXPR, TREE_TYPE (tonegate), tonegate);
- resultofnegate = force_gimple_operand_bsi (bsi, tonegate, true,
- NULL_TREE, true, BSI_SAME_STMT);
+ resultofnegate = force_gimple_operand_gsi (gsi, tonegate, true,
+ NULL_TREE, true, GSI_SAME_STMT);
VEC_safe_push (tree, heap, broken_up_subtracts, resultofnegate);
return resultofnegate;
-
}
/* Return true if we should break up the subtract in STMT into an add
@@ -1073,14 +1078,12 @@ negate_value (tree tonegate, block_stmt_iterator *bsi)
exposes the adds to reassociation. */
static bool
-should_break_up_subtract (tree stmt)
+should_break_up_subtract (gimple stmt)
{
-
- tree lhs = GIMPLE_STMT_OPERAND (stmt, 0);
- tree rhs = GIMPLE_STMT_OPERAND (stmt, 1);
- tree binlhs = TREE_OPERAND (rhs, 0);
- tree binrhs = TREE_OPERAND (rhs, 1);
- tree immusestmt;
+ tree lhs = gimple_assign_lhs (stmt);
+ tree binlhs = gimple_assign_rhs1 (stmt);
+ tree binrhs = gimple_assign_rhs2 (stmt);
+ gimple immusestmt;
struct loop *loop = loop_containing_stmt (stmt);
if (TREE_CODE (binlhs) == SSA_NAME
@@ -1093,28 +1096,28 @@ should_break_up_subtract (tree stmt)
if (TREE_CODE (lhs) == SSA_NAME
&& (immusestmt = get_single_immediate_use (lhs))
- && TREE_CODE (GIMPLE_STMT_OPERAND (immusestmt, 1)) == PLUS_EXPR)
+ && is_gimple_assign (immusestmt)
+ && gimple_assign_rhs_code (immusestmt) == PLUS_EXPR)
return true;
return false;
-
}
/* Transform STMT from A - B into A + -B. */
static void
-break_up_subtract (tree stmt, block_stmt_iterator *bsi)
+break_up_subtract (gimple stmt, gimple_stmt_iterator *gsip)
{
- tree rhs = GIMPLE_STMT_OPERAND (stmt, 1);
+ tree rhs1 = gimple_assign_rhs1 (stmt);
+ tree rhs2 = gimple_assign_rhs2 (stmt);
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "Breaking up subtract ");
- print_generic_stmt (dump_file, stmt, 0);
+ print_gimple_stmt (dump_file, stmt, 0, 0);
}
- TREE_SET_CODE (GIMPLE_STMT_OPERAND (stmt, 1), PLUS_EXPR);
- TREE_OPERAND (rhs, 1) = negate_value (TREE_OPERAND (rhs, 1), bsi);
-
+ rhs2 = negate_value (rhs2, gsip);
+ gimple_assign_set_rhs_with_ops (gsip, PLUS_EXPR, rhs1, rhs2);
update_stmt (stmt);
}
@@ -1122,19 +1125,18 @@ break_up_subtract (tree stmt, block_stmt_iterator *bsi)
Place the operands of the expression tree in the vector named OPS. */
static void
-linearize_expr_tree (VEC(operand_entry_t, heap) **ops, tree stmt)
+linearize_expr_tree (VEC(operand_entry_t, heap) **ops, gimple stmt)
{
- block_stmt_iterator bsinow, bsilhs;
- tree rhs = GENERIC_TREE_OPERAND (stmt, 1);
- tree binrhs = TREE_OPERAND (rhs, 1);
- tree binlhs = TREE_OPERAND (rhs, 0);
- tree binlhsdef, binrhsdef;
+ gimple_stmt_iterator gsinow, gsilhs;
+ tree binlhs = gimple_assign_rhs1 (stmt);
+ tree binrhs = gimple_assign_rhs2 (stmt);
+ gimple binlhsdef, binrhsdef;
bool binlhsisreassoc = false;
bool binrhsisreassoc = false;
- enum tree_code rhscode = TREE_CODE (rhs);
+ enum tree_code rhscode = gimple_assign_rhs_code (stmt);
struct loop *loop = loop_containing_stmt (stmt);
- TREE_VISITED (stmt) = 1;
+ gimple_set_visited (stmt, true);
if (TREE_CODE (binlhs) == SSA_NAME)
{
@@ -1168,17 +1170,18 @@ linearize_expr_tree (VEC(operand_entry_t, heap) **ops, tree stmt)
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "swapping operands of ");
- print_generic_expr (dump_file, stmt, 0);
+ print_gimple_stmt (dump_file, stmt, 0, 0);
}
- swap_tree_operands (stmt, &TREE_OPERAND (rhs, 0),
- &TREE_OPERAND (rhs, 1));
+ swap_tree_operands (stmt,
+ gimple_assign_rhs1_ptr (stmt),
+ gimple_assign_rhs2_ptr (stmt));
update_stmt (stmt);
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, " is now ");
- print_generic_stmt (dump_file, stmt, 0);
+ print_gimple_stmt (dump_file, stmt, 0, 0);
}
/* We want to make it so the lhs is always the reassociative op,
@@ -1190,17 +1193,16 @@ linearize_expr_tree (VEC(operand_entry_t, heap) **ops, tree stmt)
else if (binrhsisreassoc)
{
linearize_expr (stmt);
- gcc_assert (rhs == GIMPLE_STMT_OPERAND (stmt, 1));
- binlhs = TREE_OPERAND (rhs, 0);
- binrhs = TREE_OPERAND (rhs, 1);
+ binlhs = gimple_assign_rhs1 (stmt);
+ binrhs = gimple_assign_rhs2 (stmt);
}
gcc_assert (TREE_CODE (binrhs) != SSA_NAME
|| !is_reassociable_op (SSA_NAME_DEF_STMT (binrhs),
rhscode, loop));
- bsinow = bsi_for_stmt (stmt);
- bsilhs = bsi_for_stmt (SSA_NAME_DEF_STMT (binlhs));
- bsi_move_before (&bsilhs, &bsinow);
+ gsinow = gsi_for_stmt (stmt);
+ gsilhs = gsi_for_stmt (SSA_NAME_DEF_STMT (binlhs));
+ gsi_move_before (&gsilhs, &gsinow);
linearize_expr_tree (ops, SSA_NAME_DEF_STMT (binlhs));
add_to_ops_vec (ops, binrhs);
}
@@ -1216,7 +1218,7 @@ repropagate_negates (void)
for (i = 0; VEC_iterate (tree, broken_up_subtracts, i, negate); i++)
{
- tree user = get_single_immediate_use (negate);
+ gimple user = get_single_immediate_use (negate);
/* The negate operand can be either operand of a PLUS_EXPR
(it can be the LHS if the RHS is a constant for example).
@@ -1224,27 +1226,27 @@ repropagate_negates (void)
Force the negate operand to the RHS of the PLUS_EXPR, then
transform the PLUS_EXPR into a MINUS_EXPR. */
if (user
- && TREE_CODE (user) == GIMPLE_MODIFY_STMT
- && TREE_CODE (GIMPLE_STMT_OPERAND (user, 1)) == PLUS_EXPR)
+ && is_gimple_assign (user)
+ && gimple_assign_rhs_code (user) == PLUS_EXPR)
{
- tree rhs = GIMPLE_STMT_OPERAND (user, 1);
-
/* If the negated operand appears on the LHS of the
PLUS_EXPR, exchange the operands of the PLUS_EXPR
to force the negated operand to the RHS of the PLUS_EXPR. */
- if (TREE_OPERAND (GIMPLE_STMT_OPERAND (user, 1), 0) == negate)
+ if (gimple_assign_rhs1 (user) == negate)
{
- tree temp = TREE_OPERAND (rhs, 0);
- TREE_OPERAND (rhs, 0) = TREE_OPERAND (rhs, 1);
- TREE_OPERAND (rhs, 1) = temp;
+ swap_tree_operands (user,
+ gimple_assign_rhs1_ptr (user),
+ gimple_assign_rhs2_ptr (user));
}
/* Now transform the PLUS_EXPR into a MINUS_EXPR and replace
the RHS of the PLUS_EXPR with the operand of the NEGATE_EXPR. */
- if (TREE_OPERAND (GIMPLE_STMT_OPERAND (user, 1), 1) == negate)
+ if (gimple_assign_rhs2 (user) == negate)
{
- TREE_SET_CODE (rhs, MINUS_EXPR);
- TREE_OPERAND (rhs, 1) = get_unary_op (negate, NEGATE_EXPR);
+ tree rhs1 = gimple_assign_rhs1 (user);
+ tree rhs2 = get_unary_op (negate, NEGATE_EXPR);
+ gimple_stmt_iterator gsi = gsi_for_stmt (user);
+ gimple_assign_set_rhs_with_ops (&gsi, MINUS_EXPR, rhs1, rhs2);
update_stmt (user);
}
}
@@ -1264,43 +1266,50 @@ repropagate_negates (void)
k = t - q
we want to break up k = t - q, but we won't until we've transformed q
- = b - r, which won't be broken up until we transform b = c - d. */
+ = b - r, which won't be broken up until we transform b = c - d.
+
+ En passant, clear the GIMPLE visited flag on every statement. */
static void
break_up_subtract_bb (basic_block bb)
{
- block_stmt_iterator bsi;
+ gimple_stmt_iterator gsi;
basic_block son;
- for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
- tree stmt = bsi_stmt (bsi);
+ gimple stmt = gsi_stmt (gsi);
+ gimple_set_visited (stmt, false);
- if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT)
+ /* Look for simple gimple subtract operations. */
+ if (is_gimple_assign (stmt)
+ && gimple_assign_rhs_code (stmt) == MINUS_EXPR)
{
- tree lhs = GIMPLE_STMT_OPERAND (stmt, 0);
- tree rhs = GIMPLE_STMT_OPERAND (stmt, 1);
+ tree lhs = gimple_assign_lhs (stmt);
+ tree rhs1 = gimple_assign_rhs1 (stmt);
+ tree rhs2 = gimple_assign_rhs2 (stmt);
- TREE_VISITED (stmt) = 0;
/* If associative-math we can do reassociation for
non-integral types. Or, we can do reassociation for
non-saturating fixed-point types. */
if ((!INTEGRAL_TYPE_P (TREE_TYPE (lhs))
- || !INTEGRAL_TYPE_P (TREE_TYPE (rhs)))
- && (!SCALAR_FLOAT_TYPE_P (TREE_TYPE (rhs))
- || !SCALAR_FLOAT_TYPE_P (TREE_TYPE(lhs))
+ || !INTEGRAL_TYPE_P (TREE_TYPE (rhs1))
+ || !INTEGRAL_TYPE_P (TREE_TYPE (rhs2)))
+ && (!SCALAR_FLOAT_TYPE_P (TREE_TYPE (lhs))
+ || !SCALAR_FLOAT_TYPE_P (TREE_TYPE(rhs1))
+ || !SCALAR_FLOAT_TYPE_P (TREE_TYPE(rhs2))
|| !flag_associative_math)
- && (!NON_SAT_FIXED_POINT_TYPE_P (TREE_TYPE (rhs))
- || !NON_SAT_FIXED_POINT_TYPE_P (TREE_TYPE(lhs))))
+ && (!NON_SAT_FIXED_POINT_TYPE_P (TREE_TYPE (lhs))
+ || !NON_SAT_FIXED_POINT_TYPE_P (TREE_TYPE(rhs1))
+ || !NON_SAT_FIXED_POINT_TYPE_P (TREE_TYPE(rhs2))))
continue;
/* Check for a subtract used only in an addition. If this
is the case, transform it into add of a negate for better
reassociation. IE transform C = A-B into C = A + -B if C
is only used in an addition. */
- if (TREE_CODE (rhs) == MINUS_EXPR)
- if (should_break_up_subtract (stmt))
- break_up_subtract (stmt, &bsi);
+ if (should_break_up_subtract (stmt))
+ break_up_subtract (stmt, &gsi);
}
}
for (son = first_dom_son (CDI_DOMINATORS, bb);
@@ -1315,36 +1324,48 @@ break_up_subtract_bb (basic_block bb)
static void
reassociate_bb (basic_block bb)
{
- block_stmt_iterator bsi;
+ gimple_stmt_iterator gsi;
basic_block son;
- for (bsi = bsi_last (bb); !bsi_end_p (bsi); bsi_prev (&bsi))
+ for (gsi = gsi_last_bb (bb); !gsi_end_p (gsi); gsi_prev (&gsi))
{
- tree stmt = bsi_stmt (bsi);
+ gimple stmt = gsi_stmt (gsi);
- if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT)
+ if (is_gimple_assign (stmt))
{
- tree lhs = GIMPLE_STMT_OPERAND (stmt, 0);
- tree rhs = GIMPLE_STMT_OPERAND (stmt, 1);
+ tree lhs, rhs1, rhs2;
+ enum tree_code rhs_code = gimple_assign_rhs_code (stmt);
- /* If this was part of an already processed tree, we don't
- need to touch it again. */
- if (TREE_VISITED (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))
+ continue;
+
+ lhs = gimple_assign_lhs (stmt);
+ rhs1 = gimple_assign_rhs1 (stmt);
+ rhs2 = gimple_assign_rhs2 (stmt);
+
/* If associative-math we can do reassociation for
non-integral types. Or, we can do reassociation for
non-saturating fixed-point types. */
if ((!INTEGRAL_TYPE_P (TREE_TYPE (lhs))
- || !INTEGRAL_TYPE_P (TREE_TYPE (rhs)))
- && (!SCALAR_FLOAT_TYPE_P (TREE_TYPE (rhs))
- || !SCALAR_FLOAT_TYPE_P (TREE_TYPE(lhs))
+ || !INTEGRAL_TYPE_P (TREE_TYPE (rhs1))
+ || !INTEGRAL_TYPE_P (TREE_TYPE (rhs2)))
+ && (!SCALAR_FLOAT_TYPE_P (TREE_TYPE (lhs))
+ || !SCALAR_FLOAT_TYPE_P (TREE_TYPE(rhs1))
+ || !SCALAR_FLOAT_TYPE_P (TREE_TYPE(rhs2))
|| !flag_associative_math)
- && (!NON_SAT_FIXED_POINT_TYPE_P (TREE_TYPE (rhs))
- || !NON_SAT_FIXED_POINT_TYPE_P (TREE_TYPE(lhs))))
+ && (!NON_SAT_FIXED_POINT_TYPE_P (TREE_TYPE (lhs))
+ || !NON_SAT_FIXED_POINT_TYPE_P (TREE_TYPE(rhs1))
+ || !NON_SAT_FIXED_POINT_TYPE_P (TREE_TYPE(rhs2))))
continue;
- if (associative_tree_code (TREE_CODE (rhs)))
+ if (associative_tree_code (rhs_code))
{
VEC(operand_entry_t, heap) *ops = NULL;
@@ -1353,30 +1374,31 @@ reassociate_bb (basic_block bb)
if (TREE_CODE (lhs) == SSA_NAME && has_zero_uses (lhs))
continue;
- TREE_VISITED (stmt) = 1;
+ gimple_set_visited (stmt, true);
linearize_expr_tree (&ops, stmt);
qsort (VEC_address (operand_entry_t, ops),
VEC_length (operand_entry_t, ops),
sizeof (operand_entry_t),
sort_by_operand_rank);
- optimize_ops_list (TREE_CODE (rhs), &ops);
+ optimize_ops_list (rhs_code, &ops);
if (VEC_length (operand_entry_t, ops) == 1)
{
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "Transforming ");
- print_generic_expr (dump_file, rhs, 0);
+ print_gimple_stmt (dump_file, stmt, 0, 0);
}
- GIMPLE_STMT_OPERAND (stmt, 1)
- = VEC_last (operand_entry_t, ops)->op;
+
+ gimple_assign_set_rhs_from_tree (&gsi,
+ VEC_last (operand_entry_t,
+ ops)->op);
update_stmt (stmt);
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, " into ");
- print_generic_stmt (dump_file,
- GIMPLE_STMT_OPERAND (stmt, 1), 0);
+ print_gimple_stmt (dump_file, stmt, 0, 0);
}
}
else
@@ -1408,7 +1430,7 @@ dump_ops_vector (FILE *file, VEC (operand_entry_t, heap) *ops)
for (i = 0; VEC_iterate (operand_entry_t, ops, i, oe); i++)
{
fprintf (file, "Op %d -> rank: %d, tree: ", i, oe->rank);
- print_generic_stmt (file, oe->op, 0);
+ print_generic_expr (file, oe->op, 0);
}
}
@@ -1542,3 +1564,4 @@ struct gimple_opt_pass pass_reassoc =
TODO_dump_func | TODO_ggc_collect | TODO_verify_ssa /* todo_flags_finish */
}
};
+
diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c
index 99cc08d8445..42d394f5540 100644
--- a/gcc/tree-ssa-sccvn.c
+++ b/gcc/tree-ssa-sccvn.c
@@ -29,7 +29,7 @@ along with GCC; see the file COPYING3. If not see
#include "diagnostic.h"
#include "tree-inline.h"
#include "tree-flow.h"
-#include "tree-gimple.h"
+#include "gimple.h"
#include "tree-dump.h"
#include "timevar.h"
#include "fibheap.h"
@@ -115,72 +115,9 @@ typedef struct vn_tables_s
alloc_pool references_pool;
} *vn_tables_t;
-/* Nary operations in the hashtable consist of length operands, an
- opcode, and a type. Result is the value number of the operation,
- and hashcode is stored to avoid having to calculate it
- repeatedly. */
+static htab_t constant_to_value_id;
+static bitmap constant_value_ids;
-typedef struct vn_nary_op_s
-{
- ENUM_BITFIELD(tree_code) opcode : 16;
- unsigned length : 16;
- hashval_t hashcode;
- tree result;
- tree type;
- tree op[4];
-} *vn_nary_op_t;
-typedef const struct vn_nary_op_s *const_vn_nary_op_t;
-
-/* Phi nodes in the hashtable consist of their non-VN_TOP phi
- arguments, and the basic block the phi is in. Result is the value
- number of the operation, and hashcode is stored to avoid having to
- calculate it repeatedly. Phi nodes not in the same block are never
- considered equivalent. */
-
-typedef struct vn_phi_s
-{
- VEC (tree, heap) *phiargs;
- basic_block block;
- hashval_t hashcode;
- tree result;
-} *vn_phi_t;
-typedef const struct vn_phi_s *const_vn_phi_t;
-
-/* Reference operands only exist in reference operations structures.
- They consist of an opcode, type, and some number of operands. For
- a given opcode, some, all, or none of the operands may be used.
- The operands are there to store the information that makes up the
- portion of the addressing calculation that opcode performs. */
-
-typedef struct vn_reference_op_struct
-{
- enum tree_code opcode;
- tree type;
- tree op0;
- tree op1;
-} vn_reference_op_s;
-typedef vn_reference_op_s *vn_reference_op_t;
-typedef const vn_reference_op_s *const_vn_reference_op_t;
-
-DEF_VEC_O(vn_reference_op_s);
-DEF_VEC_ALLOC_O(vn_reference_op_s, heap);
-
-/* A reference operation in the hashtable is representation as a
- collection of vuses, representing the memory state at the time of
- the operation, and a collection of operands that make up the
- addressing calculation. If two vn_reference_t's have the same set
- of operands, they access the same memory location. We also store
- the resulting value number, and the hashcode. The vuses are
- always stored in order sorted by ssa name version. */
-
-typedef struct vn_reference_s
-{
- VEC (tree, gc) *vuses;
- VEC (vn_reference_op_s, heap) *operands;
- hashval_t hashcode;
- tree result;
-} *vn_reference_t;
-typedef const struct vn_reference_s *const_vn_reference_t;
/* Valid hashtables storing information we have proven to be
correct. */
@@ -192,11 +129,6 @@ static vn_tables_t valid_info;
static vn_tables_t optimistic_info;
-/* PRE hashtables storing information about mapping from expressions to
- value handles. */
-
-static vn_tables_t pre_info;
-
/* Pointer to the set of hashtables that is currently being used.
Should always point to either the optimistic_info, or the
valid_info. */
@@ -215,6 +147,10 @@ static int *rpo_numbers;
tree VN_TOP;
+/* Unique counter for our value ids. */
+
+static unsigned int next_value_id;
+
/* Next DFS number and the stack for strongly connected component
detection. */
@@ -239,8 +175,10 @@ static struct obstack vn_ssa_aux_obstack;
vn_ssa_aux_t
VN_INFO (tree name)
{
- return VEC_index (vn_ssa_aux_t, vn_ssa_aux_table,
- SSA_NAME_VERSION (name));
+ vn_ssa_aux_t res = VEC_index (vn_ssa_aux_t, vn_ssa_aux_table,
+ SSA_NAME_VERSION (name));
+ gcc_assert (res);
+ return res;
}
/* Set the value numbering info for a given SSA name to a given
@@ -272,6 +210,86 @@ VN_INFO_GET (tree name)
}
+/* Get the representative expression for the SSA_NAME NAME. Returns
+ the representative SSA_NAME if there is no expression associated with it. */
+
+tree
+vn_get_expr_for (tree name)
+{
+ vn_ssa_aux_t vn = VN_INFO (name);
+ gimple def_stmt;
+ tree expr = NULL_TREE;
+
+ if (vn->valnum == VN_TOP)
+ return name;
+
+ /* If the value-number is a constant it is the representative
+ expression. */
+ if (TREE_CODE (vn->valnum) != SSA_NAME)
+ return vn->valnum;
+
+ /* Get to the information of the value of this SSA_NAME. */
+ vn = VN_INFO (vn->valnum);
+
+ /* If the value-number is a constant it is the representative
+ expression. */
+ if (TREE_CODE (vn->valnum) != SSA_NAME)
+ return vn->valnum;
+
+ /* Else if we have an expression, return it. */
+ if (vn->expr != NULL_TREE)
+ return vn->expr;
+
+ /* Otherwise use the defining statement to build the expression. */
+ def_stmt = SSA_NAME_DEF_STMT (vn->valnum);
+
+ /* If the value number is a default-definition or a PHI result
+ use it directly. */
+ if (gimple_nop_p (def_stmt)
+ || gimple_code (def_stmt) == GIMPLE_PHI)
+ return vn->valnum;
+
+ if (!is_gimple_assign (def_stmt))
+ return vn->valnum;
+
+ /* FIXME tuples. This is incomplete and likely will miss some
+ simplifications. */
+ switch (TREE_CODE_CLASS (gimple_assign_rhs_code (def_stmt)))
+ {
+ case tcc_reference:
+ if (gimple_assign_rhs_code (def_stmt) == VIEW_CONVERT_EXPR
+ && gimple_assign_rhs_code (def_stmt) == REALPART_EXPR
+ && gimple_assign_rhs_code (def_stmt) == IMAGPART_EXPR)
+ expr = fold_build1 (gimple_assign_rhs_code (def_stmt),
+ gimple_expr_type (def_stmt),
+ TREE_OPERAND (gimple_assign_rhs1 (def_stmt), 0));
+ break;
+
+ case tcc_unary:
+ expr = fold_build1 (gimple_assign_rhs_code (def_stmt),
+ gimple_expr_type (def_stmt),
+ gimple_assign_rhs1 (def_stmt));
+ break;
+
+ case tcc_binary:
+ expr = fold_build2 (gimple_assign_rhs_code (def_stmt),
+ gimple_expr_type (def_stmt),
+ gimple_assign_rhs1 (def_stmt),
+ gimple_assign_rhs2 (def_stmt));
+ break;
+
+ default:;
+ }
+ if (expr == NULL_TREE)
+ return vn->valnum;
+
+ /* Cache the expression. */
+ vn->expr = expr;
+
+ return expr;
+}
+
+
/* Free a phi operation structure VP. */
static void
@@ -290,6 +308,76 @@ free_reference (void *vp)
VEC_free (vn_reference_op_s, heap, vr->operands);
}
+/* Hash table equality function for vn_constant_t. */
+
+static int
+vn_constant_eq (const void *p1, const void *p2)
+{
+ const struct vn_constant_s *vc1 = (const struct vn_constant_s *) p1;
+ const struct vn_constant_s *vc2 = (const struct vn_constant_s *) p2;
+
+ return vn_constant_eq_with_type (vc1->constant, vc2->constant);
+}
+
+/* Hash table hash function for vn_constant_t. */
+
+static hashval_t
+vn_constant_hash (const void *p1)
+{
+ const struct vn_constant_s *vc1 = (const struct vn_constant_s *) p1;
+ return vc1->hashcode;
+}
+
+/* Lookup a value id for CONSTANT and return it. If it does not
+ exist returns 0. */
+
+unsigned int
+get_constant_value_id (tree constant)
+{
+ void **slot;
+ struct vn_constant_s vc;
+
+ vc.hashcode = vn_hash_constant_with_type (constant);
+ vc.constant = constant;
+ slot = htab_find_slot_with_hash (constant_to_value_id, &vc,
+ vc.hashcode, NO_INSERT);
+ if (slot)
+ return ((vn_constant_t)*slot)->value_id;
+ return 0;
+}
+
+/* Lookup a value id for CONSTANT, and if it does not exist, create a
+ new one and return it. If it does exist, return it. */
+
+unsigned int
+get_or_alloc_constant_value_id (tree constant)
+{
+ void **slot;
+ vn_constant_t vc = XNEW (struct vn_constant_s);
+
+ vc->hashcode = vn_hash_constant_with_type (constant);
+ vc->constant = constant;
+ slot = htab_find_slot_with_hash (constant_to_value_id, vc,
+ vc->hashcode, INSERT);
+ if (*slot)
+ {
+ free (vc);
+ return ((vn_constant_t)*slot)->value_id;
+ }
+ vc->value_id = get_next_value_id ();
+ *slot = vc;
+ bitmap_set_bit (constant_value_ids, vc->value_id);
+ return vc->value_id;
+}
+
+/* Return true if V is a value id for a constant. */
+
+bool
+value_id_constant_p (unsigned int v)
+{
+ return bitmap_bit_p (constant_value_ids, v);
+}
+
/* Compare two reference operands P1 and P2 for equality. Return true if
they are equal, and false otherwise. */
@@ -301,7 +389,8 @@ vn_reference_op_eq (const void *p1, const void *p2)
return vro1->opcode == vro2->opcode
&& vro1->type == vro2->type
&& expressions_equal_p (vro1->op0, vro2->op0)
- && expressions_equal_p (vro1->op1, vro2->op1);
+ && expressions_equal_p (vro1->op1, vro2->op1)
+ && expressions_equal_p (vro1->op2, vro2->op2);
}
/* Compute the hash for a reference operand VRO1. */
@@ -310,7 +399,8 @@ static hashval_t
vn_reference_op_compute_hash (const vn_reference_op_t vro1)
{
return iterative_hash_expr (vro1->op0, vro1->opcode)
- + iterative_hash_expr (vro1->op1, vro1->opcode);
+ + iterative_hash_expr (vro1->op1, vro1->opcode)
+ + iterative_hash_expr (vro1->op2, vro1->opcode);
}
/* Return the hashcode for a given reference operation P1. */
@@ -324,7 +414,7 @@ vn_reference_hash (const void *p1)
/* Compute a hash for the reference operation VR1 and return it. */
-static inline hashval_t
+hashval_t
vn_reference_compute_hash (const vn_reference_t vr1)
{
hashval_t result = 0;
@@ -343,7 +433,7 @@ vn_reference_compute_hash (const vn_reference_t vr1)
/* Return true if reference operations P1 and P2 are equivalent. This
means they have the same set of operands and vuses. */
-static int
+int
vn_reference_eq (const void *p1, const void *p2)
{
tree v;
@@ -389,7 +479,7 @@ vn_reference_eq (const void *p1, const void *p2)
/* Place the vuses from STMT into *result. */
static inline void
-vuses_to_vec (tree stmt, VEC (tree, gc) **result)
+vuses_to_vec (gimple stmt, VEC (tree, gc) **result)
{
ssa_op_iter iter;
tree vuse;
@@ -409,7 +499,7 @@ vuses_to_vec (tree stmt, VEC (tree, gc) **result)
the vector. */
VEC (tree, gc) *
-copy_vuses_from_stmt (tree stmt)
+copy_vuses_from_stmt (gimple stmt)
{
VEC (tree, gc) *vuses = NULL;
@@ -421,7 +511,7 @@ copy_vuses_from_stmt (tree stmt)
/* Place the vdefs from STMT into *result. */
static inline void
-vdefs_to_vec (tree stmt, VEC (tree, gc) **result)
+vdefs_to_vec (gimple stmt, VEC (tree, gc) **result)
{
ssa_op_iter iter;
tree vdef;
@@ -439,7 +529,7 @@ vdefs_to_vec (tree stmt, VEC (tree, gc) **result)
the vector. */
static VEC (tree, gc) *
-copy_vdefs_from_stmt (tree stmt)
+copy_vdefs_from_stmt (gimple stmt)
{
VEC (tree, gc) *vdefs = NULL;
@@ -456,7 +546,7 @@ static VEC (tree, gc) *shared_lookup_vops;
variable. */
VEC (tree, gc) *
-shared_vuses_from_stmt (tree stmt)
+shared_vuses_from_stmt (gimple stmt)
{
VEC_truncate (tree, shared_lookup_vops, 0);
vuses_to_vec (stmt, &shared_lookup_vops);
@@ -464,46 +554,12 @@ shared_vuses_from_stmt (tree stmt)
return shared_lookup_vops;
}
-/* Copy the operations present in load/store/call REF into RESULT, a vector of
+/* Copy the operations present in load/store REF into RESULT, a vector of
vn_reference_op_s's. */
static void
copy_reference_ops_from_ref (tree ref, VEC(vn_reference_op_s, heap) **result)
{
- /* Calls are different from all other reference operations. */
- if (TREE_CODE (ref) == CALL_EXPR)
- {
- vn_reference_op_s temp;
- tree callfn;
- call_expr_arg_iterator iter;
- tree callarg;
-
- /* Copy the call_expr opcode, type, function being called, and
- arguments. */
- memset (&temp, 0, sizeof (temp));
- temp.type = TREE_TYPE (ref);
- temp.opcode = CALL_EXPR;
- VEC_safe_push (vn_reference_op_s, heap, *result, &temp);
-
- callfn = get_callee_fndecl (ref);
- if (!callfn)
- callfn = CALL_EXPR_FN (ref);
- temp.type = TREE_TYPE (callfn);
- temp.opcode = TREE_CODE (callfn);
- temp.op0 = callfn;
- VEC_safe_push (vn_reference_op_s, heap, *result, &temp);
-
- FOR_EACH_CALL_EXPR_ARG (callarg, iter, ref)
- {
- memset (&temp, 0, sizeof (temp));
- temp.type = TREE_TYPE (callarg);
- temp.opcode = TREE_CODE (callarg);
- temp.op0 = callarg;
- VEC_safe_push (vn_reference_op_s, heap, *result, &temp);
- }
- return;
- }
-
if (TREE_CODE (ref) == TARGET_MEM_REF)
{
vn_reference_op_s temp;
@@ -554,6 +610,7 @@ copy_reference_ops_from_ref (tree ref, VEC(vn_reference_op_s, heap) **result)
a matching type is not necessary and a mismatching type
is always a spurious difference. */
temp.type = NULL_TREE;
+#if FIXME
/* If this is a reference to a union member, record the union
member size as operand. Do so only if we are doing
expression insertion (during FRE), as PRE currently gets
@@ -564,14 +621,17 @@ copy_reference_ops_from_ref (tree ref, VEC(vn_reference_op_s, heap) **result)
&& integer_zerop (DECL_FIELD_BIT_OFFSET (TREE_OPERAND (ref, 1))))
temp.op0 = TYPE_SIZE (TREE_TYPE (TREE_OPERAND (ref, 1)));
else
+#endif
/* Record field as operand. */
temp.op0 = TREE_OPERAND (ref, 1);
+ temp.op1 = TREE_OPERAND (ref, 2);
break;
case ARRAY_RANGE_REF:
case ARRAY_REF:
/* Record index as operand. */
temp.op0 = TREE_OPERAND (ref, 1);
- temp.op1 = TREE_OPERAND (ref, 3);
+ temp.op1 = TREE_OPERAND (ref, 2);
+ temp.op2 = TREE_OPERAND (ref, 3);
break;
case STRING_CST:
case INTEGER_CST:
@@ -579,7 +639,6 @@ copy_reference_ops_from_ref (tree ref, VEC(vn_reference_op_s, heap) **result)
case VECTOR_CST:
case REAL_CST:
case CONSTRUCTOR:
- case VALUE_HANDLE:
case VAR_DECL:
case PARM_DECL:
case CONST_DECL:
@@ -610,6 +669,53 @@ copy_reference_ops_from_ref (tree ref, VEC(vn_reference_op_s, heap) **result)
}
}
+/* Copy the operations present in load/store/call REF into RESULT, a vector of
+ vn_reference_op_s's. */
+
+void
+copy_reference_ops_from_call (gimple call,
+ VEC(vn_reference_op_s, heap) **result)
+{
+ vn_reference_op_s temp;
+ tree callfn;
+ unsigned i;
+
+ /* Copy the call_expr opcode, type, function being called, and
+ arguments. */
+ memset (&temp, 0, sizeof (temp));
+ temp.type = gimple_call_return_type (call);
+ temp.opcode = CALL_EXPR;
+ VEC_safe_push (vn_reference_op_s, heap, *result, &temp);
+
+ /* FIXME tuples
+ We make no attempt to simplify the called function because
+ the typical &FUNCTION_DECL form is also used in function pointer
+ cases that become constant. If we simplify the original to
+ FUNCTION_DECL but not the function pointer case (which can
+ happen because we have no fold functions that operate on
+ vn_reference_t), we will claim they are not equivalent.
+
+ An example of this behavior can be see if CALL_EXPR_FN below is
+ replaced with get_callee_fndecl and gcc.dg/tree-ssa/ssa-pre-13.c
+ is compiled. */
+ callfn = gimple_call_fn (call);
+ temp.type = TREE_TYPE (callfn);
+ temp.opcode = TREE_CODE (callfn);
+ temp.op0 = callfn;
+ VEC_safe_push (vn_reference_op_s, heap, *result, &temp);
+
+ for (i = 0; i < gimple_call_num_args (call); ++i)
+ {
+ tree callarg = gimple_call_arg (call, i);
+ memset (&temp, 0, sizeof (temp));
+ temp.type = TREE_TYPE (callarg);
+ temp.opcode = TREE_CODE (callarg);
+ temp.op0 = callarg;
+ VEC_safe_push (vn_reference_op_s, heap, *result, &temp);
+ }
+ return;
+}
+
/* Create a vector of vn_reference_op_s structures from REF, a
REFERENCE_CLASS_P tree. The vector is not shared. */
@@ -622,6 +728,18 @@ create_reference_ops_from_ref (tree ref)
return result;
}
+/* Create a vector of vn_reference_op_s structures from CALL, a
+ call statement. The vector is not shared. */
+
+static VEC(vn_reference_op_s, heap) *
+create_reference_ops_from_call (gimple call)
+{
+ VEC (vn_reference_op_s, heap) *result = NULL;
+
+ copy_reference_ops_from_call (call, &result);
+ return result;
+}
+
static VEC(vn_reference_op_s, heap) *shared_lookup_references;
/* Create a vector of vn_reference_op_s structures from REF, a
@@ -638,6 +756,20 @@ shared_reference_ops_from_ref (tree ref)
return shared_lookup_references;
}
+/* Create a vector of vn_reference_op_s structures from CALL, a
+ call statement. The vector is shared among all callers of
+ this function. */
+
+static VEC(vn_reference_op_s, heap) *
+shared_reference_ops_from_call (gimple call)
+{
+ if (!call)
+ return NULL;
+ VEC_truncate (vn_reference_op_s, shared_lookup_references, 0);
+ copy_reference_ops_from_call (call, &shared_lookup_references);
+ return shared_lookup_references;
+}
+
/* Transform any SSA_NAME's in a vector of vn_reference_op_s
structures into their value numbers. This is done in-place, and
@@ -653,7 +785,16 @@ valueize_refs (VEC (vn_reference_op_s, heap) *orig)
{
if (vro->opcode == SSA_NAME
|| (vro->op0 && TREE_CODE (vro->op0) == SSA_NAME))
- vro->op0 = SSA_VAL (vro->op0);
+ {
+ vro->op0 = SSA_VAL (vro->op0);
+ /* If it transforms from an SSA_NAME to a constant, update
+ the opcode. */
+ if (TREE_CODE (vro->op0) != SSA_NAME && vro->opcode == SSA_NAME)
+ vro->opcode = TREE_CODE (vro->op0);
+ }
+ /* TODO: Do we want to valueize op2 and op1 of
+ ARRAY_REF/COMPONENT_REF for Ada */
+
}
return orig;
@@ -690,16 +831,17 @@ valueize_vuses (VEC (tree, gc) *orig)
Take into account only definitions that alias REF if following
back-edges. */
-static tree
+static gimple
get_def_ref_stmt_vuses (tree ref, VEC (tree, gc) *vuses)
{
- tree def_stmt, vuse;
+ gimple def_stmt;
+ tree vuse;
unsigned int i;
gcc_assert (VEC_length (tree, vuses) >= 1);
def_stmt = SSA_NAME_DEF_STMT (VEC_index (tree, vuses, 0));
- if (TREE_CODE (def_stmt) == PHI_NODE)
+ if (gimple_code (def_stmt) == GIMPLE_PHI)
{
/* We can only handle lookups over PHI nodes for a single
virtual operand. */
@@ -709,23 +851,22 @@ get_def_ref_stmt_vuses (tree ref, VEC (tree, gc) *vuses)
goto cont;
}
else
- return NULL_TREE;
+ return NULL;
}
/* Verify each VUSE reaches the same defining stmt. */
for (i = 1; VEC_iterate (tree, vuses, i, vuse); ++i)
{
- tree tmp = SSA_NAME_DEF_STMT (vuse);
+ gimple tmp = SSA_NAME_DEF_STMT (vuse);
if (tmp != def_stmt)
- return NULL_TREE;
+ return NULL;
}
/* Now see if the definition aliases ref, and loop until it does. */
cont:
while (def_stmt
- && TREE_CODE (def_stmt) == GIMPLE_MODIFY_STMT
- && !get_call_expr_in (def_stmt)
- && !refs_may_alias_p (ref, GIMPLE_STMT_OPERAND (def_stmt, 0)))
+ && is_gimple_assign (def_stmt)
+ && !refs_may_alias_p (ref, gimple_get_lhs (def_stmt)))
def_stmt = get_single_def_stmt_with_phi (ref, def_stmt);
return def_stmt;
@@ -733,10 +874,11 @@ cont:
/* Lookup a SCCVN reference operation VR in the current hash table.
Returns the resulting value number if it exists in the hash table,
- NULL_TREE otherwise. */
+ NULL_TREE otherwise. VNRESULT will be filled in with the actual
+ vn_reference_t stored in the hashtable if something is found. */
static tree
-vn_reference_lookup_1 (vn_reference_t vr)
+vn_reference_lookup_1 (vn_reference_t vr, vn_reference_t *vnresult)
{
void **slot;
hashval_t hash;
@@ -748,25 +890,59 @@ vn_reference_lookup_1 (vn_reference_t vr)
slot = htab_find_slot_with_hash (valid_info->references, vr,
hash, NO_INSERT);
if (slot)
- return ((vn_reference_t)*slot)->result;
-
+ {
+ if (vnresult)
+ *vnresult = (vn_reference_t)*slot;
+ return ((vn_reference_t)*slot)->result;
+ }
+
return NULL_TREE;
}
-/* Lookup OP in the current hash table, and return the resulting
- value number if it exists in the hash table. Return NULL_TREE if
- it does not exist in the hash table. */
+
+/* Lookup a reference operation by it's parts, in the current hash table.
+ Returns the resulting value number if it exists in the hash table,
+ NULL_TREE otherwise. VNRESULT will be filled in with the actual
+ vn_reference_t stored in the hashtable if something is found. */
tree
-vn_reference_lookup (tree op, VEC (tree, gc) *vuses, bool maywalk)
+vn_reference_lookup_pieces (VEC (tree, gc) *vuses,
+ VEC (vn_reference_op_s, heap) *operands,
+ vn_reference_t *vnresult)
{
struct vn_reference_s vr1;
- tree result, def_stmt;
+ tree result;
+ if (vnresult)
+ *vnresult = NULL;
+
+ vr1.vuses = valueize_vuses (vuses);
+ vr1.operands = valueize_refs (operands);
+ vr1.hashcode = vn_reference_compute_hash (&vr1);
+ result = vn_reference_lookup_1 (&vr1, vnresult);
+
+ return result;
+}
+
+/* Lookup OP in the current hash table, and return the resulting value
+ number if it exists in the hash table. Return NULL_TREE if it does
+ 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. */
+
+tree
+vn_reference_lookup (tree op, VEC (tree, gc) *vuses, bool maywalk,
+ vn_reference_t *vnresult)
+{
+ struct vn_reference_s vr1;
+ tree result;
+ gimple def_stmt;
+ if (vnresult)
+ *vnresult = NULL;
vr1.vuses = valueize_vuses (vuses);
vr1.operands = valueize_refs (shared_reference_ops_from_ref (op));
vr1.hashcode = vn_reference_compute_hash (&vr1);
- result = vn_reference_lookup_1 (&vr1);
+ result = vn_reference_lookup_1 (&vr1, vnresult);
/* If there is a single defining statement for all virtual uses, we can
use that, following virtual use-def chains. */
@@ -774,35 +950,35 @@ vn_reference_lookup (tree op, VEC (tree, gc) *vuses, bool maywalk)
&& maywalk
&& vr1.vuses
&& VEC_length (tree, vr1.vuses) >= 1
- && !get_call_expr_in (op)
&& (def_stmt = get_def_ref_stmt_vuses (op, vr1.vuses))
- && TREE_CODE (def_stmt) == GIMPLE_MODIFY_STMT
- /* If there is a call involved, op must be assumed to
- be clobbered. */
- && !get_call_expr_in (def_stmt))
+ && is_gimple_assign (def_stmt))
{
/* We are now at an aliasing definition for the vuses we want to
look up. Re-do the lookup with the vdefs for this stmt. */
vdefs_to_vec (def_stmt, &vuses);
vr1.vuses = valueize_vuses (vuses);
vr1.hashcode = vn_reference_compute_hash (&vr1);
- result = vn_reference_lookup_1 (&vr1);
+ result = vn_reference_lookup_1 (&vr1, vnresult);
}
return result;
}
+
/* Insert OP into the current hash table with a value number of
- RESULT. */
+ RESULT, and return the resulting reference structure we created. */
-void
+vn_reference_t
vn_reference_insert (tree op, tree result, VEC (tree, gc) *vuses)
{
void **slot;
vn_reference_t vr1;
vr1 = (vn_reference_t) pool_alloc (current_info->references_pool);
-
+ if (TREE_CODE (result) == SSA_NAME)
+ vr1->value_id = VN_INFO (result)->value_id;
+ else
+ vr1->value_id = get_or_alloc_constant_value_id (result);
vr1->vuses = valueize_vuses (vuses);
vr1->operands = valueize_refs (create_reference_ops_from_ref (op));
vr1->hashcode = vn_reference_compute_hash (vr1);
@@ -824,11 +1000,48 @@ vn_reference_insert (tree op, tree result, VEC (tree, gc) *vuses)
free_reference (*slot);
*slot = vr1;
+ return vr1;
+}
+
+/* Insert a reference by it's pieces into the current hash table with
+ a value number of RESULT. Return the resulting reference
+ structure we created. */
+
+vn_reference_t
+vn_reference_insert_pieces (VEC (tree, gc) *vuses,
+ VEC (vn_reference_op_s, heap) *operands,
+ tree result, unsigned int value_id)
+
+{
+ void **slot;
+ vn_reference_t vr1;
+
+ vr1 = (vn_reference_t) pool_alloc (current_info->references_pool);
+ vr1->value_id = value_id;
+ vr1->vuses = valueize_vuses (vuses);
+ vr1->operands = valueize_refs (operands);
+ vr1->hashcode = vn_reference_compute_hash (vr1);
+ if (result && TREE_CODE (result) == SSA_NAME)
+ result = SSA_VAL (result);
+ vr1->result = result;
+
+ slot = htab_find_slot_with_hash (current_info->references, vr1, vr1->hashcode,
+ INSERT);
+
+ /* At this point we should have all the things inserted that we have
+ seen before, and we should never try inserting something that
+ already exists. */
+ gcc_assert (!*slot);
+ if (*slot)
+ free_reference (*slot);
+
+ *slot = vr1;
+ return vr1;
}
/* Compute and return the hash value for nary operation VBO1. */
-static inline hashval_t
+inline hashval_t
vn_nary_op_compute_hash (const vn_nary_op_t vno1)
{
hashval_t hash = 0;
@@ -865,7 +1078,7 @@ vn_nary_op_hash (const void *p1)
/* Compare nary operations P1 and P2 and return true if they are
equivalent. */
-static int
+int
vn_nary_op_eq (const void *p1, const void *p2)
{
const_vn_nary_op_t const vno1 = (const_vn_nary_op_t) p1;
@@ -883,17 +1096,56 @@ vn_nary_op_eq (const void *p1, const void *p2)
return true;
}
-/* Lookup OP in the current hash table, and return the resulting
- value number if it exists in the hash table. Return NULL_TREE if
- it does not exist in the hash table. */
+/* Lookup a n-ary operation by its pieces and return the resulting value
+ number if it exists in the hash table. Return NULL_TREE if it does
+ not exist in the hash table or if the result field of the operation
+ is NULL. VNRESULT will contain the vn_nary_op_t from the hashtable
+ if it exists. */
tree
-vn_nary_op_lookup (tree op)
+vn_nary_op_lookup_pieces (unsigned int length, enum tree_code code,
+ tree type, tree op0, tree op1, tree op2,
+ tree op3, vn_nary_op_t *vnresult)
+{
+ void **slot;
+ struct vn_nary_op_s vno1;
+ if (vnresult)
+ *vnresult = NULL;
+ vno1.opcode = code;
+ vno1.length = length;
+ vno1.type = type;
+ vno1.op[0] = op0;
+ vno1.op[1] = op1;
+ vno1.op[2] = op2;
+ vno1.op[3] = op3;
+ vno1.hashcode = vn_nary_op_compute_hash (&vno1);
+ slot = htab_find_slot_with_hash (current_info->nary, &vno1, vno1.hashcode,
+ NO_INSERT);
+ if (!slot && current_info == optimistic_info)
+ slot = htab_find_slot_with_hash (valid_info->nary, &vno1, vno1.hashcode,
+ NO_INSERT);
+ if (!slot)
+ return NULL_TREE;
+ if (vnresult)
+ *vnresult = (vn_nary_op_t)*slot;
+ return ((vn_nary_op_t)*slot)->result;
+}
+
+/* Lookup OP in the current hash table, and return the resulting value
+ number if it exists in the hash table. Return NULL_TREE if it does
+ not exist in the hash table or if the result field of the operation
+ is NULL. VNRESULT will contain the vn_nary_op_t from the hashtable
+ if it exists. */
+
+tree
+vn_nary_op_lookup (tree op, vn_nary_op_t *vnresult)
{
void **slot;
struct vn_nary_op_s vno1;
unsigned i;
+ if (vnresult)
+ *vnresult = NULL;
vno1.opcode = TREE_CODE (op);
vno1.length = TREE_CODE_LENGTH (TREE_CODE (op));
vno1.type = TREE_TYPE (op);
@@ -907,13 +1159,88 @@ vn_nary_op_lookup (tree op)
NO_INSERT);
if (!slot)
return NULL_TREE;
+ if (vnresult)
+ *vnresult = (vn_nary_op_t)*slot;
return ((vn_nary_op_t)*slot)->result;
}
+/* Lookup the rhs of STMT in the current hash table, and return the resulting
+ value number if it exists in the hash table. Return NULL_TREE if
+ it does not exist in the hash table. VNRESULT will contain the
+ vn_nary_op_t from the hashtable if it exists. */
+
+tree
+vn_nary_op_lookup_stmt (gimple stmt, vn_nary_op_t *vnresult)
+{
+ void **slot;
+ struct vn_nary_op_s vno1;
+ unsigned i;
+
+ if (vnresult)
+ *vnresult = NULL;
+ vno1.opcode = gimple_assign_rhs_code (stmt);
+ vno1.length = gimple_num_ops (stmt) - 1;
+ vno1.type = TREE_TYPE (gimple_assign_lhs (stmt));
+ for (i = 0; i < vno1.length; ++i)
+ vno1.op[i] = gimple_op (stmt, i + 1);
+ vno1.hashcode = vn_nary_op_compute_hash (&vno1);
+ slot = htab_find_slot_with_hash (current_info->nary, &vno1, vno1.hashcode,
+ NO_INSERT);
+ if (!slot && current_info == optimistic_info)
+ slot = htab_find_slot_with_hash (valid_info->nary, &vno1, vno1.hashcode,
+ NO_INSERT);
+ if (!slot)
+ return NULL_TREE;
+ if (vnresult)
+ *vnresult = (vn_nary_op_t)*slot;
+ return ((vn_nary_op_t)*slot)->result;
+}
+
+/* Insert a n-ary operation into the current hash table using it's
+ pieces. Return the vn_nary_op_t structure we created and put in
+ the hashtable. */
+
+vn_nary_op_t
+vn_nary_op_insert_pieces (unsigned int length, enum tree_code code,
+ tree type, tree op0,
+ tree op1, tree op2, tree op3,
+ tree result,
+ unsigned int value_id)
+{
+ void **slot;
+ vn_nary_op_t vno1;
+
+ vno1 = (vn_nary_op_t) obstack_alloc (&current_info->nary_obstack,
+ (sizeof (struct vn_nary_op_s)
+ - sizeof (tree) * (4 - length)));
+ vno1->value_id = value_id;
+ vno1->opcode = code;
+ vno1->length = length;
+ vno1->type = type;
+ if (length >= 1)
+ vno1->op[0] = op0;
+ if (length >= 2)
+ vno1->op[1] = op1;
+ if (length >= 3)
+ vno1->op[2] = op2;
+ if (length >= 4)
+ vno1->op[3] = op3;
+ vno1->result = result;
+ vno1->hashcode = vn_nary_op_compute_hash (vno1);
+ slot = htab_find_slot_with_hash (current_info->nary, vno1, vno1->hashcode,
+ INSERT);
+ gcc_assert (!*slot);
+
+ *slot = vno1;
+ return vno1;
+
+}
+
/* Insert OP into the current hash table with a value number of
- RESULT. */
+ RESULT. Return the vn_nary_op_t structure we created and put in
+ the hashtable. */
-void
+vn_nary_op_t
vn_nary_op_insert (tree op, tree result)
{
unsigned length = TREE_CODE_LENGTH (TREE_CODE (op));
@@ -924,6 +1251,7 @@ vn_nary_op_insert (tree op, tree result)
vno1 = (vn_nary_op_t) obstack_alloc (&current_info->nary_obstack,
(sizeof (struct vn_nary_op_s)
- sizeof (tree) * (4 - length)));
+ vno1->value_id = VN_INFO (result)->value_id;
vno1->opcode = TREE_CODE (op);
vno1->length = length;
vno1->type = TREE_TYPE (op);
@@ -936,6 +1264,37 @@ vn_nary_op_insert (tree op, tree result)
gcc_assert (!*slot);
*slot = vno1;
+ return vno1;
+}
+
+/* Insert the rhs of STMT into the current hash table with a value number of
+ RESULT. */
+
+vn_nary_op_t
+vn_nary_op_insert_stmt (gimple stmt, tree result)
+{
+ unsigned length = gimple_num_ops (stmt) - 1;
+ void **slot;
+ vn_nary_op_t vno1;
+ unsigned i;
+
+ vno1 = (vn_nary_op_t) obstack_alloc (&current_info->nary_obstack,
+ (sizeof (struct vn_nary_op_s)
+ - sizeof (tree) * (4 - length)));
+ vno1->value_id = VN_INFO (result)->value_id;
+ vno1->opcode = gimple_assign_rhs_code (stmt);
+ vno1->length = length;
+ vno1->type = TREE_TYPE (gimple_assign_lhs (stmt));
+ for (i = 0; i < vno1->length; ++i)
+ vno1->op[i] = gimple_op (stmt, i + 1);
+ vno1->result = result;
+ vno1->hashcode = vn_nary_op_compute_hash (vno1);
+ slot = htab_find_slot_with_hash (current_info->nary, vno1, vno1->hashcode,
+ INSERT);
+ gcc_assert (!*slot);
+
+ *slot = vno1;
+ return vno1;
}
/* Compute a hashcode for PHI operation VP1 and return it. */
@@ -1003,23 +1362,23 @@ static VEC(tree, heap) *shared_lookup_phiargs;
it does not exist in the hash table. */
static tree
-vn_phi_lookup (tree phi)
+vn_phi_lookup (gimple phi)
{
void **slot;
struct vn_phi_s vp1;
- int i;
+ unsigned i;
VEC_truncate (tree, shared_lookup_phiargs, 0);
/* Canonicalize the SSA_NAME's to their value number. */
- for (i = 0; i < PHI_NUM_ARGS (phi); i++)
+ for (i = 0; i < gimple_phi_num_args (phi); i++)
{
tree def = PHI_ARG_DEF (phi, i);
def = TREE_CODE (def) == SSA_NAME ? SSA_VAL (def) : def;
VEC_safe_push (tree, heap, shared_lookup_phiargs, def);
}
vp1.phiargs = shared_lookup_phiargs;
- vp1.block = bb_for_stmt (phi);
+ vp1.block = gimple_bb (phi);
vp1.hashcode = vn_phi_compute_hash (&vp1);
slot = htab_find_slot_with_hash (current_info->phis, &vp1, vp1.hashcode,
NO_INSERT);
@@ -1034,23 +1393,24 @@ vn_phi_lookup (tree phi)
/* Insert PHI into the current hash table with a value number of
RESULT. */
-static void
-vn_phi_insert (tree phi, tree result)
+static vn_phi_t
+vn_phi_insert (gimple phi, tree result)
{
void **slot;
vn_phi_t vp1 = (vn_phi_t) pool_alloc (current_info->phis_pool);
- int i;
+ unsigned i;
VEC (tree, heap) *args = NULL;
/* Canonicalize the SSA_NAME's to their value number. */
- for (i = 0; i < PHI_NUM_ARGS (phi); i++)
+ for (i = 0; i < gimple_phi_num_args (phi); i++)
{
tree def = PHI_ARG_DEF (phi, i);
def = TREE_CODE (def) == SSA_NAME ? SSA_VAL (def) : def;
VEC_safe_push (tree, heap, args, def);
}
+ vp1->value_id = VN_INFO (result)->value_id;
vp1->phiargs = args;
- vp1->block = bb_for_stmt (phi);
+ vp1->block = gimple_bb (phi);
vp1->result = result;
vp1->hashcode = vn_phi_compute_hash (vp1);
@@ -1060,6 +1420,7 @@ vn_phi_insert (tree phi, tree result)
/* Because we iterate over phi operations more than once, it's
possible the slot might already exist here, hence no assert.*/
*slot = vp1;
+ return vp1;
}
@@ -1123,7 +1484,7 @@ set_ssa_val_to (tree from, tree to)
Return true if a value number changed. */
static bool
-defs_to_varying (tree stmt)
+defs_to_varying (gimple stmt)
{
bool changed = false;
ssa_op_iter iter;
@@ -1140,7 +1501,7 @@ defs_to_varying (tree stmt)
}
static bool expr_has_constants (tree expr);
-static tree try_to_simplify (tree stmt, tree rhs);
+static tree try_to_simplify (gimple stmt);
/* Visit a copy between LHS and RHS, return true if the value number
changed. */
@@ -1148,7 +1509,6 @@ static tree try_to_simplify (tree stmt, tree rhs);
static bool
visit_copy (tree lhs, tree rhs)
{
-
/* Follow chains of copies to their destination. */
while (SSA_VAL (rhs) != rhs && TREE_CODE (SSA_VAL (rhs)) == SSA_NAME)
rhs = SSA_VAL (rhs);
@@ -1165,10 +1525,10 @@ visit_copy (tree lhs, tree rhs)
value number of LHS has changed as a result. */
static bool
-visit_unary_op (tree lhs, tree op)
+visit_unary_op (tree lhs, gimple stmt)
{
bool changed = false;
- tree result = vn_nary_op_lookup (op);
+ tree result = vn_nary_op_lookup_stmt (stmt, NULL);
if (result)
{
@@ -1177,7 +1537,7 @@ visit_unary_op (tree lhs, tree op)
else
{
changed = set_ssa_val_to (lhs, lhs);
- vn_nary_op_insert (op, lhs);
+ vn_nary_op_insert_stmt (stmt, lhs);
}
return changed;
@@ -1187,19 +1547,60 @@ visit_unary_op (tree lhs, tree op)
value number of LHS has changed as a result. */
static bool
-visit_binary_op (tree lhs, tree op)
+visit_binary_op (tree lhs, gimple stmt)
+{
+ bool changed = false;
+ tree result = vn_nary_op_lookup_stmt (stmt, NULL);
+
+ if (result)
+ {
+ changed = set_ssa_val_to (lhs, result);
+ }
+ else
+ {
+ changed = set_ssa_val_to (lhs, lhs);
+ vn_nary_op_insert_stmt (stmt, lhs);
+ }
+
+ return changed;
+}
+
+/* Visit a call STMT storing into LHS. Return true if the value number
+ of the LHS has changed as a result. */
+
+static bool
+visit_reference_op_call (tree lhs, gimple stmt)
{
bool changed = false;
- tree result = vn_nary_op_lookup (op);
+ struct vn_reference_s vr1;
+ tree result;
+ vr1.vuses = valueize_vuses (shared_vuses_from_stmt (stmt));
+ vr1.operands = valueize_refs (shared_reference_ops_from_call (stmt));
+ vr1.hashcode = vn_reference_compute_hash (&vr1);
+ result = vn_reference_lookup_1 (&vr1, NULL);
if (result)
{
changed = set_ssa_val_to (lhs, result);
+ if (TREE_CODE (result) == SSA_NAME
+ && VN_INFO (result)->has_constants)
+ VN_INFO (lhs)->has_constants = true;
}
else
{
+ void **slot;
+ vn_reference_t vr2;
changed = set_ssa_val_to (lhs, lhs);
- vn_nary_op_insert (op, lhs);
+ vr2 = (vn_reference_t) pool_alloc (current_info->references_pool);
+ vr2->vuses = valueize_vuses (copy_vuses_from_stmt (stmt));
+ vr2->operands = valueize_refs (create_reference_ops_from_call (stmt));
+ vr2->hashcode = vr1.hashcode;
+ vr2->result = lhs;
+ slot = htab_find_slot_with_hash (current_info->references,
+ vr2, vr2->hashcode, INSERT);
+ if (*slot)
+ free_reference (*slot);
+ *slot = vr2;
}
return changed;
@@ -1209,10 +1610,11 @@ visit_binary_op (tree lhs, tree op)
and return true if the value number of the LHS has changed as a result. */
static bool
-visit_reference_op_load (tree lhs, tree op, tree stmt)
+visit_reference_op_load (tree lhs, tree op, gimple stmt)
{
bool changed = false;
- tree result = vn_reference_lookup (op, shared_vuses_from_stmt (stmt), true);
+ tree result = vn_reference_lookup (op, shared_vuses_from_stmt (stmt), true,
+ NULL);
/* We handle type-punning through unions by value-numbering based
on offset and size of the access. Be prepared to handle a
@@ -1229,21 +1631,22 @@ visit_reference_op_load (tree lhs, tree op, tree stmt)
&& !is_gimple_min_invariant (val)
&& TREE_CODE (val) != SSA_NAME)
{
- tree tem = try_to_simplify (stmt, val);
+ tree tem = try_to_simplify (stmt);
if (tem)
val = tem;
}
result = val;
if (!is_gimple_min_invariant (val)
&& TREE_CODE (val) != SSA_NAME)
- result = vn_nary_op_lookup (val);
+ result = vn_nary_op_lookup (val, NULL);
/* If the expression is not yet available, value-number lhs to
a new SSA_NAME we create. */
if (!result && may_insert)
{
- result = make_ssa_name (SSA_NAME_VAR (lhs), NULL_TREE);
+ result = make_ssa_name (SSA_NAME_VAR (lhs), NULL);
/* Initialize value-number information properly. */
VN_INFO_GET (result)->valnum = result;
+ VN_INFO (result)->value_id = get_next_value_id ();
VN_INFO (result)->expr = val;
VN_INFO (result)->has_constants = expr_has_constants (val);
VN_INFO (result)->needs_insertion = true;
@@ -1297,7 +1700,7 @@ visit_reference_op_load (tree lhs, tree op, tree stmt)
and return true if the value number of the LHS has changed as a result. */
static bool
-visit_reference_op_store (tree lhs, tree op, tree stmt)
+visit_reference_op_store (tree lhs, tree op, gimple stmt)
{
bool changed = false;
tree result;
@@ -1319,7 +1722,8 @@ visit_reference_op_store (tree lhs, tree op, tree stmt)
Otherwise, the vdefs for the store are used when inserting into
the table, since the store generates a new memory state. */
- result = vn_reference_lookup (lhs, shared_vuses_from_stmt (stmt), false);
+ result = vn_reference_lookup (lhs, shared_vuses_from_stmt (stmt), false,
+ NULL);
if (result)
{
@@ -1395,13 +1799,13 @@ visit_reference_op_store (tree lhs, tree op, tree stmt)
changed. */
static bool
-visit_phi (tree phi)
+visit_phi (gimple phi)
{
bool changed = false;
tree result;
tree sameval = VN_TOP;
bool allsame = true;
- int i;
+ unsigned i;
/* TODO: We could check for this in init_sccvn, and replace this
with a gcc_assert. */
@@ -1410,7 +1814,7 @@ visit_phi (tree phi)
/* See if all non-TOP arguments have the same value. TOP is
equivalent to everything, so we can ignore it. */
- for (i = 0; i < PHI_NUM_ARGS (phi); i++)
+ for (i = 0; i < gimple_phi_num_args (phi); i++)
{
tree def = PHI_ARG_DEF (phi, i);
@@ -1497,6 +1901,32 @@ expr_has_constants (tree expr)
return false;
}
+/* Return true if STMT contains constants. */
+
+static bool
+stmt_has_constants (gimple stmt)
+{
+ if (gimple_code (stmt) != GIMPLE_ASSIGN)
+ return false;
+
+ switch (get_gimple_rhs_class (gimple_assign_rhs_code (stmt)))
+ {
+ case GIMPLE_UNARY_RHS:
+ return is_gimple_min_invariant (gimple_assign_rhs1 (stmt));
+
+ case GIMPLE_BINARY_RHS:
+ return (is_gimple_min_invariant (gimple_assign_rhs1 (stmt))
+ || is_gimple_min_invariant (gimple_assign_rhs2 (stmt)));
+ case GIMPLE_SINGLE_RHS:
+ /* Constants inside reference ops are rarely interesting, but
+ it can take a lot of looking to find them. */
+ return is_gimple_min_invariant (gimple_assign_rhs1 (stmt));
+ default:
+ gcc_unreachable ();
+ }
+ return false;
+}
+
/* Replace SSA_NAMES in expr with their value numbers, and return the
result.
This is performed in place. */
@@ -1529,11 +1959,11 @@ valueize_expr (tree expr)
simplified. */
static tree
-simplify_binary_expression (tree stmt, tree rhs)
+simplify_binary_expression (gimple stmt)
{
tree result = NULL_TREE;
- tree op0 = TREE_OPERAND (rhs, 0);
- tree op1 = TREE_OPERAND (rhs, 1);
+ tree op0 = gimple_assign_rhs1 (stmt);
+ tree op1 = gimple_assign_rhs2 (stmt);
/* This will not catch every single case we could combine, but will
catch those with constants. The goal here is to simultaneously
@@ -1541,8 +1971,9 @@ simplify_binary_expression (tree stmt, tree rhs)
expansion of expressions during simplification. */
if (TREE_CODE (op0) == SSA_NAME)
{
- if (VN_INFO (op0)->has_constants)
- op0 = valueize_expr (VN_INFO (op0)->expr);
+ if (VN_INFO (op0)->has_constants
+ || TREE_CODE_CLASS (gimple_assign_rhs_code (stmt)) == tcc_comparison)
+ op0 = valueize_expr (vn_get_expr_for (op0));
else if (SSA_VAL (op0) != VN_TOP && SSA_VAL (op0) != op0)
op0 = SSA_VAL (op0);
}
@@ -1550,28 +1981,29 @@ simplify_binary_expression (tree stmt, tree rhs)
if (TREE_CODE (op1) == SSA_NAME)
{
if (VN_INFO (op1)->has_constants)
- op1 = valueize_expr (VN_INFO (op1)->expr);
+ op1 = valueize_expr (vn_get_expr_for (op1));
else if (SSA_VAL (op1) != VN_TOP && SSA_VAL (op1) != op1)
op1 = SSA_VAL (op1);
}
/* Avoid folding if nothing changed. */
- if (op0 == TREE_OPERAND (rhs, 0)
- && op1 == TREE_OPERAND (rhs, 1))
+ if (op0 == gimple_assign_rhs1 (stmt)
+ && op1 == gimple_assign_rhs2 (stmt))
return NULL_TREE;
fold_defer_overflow_warnings ();
- result = fold_binary (TREE_CODE (rhs), TREE_TYPE (rhs), op0, op1);
+ result = fold_binary (gimple_assign_rhs_code (stmt),
+ TREE_TYPE (gimple_get_lhs (stmt)), op0, op1);
- fold_undefer_overflow_warnings (result && valid_gimple_expression_p (result),
+ fold_undefer_overflow_warnings (result && valid_gimple_rhs_p (result),
stmt, 0);
/* Make sure result is not a complex expression consisting
of operators of operators (IE (a + b) + (a + c))
Otherwise, we will end up with unbounded expressions if
fold does anything at all. */
- if (result && valid_gimple_expression_p (result))
+ if (result && valid_gimple_rhs_p (result))
return result;
return NULL_TREE;
@@ -1581,24 +2013,32 @@ simplify_binary_expression (tree stmt, tree rhs)
simplified. */
static tree
-simplify_unary_expression (tree rhs)
+simplify_unary_expression (gimple stmt)
{
tree result = NULL_TREE;
- tree op0 = TREE_OPERAND (rhs, 0);
+ tree orig_op0, op0 = gimple_assign_rhs1 (stmt);
+
+ /* We handle some tcc_reference codes here that are all
+ GIMPLE_ASSIGN_SINGLE codes. */
+ if (gimple_assign_rhs_code (stmt) == REALPART_EXPR
+ || gimple_assign_rhs_code (stmt) == IMAGPART_EXPR
+ || gimple_assign_rhs_code (stmt) == VIEW_CONVERT_EXPR)
+ op0 = TREE_OPERAND (op0, 0);
if (TREE_CODE (op0) != SSA_NAME)
return NULL_TREE;
+ orig_op0 = op0;
if (VN_INFO (op0)->has_constants)
- op0 = valueize_expr (VN_INFO (op0)->expr);
- else if (CONVERT_EXPR_P (rhs)
- || TREE_CODE (rhs) == REALPART_EXPR
- || TREE_CODE (rhs) == IMAGPART_EXPR
- || TREE_CODE (rhs) == VIEW_CONVERT_EXPR)
+ op0 = valueize_expr (vn_get_expr_for (op0));
+ else if (gimple_assign_cast_p (stmt)
+ || gimple_assign_rhs_code (stmt) == REALPART_EXPR
+ || gimple_assign_rhs_code (stmt) == IMAGPART_EXPR
+ || gimple_assign_rhs_code (stmt) == VIEW_CONVERT_EXPR)
{
/* We want to do tree-combining on conversion-like expressions.
Make sure we feed only SSA_NAMEs or constants to fold though. */
- tree tem = valueize_expr (VN_INFO (op0)->expr);
+ tree tem = valueize_expr (vn_get_expr_for (op0));
if (UNARY_CLASS_P (tem)
|| BINARY_CLASS_P (tem)
|| TREE_CODE (tem) == VIEW_CONVERT_EXPR
@@ -1608,36 +2048,38 @@ simplify_unary_expression (tree rhs)
}
/* Avoid folding if nothing changed, but remember the expression. */
- if (op0 == TREE_OPERAND (rhs, 0))
- return rhs;
+ if (op0 == orig_op0)
+ return NULL_TREE;
- result = fold_unary (TREE_CODE (rhs), TREE_TYPE (rhs), op0);
+ result = fold_unary (gimple_assign_rhs_code (stmt),
+ gimple_expr_type (stmt), op0);
if (result)
{
STRIP_USELESS_TYPE_CONVERSION (result);
- if (valid_gimple_expression_p (result))
+ if (valid_gimple_rhs_p (result))
return result;
}
- return rhs;
+ return NULL_TREE;
}
/* Try to simplify RHS using equivalences and constant folding. */
static tree
-try_to_simplify (tree stmt, tree rhs)
+try_to_simplify (gimple stmt)
{
tree tem;
/* For stores we can end up simplifying a SSA_NAME rhs. Just return
in this case, there is no point in doing extra work. */
- if (TREE_CODE (rhs) == SSA_NAME)
- return rhs;
+ if (gimple_assign_copy_p (stmt)
+ && TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME)
+ return NULL_TREE;
- switch (TREE_CODE_CLASS (TREE_CODE (rhs)))
+ switch (TREE_CODE_CLASS (gimple_assign_rhs_code (stmt)))
{
case tcc_declaration:
- tem = get_symbol_constant_value (rhs);
+ tem = get_symbol_constant_value (gimple_assign_rhs1 (stmt));
if (tem)
return tem;
break;
@@ -1645,29 +2087,29 @@ try_to_simplify (tree stmt, tree rhs)
case tcc_reference:
/* Do not do full-blown reference lookup here, but simplify
reads from constant aggregates. */
- tem = fold_const_aggregate_ref (rhs);
+ tem = fold_const_aggregate_ref (gimple_assign_rhs1 (stmt));
if (tem)
return tem;
/* Fallthrough for some codes that can operate on registers. */
- if (!(TREE_CODE (rhs) == REALPART_EXPR
- || TREE_CODE (rhs) == IMAGPART_EXPR
- || TREE_CODE (rhs) == VIEW_CONVERT_EXPR))
+ if (!(TREE_CODE (gimple_assign_rhs1 (stmt)) == REALPART_EXPR
+ || TREE_CODE (gimple_assign_rhs1 (stmt)) == IMAGPART_EXPR
+ || TREE_CODE (gimple_assign_rhs1 (stmt)) == VIEW_CONVERT_EXPR))
break;
/* We could do a little more with unary ops, if they expand
into binary ops, but it's debatable whether it is worth it. */
case tcc_unary:
- return simplify_unary_expression (rhs);
+ return simplify_unary_expression (stmt);
break;
case tcc_comparison:
case tcc_binary:
- return simplify_binary_expression (stmt, rhs);
+ return simplify_binary_expression (stmt);
break;
default:
break;
}
- return rhs;
+ return NULL_TREE;
}
/* Visit and value number USE, return true if the value number
@@ -1677,67 +2119,52 @@ static bool
visit_use (tree use)
{
bool changed = false;
- tree stmt = SSA_NAME_DEF_STMT (use);
- stmt_ann_t ann;
+ gimple stmt = SSA_NAME_DEF_STMT (use);
VN_INFO (use)->use_processed = true;
gcc_assert (!SSA_NAME_IN_FREE_LIST (use));
if (dump_file && (dump_flags & TDF_DETAILS)
- && !IS_EMPTY_STMT (stmt))
+ && !SSA_NAME_IS_DEFAULT_DEF (use))
{
fprintf (dump_file, "Value numbering ");
print_generic_expr (dump_file, use, 0);
fprintf (dump_file, " stmt = ");
- print_generic_stmt (dump_file, stmt, 0);
+ print_gimple_stmt (dump_file, stmt, 0, 0);
}
- /* RETURN_EXPR may have an embedded MODIFY_STMT. */
- if (TREE_CODE (stmt) == RETURN_EXPR
- && TREE_CODE (TREE_OPERAND (stmt, 0)) == GIMPLE_MODIFY_STMT)
- stmt = TREE_OPERAND (stmt, 0);
-
- ann = stmt_ann (stmt);
-
/* Handle uninitialized uses. */
- if (IS_EMPTY_STMT (stmt))
- {
- changed = set_ssa_val_to (use, use);
- }
+ if (SSA_NAME_IS_DEFAULT_DEF (use))
+ changed = set_ssa_val_to (use, use);
else
{
- if (TREE_CODE (stmt) == PHI_NODE)
+ if (gimple_code (stmt) == GIMPLE_PHI)
+ changed = visit_phi (stmt);
+ else if (!gimple_has_lhs (stmt)
+ || gimple_has_volatile_ops (stmt)
+ || stmt_could_throw_p (stmt))
+ changed = defs_to_varying (stmt);
+ else if (is_gimple_assign (stmt))
{
- changed = visit_phi (stmt);
- }
- else if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT
- || (ann && ann->has_volatile_ops)
- || tree_could_throw_p (stmt))
- {
- changed = defs_to_varying (stmt);
- }
- else
- {
- tree lhs = GIMPLE_STMT_OPERAND (stmt, 0);
- tree rhs = GIMPLE_STMT_OPERAND (stmt, 1);
+ tree lhs = gimple_assign_lhs (stmt);
tree simplified;
- STRIP_USELESS_TYPE_CONVERSION (rhs);
-
/* Shortcut for copies. Simplifying copies is pointless,
since we copy the expression and value they represent. */
- if (TREE_CODE (rhs) == SSA_NAME && TREE_CODE (lhs) == SSA_NAME)
+ if (gimple_assign_copy_p (stmt)
+ && TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME
+ && TREE_CODE (lhs) == SSA_NAME)
{
- changed = visit_copy (lhs, rhs);
+ changed = visit_copy (lhs, gimple_assign_rhs1 (stmt));
goto done;
}
- simplified = try_to_simplify (stmt, rhs);
- if (simplified && simplified != rhs)
+ simplified = try_to_simplify (stmt);
+ if (simplified)
{
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "RHS ");
- print_generic_expr (dump_file, rhs, 0);
+ print_gimple_expr (dump_file, stmt, 0, 0);
fprintf (dump_file, " simplified to ");
print_generic_expr (dump_file, simplified, 0);
if (TREE_CODE (lhs) == SSA_NAME)
@@ -1751,16 +2178,17 @@ visit_use (tree use)
screw up phi congruence because constants are not
uniquely associated with a single ssa name that can be
looked up. */
- if (simplified && is_gimple_min_invariant (simplified)
- && TREE_CODE (lhs) == SSA_NAME
- && simplified != rhs)
+ if (simplified
+ && is_gimple_min_invariant (simplified)
+ && TREE_CODE (lhs) == SSA_NAME)
{
VN_INFO (lhs)->expr = simplified;
VN_INFO (lhs)->has_constants = true;
changed = set_ssa_val_to (lhs, simplified);
goto done;
}
- else if (simplified && TREE_CODE (simplified) == SSA_NAME
+ else if (simplified
+ && TREE_CODE (simplified) == SSA_NAME
&& TREE_CODE (lhs) == SSA_NAME)
{
changed = visit_copy (lhs, simplified);
@@ -1775,13 +2203,10 @@ visit_use (tree use)
valuizing may change the IL stream. */
VN_INFO (lhs)->expr = unshare_expr (simplified);
}
- rhs = simplified;
- }
- else if (expr_has_constants (rhs) && TREE_CODE (lhs) == SSA_NAME)
- {
- VN_INFO (lhs)->has_constants = true;
- VN_INFO (lhs)->expr = unshare_expr (rhs);
}
+ else if (stmt_has_constants (stmt)
+ && TREE_CODE (lhs) == SSA_NAME)
+ VN_INFO (lhs)->has_constants = true;
else if (TREE_CODE (lhs) == SSA_NAME)
{
/* We reset expr and constantness here because we may
@@ -1790,56 +2215,64 @@ visit_use (tree use)
even if they were optimistically constant. */
VN_INFO (lhs)->has_constants = false;
- VN_INFO (lhs)->expr = lhs;
+ VN_INFO (lhs)->expr = NULL_TREE;
}
if (TREE_CODE (lhs) == SSA_NAME
/* We can substitute SSA_NAMEs that are live over
abnormal edges with their constant value. */
- && !is_gimple_min_invariant (rhs)
+ && !(gimple_assign_copy_p (stmt)
+ && is_gimple_min_invariant (gimple_assign_rhs1 (stmt)))
+ && !(simplified
+ && is_gimple_min_invariant (simplified))
&& SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs))
changed = defs_to_varying (stmt);
else if (REFERENCE_CLASS_P (lhs) || DECL_P (lhs))
{
- changed = visit_reference_op_store (lhs, rhs, stmt);
+ changed = visit_reference_op_store (lhs, gimple_assign_rhs1 (stmt), stmt);
}
else if (TREE_CODE (lhs) == SSA_NAME)
{
- if (is_gimple_min_invariant (rhs))
+ if ((gimple_assign_copy_p (stmt)
+ && is_gimple_min_invariant (gimple_assign_rhs1 (stmt)))
+ || (simplified
+ && is_gimple_min_invariant (simplified)))
{
VN_INFO (lhs)->has_constants = true;
- VN_INFO (lhs)->expr = rhs;
- changed = set_ssa_val_to (lhs, rhs);
+ if (simplified)
+ changed = set_ssa_val_to (lhs, simplified);
+ else
+ changed = set_ssa_val_to (lhs, gimple_assign_rhs1 (stmt));
}
else
{
- switch (TREE_CODE_CLASS (TREE_CODE (rhs)))
+ switch (get_gimple_rhs_class (gimple_assign_rhs_code (stmt)))
{
- case tcc_unary:
- changed = visit_unary_op (lhs, rhs);
- break;
- case tcc_binary:
- changed = visit_binary_op (lhs, rhs);
+ case GIMPLE_UNARY_RHS:
+ changed = visit_unary_op (lhs, stmt);
break;
- /* If tcc_vl_expr ever encompasses more than
- CALL_EXPR, this will need to be changed. */
- case tcc_vl_exp:
- if (call_expr_flags (rhs) & (ECF_PURE | ECF_CONST))
- changed = visit_reference_op_load (lhs, rhs, stmt);
- else
- changed = defs_to_varying (stmt);
+ case GIMPLE_BINARY_RHS:
+ changed = visit_binary_op (lhs, stmt);
break;
- case tcc_declaration:
- case tcc_reference:
- changed = visit_reference_op_load (lhs, rhs, stmt);
- break;
- case tcc_expression:
- if (TREE_CODE (rhs) == ADDR_EXPR)
+ case GIMPLE_SINGLE_RHS:
+ switch (TREE_CODE_CLASS (gimple_assign_rhs_code (stmt)))
{
- changed = visit_unary_op (lhs, rhs);
- goto done;
+ case tcc_declaration:
+ case tcc_reference:
+ changed = visit_reference_op_load
+ (lhs, gimple_assign_rhs1 (stmt), stmt);
+ break;
+ case tcc_expression:
+ if (gimple_assign_rhs_code (stmt) == ADDR_EXPR)
+ {
+ changed = visit_unary_op (lhs, stmt);
+ break;
+ }
+ /* Fallthrough. */
+ default:
+ changed = defs_to_varying (stmt);
}
- /* Fallthrough. */
+ break;
default:
changed = defs_to_varying (stmt);
break;
@@ -1849,6 +2282,39 @@ visit_use (tree use)
else
changed = defs_to_varying (stmt);
}
+ else if (is_gimple_call (stmt))
+ {
+ tree lhs = gimple_call_lhs (stmt);
+
+ /* ??? We could try to simplify calls. */
+
+ if (stmt_has_constants (stmt)
+ && TREE_CODE (lhs) == SSA_NAME)
+ VN_INFO (lhs)->has_constants = true;
+ else if (TREE_CODE (lhs) == SSA_NAME)
+ {
+ /* We reset expr and constantness here because we may
+ have been value numbering optimistically, and
+ iterating. They may become non-constant in this case,
+ even if they were optimistically constant. */
+ VN_INFO (lhs)->has_constants = false;
+ VN_INFO (lhs)->expr = NULL_TREE;
+ }
+
+ if (TREE_CODE (lhs) == SSA_NAME
+ && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs))
+ changed = defs_to_varying (stmt);
+ /* ??? We should handle stores from calls. */
+ else if (TREE_CODE (lhs) == SSA_NAME)
+ {
+ if (gimple_call_flags (stmt) & (ECF_PURE | ECF_CONST))
+ changed = visit_reference_op_call (lhs, stmt);
+ else
+ changed = defs_to_varying (stmt);
+ }
+ else
+ changed = defs_to_varying (stmt);
+ }
}
done:
return changed;
@@ -1861,20 +2327,20 @@ compare_ops (const void *pa, const void *pb)
{
const tree opa = *((const tree *)pa);
const tree opb = *((const tree *)pb);
- tree opstmta = SSA_NAME_DEF_STMT (opa);
- tree opstmtb = SSA_NAME_DEF_STMT (opb);
+ gimple opstmta = SSA_NAME_DEF_STMT (opa);
+ gimple opstmtb = SSA_NAME_DEF_STMT (opb);
basic_block bba;
basic_block bbb;
- if (IS_EMPTY_STMT (opstmta) && IS_EMPTY_STMT (opstmtb))
+ if (gimple_nop_p (opstmta) && gimple_nop_p (opstmtb))
return 0;
- else if (IS_EMPTY_STMT (opstmta))
+ else if (gimple_nop_p (opstmta))
return -1;
- else if (IS_EMPTY_STMT (opstmtb))
+ else if (gimple_nop_p (opstmtb))
return 1;
- bba = bb_for_stmt (opstmta);
- bbb = bb_for_stmt (opstmtb);
+ bba = gimple_bb (opstmta);
+ bbb = gimple_bb (opstmtb);
if (!bba && !bbb)
return 0;
@@ -1885,13 +2351,14 @@ compare_ops (const void *pa, const void *pb)
if (bba == bbb)
{
- if (TREE_CODE (opstmta) == PHI_NODE && TREE_CODE (opstmtb) == PHI_NODE)
+ if (gimple_code (opstmta) == GIMPLE_PHI
+ && gimple_code (opstmtb) == GIMPLE_PHI)
return 0;
- else if (TREE_CODE (opstmta) == PHI_NODE)
+ else if (gimple_code (opstmta) == GIMPLE_PHI)
return -1;
- else if (TREE_CODE (opstmtb) == PHI_NODE)
+ else if (gimple_code (opstmtb) == GIMPLE_PHI)
return 1;
- return gimple_stmt_uid (opstmta) - gimple_stmt_uid (opstmtb);
+ return gimple_uid (opstmta) - gimple_uid (opstmtb);
}
return rpo_numbers[bba->index] - rpo_numbers[bbb->index];
}
@@ -1937,6 +2404,9 @@ process_scc (VEC (tree, heap) *scc)
{
changed = false;
iterations++;
+ /* As we are value-numbering optimistically we have to
+ clear the expression tables and the simplified expressions
+ in each iteration until we converge. */
htab_empty (optimistic_info->nary);
htab_empty (optimistic_info->phis);
htab_empty (optimistic_info->references);
@@ -1945,6 +2415,8 @@ process_scc (VEC (tree, heap) *scc)
empty_alloc_pool (optimistic_info->phis_pool);
empty_alloc_pool (optimistic_info->references_pool);
for (i = 0; VEC_iterate (tree, scc, i, var); i++)
+ VN_INFO (var)->expr = NULL_TREE;
+ for (i = 0; VEC_iterate (tree, scc, i, var); i++)
changed |= visit_use (var);
}
@@ -2017,7 +2489,8 @@ DFS (tree name)
VEC(ssa_op_iter, heap) *itervec = NULL;
VEC(tree, heap) *namevec = NULL;
use_operand_p usep = NULL;
- tree defstmt, use;
+ gimple defstmt;
+ tree use;
ssa_op_iter iter;
start_over:
@@ -2031,10 +2504,10 @@ start_over:
defstmt = SSA_NAME_DEF_STMT (name);
/* Recursively DFS on our operands, looking for SCC's. */
- if (!IS_EMPTY_STMT (defstmt))
+ if (!gimple_nop_p (defstmt))
{
/* Push a new iterator. */
- if (TREE_CODE (defstmt) == PHI_NODE)
+ if (gimple_code (defstmt) == GIMPLE_PHI)
usep = op_iter_init_phiuse (&iter, defstmt, SSA_OP_ALL_USES);
else
usep = op_iter_init_use (&iter, defstmt, SSA_OP_ALL_USES);
@@ -2146,12 +2619,18 @@ init_scc_vn (void)
calculate_dominance_info (CDI_DOMINATORS);
sccstack = NULL;
+ constant_to_value_id = htab_create (23, vn_constant_hash, vn_constant_eq,
+ free);
+
+ constant_value_ids = BITMAP_ALLOC (NULL);
+
next_dfs_num = 1;
-
+ next_value_id = 1;
+
vn_ssa_aux_table = VEC_alloc (vn_ssa_aux_t, heap, num_ssa_names + 1);
/* VEC_alloc doesn't actually grow it to the right size, it just
preallocates the space to do so. */
- VEC_safe_grow (vn_ssa_aux_t, heap, vn_ssa_aux_table, num_ssa_names + 1);
+ VEC_safe_grow_cleared (vn_ssa_aux_t, heap, vn_ssa_aux_table, num_ssa_names + 1);
gcc_obstack_init (&vn_ssa_aux_obstack);
shared_lookup_phiargs = NULL;
@@ -2179,7 +2658,8 @@ init_scc_vn (void)
if (name)
{
VN_INFO_GET (name)->valnum = VN_TOP;
- VN_INFO (name)->expr = name;
+ VN_INFO (name)->expr = NULL_TREE;
+ VN_INFO (name)->value_id = 0;
}
}
@@ -2190,15 +2670,6 @@ init_scc_vn (void)
allocate_vn_table (valid_info);
optimistic_info = XCNEW (struct vn_tables_s);
allocate_vn_table (optimistic_info);
- pre_info = NULL;
-}
-
-void
-switch_to_PRE_table (void)
-{
- pre_info = XCNEW (struct vn_tables_s);
- allocate_vn_table (pre_info);
- current_info = pre_info;
}
void
@@ -2206,6 +2677,8 @@ free_scc_vn (void)
{
size_t i;
+ htab_delete (constant_to_value_id);
+ BITMAP_FREE (constant_value_ids);
VEC_free (tree, heap, shared_lookup_phiargs);
VEC_free (tree, gc, shared_lookup_vops);
VEC_free (vn_reference_op_s, heap, shared_lookup_references);
@@ -2215,10 +2688,6 @@ free_scc_vn (void)
{
tree name = ssa_name (i);
if (name
- && SSA_NAME_VALUE (name)
- && TREE_CODE (SSA_NAME_VALUE (name)) == VALUE_HANDLE)
- SSA_NAME_VALUE (name) = NULL;
- if (name
&& VN_INFO (name)->needs_insertion)
release_ssa_name (name);
}
@@ -2230,10 +2699,55 @@ free_scc_vn (void)
XDELETE (valid_info);
free_vn_table (optimistic_info);
XDELETE (optimistic_info);
- if (pre_info)
+}
+
+/* Set the value ids in the valid hash tables. */
+
+static void
+set_hashtable_value_ids (void)
+{
+ htab_iterator hi;
+ vn_nary_op_t vno;
+ vn_reference_t vr;
+ vn_phi_t vp;
+
+ /* Now set the value ids of the things we had put in the hash
+ table. */
+
+ FOR_EACH_HTAB_ELEMENT (valid_info->nary,
+ vno, vn_nary_op_t, hi)
{
- free_vn_table (pre_info);
- XDELETE (pre_info);
+ if (vno->result)
+ {
+ if (TREE_CODE (vno->result) == SSA_NAME)
+ vno->value_id = VN_INFO (vno->result)->value_id;
+ else if (is_gimple_min_invariant (vno->result))
+ vno->value_id = get_or_alloc_constant_value_id (vno->result);
+ }
+ }
+
+ FOR_EACH_HTAB_ELEMENT (valid_info->phis,
+ vp, vn_phi_t, hi)
+ {
+ if (vp->result)
+ {
+ if (TREE_CODE (vp->result) == SSA_NAME)
+ vp->value_id = VN_INFO (vp->result)->value_id;
+ else if (is_gimple_min_invariant (vp->result))
+ vp->value_id = get_or_alloc_constant_value_id (vp->result);
+ }
+ }
+
+ FOR_EACH_HTAB_ELEMENT (valid_info->references,
+ vr, vn_reference_t, hi)
+ {
+ if (vr->result)
+ {
+ if (TREE_CODE (vr->result) == SSA_NAME)
+ vr->value_id = VN_INFO (vr->result)->value_id;
+ else if (is_gimple_min_invariant (vr->result))
+ vr->value_id = get_or_alloc_constant_value_id (vr->result);
+ }
}
}
@@ -2245,7 +2759,8 @@ run_scc_vn (bool may_insert_arg)
{
size_t i;
tree param;
-
+ bool changed = true;
+
may_insert = may_insert_arg;
init_scc_vn ();
@@ -2276,22 +2791,57 @@ run_scc_vn (bool may_insert_arg)
}
}
+ /* Initialize the value ids. */
+
+ for (i = 1; i < num_ssa_names; ++i)
+ {
+ tree name = ssa_name (i);
+ vn_ssa_aux_t info;
+ if (!name)
+ continue;
+ info = VN_INFO (name);
+ if (info->valnum == name)
+ info->value_id = get_next_value_id ();
+ else if (is_gimple_min_invariant (info->valnum))
+ info->value_id = get_or_alloc_constant_value_id (info->valnum);
+ }
+
+ /* Propagate until they stop changing. */
+ while (changed)
+ {
+ changed = false;
+ for (i = 1; i < num_ssa_names; ++i)
+ {
+ tree name = ssa_name (i);
+ vn_ssa_aux_t info;
+ if (!name)
+ continue;
+ info = VN_INFO (name);
+ if (TREE_CODE (info->valnum) == SSA_NAME
+ && info->valnum != name
+ && info->value_id != VN_INFO (info->valnum)->value_id)
+ {
+ changed = true;
+ info->value_id = VN_INFO (info->valnum)->value_id;
+ }
+ }
+ }
+
+ set_hashtable_value_ids ();
+
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "Value numbers:\n");
for (i = 0; i < num_ssa_names; i++)
{
tree name = ssa_name (i);
- if (name && VN_INFO (name)->visited
- && (SSA_VAL (name) != name
- || is_gimple_min_invariant (VN_INFO (name)->expr)))
+ if (name
+ && VN_INFO (name)->visited
+ && SSA_VAL (name) != name)
{
print_generic_expr (dump_file, name, 0);
fprintf (dump_file, " = ");
- if (is_gimple_min_invariant (VN_INFO (name)->expr))
- print_generic_expr (dump_file, VN_INFO (name)->expr, 0);
- else
- print_generic_expr (dump_file, SSA_VAL (name), 0);
+ print_generic_expr (dump_file, SSA_VAL (name), 0);
fprintf (dump_file, "\n");
}
}
@@ -2300,3 +2850,84 @@ run_scc_vn (bool may_insert_arg)
may_insert = false;
return true;
}
+
+/* Return the maximum value id we have ever seen. */
+
+unsigned int
+get_max_value_id (void)
+{
+ return next_value_id;
+}
+
+/* Return the next unique value id. */
+
+unsigned int
+get_next_value_id (void)
+{
+ return next_value_id++;
+}
+
+
+/* Compare two expressions E1 and E2 and return true if they are equal. */
+
+bool
+expressions_equal_p (tree e1, tree e2)
+{
+ /* The obvious case. */
+ if (e1 == e2)
+ return true;
+
+ /* If only one of them is null, they cannot be equal. */
+ if (!e1 || !e2)
+ return false;
+
+ /* Recurse on elements of lists. */
+ if (TREE_CODE (e1) == TREE_LIST && TREE_CODE (e2) == TREE_LIST)
+ {
+ tree lop1 = e1;
+ tree lop2 = e2;
+ for (lop1 = e1, lop2 = e2;
+ lop1 || lop2;
+ lop1 = TREE_CHAIN (lop1), lop2 = TREE_CHAIN (lop2))
+ {
+ if (!lop1 || !lop2)
+ return false;
+ if (!expressions_equal_p (TREE_VALUE (lop1), TREE_VALUE (lop2)))
+ return false;
+ }
+ return true;
+ }
+
+ /* Now perform the actual comparison. */
+ if (TREE_CODE (e1) == TREE_CODE (e2)
+ && operand_equal_p (e1, e2, OEP_PURE_SAME))
+ return true;
+
+ return false;
+}
+
+/* Sort the VUSE array so that we can do equality comparisons
+ quicker on two vuse vecs. */
+
+void
+sort_vuses (VEC (tree,gc) *vuses)
+{
+ if (VEC_length (tree, vuses) > 1)
+ qsort (VEC_address (tree, vuses),
+ VEC_length (tree, vuses),
+ sizeof (tree),
+ operand_build_cmp);
+}
+
+/* Sort the VUSE array so that we can do equality comparisons
+ quicker on two vuse vecs. */
+
+void
+sort_vuses_heap (VEC (tree,heap) *vuses)
+{
+ if (VEC_length (tree, vuses) > 1)
+ qsort (VEC_address (tree, vuses),
+ VEC_length (tree, vuses),
+ sizeof (tree),
+ operand_build_cmp);
+}
diff --git a/gcc/tree-ssa-sccvn.h b/gcc/tree-ssa-sccvn.h
index ecc3297af42..923be193163 100644
--- a/gcc/tree-ssa-sccvn.h
+++ b/gcc/tree-ssa-sccvn.h
@@ -24,6 +24,110 @@
/* TOP of the VN lattice. */
extern tree VN_TOP;
+/* N-ary operations in the hashtable consist of length operands, an
+ opcode, and a type. Result is the value number of the operation,
+ and hashcode is stored to avoid having to calculate it
+ repeatedly. */
+
+typedef struct vn_nary_op_s
+{
+ /* Unique identify that all expressions with the same value have. */
+ unsigned int value_id;
+ ENUM_BITFIELD(tree_code) opcode : 16;
+ unsigned length : 16;
+ hashval_t hashcode;
+ tree result;
+ tree type;
+ tree op[4];
+} *vn_nary_op_t;
+typedef const struct vn_nary_op_s *const_vn_nary_op_t;
+
+/* Phi nodes in the hashtable consist of their non-VN_TOP phi
+ arguments, and the basic block the phi is in. Result is the value
+ number of the operation, and hashcode is stored to avoid having to
+ calculate it repeatedly. Phi nodes not in the same block are never
+ considered equivalent. */
+
+typedef struct vn_phi_s
+{
+ /* Unique identifier that all expressions with the same value have. */
+ unsigned int value_id;
+ hashval_t hashcode;
+ VEC (tree, heap) *phiargs;
+ basic_block block;
+ tree result;
+} *vn_phi_t;
+typedef const struct vn_phi_s *const_vn_phi_t;
+
+/* Reference operands only exist in reference operations structures.
+ They consist of an opcode, type, and some number of operands. For
+ a given opcode, some, all, or none of the operands may be used.
+ The operands are there to store the information that makes up the
+ portion of the addressing calculation that opcode performs. */
+
+typedef struct vn_reference_op_struct
+{
+ enum tree_code opcode;
+ tree type;
+ tree op0;
+ tree op1;
+ tree op2;
+} vn_reference_op_s;
+typedef vn_reference_op_s *vn_reference_op_t;
+typedef const vn_reference_op_s *const_vn_reference_op_t;
+
+DEF_VEC_O(vn_reference_op_s);
+DEF_VEC_ALLOC_O(vn_reference_op_s, heap);
+
+/* A reference operation in the hashtable is representation as a
+ collection of vuses, representing the memory state at the time of
+ the operation, and a collection of operands that make up the
+ addressing calculation. If two vn_reference_t's have the same set
+ of operands, they access the same memory location. We also store
+ the resulting value number, and the hashcode. The vuses are
+ always stored in order sorted by ssa name version. */
+
+typedef struct vn_reference_s
+{
+ /* Unique identifier that all expressions with the same value have. */
+ unsigned int value_id;
+ hashval_t hashcode;
+ VEC (tree, gc) *vuses;
+ VEC (vn_reference_op_s, heap) *operands;
+ tree result;
+} *vn_reference_t;
+typedef const struct vn_reference_s *const_vn_reference_t;
+
+typedef struct vn_constant_s
+{
+ unsigned int value_id;
+ hashval_t hashcode;
+ tree constant;
+} *vn_constant_t;
+
+/* Hash the constant CONSTANT with distinguishing type incompatible
+ constants in the types_compatible_p sense. */
+
+static inline hashval_t
+vn_hash_constant_with_type (tree constant)
+{
+ tree type = TREE_TYPE (constant);
+ return (iterative_hash_expr (constant, 0)
+ + INTEGRAL_TYPE_P (type)
+ + (INTEGRAL_TYPE_P (type)
+ ? TYPE_PRECISION (type) + TYPE_UNSIGNED (type) : 0));
+}
+
+/* Compare the constants C1 and C2 with distinguishing type incompatible
+ constants in the types_compatible_p sense. */
+
+static inline bool
+vn_constant_eq_with_type (tree c1, tree c2)
+{
+ return (expressions_equal_p (c1, c2)
+ && types_compatible_p (TREE_TYPE (c1), TREE_TYPE (c2)));
+}
+
typedef struct vn_ssa_aux
{
/* Value number. This may be an SSA name or a constant. */
@@ -31,6 +135,9 @@ typedef struct vn_ssa_aux
/* Representative expression, if not a direct constant. */
tree expr;
+ /* Unique identifier that all expressions with the same value have. */
+ unsigned int value_id;
+
/* SCC information. */
unsigned int dfsnum;
unsigned int low;
@@ -54,15 +161,38 @@ typedef struct vn_ssa_aux
/* Return the value numbering info for an SSA_NAME. */
extern vn_ssa_aux_t VN_INFO (tree);
extern vn_ssa_aux_t VN_INFO_GET (tree);
+tree vn_get_expr_for (tree);
bool run_scc_vn (bool);
void free_scc_vn (void);
-void switch_to_PRE_table (void);
-tree vn_nary_op_lookup (tree);
-void vn_nary_op_insert (tree, tree);
-tree vn_reference_lookup (tree, VEC (tree, gc) *, bool);
-void vn_reference_insert (tree, tree, VEC (tree, gc) *);
-VEC (tree, gc) *shared_vuses_from_stmt (tree);
-VEC (tree, gc) *copy_vuses_from_stmt (tree);
-
+tree vn_nary_op_lookup (tree, vn_nary_op_t *);
+tree vn_nary_op_lookup_stmt (gimple, vn_nary_op_t *);
+tree vn_nary_op_lookup_pieces (unsigned int, enum tree_code,
+ tree, tree, tree, tree, tree,
+ vn_nary_op_t *);
+vn_nary_op_t vn_nary_op_insert (tree, tree);
+vn_nary_op_t vn_nary_op_insert_stmt (gimple, tree);
+vn_nary_op_t vn_nary_op_insert_pieces (unsigned int, enum tree_code,
+ tree, tree, tree, tree,
+ tree, tree, unsigned int);
+void copy_reference_ops_from_call (gimple, VEC(vn_reference_op_s, heap) **);
+tree vn_reference_lookup_pieces (VEC (tree, gc) *,
+ VEC (vn_reference_op_s, heap) *,
+ vn_reference_t *);
+tree vn_reference_lookup (tree, VEC (tree, gc) *, bool, vn_reference_t *);
+vn_reference_t vn_reference_insert (tree, tree, VEC (tree, gc) *);
+vn_reference_t vn_reference_insert_pieces (VEC (tree, gc) *,
+ VEC (vn_reference_op_s, heap) *,
+ tree, unsigned int);
+hashval_t vn_nary_op_compute_hash (const vn_nary_op_t);
+int vn_nary_op_eq (const void *, const void *);
+hashval_t vn_reference_compute_hash (const vn_reference_t);
+int vn_reference_eq (const void *, const void *);
+unsigned int get_max_value_id (void);
+unsigned int get_next_value_id (void);
+unsigned int get_constant_value_id (tree);
+unsigned int get_or_alloc_constant_value_id (tree);
+bool value_id_constant_p (unsigned int);
+VEC (tree, gc) *shared_vuses_from_stmt (gimple);
+VEC (tree, gc) *copy_vuses_from_stmt (gimple);
#endif /* TREE_SSA_SCCVN_H */
diff --git a/gcc/tree-ssa-sink.c b/gcc/tree-ssa-sink.c
index ebf54e2070b..e56cce0edb1 100644
--- a/gcc/tree-ssa-sink.c
+++ b/gcc/tree-ssa-sink.c
@@ -28,7 +28,7 @@ along with GCC; see the file COPYING3. If not see
#include "diagnostic.h"
#include "tree-inline.h"
#include "tree-flow.h"
-#include "tree-gimple.h"
+#include "gimple.h"
#include "tree-dump.h"
#include "timevar.h"
#include "fibheap.h"
@@ -82,18 +82,18 @@ static struct
we return NULL. */
static basic_block
-find_bb_for_arg (tree phi, tree def)
+find_bb_for_arg (gimple phi, tree def)
{
- int i;
+ size_t i;
bool foundone = false;
basic_block result = NULL;
- for (i = 0; i < PHI_NUM_ARGS (phi); i++)
+ for (i = 0; i < gimple_phi_num_args (phi); i++)
if (PHI_ARG_DEF (phi, i) == def)
{
if (foundone)
return NULL;
foundone = true;
- result = PHI_ARG_EDGE (phi, i)->src;
+ result = gimple_phi_arg_edge (phi, i)->src;
}
return result;
}
@@ -107,9 +107,9 @@ find_bb_for_arg (tree phi, tree def)
used in, so that you only have one place you can sink it to. */
static bool
-all_immediate_uses_same_place (tree stmt)
+all_immediate_uses_same_place (gimple stmt)
{
- tree firstuse = NULL_TREE;
+ gimple firstuse = NULL;
ssa_op_iter op_iter;
imm_use_iterator imm_iter;
use_operand_p use_p;
@@ -119,7 +119,7 @@ all_immediate_uses_same_place (tree stmt)
{
FOR_EACH_IMM_USE_FAST (use_p, imm_iter, var)
{
- if (firstuse == NULL_TREE)
+ if (firstuse == NULL)
firstuse = USE_STMT (use_p);
else
if (firstuse != USE_STMT (use_p))
@@ -134,16 +134,16 @@ all_immediate_uses_same_place (tree stmt)
but we still must avoid moving them around. */
bool
-is_hidden_global_store (tree stmt)
+is_hidden_global_store (gimple stmt)
{
/* Check virtual definitions. If we get here, the only virtual
- definitions we should see are those generated by assignment
+ definitions we should see are those generated by assignment or call
statements. */
if (!ZERO_SSA_OPERANDS (stmt, SSA_OP_VIRTUAL_DEFS))
{
tree lhs;
- gcc_assert (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT);
+ gcc_assert (is_gimple_assign (stmt) || is_gimple_call (stmt));
/* Note that we must not check the individual virtual operands
here. In particular, if this is an aliased store, we could
@@ -170,7 +170,8 @@ is_hidden_global_store (tree stmt)
address is a pointer, we check if its name tag or symbol tag is
a global variable. Otherwise, we check if the base variable
is a global. */
- lhs = GIMPLE_STMT_OPERAND (stmt, 0);
+ lhs = gimple_get_lhs (stmt);
+
if (REFERENCE_CLASS_P (lhs))
lhs = get_base_address (lhs);
@@ -200,7 +201,7 @@ is_hidden_global_store (tree stmt)
/* Find the nearest common dominator of all of the immediate uses in IMM. */
static basic_block
-nearest_common_dominator_of_uses (tree stmt)
+nearest_common_dominator_of_uses (gimple stmt)
{
bitmap blocks = BITMAP_ALLOC (NULL);
basic_block commondom;
@@ -216,18 +217,18 @@ nearest_common_dominator_of_uses (tree stmt)
{
FOR_EACH_IMM_USE_FAST (use_p, imm_iter, var)
{
- tree usestmt = USE_STMT (use_p);
+ gimple usestmt = USE_STMT (use_p);
basic_block useblock;
- if (TREE_CODE (usestmt) == PHI_NODE)
+ if (gimple_code (usestmt) == GIMPLE_PHI)
{
int idx = PHI_ARG_INDEX_FROM_USE (use_p);
- useblock = PHI_ARG_EDGE (usestmt, idx)->src;
+ useblock = gimple_phi_arg_edge (usestmt, idx)->src;
}
else
{
- useblock = bb_for_stmt (usestmt);
+ useblock = gimple_bb (usestmt);
}
/* Short circuit. Nothing dominates the entry block. */
@@ -249,23 +250,22 @@ nearest_common_dominator_of_uses (tree stmt)
/* Given a statement (STMT) and the basic block it is currently in (FROMBB),
determine the location to sink the statement to, if any.
- Returns true if there is such location; in that case, TOBB is set to the
- basic block of the location, and TOBSI points to the statement before
- that STMT should be moved. */
+ Returns true if there is such location; in that case, TOGSI points to the
+ statement before that STMT should be moved. */
static bool
-statement_sink_location (tree stmt, basic_block frombb, basic_block *tobb,
- block_stmt_iterator *tobsi)
+statement_sink_location (gimple stmt, basic_block frombb,
+ gimple_stmt_iterator *togsi)
{
- tree use, def;
+ gimple use;
+ tree def;
use_operand_p one_use = NULL_USE_OPERAND_P;
basic_block sinkbb;
use_operand_p use_p;
def_operand_p def_p;
ssa_op_iter iter;
- stmt_ann_t ann;
- tree rhs;
imm_use_iterator imm_iter;
+ enum tree_code code;
FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_ALL_DEFS)
{
@@ -281,9 +281,8 @@ statement_sink_location (tree stmt, basic_block frombb, basic_block *tobb,
if (one_use == NULL_USE_OPERAND_P)
return false;
- if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT)
+ if (gimple_code (stmt) != GIMPLE_ASSIGN)
return false;
- rhs = GIMPLE_STMT_OPERAND (stmt, 1);
/* There are a few classes of things we can't or don't move, some because we
don't have code to handle it, some because it's not profitable and some
@@ -305,13 +304,13 @@ statement_sink_location (tree stmt, basic_block frombb, basic_block *tobb,
sunk.
*/
- ann = stmt_ann (stmt);
+ code = gimple_assign_rhs_code (stmt);
if (stmt_ends_bb_p (stmt)
- || TREE_SIDE_EFFECTS (rhs)
- || TREE_CODE (rhs) == EXC_PTR_EXPR
- || TREE_CODE (rhs) == FILTER_EXPR
+ || gimple_has_side_effects (stmt)
+ || code == EXC_PTR_EXPR
+ || code == FILTER_EXPR
|| is_hidden_global_store (stmt)
- || ann->has_volatile_ops
+ || gimple_has_volatile_ops (stmt)
|| !ZERO_SSA_OPERANDS (stmt, SSA_OP_VUSE))
return false;
@@ -365,20 +364,19 @@ statement_sink_location (tree stmt, basic_block frombb, basic_block *tobb,
fprintf (dump_file, "Common dominator of all uses is %d\n",
commondom->index);
}
- *tobb = commondom;
- *tobsi = bsi_after_labels (commondom);
+ *togsi = gsi_after_labels (commondom);
return true;
}
use = USE_STMT (one_use);
- if (TREE_CODE (use) != PHI_NODE)
+ if (gimple_code (use) != GIMPLE_PHI)
{
- sinkbb = bb_for_stmt (use);
+ sinkbb = gimple_bb (use);
if (sinkbb == frombb || sinkbb->loop_depth > frombb->loop_depth
|| sinkbb->loop_father != frombb->loop_father)
return false;
- *tobb = sinkbb;
- *tobsi = bsi_for_stmt (use);
+
+ *togsi = gsi_for_stmt (use);
return true;
}
@@ -399,14 +397,13 @@ statement_sink_location (tree stmt, basic_block frombb, basic_block *tobb,
If the use is a phi, and is in the same bb as the def,
we can't sink it. */
- if (bb_for_stmt (use) == frombb)
+ if (gimple_bb (use) == frombb)
return false;
if (sinkbb == frombb || sinkbb->loop_depth > frombb->loop_depth
|| sinkbb->loop_father != frombb->loop_father)
return false;
- *tobb = sinkbb;
- *tobsi = bsi_after_labels (sinkbb);
+ *togsi = gsi_after_labels (sinkbb);
return true;
}
@@ -417,7 +414,7 @@ static void
sink_code_in_bb (basic_block bb)
{
basic_block son;
- block_stmt_iterator bsi;
+ gimple_stmt_iterator gsi;
edge_iterator ei;
edge e;
bool last = true;
@@ -432,50 +429,49 @@ sink_code_in_bb (basic_block bb)
if (e->flags & EDGE_ABNORMAL)
goto earlyout;
- for (bsi = bsi_last (bb); !bsi_end_p (bsi);)
+ for (gsi = gsi_last_bb (bb); !gsi_end_p (gsi);)
{
- tree stmt = bsi_stmt (bsi);
- block_stmt_iterator tobsi;
- basic_block tobb;
+ gimple stmt = gsi_stmt (gsi);
+ gimple_stmt_iterator togsi;
- if (!statement_sink_location (stmt, bb, &tobb, &tobsi))
+ if (!statement_sink_location (stmt, bb, &togsi))
{
- if (!bsi_end_p (bsi))
- bsi_prev (&bsi);
+ if (!gsi_end_p (gsi))
+ gsi_prev (&gsi);
last = false;
continue;
}
if (dump_file)
{
fprintf (dump_file, "Sinking ");
- print_generic_expr (dump_file, stmt, TDF_VOPS);
+ print_gimple_stmt (dump_file, stmt, 0, TDF_VOPS);
fprintf (dump_file, " from bb %d to bb %d\n",
- bb->index, tobb->index);
+ bb->index, (gsi_bb (togsi))->index);
}
/* If this is the end of the basic block, we need to insert at the end
of the basic block. */
- if (bsi_end_p (tobsi))
- bsi_move_to_bb_end (&bsi, tobb);
+ if (gsi_end_p (togsi))
+ gsi_move_to_bb_end (&gsi, gsi_bb (togsi));
else
- bsi_move_before (&bsi, &tobsi);
+ gsi_move_before (&gsi, &togsi);
sink_stats.sunk++;
/* If we've just removed the last statement of the BB, the
- bsi_end_p() test below would fail, but bsi_prev() would have
+ gsi_end_p() test below would fail, but gsi_prev() would have
succeeded, and we want it to succeed. So we keep track of
whether we're at the last statement and pick up the new last
statement. */
if (last)
{
- bsi = bsi_last (bb);
+ gsi = gsi_last_bb (bb);
continue;
}
last = false;
- if (!bsi_end_p (bsi))
- bsi_prev (&bsi);
+ if (!gsi_end_p (gsi))
+ gsi_prev (&gsi);
}
earlyout:
diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c
index 553125641ce..3b9ce02a5b7 100644
--- a/gcc/tree-ssa-structalias.c
+++ b/gcc/tree-ssa-structalias.c
@@ -39,7 +39,7 @@
#include "tree-inline.h"
#include "varray.h"
#include "c-tree.h"
-#include "tree-gimple.h"
+#include "gimple.h"
#include "hashtab.h"
#include "function.h"
#include "cgraph.h"
@@ -220,8 +220,8 @@ struct variable_info
/* True for variables whose size is not known or variable. */
unsigned int is_unknown_size_var:1;
- /* True for variables that have unions somewhere in them. */
- unsigned int has_union:1;
+ /* True for (sub-)fields that represent a whole variable. */
+ unsigned int is_full_var : 1;
/* True if this is a heap variable. */
unsigned int is_heap_var:1;
@@ -262,6 +262,7 @@ struct variable_info
typedef struct variable_info *varinfo_t;
static varinfo_t first_vi_for_offset (varinfo_t, unsigned HOST_WIDE_INT);
+static varinfo_t lookup_vi_for_tree (tree);
/* Pool of variable info structures. */
static alloc_pool variable_info_pool;
@@ -375,7 +376,7 @@ new_var_info (tree t, unsigned int id, const char *name)
ret->is_heap_var = false;
ret->is_special_var = false;
ret->is_unknown_size_var = false;
- ret->has_union = false;
+ ret->is_full_var = false;
var = t;
if (TREE_CODE (var) == SSA_NAME)
var = SSA_NAME_VAR (var);
@@ -623,6 +624,96 @@ debug_constraints (void)
dump_constraints (stderr);
}
+/* Print out to FILE the edge in the constraint graph that is created by
+ constraint c. The edge may have a label, depending on the type of
+ constraint that it represents. If complex1, e.g: a = *b, then the label
+ is "=*", if complex2, e.g: *a = b, then the label is "*=", if
+ complex with an offset, e.g: a = b + 8, then the label is "+".
+ Otherwise the edge has no label. */
+
+void
+dump_constraint_edge (FILE *file, constraint_t c)
+{
+ if (c->rhs.type != ADDRESSOF)
+ {
+ const char *src = get_varinfo_fc (c->rhs.var)->name;
+ const char *dst = get_varinfo_fc (c->lhs.var)->name;
+ fprintf (file, " \"%s\" -> \"%s\" ", src, dst);
+ /* Due to preprocessing of constraints, instructions like *a = *b are
+ illegal; thus, we do not have to handle such cases. */
+ if (c->lhs.type == DEREF)
+ fprintf (file, " [ label=\"*=\" ] ;\n");
+ else if (c->rhs.type == DEREF)
+ fprintf (file, " [ label=\"=*\" ] ;\n");
+ else
+ {
+ /* We must check the case where the constraint is an offset.
+ In this case, it is treated as a complex constraint. */
+ if (c->rhs.offset != c->lhs.offset)
+ fprintf (file, " [ label=\"+\" ] ;\n");
+ else
+ fprintf (file, " ;\n");
+ }
+ }
+}
+
+/* Print the constraint graph in dot format. */
+
+void
+dump_constraint_graph (FILE *file)
+{
+ unsigned int i=0, size;
+ constraint_t c;
+
+ /* Only print the graph if it has already been initialized: */
+ if (!graph)
+ return;
+
+ /* Print the constraints used to produce the constraint graph. The
+ constraints will be printed as comments in the dot file: */
+ fprintf (file, "\n\n/* Constraints used in the constraint graph:\n");
+ dump_constraints (file);
+ fprintf (file, "*/\n");
+
+ /* Prints the header of the dot file: */
+ fprintf (file, "\n\n// The constraint graph in dot format:\n");
+ fprintf (file, "strict digraph {\n");
+ fprintf (file, " node [\n shape = box\n ]\n");
+ fprintf (file, " edge [\n fontsize = \"12\"\n ]\n");
+ fprintf (file, "\n // List of nodes in the constraint graph:\n");
+
+ /* The next lines print the nodes in the graph. In order to get the
+ number of nodes in the graph, we must choose the minimum between the
+ vector VEC (varinfo_t, varmap) and graph->size. If the graph has not
+ yet been initialized, then graph->size == 0, otherwise we must only
+ read nodes that have an entry in VEC (varinfo_t, varmap). */
+ size = VEC_length (varinfo_t, varmap);
+ size = size < graph->size ? size : graph->size;
+ for (i = 0; i < size; i++)
+ {
+ const char *name = get_varinfo_fc (graph->rep[i])->name;
+ fprintf (file, " \"%s\" ;\n", name);
+ }
+
+ /* Go over the list of constraints printing the edges in the constraint
+ graph. */
+ fprintf (file, "\n // The constraint edges:\n");
+ for (i = 0; VEC_iterate (constraint_t, constraints, i, c); i++)
+ if (c)
+ dump_constraint_edge (file, c);
+
+ /* Prints the tail of the dot file. By now, only the closing bracket. */
+ fprintf (file, "}\n\n\n");
+}
+
+/* Print out the constraint graph to stderr. */
+
+void
+debug_constraint_graph (void)
+{
+ dump_constraint_graph (stderr);
+}
+
/* SOLVER FUNCTIONS
The solver is a simple worklist solver, that works on the following
@@ -755,23 +846,32 @@ solution_set_add (bitmap set, unsigned HOST_WIDE_INT offset)
EXECUTE_IF_SET_IN_BITMAP (set, 0, i, bi)
{
- /* If this is a properly sized variable, only add offset if it's
- less than end. Otherwise, it is globbed to a single
- variable. */
+ varinfo_t vi = get_varinfo (i);
- if ((get_varinfo (i)->offset + offset) < get_varinfo (i)->fullsize)
+ /* If this is a variable with just one field just set its bit
+ in the result. */
+ if (vi->is_artificial_var
+ || vi->is_unknown_size_var
+ || vi->is_full_var)
+ bitmap_set_bit (result, i);
+ else
{
- unsigned HOST_WIDE_INT fieldoffset = get_varinfo (i)->offset + offset;
- varinfo_t v = first_vi_for_offset (get_varinfo (i), fieldoffset);
+ unsigned HOST_WIDE_INT fieldoffset = vi->offset + offset;
+ varinfo_t v = first_vi_for_offset (vi, fieldoffset);
+ /* If the result is outside of the variable use the last field. */
if (!v)
- continue;
+ {
+ v = vi;
+ while (v->next != NULL)
+ v = v->next;
+ }
bitmap_set_bit (result, v->id);
- }
- else if (get_varinfo (i)->is_artificial_var
- || get_varinfo (i)->has_union
- || get_varinfo (i)->is_unknown_size_var)
- {
- bitmap_set_bit (result, i);
+ /* If the result is not exactly at fieldoffset include the next
+ field as well. See get_constraint_for_ptr_offset for more
+ rationale. */
+ if (v->offset != fieldoffset
+ && v->next != NULL)
+ bitmap_set_bit (result, v->next->id);
}
}
@@ -1379,7 +1479,8 @@ type_safe (unsigned int n, unsigned HOST_WIDE_INT *offset)
0. */
if (ninfo->is_special_var
|| ninfo->is_artificial_var
- || ninfo->is_unknown_size_var)
+ || ninfo->is_unknown_size_var
+ || ninfo->is_full_var)
{
*offset = 0;
return true;
@@ -1406,6 +1507,51 @@ do_sd_constraint (constraint_graph_t graph, constraint_t c,
goto done;
}
+ /* For x = *ESCAPED and x = *CALLUSED we want to compute the
+ reachability set of the rhs var. As a pointer to a sub-field
+ of a variable can also reach all other fields of the variable
+ we simply have to expand the solution to contain all sub-fields
+ if one sub-field is contained. */
+ if (c->rhs.var == escaped_id
+ || c->rhs.var == callused_id)
+ {
+ bitmap vars = NULL;
+ /* In a first pass record all variables we need to add all
+ sub-fields off. This avoids quadratic behavior. */
+ EXECUTE_IF_SET_IN_BITMAP (delta, 0, j, bi)
+ {
+ varinfo_t v = get_varinfo (j);
+ if (v->is_full_var)
+ continue;
+
+ v = lookup_vi_for_tree (v->decl);
+ if (v->next != NULL)
+ {
+ if (vars == NULL)
+ vars = BITMAP_ALLOC (NULL);
+ bitmap_set_bit (vars, v->id);
+ }
+ }
+ /* In the second pass now do the addition to the solution and
+ to speed up solving add it to the delta as well. */
+ if (vars != NULL)
+ {
+ EXECUTE_IF_SET_IN_BITMAP (vars, 0, j, bi)
+ {
+ varinfo_t v = get_varinfo (j);
+ for (; v != NULL; v = v->next)
+ {
+ if (bitmap_set_bit (sol, v->id))
+ {
+ flag = true;
+ bitmap_set_bit (delta, v->id);
+ }
+ }
+ }
+ BITMAP_FREE (vars);
+ }
+ }
+
/* For each variable j in delta (Sol(y)), add
an edge in the graph from j to x, and union Sol(j) into Sol(x). */
EXECUTE_IF_SET_IN_BITMAP (delta, 0, j, bi)
@@ -1418,6 +1564,7 @@ do_sd_constraint (constraint_graph_t graph, constraint_t c,
unsigned int t;
v = first_vi_for_offset (get_varinfo (j), fieldoffset);
+ /* If the access is outside of the variable we can ignore it. */
if (!v)
continue;
t = find (v->id);
@@ -1470,9 +1617,14 @@ do_ds_constraint (constraint_t c, bitmap delta)
unsigned HOST_WIDE_INT fieldoffset = jvi->offset + loff;
varinfo_t v;
- v = first_vi_for_offset (get_varinfo (j), fieldoffset);
- if (!v)
- continue;
+ v = get_varinfo (j);
+ if (!v->is_full_var)
+ {
+ v = first_vi_for_offset (v, fieldoffset);
+ /* If the access is outside of the variable we can ignore it. */
+ if (!v)
+ continue;
+ }
t = find (v->id);
if (bitmap_set_bit (get_varinfo (t)->solution, anything_id)
@@ -1498,6 +1650,7 @@ do_ds_constraint (constraint_t c, bitmap delta)
bitmap tmp;
v = first_vi_for_offset (get_varinfo (j), fieldoffset);
+ /* If the access is outside of the variable we can ignore it. */
if (!v)
continue;
t = find (v->id);
@@ -2560,12 +2713,6 @@ process_constraint (constraint_t t)
gcc_assert (rhs.var < VEC_length (varinfo_t, varmap));
gcc_assert (lhs.var < VEC_length (varinfo_t, varmap));
- if (!use_field_sensitive)
- {
- t->rhs.offset = 0;
- t->lhs.offset = 0;
- }
-
/* ANYTHING == ANYTHING is pointless. */
if (lhs.var == anything_id && rhs.var == anything_id)
return;
@@ -2628,16 +2775,129 @@ could_have_pointers (tree t)
/* Return the position, in bits, of FIELD_DECL from the beginning of its
structure. */
-static unsigned HOST_WIDE_INT
+static HOST_WIDE_INT
bitpos_of_field (const tree fdecl)
{
- if (TREE_CODE (DECL_FIELD_OFFSET (fdecl)) != INTEGER_CST
- || TREE_CODE (DECL_FIELD_BIT_OFFSET (fdecl)) != INTEGER_CST)
+ if (!host_integerp (DECL_FIELD_OFFSET (fdecl), 0)
+ || !host_integerp (DECL_FIELD_BIT_OFFSET (fdecl), 0))
return -1;
- return (tree_low_cst (DECL_FIELD_OFFSET (fdecl), 1) * 8)
- + tree_low_cst (DECL_FIELD_BIT_OFFSET (fdecl), 1);
+ return (TREE_INT_CST_LOW (DECL_FIELD_OFFSET (fdecl)) * 8
+ + TREE_INT_CST_LOW (DECL_FIELD_BIT_OFFSET (fdecl)));
+}
+
+
+/* Get constraint expressions for offsetting PTR by OFFSET. Stores the
+ resulting constraint expressions in *RESULTS. */
+
+static void
+get_constraint_for_ptr_offset (tree ptr, tree offset,
+ VEC (ce_s, heap) **results)
+{
+ struct constraint_expr *c;
+ unsigned int j, n;
+ unsigned HOST_WIDE_INT rhsunitoffset, rhsoffset;
+
+ /* If we do not do field-sensitive PTA adding offsets to pointers
+ does not change the points-to solution. */
+ if (!use_field_sensitive)
+ {
+ get_constraint_for (ptr, results);
+ return;
+ }
+
+ /* If the offset is not a non-negative integer constant that fits
+ in a HOST_WIDE_INT, we have to fall back to a conservative
+ solution which includes all sub-fields of all pointed-to
+ variables of ptr.
+ ??? As we do not have the ability to express this, fall back
+ to anything. */
+ if (!host_integerp (offset, 1))
+ {
+ struct constraint_expr temp;
+ temp.var = anything_id;
+ temp.type = SCALAR;
+ temp.offset = 0;
+ VEC_safe_push (ce_s, heap, *results, &temp);
+ return;
+ }
+
+ /* Make sure the bit-offset also fits. */
+ rhsunitoffset = TREE_INT_CST_LOW (offset);
+ rhsoffset = rhsunitoffset * BITS_PER_UNIT;
+ if (rhsunitoffset != rhsoffset / BITS_PER_UNIT)
+ {
+ struct constraint_expr temp;
+ temp.var = anything_id;
+ temp.type = SCALAR;
+ temp.offset = 0;
+ VEC_safe_push (ce_s, heap, *results, &temp);
+ return;
+ }
+
+ get_constraint_for (ptr, results);
+ if (rhsoffset == 0)
+ return;
+
+ /* As we are eventually appending to the solution do not use
+ VEC_iterate here. */
+ n = VEC_length (ce_s, *results);
+ for (j = 0; j < n; j++)
+ {
+ varinfo_t curr;
+ c = VEC_index (ce_s, *results, j);
+ curr = get_varinfo (c->var);
+
+ if (c->type == ADDRESSOF
+ && !curr->is_full_var)
+ {
+ varinfo_t temp, curr = get_varinfo (c->var);
+
+ /* Search the sub-field which overlaps with the
+ pointed-to offset. As we deal with positive offsets
+ only, we can start the search from the current variable. */
+ temp = first_vi_for_offset (curr, curr->offset + rhsoffset);
+
+ /* If the result is outside of the variable we have to provide
+ a conservative result, as the variable is still reachable
+ from the resulting pointer (even though it technically
+ cannot point to anything). The last sub-field is such
+ a conservative result.
+ ??? If we always had a sub-field for &object + 1 then
+ we could represent this in a more precise way. */
+ if (temp == NULL)
+ {
+ temp = curr;
+ while (temp->next != NULL)
+ temp = temp->next;
+ continue;
+ }
+
+ /* If the found variable is not exactly at the pointed to
+ result, we have to include the next variable in the
+ solution as well. Otherwise two increments by offset / 2
+ do not result in the same or a conservative superset
+ solution. */
+ if (temp->offset != curr->offset + rhsoffset
+ && temp->next != NULL)
+ {
+ struct constraint_expr c2;
+ c2.var = temp->next->id;
+ c2.type = ADDRESSOF;
+ c2.offset = 0;
+ VEC_safe_push (ce_s, heap, *results, &c2);
+ }
+ c->var = temp->id;
+ c->offset = 0;
+ }
+ else if (c->type == ADDRESSOF
+ /* If this varinfo represents a full variable just use it. */
+ && curr->is_full_var)
+ c->offset = 0;
+ else
+ c->offset = rhsoffset;
+ }
}
@@ -2677,15 +2937,18 @@ get_constraint_for_component_ref (tree t, VEC(ce_s, heap) **results,
/* Pretend to take the address of the base, we'll take care of
adding the required subset of sub-fields below. */
get_constraint_for_1 (t, results, true);
- result = VEC_last (ce_s, *results);
-
gcc_assert (VEC_length (ce_s, *results) == 1);
+ result = VEC_last (ce_s, *results);
/* This can also happen due to weird offsetof type macros. */
if (TREE_CODE (t) != ADDR_EXPR && result->type == ADDRESSOF)
result->type = SCALAR;
- if (result->type == SCALAR)
+ if (result->type == SCALAR
+ && get_varinfo (result->var)->is_full_var)
+ /* For single-field vars do not bother about the offset. */
+ result->offset = 0;
+ else if (result->type == SCALAR)
{
/* In languages like C, you can access one past the end of an
array. You aren't allowed to dereference it, so we can
@@ -2714,12 +2977,25 @@ get_constraint_for_component_ref (tree t, VEC(ce_s, heap) **results,
break;
}
}
- /* assert that we found *some* field there. The user couldn't be
- accessing *only* padding. */
- /* Still the user could access one past the end of an array
- embedded in a struct resulting in accessing *only* padding. */
- gcc_assert (VEC_length (ce_s, *results) >= 1
- || ref_contains_array_ref (orig_t));
+ /* If we are going to take the address of this field then
+ to be able to compute reachability correctly add at least
+ the last field of the variable. */
+ if (address_p
+ && VEC_length (ce_s, *results) == 0)
+ {
+ curr = get_varinfo (cexpr.var);
+ while (curr->next != NULL)
+ curr = curr->next;
+ cexpr.var = curr->id;
+ VEC_safe_push (ce_s, heap, *results, &cexpr);
+ }
+ else
+ /* Assert that we found *some* field there. The user couldn't be
+ accessing *only* padding. */
+ /* Still the user could access one past the end of an array
+ embedded in a struct resulting in accessing *only* padding. */
+ gcc_assert (VEC_length (ce_s, *results) >= 1
+ || ref_contains_array_ref (orig_t));
}
else if (bitmaxsize == 0)
{
@@ -2811,7 +3087,6 @@ get_constraint_for_1 (tree t, VEC (ce_s, heap) **results, bool address_p)
switch (TREE_CODE_CLASS (TREE_CODE (t)))
{
case tcc_expression:
- case tcc_vl_exp:
{
switch (TREE_CODE (t))
{
@@ -2833,54 +3108,9 @@ get_constraint_for_1 (tree t, VEC (ce_s, heap) **results, bool address_p)
return;
}
break;
- case CALL_EXPR:
- /* XXX: In interprocedural mode, if we didn't have the
- body, we would need to do *each pointer argument =
- &ANYTHING added. */
- if (call_expr_flags (t) & (ECF_MALLOC | ECF_MAY_BE_ALLOCA))
- {
- varinfo_t vi;
- tree heapvar = heapvar_lookup (t);
-
- if (heapvar == NULL)
- {
- heapvar = create_tmp_var_raw (ptr_type_node, "HEAP");
- DECL_EXTERNAL (heapvar) = 1;
- get_var_ann (heapvar)->is_heapvar = 1;
- if (gimple_referenced_vars (cfun))
- add_referenced_var (heapvar);
- heapvar_insert (t, heapvar);
- }
-
- temp.var = create_variable_info_for (heapvar,
- alias_get_name (heapvar));
-
- vi = get_varinfo (temp.var);
- vi->is_artificial_var = 1;
- vi->is_heap_var = 1;
- temp.type = ADDRESSOF;
- temp.offset = 0;
- VEC_safe_push (ce_s, heap, *results, &temp);
- return;
- }
- else
- {
- temp.var = anything_id;
- temp.type = SCALAR;
- temp.offset = 0;
- VEC_safe_push (ce_s, heap, *results, &temp);
- return;
- }
- break;
- default:
- {
- temp.type = ADDRESSOF;
- temp.var = anything_id;
- temp.offset = 0;
- VEC_safe_push (ce_s, heap, *results, &temp);
- return;
- }
+ default:;
}
+ break;
}
case tcc_reference:
{
@@ -2897,18 +3127,14 @@ get_constraint_for_1 (tree t, VEC (ce_s, heap) **results, bool address_p)
case COMPONENT_REF:
get_constraint_for_component_ref (t, results, address_p);
return;
- default:
- {
- temp.type = ADDRESSOF;
- temp.var = anything_id;
- temp.offset = 0;
- VEC_safe_push (ce_s, heap, *results, &temp);
- return;
- }
+ default:;
}
+ break;
}
case tcc_unary:
{
+ /* FIXME tuples: this won't trigger, instead get_constraint_for
+ needs to be fed with piecewise trees. */
switch (TREE_CODE (t))
{
CASE_CONVERT:
@@ -2926,56 +3152,36 @@ get_constraint_for_1 (tree t, VEC (ce_s, heap) **results, bool address_p)
/* FALLTHRU */
}
- default:
- {
- temp.type = ADDRESSOF;
- temp.var = anything_id;
- temp.offset = 0;
- VEC_safe_push (ce_s, heap, *results, &temp);
- return;
- }
+ default:;
}
+ break;
}
case tcc_exceptional:
{
switch (TREE_CODE (t))
{
- case PHI_NODE:
- {
- get_constraint_for_1 (PHI_RESULT (t), results, address_p);
- return;
- }
- break;
case SSA_NAME:
{
get_constraint_for_ssa_var (t, results, address_p);
return;
}
- break;
- default:
- {
- temp.type = ADDRESSOF;
- temp.var = anything_id;
- temp.offset = 0;
- VEC_safe_push (ce_s, heap, *results, &temp);
- return;
- }
+ default:;
}
+ break;
}
case tcc_declaration:
{
get_constraint_for_ssa_var (t, results, address_p);
return;
}
- default:
- {
- temp.type = ADDRESSOF;
- temp.var = anything_id;
- temp.offset = 0;
- VEC_safe_push (ce_s, heap, *results, &temp);
- return;
- }
+ default:;
}
+
+ /* The default fallback is a constraint from anything. */
+ temp.type = ADDRESSOF;
+ temp.var = anything_id;
+ temp.offset = 0;
+ VEC_safe_push (ce_s, heap, *results, &temp);
}
/* Given a gimple tree T, return the constraint expression vector for it. */
@@ -3261,80 +3467,6 @@ do_structure_copy (tree lhsop, tree rhsop)
}
}
-
-/* Handle pointer arithmetic EXPR when creating aliasing constraints.
- Expressions of the type PTR + CST can be handled in two ways:
-
- 1- If the constraint for PTR is ADDRESSOF for a non-structure
- variable, then we can use it directly because adding or
- subtracting a constant may not alter the original ADDRESSOF
- constraint (i.e., pointer arithmetic may not legally go outside
- an object's boundaries).
-
- 2- If the constraint for PTR is ADDRESSOF for a structure variable,
- then if CST is a compile-time constant that can be used as an
- offset, we can determine which sub-variable will be pointed-to
- by the expression.
-
- Return true if the expression is handled. For any other kind of
- expression, return false so that each operand can be added as a
- separate constraint by the caller. */
-
-static bool
-handle_ptr_arith (VEC (ce_s, heap) *lhsc, tree expr)
-{
- tree op0, op1;
- struct constraint_expr *c, *c2;
- unsigned int i = 0;
- unsigned int j = 0;
- VEC (ce_s, heap) *temp = NULL;
- unsigned HOST_WIDE_INT rhsunitoffset, rhsoffset;
-
- if (TREE_CODE (expr) != POINTER_PLUS_EXPR)
- return false;
-
- op0 = TREE_OPERAND (expr, 0);
- op1 = TREE_OPERAND (expr, 1);
- gcc_assert (POINTER_TYPE_P (TREE_TYPE (op0)));
-
- /* If the offset is not a non-negative integer constant that fits
- in a HOST_WIDE_INT, we cannot handle it here. */
- if (!host_integerp (op1, 1))
- return false;
-
- /* Make sure the bit-offset also fits. */
- rhsunitoffset = TREE_INT_CST_LOW (op1);
- rhsoffset = rhsunitoffset * BITS_PER_UNIT;
- if (rhsunitoffset != rhsoffset / BITS_PER_UNIT)
- return false;
-
- get_constraint_for (op0, &temp);
-
- for (i = 0; VEC_iterate (ce_s, lhsc, i, c); i++)
- for (j = 0; VEC_iterate (ce_s, temp, j, c2); j++)
- {
- if (c2->type == ADDRESSOF && rhsoffset != 0)
- {
- varinfo_t temp = get_varinfo (c2->var);
-
- /* An access one after the end of an array is valid,
- so simply punt on accesses we cannot resolve. */
- temp = first_vi_for_offset (temp, rhsoffset);
- if (temp == NULL)
- continue;
- c2->var = temp->id;
- c2->offset = 0;
- }
- else
- c2->offset = rhsoffset;
- process_constraint (new_constraint (*c, *c2));
- }
-
- VEC_free (ce_s, heap, temp);
-
- return true;
-}
-
/* Create a constraint ID = OP. */
static void
@@ -3367,20 +3499,23 @@ make_escape_constraint (tree op)
RHS. */
static void
-handle_rhs_call (tree rhs)
+handle_rhs_call (gimple stmt)
{
- tree arg;
- call_expr_arg_iterator iter;
+ unsigned i;
+
+ for (i = 0; i < gimple_call_num_args (stmt); ++i)
+ {
+ tree arg = gimple_call_arg (stmt, i);
- FOR_EACH_CALL_EXPR_ARG (arg, iter, rhs)
- /* Find those pointers being passed, and make sure they end up
- pointing to anything. */
- if (could_have_pointers (arg))
- make_escape_constraint (arg);
+ /* Find those pointers being passed, and make sure they end up
+ pointing to anything. */
+ if (could_have_pointers (arg))
+ make_escape_constraint (arg);
+ }
/* The static chain escapes as well. */
- if (CALL_EXPR_STATIC_CHAIN (rhs))
- make_escape_constraint (CALL_EXPR_STATIC_CHAIN (rhs));
+ if (gimple_call_chain (stmt))
+ make_escape_constraint (gimple_call_chain (stmt));
}
/* For non-IPA mode, generate constraints necessary for a call
@@ -3435,22 +3570,20 @@ handle_lhs_call (tree lhs, int flags)
const function that returns a pointer in the statement STMT. */
static void
-handle_const_call (tree stmt)
+handle_const_call (gimple stmt)
{
- tree lhs = GIMPLE_STMT_OPERAND (stmt, 0);
- tree call = get_call_expr_in (stmt);
+ tree lhs = gimple_call_lhs (stmt);
VEC(ce_s, heap) *lhsc = NULL;
struct constraint_expr rhsc;
- unsigned int j;
+ unsigned int j, k;
struct constraint_expr *lhsp;
- tree arg, tmpvar;
- call_expr_arg_iterator iter;
+ tree tmpvar;
struct constraint_expr tmpc;
get_constraint_for (lhs, &lhsc);
/* If this is a nested function then it can return anything. */
- if (CALL_EXPR_STATIC_CHAIN (call))
+ if (gimple_call_chain (stmt))
{
rhsc.var = anything_id;
rhsc.offset = 0;
@@ -3475,18 +3608,22 @@ handle_const_call (tree stmt)
process_constraint (new_constraint (tmpc, rhsc));
/* May return arguments. */
- FOR_EACH_CALL_EXPR_ARG (arg, iter, call)
- if (could_have_pointers (arg))
- {
- VEC(ce_s, heap) *argc = NULL;
- struct constraint_expr *argp;
- int i;
-
- get_constraint_for (arg, &argc);
- for (i = 0; VEC_iterate (ce_s, argc, i, argp); i++)
- process_constraint (new_constraint (tmpc, *argp));
- VEC_free (ce_s, heap, argc);
- }
+ for (k = 0; k < gimple_call_num_args (stmt); ++k)
+ {
+ tree arg = gimple_call_arg (stmt, k);
+
+ if (could_have_pointers (arg))
+ {
+ VEC(ce_s, heap) *argc = NULL;
+ struct constraint_expr *argp;
+ int i;
+
+ get_constraint_for (arg, &argc);
+ for (i = 0; VEC_iterate (ce_s, argc, i, argp); i++)
+ process_constraint (new_constraint (tmpc, *argp));
+ VEC_free (ce_s, heap, argc);
+ }
+ }
for (j = 0; VEC_iterate (ce_s, lhsc, j, lhsp); j++)
process_constraint (new_constraint (*lhsp, tmpc));
@@ -3498,28 +3635,30 @@ handle_const_call (tree stmt)
pure function in statement STMT. */
static void
-handle_pure_call (tree stmt)
+handle_pure_call (gimple stmt)
{
- tree call = get_call_expr_in (stmt);
- tree arg;
- call_expr_arg_iterator iter;
+ unsigned i;
/* Memory reached from pointer arguments is call-used. */
- FOR_EACH_CALL_EXPR_ARG (arg, iter, call)
- if (could_have_pointers (arg))
- make_constraint_to (callused_id, arg);
+ for (i = 0; i < gimple_call_num_args (stmt); ++i)
+ {
+ tree arg = gimple_call_arg (stmt, i);
+
+ if (could_have_pointers (arg))
+ make_constraint_to (callused_id, arg);
+ }
/* The static chain is used as well. */
- if (CALL_EXPR_STATIC_CHAIN (call))
- make_constraint_to (callused_id, CALL_EXPR_STATIC_CHAIN (call));
+ if (gimple_call_chain (stmt))
+ make_constraint_to (callused_id, gimple_call_chain (stmt));
/* If the call returns a pointer it may point to reachable memory
from the arguments. Not so for malloc functions though. */
- if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT
- && could_have_pointers (GIMPLE_STMT_OPERAND (stmt, 0))
- && !(call_expr_flags (call) & ECF_MALLOC))
+ if (gimple_call_lhs (stmt)
+ && could_have_pointers (gimple_call_lhs (stmt))
+ && !(gimple_call_flags (stmt) & ECF_MALLOC))
{
- tree lhs = GIMPLE_STMT_OPERAND (stmt, 0);
+ tree lhs = gimple_call_lhs (stmt);
VEC(ce_s, heap) *lhsc = NULL;
struct constraint_expr rhsc;
struct constraint_expr *lhsp;
@@ -3528,7 +3667,7 @@ handle_pure_call (tree stmt)
get_constraint_for (lhs, &lhsc);
/* If this is a nested function then it can return anything. */
- if (CALL_EXPR_STATIC_CHAIN (call))
+ if (gimple_call_chain (stmt))
{
rhsc.var = anything_id;
rhsc.offset = 0;
@@ -3556,40 +3695,37 @@ handle_pure_call (tree stmt)
when building alias sets and computing alias grouping heuristics. */
static void
-find_func_aliases (tree origt)
+find_func_aliases (gimple origt)
{
- tree call, t = origt;
+ gimple t = origt;
VEC(ce_s, heap) *lhsc = NULL;
VEC(ce_s, heap) *rhsc = NULL;
struct constraint_expr *c;
enum escape_type stmt_escape_type;
- if (TREE_CODE (t) == RETURN_EXPR && TREE_OPERAND (t, 0))
- t = TREE_OPERAND (t, 0);
-
/* Now build constraints expressions. */
- if (TREE_CODE (t) == PHI_NODE)
+ if (gimple_code (t) == GIMPLE_PHI)
{
- gcc_assert (!AGGREGATE_TYPE_P (TREE_TYPE (PHI_RESULT (t))));
+ gcc_assert (!AGGREGATE_TYPE_P (TREE_TYPE (gimple_phi_result (t))));
/* Only care about pointers and structures containing
pointers. */
- if (could_have_pointers (PHI_RESULT (t)))
+ if (could_have_pointers (gimple_phi_result (t)))
{
- int i;
+ size_t i;
unsigned int j;
/* For a phi node, assign all the arguments to
the result. */
- get_constraint_for (PHI_RESULT (t), &lhsc);
- for (i = 0; i < PHI_NUM_ARGS (t); i++)
+ get_constraint_for (gimple_phi_result (t), &lhsc);
+ for (i = 0; i < gimple_phi_num_args (t); i++)
{
tree rhstype;
tree strippedrhs = PHI_ARG_DEF (t, i);
STRIP_NOPS (strippedrhs);
rhstype = TREE_TYPE (strippedrhs);
- get_constraint_for (PHI_ARG_DEF (t, i), &rhsc);
+ get_constraint_for (gimple_phi_arg_def (t, i), &rhsc);
for (j = 0; VEC_iterate (ce_s, lhsc, j, c); j++)
{
@@ -3605,87 +3741,73 @@ find_func_aliases (tree origt)
}
}
/* In IPA mode, we need to generate constraints to pass call
- arguments through their calls. There are two cases, either a
- GIMPLE_MODIFY_STMT when we are returning a value, or just a plain
- CALL_EXPR when we are not.
+ arguments through their calls. There are two cases,
+ either a GIMPLE_CALL returning a value, or just a plain
+ GIMPLE_CALL when we are not.
In non-ipa mode, we need to generate constraints for each
pointer passed by address. */
- else if ((call = get_call_expr_in (t)) != NULL_TREE)
+ else if (is_gimple_call (t))
{
- int flags = call_expr_flags (call);
if (!in_ipa_mode)
{
+ int flags = gimple_call_flags (t);
+
/* Const functions can return their arguments and addresses
of global memory but not of escaped memory. */
if (flags & ECF_CONST)
{
- if (TREE_CODE (t) == GIMPLE_MODIFY_STMT
- && could_have_pointers (GIMPLE_STMT_OPERAND (t, 1)))
+ if (gimple_call_lhs (t)
+ && could_have_pointers (gimple_call_lhs (t)))
handle_const_call (t);
}
+ /* Pure functions can return addresses in and of memory
+ reachable from their arguments, but they are not an escape
+ point for reachable memory of their arguments. */
else if (flags & ECF_PURE)
{
handle_pure_call (t);
- if (TREE_CODE (t) == GIMPLE_MODIFY_STMT
- && could_have_pointers (GIMPLE_STMT_OPERAND (t, 1)))
- handle_lhs_call (GIMPLE_STMT_OPERAND (t, 0), flags);
+ if (gimple_call_lhs (t)
+ && could_have_pointers (gimple_call_lhs (t)))
+ handle_lhs_call (gimple_call_lhs (t), flags);
}
- /* Pure functions can return addresses in and of memory
- reachable from their arguments, but they are not an escape
- point for reachable memory of their arguments. But as we
- do not compute call-used memory separately we cannot do
- something special here. */
- else if (TREE_CODE (t) == GIMPLE_MODIFY_STMT)
+ else
{
- handle_rhs_call (GIMPLE_STMT_OPERAND (t, 1));
- if (could_have_pointers (GIMPLE_STMT_OPERAND (t, 1)))
- handle_lhs_call (GIMPLE_STMT_OPERAND (t, 0), flags);
+ handle_rhs_call (t);
+ if (gimple_call_lhs (t)
+ && could_have_pointers (gimple_call_lhs (t)))
+ handle_lhs_call (gimple_call_lhs (t), flags);
}
- else
- handle_rhs_call (t);
}
else
{
tree lhsop;
- tree rhsop;
- tree arg;
- call_expr_arg_iterator iter;
varinfo_t fi;
int i = 1;
+ size_t j;
tree decl;
- if (TREE_CODE (t) == GIMPLE_MODIFY_STMT)
- {
- lhsop = GIMPLE_STMT_OPERAND (t, 0);
- rhsop = GIMPLE_STMT_OPERAND (t, 1);
- }
- else
- {
- lhsop = NULL;
- rhsop = t;
- }
- decl = get_callee_fndecl (rhsop);
+
+ lhsop = gimple_call_lhs (t);
+ decl = gimple_call_fndecl (t);
/* If we can directly resolve the function being called, do so.
Otherwise, it must be some sort of indirect expression that
we should still be able to handle. */
if (decl)
- {
- fi = get_vi_for_tree (decl);
- }
+ fi = get_vi_for_tree (decl);
else
{
- decl = CALL_EXPR_FN (rhsop);
+ decl = gimple_call_fn (t);
fi = get_vi_for_tree (decl);
}
/* Assign all the passed arguments to the appropriate incoming
parameters of the function. */
-
- FOR_EACH_CALL_EXPR_ARG (arg, iter, rhsop)
+ for (j = 0; j < gimple_call_num_args (t); j++)
{
struct constraint_expr lhs ;
struct constraint_expr *rhsp;
+ tree arg = gimple_call_arg (t, j);
get_constraint_for (arg, &rhsc);
if (TREE_CODE (decl) != FUNCTION_DECL)
@@ -3734,97 +3856,51 @@ find_func_aliases (tree origt)
}
}
}
- /* Otherwise, just a regular assignment statement. */
- else if (TREE_CODE (t) == GIMPLE_MODIFY_STMT)
+ /* Otherwise, just a regular assignment statement. Only care about
+ operations with pointer result, others are dealt with as escape
+ points if they have pointer operands. */
+ else if (is_gimple_assign (t)
+ && could_have_pointers (gimple_assign_lhs (t)))
{
- tree lhsop = GIMPLE_STMT_OPERAND (t, 0);
- tree rhsop = GIMPLE_STMT_OPERAND (t, 1);
- int i;
+ /* Otherwise, just a regular assignment statement. */
+ tree lhsop = gimple_assign_lhs (t);
+ tree rhsop = (gimple_num_ops (t) == 2) ? gimple_assign_rhs1 (t) : NULL;
- if (AGGREGATE_TYPE_P (TREE_TYPE (lhsop))
- && AGGREGATE_TYPE_P (TREE_TYPE (rhsop)))
- {
- do_structure_copy (lhsop, rhsop);
- }
+ if (rhsop && AGGREGATE_TYPE_P (TREE_TYPE (lhsop)))
+ do_structure_copy (lhsop, rhsop);
else
{
- /* Only care about operations with pointers, structures
- containing pointers, dereferences, and call expressions. */
- if (could_have_pointers (lhsop)
- || TREE_CODE (rhsop) == CALL_EXPR)
+ unsigned int j;
+ struct constraint_expr temp;
+ get_constraint_for (lhsop, &lhsc);
+
+ if (gimple_assign_rhs_code (t) == POINTER_PLUS_EXPR)
+ get_constraint_for_ptr_offset (gimple_assign_rhs1 (t),
+ gimple_assign_rhs2 (t), &rhsc);
+ else if (rhsop)
+ get_constraint_for (rhsop, &rhsc);
+ else
{
- get_constraint_for (lhsop, &lhsc);
- switch (TREE_CODE_CLASS (TREE_CODE (rhsop)))
- {
- /* RHS that consist of unary operations,
- exceptional types, or bare decls/constants, get
- handled directly by get_constraint_for. */
- case tcc_reference:
- case tcc_declaration:
- case tcc_constant:
- case tcc_exceptional:
- case tcc_expression:
- case tcc_vl_exp:
- case tcc_unary:
- {
- unsigned int j;
-
- get_constraint_for (rhsop, &rhsc);
- for (j = 0; VEC_iterate (ce_s, lhsc, j, c); j++)
- {
- struct constraint_expr *c2;
- unsigned int k;
-
- for (k = 0; VEC_iterate (ce_s, rhsc, k, c2); k++)
- process_constraint (new_constraint (*c, *c2));
- }
-
- }
- break;
+ temp.type = ADDRESSOF;
+ temp.var = anything_id;
+ temp.offset = 0;
+ VEC_safe_push (ce_s, heap, rhsc, &temp);
+ }
+ for (j = 0; VEC_iterate (ce_s, lhsc, j, c); j++)
+ {
+ struct constraint_expr *c2;
+ unsigned int k;
- case tcc_binary:
- {
- /* For pointer arithmetic of the form
- PTR + CST, we can simply use PTR's
- constraint because pointer arithmetic is
- not allowed to go out of bounds. */
- if (handle_ptr_arith (lhsc, rhsop))
- break;
- }
- /* FALLTHRU */
-
- /* Otherwise, walk each operand. Notice that we
- can't use the operand interface because we need
- to process expressions other than simple operands
- (e.g. INDIRECT_REF, ADDR_EXPR, CALL_EXPR). */
- default:
- for (i = 0; i < TREE_OPERAND_LENGTH (rhsop); i++)
- {
- tree op = TREE_OPERAND (rhsop, i);
- unsigned int j;
-
- gcc_assert (VEC_length (ce_s, rhsc) == 0);
- get_constraint_for (op, &rhsc);
- for (j = 0; VEC_iterate (ce_s, lhsc, j, c); j++)
- {
- struct constraint_expr *c2;
- while (VEC_length (ce_s, rhsc) > 0)
- {
- c2 = VEC_last (ce_s, rhsc);
- process_constraint (new_constraint (*c, *c2));
- VEC_pop (ce_s, rhsc);
- }
- }
- }
- }
+ for (k = 0; VEC_iterate (ce_s, rhsc, k, c2); k++)
+ process_constraint (new_constraint (*c, *c2));
}
}
}
- else if (TREE_CODE (t) == CHANGE_DYNAMIC_TYPE_EXPR)
+ else if (gimple_code (t) == GIMPLE_CHANGE_DYNAMIC_TYPE)
{
unsigned int j;
- get_constraint_for (CHANGE_DYNAMIC_TYPE_LOCATION (t), &lhsc);
+ get_constraint_for (gimple_cdt_location (t), &lhsc);
for (j = 0; VEC_iterate (ce_s, lhsc, j, c); ++j)
get_varinfo (c->var)->no_tbaa_pruning = true;
}
@@ -3832,48 +3908,47 @@ find_func_aliases (tree origt)
stmt_escape_type = is_escape_site (t);
if (stmt_escape_type == ESCAPE_STORED_IN_GLOBAL)
{
- tree rhs;
- gcc_assert (TREE_CODE (t) == GIMPLE_MODIFY_STMT);
- rhs = GIMPLE_STMT_OPERAND (t, 1);
- if (TREE_CODE (rhs) == ADDR_EXPR)
+ gcc_assert (is_gimple_assign (t));
+ if (gimple_assign_rhs_code (t) == ADDR_EXPR)
{
+ tree rhs = gimple_assign_rhs1 (t);
tree base = get_base_address (TREE_OPERAND (rhs, 0));
if (base
&& (!DECL_P (base)
|| !is_global_var (base)))
make_escape_constraint (rhs);
}
- else if (TREE_CODE (rhs) == SSA_NAME
- && POINTER_TYPE_P (TREE_TYPE (rhs)))
- make_escape_constraint (rhs);
- else if (could_have_pointers (rhs))
- make_escape_constraint (rhs);
+ else if (get_gimple_rhs_class (gimple_assign_rhs_code (t))
+ == GIMPLE_SINGLE_RHS)
+ {
+ if (could_have_pointers (gimple_assign_rhs1 (t)))
+ make_escape_constraint (gimple_assign_rhs1 (t));
+ }
+ /* FIXME tuples
+ else
+ gcc_unreachable (); */
}
else if (stmt_escape_type == ESCAPE_BAD_CAST)
{
- tree rhs;
- gcc_assert (TREE_CODE (t) == GIMPLE_MODIFY_STMT);
- rhs = GIMPLE_STMT_OPERAND (t, 1);
- gcc_assert (CONVERT_EXPR_P (rhs)
- || TREE_CODE (rhs) == VIEW_CONVERT_EXPR);
- rhs = TREE_OPERAND (rhs, 0);
- make_escape_constraint (rhs);
+ gcc_assert (is_gimple_assign (t));
+ gcc_assert (IS_CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (t))
+ || gimple_assign_rhs_code (t) == VIEW_CONVERT_EXPR);
+ make_escape_constraint (gimple_assign_rhs1 (t));
}
else if (stmt_escape_type == ESCAPE_TO_ASM)
{
- tree link;
- int i;
- for (i = 0, link = ASM_OUTPUTS (t); link; i++, link = TREE_CHAIN (link))
+ unsigned i;
+ for (i = 0; i < gimple_asm_noutputs (t); ++i)
{
- tree op = TREE_VALUE (link);
+ tree op = TREE_VALUE (gimple_asm_output_op (t, i));
if (op && could_have_pointers (op))
/* Strictly we'd only need the constraints from ESCAPED and
NONLOCAL. */
make_escape_constraint (op);
}
- for (i = 0, link = ASM_INPUTS (t); link; i++, link = TREE_CHAIN (link))
+ for (i = 0; i < gimple_asm_ninputs (t); ++i)
{
- tree op = TREE_VALUE (link);
+ tree op = TREE_VALUE (gimple_asm_input_op (t, i));
if (op && could_have_pointers (op))
/* Strictly we'd only need the constraint to ESCAPED. */
make_escape_constraint (op);
@@ -3885,7 +3960,7 @@ find_func_aliases (tree origt)
number of statements re-scanned. It's not really necessary to
re-scan *all* statements. */
if (!in_ipa_mode)
- mark_stmt_modified (origt);
+ gimple_set_modified (origt, true);
VEC_free (ce_s, heap, rhsc);
VEC_free (ce_s, heap, lhsc);
}
@@ -3963,17 +4038,15 @@ insert_into_field_list_sorted (varinfo_t base, varinfo_t field)
struct fieldoff
{
- /* Type of the field. */
- tree type;
+ /* Offset from the base of the base containing object to this field. */
+ HOST_WIDE_INT offset;
/* Size, in bits, of the field. */
- tree size;
+ unsigned HOST_WIDE_INT size;
- /* Field. */
- tree decl;
+ unsigned has_unknown_size : 1;
- /* Offset from the base of the base containing object to this field. */
- HOST_WIDE_INT offset;
+ unsigned may_have_pointers : 1;
};
typedef struct fieldoff fieldoff_s;
@@ -3994,10 +4067,10 @@ fieldoff_compare (const void *pa, const void *pb)
else if (foa->offset > fob->offset)
return 1;
- foasize = TREE_INT_CST_LOW (foa->size);
- fobsize = TREE_INT_CST_LOW (fob->size);
+ foasize = foa->size;
+ fobsize = fob->size;
if (foasize < fobsize)
- return - 1;
+ return -1;
else if (foasize > fobsize)
return 1;
return 0;
@@ -4041,14 +4114,11 @@ var_can_have_subvars (const_tree v)
OFFSET is used to keep track of the offset in this entire
structure, rather than just the immediately containing structure.
- Returns the number of fields pushed.
-
- HAS_UNION is set to true if we find a union type as a field of
- TYPE. */
+ Returns the number of fields pushed. */
static int
push_fields_onto_fieldstack (tree type, VEC(fieldoff_s,heap) **fieldstack,
- HOST_WIDE_INT offset, bool *has_union)
+ HOST_WIDE_INT offset)
{
tree field;
int count = 0;
@@ -4067,19 +4137,14 @@ push_fields_onto_fieldstack (tree type, VEC(fieldoff_s,heap) **fieldstack,
{
bool push = false;
int pushed = 0;
+ HOST_WIDE_INT foff = bitpos_of_field (field);
- if (has_union
- && (TREE_CODE (TREE_TYPE (field)) == QUAL_UNION_TYPE
- || TREE_CODE (TREE_TYPE (field)) == UNION_TYPE))
- *has_union = true;
-
- if (!var_can_have_subvars (field))
+ if (!var_can_have_subvars (field)
+ || TREE_CODE (TREE_TYPE (field)) == QUAL_UNION_TYPE
+ || TREE_CODE (TREE_TYPE (field)) == UNION_TYPE)
push = true;
else if (!(pushed = push_fields_onto_fieldstack
- (TREE_TYPE (field),
- fieldstack,
- offset + bitpos_of_field (field),
- has_union))
+ (TREE_TYPE (field), fieldstack, offset + foff))
&& (DECL_SIZE (field)
&& !integer_zerop (DECL_SIZE (field))))
/* Empty structures may have actual size, like in C++. So
@@ -4089,14 +4154,39 @@ push_fields_onto_fieldstack (tree type, VEC(fieldoff_s,heap) **fieldstack,
if (push)
{
- fieldoff_s *pair;
-
- pair = VEC_safe_push (fieldoff_s, heap, *fieldstack, NULL);
- pair->type = TREE_TYPE (field);
- pair->size = DECL_SIZE (field);
- pair->decl = field;
- pair->offset = offset + bitpos_of_field (field);
- count++;
+ fieldoff_s *pair = NULL;
+ bool has_unknown_size = false;
+
+ if (!VEC_empty (fieldoff_s, *fieldstack))
+ pair = VEC_last (fieldoff_s, *fieldstack);
+
+ if (!DECL_SIZE (field)
+ || !host_integerp (DECL_SIZE (field), 1))
+ has_unknown_size = true;
+
+ /* If adjacent fields do not contain pointers merge them. */
+ if (pair
+ && !pair->may_have_pointers
+ && !could_have_pointers (field)
+ && !pair->has_unknown_size
+ && !has_unknown_size
+ && pair->offset + (HOST_WIDE_INT)pair->size == offset + foff)
+ {
+ pair = VEC_last (fieldoff_s, *fieldstack);
+ pair->size += TREE_INT_CST_LOW (DECL_SIZE (field));
+ }
+ else
+ {
+ pair = VEC_safe_push (fieldoff_s, heap, *fieldstack, NULL);
+ pair->offset = offset + foff;
+ pair->has_unknown_size = has_unknown_size;
+ if (!has_unknown_size)
+ pair->size = TREE_INT_CST_LOW (DECL_SIZE (field));
+ else
+ pair->size = -1;
+ pair->may_have_pointers = could_have_pointers (field);
+ count++;
+ }
}
else
count += pushed;
@@ -4162,7 +4252,6 @@ create_function_info_for (tree decl, const char *name)
vi = new_var_info (decl, index, name);
vi->decl = decl;
vi->offset = 0;
- vi->has_union = 0;
vi->size = 1;
vi->fullsize = count_num_arguments (decl, &is_varargs) + 1;
insert_vi_for_tree (vi->decl, vi);
@@ -4171,8 +4260,7 @@ create_function_info_for (tree decl, const char *name)
stats.total_vars++;
/* If it's varargs, we don't know how many arguments it has, so we
- can't do much.
- */
+ can't do much. */
if (is_varargs)
{
vi->fullsize = ~0;
@@ -4206,8 +4294,8 @@ create_function_info_for (tree decl, const char *name)
VEC_safe_push (varinfo_t, heap, varmap, argvi);
argvi->offset = i;
argvi->size = 1;
+ argvi->is_full_var = true;
argvi->fullsize = vi->fullsize;
- argvi->has_union = false;
insert_into_field_list_sorted (vi, argvi);
stats.total_vars ++;
if (arg)
@@ -4243,7 +4331,7 @@ create_function_info_for (tree decl, const char *name)
resultvi->offset = i;
resultvi->size = 1;
resultvi->fullsize = vi->fullsize;
- resultvi->has_union = false;
+ resultvi->is_full_var = true;
insert_into_field_list_sorted (vi, resultvi);
stats.total_vars ++;
if (DECL_RESULT (decl))
@@ -4283,25 +4371,14 @@ create_variable_info_for (tree decl, const char *name)
varinfo_t vi;
tree decltype = TREE_TYPE (decl);
tree declsize = DECL_P (decl) ? DECL_SIZE (decl) : TYPE_SIZE (decltype);
- bool notokay = false;
- bool hasunion;
bool is_global = DECL_P (decl) ? is_global_var (decl) : false;
VEC (fieldoff_s,heap) *fieldstack = NULL;
if (TREE_CODE (decl) == FUNCTION_DECL && in_ipa_mode)
return create_function_info_for (decl, name);
- hasunion = TREE_CODE (decltype) == UNION_TYPE
- || TREE_CODE (decltype) == QUAL_UNION_TYPE;
- if (var_can_have_subvars (decl) && use_field_sensitive && !hasunion)
- {
- push_fields_onto_fieldstack (decltype, &fieldstack, 0, &hasunion);
- if (hasunion)
- {
- VEC_free (fieldoff_s, heap, fieldstack);
- notokay = true;
- }
- }
+ if (var_can_have_subvars (decl) && use_field_sensitive)
+ push_fields_onto_fieldstack (decltype, &fieldstack, 0);
/* If the variable doesn't have subvars, we may end up needing to
sort the field list and create fake variables for all the
@@ -4309,11 +4386,8 @@ create_variable_info_for (tree decl, const char *name)
vi = new_var_info (decl, index, name);
vi->decl = decl;
vi->offset = 0;
- vi->has_union = hasunion;
if (!declsize
- || TREE_CODE (declsize) != INTEGER_CST
- || TREE_CODE (decltype) == UNION_TYPE
- || TREE_CODE (decltype) == QUAL_UNION_TYPE)
+ || !host_integerp (declsize, 1))
{
vi->is_unknown_size_var = true;
vi->fullsize = ~0;
@@ -4333,7 +4407,6 @@ create_variable_info_for (tree decl, const char *name)
stats.total_vars++;
if (use_field_sensitive
- && !notokay
&& !vi->is_unknown_size_var
&& var_can_have_subvars (decl)
&& VEC_length (fieldoff_s, fieldstack) > 1
@@ -4341,12 +4414,12 @@ create_variable_info_for (tree decl, const char *name)
{
unsigned int newindex = VEC_length (varinfo_t, varmap);
fieldoff_s *fo = NULL;
+ bool notokay = false;
unsigned int i;
for (i = 0; !notokay && VEC_iterate (fieldoff_s, fieldstack, i, fo); i++)
{
- if (! fo->size
- || TREE_CODE (fo->size) != INTEGER_CST
+ if (fo->has_unknown_size
|| fo->offset < 0)
{
notokay = true;
@@ -4377,11 +4450,12 @@ create_variable_info_for (tree decl, const char *name)
vi->is_unknown_size_var = 1;
vi->fullsize = ~0;
vi->size = ~0;
+ vi->is_full_var = true;
VEC_free (fieldoff_s, heap, fieldstack);
return index;
}
- vi->size = TREE_INT_CST_LOW (fo->size);
+ vi->size = fo->size;
vi->offset = fo->offset;
for (i = VEC_length (fieldoff_s, fieldstack) - 1;
i >= 1 && VEC_iterate (fieldoff_s, fieldstack, i, fo);
@@ -4394,28 +4468,27 @@ create_variable_info_for (tree decl, const char *name)
newindex = VEC_length (varinfo_t, varmap);
if (dump_file)
{
- if (fo->decl)
- asprintf (&tempname, "%s.%s",
- vi->name, alias_get_name (fo->decl));
- else
- asprintf (&tempname, "%s." HOST_WIDE_INT_PRINT_DEC,
- vi->name, fo->offset);
+ asprintf (&tempname, "%s." HOST_WIDE_INT_PRINT_DEC
+ "+" HOST_WIDE_INT_PRINT_DEC,
+ vi->name, fo->offset, fo->size);
newname = ggc_strdup (tempname);
free (tempname);
}
newvi = new_var_info (decl, newindex, newname);
newvi->offset = fo->offset;
- newvi->size = TREE_INT_CST_LOW (fo->size);
+ newvi->size = fo->size;
newvi->fullsize = vi->fullsize;
insert_into_field_list (vi, newvi);
VEC_safe_push (varinfo_t, heap, varmap, newvi);
if (is_global && (!flag_whole_program || !in_ipa_mode)
- && (!fo->decl || could_have_pointers (fo->decl)))
+ && fo->may_have_pointers)
make_constraint_from (newvi, escaped_id);
stats.total_vars++;
}
}
+ else
+ vi->is_full_var = true;
VEC_free (fieldoff_s, heap, fieldstack);
@@ -4659,61 +4732,6 @@ set_uids_in_ptset (tree ptr, bitmap into, bitmap from, bool is_derefed,
static bool have_alias_info = false;
-/* The list of SMT's that are in use by our pointer variables. This
- is the set of SMT's for all pointers that can point to anything. */
-static bitmap used_smts;
-
-/* Due to the ordering of points-to set calculation and SMT
- calculation being a bit co-dependent, we can't just calculate SMT
- used info whenever we want, we have to calculate it around the time
- that find_what_p_points_to is called. */
-
-/* Mark which SMT's are in use by points-to anything variables. */
-
-void
-set_used_smts (void)
-{
- int i;
- varinfo_t vi;
- used_smts = BITMAP_ALLOC (&pta_obstack);
-
- for (i = 0; VEC_iterate (varinfo_t, varmap, i, vi); i++)
- {
- tree var = vi->decl;
- varinfo_t withsolution = get_varinfo (find (i));
- tree smt;
- var_ann_t va;
- struct ptr_info_def *pi = NULL;
-
- /* For parm decls, the pointer info may be under the default
- def. */
- if (TREE_CODE (vi->decl) == PARM_DECL
- && gimple_default_def (cfun, var))
- pi = SSA_NAME_PTR_INFO (gimple_default_def (cfun, var));
- else if (TREE_CODE (var) == SSA_NAME)
- pi = SSA_NAME_PTR_INFO (var);
-
- /* Skip the special variables and those that can't be aliased. */
- if (vi->is_special_var
- || !SSA_VAR_P (var)
- || (pi && !pi->memory_tag_needed)
- || (TREE_CODE (var) == VAR_DECL && !may_be_aliased (var))
- || !POINTER_TYPE_P (TREE_TYPE (var)))
- continue;
-
- if (TREE_CODE (var) == SSA_NAME)
- var = SSA_NAME_VAR (var);
-
- va = var_ann (var);
- if (!va)
- continue;
-
- smt = va->symbol_mem_tag;
- if (smt && bitmap_bit_p (withsolution->solution, anything_id))
- bitmap_set_bit (used_smts, DECL_UID (smt));
- }
-}
-
/* Given a pointer variable P, fill in its points-to set, or return
false if we can't.
Rather than return false for variables that point-to anything, we
@@ -5167,6 +5185,8 @@ init_base_vars (void)
static void
init_alias_vars (void)
{
+ use_field_sensitive = (MAX_FIELDS_FOR_FIELD_SENSITIVE > 1);
+
bitmap_obstack_initialize (&pta_obstack);
bitmap_obstack_initialize (&oldpta_obstack);
bitmap_obstack_initialize (&predbitmap_obstack);
@@ -5373,25 +5393,28 @@ compute_points_to_sets (void)
/* Now walk all statements and derive aliases. */
FOR_EACH_BB (bb)
{
- block_stmt_iterator bsi;
- tree phi;
+ gimple_stmt_iterator gsi;
+
+ for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+ {
+ gimple phi = gsi_stmt (gsi);
- for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
- if (is_gimple_reg (PHI_RESULT (phi)))
- find_func_aliases (phi);
+ if (is_gimple_reg (gimple_phi_result (phi)))
+ find_func_aliases (phi);
+ }
- for (bsi = bsi_start (bb); !bsi_end_p (bsi); )
+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); )
{
- tree stmt = bsi_stmt (bsi);
+ gimple stmt = gsi_stmt (gsi);
find_func_aliases (stmt);
- /* The information in CHANGE_DYNAMIC_TYPE_EXPR nodes has now
- been captured, and we can remove them. */
- if (TREE_CODE (stmt) == CHANGE_DYNAMIC_TYPE_EXPR)
- bsi_remove (&bsi, true);
+ /* The information in GIMPLE_CHANGE_DYNAMIC_TYPE statements
+ has now been captured, and we can remove them. */
+ if (gimple_code (stmt) == GIMPLE_CHANGE_DYNAMIC_TYPE)
+ gsi_remove (&gsi, true);
else
- bsi_next (&bsi);
+ gsi_next (&gsi);
}
}
@@ -5425,6 +5448,10 @@ compute_points_to_sets (void)
free_var_substitution_info (si);
build_succ_graph ();
+
+ if (dump_file && (dump_flags & TDF_GRAPH))
+ dump_constraint_graph (dump_file);
+
move_complex_constraints (graph);
if (dump_file)
@@ -5493,8 +5520,7 @@ delete_points_to_sets (void)
static bool
gate_ipa_pta (void)
{
- return (flag_unit_at_a_time != 0
- && flag_ipa_pta
+ return (flag_ipa_pta
/* Don't bother doing anything if the program has errors. */
&& !(errorcount || sorrycount));
}
@@ -5542,22 +5568,19 @@ ipa_pta_execute (void)
FOR_EACH_BB_FN (bb, func)
{
- block_stmt_iterator bsi;
- tree phi;
+ gimple_stmt_iterator gsi;
- for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
+ for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi);
+ gsi_next (&gsi))
{
- if (is_gimple_reg (PHI_RESULT (phi)))
- {
- find_func_aliases (phi);
- }
- }
+ gimple phi = gsi_stmt (gsi);
- for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
- {
- tree stmt = bsi_stmt (bsi);
- find_func_aliases (stmt);
+ if (is_gimple_reg (gimple_phi_result (phi)))
+ find_func_aliases (phi);
}
+
+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+ find_func_aliases (gsi_stmt (gsi));
}
current_function_decl = old_func_decl;
pop_cfun ();
@@ -5643,5 +5666,4 @@ delete_alias_heapvars (void)
heapvar_for_stmt = NULL;
}
-
#include "gt-tree-ssa-structalias.h"
diff --git a/gcc/tree-ssa-structalias.h b/gcc/tree-ssa-structalias.h
index 7d468b42f91..e684f5def7f 100644
--- a/gcc/tree-ssa-structalias.h
+++ b/gcc/tree-ssa-structalias.h
@@ -25,20 +25,22 @@ struct constraint;
typedef struct constraint *constraint_t;
/* In tree-ssa-alias.c. */
-enum escape_type is_escape_site (tree);
-void update_mem_sym_stats_from_stmt (tree, tree, long, long);
+enum escape_type is_escape_site (gimple);
+void update_mem_sym_stats_from_stmt (tree, gimple, long, long);
/* In tree-ssa-structalias.c. */
extern void compute_points_to_sets (void);
extern void delete_points_to_sets (void);
extern void dump_constraint (FILE *, constraint_t);
+extern void dump_constraint_edge (FILE *, constraint_t);
extern void dump_constraints (FILE *);
+extern void dump_constraint_graph (FILE *);
extern void debug_constraint (constraint_t);
extern void debug_constraints (void);
+extern void debug_constraint_graph (void);
extern void dump_solution_for_var (FILE *, unsigned int);
extern void debug_solution_for_var (unsigned int);
extern void dump_sa_points_to_info (FILE *);
extern void debug_sa_points_to_info (void);
-extern void set_used_smts (void);
#endif /* TREE_SSA_STRUCTALIAS_H */
diff --git a/gcc/tree-ssa-ter.c b/gcc/tree-ssa-ter.c
index a93001a985b..099c19742e4 100644
--- a/gcc/tree-ssa-ter.c
+++ b/gcc/tree-ssa-ter.c
@@ -30,6 +30,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-flow.h"
#include "tree-dump.h"
#include "tree-ssa-live.h"
+#include "flags.h"
/* Temporary Expression Replacement (TER)
@@ -88,7 +89,7 @@ along with GCC; see the file COPYING3. If not see
TER implements this but stepping through the instructions in a block and
tracking potential expressions for replacement, and the partitions they are
dependent on. Expressions are represented by the SSA_NAME_VERSION of the
- DEF on the LHS of a GIMPLE_MODIFY_STMT and the expression is the RHS.
+ DEF on the LHS of a GIMPLE_ASSIGN and the expression is the RHS.
When a stmt is determined to be a possible replacement expression, the
following steps are taken:
@@ -158,7 +159,7 @@ typedef struct temp_expr_table_d
{
var_map map;
bitmap *partition_dependencies; /* Partitions expr is dependent on. */
- tree *replaceable_expressions; /* Replacement expression table. */
+ gimple *replaceable_expressions; /* Replacement expression table. */
bitmap *expr_decl_uids; /* Base uids of exprs. */
bitmap *kill_list; /* Expr's killed by a partition. */
int virtual_partition; /* Pseudo partition for virtual ops. */
@@ -215,10 +216,10 @@ new_temp_expr_table (var_map map)
/* Free TER table T. If there are valid replacements, return the expression
vector. */
-static tree *
+static gimple *
free_temp_expr_table (temp_expr_table_p t)
{
- tree *ret = NULL;
+ gimple *ret = NULL;
unsigned i;
#ifdef ENABLE_CHECKING
@@ -254,7 +255,7 @@ version_to_be_replaced_p (temp_expr_table_p tab, int version)
{
if (!tab->replaceable_expressions)
return false;
- return tab->replaceable_expressions[version] != NULL_TREE;
+ return tab->replaceable_expressions[version] != NULL;
}
@@ -359,18 +360,20 @@ add_dependence (temp_expr_table_p tab, int version, tree var)
/* Return TRUE if expression STMT is suitable for replacement. */
static inline bool
-is_replaceable_p (tree stmt)
+is_replaceable_p (gimple stmt)
{
- tree call_expr;
use_operand_p use_p;
- tree def, use_stmt;
+ tree def;
+ gimple use_stmt;
+ location_t locus1, locus2;
+ tree block1, block2;
/* Only consider modify stmts. */
- if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT)
+ if (!is_gimple_assign (stmt))
return false;
/* If the statement may throw an exception, it cannot be replaced. */
- if (tree_could_throw_p (stmt))
+ if (stmt_could_throw_p (stmt))
return false;
/* Punt if there is more than 1 def. */
@@ -383,36 +386,57 @@ is_replaceable_p (tree stmt)
return false;
/* If the use isn't in this block, it wont be replaced either. */
- if (bb_for_stmt (use_stmt) != bb_for_stmt (stmt))
+ if (gimple_bb (use_stmt) != gimple_bb (stmt))
+ return false;
+
+ locus1 = gimple_location (stmt);
+ block1 = gimple_block (stmt);
+
+ if (gimple_code (use_stmt) == GIMPLE_PHI)
+ {
+ locus2 = 0;
+ block2 = NULL_TREE;
+ }
+ else
+ {
+ locus2 = gimple_location (use_stmt);
+ block2 = gimple_block (use_stmt);
+ }
+
+ if (!optimize
+ && ((locus1 && locus1 != locus2) || (block1 && block1 != block2)))
return false;
/* Used in this block, but at the TOP of the block, not the end. */
- if (TREE_CODE (use_stmt) == PHI_NODE)
+ if (gimple_code (use_stmt) == GIMPLE_PHI)
return false;
/* There must be no VDEFs. */
if (!(ZERO_SSA_OPERANDS (stmt, SSA_OP_VDEF)))
return false;
+ /* Without alias info we can't move around loads. */
+ if (gimple_references_memory_p (stmt) && !optimize)
+ return false;
+
/* Float expressions must go through memory if float-store is on. */
if (flag_float_store
- && FLOAT_TYPE_P (TREE_TYPE (GENERIC_TREE_OPERAND (stmt, 1))))
+ && FLOAT_TYPE_P (gimple_expr_type (stmt)))
return false;
/* An assignment with a register variable on the RHS is not
replaceable. */
- if (TREE_CODE (GENERIC_TREE_OPERAND (stmt, 1)) == VAR_DECL
- && DECL_HARD_REGISTER (GENERIC_TREE_OPERAND (stmt, 1)))
+ if (gimple_assign_rhs_code (stmt) == VAR_DECL
+ && DECL_HARD_REGISTER (gimple_assign_rhs1 (stmt)))
return false;
/* No function calls can be replaced. */
- if ((call_expr = get_call_expr_in (stmt)) != NULL_TREE)
+ if (is_gimple_call (stmt))
return false;
/* Leave any stmt with volatile operands alone as well. */
- if (stmt_ann (stmt)->has_volatile_ops)
+ if (gimple_has_volatile_ops (stmt))
return false;
-
return true;
}
@@ -444,7 +468,7 @@ finished_with_expr (temp_expr_table_p tab, int version, bool free_expr)
/* Create an expression entry for a replaceable expression. */
static void
-process_replaceable (temp_expr_table_p tab, tree stmt)
+process_replaceable (temp_expr_table_p tab, gimple stmt)
{
tree var, def, basevar;
int version;
@@ -538,7 +562,7 @@ mark_replaceable (temp_expr_table_p tab, tree var, bool more_replacing)
/* Set the replaceable expression. */
if (!tab->replaceable_expressions)
- tab->replaceable_expressions = XCNEWVEC (tree, num_ssa_names + 1);
+ tab->replaceable_expressions = XCNEWVEC (gimple, num_ssa_names + 1);
tab->replaceable_expressions[version] = SSA_NAME_DEF_STMT (var);
}
@@ -549,20 +573,20 @@ mark_replaceable (temp_expr_table_p tab, tree var, bool more_replacing)
static void
find_replaceable_in_bb (temp_expr_table_p tab, basic_block bb)
{
- block_stmt_iterator bsi;
- tree stmt, def, use;
- stmt_ann_t ann;
+ gimple_stmt_iterator bsi;
+ gimple stmt;
+ tree def, use;
int partition;
var_map map = tab->map;
ssa_op_iter iter;
bool stmt_replaceable;
- for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
+ for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi))
{
- stmt = bsi_stmt (bsi);
- ann = stmt_ann (stmt);
+ stmt = gsi_stmt (bsi);
stmt_replaceable = is_replaceable_p (stmt);
+
/* Determine if this stmt finishes an existing expression. */
FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_USE)
{
@@ -591,7 +615,7 @@ find_replaceable_in_bb (temp_expr_table_p tab, basic_block bb)
/* Mark expression as replaceable unless stmt is volatile or the
def variable has the same root variable as something in the
substitution list. */
- if (ann->has_volatile_ops || same_root_var)
+ if (gimple_has_volatile_ops (stmt) || same_root_var)
finished_with_expr (tab, ver, true);
else
mark_replaceable (tab, use, stmt_replaceable);
@@ -629,12 +653,12 @@ find_replaceable_in_bb (temp_expr_table_p tab, basic_block bb)
NULL is returned by the function, otherwise an expression vector indexed
by SSA_NAME version numbers. */
-extern tree *
+extern gimple *
find_replaceable_exprs (var_map map)
{
basic_block bb;
temp_expr_table_p table;
- tree *ret;
+ gimple *ret;
table = new_temp_expr_table (map);
FOR_EACH_BB (bb)
@@ -664,23 +688,20 @@ find_replaceable_exprs (var_map map)
/* Dump TER expression table EXPR to file F. */
-extern void
-dump_replaceable_exprs (FILE *f, tree *expr)
+void
+dump_replaceable_exprs (FILE *f, gimple *expr)
{
- tree stmt, var;
- int x;
+ tree var;
+ unsigned x;
fprintf (f, "\nReplacing Expressions\n");
- for (x = 0; x < (int)num_ssa_names; x++)
+ for (x = 0; x < num_ssa_names; x++)
if (expr[x])
{
- stmt = expr[x];
- var = SINGLE_SSA_TREE_OPERAND (stmt, SSA_OP_DEF);
- gcc_assert (var != NULL_TREE);
+ var = ssa_name (x);
print_generic_expr (f, var, TDF_SLIM);
fprintf (f, " replace with --> ");
- print_generic_expr (f, GENERIC_TREE_OPERAND (stmt, 1),
- TDF_SLIM);
+ print_gimple_stmt (f, expr[x], 0, TDF_SLIM);
fprintf (f, "\n");
}
fprintf (f, "\n");
@@ -692,7 +713,7 @@ dump_replaceable_exprs (FILE *f, tree *expr)
exclusively to debug TER. F is the place to send debug info and T is the
table being debugged. */
-extern void
+void
debug_ter (FILE *f, temp_expr_table_p t)
{
unsigned x, y;
diff --git a/gcc/tree-ssa-threadedge.c b/gcc/tree-ssa-threadedge.c
index f5de5fdb7ac..6a821611800 100644
--- a/gcc/tree-ssa-threadedge.c
+++ b/gcc/tree-ssa-threadedge.c
@@ -55,7 +55,7 @@ static int stmt_count;
bool
potentially_threadable_block (basic_block bb)
{
- block_stmt_iterator bsi;
+ gimple_stmt_iterator gsi;
/* If BB has a single successor or a single predecessor, then
there is no threading opportunity. */
@@ -64,12 +64,12 @@ potentially_threadable_block (basic_block bb)
/* If BB does not end with a conditional, switch or computed goto,
then there is no threading opportunity. */
- bsi = bsi_last (bb);
- if (bsi_end_p (bsi)
- || ! bsi_stmt (bsi)
- || (TREE_CODE (bsi_stmt (bsi)) != COND_EXPR
- && TREE_CODE (bsi_stmt (bsi)) != GOTO_EXPR
- && TREE_CODE (bsi_stmt (bsi)) != SWITCH_EXPR))
+ gsi = gsi_last_bb (bb);
+ if (gsi_end_p (gsi)
+ || ! gsi_stmt (gsi)
+ || (gimple_code (gsi_stmt (gsi)) != GIMPLE_COND
+ && gimple_code (gsi_stmt (gsi)) != GIMPLE_GOTO
+ && gimple_code (gsi_stmt (gsi)) != GIMPLE_SWITCH))
return false;
return true;
@@ -80,28 +80,27 @@ potentially_threadable_block (basic_block bb)
BB. If no such ASSERT_EXPR is found, return OP. */
static tree
-lhs_of_dominating_assert (tree op, basic_block bb, tree stmt)
+lhs_of_dominating_assert (tree op, basic_block bb, gimple stmt)
{
imm_use_iterator imm_iter;
- tree use_stmt;
+ gimple use_stmt;
use_operand_p use_p;
FOR_EACH_IMM_USE_FAST (use_p, imm_iter, op)
{
use_stmt = USE_STMT (use_p);
if (use_stmt != stmt
- && TREE_CODE (use_stmt) == GIMPLE_MODIFY_STMT
- && TREE_CODE (GIMPLE_STMT_OPERAND (use_stmt, 1)) == ASSERT_EXPR
- && TREE_OPERAND (GIMPLE_STMT_OPERAND (use_stmt, 1), 0) == op
- && dominated_by_p (CDI_DOMINATORS, bb, bb_for_stmt (use_stmt)))
+ && gimple_assign_single_p (use_stmt)
+ && TREE_CODE (gimple_assign_rhs1 (use_stmt)) == ASSERT_EXPR
+ && TREE_OPERAND (gimple_assign_rhs1 (use_stmt), 0) == op
+ && dominated_by_p (CDI_DOMINATORS, bb, gimple_bb (use_stmt)))
{
- return GIMPLE_STMT_OPERAND (use_stmt, 0);
+ return gimple_assign_lhs (use_stmt);
}
}
return op;
}
-
/* We record temporary equivalences created by PHI nodes or
statements within the target block. Doing so allows us to
identify more jump threading opportunities, even in blocks
@@ -161,23 +160,24 @@ record_temporary_equivalence (tree x, tree y, VEC(tree, heap) **stack)
static bool
record_temporary_equivalences_from_phis (edge e, VEC(tree, heap) **stack)
{
- tree phi;
+ gimple_stmt_iterator gsi;
/* Each PHI creates a temporary equivalence, record them.
These are context sensitive equivalences and will be removed
later. */
- for (phi = phi_nodes (e->dest); phi; phi = PHI_CHAIN (phi))
+ for (gsi = gsi_start_phis (e->dest); !gsi_end_p (gsi); gsi_next (&gsi))
{
+ gimple phi = gsi_stmt (gsi);
tree src = PHI_ARG_DEF_FROM_EDGE (phi, e);
- tree dst = PHI_RESULT (phi);
+ tree dst = gimple_phi_result (phi);
/* If the desired argument is not the same as this PHI's result
and it is set by a PHI in E->dest, then we can not thread
through E->dest. */
if (src != dst
&& TREE_CODE (src) == SSA_NAME
- && TREE_CODE (SSA_NAME_DEF_STMT (src)) == PHI_NODE
- && bb_for_stmt (SSA_NAME_DEF_STMT (src)) == e->dest)
+ && gimple_code (SSA_NAME_DEF_STMT (src)) == GIMPLE_PHI
+ && gimple_bb (SSA_NAME_DEF_STMT (src)) == e->dest)
return false;
/* We consider any non-virtual PHI as a statement since it
@@ -190,6 +190,56 @@ record_temporary_equivalences_from_phis (edge e, VEC(tree, heap) **stack)
return true;
}
+/* Fold the RHS of an assignment statement and return it as a tree.
+ May return NULL_TREE if no simplification is possible. */
+
+static tree
+fold_assignment_stmt (gimple stmt)
+{
+ enum tree_code subcode = gimple_assign_rhs_code (stmt);
+
+ switch (get_gimple_rhs_class (subcode))
+ {
+ case GIMPLE_SINGLE_RHS:
+ {
+ tree rhs = gimple_assign_rhs1 (stmt);
+
+ if (TREE_CODE (rhs) == COND_EXPR)
+ {
+ /* Sadly, we have to handle conditional assignments specially
+ here, because fold expects all the operands of an expression
+ to be folded before the expression itself is folded, but we
+ can't just substitute the folded condition here. */
+ tree cond = fold (COND_EXPR_COND (rhs));
+ if (cond == boolean_true_node)
+ rhs = COND_EXPR_THEN (rhs);
+ else if (cond == boolean_false_node)
+ rhs = COND_EXPR_ELSE (rhs);
+ }
+
+ return fold (rhs);
+ }
+ break;
+ case GIMPLE_UNARY_RHS:
+ {
+ tree lhs = gimple_assign_lhs (stmt);
+ tree op0 = gimple_assign_rhs1 (stmt);
+ return fold_unary (subcode, TREE_TYPE (lhs), op0);
+ }
+ break;
+ case GIMPLE_BINARY_RHS:
+ {
+ tree lhs = gimple_assign_lhs (stmt);
+ tree op0 = gimple_assign_rhs1 (stmt);
+ tree op1 = gimple_assign_rhs2 (stmt);
+ return fold_binary (subcode, TREE_TYPE (lhs), op0, op1);
+ }
+ break;
+ default:
+ gcc_unreachable ();
+ }
+}
+
/* Try to simplify each statement in E->dest, ultimately leading to
a simplification of the COND_EXPR at the end of E->dest.
@@ -204,17 +254,17 @@ record_temporary_equivalences_from_phis (edge e, VEC(tree, heap) **stack)
If we are able to simplify a statement into the form
SSA_NAME = (SSA_NAME | gimple invariant), then we can record
- a context sensitive equivalency which may help us simplify
+ a context sensitive equivalence which may help us simplify
later statements in E->dest. */
-static tree
+static gimple
record_temporary_equivalences_from_stmts_at_dest (edge e,
VEC(tree, heap) **stack,
- tree (*simplify) (tree,
- tree))
+ tree (*simplify) (gimple,
+ gimple))
{
- block_stmt_iterator bsi;
- tree stmt = NULL;
+ gimple stmt = NULL;
+ gimple_stmt_iterator gsi;
int max_stmt_count;
max_stmt_count = PARAM_VALUE (PARAM_MAX_JUMP_THREAD_DUPLICATION_STMTS);
@@ -223,21 +273,20 @@ record_temporary_equivalences_from_stmts_at_dest (edge e,
we discover. Note any equivalences we discover are context
sensitive (ie, are dependent on traversing E) and must be unwound
when we're finished processing E. */
- for (bsi = bsi_start (e->dest); ! bsi_end_p (bsi); bsi_next (&bsi))
+ for (gsi = gsi_start_bb (e->dest); !gsi_end_p (gsi); gsi_next (&gsi))
{
tree cached_lhs = NULL;
- tree rhs;
- stmt = bsi_stmt (bsi);
+ stmt = gsi_stmt (gsi);
/* Ignore empty statements and labels. */
- if (IS_EMPTY_STMT (stmt) || TREE_CODE (stmt) == LABEL_EXPR)
+ if (gimple_code (stmt) == GIMPLE_NOP || gimple_code (stmt) == GIMPLE_LABEL)
continue;
/* If the statement has volatile operands, then we assume we
can not thread through this block. This is overly
conservative in some ways. */
- if (TREE_CODE (stmt) == ASM_EXPR && ASM_VOLATILE_P (stmt))
+ if (gimple_code (stmt) == GIMPLE_ASM && gimple_asm_volatile_p (stmt))
return NULL;
/* If duplicating this block is going to cause too much code
@@ -246,15 +295,16 @@ record_temporary_equivalences_from_stmts_at_dest (edge e,
if (stmt_count > max_stmt_count)
return NULL;
- /* If this is not a GIMPLE_MODIFY_STMT which sets an SSA_NAME to a new
+ /* If this is not a statement that sets an SSA_NAME to a new
value, then do not try to simplify this statement as it will
not simplify in any way that is helpful for jump threading. */
- if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT
- || TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 0)) != SSA_NAME)
+ if ((gimple_code (stmt) != GIMPLE_ASSIGN
+ || TREE_CODE (gimple_assign_lhs (stmt)) != SSA_NAME)
+ && (gimple_code (stmt) != GIMPLE_CALL
+ || gimple_call_lhs (stmt) == NULL_TREE
+ || TREE_CODE (gimple_call_lhs (stmt)) != SSA_NAME))
continue;
- rhs = GIMPLE_STMT_OPERAND (stmt, 1);
-
/* The result of __builtin_object_size depends on all the arguments
of a phi node. Temporarily using only one edge produces invalid
results. For example
@@ -272,9 +322,9 @@ record_temporary_equivalences_from_stmts_at_dest (edge e,
remaining bytes. If we use only one edge on the phi, the result will
change to be the remaining bytes for the corresponding phi argument. */
- if (TREE_CODE (rhs) == CALL_EXPR)
+ if (is_gimple_call (stmt))
{
- tree fndecl = get_callee_fndecl (rhs);
+ tree fndecl = gimple_call_fndecl (stmt);
if (fndecl && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_OBJECT_SIZE)
continue;
}
@@ -286,16 +336,18 @@ record_temporary_equivalences_from_stmts_at_dest (edge e,
Handle simple copy operations as well as implied copies from
ASSERT_EXPRs. */
- if (TREE_CODE (rhs) == SSA_NAME)
- cached_lhs = rhs;
- else if (TREE_CODE (rhs) == ASSERT_EXPR)
- cached_lhs = TREE_OPERAND (rhs, 0);
+ if (gimple_assign_single_p (stmt)
+ && TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME)
+ cached_lhs = gimple_assign_rhs1 (stmt);
+ else if (gimple_assign_single_p (stmt)
+ && TREE_CODE (gimple_assign_rhs1 (stmt)) == ASSERT_EXPR)
+ cached_lhs = TREE_OPERAND (gimple_assign_rhs1 (stmt), 0);
else
{
/* A statement that is not a trivial copy or ASSERT_EXPR.
We're going to temporarily copy propagate the operands
and see if that allows us to simplify this statement. */
- tree *copy, pre_fold_expr;
+ tree *copy;
ssa_op_iter iter;
use_operand_p use_p;
unsigned int num, i = 0;
@@ -313,38 +365,22 @@ record_temporary_equivalences_from_stmts_at_dest (edge e,
copy[i++] = use;
if (TREE_CODE (use) == SSA_NAME)
tmp = SSA_NAME_VALUE (use);
- if (tmp && TREE_CODE (tmp) != VALUE_HANDLE)
+ if (tmp)
SET_USE (use_p, tmp);
}
/* Try to fold/lookup the new expression. Inserting the
- expression into the hash table is unlikely to help
- Sadly, we have to handle conditional assignments specially
- here, because fold expects all the operands of an expression
- to be folded before the expression itself is folded, but we
- can't just substitute the folded condition here. */
- if (TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 1)) == COND_EXPR)
- {
- tree cond = COND_EXPR_COND (GIMPLE_STMT_OPERAND (stmt, 1));
- cond = fold (cond);
- if (cond == boolean_true_node)
- pre_fold_expr = COND_EXPR_THEN (GIMPLE_STMT_OPERAND (stmt, 1));
- else if (cond == boolean_false_node)
- pre_fold_expr = COND_EXPR_ELSE (GIMPLE_STMT_OPERAND (stmt, 1));
- else
- pre_fold_expr = GIMPLE_STMT_OPERAND (stmt, 1);
- }
+ expression into the hash table is unlikely to help. */
+ if (is_gimple_call (stmt))
+ cached_lhs = fold_call_stmt (stmt, false);
else
- pre_fold_expr = GIMPLE_STMT_OPERAND (stmt, 1);
-
- if (pre_fold_expr)
- {
- cached_lhs = fold (pre_fold_expr);
- if (TREE_CODE (cached_lhs) != SSA_NAME
- && !is_gimple_min_invariant (cached_lhs))
- cached_lhs = (*simplify) (stmt, stmt);
- }
+ cached_lhs = fold_assignment_stmt (stmt);
+ if (!cached_lhs
+ || (TREE_CODE (cached_lhs) != SSA_NAME
+ && !is_gimple_min_invariant (cached_lhs)))
+ cached_lhs = (*simplify) (stmt, stmt);
+
/* Restore the statement's original uses/defs. */
i = 0;
FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE | SSA_OP_VUSE)
@@ -358,16 +394,14 @@ record_temporary_equivalences_from_stmts_at_dest (edge e,
if (cached_lhs
&& (TREE_CODE (cached_lhs) == SSA_NAME
|| is_gimple_min_invariant (cached_lhs)))
- record_temporary_equivalence (GIMPLE_STMT_OPERAND (stmt, 0),
- cached_lhs,
- stack);
+ record_temporary_equivalence (gimple_get_lhs (stmt), cached_lhs, stack);
}
return stmt;
}
/* Simplify the control statement at the end of the block E->dest.
- To avoid allocating memory unnecessarily, a scratch COND_EXPR
+ To avoid allocating memory unnecessarily, a scratch GIMPLE_COND
is available to use/clobber in DUMMY_COND.
Use SIMPLIFY (a pointer to a callback function) to further simplify
@@ -378,43 +412,37 @@ record_temporary_equivalences_from_stmts_at_dest (edge e,
static tree
simplify_control_stmt_condition (edge e,
- tree stmt,
- tree dummy_cond,
- tree (*simplify) (tree, tree),
+ gimple stmt,
+ gimple dummy_cond,
+ tree (*simplify) (gimple, gimple),
bool handle_dominating_asserts)
{
tree cond, cached_lhs;
-
- if (TREE_CODE (stmt) == COND_EXPR)
- cond = COND_EXPR_COND (stmt);
- else if (TREE_CODE (stmt) == GOTO_EXPR)
- cond = GOTO_DESTINATION (stmt);
- else
- cond = SWITCH_COND (stmt);
+ enum gimple_code code = gimple_code (stmt);
/* For comparisons, we have to update both operands, then try
to simplify the comparison. */
- if (COMPARISON_CLASS_P (cond))
+ if (code == GIMPLE_COND)
{
tree op0, op1;
enum tree_code cond_code;
- op0 = TREE_OPERAND (cond, 0);
- op1 = TREE_OPERAND (cond, 1);
- cond_code = TREE_CODE (cond);
+ op0 = gimple_cond_lhs (stmt);
+ op1 = gimple_cond_rhs (stmt);
+ cond_code = gimple_cond_code (stmt);
/* Get the current value of both operands. */
if (TREE_CODE (op0) == SSA_NAME)
{
tree tmp = SSA_NAME_VALUE (op0);
- if (tmp && TREE_CODE (tmp) != VALUE_HANDLE)
+ if (tmp)
op0 = tmp;
}
if (TREE_CODE (op1) == SSA_NAME)
{
tree tmp = SSA_NAME_VALUE (op1);
- if (tmp && TREE_CODE (tmp) != VALUE_HANDLE)
+ if (tmp)
op1 = tmp;
}
@@ -434,11 +462,10 @@ simplify_control_stmt_condition (edge e,
example, op0 might be a constant while op1 is an
SSA_NAME. Failure to canonicalize will cause us to
miss threading opportunities. */
- if (cond_code != SSA_NAME
- && tree_swap_operands_p (op0, op1, false))
+ if (tree_swap_operands_p (op0, op1, false))
{
tree tmp;
- cond_code = swap_tree_comparison (TREE_CODE (cond));
+ cond_code = swap_tree_comparison (cond_code);
tmp = op0;
op0 = op1;
op1 = tmp;
@@ -446,34 +473,47 @@ simplify_control_stmt_condition (edge e,
/* Stuff the operator and operands into our dummy conditional
expression. */
- TREE_SET_CODE (COND_EXPR_COND (dummy_cond), cond_code);
- TREE_OPERAND (COND_EXPR_COND (dummy_cond), 0) = op0;
- TREE_OPERAND (COND_EXPR_COND (dummy_cond), 1) = op1;
+ gimple_cond_set_code (dummy_cond, cond_code);
+ gimple_cond_set_lhs (dummy_cond, op0);
+ gimple_cond_set_rhs (dummy_cond, op1);
/* We absolutely do not care about any type conversions
we only care about a zero/nonzero value. */
fold_defer_overflow_warnings ();
- cached_lhs = fold (COND_EXPR_COND (dummy_cond));
- while (CONVERT_EXPR_P (cached_lhs))
- cached_lhs = TREE_OPERAND (cached_lhs, 0);
+ cached_lhs = fold_binary (cond_code, boolean_type_node, op0, op1);
+ if (cached_lhs)
+ while (TREE_CODE (cached_lhs) == NOP_EXPR
+ || TREE_CODE (cached_lhs) == CONVERT_EXPR)
+ cached_lhs = TREE_OPERAND (cached_lhs, 0);
- fold_undefer_overflow_warnings (is_gimple_min_invariant (cached_lhs),
+ fold_undefer_overflow_warnings ((cached_lhs
+ && is_gimple_min_invariant (cached_lhs)),
stmt, WARN_STRICT_OVERFLOW_CONDITIONAL);
/* If we have not simplified the condition down to an invariant,
then use the pass specific callback to simplify the condition. */
- if (! is_gimple_min_invariant (cached_lhs))
- cached_lhs = (*simplify) (dummy_cond, stmt);
+ if (!cached_lhs
+ || !is_gimple_min_invariant (cached_lhs))
+ cached_lhs = (*simplify) (dummy_cond, stmt);
+
+ return cached_lhs;
}
+ if (code == GIMPLE_SWITCH)
+ cond = gimple_switch_index (stmt);
+ else if (code == GIMPLE_GOTO)
+ cond = gimple_goto_dest (stmt);
+ else
+ gcc_unreachable ();
+
/* We can have conditionals which just test the state of a variable
rather than use a relational operator. These are simpler to handle. */
- else if (TREE_CODE (cond) == SSA_NAME)
+ if (TREE_CODE (cond) == SSA_NAME)
{
cached_lhs = cond;
- /* Get the variable's current value from the equivalency chains.
+ /* Get the variable's current value from the equivalence chains.
It is possible to get loops in the SSA_NAME_VALUE chains
(consider threading the backedge of a loop where we have
@@ -527,13 +567,13 @@ simplify_control_stmt_condition (edge e,
SIMPLIFY is a pass-specific function used to simplify statements. */
void
-thread_across_edge (tree dummy_cond,
+thread_across_edge (gimple dummy_cond,
edge e,
bool handle_dominating_asserts,
VEC(tree, heap) **stack,
- tree (*simplify) (tree, tree))
+ tree (*simplify) (gimple, gimple))
{
- tree stmt;
+ gimple stmt;
/* If E is a backedge, then we want to verify that the COND_EXPR,
SWITCH_EXPR or GOTO_EXPR at the end of e->dest is not affected
@@ -543,15 +583,15 @@ thread_across_edge (tree dummy_cond,
{
ssa_op_iter iter;
use_operand_p use_p;
- tree last = bsi_stmt (bsi_last (e->dest));
+ gimple last = gsi_stmt (gsi_last_bb (e->dest));
FOR_EACH_SSA_USE_OPERAND (use_p, last, iter, SSA_OP_USE | SSA_OP_VUSE)
{
tree use = USE_FROM_PTR (use_p);
if (TREE_CODE (use) == SSA_NAME
- && TREE_CODE (SSA_NAME_DEF_STMT (use)) != PHI_NODE
- && bb_for_stmt (SSA_NAME_DEF_STMT (use)) == e->dest)
+ && gimple_code (SSA_NAME_DEF_STMT (use)) != GIMPLE_PHI
+ && gimple_bb (SSA_NAME_DEF_STMT (use)) == e->dest)
goto fail;
}
}
@@ -570,9 +610,9 @@ thread_across_edge (tree dummy_cond,
/* If we stopped at a COND_EXPR or SWITCH_EXPR, see if we know which arm
will be taken. */
- if (TREE_CODE (stmt) == COND_EXPR
- || TREE_CODE (stmt) == GOTO_EXPR
- || TREE_CODE (stmt) == SWITCH_EXPR)
+ if (gimple_code (stmt) == GIMPLE_COND
+ || gimple_code (stmt) == GIMPLE_GOTO
+ || gimple_code (stmt) == GIMPLE_SWITCH)
{
tree cond;
diff --git a/gcc/tree-ssa-threadupdate.c b/gcc/tree-ssa-threadupdate.c
index 54f87afaf68..dedd00ecb9a 100644
--- a/gcc/tree-ssa-threadupdate.c
+++ b/gcc/tree-ssa-threadupdate.c
@@ -169,23 +169,23 @@ struct thread_stats_d thread_stats;
static void
remove_ctrl_stmt_and_useless_edges (basic_block bb, basic_block dest_bb)
{
- block_stmt_iterator bsi;
+ gimple_stmt_iterator gsi;
edge e;
edge_iterator ei;
- bsi = bsi_last (bb);
+ gsi = gsi_last_bb (bb);
/* If the duplicate ends with a control statement, then remove it.
Note that if we are duplicating the template block rather than the
original basic block, then the duplicate might not have any real
statements in it. */
- if (!bsi_end_p (bsi)
- && bsi_stmt (bsi)
- && (TREE_CODE (bsi_stmt (bsi)) == COND_EXPR
- || TREE_CODE (bsi_stmt (bsi)) == GOTO_EXPR
- || TREE_CODE (bsi_stmt (bsi)) == SWITCH_EXPR))
- bsi_remove (&bsi, true);
+ if (!gsi_end_p (gsi)
+ && gsi_stmt (gsi)
+ && (gimple_code (gsi_stmt (gsi)) == GIMPLE_COND
+ || gimple_code (gsi_stmt (gsi)) == GIMPLE_GOTO
+ || gimple_code (gsi_stmt (gsi)) == GIMPLE_SWITCH))
+ gsi_remove (&gsi, true);
for (ei = ei_start (bb->succs); (e = ei_safe_edge (ei)); )
{
@@ -311,7 +311,7 @@ static void
create_edge_and_update_destination_phis (struct redirection_data *rd)
{
edge e = make_edge (rd->dup_block, rd->outgoing_edge->dest, EDGE_FALLTHRU);
- tree phi;
+ gimple_stmt_iterator gsi;
rescan_loop_exit (e, true, false);
e->probability = REG_BR_PROB_BASE;
@@ -322,10 +322,12 @@ create_edge_and_update_destination_phis (struct redirection_data *rd)
from the duplicate block, then we will need to add a new argument
to them. The argument should have the same value as the argument
associated with the outgoing edge stored in RD. */
- for (phi = phi_nodes (e->dest); phi; phi = PHI_CHAIN (phi))
+ for (gsi = gsi_start_phis (e->dest); !gsi_end_p (gsi); gsi_next (&gsi))
{
+ gimple phi = gsi_stmt (gsi);
+
int indx = rd->outgoing_edge->dest_idx;
- add_phi_arg (phi, PHI_ARG_DEF (phi, indx), e);
+ add_phi_arg (phi, gimple_phi_arg_def (phi, indx), e);
}
}
@@ -468,24 +470,24 @@ redirect_edges (void **slot, void *data)
static bool
redirection_block_p (basic_block bb)
{
- block_stmt_iterator bsi;
+ gimple_stmt_iterator gsi;
/* Advance to the first executable statement. */
- bsi = bsi_start (bb);
- while (!bsi_end_p (bsi)
- && (TREE_CODE (bsi_stmt (bsi)) == LABEL_EXPR
- || IS_EMPTY_STMT (bsi_stmt (bsi))))
- bsi_next (&bsi);
-
+ gsi = gsi_start_bb (bb);
+ while (!gsi_end_p (gsi)
+ && (gimple_code (gsi_stmt (gsi)) == GIMPLE_LABEL
+ || gimple_nop_p (gsi_stmt (gsi))))
+ gsi_next (&gsi);
+
/* Check if this is an empty block. */
- if (bsi_end_p (bsi))
+ if (gsi_end_p (gsi))
return true;
/* Test that we've reached the terminating control statement. */
- return bsi_stmt (bsi)
- && (TREE_CODE (bsi_stmt (bsi)) == COND_EXPR
- || TREE_CODE (bsi_stmt (bsi)) == GOTO_EXPR
- || TREE_CODE (bsi_stmt (bsi)) == SWITCH_EXPR);
+ return gsi_stmt (gsi)
+ && (gimple_code (gsi_stmt (gsi)) == GIMPLE_COND
+ || gimple_code (gsi_stmt (gsi)) == GIMPLE_GOTO
+ || gimple_code (gsi_stmt (gsi)) == GIMPLE_SWITCH);
}
/* BB is a block which ends with a COND_EXPR or SWITCH_EXPR and when BB
diff --git a/gcc/tree-ssa-uncprop.c b/gcc/tree-ssa-uncprop.c
index 0d19c2dfa5f..335d7aed14b 100644
--- a/gcc/tree-ssa-uncprop.c
+++ b/gcc/tree-ssa-uncprop.c
@@ -1,5 +1,5 @@
/* Routines for discovering and unpropagating edge equivalences.
- Copyright (C) 2005, 2007 Free Software Foundation, Inc.
+ Copyright (C) 2005, 2007, 2008 Free Software Foundation, Inc.
This file is part of GCC.
@@ -65,50 +65,35 @@ associate_equivalences_with_edges (void)
then it might create a useful equivalence. */
FOR_EACH_BB (bb)
{
- block_stmt_iterator bsi = bsi_last (bb);
- tree stmt;
+ gimple_stmt_iterator gsi = gsi_last_bb (bb);
+ gimple stmt;
/* If the block does not end with a COND_EXPR or SWITCH_EXPR
then there is nothing to do. */
- if (bsi_end_p (bsi))
+ if (gsi_end_p (gsi))
continue;
- stmt = bsi_stmt (bsi);
+ stmt = gsi_stmt (gsi);
if (!stmt)
continue;
/* A COND_EXPR may create an equivalency in a variety of different
ways. */
- if (TREE_CODE (stmt) == COND_EXPR)
+ if (gimple_code (stmt) == GIMPLE_COND)
{
- tree cond = COND_EXPR_COND (stmt);
edge true_edge;
edge false_edge;
struct edge_equivalency *equivalency;
+ enum tree_code code = gimple_cond_code (stmt);
extract_true_false_edges_from_block (bb, &true_edge, &false_edge);
- /* If the conditional is a single variable 'X', record 'X = 1'
- for the true edge and 'X = 0' on the false edge. */
- if (TREE_CODE (cond) == SSA_NAME
- && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (cond))
- {
- equivalency = XNEW (struct edge_equivalency);
- equivalency->rhs = constant_boolean_node (1, TREE_TYPE (cond));
- equivalency->lhs = cond;
- true_edge->aux = equivalency;
-
- equivalency = XNEW (struct edge_equivalency);
- equivalency->rhs = constant_boolean_node (0, TREE_TYPE (cond));
- equivalency->lhs = cond;
- false_edge->aux = equivalency;
- }
/* Equality tests may create one or two equivalences. */
- else if (TREE_CODE (cond) == EQ_EXPR || TREE_CODE (cond) == NE_EXPR)
+ if (code == EQ_EXPR || code == NE_EXPR)
{
- tree op0 = TREE_OPERAND (cond, 0);
- tree op1 = TREE_OPERAND (cond, 1);
+ tree op0 = gimple_cond_lhs (stmt);
+ tree op1 = gimple_cond_rhs (stmt);
/* Special case comparing booleans against a constant as we
know the value of OP0 on both arms of the branch. i.e., we
@@ -118,7 +103,7 @@ associate_equivalences_with_edges (void)
&& TREE_CODE (TREE_TYPE (op0)) == BOOLEAN_TYPE
&& is_gimple_min_invariant (op1))
{
- if (TREE_CODE (cond) == EQ_EXPR)
+ if (code == EQ_EXPR)
{
equivalency = XNEW (struct edge_equivalency);
equivalency->lhs = op0;
@@ -170,7 +155,7 @@ associate_equivalences_with_edges (void)
equivalency = XNEW (struct edge_equivalency);
equivalency->lhs = op0;
equivalency->rhs = op1;
- if (TREE_CODE (cond) == EQ_EXPR)
+ if (code == EQ_EXPR)
true_edge->aux = equivalency;
else
false_edge->aux = equivalency;
@@ -184,15 +169,14 @@ associate_equivalences_with_edges (void)
/* For a SWITCH_EXPR, a case label which represents a single
value and which is the only case label which reaches the
target block creates an equivalence. */
- if (TREE_CODE (stmt) == SWITCH_EXPR)
+ else if (gimple_code (stmt) == GIMPLE_SWITCH)
{
- tree cond = SWITCH_COND (stmt);
+ tree cond = gimple_switch_index (stmt);
if (TREE_CODE (cond) == SSA_NAME
&& !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (cond))
{
- tree labels = SWITCH_LABELS (stmt);
- int i, n_labels = TREE_VEC_LENGTH (labels);
+ int i, n_labels = gimple_switch_num_labels (stmt);
tree *info = XCNEWVEC (tree, n_basic_blocks);
/* Walk over the case label vector. Record blocks
@@ -200,10 +184,9 @@ associate_equivalences_with_edges (void)
a single value. */
for (i = 0; i < n_labels; i++)
{
- tree label = TREE_VEC_ELT (labels, i);
+ tree label = gimple_switch_label (stmt, i);
basic_block bb = label_to_block (CASE_LABEL (label));
-
if (CASE_HIGH (label)
|| !CASE_LOW (label)
|| info[bb->index])
@@ -475,11 +458,12 @@ uncprop_into_successor_phis (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
destination of the edge. Then remove the temporary equivalence. */
FOR_EACH_EDGE (e, ei, bb->succs)
{
- tree phi = phi_nodes (e->dest);
+ gimple_seq phis = phi_nodes (e->dest);
+ gimple_stmt_iterator gsi;
/* If there are no PHI nodes in this destination, then there is
no sense in recording any equivalences. */
- if (!phi)
+ if (!phis)
continue;
/* Record any equivalency associated with E. */
@@ -490,9 +474,10 @@ uncprop_into_successor_phis (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
}
/* Walk over the PHI nodes, unpropagating values. */
- for ( ; phi; phi = PHI_CHAIN (phi))
+ for (gsi = gsi_start (phis) ; !gsi_end_p (gsi); gsi_next (&gsi))
{
/* Sigh. We'll have more efficient access to this one day. */
+ gimple phi = gsi_stmt (gsi);
tree arg = PHI_ARG_DEF (phi, e->dest_idx);
struct equiv_hash_elt equiv_hash_elt;
void **slot;
@@ -624,3 +609,4 @@ struct gimple_opt_pass pass_uncprop =
TODO_dump_func | TODO_verify_ssa /* todo_flags_finish */
}
};
+
diff --git a/gcc/tree-ssa.c b/gcc/tree-ssa.c
index 7f567b57a2e..fbfcbf213d3 100644
--- a/gcc/tree-ssa.c
+++ b/gcc/tree-ssa.c
@@ -37,7 +37,7 @@ along with GCC; see the file COPYING3. If not see
#include "bitmap.h"
#include "pointer-set.h"
#include "tree-flow.h"
-#include "tree-gimple.h"
+#include "gimple.h"
#include "tree-inline.h"
#include "varray.h"
#include "timevar.h"
@@ -171,19 +171,23 @@ redirect_edge_var_map_destroy (void)
edge
ssa_redirect_edge (edge e, basic_block dest)
{
- tree phi;
+ gimple_stmt_iterator gsi;
+ gimple phi;
redirect_edge_var_map_clear (e);
/* Remove the appropriate PHI arguments in E's destination block. */
- for (phi = phi_nodes (e->dest); phi; phi = PHI_CHAIN (phi))
+ for (gsi = gsi_start_phis (e->dest); !gsi_end_p (gsi); gsi_next (&gsi))
{
- tree def = PHI_ARG_DEF (phi, e->dest_idx);
+ tree def;
+
+ phi = gsi_stmt (gsi);
+ def = gimple_phi_arg_def (phi, e->dest_idx);
if (def == NULL_TREE)
continue;
- redirect_edge_var_map_add (e, PHI_RESULT (phi), def);
+ redirect_edge_var_map_add (e, gimple_phi_result (phi), def);
}
e = redirect_edge_succ_nodup (e, dest);
@@ -191,26 +195,31 @@ ssa_redirect_edge (edge e, basic_block dest)
return e;
}
+
/* Add PHI arguments queued in PENDING_STMT list on edge E to edge
E->dest. */
void
flush_pending_stmts (edge e)
{
- tree phi;
+ gimple phi;
edge_var_map_vector v;
edge_var_map *vm;
int i;
+ gimple_stmt_iterator gsi;
v = redirect_edge_var_map_vector (e);
if (!v)
return;
- for (phi = phi_nodes (e->dest), i = 0;
- phi && VEC_iterate (edge_var_map, v, i, vm);
- phi = PHI_CHAIN (phi), i++)
+ for (gsi = gsi_start_phis (e->dest), i = 0;
+ !gsi_end_p (gsi) && VEC_iterate (edge_var_map, v, i, vm);
+ gsi_next (&gsi), i++)
{
- tree def = redirect_edge_var_map_def (vm);
+ tree def;
+
+ phi = gsi_stmt (gsi);
+ def = redirect_edge_var_map_def (vm);
add_phi_arg (phi, def, e);
}
@@ -256,7 +265,7 @@ verify_ssa_name (tree ssa_name, bool is_virtual)
}
if (SSA_NAME_IS_DEFAULT_DEF (ssa_name)
- && !IS_EMPTY_STMT (SSA_NAME_DEF_STMT (ssa_name)))
+ && !gimple_nop_p (SSA_NAME_DEF_STMT (ssa_name)))
{
error ("found a default name with a non-empty defining statement");
return true;
@@ -279,7 +288,7 @@ verify_ssa_name (tree ssa_name, bool is_virtual)
static bool
verify_def (basic_block bb, basic_block *definition_block, tree ssa_name,
- tree stmt, bool is_virtual)
+ gimple stmt, bool is_virtual)
{
if (verify_ssa_name (ssa_name, is_virtual))
goto err;
@@ -297,9 +306,9 @@ verify_def (basic_block bb, basic_block *definition_block, tree ssa_name,
{
error ("SSA_NAME_DEF_STMT is wrong");
fprintf (stderr, "Expected definition statement:\n");
- print_generic_stmt (stderr, SSA_NAME_DEF_STMT (ssa_name), TDF_VOPS);
+ print_gimple_stmt (stderr, SSA_NAME_DEF_STMT (ssa_name), 4, TDF_VOPS);
fprintf (stderr, "\nActual definition statement:\n");
- print_generic_stmt (stderr, stmt, TDF_VOPS);
+ print_gimple_stmt (stderr, stmt, 4, TDF_VOPS);
goto err;
}
@@ -309,7 +318,7 @@ err:
fprintf (stderr, "while verifying SSA_NAME ");
print_generic_expr (stderr, ssa_name, 0);
fprintf (stderr, " in statement\n");
- print_generic_stmt (stderr, stmt, TDF_VOPS);
+ print_gimple_stmt (stderr, stmt, 4, TDF_VOPS);
return true;
}
@@ -331,7 +340,7 @@ err:
static bool
verify_use (basic_block bb, basic_block def_bb, use_operand_p use_p,
- tree stmt, bool check_abnormal, bitmap names_defined_in_bb)
+ gimple stmt, bool check_abnormal, bitmap names_defined_in_bb)
{
bool err = false;
tree ssa_name = USE_FROM_PTR (use_p);
@@ -342,7 +351,7 @@ verify_use (basic_block bb, basic_block def_bb, use_operand_p use_p,
TREE_VISITED (ssa_name) = 1;
- if (IS_EMPTY_STMT (SSA_NAME_DEF_STMT (ssa_name))
+ if (gimple_nop_p (SSA_NAME_DEF_STMT (ssa_name))
&& SSA_NAME_IS_DEFAULT_DEF (ssa_name))
; /* Default definitions have empty statements. Nothing to do. */
else if (!def_bb)
@@ -381,9 +390,9 @@ verify_use (basic_block bb, basic_block def_bb, use_operand_p use_p,
}
else
{
- tree listvar ;
+ tree listvar;
if (use_p->prev->use == NULL)
- listvar = use_p->prev->stmt;
+ listvar = use_p->prev->loc.ssa_name;
else
listvar = USE_FROM_PTR (use_p->prev);
if (listvar != ssa_name)
@@ -398,7 +407,7 @@ verify_use (basic_block bb, basic_block def_bb, use_operand_p use_p,
fprintf (stderr, "for SSA_NAME: ");
print_generic_expr (stderr, ssa_name, TDF_VOPS);
fprintf (stderr, " in statement:\n");
- print_generic_stmt (stderr, stmt, TDF_VOPS);
+ print_gimple_stmt (stderr, stmt, 0, TDF_VOPS);
}
return err;
@@ -414,11 +423,11 @@ verify_use (basic_block bb, basic_block def_bb, use_operand_p use_p,
definition of SSA_NAME. */
static bool
-verify_phi_args (tree phi, basic_block bb, basic_block *definition_block)
+verify_phi_args (gimple phi, basic_block bb, basic_block *definition_block)
{
edge e;
bool err = false;
- unsigned i, phi_num_args = PHI_NUM_ARGS (phi);
+ size_t i, phi_num_args = gimple_phi_num_args (phi);
if (EDGE_COUNT (bb->preds) != phi_num_args)
{
@@ -429,7 +438,7 @@ verify_phi_args (tree phi, basic_block bb, basic_block *definition_block)
for (i = 0; i < phi_num_args; i++)
{
- use_operand_p op_p = PHI_ARG_DEF_PTR (phi, i);
+ use_operand_p op_p = gimple_phi_arg_imm_use_ptr (phi, i);
tree op = USE_FROM_PTR (op_p);
e = EDGE_PRED (bb, i);
@@ -451,7 +460,7 @@ verify_phi_args (tree phi, basic_block bb, basic_block *definition_block)
if (TREE_CODE (op) == SSA_NAME)
{
- err = verify_ssa_name (op, !is_gimple_reg (PHI_RESULT (phi)));
+ err = verify_ssa_name (op, !is_gimple_reg (gimple_phi_result (phi)));
err |= verify_use (e->src, definition_block[SSA_NAME_VERSION (op)],
op_p, phi, e->flags & EDGE_ABNORMAL, NULL);
}
@@ -475,7 +484,7 @@ error:
if (err)
{
fprintf (stderr, "for PHI node\n");
- print_generic_stmt (stderr, phi, TDF_VOPS|TDF_MEMSYMS);
+ print_gimple_stmt (stderr, phi, 0, TDF_VOPS|TDF_MEMSYMS);
}
@@ -735,13 +744,13 @@ verify_ssa (bool check_modified_stmt)
tree name = ssa_name (i);
if (name)
{
- tree stmt;
+ gimple stmt;
TREE_VISITED (name) = 0;
stmt = SSA_NAME_DEF_STMT (name);
- if (!IS_EMPTY_STMT (stmt))
+ if (!gimple_nop_p (stmt))
{
- basic_block bb = bb_for_stmt (stmt);
+ basic_block bb = gimple_bb (stmt);
verify_def (bb, definition_block,
name, stmt, !is_gimple_reg (name));
@@ -756,9 +765,9 @@ verify_ssa (bool check_modified_stmt)
FOR_EACH_BB (bb)
{
edge e;
- tree phi;
+ gimple phi;
edge_iterator ei;
- block_stmt_iterator bsi;
+ gimple_stmt_iterator gsi;
/* Make sure that all edges have a clear 'aux' field. */
FOR_EACH_EDGE (e, ei, bb->preds)
@@ -772,45 +781,46 @@ verify_ssa (bool check_modified_stmt)
}
/* Verify the arguments for every PHI node in the block. */
- for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
+ for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
+ phi = gsi_stmt (gsi);
if (verify_phi_args (phi, bb, definition_block))
goto err;
bitmap_set_bit (names_defined_in_bb,
- SSA_NAME_VERSION (PHI_RESULT (phi)));
+ SSA_NAME_VERSION (gimple_phi_result (phi)));
}
/* Now verify all the uses and vuses in every statement of the block. */
- for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
- tree stmt = bsi_stmt (bsi);
+ gimple stmt = gsi_stmt (gsi);
use_operand_p use_p;
- if (check_modified_stmt && stmt_modified_p (stmt))
+ if (check_modified_stmt && gimple_modified_p (stmt))
{
error ("stmt (%p) marked modified after optimization pass: ",
(void *)stmt);
- print_generic_stmt (stderr, stmt, TDF_VOPS);
+ print_gimple_stmt (stderr, stmt, 0, TDF_VOPS);
goto err;
}
- if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT
- && TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 0)) != SSA_NAME)
+ if (is_gimple_assign (stmt)
+ && TREE_CODE (gimple_assign_lhs (stmt)) != SSA_NAME)
{
tree lhs, base_address;
- lhs = GIMPLE_STMT_OPERAND (stmt, 0);
+ lhs = gimple_assign_lhs (stmt);
base_address = get_base_address (lhs);
if (base_address
&& gimple_aliases_computed_p (cfun)
&& SSA_VAR_P (base_address)
- && !stmt_ann (stmt)->has_volatile_ops
+ && !gimple_has_volatile_ops (stmt)
&& ZERO_SSA_OPERANDS (stmt, SSA_OP_VDEF))
{
error ("statement makes a memory store, but has no VDEFS");
- print_generic_stmt (stderr, stmt, TDF_VOPS);
+ print_gimple_stmt (stderr, stmt, 0, TDF_VOPS);
goto err;
}
}
@@ -820,7 +830,7 @@ verify_ssa (bool check_modified_stmt)
if (verify_ssa_name (op, true))
{
error ("in statement");
- print_generic_stmt (stderr, stmt, TDF_VOPS|TDF_MEMSYMS);
+ print_gimple_stmt (stderr, stmt, 0, TDF_VOPS|TDF_MEMSYMS);
goto err;
}
}
@@ -830,7 +840,7 @@ verify_ssa (bool check_modified_stmt)
if (verify_ssa_name (op, false))
{
error ("in statement");
- print_generic_stmt (stderr, stmt, TDF_VOPS|TDF_MEMSYMS);
+ print_gimple_stmt (stderr, stmt, 0, TDF_VOPS|TDF_MEMSYMS);
goto err;
}
}
@@ -951,7 +961,7 @@ delete_tree_ssa (void)
{
size_t i;
basic_block bb;
- block_stmt_iterator bsi;
+ gimple_stmt_iterator gsi;
referenced_var_iterator rvi;
tree var;
@@ -967,17 +977,32 @@ delete_tree_ssa (void)
release_ssa_name (var);
}
- /* Remove annotations from every tree in the function. */
+ /* FIXME. This may not be necessary. We will release all this
+ memory en masse in free_ssa_operands. This clearing used to be
+ necessary to avoid problems with the inliner, but it may not be
+ needed anymore. */
FOR_EACH_BB (bb)
{
- for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
- tree stmt = bsi_stmt (bsi);
- stmt_ann_t ann = get_stmt_ann (stmt);
+ gimple stmt = gsi_stmt (gsi);
+
+ if (gimple_has_ops (stmt))
+ {
+ gimple_set_def_ops (stmt, NULL);
+ gimple_set_use_ops (stmt, NULL);
+ gimple_set_addresses_taken (stmt, NULL);
+ }
+
+ if (gimple_has_mem_ops (stmt))
+ {
+ gimple_set_vdef_ops (stmt, NULL);
+ gimple_set_vuse_ops (stmt, NULL);
+ BITMAP_FREE (stmt->gsmem.membase.stores);
+ BITMAP_FREE (stmt->gsmem.membase.loads);
+ }
- free_ssa_operands (&ann->operands);
- ann->addresses_taken = 0;
- mark_stmt_modified (stmt);
+ gimple_set_modified (stmt, true);
}
set_phi_nodes (bb, NULL);
}
@@ -1001,7 +1026,8 @@ delete_tree_ssa (void)
fini_ssanames ();
fini_phinodes ();
- /* we no longer maintain the SSA operand cache at this point. */
+
+ /* We no longer maintain the SSA operand cache at this point. */
if (ssa_operands_active ())
fini_ssa_operands ();
@@ -1209,12 +1235,9 @@ tree_ssa_useless_type_conversion (tree expr)
if (CONVERT_EXPR_P (expr)
|| TREE_CODE (expr) == VIEW_CONVERT_EXPR
|| TREE_CODE (expr) == NON_LVALUE_EXPR)
- /* FIXME: Use of GENERIC_TREE_TYPE here is a temporary measure to work
- around known bugs with GIMPLE_MODIFY_STMTs appearing in places
- they shouldn't. See PR 30391. */
return useless_type_conversion_p
(TREE_TYPE (expr),
- GENERIC_TREE_TYPE (TREE_OPERAND (expr, 0)));
+ TREE_TYPE (TREE_OPERAND (expr, 0)));
return false;
}
@@ -1238,33 +1261,33 @@ static bool
walk_use_def_chains_1 (tree var, walk_use_def_chains_fn fn, void *data,
struct pointer_set_t *visited, bool is_dfs)
{
- tree def_stmt;
+ gimple def_stmt;
if (pointer_set_insert (visited, var))
return false;
def_stmt = SSA_NAME_DEF_STMT (var);
- if (TREE_CODE (def_stmt) != PHI_NODE)
+ if (gimple_code (def_stmt) != GIMPLE_PHI)
{
/* If we reached the end of the use-def chain, call FN. */
return fn (var, def_stmt, data);
}
else
{
- int i;
+ size_t i;
/* When doing a breadth-first search, call FN before following the
use-def links for each argument. */
if (!is_dfs)
- for (i = 0; i < PHI_NUM_ARGS (def_stmt); i++)
- if (fn (PHI_ARG_DEF (def_stmt, i), def_stmt, data))
+ for (i = 0; i < gimple_phi_num_args (def_stmt); i++)
+ if (fn (gimple_phi_arg_def (def_stmt, i), def_stmt, data))
return true;
/* Follow use-def links out of each PHI argument. */
- for (i = 0; i < PHI_NUM_ARGS (def_stmt); i++)
+ for (i = 0; i < gimple_phi_num_args (def_stmt); i++)
{
- tree arg = PHI_ARG_DEF (def_stmt, i);
+ tree arg = gimple_phi_arg_def (def_stmt, i);
/* ARG may be NULL for newly introduced PHI nodes. */
if (arg
@@ -1276,8 +1299,8 @@ walk_use_def_chains_1 (tree var, walk_use_def_chains_fn fn, void *data,
/* When doing a depth-first search, call FN after following the
use-def links for each argument. */
if (is_dfs)
- for (i = 0; i < PHI_NUM_ARGS (def_stmt); i++)
- if (fn (PHI_ARG_DEF (def_stmt, i), def_stmt, data))
+ for (i = 0; i < gimple_phi_num_args (def_stmt); i++)
+ if (fn (gimple_phi_arg_def (def_stmt, i), def_stmt, data))
return true;
}
@@ -1310,7 +1333,7 @@ void
walk_use_def_chains (tree var, walk_use_def_chains_fn fn, void *data,
bool is_dfs)
{
- tree def_stmt;
+ gimple def_stmt;
gcc_assert (TREE_CODE (var) == SSA_NAME);
@@ -1318,7 +1341,7 @@ walk_use_def_chains (tree var, walk_use_def_chains_fn fn, void *data,
/* We only need to recurse if the reaching definition comes from a PHI
node. */
- if (TREE_CODE (def_stmt) != PHI_NODE)
+ if (gimple_code (def_stmt) != GIMPLE_PHI)
(*fn) (var, def_stmt, data);
else
{
@@ -1345,7 +1368,7 @@ ssa_undefined_value_p (tree t)
return false;
/* The value is undefined iff its definition statement is empty. */
- return IS_EMPTY_STMT (SSA_NAME_DEF_STMT (t));
+ return gimple_nop_p (SSA_NAME_DEF_STMT (t));
}
/* Emit warnings for uninitialized variables. This is done in two passes.
@@ -1370,8 +1393,8 @@ static void
warn_uninit (tree t, const char *gmsgid, void *data)
{
tree var = SSA_NAME_VAR (t);
- tree context = (tree) data;
- location_t *locus;
+ gimple context = (gimple) data;
+ location_t location;
expanded_location xloc, floc;
if (!ssa_undefined_value_p (t))
@@ -1382,11 +1405,11 @@ warn_uninit (tree t, const char *gmsgid, void *data)
if (TREE_NO_WARNING (var))
return;
- locus = (context != NULL && EXPR_HAS_LOCATION (context)
- ? EXPR_LOCUS (context)
- : &DECL_SOURCE_LOCATION (var));
- warning (OPT_Wuninitialized, gmsgid, locus, var);
- xloc = expand_location (*locus);
+ location = (context != NULL && gimple_has_location (context))
+ ? gimple_location (context)
+ : DECL_SOURCE_LOCATION (var);
+ warning_at (location, OPT_Wuninitialized, gmsgid, var);
+ xloc = expand_location (location);
floc = expand_location (DECL_SOURCE_LOCATION (cfun->decl));
if (xloc.file != floc.file
|| xloc.line < floc.line
@@ -1397,7 +1420,7 @@ warn_uninit (tree t, const char *gmsgid, void *data)
}
struct walk_data {
- tree stmt;
+ gimple stmt;
bool always_executed;
};
@@ -1407,7 +1430,8 @@ struct walk_data {
static tree
warn_uninitialized_var (tree *tp, int *walk_subtrees, void *data_)
{
- struct walk_data *data = (struct walk_data *)data_;
+ struct walk_stmt_info *wi = (struct walk_stmt_info *) data_;
+ struct walk_data *data = (struct walk_data *) wi->info;
tree t = *tp;
switch (TREE_CODE (t))
@@ -1416,10 +1440,10 @@ warn_uninitialized_var (tree *tp, int *walk_subtrees, void *data_)
/* We only do data flow with SSA_NAMEs, so that's all we
can warn about. */
if (data->always_executed)
- warn_uninit (t, "%H%qD is used uninitialized in this function",
+ warn_uninit (t, "%qD is used uninitialized in this function",
data->stmt);
else
- warn_uninit (t, "%H%qD may be used uninitialized in this function",
+ warn_uninit (t, "%qD may be used uninitialized in this function",
data->stmt);
*walk_subtrees = 0;
break;
@@ -1446,19 +1470,19 @@ warn_uninitialized_var (tree *tp, int *walk_subtrees, void *data_)
and warn about them. */
static void
-warn_uninitialized_phi (tree phi)
+warn_uninitialized_phi (gimple phi)
{
- int i, n = PHI_NUM_ARGS (phi);
+ size_t i, n = gimple_phi_num_args (phi);
/* Don't look at memory tags. */
- if (!is_gimple_reg (PHI_RESULT (phi)))
+ if (!is_gimple_reg (gimple_phi_result (phi)))
return;
for (i = 0; i < n; ++i)
{
- tree op = PHI_ARG_DEF (phi, i);
+ tree op = gimple_phi_arg_def (phi, i);
if (TREE_CODE (op) == SSA_NAME)
- warn_uninit (op, "%H%qD may be used uninitialized in this function",
+ warn_uninit (op, "%qD may be used uninitialized in this function",
NULL);
}
}
@@ -1466,7 +1490,7 @@ warn_uninitialized_phi (tree phi)
static unsigned int
execute_early_warn_uninitialized (void)
{
- block_stmt_iterator bsi;
+ gimple_stmt_iterator gsi;
basic_block bb;
struct walk_data data;
@@ -1476,12 +1500,14 @@ execute_early_warn_uninitialized (void)
{
data.always_executed = dominated_by_p (CDI_POST_DOMINATORS,
single_succ (ENTRY_BLOCK_PTR), bb);
- for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
- {
- data.stmt = bsi_stmt (bsi);
- walk_tree (bsi_stmt_ptr (bsi), warn_uninitialized_var,
- &data, NULL);
- }
+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+ {
+ struct walk_stmt_info wi;
+ data.stmt = gsi_stmt (gsi);
+ memset (&wi, 0, sizeof (wi));
+ wi.info = &data;
+ walk_gimple_op (gsi_stmt (gsi), warn_uninitialized_var, &wi);
+ }
}
return 0;
}
@@ -1490,7 +1516,7 @@ static unsigned int
execute_late_warn_uninitialized (void)
{
basic_block bb;
- tree phi;
+ gimple_stmt_iterator gsi;
/* Re-do the plain uninitialized variable check, as optimization may have
straightened control flow. Do this first so that we don't accidentally
@@ -1498,8 +1524,9 @@ execute_late_warn_uninitialized (void)
execute_early_warn_uninitialized ();
FOR_EACH_BB (bb)
- for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
- warn_uninitialized_phi (phi);
+ for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+ warn_uninitialized_phi (gsi_stmt (gsi));
+
return 0;
}
@@ -1554,32 +1581,33 @@ execute_update_addresses_taken (void)
{
tree var;
referenced_var_iterator rvi;
- block_stmt_iterator bsi;
+ gimple_stmt_iterator gsi;
basic_block bb;
bitmap addresses_taken = BITMAP_ALLOC (NULL);
bitmap vars_updated = BITMAP_ALLOC (NULL);
bool update_vops = false;
- tree phi;
/* Collect into ADDRESSES_TAKEN all variables whose address is taken within
the function body. */
FOR_EACH_BB (bb)
{
- for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
- stmt_ann_t s_ann = stmt_ann (bsi_stmt (bsi));
-
- if (s_ann->addresses_taken)
- bitmap_ior_into (addresses_taken, s_ann->addresses_taken);
+ bitmap taken = gimple_addresses_taken (gsi_stmt (gsi));
+ if (taken)
+ bitmap_ior_into (addresses_taken, taken);
}
- for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
+
+ for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
- unsigned i, phi_num_args = PHI_NUM_ARGS (phi);
- for (i = 0; i < phi_num_args; i++)
+ size_t i;
+ gimple phi = gsi_stmt (gsi);
+
+ for (i = 0; i < gimple_phi_num_args (phi); i++)
{
tree op = PHI_ARG_DEF (phi, i), var;
if (TREE_CODE (op) == ADDR_EXPR
- && (var = get_base_address (TREE_OPERAND (op, 0))) != NULL_TREE
+ && (var = get_base_address (TREE_OPERAND (op, 0))) != NULL
&& DECL_P (var))
bitmap_set_bit (addresses_taken, DECL_UID (var));
}
@@ -1611,14 +1639,14 @@ execute_update_addresses_taken (void)
variables. */
if (update_vops)
FOR_EACH_BB (bb)
- for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
- tree stmt = bsi_stmt (bsi);
+ gimple stmt = gsi_stmt (gsi);
- if ((LOADED_SYMS (stmt)
- && bitmap_intersect_p (LOADED_SYMS (stmt), vars_updated))
- || (STORED_SYMS (stmt)
- && bitmap_intersect_p (STORED_SYMS (stmt), vars_updated)))
+ if ((gimple_loaded_syms (stmt)
+ && bitmap_intersect_p (gimple_loaded_syms (stmt), vars_updated))
+ || (gimple_stored_syms (stmt)
+ && bitmap_intersect_p (gimple_stored_syms (stmt), vars_updated)))
update_stmt (stmt);
}
BITMAP_FREE (addresses_taken);
diff --git a/gcc/tree-ssanames.c b/gcc/tree-ssanames.c
index 8d675b43c49..f3101d28271 100644
--- a/gcc/tree-ssanames.c
+++ b/gcc/tree-ssanames.c
@@ -115,17 +115,12 @@ ssanames_print_statistics (void)
used without a preceding definition). */
tree
-make_ssa_name_fn (struct function *fn, tree var, tree stmt)
+make_ssa_name_fn (struct function *fn, tree var, gimple stmt)
{
tree t;
use_operand_p imm;
- gcc_assert (DECL_P (var)
- || TREE_CODE (var) == INDIRECT_REF);
-
- gcc_assert (!stmt
- || EXPR_P (stmt) || GIMPLE_STMT_P (stmt)
- || TREE_CODE (stmt) == PHI_NODE);
+ gcc_assert (DECL_P (var));
/* If our free list has an element, then use it. */
if (FREE_SSANAMES (fn))
@@ -161,7 +156,7 @@ make_ssa_name_fn (struct function *fn, tree var, tree stmt)
imm->use = NULL;
imm->prev = imm;
imm->next = imm;
- imm->stmt = t;
+ imm->loc.ssa_name = t;
return t;
}
@@ -219,7 +214,8 @@ release_ssa_name (tree var)
imm->prev = imm;
imm->next = imm;
- imm->stmt = var;
+ imm->loc.ssa_name = var;
+
/* First put back the right tree node so that the tree checking
macros do not complain. */
TREE_SET_CODE (var, SSA_NAME);
@@ -243,7 +239,7 @@ release_ssa_name (tree var)
/* Creates a duplicate of a ssa name NAME defined in statement STMT. */
tree
-duplicate_ssa_name (tree name, tree stmt)
+duplicate_ssa_name (tree name, gimple stmt)
{
tree new_name = make_ssa_name (SSA_NAME_VAR (name), stmt);
struct ptr_info_def *old_ptr_info = SSA_NAME_PTR_INFO (name);
@@ -285,7 +281,7 @@ duplicate_ssa_name_ptr_info (tree name, struct ptr_info_def *ptr_info)
/* Release all the SSA_NAMEs created by STMT. */
void
-release_defs (tree stmt)
+release_defs (gimple stmt)
{
tree def;
ssa_op_iter iter;
diff --git a/gcc/tree-stdarg.c b/gcc/tree-stdarg.c
index 728c37d4d6d..96a72fad08e 100644
--- a/gcc/tree-stdarg.c
+++ b/gcc/tree-stdarg.c
@@ -112,7 +112,8 @@ static unsigned HOST_WIDE_INT
va_list_counter_bump (struct stdarg_info *si, tree counter, tree rhs,
bool gpr_p)
{
- tree stmt, lhs, orig_lhs;
+ tree lhs, orig_lhs;
+ gimple stmt;
unsigned HOST_WIDE_INT ret = 0, val, counter_val;
unsigned int max_size;
@@ -130,6 +131,8 @@ va_list_counter_bump (struct stdarg_info *si, tree counter, tree rhs,
orig_lhs = lhs = rhs;
while (lhs)
{
+ enum tree_code rhs_code;
+
if (si->offsets[SSA_NAME_VERSION (lhs)] != -1)
{
if (counter_val >= max_size)
@@ -144,38 +147,32 @@ va_list_counter_bump (struct stdarg_info *si, tree counter, tree rhs,
stmt = SSA_NAME_DEF_STMT (lhs);
- if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT
- || GIMPLE_STMT_OPERAND (stmt, 0) != lhs)
+ if (!is_gimple_assign (stmt) || gimple_assign_lhs (stmt) != lhs)
return (unsigned HOST_WIDE_INT) -1;
- rhs = GIMPLE_STMT_OPERAND (stmt, 1);
- if (TREE_CODE (rhs) == WITH_SIZE_EXPR)
- rhs = TREE_OPERAND (rhs, 0);
-
- if (TREE_CODE (rhs) == SSA_NAME)
+ rhs_code = gimple_assign_rhs_code (stmt);
+ if ((get_gimple_rhs_class (rhs_code) == GIMPLE_SINGLE_RHS
+ || gimple_assign_cast_p (stmt))
+ && TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME)
{
- lhs = rhs;
+ lhs = gimple_assign_rhs1 (stmt);
continue;
}
- if (CONVERT_EXPR_P (rhs)
- && TREE_CODE (TREE_OPERAND (rhs, 0)) == SSA_NAME)
+ if ((rhs_code == POINTER_PLUS_EXPR
+ || rhs_code == PLUS_EXPR)
+ && TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME
+ && host_integerp (gimple_assign_rhs2 (stmt), 1))
{
- lhs = TREE_OPERAND (rhs, 0);
+ ret += tree_low_cst (gimple_assign_rhs2 (stmt), 1);
+ lhs = gimple_assign_rhs1 (stmt);
continue;
}
- if ((TREE_CODE (rhs) == POINTER_PLUS_EXPR
- || TREE_CODE (rhs) == PLUS_EXPR)
- && TREE_CODE (TREE_OPERAND (rhs, 0)) == SSA_NAME
- && TREE_CODE (TREE_OPERAND (rhs, 1)) == INTEGER_CST
- && host_integerp (TREE_OPERAND (rhs, 1), 1))
- {
- ret += tree_low_cst (TREE_OPERAND (rhs, 1), 1);
- lhs = TREE_OPERAND (rhs, 0);
- continue;
- }
+ if (get_gimple_rhs_class (rhs_code) != GIMPLE_SINGLE_RHS)
+ return (unsigned HOST_WIDE_INT) -1;
+ rhs = gimple_assign_rhs1 (stmt);
if (TREE_CODE (counter) != TREE_CODE (rhs))
return (unsigned HOST_WIDE_INT) -1;
@@ -196,6 +193,8 @@ va_list_counter_bump (struct stdarg_info *si, tree counter, tree rhs,
val = ret + counter_val;
while (lhs)
{
+ enum tree_code rhs_code;
+
if (si->offsets[SSA_NAME_VERSION (lhs)] != -1)
break;
@@ -206,31 +205,22 @@ va_list_counter_bump (struct stdarg_info *si, tree counter, tree rhs,
stmt = SSA_NAME_DEF_STMT (lhs);
- rhs = GIMPLE_STMT_OPERAND (stmt, 1);
- if (TREE_CODE (rhs) == WITH_SIZE_EXPR)
- rhs = TREE_OPERAND (rhs, 0);
-
- if (TREE_CODE (rhs) == SSA_NAME)
+ rhs_code = gimple_assign_rhs_code (stmt);
+ if ((get_gimple_rhs_class (rhs_code) == GIMPLE_SINGLE_RHS
+ || gimple_assign_cast_p (stmt))
+ && TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME)
{
- lhs = rhs;
+ lhs = gimple_assign_rhs1 (stmt);
continue;
}
- if (CONVERT_EXPR_P (rhs)
- && TREE_CODE (TREE_OPERAND (rhs, 0)) == SSA_NAME)
+ if ((rhs_code == POINTER_PLUS_EXPR
+ || rhs_code == PLUS_EXPR)
+ && TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME
+ && host_integerp (gimple_assign_rhs2 (stmt), 1))
{
- lhs = TREE_OPERAND (rhs, 0);
- continue;
- }
-
- if ((TREE_CODE (rhs) == POINTER_PLUS_EXPR
- || TREE_CODE (rhs) == PLUS_EXPR)
- && TREE_CODE (TREE_OPERAND (rhs, 0)) == SSA_NAME
- && TREE_CODE (TREE_OPERAND (rhs, 1)) == INTEGER_CST
- && host_integerp (TREE_OPERAND (rhs, 1), 1))
- {
- val -= tree_low_cst (TREE_OPERAND (rhs, 1), 1);
- lhs = TREE_OPERAND (rhs, 0);
+ val -= tree_low_cst (gimple_assign_rhs2 (stmt), 1);
+ lhs = gimple_assign_rhs1 (stmt);
continue;
}
@@ -247,7 +237,7 @@ static tree
find_va_list_reference (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
void *data)
{
- bitmap va_list_vars = (bitmap) data;
+ bitmap va_list_vars = (bitmap) ((struct walk_stmt_info *) data)->info;
tree var = *tp;
if (TREE_CODE (var) == SSA_NAME)
@@ -442,12 +432,6 @@ check_va_list_escapes (struct stdarg_info *si, tree lhs, tree rhs)
if (! POINTER_TYPE_P (TREE_TYPE (rhs)))
return;
- if (((TREE_CODE (rhs) == POINTER_PLUS_EXPR
- || TREE_CODE (rhs) == PLUS_EXPR)
- && TREE_CODE (TREE_OPERAND (rhs, 1)) == INTEGER_CST)
- || CONVERT_EXPR_P (rhs))
- rhs = TREE_OPERAND (rhs, 0);
-
if (TREE_CODE (rhs) != SSA_NAME
|| ! bitmap_bit_p (si->va_list_escape_vars,
DECL_UID (SSA_NAME_VAR (rhs))))
@@ -504,11 +488,12 @@ check_all_va_list_escapes (struct stdarg_info *si)
FOR_EACH_BB (bb)
{
- block_stmt_iterator i;
+ gimple_stmt_iterator i;
- for (i = bsi_start (bb); !bsi_end_p (i); bsi_next (&i))
+ for (i = gsi_start_bb (bb); !gsi_end_p (i); gsi_next (&i))
{
- tree stmt = bsi_stmt (i), use;
+ gimple stmt = gsi_stmt (i);
+ tree use;
ssa_op_iter iter;
FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_ALL_USES)
@@ -517,16 +502,13 @@ check_all_va_list_escapes (struct stdarg_info *si)
DECL_UID (SSA_NAME_VAR (use))))
continue;
- if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT)
+ if (is_gimple_assign (stmt))
{
- tree lhs = GIMPLE_STMT_OPERAND (stmt, 0);
- tree rhs = GIMPLE_STMT_OPERAND (stmt, 1);
-
- if (TREE_CODE (rhs) == WITH_SIZE_EXPR)
- rhs = TREE_OPERAND (rhs, 0);
+ tree rhs = gimple_assign_rhs1 (stmt);
+ enum tree_code rhs_code = gimple_assign_rhs_code (stmt);
/* x = *ap_temp; */
- if (TREE_CODE (rhs) == INDIRECT_REF
+ if (gimple_assign_rhs_code (stmt) == INDIRECT_REF
&& TREE_OPERAND (rhs, 0) == use
&& TYPE_SIZE_UNIT (TREE_TYPE (rhs))
&& host_integerp (TYPE_SIZE_UNIT (TREE_TYPE (rhs)), 1)
@@ -550,13 +532,16 @@ check_all_va_list_escapes (struct stdarg_info *si)
other_ap_temp = (some_type *) ap_temp;
ap = ap_temp;
statements. */
- if ((TREE_CODE (rhs) == POINTER_PLUS_EXPR
- && TREE_CODE (TREE_OPERAND (rhs, 1)) == INTEGER_CST)
- || CONVERT_EXPR_P (rhs))
- rhs = TREE_OPERAND (rhs, 0);
-
- if (rhs == use)
+ if (rhs == use
+ && ((rhs_code == POINTER_PLUS_EXPR
+ && (TREE_CODE (gimple_assign_rhs2 (stmt))
+ == INTEGER_CST))
+ || gimple_assign_cast_p (stmt)
+ || (get_gimple_rhs_class (rhs_code)
+ == GIMPLE_SINGLE_RHS)))
{
+ tree lhs = gimple_assign_lhs (stmt);
+
if (TREE_CODE (lhs) == SSA_NAME
&& bitmap_bit_p (si->va_list_escape_vars,
DECL_UID (SSA_NAME_VAR (lhs))))
@@ -572,7 +557,7 @@ check_all_va_list_escapes (struct stdarg_info *si)
if (dump_file && (dump_flags & TDF_DETAILS))
{
fputs ("va_list escapes in ", dump_file);
- print_generic_expr (dump_file, stmt, dump_flags);
+ print_gimple_stmt (dump_file, stmt, 0, dump_flags);
fputc ('\n', dump_file);
}
return true;
@@ -604,7 +589,9 @@ execute_optimize_stdarg (void)
bool va_list_escapes = false;
bool va_list_simple_ptr;
struct stdarg_info si;
+ struct walk_stmt_info wi;
const char *funcname = NULL;
+ tree cfun_va_list;
cfun->va_list_gpr_size = 0;
cfun->va_list_fpr_size = 0;
@@ -615,25 +602,25 @@ execute_optimize_stdarg (void)
if (dump_file)
funcname = lang_hooks.decl_printable_name (current_function_decl, 2);
- va_list_simple_ptr = POINTER_TYPE_P (va_list_type_node)
- && (TREE_TYPE (va_list_type_node) == void_type_node
- || TREE_TYPE (va_list_type_node) == char_type_node);
- gcc_assert (is_gimple_reg_type (va_list_type_node) == va_list_simple_ptr);
+ cfun_va_list = targetm.fn_abi_va_list (cfun->decl);
+ va_list_simple_ptr = POINTER_TYPE_P (cfun_va_list)
+ && (TREE_TYPE (cfun_va_list) == void_type_node
+ || TREE_TYPE (cfun_va_list) == char_type_node);
+ gcc_assert (is_gimple_reg_type (cfun_va_list) == va_list_simple_ptr);
FOR_EACH_BB (bb)
{
- block_stmt_iterator i;
+ gimple_stmt_iterator i;
- for (i = bsi_start (bb); !bsi_end_p (i); bsi_next (&i))
+ for (i = gsi_start_bb (bb); !gsi_end_p (i); gsi_next (&i))
{
- tree stmt = bsi_stmt (i);
- tree call = get_call_expr_in (stmt), callee;
- tree ap;
+ gimple stmt = gsi_stmt (i);
+ tree callee, ap;
- if (!call)
+ if (!is_gimple_call (stmt))
continue;
- callee = get_callee_fndecl (call);
+ callee = gimple_call_fndecl (stmt);
if (!callee
|| DECL_BUILT_IN_CLASS (callee) != BUILT_IN_NORMAL)
continue;
@@ -653,7 +640,7 @@ execute_optimize_stdarg (void)
}
si.va_start_count++;
- ap = CALL_EXPR_ARG (call, 0);
+ ap = gimple_call_arg (stmt, 0);
if (TREE_CODE (ap) != ADDR_EXPR)
{
@@ -671,7 +658,7 @@ execute_optimize_stdarg (void)
ap = TREE_OPERAND (ap, 0);
}
if (TYPE_MAIN_VARIANT (TREE_TYPE (ap))
- != TYPE_MAIN_VARIANT (va_list_type_node)
+ != TYPE_MAIN_VARIANT (targetm.fn_abi_va_list (cfun->decl))
|| TREE_CODE (ap) != VAR_DECL)
{
va_list_escapes = true;
@@ -729,10 +716,12 @@ execute_optimize_stdarg (void)
cfun->va_list_fpr_size = VA_LIST_MAX_FPR_SIZE;
calculate_dominance_info (CDI_DOMINATORS);
+ memset (&wi, 0, sizeof (wi));
+ wi.info = si.va_list_vars;
FOR_EACH_BB (bb)
{
- block_stmt_iterator i;
+ gimple_stmt_iterator i;
si.compute_sizes = -1;
si.bb = bb;
@@ -743,12 +732,13 @@ execute_optimize_stdarg (void)
any real data movement. */
if (va_list_simple_ptr)
{
- tree phi, lhs, rhs;
+ tree lhs, rhs;
use_operand_p uop;
ssa_op_iter soi;
- for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
+ for (i = gsi_start_phis (bb); !gsi_end_p (i); gsi_next (&i))
{
+ gimple phi = gsi_stmt (i);
lhs = PHI_RESULT (phi);
if (!is_gimple_reg (lhs))
@@ -764,14 +754,12 @@ execute_optimize_stdarg (void)
else
check_va_list_escapes (&si, lhs, rhs);
- if (si.va_list_escapes
- || walk_tree (&phi, find_va_list_reference,
- si.va_list_vars, NULL))
+ if (si.va_list_escapes)
{
if (dump_file && (dump_flags & TDF_DETAILS))
{
fputs ("va_list escapes in ", dump_file);
- print_generic_expr (dump_file, phi, dump_flags);
+ print_gimple_stmt (dump_file, phi, 0, dump_flags);
fputc ('\n', dump_file);
}
va_list_escapes = true;
@@ -780,18 +768,16 @@ execute_optimize_stdarg (void)
}
}
- for (i = bsi_start (bb);
- !bsi_end_p (i) && !va_list_escapes;
- bsi_next (&i))
+ for (i = gsi_start_bb (bb);
+ !gsi_end_p (i) && !va_list_escapes;
+ gsi_next (&i))
{
- tree stmt = bsi_stmt (i);
- tree call;
+ gimple stmt = gsi_stmt (i);
/* Don't look at __builtin_va_{start,end}, they are ok. */
- call = get_call_expr_in (stmt);
- if (call)
+ if (is_gimple_call (stmt))
{
- tree callee = get_callee_fndecl (call);
+ tree callee = gimple_call_fndecl (stmt);
if (callee
&& DECL_BUILT_IN_CLASS (callee) == BUILT_IN_NORMAL
@@ -800,44 +786,54 @@ execute_optimize_stdarg (void)
continue;
}
- if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT)
+ if (is_gimple_assign (stmt))
{
- tree lhs = GIMPLE_STMT_OPERAND (stmt, 0);
- tree rhs = GIMPLE_STMT_OPERAND (stmt, 1);
-
- if (TREE_CODE (rhs) == WITH_SIZE_EXPR)
- rhs = TREE_OPERAND (rhs, 0);
+ tree lhs = gimple_assign_lhs (stmt);
+ tree rhs = gimple_assign_rhs1 (stmt);
if (va_list_simple_ptr)
{
- /* Check for tem = ap. */
- if (va_list_ptr_read (&si, rhs, lhs))
- continue;
+ if (get_gimple_rhs_class (gimple_assign_rhs_code (stmt))
+ == GIMPLE_SINGLE_RHS)
+ {
+ /* Check for tem = ap. */
+ if (va_list_ptr_read (&si, rhs, lhs))
+ continue;
- /* Check for the last insn in:
- tem1 = ap;
- tem2 = tem1 + CST;
- ap = tem2;
- sequence. */
- else if (va_list_ptr_write (&si, lhs, rhs))
- continue;
+ /* Check for the last insn in:
+ tem1 = ap;
+ tem2 = tem1 + CST;
+ ap = tem2;
+ sequence. */
+ else if (va_list_ptr_write (&si, lhs, rhs))
+ continue;
+ }
- else
+ if ((gimple_assign_rhs_code (stmt) == POINTER_PLUS_EXPR
+ && TREE_CODE (gimple_assign_rhs2 (stmt)) == INTEGER_CST)
+ || IS_CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (stmt))
+ || (get_gimple_rhs_class (gimple_assign_rhs_code (stmt))
+ == GIMPLE_SINGLE_RHS))
check_va_list_escapes (&si, lhs, rhs);
}
else
{
- /* Check for ap[0].field = temp. */
- if (va_list_counter_struct_op (&si, lhs, rhs, true))
- continue;
+ if (get_gimple_rhs_class (gimple_assign_rhs_code (stmt))
+ == GIMPLE_SINGLE_RHS)
+ {
+ /* Check for ap[0].field = temp. */
+ if (va_list_counter_struct_op (&si, lhs, rhs, true))
+ continue;
- /* Check for temp = ap[0].field. */
- else if (va_list_counter_struct_op (&si, rhs, lhs, false))
- continue;
+ /* Check for temp = ap[0].field. */
+ else if (va_list_counter_struct_op (&si, rhs, lhs,
+ false))
+ continue;
+ }
/* Do any architecture specific checking. */
- else if (targetm.stdarg_optimize_hook
- && targetm.stdarg_optimize_hook (&si, lhs, rhs))
+ if (targetm.stdarg_optimize_hook
+ && targetm.stdarg_optimize_hook (&si, stmt))
continue;
}
}
@@ -849,13 +845,12 @@ execute_optimize_stdarg (void)
fully), or some unexpected use of va_list. None of these should
happen in a gimplified VA_ARG_EXPR. */
if (si.va_list_escapes
- || walk_tree (&stmt, find_va_list_reference,
- si.va_list_vars, NULL))
+ || walk_gimple_op (stmt, find_va_list_reference, &wi))
{
if (dump_file && (dump_flags & TDF_DETAILS))
{
fputs ("va_list escapes in ", dump_file);
- print_generic_expr (dump_file, stmt, dump_flags);
+ print_gimple_stmt (dump_file, stmt, 0, dump_flags);
fputc ('\n', dump_file);
}
va_list_escapes = true;
diff --git a/gcc/tree-switch-conversion.c b/gcc/tree-switch-conversion.c
index 68d6b50d1bd..8bcfcfde5ca 100644
--- a/gcc/tree-switch-conversion.c
+++ b/gcc/tree-switch-conversion.c
@@ -147,10 +147,10 @@ struct switch_conv_info
/* The first load statement that loads a temporary from a new static array.
*/
- tree arr_ref_first;
+ gimple arr_ref_first;
/* The last load statement that loads a temporary from a new static array. */
- tree arr_ref_last;
+ gimple arr_ref_last;
/* String reason why the case wasn't a good candidate that is written to the
dump file, if there is one. */
@@ -166,22 +166,21 @@ static struct switch_conv_info info;
satisfies the size of the new array. */
static bool
-check_range (tree swtch)
+check_range (gimple swtch)
{
tree min_case, max_case;
- tree cases = SWITCH_LABELS (swtch);
- unsigned int branch_num = TREE_VEC_LENGTH (cases);
+ unsigned int branch_num = gimple_switch_num_labels (swtch);
tree range_max;
/* The gimplifier has already sorted the cases by CASE_LOW and ensured there
is a default label which is the last in the vector. */
- min_case = TREE_VEC_ELT (cases, 0);
+ min_case = gimple_switch_label (swtch, 1);
info.range_min = CASE_LOW (min_case);
gcc_assert (branch_num > 1);
- gcc_assert (CASE_LOW (TREE_VEC_ELT (cases, branch_num - 1)) == NULL_TREE);
- max_case = TREE_VEC_ELT (cases, branch_num - 2);
+ gcc_assert (CASE_LOW (gimple_switch_label (swtch, 0)) == NULL_TREE);
+ max_case = gimple_switch_label (swtch, branch_num - 1);
if (CASE_HIGH (max_case) != NULL_TREE)
range_max = CASE_HIGH (max_case);
else
@@ -283,25 +282,26 @@ check_process_case (tree cs)
static bool
check_final_bb (void)
{
- tree phi;
+ gimple_stmt_iterator gsi;
info.phi_count = 0;
- for (phi = phi_nodes (info.final_bb); phi; phi = PHI_CHAIN (phi))
+ for (gsi = gsi_start_phis (info.final_bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
- int i;
+ gimple phi = gsi_stmt (gsi);
+ unsigned int i;
info.phi_count++;
- for (i = 0; i < PHI_NUM_ARGS (phi); i++)
+ for (i = 0; i < gimple_phi_num_args (phi); i++)
{
- basic_block bb = PHI_ARG_EDGE (phi, i)->src;
+ basic_block bb = gimple_phi_arg_edge (phi, i)->src;
if ((bb == info.switch_bb
|| (single_pred_p (bb) && single_pred (bb) == info.switch_bb))
- && !is_gimple_min_invariant (PHI_ARG_ELT (phi, i).def))
+ && !is_gimple_min_invariant (gimple_phi_arg_def (phi, i)))
{
info.reason = " Non-invariant value from a case\n";
- return false; /* non invariant argument */
+ return false; /* Non-invariant argument. */
}
}
}
@@ -326,10 +326,8 @@ create_temp_arrays (void)
sizeof (tree));
for (i = 0; i < info.phi_count; i++)
- {
- info.constructors[i] = VEC_alloc (constructor_elt, gc,
- tree_low_cst (info.range_size, 1) + 1);
- }
+ info.constructors[i]
+ = VEC_alloc (constructor_elt, gc, tree_low_cst (info.range_size, 1) + 1);
}
/* Free the arrays created by create_temp_arrays(). The vectors that are
@@ -351,10 +349,10 @@ free_temp_arrays (void)
static void
gather_default_values (tree default_case)
{
- tree phi;
+ gimple_stmt_iterator gsi;
basic_block bb = label_to_block (CASE_LABEL (default_case));
edge e;
- int i;
+ int i = 0;
gcc_assert (CASE_LOW (default_case) == NULL_TREE);
@@ -363,11 +361,12 @@ gather_default_values (tree default_case)
else
e = single_succ_edge (bb);
- for (phi = phi_nodes (info.final_bb), i = 0; phi; phi = PHI_CHAIN (phi), i++)
+ for (gsi = gsi_start_phis (info.final_bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
+ gimple phi = gsi_stmt (gsi);
tree val = PHI_ARG_DEF_FROM_EDGE (phi, e);
gcc_assert (val);
- info.default_values[i] = val;
+ info.default_values[i++] = val;
}
}
@@ -376,18 +375,18 @@ gather_default_values (tree default_case)
order of phi nodes. SWTCH is the switch statement being converted. */
static void
-build_constructors (tree swtch)
+build_constructors (gimple swtch)
{
- int i;
- tree cases = SWITCH_LABELS (swtch);
+ unsigned i, branch_num = gimple_switch_num_labels (swtch);
tree pos = info.range_min;
- for (i = 0; i < TREE_VEC_LENGTH (cases) - 1; i++)
+ for (i = 1; i < branch_num; i++)
{
- tree cs = TREE_VEC_ELT (cases, i);
+ tree cs = gimple_switch_label (swtch, i);
basic_block bb = label_to_block (CASE_LABEL (cs));
edge e;
- tree phi, high;
+ tree high;
+ gimple_stmt_iterator gsi;
int j;
if (bb == info.final_bb)
@@ -405,7 +404,8 @@ build_constructors (tree swtch)
elt = VEC_quick_push (constructor_elt,
info.constructors[k], NULL);
- elt->index = int_const_binop (MINUS_EXPR, pos, info.range_min, 0);
+ elt->index = int_const_binop (MINUS_EXPR, pos,
+ info.range_min, 0);
elt->value = info.default_values[k];
}
@@ -418,8 +418,10 @@ build_constructors (tree swtch)
high = CASE_HIGH (cs);
else
high = CASE_LOW (cs);
- for (phi = phi_nodes (info.final_bb); phi; phi = PHI_CHAIN (phi))
+ for (gsi = gsi_start_phis (info.final_bb);
+ !gsi_end_p (gsi); gsi_next (&gsi))
{
+ gimple phi = gsi_stmt (gsi);
tree val = PHI_ARG_DEF_FROM_EDGE (phi, e);
pos = CASE_LOW (cs);
@@ -449,15 +451,12 @@ build_constructors (tree swtch)
is a temporary variable holding the index for loads from the new array. */
static void
-build_one_array (tree swtch, int num, tree arr_index_type, tree phi, tree tidx)
+build_one_array (gimple swtch, int num, tree arr_index_type, gimple phi,
+ tree tidx)
{
- tree array_type;
- tree ctor;
- tree decl;
- tree value_type;
- tree name;
- tree fetch, load;
- block_stmt_iterator bsi;
+ tree array_type, ctor, decl, value_type, name, fetch;
+ gimple load;
+ gimple_stmt_iterator gsi;
gcc_assert (info.default_values[num]);
value_type = TREE_TYPE (info.default_values[num]);
@@ -474,24 +473,23 @@ build_one_array (tree swtch, int num, tree arr_index_type, tree phi, tree tidx)
DECL_ARTIFICIAL (decl) = 1;
TREE_CONSTANT (decl) = 1;
add_referenced_var (decl);
- assemble_variable (decl, 0, 0, 0);
+ varpool_mark_needed_node (varpool_node (decl));
+ varpool_finalize_decl (decl);
mark_sym_for_renaming (decl);
- name = make_ssa_name (SSA_NAME_VAR (PHI_RESULT (phi)), NULL_TREE);
+ name = make_ssa_name (SSA_NAME_VAR (PHI_RESULT (phi)), NULL);
info.target_inbound_names[num] = name;
fetch = build4 (ARRAY_REF, value_type, decl, tidx, NULL_TREE,
NULL_TREE);
- load = build2 (GIMPLE_MODIFY_STMT, void_type_node, name, fetch);
+ load = gimple_build_assign (name, fetch);
SSA_NAME_DEF_STMT (name) = load;
- bsi = bsi_for_stmt (swtch);
- bsi_insert_before (&bsi, load, BSI_SAME_STMT);
+ gsi = gsi_for_stmt (swtch);
+ gsi_insert_before (&gsi, load, GSI_SAME_STMT);
mark_symbols_for_renaming (load);
info.arr_ref_last = load;
-
- return;
}
/* Builds and initializes static arrays initialized with values gathered from
@@ -499,51 +497,53 @@ build_one_array (tree swtch, int num, tree arr_index_type, tree phi, tree tidx)
them. */
static void
-build_arrays (tree swtch)
+build_arrays (gimple swtch)
{
tree arr_index_type;
tree tidx, sub;
- block_stmt_iterator bsi;
- tree phi = phi_nodes (info.final_bb);
+ gimple stmt;
+ gimple_stmt_iterator gsi;
int i;
+ gsi = gsi_for_stmt (swtch);
+
arr_index_type = build_index_type (info.range_size);
tidx = make_rename_temp (arr_index_type, "csti");
- sub = build2 (MINUS_EXPR, TREE_TYPE (info.index_expr), info.index_expr,
- fold_convert (TREE_TYPE (info.index_expr), info.range_min));
- sub = build2 (GIMPLE_MODIFY_STMT, void_type_node, tidx, sub);
-
- bsi = bsi_for_stmt (swtch);
- bsi_insert_before (&bsi, sub, BSI_SAME_STMT);
- mark_symbols_for_renaming (sub);
- info.arr_ref_first = sub;
-
- for (phi = phi_nodes (info.final_bb), i = 0; phi; phi = PHI_CHAIN (phi), i++)
- build_one_array (swtch, i, arr_index_type, phi, tidx);
-
- return;
+ sub = fold_build2 (MINUS_EXPR, TREE_TYPE (info.index_expr), info.index_expr,
+ fold_convert (TREE_TYPE (info.index_expr),
+ info.range_min));
+ sub = force_gimple_operand_gsi (&gsi, fold_convert (arr_index_type, sub),
+ false, NULL, true, GSI_SAME_STMT);
+ stmt = gimple_build_assign (tidx, sub);
+
+ gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
+ mark_symbols_for_renaming (stmt);
+ info.arr_ref_first = stmt;
+
+ for (gsi = gsi_start_phis (info.final_bb), i = 0;
+ !gsi_end_p (gsi); gsi_next (&gsi), i++)
+ build_one_array (swtch, i, arr_index_type, gsi_stmt (gsi), tidx);
}
/* Generates and appropriately inserts loads of default values at the position
given by BSI. Returns the last inserted statement. */
-static tree
-gen_def_assigns (block_stmt_iterator *bsi)
+static gimple
+gen_def_assigns (gimple_stmt_iterator *gsi)
{
int i;
- tree assign = NULL_TREE;
+ gimple assign = NULL;
for (i = 0; i < info.phi_count; i++)
{
- tree name = make_ssa_name (SSA_NAME_VAR (info.target_inbound_names[i]),
- NULL_TREE);
+ tree name
+ = make_ssa_name (SSA_NAME_VAR (info.target_inbound_names[i]), NULL);
info.target_outbound_names[i] = name;
- assign = build2 (GIMPLE_MODIFY_STMT, void_type_node, name,
- info.default_values[i]);
+ assign = gimple_build_assign (name, info.default_values[i]);
SSA_NAME_DEF_STMT (name) = assign;
- bsi_insert_before (bsi, assign, BSI_SAME_STMT);
- find_new_referenced_vars (&assign);
+ gsi_insert_before (gsi, assign, GSI_SAME_STMT);
+ find_new_referenced_vars (assign);
mark_symbols_for_renaming (assign);
}
return assign;
@@ -579,11 +579,13 @@ prune_bbs (basic_block bbd, basic_block final)
static void
fix_phi_nodes (edge e1f, edge e2f, basic_block bbf)
{
- tree phi;
+ gimple_stmt_iterator gsi;
int i;
- for (phi = phi_nodes (bbf), i = 0; phi; phi = PHI_CHAIN (phi), i++)
+ for (gsi = gsi_start_phis (bbf), i = 0;
+ !gsi_end_p (gsi); gsi_next (&gsi), i++)
{
+ gimple phi = gsi_stmt (gsi);
add_phi_arg (phi, info.target_inbound_names[i], e1f);
add_phi_arg (phi, info.target_outbound_names[i], e2f);
}
@@ -612,74 +614,81 @@ fix_phi_nodes (edge e1f, edge e2f, basic_block bbf)
*/
static void
-gen_inbound_check (tree swtch)
+gen_inbound_check (gimple swtch)
{
tree label_decl1 = create_artificial_label ();
tree label_decl2 = create_artificial_label ();
tree label_decl3 = create_artificial_label ();
- tree label1, label2, label3;
+ gimple label1, label2, label3;
- tree utype = unsigned_type_for (TREE_TYPE (info.index_expr));
+ tree utype;
tree tmp_u;
- tree cast, cast_assign;
- tree ulb, minus, minus_assign;
+ tree cast;
+ gimple cast_assign, minus_assign;
+ tree ulb, minus;
tree bound;
- tree if_expr;
+ gimple cond_stmt;
- tree last_assign;
- block_stmt_iterator bsi;
+ gimple last_assign;
+ gimple_stmt_iterator gsi;
basic_block bb0, bb1, bb2, bbf, bbd;
edge e01, e02, e21, e1d, e1f, e2f;
gcc_assert (info.default_values);
- bb0 = bb_for_stmt (swtch);
+ bb0 = gimple_bb (swtch);
+
+ /* Make sure we do not generate arithmetics in a subrange. */
+ if (TREE_TYPE (TREE_TYPE (info.index_expr)))
+ utype = unsigned_type_for (TREE_TYPE (TREE_TYPE (info.index_expr)));
+ else
+ utype = unsigned_type_for (TREE_TYPE (info.index_expr));
/* (end of) block 0 */
- bsi = bsi_for_stmt (info.arr_ref_first);
+ gsi = gsi_for_stmt (info.arr_ref_first);
tmp_u = make_rename_temp (utype, "csui");
- cast = build1 (NOP_EXPR, utype, info.index_expr);
- cast_assign = build2 (GIMPLE_MODIFY_STMT, void_type_node, tmp_u, cast);
- find_new_referenced_vars (&cast_assign);
- bsi_insert_before (&bsi, cast_assign, BSI_SAME_STMT);
+ cast = fold_convert (utype, info.index_expr);
+ cast_assign = gimple_build_assign (tmp_u, cast);
+ find_new_referenced_vars (cast_assign);
+ gsi_insert_before (&gsi, cast_assign, GSI_SAME_STMT);
mark_symbols_for_renaming (cast_assign);
ulb = fold_convert (utype, info.range_min);
- minus = build2 (MINUS_EXPR, utype, tmp_u, ulb);
- minus_assign = build2 (GIMPLE_MODIFY_STMT, void_type_node, tmp_u, minus);
- find_new_referenced_vars (&minus_assign);
- bsi_insert_before (&bsi, minus_assign, BSI_SAME_STMT);
+ minus = fold_build2 (MINUS_EXPR, utype, tmp_u, ulb);
+ minus = force_gimple_operand_gsi (&gsi, minus, false, NULL, true,
+ GSI_SAME_STMT);
+ minus_assign = gimple_build_assign (tmp_u, minus);
+ find_new_referenced_vars (minus_assign);
+ gsi_insert_before (&gsi, minus_assign, GSI_SAME_STMT);
mark_symbols_for_renaming (minus_assign);
bound = fold_convert (utype, info.range_size);
- if_expr = build3 (COND_EXPR, void_type_node,
- build2 (LE_EXPR, boolean_type_node, tmp_u, bound),
- NULL_TREE, NULL_TREE);
+ cond_stmt = gimple_build_cond (LE_EXPR, tmp_u, bound, NULL_TREE, NULL_TREE);
- find_new_referenced_vars (&if_expr);
- bsi_insert_before (&bsi, if_expr, BSI_SAME_STMT);
- mark_symbols_for_renaming (if_expr);
+ find_new_referenced_vars (cond_stmt);
+ gsi_insert_before (&gsi, cond_stmt, GSI_SAME_STMT);
+ mark_symbols_for_renaming (cond_stmt);
/* block 2 */
- bsi = bsi_for_stmt (info.arr_ref_first);
- label2 = build1 (LABEL_EXPR, void_type_node, label_decl2);
- bsi_insert_before (&bsi, label2, BSI_SAME_STMT);
- last_assign = gen_def_assigns (&bsi);
+ gsi = gsi_for_stmt (info.arr_ref_first);
+ label2 = gimple_build_label (label_decl2);
+ gsi_insert_before (&gsi, label2, GSI_SAME_STMT);
+ last_assign = gen_def_assigns (&gsi);
/* block 1 */
- bsi = bsi_for_stmt (info.arr_ref_first);
- label1 = build1 (LABEL_EXPR, void_type_node, label_decl1);
- bsi_insert_before (&bsi, label1, BSI_SAME_STMT);
+ gsi = gsi_for_stmt (info.arr_ref_first);
+ label1 = gimple_build_label (label_decl1);
+ gsi_insert_before (&gsi, label1, GSI_SAME_STMT);
/* block F */
- bsi = bsi_start (info.final_bb);
- label3 = build1 (LABEL_EXPR, void_type_node, label_decl3);
- bsi_insert_before (&bsi, label3, BSI_SAME_STMT);
+ gsi = gsi_start_bb (info.final_bb);
+ label3 = gimple_build_label (label_decl3);
+ gsi_insert_before (&gsi, label3, GSI_SAME_STMT);
/* cfg fix */
- e02 = split_block (bb0, if_expr);
+ e02 = split_block (bb0, cond_stmt);
bb2 = e02->dest;
e21 = split_block (bb2, last_assign);
@@ -716,8 +725,8 @@ gen_inbound_check (tree swtch)
bb2->frequency = EDGE_FREQUENCY (e02);
bbf->frequency = EDGE_FREQUENCY (e1f) + EDGE_FREQUENCY (e2f);
- prune_bbs (bbd, info.final_bb); /* to keep calc_dfs_tree() in dominance.c
- happy */
+ prune_bbs (bbd, info.final_bb); /* To keep calc_dfs_tree() in dominance.c
+ happy. */
fix_phi_nodes (e1f, e2f, bbf);
@@ -730,31 +739,24 @@ gen_inbound_check (tree swtch)
one after another until one fails or the conversion is completed. */
static bool
-process_switch (tree swtch)
+process_switch (gimple swtch)
{
- int i;
- tree cases;
+ unsigned int i, branch_num = gimple_switch_num_labels (swtch);
tree index_type;
/* Operand 2 is either NULL_TREE or a vector of cases (stmt.c). */
- if (TREE_OPERAND (swtch, 2) == NULL_TREE)
+ if (branch_num < 2)
{
- info.reason = "swtch has no labels\n";
+ info.reason = "switch has no labels\n";
return false;
}
- /* Comment from stmt.c:
- The switch body is lowered in gimplify.c, we should never have switches
- with a non-NULL SWITCH_BODY here. */
- gcc_assert (!SWITCH_BODY (swtch));
-
- cases = SWITCH_LABELS (swtch);
info.final_bb = NULL;
- info.switch_bb = bb_for_stmt (swtch);
- info.index_expr = SWITCH_COND (swtch);
+ info.switch_bb = gimple_bb (swtch);
+ info.index_expr = gimple_switch_index (swtch);
index_type = TREE_TYPE (info.index_expr);
- info.arr_ref_first = NULL_TREE;
- info.arr_ref_last = NULL_TREE;
+ info.arr_ref_first = NULL;
+ info.arr_ref_last = NULL;
info.default_prob = 0;
info.default_count = 0;
info.other_count = 0;
@@ -773,16 +775,13 @@ process_switch (tree swtch)
/* For all the cases, see whether they are empty, the assignments they
represent constant and so on... */
- for (i = 0; i < TREE_VEC_LENGTH (cases); i++)
- {
- tree part_case = TREE_VEC_ELT (cases, i);
- if (!check_process_case (part_case))
- {
- if (dump_file)
- fprintf (dump_file, "Processing of case %i failed\n", i);
- return false;
- }
- }
+ for (i = 0; i < branch_num; i++)
+ if (!check_process_case (gimple_switch_label (swtch, i)))
+ {
+ if (dump_file)
+ fprintf (dump_file, "Processing of case %i failed\n", i);
+ return false;
+ }
if (!check_final_bb ())
return false;
@@ -791,7 +790,7 @@ process_switch (tree swtch)
transformation. */
create_temp_arrays ();
- gather_default_values (TREE_VEC_ELT (cases, TREE_VEC_LENGTH (cases) - 1));
+ gather_default_values (gimple_switch_label (swtch, 0));
build_constructors (swtch);
build_arrays (swtch); /* Build the static arrays and assignments. */
@@ -812,17 +811,17 @@ do_switchconv (void)
FOR_EACH_BB (bb)
{
- tree stmt = last_stmt (bb);
- if (stmt && TREE_CODE (stmt) == SWITCH_EXPR)
+ gimple stmt = last_stmt (bb);
+ if (stmt && gimple_code (stmt) == GIMPLE_SWITCH)
{
- expanded_location loc = expand_location (EXPR_LOCATION (stmt));
-
if (dump_file)
{
+ expanded_location loc = expand_location (gimple_location (stmt));
+
fprintf (dump_file, "beginning to process the following "
"SWITCH statement (%s:%d) : ------- \n",
loc.file, loc.line);
- print_generic_stmt (dump_file, stmt, 2);
+ print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
fprintf (dump_file, "\n");
}
diff --git a/gcc/tree-tailcall.c b/gcc/tree-tailcall.c
index 09a2eafe119..78bf1550d2b 100644
--- a/gcc/tree-tailcall.c
+++ b/gcc/tree-tailcall.c
@@ -100,11 +100,8 @@ along with GCC; see the file COPYING3. If not see
struct tailcall
{
- /* The block in that the call occur. */
- basic_block call_block;
-
/* The iterator pointing to the call statement. */
- block_stmt_iterator call_bsi;
+ gimple_stmt_iterator call_gsi;
/* True if it is a call to the current function. */
bool tail_recursion;
@@ -138,14 +135,14 @@ suitable_for_tail_opt_p (void)
if (cfun->stdarg)
return false;
- /* No local variable nor structure field should be call-clobbered. We
+ /* No local variable nor structure field should be call-used. We
ignore any kind of memory tag, as these are not real variables. */
FOR_EACH_REFERENCED_VAR (var, rvi)
{
if (!is_global_var (var)
&& !MTAG_P (var)
- && (gimple_aliases_computed_p (cfun) ? is_call_clobbered (var)
+ && (gimple_aliases_computed_p (cfun)? is_call_used (var)
: TREE_ADDRESSABLE (var)))
return false;
}
@@ -191,13 +188,13 @@ suitable_for_tail_call_opt_p (void)
}
/* Checks whether the expression EXPR in stmt AT is independent of the
- statement pointed to by BSI (in a sense that we already know EXPR's value
- at BSI). We use the fact that we are only called from the chain of
+ statement pointed to by GSI (in a sense that we already know EXPR's value
+ at GSI). We use the fact that we are only called from the chain of
basic blocks that have only single successor. Returns the expression
- containing the value of EXPR at BSI. */
+ containing the value of EXPR at GSI. */
static tree
-independent_of_stmt_p (tree expr, tree at, block_stmt_iterator bsi)
+independent_of_stmt_p (tree expr, gimple at, gimple_stmt_iterator gsi)
{
basic_block bb, call_bb, at_bb;
edge e;
@@ -210,8 +207,8 @@ independent_of_stmt_p (tree expr, tree at, block_stmt_iterator bsi)
return NULL_TREE;
/* Mark the blocks in the chain leading to the end. */
- at_bb = bb_for_stmt (at);
- call_bb = bb_for_stmt (bsi_stmt (bsi));
+ at_bb = gimple_bb (at);
+ call_bb = gimple_bb (gsi_stmt (gsi));
for (bb = call_bb; bb != at_bb; bb = single_succ (bb))
bb->aux = &bb->aux;
bb->aux = &bb->aux;
@@ -219,7 +216,7 @@ independent_of_stmt_p (tree expr, tree at, block_stmt_iterator bsi)
while (1)
{
at = SSA_NAME_DEF_STMT (expr);
- bb = bb_for_stmt (at);
+ bb = gimple_bb (at);
/* The default definition or defined before the chain. */
if (!bb || !bb->aux)
@@ -227,16 +224,16 @@ independent_of_stmt_p (tree expr, tree at, block_stmt_iterator bsi)
if (bb == call_bb)
{
- for (; !bsi_end_p (bsi); bsi_next (&bsi))
- if (bsi_stmt (bsi) == at)
+ for (; !gsi_end_p (gsi); gsi_next (&gsi))
+ if (gsi_stmt (gsi) == at)
break;
- if (!bsi_end_p (bsi))
+ if (!gsi_end_p (gsi))
expr = NULL_TREE;
break;
}
- if (TREE_CODE (at) != PHI_NODE)
+ if (gimple_code (at) != GIMPLE_PHI)
{
expr = NULL_TREE;
break;
@@ -263,27 +260,33 @@ independent_of_stmt_p (tree expr, tree at, block_stmt_iterator bsi)
return expr;
}
-/* Simulates the effect of an assignment of ASS in STMT on the return value
- of the tail recursive CALL passed in ASS_VAR. M and A are the
- multiplicative and the additive factor for the real return value. */
+/* Simulates the effect of an assignment STMT on the return value of the tail
+ recursive CALL passed in ASS_VAR. M and A are the multiplicative and the
+ additive factor for the real return value. */
static bool
-process_assignment (tree ass, tree stmt, block_stmt_iterator call, tree *m,
+process_assignment (gimple stmt, gimple_stmt_iterator call, tree *m,
tree *a, tree *ass_var)
{
tree op0, op1, non_ass_var;
- tree dest = GIMPLE_STMT_OPERAND (ass, 0);
- tree src = GIMPLE_STMT_OPERAND (ass, 1);
- enum tree_code code = TREE_CODE (src);
- tree src_var = src;
-
+ tree dest = gimple_assign_lhs (stmt);
+ enum tree_code code = gimple_assign_rhs_code (stmt);
+ enum gimple_rhs_class rhs_class = get_gimple_rhs_class (code);
+ tree src_var = gimple_assign_rhs1 (stmt);
+
/* See if this is a simple copy operation of an SSA name to the function
result. In that case we may have a simple tail call. Ignore type
conversions that can never produce extra code between the function
call and the function return. */
- STRIP_NOPS (src_var);
- if (TREE_CODE (src_var) == SSA_NAME)
+ if ((rhs_class == GIMPLE_SINGLE_RHS || gimple_assign_cast_p (stmt))
+ && (TREE_CODE (src_var) == SSA_NAME))
{
+ /* Reject a tailcall if the type conversion might need
+ additional code. */
+ if (IS_CONVERT_EXPR_CODE_P (code)
+ && TYPE_MODE (TREE_TYPE (dest)) != TYPE_MODE (TREE_TYPE (src_var)))
+ return false;
+
if (src_var != *ass_var)
return false;
@@ -291,7 +294,7 @@ process_assignment (tree ass, tree stmt, block_stmt_iterator call, tree *m,
return true;
}
- if (TREE_CODE_CLASS (code) != tcc_binary)
+ if (rhs_class != GIMPLE_BINARY_RHS)
return false;
/* Accumulator optimizations will reverse the order of operations.
@@ -311,8 +314,8 @@ process_assignment (tree ass, tree stmt, block_stmt_iterator call, tree *m,
TODO -- Extend it for cases where the linear transformation of the output
is expressed in a more complicated way. */
- op0 = TREE_OPERAND (src, 0);
- op1 = TREE_OPERAND (src, 1);
+ op0 = gimple_assign_rhs1 (stmt);
+ op1 = gimple_assign_rhs2 (stmt);
if (op0 == *ass_var
&& (non_ass_var = independent_of_stmt_p (op1, stmt, call)))
@@ -346,7 +349,8 @@ process_assignment (tree ass, tree stmt, block_stmt_iterator call, tree *m,
*ass_var = dest;
return true;
- /* TODO -- Handle other codes (NEGATE_EXPR, MINUS_EXPR, POINTER_PLUS_EXPR). */
+ /* TODO -- Handle other codes (NEGATE_EXPR, MINUS_EXPR,
+ POINTER_PLUS_EXPR). */
default:
return false;
@@ -359,12 +363,14 @@ static tree
propagate_through_phis (tree var, edge e)
{
basic_block dest = e->dest;
- tree phi;
-
- for (phi = phi_nodes (dest); phi; phi = PHI_CHAIN (phi))
- if (PHI_ARG_DEF_FROM_EDGE (phi, e) == var)
- return PHI_RESULT (phi);
-
+ gimple_stmt_iterator gsi;
+
+ for (gsi = gsi_start_phis (dest); !gsi_end_p (gsi); gsi_next (&gsi))
+ {
+ gimple phi = gsi_stmt (gsi);
+ if (PHI_ARG_DEF_FROM_EDGE (phi, e) == var)
+ return PHI_RESULT (phi);
+ }
return var;
}
@@ -374,52 +380,44 @@ propagate_through_phis (tree var, edge e)
static void
find_tail_calls (basic_block bb, struct tailcall **ret)
{
- tree ass_var, ret_var, stmt, func, param, call = NULL_TREE;
- block_stmt_iterator bsi, absi;
+ tree ass_var = NULL_TREE, ret_var, func, param;
+ gimple stmt, call = NULL;
+ gimple_stmt_iterator gsi, agsi;
bool tail_recursion;
struct tailcall *nw;
edge e;
tree m, a;
basic_block abb;
- stmt_ann_t ann;
+ size_t idx;
if (!single_succ_p (bb))
return;
- for (bsi = bsi_last (bb); !bsi_end_p (bsi); bsi_prev (&bsi))
+ for (gsi = gsi_last_bb (bb); !gsi_end_p (gsi); gsi_prev (&gsi))
{
- stmt = bsi_stmt (bsi);
+ stmt = gsi_stmt (gsi);
/* Ignore labels. */
- if (TREE_CODE (stmt) == LABEL_EXPR)
+ if (gimple_code (stmt) == GIMPLE_LABEL)
continue;
/* Check for a call. */
- if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT)
- {
- ass_var = GIMPLE_STMT_OPERAND (stmt, 0);
- call = GIMPLE_STMT_OPERAND (stmt, 1);
- if (TREE_CODE (call) == WITH_SIZE_EXPR)
- call = TREE_OPERAND (call, 0);
- }
- else
+ if (is_gimple_call (stmt))
{
- ass_var = NULL_TREE;
call = stmt;
+ ass_var = gimple_call_lhs (stmt);
+ break;
}
- if (TREE_CODE (call) == CALL_EXPR)
- break;
-
/* If the statement has virtual or volatile operands, fail. */
- ann = stmt_ann (stmt);
if (!ZERO_SSA_OPERANDS (stmt, (SSA_OP_VUSE | SSA_OP_VIRTUAL_DEFS))
- || ann->has_volatile_ops
- || (!gimple_aliases_computed_p (cfun) && ann->references_memory))
+ || gimple_has_volatile_ops (stmt)
+ || (!gimple_aliases_computed_p (cfun)
+ && gimple_references_memory_p (stmt)))
return;
}
- if (bsi_end_p (bsi))
+ if (gsi_end_p (gsi))
{
edge_iterator ei;
/* Recurse to the predecessors. */
@@ -445,16 +443,15 @@ find_tail_calls (basic_block bb, struct tailcall **ret)
/* We found the call, check whether it is suitable. */
tail_recursion = false;
- func = get_callee_fndecl (call);
+ func = gimple_call_fndecl (call);
if (func == current_function_decl)
{
- call_expr_arg_iterator iter;
tree arg;
- for (param = DECL_ARGUMENTS (func),
- arg = first_call_expr_arg (call, &iter);
- param && arg;
- param = TREE_CHAIN (param), arg = next_call_expr_arg (&iter))
+ for (param = DECL_ARGUMENTS (func), idx = 0;
+ param && idx < gimple_call_num_args (call);
+ param = TREE_CHAIN (param), idx ++)
{
+ arg = gimple_call_arg (call, idx);
if (param != arg)
{
/* Make sure there are no problems with copying. The parameter
@@ -463,7 +460,7 @@ find_tail_calls (basic_block bb, struct tailcall **ret)
we emitted a suitable type conversion statement. */
if (!is_gimple_reg_type (TREE_TYPE (param))
|| !useless_type_conversion_p (TREE_TYPE (param),
- TREE_TYPE (arg)))
+ TREE_TYPE (arg)))
break;
/* The parameter should be a real operand, so that phi node
@@ -471,13 +468,13 @@ find_tail_calls (basic_block bb, struct tailcall **ret)
of copying the value. This test implies is_gimple_reg_type
from the previous condition, however this one could be
relaxed by being more careful with copying the new value
- of the parameter (emitting appropriate GIMPLE_MODIFY_STMT and
+ of the parameter (emitting appropriate GIMPLE_ASSIGN and
updating the virtual operands). */
if (!is_gimple_reg (param))
break;
}
}
- if (!arg && !param)
+ if (idx == gimple_call_num_args (call) && !param)
tail_recursion = true;
}
@@ -489,48 +486,36 @@ find_tail_calls (basic_block bb, struct tailcall **ret)
a = NULL_TREE;
abb = bb;
- absi = bsi;
+ agsi = gsi;
while (1)
{
- bsi_next (&absi);
+ gsi_next (&agsi);
- while (bsi_end_p (absi))
+ while (gsi_end_p (agsi))
{
ass_var = propagate_through_phis (ass_var, single_succ_edge (abb));
abb = single_succ (abb);
- absi = bsi_start (abb);
+ agsi = gsi_start_bb (abb);
}
- stmt = bsi_stmt (absi);
+ stmt = gsi_stmt (agsi);
- if (TREE_CODE (stmt) == LABEL_EXPR)
+ if (gimple_code (stmt) == GIMPLE_LABEL)
continue;
- if (TREE_CODE (stmt) == RETURN_EXPR)
+ if (gimple_code (stmt) == GIMPLE_RETURN)
break;
- if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT)
+ if (gimple_code (stmt) != GIMPLE_ASSIGN)
return;
- if (!process_assignment (stmt, stmt, bsi, &m, &a, &ass_var))
+ /* This is a gimple assign. */
+ if (! process_assignment (stmt, gsi, &m, &a, &ass_var))
return;
}
/* See if this is a tail call we can handle. */
- ret_var = TREE_OPERAND (stmt, 0);
- if (ret_var
- && TREE_CODE (ret_var) == GIMPLE_MODIFY_STMT)
- {
- tree ret_op = GIMPLE_STMT_OPERAND (ret_var, 1);
- STRIP_NOPS (ret_op);
- if (!tail_recursion
- && TREE_CODE (ret_op) != SSA_NAME)
- return;
-
- if (!process_assignment (ret_var, stmt, bsi, &m, &a, &ass_var))
- return;
- ret_var = GIMPLE_STMT_OPERAND (ret_var, 0);
- }
+ ret_var = gimple_return_retval (stmt);
/* We may proceed if there either is no return value, or the return value
is identical to the call's return. */
@@ -545,8 +530,7 @@ find_tail_calls (basic_block bb, struct tailcall **ret)
nw = XNEW (struct tailcall);
- nw->call_block = bb;
- nw->call_bsi = bsi;
+ nw->call_gsi = gsi;
nw->tail_recursion = tail_recursion;
@@ -557,15 +541,70 @@ find_tail_calls (basic_block bb, struct tailcall **ret)
*ret = nw;
}
-/* Adjust the accumulator values according to A and M after BSI, and update
- the phi nodes on edge BACK. */
+/* Helper to insert PHI_ARGH to the phi of VAR in the destination of edge E. */
static void
-adjust_accumulator_values (block_stmt_iterator bsi, tree m, tree a, edge back)
+add_successor_phi_arg (edge e, tree var, tree phi_arg)
+{
+ gimple_stmt_iterator gsi;
+
+ for (gsi = gsi_start_phis (e->dest); !gsi_end_p (gsi); gsi_next (&gsi))
+ if (PHI_RESULT (gsi_stmt (gsi)) == var)
+ break;
+
+ gcc_assert (!gsi_end_p (gsi));
+ add_phi_arg (gsi_stmt (gsi), phi_arg, e);
+}
+
+/* Creates a GIMPLE statement which computes the operation specified by
+ CODE, OP0 and OP1 to a new variable with name LABEL and inserts the
+ statement in the position specified by GSI and UPDATE. Returns the
+ tree node of the statement's result. */
+
+static tree
+adjust_return_value_with_ops (enum tree_code code, const char *label,
+ tree op0, tree op1, gimple_stmt_iterator gsi,
+ enum gsi_iterator_update update)
{
- tree stmt, var, phi, tmp;
+
tree ret_type = TREE_TYPE (DECL_RESULT (current_function_decl));
- tree a_acc_arg = a_acc, m_acc_arg = m_acc;
+ tree tmp = create_tmp_var (ret_type, label);
+ gimple stmt = gimple_build_assign_with_ops (code, tmp, op0, op1);
+ tree result;
+
+ add_referenced_var (tmp);
+ result = make_ssa_name (tmp, stmt);
+ gimple_assign_set_lhs (stmt, result);
+ update_stmt (stmt);
+ gsi_insert_before (&gsi, stmt, update);
+ return result;
+}
+
+/* Creates a new GIMPLE statement that adjusts the value of accumulator ACC by
+ the computation specified by CODE and OP1 and insert the statement
+ at the position specified by GSI as a new statement. Returns new SSA name
+ of updated accumulator. */
+
+static tree
+update_accumulator_with_ops (enum tree_code code, tree acc, tree op1,
+ gimple_stmt_iterator gsi)
+{
+ gimple stmt = gimple_build_assign_with_ops (code, SSA_NAME_VAR (acc), acc,
+ op1);
+ tree var = make_ssa_name (SSA_NAME_VAR (acc), stmt);
+ gimple_assign_set_lhs (stmt, var);
+ update_stmt (stmt);
+ gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
+ return var;
+}
+
+/* Adjust the accumulator values according to A and M after GSI, and update
+ the phi nodes on edge BACK. */
+
+static void
+adjust_accumulator_values (gimple_stmt_iterator gsi, tree m, tree a, edge back)
+{
+ tree var, a_acc_arg = a_acc, m_acc_arg = m_acc;
if (a)
{
@@ -574,58 +613,23 @@ adjust_accumulator_values (block_stmt_iterator bsi, tree m, tree a, edge back)
if (integer_onep (a))
var = m_acc;
else
- {
- stmt = build_gimple_modify_stmt (NULL_TREE,
- build2 (MULT_EXPR, ret_type,
- m_acc, a));
-
- tmp = create_tmp_var (ret_type, "acc_tmp");
- add_referenced_var (tmp);
-
- var = make_ssa_name (tmp, stmt);
- GIMPLE_STMT_OPERAND (stmt, 0) = var;
- bsi_insert_after (&bsi, stmt, BSI_NEW_STMT);
- }
+ var = adjust_return_value_with_ops (MULT_EXPR, "acc_tmp", m_acc,
+ a, gsi, GSI_NEW_STMT);
}
else
var = a;
- stmt = build_gimple_modify_stmt (NULL_TREE, build2 (PLUS_EXPR, ret_type,
- a_acc, var));
- var = make_ssa_name (SSA_NAME_VAR (a_acc), stmt);
- GIMPLE_STMT_OPERAND (stmt, 0) = var;
- bsi_insert_after (&bsi, stmt, BSI_NEW_STMT);
- a_acc_arg = var;
+ a_acc_arg = update_accumulator_with_ops (PLUS_EXPR, a_acc, var, gsi);
}
if (m)
- {
- stmt = build_gimple_modify_stmt (NULL_TREE,
- build2 (MULT_EXPR, ret_type,
- m_acc, m));
- var = make_ssa_name (SSA_NAME_VAR (m_acc), stmt);
- GIMPLE_STMT_OPERAND (stmt, 0) = var;
- bsi_insert_after (&bsi, stmt, BSI_NEW_STMT);
- m_acc_arg = var;
- }
+ m_acc_arg = update_accumulator_with_ops (MULT_EXPR, m_acc, m, gsi);
if (a_acc)
- {
- for (phi = phi_nodes (back->dest); phi; phi = PHI_CHAIN (phi))
- if (PHI_RESULT (phi) == a_acc)
- break;
-
- add_phi_arg (phi, a_acc_arg, back);
- }
+ add_successor_phi_arg (back, a_acc, a_acc_arg);
if (m_acc)
- {
- for (phi = phi_nodes (back->dest); phi; phi = PHI_CHAIN (phi))
- if (PHI_RESULT (phi) == m_acc)
- break;
-
- add_phi_arg (phi, m_acc_arg, back);
- }
+ add_successor_phi_arg (back, m_acc, m_acc_arg);
}
/* Adjust value of the return at the end of BB according to M and A
@@ -634,56 +638,23 @@ adjust_accumulator_values (block_stmt_iterator bsi, tree m, tree a, edge back)
static void
adjust_return_value (basic_block bb, tree m, tree a)
{
- tree ret_stmt = last_stmt (bb), ret_var, var, stmt, tmp;
- tree ret_type = TREE_TYPE (DECL_RESULT (current_function_decl));
- tree *ret_op;
- block_stmt_iterator bsi = bsi_last (bb);
+ tree retval;
+ gimple ret_stmt = gimple_seq_last_stmt (bb_seq (bb));
+ gimple_stmt_iterator gsi = gsi_last_bb (bb);
- gcc_assert (TREE_CODE (ret_stmt) == RETURN_EXPR);
+ gcc_assert (gimple_code (ret_stmt) == GIMPLE_RETURN);
- ret_var = TREE_OPERAND (ret_stmt, 0);
- if (!ret_var)
+ retval = gimple_return_retval (ret_stmt);
+ if (!retval || retval == error_mark_node)
return;
- if (TREE_CODE (ret_var) == GIMPLE_MODIFY_STMT)
- {
- ret_op = &GIMPLE_STMT_OPERAND (ret_var, 1);
- ret_var = *ret_op;
- }
- else
- ret_op = &TREE_OPERAND (ret_stmt, 0);
-
if (m)
- {
- stmt = build_gimple_modify_stmt (NULL_TREE,
- build2 (MULT_EXPR, ret_type,
- m_acc, ret_var));
-
- tmp = create_tmp_var (ret_type, "acc_tmp");
- add_referenced_var (tmp);
-
- var = make_ssa_name (tmp, stmt);
- GIMPLE_STMT_OPERAND (stmt, 0) = var;
- bsi_insert_before (&bsi, stmt, BSI_SAME_STMT);
- }
- else
- var = ret_var;
-
+ retval = adjust_return_value_with_ops (MULT_EXPR, "mul_tmp", m_acc, retval,
+ gsi, GSI_SAME_STMT);
if (a)
- {
- stmt = build_gimple_modify_stmt (NULL_TREE,
- build2 (PLUS_EXPR, ret_type,
- a_acc, var));
-
- tmp = create_tmp_var (ret_type, "acc_tmp");
- add_referenced_var (tmp);
-
- var = make_ssa_name (tmp, stmt);
- GIMPLE_STMT_OPERAND (stmt, 0) = var;
- bsi_insert_before (&bsi, stmt, BSI_SAME_STMT);
- }
-
- *ret_op = var;
+ retval = adjust_return_value_with_ops (PLUS_EXPR, "acc_tmp", a_acc, retval,
+ gsi, GSI_SAME_STMT);
+ gimple_return_set_retval (ret_stmt, retval);
update_stmt (ret_stmt);
}
@@ -735,90 +706,92 @@ arg_needs_copy_p (tree param)
static void
eliminate_tail_call (struct tailcall *t)
{
- tree param, stmt, rslt, call;
+ tree param, rslt;
+ gimple stmt, call;
tree arg;
- call_expr_arg_iterator iter;
+ size_t idx;
basic_block bb, first;
edge e;
- tree phi;
- block_stmt_iterator bsi;
- tree orig_stmt;
+ gimple phi;
+ gimple_stmt_iterator gsi;
+ gimple orig_stmt;
- stmt = orig_stmt = bsi_stmt (t->call_bsi);
- bb = t->call_block;
+ stmt = orig_stmt = gsi_stmt (t->call_gsi);
+ bb = gsi_bb (t->call_gsi);
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "Eliminated tail recursion in bb %d : ",
bb->index);
- print_generic_stmt (dump_file, stmt, TDF_SLIM);
+ print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
fprintf (dump_file, "\n");
}
- if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT)
- stmt = GIMPLE_STMT_OPERAND (stmt, 1);
+ gcc_assert (is_gimple_call (stmt));
first = single_succ (ENTRY_BLOCK_PTR);
- /* Remove the code after call_bsi that will become unreachable. The
+ /* Remove the code after call_gsi that will become unreachable. The
possibly unreachable code in other blocks is removed later in
cfg cleanup. */
- bsi = t->call_bsi;
- bsi_next (&bsi);
- while (!bsi_end_p (bsi))
+ gsi = t->call_gsi;
+ gsi_next (&gsi);
+ while (!gsi_end_p (gsi))
{
- tree t = bsi_stmt (bsi);
+ gimple t = gsi_stmt (gsi);
/* Do not remove the return statement, so that redirect_edge_and_branch
sees how the block ends. */
- if (TREE_CODE (t) == RETURN_EXPR)
+ if (gimple_code (t) == GIMPLE_RETURN)
break;
- bsi_remove (&bsi, true);
+ gsi_remove (&gsi, true);
release_defs (t);
}
/* Number of executions of function has reduced by the tailcall. */
- e = single_succ_edge (t->call_block);
+ e = single_succ_edge (gsi_bb (t->call_gsi));
decrease_profile (EXIT_BLOCK_PTR, e->count, EDGE_FREQUENCY (e));
decrease_profile (ENTRY_BLOCK_PTR, e->count, EDGE_FREQUENCY (e));
if (e->dest != EXIT_BLOCK_PTR)
decrease_profile (e->dest, e->count, EDGE_FREQUENCY (e));
/* Replace the call by a jump to the start of function. */
- e = redirect_edge_and_branch (single_succ_edge (t->call_block), first);
+ e = redirect_edge_and_branch (single_succ_edge (gsi_bb (t->call_gsi)),
+ first);
gcc_assert (e);
- PENDING_STMT (e) = NULL_TREE;
+ PENDING_STMT (e) = NULL;
/* Add phi node entries for arguments. The ordering of the phi nodes should
be the same as the ordering of the arguments. */
for (param = DECL_ARGUMENTS (current_function_decl),
- arg = first_call_expr_arg (stmt, &iter),
- phi = phi_nodes (first);
+ idx = 0, gsi = gsi_start_phis (first);
param;
- param = TREE_CHAIN (param), arg = next_call_expr_arg (&iter))
+ param = TREE_CHAIN (param), idx++)
{
if (!arg_needs_copy_p (param))
continue;
+
+ arg = gimple_call_arg (stmt, idx);
+ phi = gsi_stmt (gsi);
gcc_assert (param == SSA_NAME_VAR (PHI_RESULT (phi)));
add_phi_arg (phi, arg, e);
- phi = PHI_CHAIN (phi);
+ gsi_next (&gsi);
}
/* Update the values of accumulators. */
- adjust_accumulator_values (t->call_bsi, t->mult, t->add, e);
+ adjust_accumulator_values (t->call_gsi, t->mult, t->add, e);
- call = bsi_stmt (t->call_bsi);
- if (TREE_CODE (call) == GIMPLE_MODIFY_STMT)
+ call = gsi_stmt (t->call_gsi);
+ rslt = gimple_call_lhs (call);
+ if (rslt != NULL_TREE)
{
- rslt = GIMPLE_STMT_OPERAND (call, 0);
-
/* Result of the call will no longer be defined. So adjust the
SSA_NAME_DEF_STMT accordingly. */
- SSA_NAME_DEF_STMT (rslt) = build_empty_stmt ();
+ SSA_NAME_DEF_STMT (rslt) = gimple_build_nop ();
}
- bsi_remove (&t->call_bsi, true);
+ gsi_remove (&t->call_gsi, true);
release_defs (call);
}
@@ -866,21 +839,40 @@ optimize_tail_call (struct tailcall *t, bool opt_tailcalls)
if (opt_tailcalls)
{
- tree stmt = bsi_stmt (t->call_bsi);
+ gimple stmt = gsi_stmt (t->call_gsi);
- stmt = get_call_expr_in (stmt);
- CALL_EXPR_TAILCALL (stmt) = 1;
+ gimple_call_set_tail (stmt, true);
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "Found tail call ");
- print_generic_expr (dump_file, stmt, dump_flags);
- fprintf (dump_file, " in bb %i\n", t->call_block->index);
+ print_gimple_stmt (dump_file, stmt, 0, dump_flags);
+ fprintf (dump_file, " in bb %i\n", (gsi_bb (t->call_gsi))->index);
}
}
return false;
}
+/* Creates a tail-call accumulator of the same type as the return type of the
+ current function. LABEL is the name used to creating the temporary
+ variable for the accumulator. The accumulator will be inserted in the
+ phis of a basic block BB with single predecessor with an initial value
+ INIT converted to the current function return type. */
+
+static tree
+create_tailcall_accumulator (const char *label, basic_block bb, tree init)
+{
+ tree ret_type = TREE_TYPE (DECL_RESULT (current_function_decl));
+ tree tmp = create_tmp_var (ret_type, label);
+ gimple phi;
+
+ add_referenced_var (tmp);
+ phi = create_phi_node (tmp, bb);
+ /* RET_TYPE can be a float when -ffast-maths is enabled. */
+ add_phi_arg (phi, fold_convert (ret_type, init), single_pred_edge (bb));
+ return PHI_RESULT (phi);
+}
+
/* Optimizes tail calls in the function, turning the tail recursion
into iteration. */
@@ -892,7 +884,8 @@ tree_optimize_tail_calls_1 (bool opt_tailcalls)
struct tailcall *tailcalls = NULL, *act, *next;
bool changed = false;
basic_block first = single_succ (ENTRY_BLOCK_PTR);
- tree stmt, param, ret_type, tmp, phi;
+ tree param;
+ gimple stmt;
edge_iterator ei;
if (!suitable_for_tail_opt_p ())
@@ -907,7 +900,7 @@ tree_optimize_tail_calls_1 (bool opt_tailcalls)
stmt = last_stmt (e->src);
if (stmt
- && TREE_CODE (stmt) == RETURN_EXPR)
+ && gimple_code (stmt) == GIMPLE_RETURN)
find_tail_calls (e->src, &tailcalls);
}
@@ -932,7 +925,7 @@ tree_optimize_tail_calls_1 (bool opt_tailcalls)
{
tree name = gimple_default_def (cfun, param);
tree new_name = make_ssa_name (param, SSA_NAME_DEF_STMT (name));
- tree phi;
+ gimple phi;
set_default_def (param, new_name);
phi = create_phi_node (name, first);
@@ -943,44 +936,12 @@ tree_optimize_tail_calls_1 (bool opt_tailcalls)
}
if (act->add && !a_acc)
- {
- ret_type = TREE_TYPE (DECL_RESULT (current_function_decl));
-
- tmp = create_tmp_var (ret_type, "add_acc");
- add_referenced_var (tmp);
-
- phi = create_phi_node (tmp, first);
- add_phi_arg (phi,
- /* RET_TYPE can be a float when -ffast-maths is
- enabled. */
- fold_convert (ret_type, integer_zero_node),
- single_pred_edge (first));
- a_acc = PHI_RESULT (phi);
- }
+ a_acc = create_tailcall_accumulator ("add_acc", first,
+ integer_zero_node);
if (act->mult && !m_acc)
- {
- ret_type = TREE_TYPE (DECL_RESULT (current_function_decl));
-
- tmp = create_tmp_var (ret_type, "mult_acc");
- add_referenced_var (tmp);
-
- phi = create_phi_node (tmp, first);
- add_phi_arg (phi,
- /* RET_TYPE can be a float when -ffast-maths is
- enabled. */
- fold_convert (ret_type, integer_one_node),
- single_pred_edge (first));
- m_acc = PHI_RESULT (phi);
- }
- }
-
-
- if (phis_constructed)
- {
- /* Reverse the order of the phi nodes, so that it matches the order
- of operands of the function, as assumed by eliminate_tail_call. */
- set_phi_nodes (first, phi_reverse (phi_nodes (first)));
+ m_acc = create_tailcall_accumulator ("mult_acc", first,
+ integer_one_node);
}
for (; tailcalls; tailcalls = next)
@@ -998,7 +959,7 @@ tree_optimize_tail_calls_1 (bool opt_tailcalls)
stmt = last_stmt (e->src);
if (stmt
- && TREE_CODE (stmt) == RETURN_EXPR)
+ && gimple_code (stmt) == GIMPLE_RETURN)
adjust_return_value (e->src, m_acc, a_acc);
}
}
diff --git a/gcc/tree-vect-analyze.c b/gcc/tree-vect-analyze.c
index 9f2640d09d6..c9753a0598d 100644
--- a/gcc/tree-vect-analyze.c
+++ b/gcc/tree-vect-analyze.c
@@ -75,10 +75,10 @@ vect_determine_vectorization_factor (loop_vec_info loop_vinfo)
struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo);
int nbbs = loop->num_nodes;
- block_stmt_iterator si;
+ gimple_stmt_iterator si;
unsigned int vectorization_factor = 0;
tree scalar_type;
- tree phi;
+ gimple phi;
tree vectype;
unsigned int nunits;
stmt_vec_info stmt_info;
@@ -91,13 +91,14 @@ vect_determine_vectorization_factor (loop_vec_info loop_vinfo)
{
basic_block bb = bbs[i];
- for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
+ for (si = gsi_start_phis (bb); !gsi_end_p (si); gsi_next (&si))
{
+ phi = gsi_stmt (si);
stmt_info = vinfo_for_stmt (phi);
if (vect_print_dump_info (REPORT_DETAILS))
{
fprintf (vect_dump, "==> examining phi: ");
- print_generic_expr (vect_dump, phi, TDF_SLIM);
+ print_gimple_stmt (vect_dump, phi, 0, TDF_SLIM);
}
gcc_assert (stmt_info);
@@ -142,15 +143,15 @@ vect_determine_vectorization_factor (loop_vec_info loop_vinfo)
}
}
- for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
+ for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
{
- tree stmt = bsi_stmt (si);
+ gimple stmt = gsi_stmt (si);
stmt_info = vinfo_for_stmt (stmt);
if (vect_print_dump_info (REPORT_DETAILS))
{
fprintf (vect_dump, "==> examining statement: ");
- print_generic_expr (vect_dump, stmt, TDF_SLIM);
+ print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
}
gcc_assert (stmt_info);
@@ -164,23 +165,22 @@ vect_determine_vectorization_factor (loop_vec_info loop_vinfo)
continue;
}
- if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT)
+ if (gimple_get_lhs (stmt) == NULL_TREE)
{
if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
{
fprintf (vect_dump, "not vectorized: irregular stmt.");
- print_generic_expr (vect_dump, stmt, TDF_SLIM);
+ print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
}
return false;
}
- if (!GIMPLE_STMT_P (stmt)
- && VECTOR_MODE_P (TYPE_MODE (TREE_TYPE (stmt))))
+ if (VECTOR_MODE_P (TYPE_MODE (gimple_expr_type (stmt))))
{
if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
{
fprintf (vect_dump, "not vectorized: vector stmt in loop:");
- print_generic_expr (vect_dump, stmt, TDF_SLIM);
+ print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
}
return false;
}
@@ -196,7 +196,6 @@ vect_determine_vectorization_factor (loop_vec_info loop_vinfo)
}
else
{
- tree operation;
gcc_assert (! STMT_VINFO_DATA_REF (stmt_info)
&& !is_pattern_stmt_p (stmt_info));
@@ -216,16 +215,16 @@ vect_determine_vectorization_factor (loop_vec_info loop_vinfo)
cannot rely on invariant motion to always take invariants out
of the loop, and so in the case of promotion we also have to
check the rhs. */
- scalar_type = TREE_TYPE (GIMPLE_STMT_OPERAND (stmt, 0));
+ scalar_type = gimple_expr_type (stmt);
- operation = GIMPLE_STMT_OPERAND (stmt, 1);
- if (CONVERT_EXPR_P (operation)
- || TREE_CODE (operation) == WIDEN_MULT_EXPR
- || TREE_CODE (operation) == FLOAT_EXPR)
+ if (is_gimple_assign (stmt)
+ && (gimple_assign_cast_p (stmt)
+ || gimple_assign_rhs_code (stmt) == WIDEN_MULT_EXPR
+ || gimple_assign_rhs_code (stmt) == FLOAT_EXPR))
{
- tree rhs_type = TREE_TYPE (TREE_OPERAND (operation, 0));
- if (TREE_INT_CST_LOW (TYPE_SIZE_UNIT (rhs_type)) <
- TREE_INT_CST_LOW (TYPE_SIZE_UNIT (scalar_type)))
+ tree rhs_type = TREE_TYPE (gimple_assign_rhs1 (stmt));
+ if (TREE_INT_CST_LOW (TYPE_SIZE_UNIT (rhs_type))
+ < TREE_INT_CST_LOW (TYPE_SIZE_UNIT (scalar_type)))
scalar_type = rhs_type;
}
@@ -315,11 +314,11 @@ vect_analyze_operations (loop_vec_info loop_vinfo)
struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo);
int nbbs = loop->num_nodes;
- block_stmt_iterator si;
+ gimple_stmt_iterator si;
unsigned int vectorization_factor = 0;
int i;
bool ok;
- tree phi;
+ gimple phi;
stmt_vec_info stmt_info;
bool need_to_vectorize = false;
int min_profitable_iters;
@@ -337,15 +336,16 @@ vect_analyze_operations (loop_vec_info loop_vinfo)
{
basic_block bb = bbs[i];
- for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
+ for (si = gsi_start_phis (bb); !gsi_end_p (si); gsi_next (&si))
{
+ phi = gsi_stmt (si);
ok = true;
stmt_info = vinfo_for_stmt (phi);
if (vect_print_dump_info (REPORT_DETAILS))
{
fprintf (vect_dump, "examining phi: ");
- print_generic_expr (vect_dump, phi, TDF_SLIM);
+ print_gimple_stmt (vect_dump, phi, 0, TDF_SLIM);
}
if (! is_loop_header_bb_p (bb))
@@ -398,22 +398,22 @@ vect_analyze_operations (loop_vec_info loop_vinfo)
{
fprintf (vect_dump,
"not vectorized: relevant phi not supported: ");
- print_generic_expr (vect_dump, phi, TDF_SLIM);
+ print_gimple_stmt (vect_dump, phi, 0, TDF_SLIM);
}
return false;
}
}
- for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
+ for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
{
- tree stmt = bsi_stmt (si);
+ gimple stmt = gsi_stmt (si);
stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
enum vect_def_type relevance = STMT_VINFO_RELEVANT (stmt_info);
if (vect_print_dump_info (REPORT_DETAILS))
{
fprintf (vect_dump, "==> examining statement: ");
- print_generic_expr (vect_dump, stmt, TDF_SLIM);
+ print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
}
gcc_assert (stmt_info);
@@ -454,8 +454,7 @@ vect_analyze_operations (loop_vec_info loop_vinfo)
if (STMT_VINFO_RELEVANT_P (stmt_info))
{
- gcc_assert (GIMPLE_STMT_P (stmt)
- || !VECTOR_MODE_P (TYPE_MODE (TREE_TYPE (stmt))));
+ gcc_assert (!VECTOR_MODE_P (TYPE_MODE (gimple_expr_type (stmt))));
gcc_assert (STMT_VINFO_VECTYPE (stmt_info));
need_to_vectorize = true;
}
@@ -480,7 +479,7 @@ vect_analyze_operations (loop_vec_info loop_vinfo)
{
fprintf (vect_dump, "not vectorized: relevant stmt not ");
fprintf (vect_dump, "supported: ");
- print_generic_expr (vect_dump, stmt, TDF_SLIM);
+ print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
}
return false;
}
@@ -497,7 +496,7 @@ vect_analyze_operations (loop_vec_info loop_vinfo)
{
fprintf (vect_dump, "not vectorized: live stmt not ");
fprintf (vect_dump, "supported: ");
- print_generic_expr (vect_dump, stmt, TDF_SLIM);
+ print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
}
return false;
}
@@ -520,7 +519,7 @@ vect_analyze_operations (loop_vec_info loop_vinfo)
{
fprintf (vect_dump, "not vectorized: the size of group "
"of strided accesses is not a power of 2");
- print_generic_expr (vect_dump, stmt, TDF_SLIM);
+ print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
}
return false;
}
@@ -649,7 +648,7 @@ vect_analyze_operations (loop_vec_info loop_vinfo)
used in STMT for anything other than indexing an array. */
static bool
-exist_non_indexing_operands_for_use_p (tree use, tree stmt)
+exist_non_indexing_operands_for_use_p (tree use, gimple stmt)
{
tree operand;
stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
@@ -673,10 +672,12 @@ exist_non_indexing_operands_for_use_p (tree use, tree stmt)
Therefore, all we need to check is if STMT falls into the
first case, and whether var corresponds to USE. */
- if (TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 0)) == SSA_NAME)
+ if (TREE_CODE (gimple_assign_lhs (stmt)) == SSA_NAME)
return false;
- operand = GIMPLE_STMT_OPERAND (stmt, 1);
+ if (!gimple_assign_copy_p (stmt))
+ return false;
+ operand = gimple_assign_rhs1 (stmt);
if (TREE_CODE (operand) != SSA_NAME)
return false;
@@ -698,17 +699,18 @@ exist_non_indexing_operands_for_use_p (tree use, tree stmt)
static void
vect_analyze_scalar_cycles_1 (loop_vec_info loop_vinfo, struct loop *loop)
{
- tree phi;
basic_block bb = loop->header;
tree dumy;
- VEC(tree,heap) *worklist = VEC_alloc (tree, heap, 64);
+ VEC(gimple,heap) *worklist = VEC_alloc (gimple, heap, 64);
+ gimple_stmt_iterator gsi;
if (vect_print_dump_info (REPORT_DETAILS))
fprintf (vect_dump, "=== vect_analyze_scalar_cycles ===");
/* First - identify all inductions. */
- for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
+ for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
+ gimple phi = gsi_stmt (gsi);
tree access_fn = NULL;
tree def = PHI_RESULT (phi);
stmt_vec_info stmt_vinfo = vinfo_for_stmt (phi);
@@ -716,7 +718,7 @@ vect_analyze_scalar_cycles_1 (loop_vec_info loop_vinfo, struct loop *loop)
if (vect_print_dump_info (REPORT_DETAILS))
{
fprintf (vect_dump, "Analyze phi: ");
- print_generic_expr (vect_dump, phi, TDF_SLIM);
+ print_gimple_stmt (vect_dump, phi, 0, TDF_SLIM);
}
/* Skip virtual phi's. The data dependences that are associated with
@@ -737,7 +739,7 @@ vect_analyze_scalar_cycles_1 (loop_vec_info loop_vinfo, struct loop *loop)
if (!access_fn
|| !vect_is_simple_iv_evolution (loop->num, access_fn, &dumy, &dumy))
{
- VEC_safe_push (tree, heap, worklist, phi);
+ VEC_safe_push (gimple, heap, worklist, phi);
continue;
}
@@ -748,17 +750,17 @@ vect_analyze_scalar_cycles_1 (loop_vec_info loop_vinfo, struct loop *loop)
/* Second - identify all reductions. */
- while (VEC_length (tree, worklist) > 0)
+ while (VEC_length (gimple, worklist) > 0)
{
- tree phi = VEC_pop (tree, worklist);
+ gimple phi = VEC_pop (gimple, worklist);
tree def = PHI_RESULT (phi);
stmt_vec_info stmt_vinfo = vinfo_for_stmt (phi);
- tree reduc_stmt;
+ gimple reduc_stmt;
if (vect_print_dump_info (REPORT_DETAILS))
{
fprintf (vect_dump, "Analyze phi: ");
- print_generic_expr (vect_dump, phi, TDF_SLIM);
+ print_gimple_stmt (vect_dump, phi, 0, TDF_SLIM);
}
gcc_assert (is_gimple_reg (SSA_NAME_VAR (def)));
@@ -778,7 +780,7 @@ vect_analyze_scalar_cycles_1 (loop_vec_info loop_vinfo, struct loop *loop)
fprintf (vect_dump, "Unknown def-use cycle pattern.");
}
- VEC_free (tree, heap, worklist);
+ VEC_free (gimple, heap, worklist);
return;
}
@@ -833,7 +835,8 @@ static void
vect_insert_into_interleaving_chain (struct data_reference *dra,
struct data_reference *drb)
{
- tree prev, next, next_init;
+ gimple prev, next;
+ tree next_init;
stmt_vec_info stmtinfo_a = vinfo_for_stmt (DR_STMT (dra));
stmt_vec_info stmtinfo_b = vinfo_for_stmt (DR_STMT (drb));
@@ -855,7 +858,7 @@ vect_insert_into_interleaving_chain (struct data_reference *dra,
/* We got to the end of the list. Insert here. */
DR_GROUP_NEXT_DR (vinfo_for_stmt (prev)) = DR_STMT (dra);
- DR_GROUP_NEXT_DR (stmtinfo_a) = NULL_TREE;
+ DR_GROUP_NEXT_DR (stmtinfo_a) = NULL;
}
@@ -888,8 +891,10 @@ vect_update_interleaving_chain (struct data_reference *drb,
{
stmt_vec_info stmtinfo_a = vinfo_for_stmt (DR_STMT (dra));
stmt_vec_info stmtinfo_b = vinfo_for_stmt (DR_STMT (drb));
- tree next_init, init_dra_chain, init_drb_chain, first_a, first_b;
- tree node, prev, next, node_init, first_stmt;
+ tree next_init, init_dra_chain, init_drb_chain;
+ gimple first_a, first_b;
+ tree node_init;
+ gimple node, prev, next, first_stmt;
/* 1. New stmts - both DRA and DRB are not a part of any chain. */
if (!DR_GROUP_FIRST_DR (stmtinfo_a) && !DR_GROUP_FIRST_DR (stmtinfo_b))
@@ -912,10 +917,10 @@ vect_update_interleaving_chain (struct data_reference *drb,
/* 3. DRA is a part of a chain and DRB is not. */
if (DR_GROUP_FIRST_DR (stmtinfo_a) && !DR_GROUP_FIRST_DR (stmtinfo_b))
{
- tree old_first_stmt = DR_GROUP_FIRST_DR (stmtinfo_a);
+ gimple old_first_stmt = DR_GROUP_FIRST_DR (stmtinfo_a);
tree init_old = DR_INIT (STMT_VINFO_DATA_REF (vinfo_for_stmt (
old_first_stmt)));
- tree tmp;
+ gimple tmp;
if (tree_int_cst_compare (init_old, DR_INIT (drb)) > 0)
{
@@ -991,7 +996,7 @@ vect_update_interleaving_chain (struct data_reference *drb,
{
/* We got to the end of the list. Insert here. */
DR_GROUP_NEXT_DR (vinfo_for_stmt (prev)) = node;
- DR_GROUP_NEXT_DR (vinfo_for_stmt (node)) = NULL_TREE;
+ DR_GROUP_NEXT_DR (vinfo_for_stmt (node)) = NULL;
prev = node;
}
DR_GROUP_FIRST_DR (vinfo_for_stmt (node)) = first_stmt;
@@ -1122,8 +1127,8 @@ vect_check_interleaving (struct data_reference *dra,
static bool
vect_same_range_drs (data_reference_p dr_i, data_reference_p dr_j)
{
- tree stmt_i = DR_STMT (dr_i);
- tree stmt_j = DR_STMT (dr_j);
+ gimple stmt_i = DR_STMT (dr_i);
+ gimple stmt_j = DR_STMT (dr_j);
if (operand_equal_p (DR_REF (dr_i), DR_REF (dr_j), 0)
|| (DR_GROUP_FIRST_DR (vinfo_for_stmt (stmt_i))
@@ -1351,7 +1356,7 @@ vect_analyze_data_ref_dependences (loop_vec_info loop_vinfo)
static bool
vect_compute_data_ref_alignment (struct data_reference *dr)
{
- tree stmt = DR_STMT (dr);
+ gimple stmt = DR_STMT (dr);
stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
@@ -1570,7 +1575,7 @@ vect_verify_datarefs_alignment (loop_vec_info loop_vinfo)
for (i = 0; VEC_iterate (data_reference_p, datarefs, i, dr); i++)
{
- tree stmt = DR_STMT (dr);
+ gimple stmt = DR_STMT (dr);
stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
/* For interleaving, only the alignment of the first access matters. */
@@ -1608,7 +1613,7 @@ vect_verify_datarefs_alignment (loop_vec_info loop_vinfo)
static bool
vector_alignment_reachable_p (struct data_reference *dr)
{
- tree stmt = DR_STMT (dr);
+ gimple stmt = DR_STMT (dr);
stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
tree vectype = STMT_VINFO_VECTYPE (stmt_info);
@@ -1773,7 +1778,7 @@ vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo)
bool do_peeling = false;
bool do_versioning = false;
bool stat;
- tree stmt;
+ gimple stmt;
stmt_vec_info stmt_info;
int vect_versioning_for_alias_required;
@@ -1857,7 +1862,7 @@ vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo)
{
int mis;
int npeel = 0;
- tree stmt = DR_STMT (dr0);
+ gimple stmt = DR_STMT (dr0);
stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
tree vectype = STMT_VINFO_VECTYPE (stmt_info);
int nelements = TYPE_VECTOR_SUBPARTS (vectype);
@@ -1973,12 +1978,12 @@ vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo)
if (!supportable_dr_alignment)
{
- tree stmt;
+ gimple stmt;
int mask;
tree vectype;
if (known_alignment_for_access_p (dr)
- || VEC_length (tree,
+ || VEC_length (gimple,
LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo))
>= (unsigned) PARAM_VALUE (PARAM_VECT_MAX_VERSION_FOR_ALIGNMENT_CHECKS))
{
@@ -2004,29 +2009,29 @@ vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo)
gcc_assert (!LOOP_VINFO_PTR_MASK (loop_vinfo)
|| LOOP_VINFO_PTR_MASK (loop_vinfo) == mask);
LOOP_VINFO_PTR_MASK (loop_vinfo) = mask;
- VEC_safe_push (tree, heap,
+ VEC_safe_push (gimple, heap,
LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo),
DR_STMT (dr));
}
}
/* Versioning requires at least one misaligned data reference. */
- if (VEC_length (tree, LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo)) == 0)
+ if (VEC_length (gimple, LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo)) == 0)
do_versioning = false;
else if (!do_versioning)
- VEC_truncate (tree, LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo), 0);
+ VEC_truncate (gimple, LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo), 0);
}
if (do_versioning)
{
- VEC(tree,heap) *may_misalign_stmts
+ VEC(gimple,heap) *may_misalign_stmts
= LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo);
- tree stmt;
+ gimple stmt;
/* It can now be assumed that the data references in the statements
in LOOP_VINFO_MAY_MISALIGN_STMTS will be aligned in the version
of the loop being vectorized. */
- for (i = 0; VEC_iterate (tree, may_misalign_stmts, i, stmt); i++)
+ for (i = 0; VEC_iterate (gimple, may_misalign_stmts, i, stmt); i++)
{
stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
dr = STMT_VINFO_DATA_REF (stmt_info);
@@ -2088,7 +2093,7 @@ vect_analyze_group_access (struct data_reference *dr)
tree step = DR_STEP (dr);
tree scalar_type = TREE_TYPE (DR_REF (dr));
HOST_WIDE_INT type_size = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (scalar_type));
- tree stmt = DR_STMT (dr);
+ gimple stmt = DR_STMT (dr);
stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
HOST_WIDE_INT dr_step = TREE_INT_CST_LOW (step);
@@ -2132,12 +2137,12 @@ vect_analyze_group_access (struct data_reference *dr)
if (DR_GROUP_FIRST_DR (vinfo_for_stmt (stmt)) == stmt)
{
/* First stmt in the interleaving chain. Check the chain. */
- tree next = DR_GROUP_NEXT_DR (vinfo_for_stmt (stmt));
+ gimple next = DR_GROUP_NEXT_DR (vinfo_for_stmt (stmt));
struct data_reference *data_ref = dr;
unsigned int count = 1;
tree next_step;
tree prev_init = DR_INIT (data_ref);
- tree prev = stmt;
+ gimple prev = stmt;
HOST_WIDE_INT diff, count_in_bytes;
while (next)
@@ -2280,7 +2285,7 @@ vect_analyze_group_access (struct data_reference *dr)
/* SLP: create an SLP data structure for every interleaving group of
stores for further analysis in vect_analyse_slp. */
if (!DR_IS_READ (dr) && !slp_impossible)
- VEC_safe_push (tree, heap, LOOP_VINFO_STRIDED_STORES (loop_vinfo), stmt);
+ VEC_safe_push (gimple, heap, LOOP_VINFO_STRIDED_STORES (loop_vinfo), stmt);
}
return true;
@@ -2296,7 +2301,7 @@ vect_analyze_data_ref_access (struct data_reference *dr)
{
tree step = DR_STEP (dr);
tree scalar_type = TREE_TYPE (DR_REF (dr));
- tree stmt = DR_STMT (dr);
+ gimple stmt = DR_STMT (dr);
stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
@@ -2317,7 +2322,7 @@ vect_analyze_data_ref_access (struct data_reference *dr)
{
/* Interleaved accesses are not yet supported within outer-loop
vectorization for references in the inner-loop. */
- DR_GROUP_FIRST_DR (vinfo_for_stmt (stmt)) = NULL_TREE;
+ DR_GROUP_FIRST_DR (vinfo_for_stmt (stmt)) = NULL;
/* For the rest of the analysis we use the outer-loop step. */
step = STMT_VINFO_DR_STEP (stmt_info);
@@ -2338,7 +2343,7 @@ vect_analyze_data_ref_access (struct data_reference *dr)
if (!tree_int_cst_compare (step, TYPE_SIZE_UNIT (scalar_type)))
{
/* Mark that it is not interleaving. */
- DR_GROUP_FIRST_DR (vinfo_for_stmt (stmt)) = NULL_TREE;
+ DR_GROUP_FIRST_DR (vinfo_for_stmt (stmt)) = NULL;
return true;
}
@@ -2470,23 +2475,23 @@ vect_free_slp_tree (slp_tree node)
if (SLP_TREE_RIGHT (node))
vect_free_slp_tree (SLP_TREE_RIGHT (node));
- VEC_free (tree, heap, SLP_TREE_SCALAR_STMTS (node));
+ VEC_free (gimple, heap, SLP_TREE_SCALAR_STMTS (node));
if (SLP_TREE_VEC_STMTS (node))
- VEC_free (tree, heap, SLP_TREE_VEC_STMTS (node));
+ VEC_free (gimple, heap, SLP_TREE_VEC_STMTS (node));
free (node);
}
-/* Get the defs for the RHS (collect them in DEF_STMTS0/1), check that they are
- of a legal type and that they match the defs of the first stmt of the SLP
- group (stored in FIRST_STMT_...). */
+/* Get the defs for the rhs of STMT (collect them in DEF_STMTS0/1), check that
+ they are of a legal type and that they match the defs of the first stmt of
+ the SLP group (stored in FIRST_STMT_...). */
static bool
vect_get_and_check_slp_defs (loop_vec_info loop_vinfo, slp_tree slp_node,
- tree rhs, VEC (tree, heap) **def_stmts0,
- VEC (tree, heap) **def_stmts1,
+ gimple stmt, VEC (gimple, heap) **def_stmts0,
+ VEC (gimple, heap) **def_stmts1,
enum vect_def_type *first_stmt_dt0,
enum vect_def_type *first_stmt_dt1,
tree *first_stmt_def0_type,
@@ -2495,25 +2500,20 @@ vect_get_and_check_slp_defs (loop_vec_info loop_vinfo, slp_tree slp_node,
int ncopies_for_cost)
{
tree oprnd;
- enum operation_type op_type = TREE_OPERAND_LENGTH (rhs);
- unsigned int i, number_of_oprnds = op_type;
- tree def, def_stmt;
+ unsigned int i, number_of_oprnds;
+ tree def;
+ gimple def_stmt;
enum vect_def_type dt[2] = {vect_unknown_def_type, vect_unknown_def_type};
stmt_vec_info stmt_info =
- vinfo_for_stmt (VEC_index (tree, SLP_TREE_SCALAR_STMTS (slp_node), 0));
+ vinfo_for_stmt (VEC_index (gimple, SLP_TREE_SCALAR_STMTS (slp_node), 0));
+ enum gimple_rhs_class rhs_class;
- /* Store. */
- if (!op_type)
- number_of_oprnds = 1;
- else
- gcc_assert (op_type == unary_op || op_type == binary_op);
+ rhs_class = get_gimple_rhs_class (gimple_assign_rhs_code (stmt));
+ number_of_oprnds = gimple_num_ops (stmt) - 1; /* RHS only */
for (i = 0; i < number_of_oprnds; i++)
{
- if (op_type)
- oprnd = TREE_OPERAND (rhs, i);
- else
- oprnd = rhs;
+ oprnd = gimple_op (stmt, i + 1);
if (!vect_is_simple_use (oprnd, loop_vinfo, &def_stmt, &def, &dt[i])
|| (!def_stmt && dt[i] != vect_constant_def))
@@ -2537,7 +2537,7 @@ vect_get_and_check_slp_defs (loop_vec_info loop_vinfo, slp_tree slp_node,
*first_stmt_const_oprnd = oprnd;
/* Analyze costs (for the first stmt of the group only). */
- if (op_type)
+ if (rhs_class != GIMPLE_SINGLE_RHS)
/* Not memory operation (we don't call this functions for loads). */
vect_model_simple_cost (stmt_info, ncopies_for_cost, dt, slp_node);
else
@@ -2600,9 +2600,9 @@ vect_get_and_check_slp_defs (loop_vec_info loop_vinfo, slp_tree slp_node,
case vect_loop_def:
if (i == 0)
- VEC_safe_push (tree, heap, *def_stmts0, def_stmt);
+ VEC_safe_push (gimple, heap, *def_stmts0, def_stmt);
else
- VEC_safe_push (tree, heap, *def_stmts1, def_stmt);
+ VEC_safe_push (gimple, heap, *def_stmts1, def_stmt);
break;
default:
@@ -2634,15 +2634,16 @@ vect_build_slp_tree (loop_vec_info loop_vinfo, slp_tree *node,
int *inside_cost, int *outside_cost,
int ncopies_for_cost)
{
- VEC (tree, heap) *def_stmts0 = VEC_alloc (tree, heap, group_size);
- VEC (tree, heap) *def_stmts1 = VEC_alloc (tree, heap, group_size);
+ VEC (gimple, heap) *def_stmts0 = VEC_alloc (gimple, heap, group_size);
+ VEC (gimple, heap) *def_stmts1 = VEC_alloc (gimple, heap, group_size);
unsigned int i;
- VEC (tree, heap) *stmts = SLP_TREE_SCALAR_STMTS (*node);
- tree stmt = VEC_index (tree, stmts, 0);
+ VEC (gimple, heap) *stmts = SLP_TREE_SCALAR_STMTS (*node);
+ gimple stmt = VEC_index (gimple, stmts, 0);
enum vect_def_type first_stmt_dt0 = 0, first_stmt_dt1 = 0;
- enum tree_code first_stmt_code = 0;
+ enum tree_code first_stmt_code = 0, rhs_code;
tree first_stmt_def1_type = NULL_TREE, first_stmt_def0_type = NULL_TREE;
- tree lhs, rhs, prev_stmt = NULL_TREE;
+ tree lhs;
+ gimple prev_stmt = NULL;
bool stop_recursion = false, need_same_oprnds = false;
tree vectype, scalar_type, first_op1 = NULL_TREE;
unsigned int vectorization_factor = 0, ncopies;
@@ -2654,26 +2655,28 @@ vect_build_slp_tree (loop_vec_info loop_vinfo, slp_tree *node,
struct data_reference *first_dr;
/* For every stmt in NODE find its def stmt/s. */
- for (i = 0; VEC_iterate (tree, stmts, i, stmt); i++)
+ for (i = 0; VEC_iterate (gimple, stmts, i, stmt); i++)
{
if (vect_print_dump_info (REPORT_SLP))
{
fprintf (vect_dump, "Build SLP for ");
- print_generic_expr (vect_dump, stmt, TDF_SLIM);
+ print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
}
- if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT)
+ lhs = gimple_get_lhs (stmt);
+ if (lhs == NULL_TREE)
{
if (vect_print_dump_info (REPORT_SLP))
{
- fprintf (vect_dump, "Build SLP failed: not MODIFY_STMT ");
- print_generic_expr (vect_dump, stmt, TDF_SLIM);
+ fprintf (vect_dump,
+ "Build SLP failed: not GIMPLE_ASSIGN nor GIMPLE_CALL");
+ print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
}
return false;
}
- scalar_type = TREE_TYPE (GIMPLE_STMT_OPERAND (stmt, 0));
+ scalar_type = TREE_TYPE (lhs);
vectype = get_vectype_for_scalar_type (scalar_type);
if (!vectype)
{
@@ -2698,24 +2701,26 @@ vect_build_slp_tree (loop_vec_info loop_vinfo, slp_tree *node,
return false;
}
- lhs = GIMPLE_STMT_OPERAND (stmt, 0);
- rhs = GIMPLE_STMT_OPERAND (stmt, 1);
+ if (is_gimple_call (stmt))
+ rhs_code = CALL_EXPR;
+ else
+ rhs_code = gimple_assign_rhs_code (stmt);
/* Check the operation. */
if (i == 0)
{
- first_stmt_code = TREE_CODE (rhs);
+ first_stmt_code = rhs_code;
/* Shift arguments should be equal in all the packed stmts for a
vector shift with scalar shift operand. */
- if (TREE_CODE (rhs) == LSHIFT_EXPR || TREE_CODE (rhs) == RSHIFT_EXPR
- || TREE_CODE (rhs) == LROTATE_EXPR
- || TREE_CODE (rhs) == RROTATE_EXPR)
+ if (rhs_code == LSHIFT_EXPR || rhs_code == RSHIFT_EXPR
+ || rhs_code == LROTATE_EXPR
+ || rhs_code == RROTATE_EXPR)
{
vec_mode = TYPE_MODE (vectype);
/* First see if we have a vector/vector shift. */
- optab = optab_for_tree_code (TREE_CODE (rhs), vectype,
+ optab = optab_for_tree_code (rhs_code, vectype,
optab_vector);
if (!optab
@@ -2723,7 +2728,7 @@ vect_build_slp_tree (loop_vec_info loop_vinfo, slp_tree *node,
== CODE_FOR_nothing))
{
/* No vector/vector shift, try for a vector/scalar shift. */
- optab = optab_for_tree_code (TREE_CODE (rhs), vectype,
+ optab = optab_for_tree_code (rhs_code, vectype,
optab_scalar);
if (!optab)
@@ -2744,33 +2749,37 @@ vect_build_slp_tree (loop_vec_info loop_vinfo, slp_tree *node,
if (!VECTOR_MODE_P (optab_op2_mode))
{
need_same_oprnds = true;
- first_op1 = TREE_OPERAND (rhs, 1);
+ first_op1 = gimple_assign_rhs2 (stmt);
}
}
}
}
else
{
- if (first_stmt_code != TREE_CODE (rhs))
+ if (first_stmt_code != rhs_code
+ && (first_stmt_code != IMAGPART_EXPR
+ || rhs_code != REALPART_EXPR)
+ && (first_stmt_code != REALPART_EXPR
+ || rhs_code != IMAGPART_EXPR))
{
if (vect_print_dump_info (REPORT_SLP))
{
fprintf (vect_dump,
"Build SLP failed: different operation in stmt ");
- print_generic_expr (vect_dump, stmt, TDF_SLIM);
+ print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
}
return false;
}
if (need_same_oprnds
- && !operand_equal_p (first_op1, TREE_OPERAND (rhs, 1), 0))
+ && !operand_equal_p (first_op1, gimple_assign_rhs2 (stmt), 0))
{
if (vect_print_dump_info (REPORT_SLP))
{
fprintf (vect_dump,
"Build SLP failed: different shift arguments in ");
- print_generic_expr (vect_dump, stmt, TDF_SLIM);
+ print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
}
return false;
@@ -2783,7 +2792,7 @@ vect_build_slp_tree (loop_vec_info loop_vinfo, slp_tree *node,
if (REFERENCE_CLASS_P (lhs))
{
/* Store. */
- if (!vect_get_and_check_slp_defs (loop_vinfo, *node, rhs,
+ if (!vect_get_and_check_slp_defs (loop_vinfo, *node, stmt,
&def_stmts0, &def_stmts1,
&first_stmt_dt0,
&first_stmt_dt1,
@@ -2810,7 +2819,7 @@ vect_build_slp_tree (loop_vec_info loop_vinfo, slp_tree *node,
{
fprintf (vect_dump, "Build SLP failed: strided "
" loads need permutation or have gaps ");
- print_generic_expr (vect_dump, stmt, TDF_SLIM);
+ print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
}
return false;
@@ -2824,7 +2833,7 @@ vect_build_slp_tree (loop_vec_info loop_vinfo, slp_tree *node,
{
fprintf (vect_dump, "Build SLP failed: unsupported "
" unaligned load ");
- print_generic_expr (vect_dump, stmt, TDF_SLIM);
+ print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
}
return false;
@@ -2847,7 +2856,7 @@ vect_build_slp_tree (loop_vec_info loop_vinfo, slp_tree *node,
{
fprintf (vect_dump, "Build SLP failed: strided "
" loads need permutation or have gaps ");
- print_generic_expr (vect_dump, stmt, TDF_SLIM);
+ print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
}
return false;
}
@@ -2862,13 +2871,13 @@ vect_build_slp_tree (loop_vec_info loop_vinfo, slp_tree *node,
} /* Strided access. */
else
{
- if (REFERENCE_CLASS_P (rhs))
+ if (TREE_CODE_CLASS (rhs_code) == tcc_reference)
{
/* Not strided load. */
if (vect_print_dump_info (REPORT_SLP))
{
fprintf (vect_dump, "Build SLP failed: not strided load ");
- print_generic_expr (vect_dump, stmt, TDF_SLIM);
+ print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
}
/* FORNOW: Not strided loads are not supported. */
@@ -2876,22 +2885,23 @@ vect_build_slp_tree (loop_vec_info loop_vinfo, slp_tree *node,
}
/* Not memory operation. */
- if (!BINARY_CLASS_P (rhs) && !UNARY_CLASS_P (rhs))
+ if (TREE_CODE_CLASS (rhs_code) != tcc_binary
+ && TREE_CODE_CLASS (rhs_code) != tcc_unary)
{
if (vect_print_dump_info (REPORT_SLP))
{
fprintf (vect_dump, "Build SLP failed: operation");
fprintf (vect_dump, " unsupported ");
- print_generic_expr (vect_dump, stmt, TDF_SLIM);
+ print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
}
return false;
}
/* Find the def-stmts. */
- if (!vect_get_and_check_slp_defs (loop_vinfo, *node, rhs, &def_stmts0,
- &def_stmts1, &first_stmt_dt0,
- &first_stmt_dt1,
+ if (!vect_get_and_check_slp_defs (loop_vinfo, *node, stmt,
+ &def_stmts0, &def_stmts1,
+ &first_stmt_dt0, &first_stmt_dt1,
&first_stmt_def0_type,
&first_stmt_def1_type,
&first_stmt_const_oprnd,
@@ -2951,16 +2961,16 @@ static void
vect_print_slp_tree (slp_tree node)
{
int i;
- tree stmt;
+ gimple stmt;
if (!node)
return;
fprintf (vect_dump, "node ");
- for (i = 0; VEC_iterate (tree, SLP_TREE_SCALAR_STMTS (node), i, stmt); i++)
+ for (i = 0; VEC_iterate (gimple, SLP_TREE_SCALAR_STMTS (node), i, stmt); i++)
{
fprintf (vect_dump, "\n\tstmt %d ", i);
- print_generic_expr (vect_dump, stmt, TDF_SLIM);
+ print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
}
fprintf (vect_dump, "\n");
@@ -2978,12 +2988,12 @@ static void
vect_mark_slp_stmts (slp_tree node, enum slp_vect_type mark, int j)
{
int i;
- tree stmt;
+ gimple stmt;
if (!node)
return;
- for (i = 0; VEC_iterate (tree, SLP_TREE_SCALAR_STMTS (node), i, stmt); i++)
+ for (i = 0; VEC_iterate (gimple, SLP_TREE_SCALAR_STMTS (node), i, stmt); i++)
if (j < 0 || i == j)
STMT_SLP_TYPE (vinfo_for_stmt (stmt)) = mark;
@@ -2997,13 +3007,14 @@ vect_mark_slp_stmts (slp_tree node, enum slp_vect_type mark, int j)
Return FALSE if it's impossible to SLP any stmt in the loop. */
static bool
-vect_analyze_slp_instance (loop_vec_info loop_vinfo, tree stmt)
+vect_analyze_slp_instance (loop_vec_info loop_vinfo, gimple stmt)
{
slp_instance new_instance;
slp_tree node = XNEW (struct _slp_tree);
unsigned int group_size = DR_GROUP_SIZE (vinfo_for_stmt (stmt));
unsigned int unrolling_factor = 1, nunits;
- tree vectype, scalar_type, next;
+ tree vectype, scalar_type;
+ gimple next;
unsigned int vectorization_factor = 0, ncopies;
bool slp_impossible = false;
int inside_cost = 0, outside_cost = 0, ncopies_for_cost;
@@ -3033,12 +3044,12 @@ vect_analyze_slp_instance (loop_vec_info loop_vinfo, tree stmt)
}
/* Create a node (a root of the SLP tree) for the packed strided stores. */
- SLP_TREE_SCALAR_STMTS (node) = VEC_alloc (tree, heap, group_size);
+ SLP_TREE_SCALAR_STMTS (node) = VEC_alloc (gimple, heap, group_size);
next = stmt;
/* Collect the stores and store them in SLP_TREE_SCALAR_STMTS. */
while (next)
{
- VEC_safe_push (tree, heap, SLP_TREE_SCALAR_STMTS (node), next);
+ VEC_safe_push (gimple, heap, SLP_TREE_SCALAR_STMTS (node), next);
next = DR_GROUP_NEXT_DR (vinfo_for_stmt (next));
}
@@ -3096,13 +3107,13 @@ static bool
vect_analyze_slp (loop_vec_info loop_vinfo)
{
unsigned int i;
- VEC (tree, heap) *strided_stores = LOOP_VINFO_STRIDED_STORES (loop_vinfo);
- tree store;
+ VEC (gimple, heap) *strided_stores = LOOP_VINFO_STRIDED_STORES (loop_vinfo);
+ gimple store;
if (vect_print_dump_info (REPORT_SLP))
fprintf (vect_dump, "=== vect_analyze_slp ===");
- for (i = 0; VEC_iterate (tree, strided_stores, i, store); i++)
+ for (i = 0; VEC_iterate (gimple, strided_stores, i, store); i++)
if (!vect_analyze_slp_instance (loop_vinfo, store))
{
/* SLP failed. No instance can be SLPed in the loop. */
@@ -3158,17 +3169,17 @@ static void
vect_detect_hybrid_slp_stmts (slp_tree node)
{
int i;
- tree stmt;
+ gimple stmt;
imm_use_iterator imm_iter;
- tree use_stmt;
+ gimple use_stmt;
if (!node)
return;
- for (i = 0; VEC_iterate (tree, SLP_TREE_SCALAR_STMTS (node), i, stmt); i++)
+ for (i = 0; VEC_iterate (gimple, SLP_TREE_SCALAR_STMTS (node), i, stmt); i++)
if (PURE_SLP_STMT (vinfo_for_stmt (stmt))
- && TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 0)) == SSA_NAME)
- FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, GIMPLE_STMT_OPERAND (stmt, 0))
+ && TREE_CODE (gimple_op (stmt, 0)) == SSA_NAME)
+ FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, gimple_op (stmt, 0))
if (vinfo_for_stmt (use_stmt)
&& !STMT_SLP_TYPE (vinfo_for_stmt (use_stmt)))
vect_mark_slp_stmts (node, hybrid, i);
@@ -3231,7 +3242,7 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo)
for (i = 0; VEC_iterate (data_reference_p, datarefs, i, dr); i++)
{
- tree stmt;
+ gimple stmt;
stmt_vec_info stmt_info;
basic_block bb;
tree base, offset, init;
@@ -3253,7 +3264,7 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo)
if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
{
fprintf (vect_dump, "not vectorized: data ref analysis failed ");
- print_generic_expr (vect_dump, stmt, TDF_SLIM);
+ print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
}
return false;
}
@@ -3281,7 +3292,7 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo)
init = unshare_expr (DR_INIT (dr));
/* Update DR field in stmt_vec_info struct. */
- bb = bb_for_stmt (stmt);
+ bb = gimple_bb (stmt);
/* If the dataref is in an inner-loop of the loop that is considered for
for vectorization, we also want to analyze the access relative to
@@ -3392,7 +3403,7 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo)
{
fprintf (vect_dump,
"not vectorized: more than one data ref in stmt: ");
- print_generic_expr (vect_dump, stmt, TDF_SLIM);
+ print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
}
return false;
}
@@ -3408,7 +3419,7 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo)
{
fprintf (vect_dump,
"not vectorized: no vectype for stmt: ");
- print_generic_expr (vect_dump, stmt, TDF_SLIM);
+ print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
fprintf (vect_dump, " scalar_type: ");
print_generic_expr (vect_dump, scalar_type, TDF_DETAILS);
}
@@ -3427,7 +3438,7 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo)
Mark STMT as "relevant for vectorization" and add it to WORKLIST. */
static void
-vect_mark_relevant (VEC(tree,heap) **worklist, tree stmt,
+vect_mark_relevant (VEC(gimple,heap) **worklist, gimple stmt,
enum vect_relevant relevant, bool live_p)
{
stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
@@ -3439,7 +3450,7 @@ vect_mark_relevant (VEC(tree,heap) **worklist, tree stmt,
if (STMT_VINFO_IN_PATTERN_P (stmt_info))
{
- tree pattern_stmt;
+ gimple pattern_stmt;
/* This is the last stmt in a sequence that was detected as a
pattern that can potentially be vectorized. Don't mark the stmt
@@ -3469,7 +3480,7 @@ vect_mark_relevant (VEC(tree,heap) **worklist, tree stmt,
return;
}
- VEC_safe_push (tree, heap, *worklist, stmt);
+ VEC_safe_push (gimple, heap, *worklist, stmt);
}
@@ -3486,7 +3497,7 @@ vect_mark_relevant (VEC(tree,heap) **worklist, tree stmt,
CHECKME: what other side effects would the vectorizer allow? */
static bool
-vect_stmt_relevant_p (tree stmt, loop_vec_info loop_vinfo,
+vect_stmt_relevant_p (gimple stmt, loop_vec_info loop_vinfo,
enum vect_relevant *relevant, bool *live_p)
{
struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
@@ -3504,7 +3515,7 @@ vect_stmt_relevant_p (tree stmt, loop_vec_info loop_vinfo,
*relevant = vect_used_in_loop;
/* changing memory. */
- if (TREE_CODE (stmt) != PHI_NODE)
+ if (gimple_code (stmt) != GIMPLE_PHI)
if (!ZERO_SSA_OPERANDS (stmt, SSA_OP_VIRTUAL_DEFS))
{
if (vect_print_dump_info (REPORT_DETAILS))
@@ -3517,7 +3528,7 @@ vect_stmt_relevant_p (tree stmt, loop_vec_info loop_vinfo,
{
FOR_EACH_IMM_USE_FAST (use_p, imm_iter, DEF_FROM_PTR (def_p))
{
- basic_block bb = bb_for_stmt (USE_STMT (use_p));
+ basic_block bb = gimple_bb (USE_STMT (use_p));
if (!flow_bb_inside_loop_p (loop, bb))
{
if (vect_print_dump_info (REPORT_DETAILS))
@@ -3525,7 +3536,7 @@ vect_stmt_relevant_p (tree stmt, loop_vec_info loop_vinfo,
/* We expect all such uses to be in the loop exit phis
(because of loop closed form) */
- gcc_assert (TREE_CODE (USE_STMT (use_p)) == PHI_NODE);
+ gcc_assert (gimple_code (USE_STMT (use_p)) == GIMPLE_PHI);
gcc_assert (bb == single_exit (loop)->dest);
*live_p = true;
@@ -3563,14 +3574,15 @@ vect_stmt_relevant_p (tree stmt, loop_vec_info loop_vinfo,
Return true if everything is as expected. Return false otherwise. */
static bool
-process_use (tree stmt, tree use, loop_vec_info loop_vinfo, bool live_p,
- enum vect_relevant relevant, VEC(tree,heap) **worklist)
+process_use (gimple stmt, tree use, loop_vec_info loop_vinfo, bool live_p,
+ enum vect_relevant relevant, VEC(gimple,heap) **worklist)
{
struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
stmt_vec_info stmt_vinfo = vinfo_for_stmt (stmt);
stmt_vec_info dstmt_vinfo;
basic_block bb, def_bb;
- tree def, def_stmt;
+ tree def;
+ gimple def_stmt;
enum vect_def_type dt;
/* case 1: we are only interested in uses that need to be vectorized. Uses
@@ -3585,10 +3597,10 @@ process_use (tree stmt, tree use, loop_vec_info loop_vinfo, bool live_p,
return false;
}
- if (!def_stmt || IS_EMPTY_STMT (def_stmt))
+ if (!def_stmt || gimple_nop_p (def_stmt))
return true;
- def_bb = bb_for_stmt (def_stmt);
+ def_bb = gimple_bb (def_stmt);
if (!flow_bb_inside_loop_p (loop, def_bb))
{
if (vect_print_dump_info (REPORT_DETAILS))
@@ -3602,10 +3614,10 @@ process_use (tree stmt, tree use, loop_vec_info loop_vinfo, bool live_p,
as there should be no other uses for DEF_STMT in the loop. So we just
check that everything is as expected, and we are done. */
dstmt_vinfo = vinfo_for_stmt (def_stmt);
- bb = bb_for_stmt (stmt);
- if (TREE_CODE (stmt) == PHI_NODE
+ bb = gimple_bb (stmt);
+ if (gimple_code (stmt) == GIMPLE_PHI
&& STMT_VINFO_DEF_TYPE (stmt_vinfo) == vect_reduction_def
- && TREE_CODE (def_stmt) != PHI_NODE
+ && gimple_code (def_stmt) != GIMPLE_PHI
&& STMT_VINFO_DEF_TYPE (dstmt_vinfo) == vect_reduction_def
&& bb->loop_father == def_bb->loop_father)
{
@@ -3710,47 +3722,47 @@ process_use (tree stmt, tree use, loop_vec_info loop_vinfo, bool live_p,
static bool
vect_mark_stmts_to_be_vectorized (loop_vec_info loop_vinfo)
{
- VEC(tree,heap) *worklist;
+ VEC(gimple,heap) *worklist;
struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo);
unsigned int nbbs = loop->num_nodes;
- block_stmt_iterator si;
- tree stmt;
- stmt_ann_t ann;
+ gimple_stmt_iterator si;
+ gimple stmt;
unsigned int i;
stmt_vec_info stmt_vinfo;
basic_block bb;
- tree phi;
+ gimple phi;
bool live_p;
enum vect_relevant relevant;
if (vect_print_dump_info (REPORT_DETAILS))
fprintf (vect_dump, "=== vect_mark_stmts_to_be_vectorized ===");
- worklist = VEC_alloc (tree, heap, 64);
+ worklist = VEC_alloc (gimple, heap, 64);
/* 1. Init worklist. */
for (i = 0; i < nbbs; i++)
{
bb = bbs[i];
- for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
+ for (si = gsi_start_phis (bb); !gsi_end_p (si); gsi_next (&si))
{
+ phi = gsi_stmt (si);
if (vect_print_dump_info (REPORT_DETAILS))
{
fprintf (vect_dump, "init: phi relevant? ");
- print_generic_expr (vect_dump, phi, TDF_SLIM);
+ print_gimple_stmt (vect_dump, phi, 0, TDF_SLIM);
}
if (vect_stmt_relevant_p (phi, loop_vinfo, &relevant, &live_p))
vect_mark_relevant (&worklist, phi, relevant, live_p);
}
- for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
+ for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
{
- stmt = bsi_stmt (si);
+ stmt = gsi_stmt (si);
if (vect_print_dump_info (REPORT_DETAILS))
{
fprintf (vect_dump, "init: stmt relevant? ");
- print_generic_expr (vect_dump, stmt, TDF_SLIM);
+ print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
}
if (vect_stmt_relevant_p (stmt, loop_vinfo, &relevant, &live_p))
@@ -3759,22 +3771,21 @@ vect_mark_stmts_to_be_vectorized (loop_vec_info loop_vinfo)
}
/* 2. Process_worklist */
- while (VEC_length (tree, worklist) > 0)
+ while (VEC_length (gimple, worklist) > 0)
{
use_operand_p use_p;
ssa_op_iter iter;
- stmt = VEC_pop (tree, worklist);
+ stmt = VEC_pop (gimple, worklist);
if (vect_print_dump_info (REPORT_DETAILS))
{
fprintf (vect_dump, "worklist: examine stmt: ");
- print_generic_expr (vect_dump, stmt, TDF_SLIM);
+ print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
}
/* Examine the USEs of STMT. For each USE, mark the stmt that defines it
(DEF_STMT) as relevant/irrelevant and live/dead according to the
liveness and relevance properties of STMT. */
- ann = stmt_ann (stmt);
stmt_vinfo = vinfo_for_stmt (stmt);
relevant = STMT_VINFO_RELEVANT (stmt_vinfo);
live_p = STMT_VINFO_LIVE_P (stmt_vinfo);
@@ -3812,25 +3823,25 @@ vect_mark_stmts_to_be_vectorized (loop_vec_info loop_vinfo)
switch (tmp_relevant)
{
case vect_unused_in_loop:
- gcc_assert (TREE_CODE (stmt) != PHI_NODE);
+ gcc_assert (gimple_code (stmt) != GIMPLE_PHI);
relevant = vect_used_by_reduction;
break;
case vect_used_in_outer_by_reduction:
case vect_used_in_outer:
- gcc_assert (TREE_CODE (stmt) != WIDEN_SUM_EXPR
- && TREE_CODE (stmt) != DOT_PROD_EXPR);
+ gcc_assert (gimple_code (stmt) != WIDEN_SUM_EXPR
+ && gimple_code (stmt) != DOT_PROD_EXPR);
break;
case vect_used_by_reduction:
- if (TREE_CODE (stmt) == PHI_NODE)
+ if (gimple_code (stmt) == GIMPLE_PHI)
break;
/* fall through */
case vect_used_in_loop:
default:
if (vect_print_dump_info (REPORT_DETAILS))
fprintf (vect_dump, "unsupported use of reduction.");
- VEC_free (tree, heap, worklist);
+ VEC_free (gimple, heap, worklist);
return false;
}
live_p = false;
@@ -3841,13 +3852,13 @@ vect_mark_stmts_to_be_vectorized (loop_vec_info loop_vinfo)
tree op = USE_FROM_PTR (use_p);
if (!process_use (stmt, op, loop_vinfo, live_p, relevant, &worklist))
{
- VEC_free (tree, heap, worklist);
+ VEC_free (gimple, heap, worklist);
return false;
}
}
} /* while worklist */
- VEC_free (tree, heap, worklist);
+ VEC_free (gimple, heap, worklist);
return true;
}
@@ -3866,22 +3877,24 @@ vect_can_advance_ivs_p (loop_vec_info loop_vinfo)
{
struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
basic_block bb = loop->header;
- tree phi;
+ gimple phi;
+ gimple_stmt_iterator gsi;
/* Analyze phi functions of the loop header. */
if (vect_print_dump_info (REPORT_DETAILS))
fprintf (vect_dump, "vect_can_advance_ivs_p:");
- for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
+ for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
tree access_fn = NULL;
tree evolution_part;
+ phi = gsi_stmt (gsi);
if (vect_print_dump_info (REPORT_DETAILS))
{
fprintf (vect_dump, "Analyze phi: ");
- print_generic_expr (vect_dump, phi, TDF_SLIM);
+ print_gimple_stmt (vect_dump, phi, 0, TDF_SLIM);
}
/* Skip virtual phi's. The data dependences that are associated with
@@ -3948,7 +3961,7 @@ vect_can_advance_ivs_p (loop_vec_info loop_vinfo)
can be constructed, place it in NUMBER_OF_ITERATIONS.
Return the loop exit condition. */
-static tree
+static gimple
vect_get_loop_niters (struct loop *loop, tree *number_of_iterations)
{
tree niters;
@@ -4016,7 +4029,7 @@ loop_vec_info
vect_analyze_loop_form (struct loop *loop)
{
loop_vec_info loop_vinfo;
- tree loop_cond;
+ gimple loop_cond;
tree number_of_iterations = NULL;
loop_vec_info inner_loop_vinfo = NULL;
diff --git a/gcc/tree-vect-generic.c b/gcc/tree-vect-generic.c
index 8313e54bdbc..9919389dfc3 100644
--- a/gcc/tree-vect-generic.c
+++ b/gcc/tree-vect-generic.c
@@ -30,7 +30,7 @@ along with GCC; see the file COPYING3. If not see
#include "machmode.h"
#include "langhooks.h"
#include "tree-flow.h"
-#include "tree-gimple.h"
+#include "gimple.h"
#include "tree-iterator.h"
#include "tree-pass.h"
#include "flags.h"
@@ -96,35 +96,35 @@ build_word_mode_vector_type (int nunits)
return vector_last_type;
}
-typedef tree (*elem_op_func) (block_stmt_iterator *,
+typedef tree (*elem_op_func) (gimple_stmt_iterator *,
tree, tree, tree, tree, tree, enum tree_code);
static inline tree
-tree_vec_extract (block_stmt_iterator *bsi, tree type,
+tree_vec_extract (gimple_stmt_iterator *gsi, tree type,
tree t, tree bitsize, tree bitpos)
{
if (bitpos)
- return gimplify_build3 (bsi, BIT_FIELD_REF, type, t, bitsize, bitpos);
+ return gimplify_build3 (gsi, BIT_FIELD_REF, type, t, bitsize, bitpos);
else
- return gimplify_build1 (bsi, VIEW_CONVERT_EXPR, type, t);
+ return gimplify_build1 (gsi, VIEW_CONVERT_EXPR, type, t);
}
static tree
-do_unop (block_stmt_iterator *bsi, tree inner_type, tree a,
+do_unop (gimple_stmt_iterator *gsi, tree inner_type, tree a,
tree b ATTRIBUTE_UNUSED, tree bitpos, tree bitsize,
enum tree_code code)
{
- a = tree_vec_extract (bsi, inner_type, a, bitsize, bitpos);
- return gimplify_build1 (bsi, code, inner_type, a);
+ a = tree_vec_extract (gsi, inner_type, a, bitsize, bitpos);
+ return gimplify_build1 (gsi, code, inner_type, a);
}
static tree
-do_binop (block_stmt_iterator *bsi, tree inner_type, tree a, tree b,
+do_binop (gimple_stmt_iterator *gsi, tree inner_type, tree a, tree b,
tree bitpos, tree bitsize, enum tree_code code)
{
- a = tree_vec_extract (bsi, inner_type, a, bitsize, bitpos);
- b = tree_vec_extract (bsi, inner_type, b, bitsize, bitpos);
- return gimplify_build2 (bsi, code, inner_type, a, b);
+ a = tree_vec_extract (gsi, inner_type, a, bitsize, bitpos);
+ b = tree_vec_extract (gsi, inner_type, b, bitsize, bitpos);
+ return gimplify_build2 (gsi, code, inner_type, a, b);
}
/* Expand vector addition to scalars. This does bit twiddling
@@ -141,7 +141,7 @@ do_binop (block_stmt_iterator *bsi, tree inner_type, tree a, tree b,
This optimization should be done only if 4 vector items or more
fit into a word. */
static tree
-do_plus_minus (block_stmt_iterator *bsi, tree word_type, tree a, tree b,
+do_plus_minus (gimple_stmt_iterator *gsi, tree word_type, tree a, tree b,
tree bitpos ATTRIBUTE_UNUSED, tree bitsize ATTRIBUTE_UNUSED,
enum tree_code code)
{
@@ -153,26 +153,26 @@ do_plus_minus (block_stmt_iterator *bsi, tree word_type, tree a, tree b,
low_bits = build_replicated_const (word_type, inner_type, max >> 1);
high_bits = build_replicated_const (word_type, inner_type, max & ~(max >> 1));
- a = tree_vec_extract (bsi, word_type, a, bitsize, bitpos);
- b = tree_vec_extract (bsi, word_type, b, bitsize, bitpos);
+ a = tree_vec_extract (gsi, word_type, a, bitsize, bitpos);
+ b = tree_vec_extract (gsi, word_type, b, bitsize, bitpos);
- signs = gimplify_build2 (bsi, BIT_XOR_EXPR, word_type, a, b);
- b_low = gimplify_build2 (bsi, BIT_AND_EXPR, word_type, b, low_bits);
+ signs = gimplify_build2 (gsi, BIT_XOR_EXPR, word_type, a, b);
+ b_low = gimplify_build2 (gsi, BIT_AND_EXPR, word_type, b, low_bits);
if (code == PLUS_EXPR)
- a_low = gimplify_build2 (bsi, BIT_AND_EXPR, word_type, a, low_bits);
+ a_low = gimplify_build2 (gsi, BIT_AND_EXPR, word_type, a, low_bits);
else
{
- a_low = gimplify_build2 (bsi, BIT_IOR_EXPR, word_type, a, high_bits);
- signs = gimplify_build1 (bsi, BIT_NOT_EXPR, word_type, signs);
+ a_low = gimplify_build2 (gsi, BIT_IOR_EXPR, word_type, a, high_bits);
+ signs = gimplify_build1 (gsi, BIT_NOT_EXPR, word_type, signs);
}
- signs = gimplify_build2 (bsi, BIT_AND_EXPR, word_type, signs, high_bits);
- result_low = gimplify_build2 (bsi, code, word_type, a_low, b_low);
- return gimplify_build2 (bsi, BIT_XOR_EXPR, word_type, result_low, signs);
+ signs = gimplify_build2 (gsi, BIT_AND_EXPR, word_type, signs, high_bits);
+ result_low = gimplify_build2 (gsi, code, word_type, a_low, b_low);
+ return gimplify_build2 (gsi, BIT_XOR_EXPR, word_type, result_low, signs);
}
static tree
-do_negate (block_stmt_iterator *bsi, tree word_type, tree b,
+do_negate (gimple_stmt_iterator *gsi, tree word_type, tree b,
tree unused ATTRIBUTE_UNUSED, tree bitpos ATTRIBUTE_UNUSED,
tree bitsize ATTRIBUTE_UNUSED,
enum tree_code code ATTRIBUTE_UNUSED)
@@ -185,19 +185,19 @@ do_negate (block_stmt_iterator *bsi, tree word_type, tree b,
low_bits = build_replicated_const (word_type, inner_type, max >> 1);
high_bits = build_replicated_const (word_type, inner_type, max & ~(max >> 1));
- b = tree_vec_extract (bsi, word_type, b, bitsize, bitpos);
+ b = tree_vec_extract (gsi, word_type, b, bitsize, bitpos);
- b_low = gimplify_build2 (bsi, BIT_AND_EXPR, word_type, b, low_bits);
- signs = gimplify_build1 (bsi, BIT_NOT_EXPR, word_type, b);
- signs = gimplify_build2 (bsi, BIT_AND_EXPR, word_type, signs, high_bits);
- result_low = gimplify_build2 (bsi, MINUS_EXPR, word_type, high_bits, b_low);
- return gimplify_build2 (bsi, BIT_XOR_EXPR, word_type, result_low, signs);
+ b_low = gimplify_build2 (gsi, BIT_AND_EXPR, word_type, b, low_bits);
+ signs = gimplify_build1 (gsi, BIT_NOT_EXPR, word_type, b);
+ signs = gimplify_build2 (gsi, BIT_AND_EXPR, word_type, signs, high_bits);
+ result_low = gimplify_build2 (gsi, MINUS_EXPR, word_type, high_bits, b_low);
+ return gimplify_build2 (gsi, BIT_XOR_EXPR, word_type, result_low, signs);
}
/* Expand a vector operation to scalars, by using many operations
whose type is the vector type's inner type. */
static tree
-expand_vector_piecewise (block_stmt_iterator *bsi, elem_op_func f,
+expand_vector_piecewise (gimple_stmt_iterator *gsi, elem_op_func f,
tree type, tree inner_type,
tree a, tree b, enum tree_code code)
{
@@ -213,7 +213,7 @@ expand_vector_piecewise (block_stmt_iterator *bsi, elem_op_func f,
for (i = 0; i < nunits;
i += delta, index = int_const_binop (PLUS_EXPR, index, part_width, 0))
{
- tree result = f (bsi, inner_type, a, b, index, part_width, code);
+ tree result = f (gsi, inner_type, a, b, index, part_width, code);
constructor_elt *ce = VEC_quick_push (constructor_elt, v, NULL);
ce->index = NULL_TREE;
ce->value = result;
@@ -226,7 +226,7 @@ expand_vector_piecewise (block_stmt_iterator *bsi, elem_op_func f,
a scalar integer type, or to use a different size for the items
in the vector type. */
static tree
-expand_vector_parallel (block_stmt_iterator *bsi, elem_op_func f, tree type,
+expand_vector_parallel (gimple_stmt_iterator *gsi, elem_op_func f, tree type,
tree a, tree b,
enum tree_code code)
{
@@ -239,23 +239,24 @@ expand_vector_parallel (block_stmt_iterator *bsi, elem_op_func f, tree type,
one word, do it a word at a time; finally, if the vector is smaller
than one word, do it as a scalar. */
if (TYPE_MODE (TREE_TYPE (type)) == word_mode)
- return expand_vector_piecewise (bsi, f,
+ return expand_vector_piecewise (gsi, f,
type, TREE_TYPE (type),
a, b, code);
else if (n_words > 1)
{
tree word_type = build_word_mode_vector_type (n_words);
- result = expand_vector_piecewise (bsi, f,
+ result = expand_vector_piecewise (gsi, f,
word_type, TREE_TYPE (word_type),
a, b, code);
- result = gimplify_val (bsi, word_type, result);
+ result = force_gimple_operand_gsi (gsi, result, true, NULL, true,
+ GSI_SAME_STMT);
}
else
{
/* Use a single scalar operation with a mode no wider than word_mode. */
mode = mode_for_size (tree_low_cst (TYPE_SIZE (type), 1), MODE_INT, 0);
compute_type = lang_hooks.types.type_for_mode (mode, 1);
- result = f (bsi, compute_type, a, b, NULL_TREE, NULL_TREE, code);
+ result = f (gsi, compute_type, a, b, NULL_TREE, NULL_TREE, code);
}
return result;
@@ -267,7 +268,7 @@ expand_vector_parallel (block_stmt_iterator *bsi, elem_op_func f, tree type,
they can process at least four items, that is, only if the vector
holds at least four items and if a word can hold four items. */
static tree
-expand_vector_addition (block_stmt_iterator *bsi,
+expand_vector_addition (gimple_stmt_iterator *gsi,
elem_op_func f, elem_op_func f_parallel,
tree type, tree a, tree b, enum tree_code code)
{
@@ -277,17 +278,17 @@ expand_vector_addition (block_stmt_iterator *bsi,
if (INTEGRAL_TYPE_P (TREE_TYPE (type))
&& parts_per_word >= 4
&& TYPE_VECTOR_SUBPARTS (type) >= 4)
- return expand_vector_parallel (bsi, f_parallel,
+ return expand_vector_parallel (gsi, f_parallel,
type, a, b, code);
else
- return expand_vector_piecewise (bsi, f,
+ return expand_vector_piecewise (gsi, f,
type, TREE_TYPE (type),
a, b, code);
}
static tree
-expand_vector_operation (block_stmt_iterator *bsi, tree type, tree compute_type,
- tree rhs, enum tree_code code)
+expand_vector_operation (gimple_stmt_iterator *gsi, tree type, tree compute_type,
+ gimple assign, enum tree_code code)
{
enum machine_mode compute_mode = TYPE_MODE (compute_type);
@@ -305,28 +306,28 @@ expand_vector_operation (block_stmt_iterator *bsi, tree type, tree compute_type,
case PLUS_EXPR:
case MINUS_EXPR:
if (!TYPE_OVERFLOW_TRAPS (type))
- return expand_vector_addition (bsi, do_binop, do_plus_minus, type,
- TREE_OPERAND (rhs, 0),
- TREE_OPERAND (rhs, 1), code);
+ return expand_vector_addition (gsi, do_binop, do_plus_minus, type,
+ gimple_assign_rhs1 (assign),
+ gimple_assign_rhs2 (assign), code);
break;
case NEGATE_EXPR:
if (!TYPE_OVERFLOW_TRAPS (type))
- return expand_vector_addition (bsi, do_unop, do_negate, type,
- TREE_OPERAND (rhs, 0),
+ return expand_vector_addition (gsi, do_unop, do_negate, type,
+ gimple_assign_rhs1 (assign),
NULL_TREE, code);
break;
case BIT_AND_EXPR:
case BIT_IOR_EXPR:
case BIT_XOR_EXPR:
- return expand_vector_parallel (bsi, do_binop, type,
- TREE_OPERAND (rhs, 0),
- TREE_OPERAND (rhs, 1), code);
+ return expand_vector_parallel (gsi, do_binop, type,
+ gimple_assign_rhs1 (assign),
+ gimple_assign_rhs2 (assign), code);
case BIT_NOT_EXPR:
- return expand_vector_parallel (bsi, do_unop, type,
- TREE_OPERAND (rhs, 0),
+ return expand_vector_parallel (gsi, do_unop, type,
+ gimple_assign_rhs1 (assign),
NULL_TREE, code);
default:
@@ -334,13 +335,13 @@ expand_vector_operation (block_stmt_iterator *bsi, tree type, tree compute_type,
}
if (TREE_CODE_CLASS (code) == tcc_unary)
- return expand_vector_piecewise (bsi, do_unop, type, compute_type,
- TREE_OPERAND (rhs, 0),
+ return expand_vector_piecewise (gsi, do_unop, type, compute_type,
+ gimple_assign_rhs1 (assign),
NULL_TREE, code);
else
- return expand_vector_piecewise (bsi, do_binop, type, compute_type,
- TREE_OPERAND (rhs, 0),
- TREE_OPERAND (rhs, 1), code);
+ return expand_vector_piecewise (gsi, do_binop, type, compute_type,
+ gimple_assign_rhs1 (assign),
+ gimple_assign_rhs2 (assign), code);
}
/* Return a type for the widest vector mode whose components are of mode
@@ -387,43 +388,34 @@ type_for_widest_vector_mode (enum machine_mode inner_mode, optab op, int satp)
/* Process one statement. If we identify a vector operation, expand it. */
static void
-expand_vector_operations_1 (block_stmt_iterator *bsi)
+expand_vector_operations_1 (gimple_stmt_iterator *gsi)
{
- tree stmt = bsi_stmt (*bsi);
- tree *p_lhs, *p_rhs, lhs, rhs, type, compute_type;
+ gimple stmt = gsi_stmt (*gsi);
+ tree lhs, rhs1, rhs2 = NULL, type, compute_type;
enum tree_code code;
enum machine_mode compute_mode;
optab op;
+ enum gimple_rhs_class rhs_class;
+ tree new_rhs;
- switch (TREE_CODE (stmt))
- {
- case RETURN_EXPR:
- stmt = TREE_OPERAND (stmt, 0);
- if (!stmt || TREE_CODE (stmt) != GIMPLE_MODIFY_STMT)
- return;
+ if (gimple_code (stmt) != GIMPLE_ASSIGN)
+ return;
- /* FALLTHRU */
+ code = gimple_assign_rhs_code (stmt);
+ rhs_class = get_gimple_rhs_class (code);
- case GIMPLE_MODIFY_STMT:
- p_lhs = &GIMPLE_STMT_OPERAND (stmt, 0);
- p_rhs = &GIMPLE_STMT_OPERAND (stmt, 1);
- lhs = *p_lhs;
- rhs = *p_rhs;
- break;
+ if (rhs_class != GIMPLE_UNARY_RHS && rhs_class != GIMPLE_BINARY_RHS)
+ return;
- default:
- return;
- }
+ lhs = gimple_assign_lhs (stmt);
+ rhs1 = gimple_assign_rhs1 (stmt);
+ type = gimple_expr_type (stmt);
+ if (rhs_class == GIMPLE_BINARY_RHS)
+ rhs2 = gimple_assign_rhs2 (stmt);
- type = TREE_TYPE (rhs);
if (TREE_CODE (type) != VECTOR_TYPE)
return;
- code = TREE_CODE (rhs);
- if (TREE_CODE_CLASS (code) != tcc_unary
- && TREE_CODE_CLASS (code) != tcc_binary)
- return;
-
if (code == NOP_EXPR
|| code == FLOAT_EXPR
|| code == FIX_TRUNC_EXPR
@@ -435,17 +427,18 @@ expand_vector_operations_1 (block_stmt_iterator *bsi)
/* The signedness is determined from input argument. */
if (code == VEC_UNPACK_FLOAT_HI_EXPR
|| code == VEC_UNPACK_FLOAT_LO_EXPR)
- type = TREE_TYPE (TREE_OPERAND (rhs, 0));
+ type = TREE_TYPE (rhs1);
/* Choose between vector shift/rotate by vector and vector shift/rotate by
scalar */
- if (code == LSHIFT_EXPR || code == RSHIFT_EXPR || code == LROTATE_EXPR
+ if (code == LSHIFT_EXPR
+ || code == RSHIFT_EXPR
+ || code == LROTATE_EXPR
|| code == RROTATE_EXPR)
{
/* If the 2nd argument is vector, we need a vector/vector shift */
- if (VECTOR_MODE_P (TYPE_MODE (TREE_TYPE (TREE_OPERAND (rhs, 1)))))
+ if (VECTOR_MODE_P (TYPE_MODE (TREE_TYPE (rhs2))))
op = optab_for_tree_code (code, type, optab_vector);
-
else
{
/* Try for a vector/scalar shift, and if we don't have one, see if we
@@ -471,7 +464,7 @@ expand_vector_operations_1 (block_stmt_iterator *bsi)
|| code == VEC_PACK_TRUNC_EXPR
|| code == VEC_PACK_SAT_EXPR
|| code == VEC_PACK_FIX_TRUNC_EXPR)
- type = TREE_TYPE (TREE_OPERAND (rhs, 0));
+ type = TREE_TYPE (rhs1);
/* Optabs will try converting a negation into a subtraction, so
look for it as well. TODO: negation of floating-point vectors
@@ -513,13 +506,17 @@ expand_vector_operations_1 (block_stmt_iterator *bsi)
}
gcc_assert (code != VEC_LSHIFT_EXPR && code != VEC_RSHIFT_EXPR);
- rhs = expand_vector_operation (bsi, type, compute_type, rhs, code);
- if (useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (rhs)))
- *p_rhs = rhs;
- else
- *p_rhs = gimplify_build1 (bsi, VIEW_CONVERT_EXPR, TREE_TYPE (lhs), rhs);
+ new_rhs = expand_vector_operation (gsi, type, compute_type, stmt, code);
+ if (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (new_rhs)))
+ new_rhs = gimplify_build1 (gsi, VIEW_CONVERT_EXPR, TREE_TYPE (lhs),
+ new_rhs);
+
+ /* NOTE: We should avoid using gimple_assign_set_rhs_from_tree. One
+ way to do it is change expand_vector_operation and its callees to
+ return a tree_code, RHS1 and RHS2 instead of a tree. */
+ gimple_assign_set_rhs_from_tree (gsi, new_rhs);
- mark_stmt_modified (bsi_stmt (*bsi));
+ gimple_set_modified (gsi_stmt (*gsi), true);
}
/* Use this to lower vector operations introduced by the vectorizer,
@@ -534,15 +531,15 @@ gate_expand_vector_operations (void)
static unsigned int
expand_vector_operations (void)
{
- block_stmt_iterator bsi;
+ gimple_stmt_iterator gsi;
basic_block bb;
FOR_EACH_BB (bb)
{
- for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
- expand_vector_operations_1 (&bsi);
- update_stmt_if_modified (bsi_stmt (bsi));
+ expand_vector_operations_1 (&gsi);
+ update_stmt_if_modified (gsi_stmt (gsi));
}
}
return 0;
diff --git a/gcc/tree-vect-patterns.c b/gcc/tree-vect-patterns.c
index b9a302d8430..e53780f1ef6 100644
--- a/gcc/tree-vect-patterns.c
+++ b/gcc/tree-vect-patterns.c
@@ -1,5 +1,5 @@
/* Analysis Utilities for Loop Vectorization.
- Copyright (C) 2006, 2007 Free Software Foundation, Inc.
+ Copyright (C) 2006, 2007, 2008 Free Software Foundation, Inc.
Contributed by Dorit Nuzman <dorit@il.ibm.com>
This file is part of GCC.
@@ -42,14 +42,14 @@ along with GCC; see the file COPYING3. If not see
/* Function prototypes */
static void vect_pattern_recog_1
- (tree (* ) (tree, tree *, tree *), block_stmt_iterator);
-static bool widened_name_p (tree, tree, tree *, tree *);
+ (gimple (* ) (gimple, tree *, tree *), gimple_stmt_iterator);
+static bool widened_name_p (tree, gimple, tree *, gimple *);
/* Pattern recognition functions */
-static tree vect_recog_widen_sum_pattern (tree, tree *, tree *);
-static tree vect_recog_widen_mult_pattern (tree, tree *, tree *);
-static tree vect_recog_dot_prod_pattern (tree, tree *, tree *);
-static tree vect_recog_pow_pattern (tree, tree *, tree *);
+static gimple vect_recog_widen_sum_pattern (gimple, tree *, tree *);
+static gimple vect_recog_widen_mult_pattern (gimple, tree *, tree *);
+static gimple vect_recog_dot_prod_pattern (gimple, tree *, tree *);
+static gimple vect_recog_pow_pattern (gimple, tree *, tree *);
static vect_recog_func_ptr vect_vect_recog_func_ptrs[NUM_PATTERNS] = {
vect_recog_widen_mult_pattern,
vect_recog_widen_sum_pattern,
@@ -66,12 +66,12 @@ static vect_recog_func_ptr vect_vect_recog_func_ptrs[NUM_PATTERNS] = {
*/
static bool
-widened_name_p (tree name, tree use_stmt, tree *half_type, tree *def_stmt)
+widened_name_p (tree name, gimple use_stmt, tree *half_type, gimple *def_stmt)
{
tree dummy;
+ gimple dummy_gimple;
loop_vec_info loop_vinfo;
stmt_vec_info stmt_vinfo;
- tree expr;
tree type = TREE_TYPE (name);
tree oprnd0;
enum vect_def_type dt;
@@ -90,14 +90,13 @@ widened_name_p (tree name, tree use_stmt, tree *half_type, tree *def_stmt)
if (! *def_stmt)
return false;
- if (TREE_CODE (*def_stmt) != GIMPLE_MODIFY_STMT)
+ if (!is_gimple_assign (*def_stmt))
return false;
- expr = GIMPLE_STMT_OPERAND (*def_stmt, 1);
- if (TREE_CODE (expr) != NOP_EXPR)
+ if (gimple_assign_rhs_code (*def_stmt) != NOP_EXPR)
return false;
- oprnd0 = TREE_OPERAND (expr, 0);
+ oprnd0 = gimple_assign_rhs1 (*def_stmt);
*half_type = TREE_TYPE (oprnd0);
if (!INTEGRAL_TYPE_P (type) || !INTEGRAL_TYPE_P (*half_type)
@@ -105,12 +104,24 @@ widened_name_p (tree name, tree use_stmt, tree *half_type, tree *def_stmt)
|| (TYPE_PRECISION (type) < (TYPE_PRECISION (*half_type) * 2)))
return false;
- if (!vect_is_simple_use (oprnd0, loop_vinfo, &dummy, &dummy, &dt))
+ if (!vect_is_simple_use (oprnd0, loop_vinfo, &dummy_gimple, &dummy, &dt))
return false;
return true;
}
+/* Helper to return a new temporary for pattern of TYPE for STMT. If STMT
+ is NULL, the caller must set SSA_NAME_DEF_STMT for the returned SSA var. */
+
+static tree
+vect_recog_temp_ssa_var (tree type, gimple stmt)
+{
+ tree var = create_tmp_var (type, "patt");
+
+ add_referenced_var (var);
+ var = make_ssa_name (var, stmt);
+ return var;
+}
/* Function vect_recog_dot_prod_pattern
@@ -157,24 +168,24 @@ widened_name_p (tree name, tree use_stmt, tree *half_type, tree *def_stmt)
the correct order (as is the case when this computation is in an
inner-loop nested in an outer-loop that us being vectorized). */
-static tree
-vect_recog_dot_prod_pattern (tree last_stmt, tree *type_in, tree *type_out)
+static gimple
+vect_recog_dot_prod_pattern (gimple last_stmt, tree *type_in, tree *type_out)
{
- tree stmt, expr;
+ gimple stmt;
tree oprnd0, oprnd1;
tree oprnd00, oprnd01;
stmt_vec_info stmt_vinfo = vinfo_for_stmt (last_stmt);
tree type, half_type;
- tree pattern_expr;
+ gimple pattern_stmt;
tree prod_type;
loop_vec_info loop_info = STMT_VINFO_LOOP_VINFO (stmt_vinfo);
struct loop *loop = LOOP_VINFO_LOOP (loop_info);
+ tree var, rhs;
- if (TREE_CODE (last_stmt) != GIMPLE_MODIFY_STMT)
+ if (!is_gimple_assign (last_stmt))
return NULL;
- expr = GIMPLE_STMT_OPERAND (last_stmt, 1);
- type = TREE_TYPE (expr);
+ type = gimple_expr_type (last_stmt);
/* Look for the following pattern
DX = (TYPE1) X;
@@ -200,7 +211,7 @@ vect_recog_dot_prod_pattern (tree last_stmt, tree *type_in, tree *type_out)
/* Starting from LAST_STMT, follow the defs of its uses in search
of the above pattern. */
- if (TREE_CODE (expr) != PLUS_EXPR)
+ if (gimple_assign_rhs_code (last_stmt) != PLUS_EXPR)
return NULL;
if (STMT_VINFO_IN_PATTERN_P (stmt_vinfo))
@@ -208,22 +219,21 @@ vect_recog_dot_prod_pattern (tree last_stmt, tree *type_in, tree *type_out)
/* Has been detected as widening-summation? */
stmt = STMT_VINFO_RELATED_STMT (stmt_vinfo);
- expr = GIMPLE_STMT_OPERAND (stmt, 1);
- type = TREE_TYPE (expr);
- if (TREE_CODE (expr) != WIDEN_SUM_EXPR)
+ type = gimple_expr_type (stmt);
+ if (gimple_assign_rhs_code (stmt) != WIDEN_SUM_EXPR)
return NULL;
- oprnd0 = TREE_OPERAND (expr, 0);
- oprnd1 = TREE_OPERAND (expr, 1);
+ oprnd0 = gimple_assign_rhs1 (stmt);
+ oprnd1 = gimple_assign_rhs2 (stmt);
half_type = TREE_TYPE (oprnd0);
}
else
{
- tree def_stmt;
+ gimple def_stmt;
if (STMT_VINFO_DEF_TYPE (stmt_vinfo) != vect_reduction_def)
return NULL;
- oprnd0 = TREE_OPERAND (expr, 0);
- oprnd1 = TREE_OPERAND (expr, 1);
+ oprnd0 = gimple_assign_rhs1 (last_stmt);
+ oprnd1 = gimple_assign_rhs2 (last_stmt);
if (TYPE_MAIN_VARIANT (TREE_TYPE (oprnd0)) != TYPE_MAIN_VARIANT (type)
|| TYPE_MAIN_VARIANT (TREE_TYPE (oprnd1)) != TYPE_MAIN_VARIANT (type))
return NULL;
@@ -232,8 +242,7 @@ vect_recog_dot_prod_pattern (tree last_stmt, tree *type_in, tree *type_out)
if (widened_name_p (oprnd0, stmt, &half_type, &def_stmt))
{
stmt = def_stmt;
- expr = GIMPLE_STMT_OPERAND (stmt, 1);
- oprnd0 = TREE_OPERAND (expr, 0);
+ oprnd0 = gimple_assign_rhs1 (stmt);
}
else
half_type = type;
@@ -248,37 +257,35 @@ vect_recog_dot_prod_pattern (tree last_stmt, tree *type_in, tree *type_out)
stmt = SSA_NAME_DEF_STMT (oprnd0);
/* FORNOW. Can continue analyzing the def-use chain when this stmt in a phi
inside the loop (in case we are analyzing an outer-loop). */
- if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT)
+ if (!is_gimple_assign (stmt))
return NULL;
stmt_vinfo = vinfo_for_stmt (stmt);
gcc_assert (stmt_vinfo);
if (STMT_VINFO_DEF_TYPE (stmt_vinfo) != vect_loop_def)
return NULL;
- expr = GIMPLE_STMT_OPERAND (stmt, 1);
- if (TREE_CODE (expr) != MULT_EXPR)
+ if (gimple_assign_rhs_code (stmt) != MULT_EXPR)
return NULL;
if (STMT_VINFO_IN_PATTERN_P (stmt_vinfo))
{
/* Has been detected as a widening multiplication? */
stmt = STMT_VINFO_RELATED_STMT (stmt_vinfo);
- expr = GIMPLE_STMT_OPERAND (stmt, 1);
- if (TREE_CODE (expr) != WIDEN_MULT_EXPR)
+ if (gimple_assign_rhs_code (stmt) != WIDEN_MULT_EXPR)
return NULL;
stmt_vinfo = vinfo_for_stmt (stmt);
gcc_assert (stmt_vinfo);
gcc_assert (STMT_VINFO_DEF_TYPE (stmt_vinfo) == vect_loop_def);
- oprnd00 = TREE_OPERAND (expr, 0);
- oprnd01 = TREE_OPERAND (expr, 1);
+ oprnd00 = gimple_assign_rhs1 (stmt);
+ oprnd01 = gimple_assign_rhs2 (stmt);
}
else
{
tree half_type0, half_type1;
- tree def_stmt;
+ gimple def_stmt;
tree oprnd0, oprnd1;
- oprnd0 = TREE_OPERAND (expr, 0);
- oprnd1 = TREE_OPERAND (expr, 1);
+ oprnd0 = gimple_assign_rhs1 (stmt);
+ oprnd1 = gimple_assign_rhs2 (stmt);
if (TYPE_MAIN_VARIANT (TREE_TYPE (oprnd0))
!= TYPE_MAIN_VARIANT (prod_type)
|| TYPE_MAIN_VARIANT (TREE_TYPE (oprnd1))
@@ -286,10 +293,10 @@ vect_recog_dot_prod_pattern (tree last_stmt, tree *type_in, tree *type_out)
return NULL;
if (!widened_name_p (oprnd0, stmt, &half_type0, &def_stmt))
return NULL;
- oprnd00 = TREE_OPERAND (GIMPLE_STMT_OPERAND (def_stmt, 1), 0);
+ oprnd00 = gimple_assign_rhs1 (def_stmt);
if (!widened_name_p (oprnd1, stmt, &half_type1, &def_stmt))
return NULL;
- oprnd01 = TREE_OPERAND (GIMPLE_STMT_OPERAND (def_stmt, 1), 0);
+ oprnd01 = gimple_assign_rhs1 (def_stmt);
if (TYPE_MAIN_VARIANT (half_type0) != TYPE_MAIN_VARIANT (half_type1))
return NULL;
if (TYPE_PRECISION (prod_type) != TYPE_PRECISION (half_type0) * 2)
@@ -301,11 +308,14 @@ vect_recog_dot_prod_pattern (tree last_stmt, tree *type_in, tree *type_out)
*type_out = type;
/* Pattern detected. Create a stmt to be used to replace the pattern: */
- pattern_expr = build3 (DOT_PROD_EXPR, type, oprnd00, oprnd01, oprnd1);
+ var = vect_recog_temp_ssa_var (type, NULL);
+ rhs = build3 (DOT_PROD_EXPR, type, oprnd00, oprnd01, oprnd1),
+ pattern_stmt = gimple_build_assign (var, rhs);
+
if (vect_print_dump_info (REPORT_DETAILS))
{
fprintf (vect_dump, "vect_recog_dot_prod_pattern: detected: ");
- print_generic_expr (vect_dump, pattern_expr, TDF_SLIM);
+ print_gimple_stmt (vect_dump, pattern_stmt, 0, TDF_SLIM);
}
/* We don't allow changing the order of the computation in the inner-loop
@@ -317,10 +327,9 @@ vect_recog_dot_prod_pattern (tree last_stmt, tree *type_in, tree *type_out)
return NULL;
}
- return pattern_expr;
+ return pattern_stmt;
}
-
-
+
/* Function vect_recog_widen_mult_pattern
Try to find the following pattern:
@@ -352,34 +361,33 @@ vect_recog_dot_prod_pattern (tree last_stmt, tree *type_in, tree *type_out)
WIDEN_MULT <a_t, b_t>
*/
-static tree
-vect_recog_widen_mult_pattern (tree last_stmt,
+static gimple
+vect_recog_widen_mult_pattern (gimple last_stmt,
tree *type_in,
tree *type_out)
{
- tree expr;
- tree def_stmt0, def_stmt1;
+ gimple def_stmt0, def_stmt1;
tree oprnd0, oprnd1;
tree type, half_type0, half_type1;
- tree pattern_expr;
+ gimple pattern_stmt;
tree vectype;
tree dummy;
+ tree var;
enum tree_code dummy_code;
- if (TREE_CODE (last_stmt) != GIMPLE_MODIFY_STMT)
+ if (!is_gimple_assign (last_stmt))
return NULL;
- expr = GIMPLE_STMT_OPERAND (last_stmt, 1);
- type = TREE_TYPE (expr);
+ type = gimple_expr_type (last_stmt);
/* Starting from LAST_STMT, follow the defs of its uses in search
of the above pattern. */
- if (TREE_CODE (expr) != MULT_EXPR)
+ if (gimple_assign_rhs_code (last_stmt) != MULT_EXPR)
return NULL;
- oprnd0 = TREE_OPERAND (expr, 0);
- oprnd1 = TREE_OPERAND (expr, 1);
+ oprnd0 = gimple_assign_rhs1 (last_stmt);
+ oprnd1 = gimple_assign_rhs2 (last_stmt);
if (TYPE_MAIN_VARIANT (TREE_TYPE (oprnd0)) != TYPE_MAIN_VARIANT (type)
|| TYPE_MAIN_VARIANT (TREE_TYPE (oprnd1)) != TYPE_MAIN_VARIANT (type))
return NULL;
@@ -387,12 +395,12 @@ vect_recog_widen_mult_pattern (tree last_stmt,
/* Check argument 0 */
if (!widened_name_p (oprnd0, last_stmt, &half_type0, &def_stmt0))
return NULL;
- oprnd0 = TREE_OPERAND (GIMPLE_STMT_OPERAND (def_stmt0, 1), 0);
+ oprnd0 = gimple_assign_rhs1 (def_stmt0);
/* Check argument 1 */
if (!widened_name_p (oprnd1, last_stmt, &half_type1, &def_stmt1))
return NULL;
- oprnd1 = TREE_OPERAND (GIMPLE_STMT_OPERAND (def_stmt1, 1), 0);
+ oprnd1 = gimple_assign_rhs1 (def_stmt1);
if (TYPE_MAIN_VARIANT (half_type0) != TYPE_MAIN_VARIANT (half_type1))
return NULL;
@@ -405,18 +413,23 @@ vect_recog_widen_mult_pattern (tree last_stmt,
vectype = get_vectype_for_scalar_type (half_type0);
if (!vectype
|| !supportable_widening_operation (WIDEN_MULT_EXPR, last_stmt, vectype,
- &dummy, &dummy, &dummy_code,
- &dummy_code))
+ &dummy, &dummy, &dummy_code,
+ &dummy_code))
return NULL;
*type_in = vectype;
*type_out = NULL_TREE;
/* Pattern supported. Create a stmt to be used to replace the pattern: */
- pattern_expr = build2 (WIDEN_MULT_EXPR, type, oprnd0, oprnd1);
+ var = vect_recog_temp_ssa_var (type, NULL);
+ pattern_stmt = gimple_build_assign_with_ops (WIDEN_MULT_EXPR, var, oprnd0,
+ oprnd1);
+ SSA_NAME_DEF_STMT (var) = pattern_stmt;
+
if (vect_print_dump_info (REPORT_DETAILS))
- print_generic_expr (vect_dump, pattern_expr, TDF_SLIM);
- return pattern_expr;
+ print_gimple_stmt (vect_dump, pattern_stmt, 0, TDF_SLIM);
+
+ return pattern_stmt;
}
@@ -441,43 +454,40 @@ vect_recog_widen_mult_pattern (tree last_stmt,
* Return value: A new stmt that will be used to replace the sequence of
stmts that constitute the pattern. In this case it will be:
- x * x
+ x = x * x
or
- sqrt (x)
+ x = sqrt (x)
*/
-static tree
-vect_recog_pow_pattern (tree last_stmt, tree *type_in, tree *type_out)
+static gimple
+vect_recog_pow_pattern (gimple last_stmt, tree *type_in, tree *type_out)
{
- tree expr;
tree type;
- tree fn, base, exp;
+ tree fn, base, exp = NULL;
+ gimple stmt;
+ tree var;
- if (TREE_CODE (last_stmt) != GIMPLE_MODIFY_STMT)
+ if (!is_gimple_call (last_stmt) || gimple_call_lhs (last_stmt) == NULL)
return NULL;
- expr = GIMPLE_STMT_OPERAND (last_stmt, 1);
- type = TREE_TYPE (expr);
-
- if (TREE_CODE (expr) != CALL_EXPR)
- return NULL_TREE;
+ type = gimple_expr_type (last_stmt);
- fn = get_callee_fndecl (expr);
+ fn = gimple_call_fndecl (last_stmt);
switch (DECL_FUNCTION_CODE (fn))
{
case BUILT_IN_POWIF:
case BUILT_IN_POWI:
case BUILT_IN_POWF:
case BUILT_IN_POW:
- base = CALL_EXPR_ARG (expr, 0);
- exp = CALL_EXPR_ARG (expr, 1);
+ base = gimple_call_arg (last_stmt, 0);
+ exp = gimple_call_arg (last_stmt, 1);
if (TREE_CODE (exp) != REAL_CST
&& TREE_CODE (exp) != INTEGER_CST)
- return NULL_TREE;
+ return NULL;
break;
- default:;
- return NULL_TREE;
+ default:
+ return NULL;
}
/* We now have a pow or powi builtin function call with a constant
@@ -492,7 +502,11 @@ vect_recog_pow_pattern (tree last_stmt, tree *type_in, tree *type_out)
&& REAL_VALUES_EQUAL (TREE_REAL_CST (exp), dconst2)))
{
*type_in = TREE_TYPE (base);
- return build2 (MULT_EXPR, TREE_TYPE (base), base, base);
+
+ var = vect_recog_temp_ssa_var (TREE_TYPE (base), NULL);
+ stmt = gimple_build_assign_with_ops (MULT_EXPR, var, base, base);
+ SSA_NAME_DEF_STMT (var) = stmt;
+ return stmt;
}
/* Catch square root. */
@@ -503,13 +517,18 @@ vect_recog_pow_pattern (tree last_stmt, tree *type_in, tree *type_out)
*type_in = get_vectype_for_scalar_type (TREE_TYPE (base));
if (*type_in)
{
- newfn = build_call_expr (newfn, 1, base);
- if (vectorizable_function (newfn, *type_in, *type_in) != NULL_TREE)
- return newfn;
+ gimple stmt = gimple_build_call (newfn, 1, base);
+ if (vectorizable_function (stmt, *type_in, *type_in)
+ != NULL_TREE)
+ {
+ var = vect_recog_temp_ssa_var (TREE_TYPE (base), stmt);
+ gimple_call_set_lhs (stmt, var);
+ return stmt;
+ }
}
}
- return NULL_TREE;
+ return NULL;
}
@@ -552,22 +571,22 @@ vect_recog_pow_pattern (tree last_stmt, tree *type_in, tree *type_out)
the correct order (as is the case when this computation is in an
inner-loop nested in an outer-loop that us being vectorized). */
-static tree
-vect_recog_widen_sum_pattern (tree last_stmt, tree *type_in, tree *type_out)
+static gimple
+vect_recog_widen_sum_pattern (gimple last_stmt, tree *type_in, tree *type_out)
{
- tree stmt, expr;
+ gimple stmt;
tree oprnd0, oprnd1;
stmt_vec_info stmt_vinfo = vinfo_for_stmt (last_stmt);
tree type, half_type;
- tree pattern_expr;
+ gimple pattern_stmt;
loop_vec_info loop_info = STMT_VINFO_LOOP_VINFO (stmt_vinfo);
struct loop *loop = LOOP_VINFO_LOOP (loop_info);
+ tree var;
- if (TREE_CODE (last_stmt) != GIMPLE_MODIFY_STMT)
+ if (!is_gimple_assign (last_stmt))
return NULL;
- expr = GIMPLE_STMT_OPERAND (last_stmt, 1);
- type = TREE_TYPE (expr);
+ type = gimple_expr_type (last_stmt);
/* Look for the following pattern
DX = (TYPE) X;
@@ -579,14 +598,14 @@ vect_recog_widen_sum_pattern (tree last_stmt, tree *type_in, tree *type_out)
/* Starting from LAST_STMT, follow the defs of its uses in search
of the above pattern. */
- if (TREE_CODE (expr) != PLUS_EXPR)
+ if (gimple_assign_rhs_code (last_stmt) != PLUS_EXPR)
return NULL;
if (STMT_VINFO_DEF_TYPE (stmt_vinfo) != vect_reduction_def)
return NULL;
- oprnd0 = TREE_OPERAND (expr, 0);
- oprnd1 = TREE_OPERAND (expr, 1);
+ oprnd0 = gimple_assign_rhs1 (last_stmt);
+ oprnd1 = gimple_assign_rhs2 (last_stmt);
if (TYPE_MAIN_VARIANT (TREE_TYPE (oprnd0)) != TYPE_MAIN_VARIANT (type)
|| TYPE_MAIN_VARIANT (TREE_TYPE (oprnd1)) != TYPE_MAIN_VARIANT (type))
return NULL;
@@ -600,16 +619,20 @@ vect_recog_widen_sum_pattern (tree last_stmt, tree *type_in, tree *type_out)
if (!widened_name_p (oprnd0, last_stmt, &half_type, &stmt))
return NULL;
- oprnd0 = TREE_OPERAND (GIMPLE_STMT_OPERAND (stmt, 1), 0);
+ oprnd0 = gimple_assign_rhs1 (stmt);
*type_in = half_type;
*type_out = type;
/* Pattern detected. Create a stmt to be used to replace the pattern: */
- pattern_expr = build2 (WIDEN_SUM_EXPR, type, oprnd0, oprnd1);
+ var = vect_recog_temp_ssa_var (type, NULL);
+ pattern_stmt = gimple_build_assign_with_ops (WIDEN_SUM_EXPR, var,
+ oprnd0, oprnd1);
+ SSA_NAME_DEF_STMT (var) = pattern_stmt;
+
if (vect_print_dump_info (REPORT_DETAILS))
{
fprintf (vect_dump, "vect_recog_widen_sum_pattern: detected: ");
- print_generic_expr (vect_dump, pattern_expr, TDF_SLIM);
+ print_gimple_stmt (vect_dump, pattern_stmt, 0, TDF_SLIM);
}
/* We don't allow changing the order of the computation in the inner-loop
@@ -621,7 +644,7 @@ vect_recog_widen_sum_pattern (tree last_stmt, tree *type_in, tree *type_out)
return NULL;
}
- return pattern_expr;
+ return pattern_stmt;
}
@@ -649,23 +672,19 @@ vect_recog_widen_sum_pattern (tree last_stmt, tree *type_in, tree *type_out)
static void
vect_pattern_recog_1 (
- tree (* vect_recog_func) (tree, tree *, tree *),
- block_stmt_iterator si)
+ gimple (* vect_recog_func) (gimple, tree *, tree *),
+ gimple_stmt_iterator si)
{
- tree stmt = bsi_stmt (si);
+ gimple stmt = gsi_stmt (si), pattern_stmt;
stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
stmt_vec_info pattern_stmt_info;
loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
- tree pattern_expr;
tree pattern_vectype;
tree type_in, type_out;
- tree pattern_type;
enum tree_code code;
- tree var, var_name;
- stmt_ann_t ann;
- pattern_expr = (* vect_recog_func) (stmt, &type_in, &type_out);
- if (!pattern_expr)
+ pattern_stmt = (* vect_recog_func) (stmt, &type_in, &type_out);
+ if (!pattern_stmt)
return;
if (VECTOR_MODE_P (TYPE_MODE (type_in)))
@@ -685,8 +704,15 @@ vect_pattern_recog_1 (
if (!pattern_vectype)
return;
- optab = optab_for_tree_code (TREE_CODE (pattern_expr), pattern_vectype,
- optab_default);
+ if (is_gimple_assign (pattern_stmt))
+ code = gimple_assign_rhs_code (pattern_stmt);
+ else
+ {
+ gcc_assert (is_gimple_call (pattern_stmt));
+ code = CALL_EXPR;
+ }
+
+ optab = optab_for_tree_code (code, pattern_vectype, optab_default);
vec_mode = TYPE_MODE (pattern_vectype);
if (!optab
|| (icode = optab_handler (optab, vec_mode)->insn_code) ==
@@ -702,28 +728,20 @@ vect_pattern_recog_1 (
if (vect_print_dump_info (REPORT_DETAILS))
{
fprintf (vect_dump, "pattern recognized: ");
- print_generic_expr (vect_dump, pattern_expr, TDF_SLIM);
+ print_gimple_stmt (vect_dump, pattern_stmt, 0, TDF_SLIM);
}
- /* Mark the stmts that are involved in the pattern,
- create a new stmt to express the pattern and insert it. */
- code = TREE_CODE (pattern_expr);
- pattern_type = TREE_TYPE (pattern_expr);
- var = create_tmp_var (pattern_type, "patt");
- add_referenced_var (var);
- var_name = make_ssa_name (var, NULL_TREE);
- pattern_expr = build_gimple_modify_stmt (var_name, pattern_expr);
- SSA_NAME_DEF_STMT (var_name) = pattern_expr;
- bsi_insert_before (&si, pattern_expr, BSI_SAME_STMT);
- ann = stmt_ann (pattern_expr);
- set_stmt_info (ann, new_stmt_vec_info (pattern_expr, loop_vinfo));
- pattern_stmt_info = vinfo_for_stmt (pattern_expr);
+ /* Mark the stmts that are involved in the pattern. */
+ gsi_insert_before (&si, pattern_stmt, GSI_SAME_STMT);
+ set_vinfo_for_stmt (pattern_stmt,
+ new_stmt_vec_info (pattern_stmt, loop_vinfo));
+ pattern_stmt_info = vinfo_for_stmt (pattern_stmt);
STMT_VINFO_RELATED_STMT (pattern_stmt_info) = stmt;
STMT_VINFO_DEF_TYPE (pattern_stmt_info) = STMT_VINFO_DEF_TYPE (stmt_info);
STMT_VINFO_VECTYPE (pattern_stmt_info) = pattern_vectype;
STMT_VINFO_IN_PATTERN_P (stmt_info) = true;
- STMT_VINFO_RELATED_STMT (stmt_info) = pattern_expr;
+ STMT_VINFO_RELATED_STMT (stmt_info) = pattern_stmt;
return;
}
@@ -804,10 +822,10 @@ vect_pattern_recog (loop_vec_info loop_vinfo)
struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo);
unsigned int nbbs = loop->num_nodes;
- block_stmt_iterator si;
- tree stmt;
+ gimple_stmt_iterator si;
+ gimple stmt;
unsigned int i, j;
- tree (* vect_recog_func_ptr) (tree, tree *, tree *);
+ gimple (* vect_recog_func_ptr) (gimple, tree *, tree *);
if (vect_print_dump_info (REPORT_DETAILS))
fprintf (vect_dump, "=== vect_pattern_recog ===");
@@ -817,9 +835,9 @@ vect_pattern_recog (loop_vec_info loop_vinfo)
for (i = 0; i < nbbs; i++)
{
basic_block bb = bbs[i];
- for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
+ for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
{
- stmt = bsi_stmt (si);
+ stmt = gsi_stmt (si);
/* Scan over all generic vect_recog_xxx_pattern functions. */
for (j = 0; j < NUM_PATTERNS; j++)
diff --git a/gcc/tree-vect-transform.c b/gcc/tree-vect-transform.c
index 1fa786da0b9..362d37cf861 100644
--- a/gcc/tree-vect-transform.c
+++ b/gcc/tree-vect-transform.c
@@ -46,20 +46,22 @@ along with GCC; see the file COPYING3. If not see
#include "real.h"
/* Utility functions for the code transformation. */
-static bool vect_transform_stmt (tree, block_stmt_iterator *, bool *, slp_tree);
+static bool vect_transform_stmt (gimple, gimple_stmt_iterator *, bool *,
+ slp_tree);
static tree vect_create_destination_var (tree, tree);
static tree vect_create_data_ref_ptr
- (tree, struct loop*, tree, tree *, tree *, bool, bool *);
+ (gimple, struct loop*, tree, tree *, gimple *, bool, bool *);
static tree vect_create_addr_base_for_vector_ref
- (tree, tree *, tree, struct loop *);
+ (gimple, gimple_seq *, tree, struct loop *);
static tree vect_get_new_vect_var (tree, enum vect_var_kind, const char *);
-static tree vect_get_vec_def_for_operand (tree, tree, tree *);
-static tree vect_init_vector (tree, tree, tree, block_stmt_iterator *);
+static tree vect_get_vec_def_for_operand (tree, gimple, tree *);
+static tree vect_init_vector (gimple, tree, tree, gimple_stmt_iterator *);
static void vect_finish_stmt_generation
- (tree stmt, tree vec_stmt, block_stmt_iterator *);
+ (gimple stmt, gimple vec_stmt, gimple_stmt_iterator *);
static bool vect_is_simple_cond (tree, loop_vec_info);
-static void vect_create_epilog_for_reduction (tree, tree, enum tree_code, tree);
-static tree get_initial_def_for_reduction (tree, tree, tree *);
+static void vect_create_epilog_for_reduction (tree, gimple, enum tree_code,
+ gimple);
+static tree get_initial_def_for_reduction (gimple, tree, tree *);
/* Utility function dealing with loop peeling (not peeling itself). */
static void vect_generate_tmps_on_preheader
@@ -73,7 +75,7 @@ static int vect_min_worthwhile_factor (enum tree_code);
static int
-cost_for_stmt (tree stmt)
+cost_for_stmt (gimple stmt)
{
stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
@@ -148,11 +150,11 @@ vect_estimate_min_profitable_iters (loop_vec_info loop_vinfo)
/* Requires loop versioning tests to handle misalignment. */
- if (VEC_length (tree, LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo)))
+ if (VEC_length (gimple, LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo)))
{
/* FIXME: Make cost depend on complexity of individual check. */
vec_outside_cost +=
- VEC_length (tree, LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo));
+ VEC_length (gimple, LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo));
if (vect_print_dump_info (REPORT_COST))
fprintf (vect_dump, "cost model: Adding cost of checks for loop "
"versioning to treat misalignment.\n");
@@ -168,7 +170,7 @@ vect_estimate_min_profitable_iters (loop_vec_info loop_vinfo)
"versioning aliasing.\n");
}
- if (VEC_length (tree, LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo))
+ if (VEC_length (gimple, LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo))
|| VEC_length (ddr_p, LOOP_VINFO_MAY_ALIAS_DDRS (loop_vinfo)))
{
vec_outside_cost += TARG_COND_TAKEN_BRANCH_COST;
@@ -188,7 +190,7 @@ vect_estimate_min_profitable_iters (loop_vec_info loop_vinfo)
for (i = 0; i < nbbs; i++)
{
- block_stmt_iterator si;
+ gimple_stmt_iterator si;
basic_block bb = bbs[i];
if (bb->loop_father == loop->inner)
@@ -196,9 +198,9 @@ vect_estimate_min_profitable_iters (loop_vec_info loop_vinfo)
else
factor = 1;
- for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
+ for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
{
- tree stmt = bsi_stmt (si);
+ gimple stmt = gsi_stmt (si);
stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
/* Skip stmts that are not vectorized inside the loop. */
if (!STMT_VINFO_RELEVANT_P (stmt_info)
@@ -338,7 +340,7 @@ vect_estimate_min_profitable_iters (loop_vec_info loop_vinfo)
if (runtime_test)
{
/* Cost model check occurs at versioning. */
- if (VEC_length (tree, LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo))
+ if (VEC_length (gimple, LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo))
|| VEC_length (ddr_p, LOOP_VINFO_MAY_ALIAS_DDRS (loop_vinfo)))
scalar_outside_cost += TARG_COND_NOT_TAKEN_BRANCH_COST;
else
@@ -451,18 +453,34 @@ vect_model_reduction_cost (stmt_vec_info stmt_info, enum tree_code reduc_code,
enum tree_code code;
optab optab;
tree vectype;
- tree orig_stmt;
+ gimple stmt, orig_stmt;
tree reduction_op;
enum machine_mode mode;
- tree operation = GIMPLE_STMT_OPERAND (STMT_VINFO_STMT (stmt_info), 1);
- int op_type = TREE_CODE_LENGTH (TREE_CODE (operation));
loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
+
/* Cost of reduction op inside loop. */
STMT_VINFO_INSIDE_OF_LOOP_COST (stmt_info) += ncopies * TARG_VEC_STMT_COST;
- reduction_op = TREE_OPERAND (operation, op_type-1);
+ stmt = STMT_VINFO_STMT (stmt_info);
+
+ switch (get_gimple_rhs_class (gimple_assign_rhs_code (stmt)))
+ {
+ case GIMPLE_SINGLE_RHS:
+ gcc_assert (TREE_OPERAND_LENGTH (gimple_assign_rhs1 (stmt)) == ternary_op);
+ reduction_op = TREE_OPERAND (gimple_assign_rhs1 (stmt), 2);
+ break;
+ case GIMPLE_UNARY_RHS:
+ reduction_op = gimple_assign_rhs1 (stmt);
+ break;
+ case GIMPLE_BINARY_RHS:
+ reduction_op = gimple_assign_rhs2 (stmt);
+ break;
+ default:
+ gcc_unreachable ();
+ }
+
vectype = get_vectype_for_scalar_type (TREE_TYPE (reduction_op));
if (!vectype)
{
@@ -480,7 +498,7 @@ vect_model_reduction_cost (stmt_vec_info stmt_info, enum tree_code reduc_code,
if (!orig_stmt)
orig_stmt = STMT_VINFO_STMT (stmt_info);
- code = TREE_CODE (GIMPLE_STMT_OPERAND (orig_stmt, 1));
+ code = gimple_assign_rhs_code (orig_stmt);
/* Add in cost for initial definition. */
outer_cost += TARG_SCALAR_TO_VEC_COST;
@@ -498,7 +516,7 @@ vect_model_reduction_cost (stmt_vec_info stmt_info, enum tree_code reduc_code,
{
int vec_size_in_bits = tree_low_cst (TYPE_SIZE (vectype), 1);
tree bitsize =
- TYPE_SIZE (TREE_TYPE ( GIMPLE_STMT_OPERAND (orig_stmt, 0)));
+ TYPE_SIZE (TREE_TYPE (gimple_assign_lhs (orig_stmt)));
int element_bitsize = tree_low_cst (bitsize, 1);
int nelements = vec_size_in_bits / element_bitsize;
@@ -590,7 +608,7 @@ vect_model_simple_cost (stmt_vec_info stmt_info, int ncopies,
static int
vect_cost_strided_group_size (stmt_vec_info stmt_info)
{
- tree first_stmt = DR_GROUP_FIRST_DR (stmt_info);
+ gimple first_stmt = DR_GROUP_FIRST_DR (stmt_info);
if (first_stmt == STMT_VINFO_STMT (stmt_info))
return DR_GROUP_SIZE (stmt_info);
@@ -661,7 +679,7 @@ vect_model_load_cost (stmt_vec_info stmt_info, int ncopies, slp_tree slp_node)
{
int group_size;
int alignment_support_cheme;
- tree first_stmt;
+ gimple first_stmt;
struct data_reference *dr = STMT_VINFO_DATA_REF (stmt_info), *first_dr;
int inside_cost = 0, outside_cost = 0;
@@ -846,21 +864,21 @@ vect_get_new_vect_var (tree type, enum vect_var_kind var_kind, const char *name)
FORNOW: We are only handling array accesses with step 1. */
static tree
-vect_create_addr_base_for_vector_ref (tree stmt,
- tree *new_stmt_list,
+vect_create_addr_base_for_vector_ref (gimple stmt,
+ gimple_seq *new_stmt_list,
tree offset,
struct loop *loop)
{
stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
struct data_reference *dr = STMT_VINFO_DATA_REF (stmt_info);
- struct loop *containing_loop = (bb_for_stmt (stmt))->loop_father;
+ struct loop *containing_loop = (gimple_bb (stmt))->loop_father;
tree data_ref_base = unshare_expr (DR_BASE_ADDRESS (dr));
tree base_name;
tree data_ref_base_var;
- tree new_base_stmt;
tree vec_stmt;
tree addr_base, addr_expr;
- tree dest, new_stmt;
+ tree dest;
+ gimple_seq seq = NULL;
tree base_offset = unshare_expr (DR_OFFSET (dr));
tree init = unshare_expr (DR_INIT (dr));
tree vect_ptr_type, addr_expr2;
@@ -883,17 +901,17 @@ vect_create_addr_base_for_vector_ref (tree stmt,
base_name = build_fold_indirect_ref (data_ref_base);
data_ref_base_var = create_tmp_var (TREE_TYPE (data_ref_base), "batmp");
add_referenced_var (data_ref_base_var);
- data_ref_base = force_gimple_operand (data_ref_base, &new_base_stmt,
- true, data_ref_base_var);
- append_to_statement_list_force(new_base_stmt, new_stmt_list);
+ data_ref_base = force_gimple_operand (data_ref_base, &seq, true,
+ data_ref_base_var);
+ gimple_seq_add_seq (new_stmt_list, seq);
/* Create base_offset */
base_offset = size_binop (PLUS_EXPR, base_offset, init);
base_offset = fold_convert (sizetype, base_offset);
dest = create_tmp_var (TREE_TYPE (base_offset), "base_off");
add_referenced_var (dest);
- base_offset = force_gimple_operand (base_offset, &new_stmt, true, dest);
- append_to_statement_list_force (new_stmt, new_stmt_list);
+ base_offset = force_gimple_operand (base_offset, &seq, true, dest);
+ gimple_seq_add_seq (new_stmt_list, seq);
if (offset)
{
@@ -903,8 +921,8 @@ vect_create_addr_base_for_vector_ref (tree stmt,
offset = fold_build2 (MULT_EXPR, TREE_TYPE (offset), offset, step);
base_offset = fold_build2 (PLUS_EXPR, TREE_TYPE (base_offset),
base_offset, offset);
- base_offset = force_gimple_operand (base_offset, &new_stmt, false, tmp);
- append_to_statement_list_force (new_stmt, new_stmt_list);
+ base_offset = force_gimple_operand (base_offset, &seq, false, tmp);
+ gimple_seq_add_seq (new_stmt_list, seq);
}
/* base + base_offset */
@@ -921,8 +939,8 @@ vect_create_addr_base_for_vector_ref (tree stmt,
addr_expr2 = vect_get_new_vect_var (vect_ptr_type, vect_pointer_var,
get_name (base_name));
add_referenced_var (addr_expr2);
- vec_stmt = force_gimple_operand (vec_stmt, &new_stmt, false, addr_expr2);
- append_to_statement_list_force (new_stmt, new_stmt_list);
+ vec_stmt = force_gimple_operand (vec_stmt, &seq, false, addr_expr2);
+ gimple_seq_add_seq (new_stmt_list, seq);
if (vect_print_dump_info (REPORT_DETAILS))
{
@@ -944,8 +962,8 @@ vect_create_addr_base_for_vector_ref (tree stmt,
Input:
1. STMT: a stmt that references memory. Expected to be of the form
- GIMPLE_MODIFY_STMT <name, data-ref> or
- GIMPLE_MODIFY_STMT <data-ref, name>.
+ GIMPLE_ASSIGN <name, data-ref> or
+ GIMPLE_ASSIGN <data-ref, name>.
2. AT_LOOP: the loop where the vector memref is to be created.
3. OFFSET (optional): an offset to be added to the initial address accessed
by the data-ref in STMT.
@@ -978,8 +996,8 @@ vect_create_addr_base_for_vector_ref (tree stmt,
4. Return the pointer. */
static tree
-vect_create_data_ref_ptr (tree stmt, struct loop *at_loop,
- tree offset, tree *initial_address, tree *ptr_incr,
+vect_create_data_ref_ptr (gimple stmt, struct loop *at_loop,
+ tree offset, tree *initial_address, gimple *ptr_incr,
bool only_init, bool *inv_p)
{
tree base_name;
@@ -987,23 +1005,23 @@ vect_create_data_ref_ptr (tree stmt, struct loop *at_loop,
loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
bool nested_in_vect_loop = nested_in_vect_loop_p (loop, stmt);
- struct loop *containing_loop = (bb_for_stmt (stmt))->loop_father;
+ struct loop *containing_loop = (gimple_bb (stmt))->loop_father;
tree vectype = STMT_VINFO_VECTYPE (stmt_info);
tree vect_ptr_type;
tree vect_ptr;
tree tag;
tree new_temp;
- tree vec_stmt;
- tree new_stmt_list = NULL_TREE;
+ gimple vec_stmt;
+ gimple_seq new_stmt_list = NULL;
edge pe;
basic_block new_bb;
tree vect_ptr_init;
struct data_reference *dr = STMT_VINFO_DATA_REF (stmt_info);
tree vptr;
- block_stmt_iterator incr_bsi;
+ gimple_stmt_iterator incr_gsi;
bool insert_after;
tree indx_before_incr, indx_after_incr;
- tree incr;
+ gimple incr;
tree step;
/* Check the step (evolution) of the load in LOOP, and record
@@ -1020,7 +1038,7 @@ vect_create_data_ref_ptr (tree stmt, struct loop *at_loop,
/* Create an expression for the first address accessed by this load
in LOOP. */
- base_name = build_fold_indirect_ref (unshare_expr (DR_BASE_ADDRESS (dr)));
+ base_name = build_fold_indirect_ref (unshare_expr (DR_BASE_ADDRESS (dr)));
if (vect_print_dump_info (REPORT_DETAILS))
{
@@ -1099,18 +1117,18 @@ vect_create_data_ref_ptr (tree stmt, struct loop *at_loop,
pe = loop_preheader_edge (loop);
if (new_stmt_list)
{
- new_bb = bsi_insert_on_edge_immediate (pe, new_stmt_list);
+ new_bb = gsi_insert_seq_on_edge_immediate (pe, new_stmt_list);
gcc_assert (!new_bb);
}
*initial_address = new_temp;
/* Create: p = (vectype *) initial_base */
- vec_stmt = fold_convert (vect_ptr_type, new_temp);
- vec_stmt = build_gimple_modify_stmt (vect_ptr, vec_stmt);
+ vec_stmt = gimple_build_assign (vect_ptr,
+ fold_convert (vect_ptr_type, new_temp));
vect_ptr_init = make_ssa_name (vect_ptr, vec_stmt);
- GIMPLE_STMT_OPERAND (vec_stmt, 0) = vect_ptr_init;
- new_bb = bsi_insert_on_edge_immediate (pe, vec_stmt);
+ gimple_assign_set_lhs (vec_stmt, vect_ptr_init);
+ new_bb = gsi_insert_on_edge_immediate (pe, vec_stmt);
gcc_assert (!new_bb);
@@ -1135,15 +1153,14 @@ vect_create_data_ref_ptr (tree stmt, struct loop *at_loop,
if (*inv_p)
step = size_zero_node;
- standard_iv_increment_position (loop, &incr_bsi, &insert_after);
+ standard_iv_increment_position (loop, &incr_gsi, &insert_after);
create_iv (vect_ptr_init,
fold_convert (vect_ptr_type, step),
- NULL_TREE, loop, &incr_bsi, insert_after,
+ NULL_TREE, loop, &incr_gsi, insert_after,
&indx_before_incr, &indx_after_incr);
- incr = bsi_stmt (incr_bsi);
- set_stmt_info (stmt_ann (incr),
- new_stmt_vec_info (incr, loop_vinfo));
+ incr = gsi_stmt (incr_gsi);
+ set_vinfo_for_stmt (incr, new_stmt_vec_info (incr, loop_vinfo));
/* Copy the points-to information if it exists. */
if (DR_PTR_INFO (dr))
@@ -1169,13 +1186,13 @@ vect_create_data_ref_ptr (tree stmt, struct loop *at_loop,
gcc_assert (nested_in_vect_loop);
if (!only_init)
{
- standard_iv_increment_position (containing_loop, &incr_bsi,
+ standard_iv_increment_position (containing_loop, &incr_gsi,
&insert_after);
create_iv (vptr, fold_convert (vect_ptr_type, DR_STEP (dr)), NULL_TREE,
- containing_loop, &incr_bsi, insert_after, &indx_before_incr,
+ containing_loop, &incr_gsi, insert_after, &indx_before_incr,
&indx_after_incr);
- incr = bsi_stmt (incr_bsi);
- set_stmt_info (stmt_ann (incr), new_stmt_vec_info (incr, loop_vinfo));
+ incr = gsi_stmt (incr_gsi);
+ set_vinfo_for_stmt (incr, new_stmt_vec_info (incr, loop_vinfo));
/* Copy the points-to information if it exists. */
if (DR_PTR_INFO (dr))
@@ -1230,16 +1247,15 @@ vect_create_data_ref_ptr (tree stmt, struct loop *at_loop,
*/
static tree
-bump_vector_ptr (tree dataref_ptr, tree ptr_incr, block_stmt_iterator *bsi,
- tree stmt, tree bump)
+bump_vector_ptr (tree dataref_ptr, gimple ptr_incr, gimple_stmt_iterator *gsi,
+ gimple stmt, tree bump)
{
stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
struct data_reference *dr = STMT_VINFO_DATA_REF (stmt_info);
tree vectype = STMT_VINFO_VECTYPE (stmt_info);
- tree vptr_type = TREE_TYPE (dataref_ptr);
tree ptr_var = SSA_NAME_VAR (dataref_ptr);
tree update = TYPE_SIZE_UNIT (vectype);
- tree incr_stmt;
+ gimple incr_stmt;
ssa_op_iter iter;
use_operand_p use_p;
tree new_dataref_ptr;
@@ -1247,12 +1263,11 @@ bump_vector_ptr (tree dataref_ptr, tree ptr_incr, block_stmt_iterator *bsi,
if (bump)
update = bump;
- incr_stmt = build_gimple_modify_stmt (ptr_var,
- build2 (POINTER_PLUS_EXPR, vptr_type,
- dataref_ptr, update));
+ incr_stmt = gimple_build_assign_with_ops (POINTER_PLUS_EXPR, ptr_var,
+ dataref_ptr, update);
new_dataref_ptr = make_ssa_name (ptr_var, incr_stmt);
- GIMPLE_STMT_OPERAND (incr_stmt, 0) = new_dataref_ptr;
- vect_finish_stmt_generation (stmt, incr_stmt, bsi);
+ gimple_assign_set_lhs (incr_stmt, new_dataref_ptr);
+ vect_finish_stmt_generation (stmt, incr_stmt, gsi);
/* Copy the points-to information if it exists. */
if (DR_PTR_INFO (dr))
@@ -1313,12 +1328,12 @@ vect_create_destination_var (tree scalar_dest, tree vectype)
It will be used in the vectorization of STMT. */
static tree
-vect_init_vector (tree stmt, tree vector_var, tree vector_type,
- block_stmt_iterator *bsi)
+vect_init_vector (gimple stmt, tree vector_var, tree vector_type,
+ gimple_stmt_iterator *gsi)
{
stmt_vec_info stmt_vinfo = vinfo_for_stmt (stmt);
tree new_var;
- tree init_stmt;
+ gimple init_stmt;
tree vec_oprnd;
edge pe;
tree new_temp;
@@ -1326,12 +1341,12 @@ vect_init_vector (tree stmt, tree vector_var, tree vector_type,
new_var = vect_get_new_vect_var (vector_type, vect_simple_var, "cst_");
add_referenced_var (new_var);
- init_stmt = build_gimple_modify_stmt (new_var, vector_var);
+ init_stmt = gimple_build_assign (new_var, vector_var);
new_temp = make_ssa_name (new_var, init_stmt);
- GIMPLE_STMT_OPERAND (init_stmt, 0) = new_temp;
+ gimple_assign_set_lhs (init_stmt, new_temp);
- if (bsi)
- vect_finish_stmt_generation (stmt, init_stmt, bsi);
+ if (gsi)
+ vect_finish_stmt_generation (stmt, init_stmt, gsi);
else
{
loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_vinfo);
@@ -1340,17 +1355,17 @@ vect_init_vector (tree stmt, tree vector_var, tree vector_type,
if (nested_in_vect_loop_p (loop, stmt))
loop = loop->inner;
pe = loop_preheader_edge (loop);
- new_bb = bsi_insert_on_edge_immediate (pe, init_stmt);
+ new_bb = gsi_insert_on_edge_immediate (pe, init_stmt);
gcc_assert (!new_bb);
}
if (vect_print_dump_info (REPORT_DETAILS))
{
fprintf (vect_dump, "created new init_stmt: ");
- print_generic_expr (vect_dump, init_stmt, TDF_SLIM);
+ print_gimple_stmt (vect_dump, init_stmt, 0, TDF_SLIM);
}
- vec_oprnd = GIMPLE_STMT_OPERAND (init_stmt, 0);
+ vec_oprnd = gimple_assign_lhs (init_stmt);
return vec_oprnd;
}
@@ -1364,8 +1379,8 @@ static void
vect_get_constant_vectors (slp_tree slp_node, VEC(tree,heap) **vec_oprnds,
unsigned int op_num)
{
- VEC (tree, heap) *stmts = SLP_TREE_SCALAR_STMTS (slp_node);
- tree stmt = VEC_index (tree, stmts, 0);
+ VEC (gimple, heap) *stmts = SLP_TREE_SCALAR_STMTS (slp_node);
+ gimple stmt = VEC_index (gimple, stmts, 0);
stmt_vec_info stmt_vinfo = vinfo_for_stmt (stmt);
tree vectype = STMT_VINFO_VECTYPE (stmt_vinfo);
int nunits = TYPE_VECTOR_SUBPARTS (vectype);
@@ -1373,8 +1388,8 @@ vect_get_constant_vectors (slp_tree slp_node, VEC(tree,heap) **vec_oprnds,
tree t = NULL_TREE;
int j, number_of_places_left_in_vector;
tree vector_type;
- tree op, vop, operation;
- int group_size = VEC_length (tree, stmts);
+ tree op, vop;
+ int group_size = VEC_length (gimple, stmts);
unsigned int vec_num, i;
int number_of_copies = 1;
bool is_store = false;
@@ -1407,13 +1422,12 @@ vect_get_constant_vectors (slp_tree slp_node, VEC(tree,heap) **vec_oprnds,
constant_p = true;
for (j = 0; j < number_of_copies; j++)
{
- for (i = group_size - 1; VEC_iterate (tree, stmts, i, stmt); i--)
+ for (i = group_size - 1; VEC_iterate (gimple, stmts, i, stmt); i--)
{
- operation = GIMPLE_STMT_OPERAND (stmt, 1);
if (is_store)
- op = operation;
+ op = gimple_assign_rhs1 (stmt);
else
- op = TREE_OPERAND (operation, op_num);
+ op = gimple_op (stmt, op_num + 1);
if (!CONSTANT_CLASS_P (op))
constant_p = false;
@@ -1471,17 +1485,17 @@ static void
vect_get_slp_vect_defs (slp_tree slp_node, VEC (tree,heap) **vec_oprnds)
{
tree vec_oprnd;
- tree vec_def_stmt;
+ gimple vec_def_stmt;
unsigned int i;
gcc_assert (SLP_TREE_VEC_STMTS (slp_node));
for (i = 0;
- VEC_iterate (tree, SLP_TREE_VEC_STMTS (slp_node), i, vec_def_stmt);
+ VEC_iterate (gimple, SLP_TREE_VEC_STMTS (slp_node), i, vec_def_stmt);
i++)
{
gcc_assert (vec_def_stmt);
- vec_oprnd = GIMPLE_STMT_OPERAND (vec_def_stmt, 0);
+ vec_oprnd = gimple_get_lhs (vec_def_stmt);
VEC_quick_push (tree, *vec_oprnds, vec_oprnd);
}
}
@@ -1500,7 +1514,8 @@ static void
vect_get_slp_defs (slp_tree slp_node, VEC (tree,heap) **vec_oprnds0,
VEC (tree,heap) **vec_oprnds1)
{
- tree operation, first_stmt;
+ gimple first_stmt;
+ enum tree_code code;
/* Allocate memory for vectorized defs. */
*vec_oprnds0 = VEC_alloc (tree, heap,
@@ -1515,14 +1530,14 @@ vect_get_slp_defs (slp_tree slp_node, VEC (tree,heap) **vec_oprnds0,
/* Build vectors from scalar defs. */
vect_get_constant_vectors (slp_node, vec_oprnds0, 0);
- first_stmt = VEC_index (tree, SLP_TREE_SCALAR_STMTS (slp_node), 0);
+ first_stmt = VEC_index (gimple, SLP_TREE_SCALAR_STMTS (slp_node), 0);
if (STMT_VINFO_DATA_REF (vinfo_for_stmt (first_stmt)))
/* Since we don't call this function with loads, this is a group of
stores. */
return;
- operation = GIMPLE_STMT_OPERAND (first_stmt, 1);
- if (TREE_OPERAND_LENGTH (operation) == unary_op || !vec_oprnds1)
+ code = gimple_assign_rhs_code (first_stmt);
+ if (get_gimple_rhs_class (code) != GIMPLE_BINARY_RHS || !vec_oprnds1)
return;
*vec_oprnds1 = VEC_alloc (tree, heap,
@@ -1550,12 +1565,12 @@ vect_get_slp_defs (slp_tree slp_node, VEC (tree,heap) **vec_oprnds0,
[X, X + S, X + 2*S, X + 3*S]. */
static tree
-get_initial_def_for_induction (tree iv_phi)
+get_initial_def_for_induction (gimple iv_phi)
{
stmt_vec_info stmt_vinfo = vinfo_for_stmt (iv_phi);
loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_vinfo);
struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
- tree scalar_type = TREE_TYPE (PHI_RESULT_TREE (iv_phi));
+ tree scalar_type = TREE_TYPE (gimple_phi_result (iv_phi));
tree vectype;
int nunits;
edge pe = loop_preheader_edge (loop);
@@ -1565,8 +1580,8 @@ get_initial_def_for_induction (tree iv_phi)
tree access_fn;
tree new_var;
tree new_name;
- tree init_stmt;
- tree induction_phi, induc_def, new_stmt, vec_def, vec_dest;
+ gimple init_stmt, induction_phi, new_stmt;
+ tree induc_def, vec_def, vec_dest;
tree init_expr, step_expr;
int vf = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
int i;
@@ -1575,14 +1590,14 @@ get_initial_def_for_induction (tree iv_phi)
tree expr;
stmt_vec_info phi_info = vinfo_for_stmt (iv_phi);
bool nested_in_vect_loop = false;
- tree stmts;
+ gimple_seq stmts = NULL;
imm_use_iterator imm_iter;
use_operand_p use_p;
- tree exit_phi;
+ gimple exit_phi;
edge latch_e;
tree loop_arg;
- block_stmt_iterator si;
- basic_block bb = bb_for_stmt (iv_phi);
+ gimple_stmt_iterator si;
+ basic_block bb = gimple_bb (iv_phi);
vectype = get_vectype_for_scalar_type (scalar_type);
gcc_assert (vectype);
@@ -1593,9 +1608,9 @@ get_initial_def_for_induction (tree iv_phi)
gcc_assert (ncopies >= 1);
/* Find the first insertion point in the BB. */
- si = bsi_after_labels (bb);
+ si = gsi_after_labels (bb);
- if (INTEGRAL_TYPE_P (scalar_type))
+ if (INTEGRAL_TYPE_P (scalar_type) || POINTER_TYPE_P (scalar_type))
step_expr = build_int_cst (scalar_type, 0);
else
step_expr = build_real (scalar_type, dconst0);
@@ -1608,7 +1623,7 @@ get_initial_def_for_induction (tree iv_phi)
}
else
iv_loop = loop;
- gcc_assert (iv_loop == (bb_for_stmt (iv_phi))->loop_father);
+ gcc_assert (iv_loop == (gimple_bb (iv_phi))->loop_father);
latch_e = loop_latch_edge (iv_loop);
loop_arg = PHI_ARG_DEF_FROM_EDGE (iv_phi, latch_e);
@@ -1639,7 +1654,7 @@ get_initial_def_for_induction (tree iv_phi)
new_name = force_gimple_operand (init_expr, &stmts, false, new_var);
if (stmts)
{
- new_bb = bsi_insert_on_edge_immediate (pe, stmts);
+ new_bb = gsi_insert_seq_on_edge_immediate (pe, stmts);
gcc_assert (!new_bb);
}
@@ -1647,21 +1662,21 @@ get_initial_def_for_induction (tree iv_phi)
t = tree_cons (NULL_TREE, init_expr, t);
for (i = 1; i < nunits; i++)
{
- tree tmp;
-
/* Create: new_name_i = new_name + step_expr */
- tmp = fold_build2 (PLUS_EXPR, scalar_type, new_name, step_expr);
- init_stmt = build_gimple_modify_stmt (new_var, tmp);
+ enum tree_code code = POINTER_TYPE_P (scalar_type)
+ ? POINTER_PLUS_EXPR : PLUS_EXPR;
+ init_stmt = gimple_build_assign_with_ops (code, new_var,
+ new_name, step_expr);
new_name = make_ssa_name (new_var, init_stmt);
- GIMPLE_STMT_OPERAND (init_stmt, 0) = new_name;
+ gimple_assign_set_lhs (init_stmt, new_name);
- new_bb = bsi_insert_on_edge_immediate (pe, init_stmt);
+ new_bb = gsi_insert_on_edge_immediate (pe, init_stmt);
gcc_assert (!new_bb);
if (vect_print_dump_info (REPORT_DETAILS))
{
fprintf (vect_dump, "created new init_stmt: ");
- print_generic_expr (vect_dump, init_stmt, TDF_SLIM);
+ print_gimple_stmt (vect_dump, init_stmt, 0, TDF_SLIM);
}
t = tree_cons (NULL_TREE, new_name, t);
}
@@ -1707,19 +1722,17 @@ get_initial_def_for_induction (tree iv_phi)
vec_dest = vect_get_new_vect_var (vectype, vect_simple_var, "vec_iv_");
add_referenced_var (vec_dest);
induction_phi = create_phi_node (vec_dest, iv_loop->header);
- set_stmt_info (get_stmt_ann (induction_phi),
- new_stmt_vec_info (induction_phi, loop_vinfo));
+ set_vinfo_for_stmt (induction_phi,
+ new_stmt_vec_info (induction_phi, loop_vinfo));
induc_def = PHI_RESULT (induction_phi);
/* Create the iv update inside the loop */
- new_stmt = build_gimple_modify_stmt (NULL_TREE,
- build2 (PLUS_EXPR, vectype,
- induc_def, vec_step));
+ new_stmt = gimple_build_assign_with_ops (PLUS_EXPR, vec_dest,
+ induc_def, vec_step);
vec_def = make_ssa_name (vec_dest, new_stmt);
- GIMPLE_STMT_OPERAND (new_stmt, 0) = vec_def;
- bsi_insert_before (&si, new_stmt, BSI_SAME_STMT);
- set_stmt_info (get_stmt_ann (new_stmt),
- new_stmt_vec_info (new_stmt, loop_vinfo));
+ gimple_assign_set_lhs (new_stmt, vec_def);
+ gsi_insert_before (&si, new_stmt, GSI_SAME_STMT);
+ set_vinfo_for_stmt (new_stmt, new_stmt_vec_info (new_stmt, loop_vinfo));
/* Set the arguments of the phi node: */
add_phi_arg (induction_phi, vec_init, pe);
@@ -1752,16 +1765,15 @@ get_initial_def_for_induction (tree iv_phi)
prev_stmt_vinfo = vinfo_for_stmt (induction_phi);
for (i = 1; i < ncopies; i++)
{
- tree tmp;
-
/* vec_i = vec_prev + vec_step */
- tmp = build2 (PLUS_EXPR, vectype, vec_def, vec_step);
- new_stmt = build_gimple_modify_stmt (NULL_TREE, tmp);
+ new_stmt = gimple_build_assign_with_ops (PLUS_EXPR, vec_dest,
+ vec_def, vec_step);
vec_def = make_ssa_name (vec_dest, new_stmt);
- GIMPLE_STMT_OPERAND (new_stmt, 0) = vec_def;
- bsi_insert_before (&si, new_stmt, BSI_SAME_STMT);
- set_stmt_info (get_stmt_ann (new_stmt),
- new_stmt_vec_info (new_stmt, loop_vinfo));
+ gimple_assign_set_lhs (new_stmt, vec_def);
+
+ gsi_insert_before (&si, new_stmt, GSI_SAME_STMT);
+ set_vinfo_for_stmt (new_stmt,
+ new_stmt_vec_info (new_stmt, loop_vinfo));
STMT_VINFO_RELATED_STMT (prev_stmt_vinfo) = new_stmt;
prev_stmt_vinfo = vinfo_for_stmt (new_stmt);
}
@@ -1774,7 +1786,7 @@ get_initial_def_for_induction (tree iv_phi)
exit_phi = NULL;
FOR_EACH_IMM_USE_FAST (use_p, imm_iter, loop_arg)
{
- if (!flow_bb_inside_loop_p (iv_loop, bb_for_stmt (USE_STMT (use_p))))
+ if (!flow_bb_inside_loop_p (iv_loop, gimple_bb (USE_STMT (use_p))))
{
exit_phi = USE_STMT (use_p);
break;
@@ -1792,7 +1804,7 @@ get_initial_def_for_induction (tree iv_phi)
if (vect_print_dump_info (REPORT_DETAILS))
{
fprintf (vect_dump, "vector of inductions after inner-loop:");
- print_generic_expr (vect_dump, new_stmt, TDF_SLIM);
+ print_gimple_stmt (vect_dump, new_stmt, 0, TDF_SLIM);
}
}
}
@@ -1801,9 +1813,9 @@ get_initial_def_for_induction (tree iv_phi)
if (vect_print_dump_info (REPORT_DETAILS))
{
fprintf (vect_dump, "transform induction: created def-use cycle:");
- print_generic_expr (vect_dump, induction_phi, TDF_SLIM);
+ print_gimple_stmt (vect_dump, induction_phi, 0, TDF_SLIM);
fprintf (vect_dump, "\n");
- print_generic_expr (vect_dump, SSA_NAME_DEF_STMT (vec_def), TDF_SLIM);
+ print_gimple_stmt (vect_dump, SSA_NAME_DEF_STMT (vec_def), 0, TDF_SLIM);
}
STMT_VINFO_VEC_STMT (phi_info) = induction_phi;
@@ -1823,11 +1835,11 @@ get_initial_def_for_induction (tree iv_phi)
needs to be introduced. */
static tree
-vect_get_vec_def_for_operand (tree op, tree stmt, tree *scalar_def)
+vect_get_vec_def_for_operand (tree op, gimple stmt, tree *scalar_def)
{
tree vec_oprnd;
- tree vec_stmt;
- tree def_stmt;
+ gimple vec_stmt;
+ gimple def_stmt;
stmt_vec_info def_stmt_info = NULL;
stmt_vec_info stmt_vinfo = vinfo_for_stmt (stmt);
tree vectype = STMT_VINFO_VECTYPE (stmt_vinfo);
@@ -1860,7 +1872,7 @@ vect_get_vec_def_for_operand (tree op, tree stmt, tree *scalar_def)
if (def_stmt)
{
fprintf (vect_dump, " def_stmt = ");
- print_generic_expr (vect_dump, def_stmt, TDF_SLIM);
+ print_gimple_stmt (vect_dump, def_stmt, 0, TDF_SLIM);
}
}
@@ -1913,16 +1925,18 @@ vect_get_vec_def_for_operand (tree op, tree stmt, tree *scalar_def)
case vect_loop_def:
{
if (scalar_def)
- *scalar_def = def_stmt;
+ *scalar_def = NULL/* FIXME tuples: def_stmt*/;
/* Get the def from the vectorized stmt. */
def_stmt_info = vinfo_for_stmt (def_stmt);
vec_stmt = STMT_VINFO_VEC_STMT (def_stmt_info);
gcc_assert (vec_stmt);
- if (TREE_CODE (vec_stmt) == PHI_NODE)
+ if (gimple_code (vec_stmt) == GIMPLE_PHI)
vec_oprnd = PHI_RESULT (vec_stmt);
+ else if (is_gimple_call (vec_stmt))
+ vec_oprnd = gimple_call_lhs (vec_stmt);
else
- vec_oprnd = GIMPLE_STMT_OPERAND (vec_stmt, 0);
+ vec_oprnd = gimple_assign_lhs (vec_stmt);
return vec_oprnd;
}
@@ -1931,8 +1945,8 @@ vect_get_vec_def_for_operand (tree op, tree stmt, tree *scalar_def)
{
struct loop *loop;
- gcc_assert (TREE_CODE (def_stmt) == PHI_NODE);
- loop = (bb_for_stmt (def_stmt))->loop_father;
+ gcc_assert (gimple_code (def_stmt) == GIMPLE_PHI);
+ loop = (gimple_bb (def_stmt))->loop_father;
/* Get the def before the loop */
op = PHI_ARG_DEF_FROM_EDGE (def_stmt, loop_preheader_edge (loop));
@@ -1942,12 +1956,12 @@ vect_get_vec_def_for_operand (tree op, tree stmt, tree *scalar_def)
/* Case 5: operand is defined by loop-header phi - induction. */
case vect_induction_def:
{
- gcc_assert (TREE_CODE (def_stmt) == PHI_NODE);
+ gcc_assert (gimple_code (def_stmt) == GIMPLE_PHI);
/* Get the def from the vectorized stmt. */
def_stmt_info = vinfo_for_stmt (def_stmt);
vec_stmt = STMT_VINFO_VEC_STMT (def_stmt_info);
- gcc_assert (vec_stmt && (TREE_CODE (vec_stmt) == PHI_NODE));
+ gcc_assert (vec_stmt && gimple_code (vec_stmt) == GIMPLE_PHI);
vec_oprnd = PHI_RESULT (vec_stmt);
return vec_oprnd;
}
@@ -2017,7 +2031,7 @@ vect_get_vec_def_for_operand (tree op, tree stmt, tree *scalar_def)
static tree
vect_get_vec_def_for_stmt_copy (enum vect_def_type dt, tree vec_oprnd)
{
- tree vec_stmt_for_operand;
+ gimple vec_stmt_for_operand;
stmt_vec_info def_stmt_info;
/* Do nothing; can reuse same def. */
@@ -2029,7 +2043,7 @@ vect_get_vec_def_for_stmt_copy (enum vect_def_type dt, tree vec_oprnd)
gcc_assert (def_stmt_info);
vec_stmt_for_operand = STMT_VINFO_RELATED_STMT (def_stmt_info);
gcc_assert (vec_stmt_for_operand);
- vec_oprnd = GIMPLE_STMT_OPERAND (vec_stmt_for_operand, 0);
+ vec_oprnd = gimple_get_lhs (vec_stmt_for_operand);
return vec_oprnd;
}
@@ -2059,8 +2073,9 @@ vect_get_vec_defs_for_stmt_copy (enum vect_def_type *dt,
/* Get vectorized definitions for OP0 and OP1, or SLP_NODE if it is not NULL. */
static void
-vect_get_vec_defs (tree op0, tree op1, tree stmt, VEC(tree,heap) **vec_oprnds0,
- VEC(tree,heap) **vec_oprnds1, slp_tree slp_node)
+vect_get_vec_defs (tree op0, tree op1, gimple stmt,
+ VEC(tree,heap) **vec_oprnds0, VEC(tree,heap) **vec_oprnds1,
+ slp_tree slp_node)
{
if (slp_node)
vect_get_slp_defs (slp_node, vec_oprnds0, vec_oprnds1);
@@ -2087,30 +2102,29 @@ vect_get_vec_defs (tree op0, tree op1, tree stmt, VEC(tree,heap) **vec_oprnds0,
Insert a new stmt. */
static void
-vect_finish_stmt_generation (tree stmt, tree vec_stmt,
- block_stmt_iterator *bsi)
+vect_finish_stmt_generation (gimple stmt, gimple vec_stmt,
+ gimple_stmt_iterator *gsi)
{
stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
- gcc_assert (stmt == bsi_stmt (*bsi));
- gcc_assert (TREE_CODE (stmt) != LABEL_EXPR);
+ gcc_assert (stmt == gsi_stmt (*gsi));
+ gcc_assert (gimple_code (stmt) != GIMPLE_LABEL);
- bsi_insert_before (bsi, vec_stmt, BSI_SAME_STMT);
+ gsi_insert_before (gsi, vec_stmt, GSI_SAME_STMT);
- set_stmt_info (get_stmt_ann (vec_stmt),
- new_stmt_vec_info (vec_stmt, loop_vinfo));
+ set_vinfo_for_stmt (vec_stmt, new_stmt_vec_info (vec_stmt, loop_vinfo));
if (vect_print_dump_info (REPORT_DETAILS))
{
fprintf (vect_dump, "add new stmt: ");
- print_generic_expr (vect_dump, vec_stmt, TDF_SLIM);
+ print_gimple_stmt (vect_dump, vec_stmt, 0, TDF_SLIM);
}
- /* Make sure bsi points to the stmt that is being vectorized. */
- gcc_assert (stmt == bsi_stmt (*bsi));
+ /* Make sure gsi points to the stmt that is being vectorized. */
+ gcc_assert (stmt == gsi_stmt (*gsi));
- SET_EXPR_LOCATION (vec_stmt, EXPR_LOCATION (stmt));
+ gimple_set_location (vec_stmt, gimple_location (stmt));
}
@@ -2158,14 +2172,14 @@ vect_finish_stmt_generation (tree stmt, tree vec_stmt,
A cost model should help decide between these two schemes. */
static tree
-get_initial_def_for_reduction (tree stmt, tree init_val, tree *adjustment_def)
+get_initial_def_for_reduction (gimple stmt, tree init_val, tree *adjustment_def)
{
stmt_vec_info stmt_vinfo = vinfo_for_stmt (stmt);
loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_vinfo);
struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
tree vectype = STMT_VINFO_VECTYPE (stmt_vinfo);
int nunits = TYPE_VECTOR_SUBPARTS (vectype);
- enum tree_code code = TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 1));
+ enum tree_code code = gimple_assign_rhs_code (stmt);
tree type = TREE_TYPE (init_val);
tree vecdef;
tree def_for_init;
@@ -2179,7 +2193,7 @@ get_initial_def_for_reduction (tree stmt, tree init_val, tree *adjustment_def)
if (nested_in_vect_loop_p (loop, stmt))
nested_in_vect_loop = true;
else
- gcc_assert (loop == (bb_for_stmt (stmt))->loop_father);
+ gcc_assert (loop == (gimple_bb (stmt))->loop_father);
vecdef = vect_get_vec_def_for_operand (init_val, stmt, NULL);
@@ -2267,8 +2281,9 @@ get_initial_def_for_reduction (tree stmt, tree init_val, tree *adjustment_def)
*/
static void
-vect_create_epilog_for_reduction (tree vect_def, tree stmt,
- enum tree_code reduc_code, tree reduction_phi)
+vect_create_epilog_for_reduction (tree vect_def, gimple stmt,
+ enum tree_code reduc_code,
+ gimple reduction_phi)
{
stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
tree vectype;
@@ -2278,15 +2293,16 @@ vect_create_epilog_for_reduction (tree vect_def, tree stmt,
basic_block exit_bb;
tree scalar_dest;
tree scalar_type;
- tree new_phi;
- block_stmt_iterator exit_bsi;
+ gimple new_phi;
+ gimple_stmt_iterator exit_gsi;
tree vec_dest;
tree new_temp = NULL_TREE;
tree new_name;
- tree epilog_stmt = NULL_TREE;
- tree new_scalar_dest, exit_phi, new_dest;
+ gimple epilog_stmt = NULL;
+ tree new_scalar_dest, new_dest;
+ gimple exit_phi;
tree bitsize, bitpos, bytesize;
- enum tree_code code = TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 1));
+ enum tree_code code = gimple_assign_rhs_code (stmt);
tree adjustment_def;
tree vec_initial_def;
tree orig_name;
@@ -2294,12 +2310,10 @@ vect_create_epilog_for_reduction (tree vect_def, tree stmt,
use_operand_p use_p;
bool extract_scalar_result = false;
tree reduction_op, expr;
- tree orig_stmt;
- tree use_stmt;
- tree operation = GIMPLE_STMT_OPERAND (stmt, 1);
+ gimple orig_stmt;
+ gimple use_stmt;
bool nested_in_vect_loop = false;
- int op_type;
- VEC(tree,heap) *phis = NULL;
+ VEC(gimple,heap) *phis = NULL;
int i;
if (nested_in_vect_loop_p (loop, stmt))
@@ -2308,8 +2322,22 @@ vect_create_epilog_for_reduction (tree vect_def, tree stmt,
nested_in_vect_loop = true;
}
- op_type = TREE_OPERAND_LENGTH (operation);
- reduction_op = TREE_OPERAND (operation, op_type-1);
+ switch (get_gimple_rhs_class (gimple_assign_rhs_code (stmt)))
+ {
+ case GIMPLE_SINGLE_RHS:
+ gcc_assert (TREE_OPERAND_LENGTH (gimple_assign_rhs1 (stmt)) == ternary_op);
+ reduction_op = TREE_OPERAND (gimple_assign_rhs1 (stmt), 2);
+ break;
+ case GIMPLE_UNARY_RHS:
+ reduction_op = gimple_assign_rhs1 (stmt);
+ break;
+ case GIMPLE_BINARY_RHS:
+ reduction_op = gimple_assign_rhs2 (stmt);
+ break;
+ default:
+ gcc_unreachable ();
+ }
+
vectype = get_vectype_for_scalar_type (TREE_TYPE (reduction_op));
gcc_assert (vectype);
mode = TYPE_MODE (vectype);
@@ -2330,9 +2358,9 @@ vect_create_epilog_for_reduction (tree vect_def, tree stmt,
if (vect_print_dump_info (REPORT_DETAILS))
{
fprintf (vect_dump, "transform reduction: created def-use cycle:");
- print_generic_expr (vect_dump, reduction_phi, TDF_SLIM);
+ print_gimple_stmt (vect_dump, reduction_phi, 0, TDF_SLIM);
fprintf (vect_dump, "\n");
- print_generic_expr (vect_dump, SSA_NAME_DEF_STMT (vect_def), TDF_SLIM);
+ print_gimple_stmt (vect_dump, SSA_NAME_DEF_STMT (vect_def), 0, TDF_SLIM);
}
@@ -2369,7 +2397,7 @@ vect_create_epilog_for_reduction (tree vect_def, tree stmt,
exit_bb = single_exit (loop)->dest;
new_phi = create_phi_node (SSA_NAME_VAR (vect_def), exit_bb);
SET_PHI_ARG_DEF (new_phi, single_exit (loop)->dest_idx, vect_def);
- exit_bsi = bsi_after_labels (exit_bb);
+ exit_gsi = gsi_after_labels (exit_bb);
/* 2.2 Get the relevant tree-code to use in the epilog for schemes 2,3
(i.e. when reduc_code is not available) and in the final adjustment
@@ -2393,8 +2421,8 @@ vect_create_epilog_for_reduction (tree vect_def, tree stmt,
gcc_assert (STMT_VINFO_IN_PATTERN_P (stmt_vinfo));
gcc_assert (STMT_VINFO_RELATED_STMT (stmt_vinfo) == stmt);
}
- code = TREE_CODE (GIMPLE_STMT_OPERAND (orig_stmt, 1));
- scalar_dest = GIMPLE_STMT_OPERAND (orig_stmt, 0);
+ code = gimple_assign_rhs_code (orig_stmt);
+ scalar_dest = gimple_assign_lhs (orig_stmt);
scalar_type = TREE_TYPE (scalar_dest);
new_scalar_dest = vect_create_destination_var (scalar_dest, NULL);
bitsize = TYPE_SIZE (scalar_type);
@@ -2424,10 +2452,10 @@ vect_create_epilog_for_reduction (tree vect_def, tree stmt,
vec_dest = vect_create_destination_var (scalar_dest, vectype);
tmp = build1 (reduc_code, vectype, PHI_RESULT (new_phi));
- epilog_stmt = build_gimple_modify_stmt (vec_dest, tmp);
+ epilog_stmt = gimple_build_assign (vec_dest, tmp);
new_temp = make_ssa_name (vec_dest, epilog_stmt);
- GIMPLE_STMT_OPERAND (epilog_stmt, 0) = new_temp;
- bsi_insert_before (&exit_bsi, epilog_stmt, BSI_SAME_STMT);
+ gimple_assign_set_lhs (epilog_stmt, new_temp);
+ gsi_insert_before (&exit_gsi, epilog_stmt, GSI_SAME_STMT);
extract_scalar_result = true;
}
@@ -2480,17 +2508,17 @@ vect_create_epilog_for_reduction (tree vect_def, tree stmt,
bit_offset /= 2)
{
tree bitpos = size_int (bit_offset);
- tree tmp = build2 (shift_code, vectype, new_temp, bitpos);
- epilog_stmt = build_gimple_modify_stmt (vec_dest, tmp);
+ epilog_stmt = gimple_build_assign_with_ops (shift_code, vec_dest,
+ new_temp, bitpos);
new_name = make_ssa_name (vec_dest, epilog_stmt);
- GIMPLE_STMT_OPERAND (epilog_stmt, 0) = new_name;
- bsi_insert_before (&exit_bsi, epilog_stmt, BSI_SAME_STMT);
+ gimple_assign_set_lhs (epilog_stmt, new_name);
+ gsi_insert_before (&exit_gsi, epilog_stmt, GSI_SAME_STMT);
- tmp = build2 (code, vectype, new_name, new_temp);
- epilog_stmt = build_gimple_modify_stmt (vec_dest, tmp);
+ epilog_stmt = gimple_build_assign_with_ops (code, vec_dest,
+ new_name, new_temp);
new_temp = make_ssa_name (vec_dest, epilog_stmt);
- GIMPLE_STMT_OPERAND (epilog_stmt, 0) = new_temp;
- bsi_insert_before (&exit_bsi, epilog_stmt, BSI_SAME_STMT);
+ gimple_assign_set_lhs (epilog_stmt, new_temp);
+ gsi_insert_before (&exit_gsi, epilog_stmt, GSI_SAME_STMT);
}
extract_scalar_result = true;
@@ -2516,30 +2544,30 @@ vect_create_epilog_for_reduction (tree vect_def, tree stmt,
vec_size_in_bits = tree_low_cst (TYPE_SIZE (vectype), 1);
rhs = build3 (BIT_FIELD_REF, scalar_type, vec_temp, bitsize,
bitsize_zero_node);
- epilog_stmt = build_gimple_modify_stmt (new_scalar_dest, rhs);
+ epilog_stmt = gimple_build_assign (new_scalar_dest, rhs);
new_temp = make_ssa_name (new_scalar_dest, epilog_stmt);
- GIMPLE_STMT_OPERAND (epilog_stmt, 0) = new_temp;
- bsi_insert_before (&exit_bsi, epilog_stmt, BSI_SAME_STMT);
+ gimple_assign_set_lhs (epilog_stmt, new_temp);
+ gsi_insert_before (&exit_gsi, epilog_stmt, GSI_SAME_STMT);
for (bit_offset = element_bitsize;
bit_offset < vec_size_in_bits;
bit_offset += element_bitsize)
{
- tree tmp;
tree bitpos = bitsize_int (bit_offset);
tree rhs = build3 (BIT_FIELD_REF, scalar_type, vec_temp, bitsize,
bitpos);
- epilog_stmt = build_gimple_modify_stmt (new_scalar_dest, rhs);
+ epilog_stmt = gimple_build_assign (new_scalar_dest, rhs);
new_name = make_ssa_name (new_scalar_dest, epilog_stmt);
- GIMPLE_STMT_OPERAND (epilog_stmt, 0) = new_name;
- bsi_insert_before (&exit_bsi, epilog_stmt, BSI_SAME_STMT);
+ gimple_assign_set_lhs (epilog_stmt, new_name);
+ gsi_insert_before (&exit_gsi, epilog_stmt, GSI_SAME_STMT);
- tmp = build2 (code, scalar_type, new_name, new_temp);
- epilog_stmt = build_gimple_modify_stmt (new_scalar_dest, tmp);
+ epilog_stmt = gimple_build_assign_with_ops (code,
+ new_scalar_dest,
+ new_name, new_temp);
new_temp = make_ssa_name (new_scalar_dest, epilog_stmt);
- GIMPLE_STMT_OPERAND (epilog_stmt, 0) = new_temp;
- bsi_insert_before (&exit_bsi, epilog_stmt, BSI_SAME_STMT);
+ gimple_assign_set_lhs (epilog_stmt, new_temp);
+ gsi_insert_before (&exit_gsi, epilog_stmt, GSI_SAME_STMT);
}
extract_scalar_result = false;
@@ -2565,10 +2593,10 @@ vect_create_epilog_for_reduction (tree vect_def, tree stmt,
bitpos = bitsize_zero_node;
rhs = build3 (BIT_FIELD_REF, scalar_type, new_temp, bitsize, bitpos);
- epilog_stmt = build_gimple_modify_stmt (new_scalar_dest, rhs);
+ epilog_stmt = gimple_build_assign (new_scalar_dest, rhs);
new_temp = make_ssa_name (new_scalar_dest, epilog_stmt);
- GIMPLE_STMT_OPERAND (epilog_stmt, 0) = new_temp;
- bsi_insert_before (&exit_bsi, epilog_stmt, BSI_SAME_STMT);
+ gimple_assign_set_lhs (epilog_stmt, new_temp);
+ gsi_insert_before (&exit_gsi, epilog_stmt, GSI_SAME_STMT);
}
vect_finalize_reduction:
@@ -2592,10 +2620,11 @@ vect_finalize_reduction:
expr = build2 (code, scalar_type, new_temp, adjustment_def);
new_dest = vect_create_destination_var (scalar_dest, scalar_type);
}
- epilog_stmt = build_gimple_modify_stmt (new_dest, expr);
+ epilog_stmt = gimple_build_assign (new_dest, expr);
new_temp = make_ssa_name (new_dest, epilog_stmt);
- GIMPLE_STMT_OPERAND (epilog_stmt, 0) = new_temp;
- bsi_insert_before (&exit_bsi, epilog_stmt, BSI_SAME_STMT);
+ gimple_assign_set_lhs (epilog_stmt, new_temp);
+ SSA_NAME_DEF_STMT (new_temp) = epilog_stmt;
+ gsi_insert_before (&exit_gsi, epilog_stmt, GSI_SAME_STMT);
}
@@ -2605,19 +2634,19 @@ vect_finalize_reduction:
Find the loop-closed-use at the loop exit of the original scalar result.
(The reduction result is expected to have two immediate uses - one at the
latch block, and one at the loop exit). */
- phis = VEC_alloc (tree, heap, 10);
+ phis = VEC_alloc (gimple, heap, 10);
FOR_EACH_IMM_USE_FAST (use_p, imm_iter, scalar_dest)
{
- if (!flow_bb_inside_loop_p (loop, bb_for_stmt (USE_STMT (use_p))))
+ if (!flow_bb_inside_loop_p (loop, gimple_bb (USE_STMT (use_p))))
{
exit_phi = USE_STMT (use_p);
- VEC_quick_push (tree, phis, exit_phi);
+ VEC_quick_push (gimple, phis, exit_phi);
}
}
/* We expect to have found an exit_phi because of loop-closed-ssa form. */
- gcc_assert (!VEC_empty (tree, phis));
+ gcc_assert (!VEC_empty (gimple, phis));
- for (i = 0; VEC_iterate (tree, phis, i, exit_phi); i++)
+ for (i = 0; VEC_iterate (gimple, phis, i, exit_phi); i++)
{
if (nested_in_vect_loop)
{
@@ -2630,8 +2659,8 @@ vect_finalize_reduction:
epilog_stmt = adjustment_def ? epilog_stmt : new_phi;
STMT_VINFO_VEC_STMT (stmt_vinfo) = epilog_stmt;
- set_stmt_info (get_stmt_ann (epilog_stmt),
- new_stmt_vec_info (epilog_stmt, loop_vinfo));
+ set_vinfo_for_stmt (epilog_stmt,
+ new_stmt_vec_info (epilog_stmt, loop_vinfo));
continue;
}
@@ -2641,7 +2670,7 @@ vect_finalize_reduction:
FOR_EACH_IMM_USE_ON_STMT (use_p, imm_iter)
SET_USE (use_p, new_temp);
}
- VEC_free (tree, heap, phis);
+ VEC_free (gimple, heap, phis);
}
@@ -2686,28 +2715,28 @@ vect_finalize_reduction:
does *NOT* necessarily hold for reduction patterns. */
bool
-vectorizable_reduction (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt)
+vectorizable_reduction (gimple stmt, gimple_stmt_iterator *gsi,
+ gimple *vec_stmt)
{
tree vec_dest;
tree scalar_dest;
- tree op;
tree loop_vec_def0 = NULL_TREE, loop_vec_def1 = NULL_TREE;
stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
tree vectype = STMT_VINFO_VECTYPE (stmt_info);
loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
- tree operation;
enum tree_code code, orig_code, epilog_reduc_code = 0;
enum machine_mode vec_mode;
int op_type;
optab optab, reduc_optab;
tree new_temp = NULL_TREE;
- tree def, def_stmt;
+ tree def;
+ gimple def_stmt;
enum vect_def_type dt;
- tree new_phi;
+ gimple new_phi;
tree scalar_type;
bool is_simple_use;
- tree orig_stmt;
+ gimple orig_stmt;
stmt_vec_info orig_stmt_info;
tree expr = NULL_TREE;
int i;
@@ -2715,8 +2744,9 @@ vectorizable_reduction (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt)
int ncopies = LOOP_VINFO_VECT_FACTOR (loop_vinfo) / nunits;
stmt_vec_info prev_stmt_info;
tree reduc_def;
- tree new_stmt = NULL_TREE;
+ gimple new_stmt = NULL;
int j;
+ tree ops[3];
if (nested_in_vect_loop_p (loop, stmt))
{
@@ -2772,14 +2802,41 @@ vectorizable_reduction (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt)
inside the loop body. The last operand is the reduction variable,
which is defined by the loop-header-phi. */
- gcc_assert (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT);
+ gcc_assert (is_gimple_assign (stmt));
- operation = GIMPLE_STMT_OPERAND (stmt, 1);
- code = TREE_CODE (operation);
- op_type = TREE_OPERAND_LENGTH (operation);
- if (op_type != binary_op && op_type != ternary_op)
- return false;
- scalar_dest = GIMPLE_STMT_OPERAND (stmt, 0);
+ /* Flatten RHS */
+ switch (get_gimple_rhs_class (gimple_assign_rhs_code (stmt)))
+ {
+ case GIMPLE_SINGLE_RHS:
+ op_type = TREE_OPERAND_LENGTH (gimple_assign_rhs1 (stmt));
+ if (op_type == ternary_op)
+ {
+ tree rhs = gimple_assign_rhs1 (stmt);
+ ops[0] = TREE_OPERAND (rhs, 0);
+ ops[1] = TREE_OPERAND (rhs, 1);
+ ops[2] = TREE_OPERAND (rhs, 2);
+ code = TREE_CODE (rhs);
+ }
+ else
+ return false;
+ break;
+
+ case GIMPLE_BINARY_RHS:
+ code = gimple_assign_rhs_code (stmt);
+ op_type = TREE_CODE_LENGTH (code);
+ gcc_assert (op_type == binary_op);
+ ops[0] = gimple_assign_rhs1 (stmt);
+ ops[1] = gimple_assign_rhs2 (stmt);
+ break;
+
+ case GIMPLE_UNARY_RHS:
+ return false;
+
+ default:
+ gcc_unreachable ();
+ }
+
+ scalar_dest = gimple_assign_lhs (stmt);
scalar_type = TREE_TYPE (scalar_dest);
if (!POINTER_TYPE_P (scalar_type) && !INTEGRAL_TYPE_P (scalar_type)
&& !SCALAR_FLOAT_TYPE_P (scalar_type))
@@ -2789,8 +2846,8 @@ vectorizable_reduction (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt)
The last use is the reduction variable. */
for (i = 0; i < op_type-1; i++)
{
- op = TREE_OPERAND (operation, i);
- is_simple_use = vect_is_simple_use (op, loop_vinfo, &def_stmt, &def, &dt);
+ is_simple_use = vect_is_simple_use (ops[i], loop_vinfo, &def_stmt,
+ &def, &dt);
gcc_assert (is_simple_use);
if (dt != vect_loop_def
&& dt != vect_invariant_def
@@ -2799,11 +2856,10 @@ vectorizable_reduction (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt)
return false;
}
- op = TREE_OPERAND (operation, i);
- is_simple_use = vect_is_simple_use (op, loop_vinfo, &def_stmt, &def, &dt);
+ is_simple_use = vect_is_simple_use (ops[i], loop_vinfo, &def_stmt, &def, &dt);
gcc_assert (is_simple_use);
gcc_assert (dt == vect_reduction_def);
- gcc_assert (TREE_CODE (def_stmt) == PHI_NODE);
+ gcc_assert (gimple_code (def_stmt) == GIMPLE_PHI);
if (orig_stmt)
gcc_assert (orig_stmt == vect_is_simple_reduction (loop_vinfo, def_stmt));
else
@@ -2883,7 +2939,7 @@ vectorizable_reduction (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt)
{
/* This is a reduction pattern: get the vectype from the type of the
reduction variable, and get the tree-code from orig_stmt. */
- orig_code = TREE_CODE (GIMPLE_STMT_OPERAND (orig_stmt, 1));
+ orig_code = gimple_assign_rhs_code (orig_stmt);
vectype = get_vectype_for_scalar_type (TREE_TYPE (def));
if (!vectype)
{
@@ -2951,12 +3007,10 @@ vectorizable_reduction (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt)
/* Handle uses. */
if (j == 0)
{
- op = TREE_OPERAND (operation, 0);
- loop_vec_def0 = vect_get_vec_def_for_operand (op, stmt, NULL);
+ loop_vec_def0 = vect_get_vec_def_for_operand (ops[0], stmt, NULL);
if (op_type == ternary_op)
{
- op = TREE_OPERAND (operation, 1);
- loop_vec_def1 = vect_get_vec_def_for_operand (op, stmt, NULL);
+ loop_vec_def1 = vect_get_vec_def_for_operand (ops[1], stmt, NULL);
}
/* Get the vector def for the reduction variable from the phi node */
@@ -2971,7 +3025,7 @@ vectorizable_reduction (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt)
/* Get the vector def for the reduction variable from the vectorized
reduction operation generated in the previous iteration (j-1) */
- reduc_def = GIMPLE_STMT_OPERAND (new_stmt ,0);
+ reduc_def = gimple_assign_lhs (new_stmt);
}
/* Arguments are ready. create the new vector stmt. */
@@ -2980,10 +3034,10 @@ vectorizable_reduction (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt)
else
expr = build3 (code, vectype, loop_vec_def0, loop_vec_def1,
reduc_def);
- new_stmt = build_gimple_modify_stmt (vec_dest, expr);
+ new_stmt = gimple_build_assign (vec_dest, expr);
new_temp = make_ssa_name (vec_dest, new_stmt);
- GIMPLE_STMT_OPERAND (new_stmt, 0) = new_temp;
- vect_finish_stmt_generation (stmt, new_stmt, bsi);
+ gimple_assign_set_lhs (new_stmt, new_temp);
+ vect_finish_stmt_generation (stmt, new_stmt, gsi);
if (j == 0)
STMT_VINFO_VEC_STMT (stmt_info) = *vec_stmt = new_stmt;
@@ -3003,14 +3057,14 @@ vectorizable_reduction (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt)
of the function, or NULL_TREE if the function cannot be vectorized. */
tree
-vectorizable_function (tree call, tree vectype_out, tree vectype_in)
+vectorizable_function (gimple call, tree vectype_out, tree vectype_in)
{
- tree fndecl = get_callee_fndecl (call);
+ tree fndecl = gimple_call_fndecl (call);
enum built_in_function code;
/* We only handle functions that do not read or clobber memory -- i.e.
const or novops ones. */
- if (!(call_expr_flags (call) & (ECF_CONST | ECF_NOVOPS)))
+ if (!(gimple_call_flags (call) & (ECF_CONST | ECF_NOVOPS)))
return NULL_TREE;
if (!fndecl
@@ -3031,11 +3085,10 @@ vectorizable_function (tree call, tree vectype_out, tree vectype_in)
Return FALSE if not a vectorizable STMT, TRUE otherwise. */
bool
-vectorizable_call (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt)
+vectorizable_call (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt)
{
tree vec_dest;
tree scalar_dest;
- tree operation;
tree op, type;
tree vec_oprnd0 = NULL_TREE, vec_oprnd1 = NULL_TREE;
stmt_vec_info stmt_info = vinfo_for_stmt (stmt), prev_stmt_info;
@@ -3044,13 +3097,14 @@ vectorizable_call (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt)
int nunits_out;
loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
- tree fndecl, rhs, new_temp, def, def_stmt, rhs_type, lhs_type;
+ tree fndecl, new_temp, def, rhs_type, lhs_type;
+ gimple def_stmt;
enum vect_def_type dt[2] = {vect_unknown_def_type, vect_unknown_def_type};
- tree new_stmt;
- int ncopies, j, nargs;
- call_expr_arg_iterator iter;
- tree vargs;
+ gimple new_stmt;
+ int ncopies, j;
+ VEC(tree, heap) *vargs = NULL;
enum { NARROW, NONE, WIDEN } modifier;
+ size_t i, nargs;
if (!STMT_VINFO_RELEVANT_P (stmt_info))
return false;
@@ -3063,25 +3117,24 @@ vectorizable_call (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt)
return false;
/* Is STMT a vectorizable call? */
- if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT)
+ if (!is_gimple_call (stmt))
return false;
- if (TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 0)) != SSA_NAME)
- return false;
-
- operation = GIMPLE_STMT_OPERAND (stmt, 1);
- if (TREE_CODE (operation) != CALL_EXPR)
+ if (TREE_CODE (gimple_call_lhs (stmt)) != SSA_NAME)
return false;
/* Process function arguments. */
rhs_type = NULL_TREE;
- nargs = 0;
- FOR_EACH_CALL_EXPR_ARG (op, iter, operation)
+ nargs = gimple_call_num_args (stmt);
+
+ for (i = 0; i < nargs; i++)
{
+ op = gimple_call_arg (stmt, i);
+
/* Bail out if the function has more than two arguments, we
do not have interesting builtin functions to vectorize with
more than two arguments. */
- if (nargs >= 2)
+ if (i >= 2)
return false;
/* We can only handle calls with arguments of the same type. */
@@ -3100,8 +3153,6 @@ vectorizable_call (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt)
fprintf (vect_dump, "use not simple.");
return false;
}
-
- ++nargs;
}
/* No arguments is also not good. */
@@ -3113,7 +3164,7 @@ vectorizable_call (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt)
return false;
nunits_in = TYPE_VECTOR_SUBPARTS (vectype_in);
- lhs_type = TREE_TYPE (GIMPLE_STMT_OPERAND (stmt, 0));
+ lhs_type = TREE_TYPE (gimple_call_lhs (stmt));
vectype_out = get_vectype_for_scalar_type (lhs_type);
if (!vectype_out)
return false;
@@ -3133,7 +3184,7 @@ vectorizable_call (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt)
is available. TODO -- in some cases, it might be profitable to
insert the calls for pieces of the vector, in order to be able
to vectorize other operations in the loop. */
- fndecl = vectorizable_function (operation, vectype_out, vectype_in);
+ fndecl = vectorizable_function (stmt, vectype_out, vectype_in);
if (fndecl == NULL_TREE)
{
if (vect_print_dump_info (REPORT_DETAILS))
@@ -3184,7 +3235,7 @@ vectorizable_call (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt)
}
/* Handle def. */
- scalar_dest = GIMPLE_STMT_OPERAND (stmt, 0);
+ scalar_dest = gimple_call_lhs (stmt);
vec_dest = vect_create_destination_var (scalar_dest, vectype_out);
prev_stmt_info = NULL;
@@ -3194,12 +3245,14 @@ vectorizable_call (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt)
for (j = 0; j < ncopies; ++j)
{
/* Build argument list for the vectorized call. */
- /* FIXME: Rewrite this so that it doesn't
- construct a temporary list. */
- vargs = NULL_TREE;
- nargs = 0;
- FOR_EACH_CALL_EXPR_ARG (op, iter, operation)
+ if (j == 0)
+ vargs = VEC_alloc (tree, heap, nargs);
+ else
+ VEC_truncate (tree, vargs, 0);
+
+ for (i = 0; i < nargs; i++)
{
+ op = gimple_call_arg (stmt, i);
if (j == 0)
vec_oprnd0
= vect_get_vec_def_for_operand (op, stmt, NULL);
@@ -3207,18 +3260,14 @@ vectorizable_call (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt)
vec_oprnd0
= vect_get_vec_def_for_stmt_copy (dt[nargs], vec_oprnd0);
- vargs = tree_cons (NULL_TREE, vec_oprnd0, vargs);
-
- ++nargs;
+ VEC_quick_push (tree, vargs, vec_oprnd0);
}
- vargs = nreverse (vargs);
- rhs = build_function_call_expr (fndecl, vargs);
- new_stmt = build_gimple_modify_stmt (vec_dest, rhs);
+ new_stmt = gimple_build_call_vec (fndecl, vargs);
new_temp = make_ssa_name (vec_dest, new_stmt);
- GIMPLE_STMT_OPERAND (new_stmt, 0) = new_temp;
+ gimple_call_set_lhs (new_stmt, new_temp);
- vect_finish_stmt_generation (stmt, new_stmt, bsi);
+ vect_finish_stmt_generation (stmt, new_stmt, gsi);
if (j == 0)
STMT_VINFO_VEC_STMT (stmt_info) = *vec_stmt = new_stmt;
@@ -3234,12 +3283,14 @@ vectorizable_call (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt)
for (j = 0; j < ncopies; ++j)
{
/* Build argument list for the vectorized call. */
- /* FIXME: Rewrite this so that it doesn't
- construct a temporary list. */
- vargs = NULL_TREE;
- nargs = 0;
- FOR_EACH_CALL_EXPR_ARG (op, iter, operation)
+ if (j == 0)
+ vargs = VEC_alloc (tree, heap, nargs * 2);
+ else
+ VEC_truncate (tree, vargs, 0);
+
+ for (i = 0; i < nargs; i++)
{
+ op = gimple_call_arg (stmt, i);
if (j == 0)
{
vec_oprnd0
@@ -3255,19 +3306,15 @@ vectorizable_call (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt)
= vect_get_vec_def_for_stmt_copy (dt[nargs], vec_oprnd0);
}
- vargs = tree_cons (NULL_TREE, vec_oprnd0, vargs);
- vargs = tree_cons (NULL_TREE, vec_oprnd1, vargs);
-
- ++nargs;
+ VEC_quick_push (tree, vargs, vec_oprnd0);
+ VEC_quick_push (tree, vargs, vec_oprnd1);
}
- vargs = nreverse (vargs);
- rhs = build_function_call_expr (fndecl, vargs);
- new_stmt = build_gimple_modify_stmt (vec_dest, rhs);
+ new_stmt = gimple_build_call_vec (fndecl, vargs);
new_temp = make_ssa_name (vec_dest, new_stmt);
- GIMPLE_STMT_OPERAND (new_stmt, 0) = new_temp;
+ gimple_call_set_lhs (new_stmt, new_temp);
- vect_finish_stmt_generation (stmt, new_stmt, bsi);
+ vect_finish_stmt_generation (stmt, new_stmt, gsi);
if (j == 0)
STMT_VINFO_VEC_STMT (stmt_info) = new_stmt;
@@ -3286,13 +3333,21 @@ vectorizable_call (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt)
return false;
}
+ VEC_free (tree, heap, vargs);
+
/* The call in STMT might prevent it from being removed in dce.
We however cannot remove it here, due to the way the ssa name
it defines is mapped to the new definition. So just replace
rhs of the statement with something harmless. */
+
type = TREE_TYPE (scalar_dest);
- GIMPLE_STMT_OPERAND (stmt, 1) = fold_convert (type, integer_zero_node);
- update_stmt (stmt);
+ new_stmt = gimple_build_assign (gimple_call_lhs (stmt),
+ fold_convert (type, integer_zero_node));
+ set_vinfo_for_stmt (new_stmt, stmt_info);
+ set_vinfo_for_stmt (stmt, NULL);
+ STMT_VINFO_STMT (stmt_info) = new_stmt;
+ gsi_replace (gsi, new_stmt, false);
+ SSA_NAME_DEF_STMT (gimple_assign_lhs (new_stmt)) = new_stmt;
return true;
}
@@ -3307,14 +3362,15 @@ vectorizable_call (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt)
needs to be created (DECL is a function-decl of a target-builtin).
STMT is the original scalar stmt that we are vectorizing. */
-static tree
-vect_gen_widened_results_half (enum tree_code code, tree vectype, tree decl,
+static gimple
+vect_gen_widened_results_half (enum tree_code code,
+ tree vectype ATTRIBUTE_UNUSED,
+ tree decl,
tree vec_oprnd0, tree vec_oprnd1, int op_type,
- tree vec_dest, block_stmt_iterator *bsi,
- tree stmt)
+ tree vec_dest, gimple_stmt_iterator *gsi,
+ gimple stmt)
{
- tree expr;
- tree new_stmt;
+ gimple new_stmt;
tree new_temp;
tree sym;
ssa_op_iter iter;
@@ -3324,23 +3380,24 @@ vect_gen_widened_results_half (enum tree_code code, tree vectype, tree decl,
{
/* Target specific support */
if (op_type == binary_op)
- expr = build_call_expr (decl, 2, vec_oprnd0, vec_oprnd1);
+ new_stmt = gimple_build_call (decl, 2, vec_oprnd0, vec_oprnd1);
else
- expr = build_call_expr (decl, 1, vec_oprnd0);
+ new_stmt = gimple_build_call (decl, 1, vec_oprnd0);
+ new_temp = make_ssa_name (vec_dest, new_stmt);
+ gimple_call_set_lhs (new_stmt, new_temp);
}
else
- {
+ {
/* Generic support */
gcc_assert (op_type == TREE_CODE_LENGTH (code));
- if (op_type == binary_op)
- expr = build2 (code, vectype, vec_oprnd0, vec_oprnd1);
- else
- expr = build1 (code, vectype, vec_oprnd0);
+ if (op_type != binary_op)
+ vec_oprnd1 = NULL;
+ new_stmt = gimple_build_assign_with_ops (code, vec_dest, vec_oprnd0,
+ vec_oprnd1);
+ new_temp = make_ssa_name (vec_dest, new_stmt);
+ gimple_assign_set_lhs (new_stmt, new_temp);
}
- new_stmt = build_gimple_modify_stmt (vec_dest, expr);
- new_temp = make_ssa_name (vec_dest, new_stmt);
- GIMPLE_STMT_OPERAND (new_stmt, 0) = new_temp;
- vect_finish_stmt_generation (stmt, new_stmt, bsi);
+ vect_finish_stmt_generation (stmt, new_stmt, gsi);
if (code == CALL_EXPR)
{
@@ -3362,12 +3419,11 @@ vect_gen_widened_results_half (enum tree_code code, tree vectype, tree decl,
Return FALSE if not a vectorizable STMT, TRUE otherwise. */
bool
-vectorizable_conversion (tree stmt, block_stmt_iterator *bsi,
- tree *vec_stmt, slp_tree slp_node)
+vectorizable_conversion (gimple stmt, gimple_stmt_iterator *gsi,
+ gimple *vec_stmt, slp_tree slp_node)
{
tree vec_dest;
tree scalar_dest;
- tree operation;
tree op0;
tree vec_oprnd0 = NULL_TREE, vec_oprnd1 = NULL_TREE;
stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
@@ -3376,9 +3432,10 @@ vectorizable_conversion (tree stmt, block_stmt_iterator *bsi,
enum tree_code code, code1 = ERROR_MARK, code2 = ERROR_MARK;
tree decl1 = NULL_TREE, decl2 = NULL_TREE;
tree new_temp;
- tree def, def_stmt;
+ tree def;
+ gimple def_stmt;
enum vect_def_type dt[2] = {vect_unknown_def_type, vect_unknown_def_type};
- tree new_stmt = NULL_TREE;
+ gimple new_stmt = NULL;
stmt_vec_info prev_stmt_info;
int nunits_in;
int nunits_out;
@@ -3400,26 +3457,25 @@ vectorizable_conversion (tree stmt, block_stmt_iterator *bsi,
if (STMT_VINFO_DEF_TYPE (stmt_info) != vect_loop_def)
return false;
- if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT)
+ if (!is_gimple_assign (stmt))
return false;
- if (TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 0)) != SSA_NAME)
+ if (TREE_CODE (gimple_assign_lhs (stmt)) != SSA_NAME)
return false;
- operation = GIMPLE_STMT_OPERAND (stmt, 1);
- code = TREE_CODE (operation);
+ code = gimple_assign_rhs_code (stmt);
if (code != FIX_TRUNC_EXPR && code != FLOAT_EXPR)
return false;
/* Check types of lhs and rhs. */
- op0 = TREE_OPERAND (operation, 0);
+ op0 = gimple_assign_rhs1 (stmt);
rhs_type = TREE_TYPE (op0);
vectype_in = get_vectype_for_scalar_type (rhs_type);
if (!vectype_in)
return false;
nunits_in = TYPE_VECTOR_SUBPARTS (vectype_in);
- scalar_dest = GIMPLE_STMT_OPERAND (stmt, 0);
+ scalar_dest = gimple_assign_lhs (stmt);
lhs_type = TREE_TYPE (scalar_dest);
vectype_out = get_vectype_for_scalar_type (lhs_type);
if (!vectype_out)
@@ -3532,13 +3588,11 @@ vectorizable_conversion (tree stmt, block_stmt_iterator *bsi,
targetm.vectorize.builtin_conversion (code, vectype_in);
for (i = 0; VEC_iterate (tree, vec_oprnds0, i, vop0); i++)
{
- new_stmt = build_call_expr (builtin_decl, 1, vop0);
-
/* Arguments are ready. create the new vector stmt. */
- new_stmt = build_gimple_modify_stmt (vec_dest, new_stmt);
+ new_stmt = gimple_build_call (builtin_decl, 1, vop0);
new_temp = make_ssa_name (vec_dest, new_stmt);
- GIMPLE_STMT_OPERAND (new_stmt, 0) = new_temp;
- vect_finish_stmt_generation (stmt, new_stmt, bsi);
+ gimple_call_set_lhs (new_stmt, new_temp);
+ vect_finish_stmt_generation (stmt, new_stmt, gsi);
FOR_EACH_SSA_TREE_OPERAND (sym, new_stmt, iter,
SSA_OP_ALL_VIRTUALS)
{
@@ -3547,7 +3601,7 @@ vectorizable_conversion (tree stmt, block_stmt_iterator *bsi,
mark_sym_for_renaming (sym);
}
if (slp_node)
- VEC_quick_push (tree, SLP_TREE_VEC_STMTS (slp_node), new_stmt);
+ VEC_quick_push (gimple, SLP_TREE_VEC_STMTS (slp_node), new_stmt);
}
if (j == 0)
@@ -3576,7 +3630,7 @@ vectorizable_conversion (tree stmt, block_stmt_iterator *bsi,
new_stmt
= vect_gen_widened_results_half (code1, vectype_out, decl1,
vec_oprnd0, vec_oprnd1,
- unary_op, vec_dest, bsi, stmt);
+ unary_op, vec_dest, gsi, stmt);
if (j == 0)
STMT_VINFO_VEC_STMT (stmt_info) = new_stmt;
else
@@ -3587,7 +3641,7 @@ vectorizable_conversion (tree stmt, block_stmt_iterator *bsi,
new_stmt
= vect_gen_widened_results_half (code2, vectype_out, decl2,
vec_oprnd0, vec_oprnd1,
- unary_op, vec_dest, bsi, stmt);
+ unary_op, vec_dest, gsi, stmt);
STMT_VINFO_RELATED_STMT (prev_stmt_info) = new_stmt;
prev_stmt_info = vinfo_for_stmt (new_stmt);
}
@@ -3614,10 +3668,11 @@ vectorizable_conversion (tree stmt, block_stmt_iterator *bsi,
/* Arguments are ready. Create the new vector stmt. */
expr = build2 (code1, vectype_out, vec_oprnd0, vec_oprnd1);
- new_stmt = build_gimple_modify_stmt (vec_dest, expr);
+ new_stmt = gimple_build_assign_with_ops (code1, vec_dest, vec_oprnd0,
+ vec_oprnd1);
new_temp = make_ssa_name (vec_dest, new_stmt);
- GIMPLE_STMT_OPERAND (new_stmt, 0) = new_temp;
- vect_finish_stmt_generation (stmt, new_stmt, bsi);
+ gimple_assign_set_lhs (new_stmt, new_temp);
+ vect_finish_stmt_generation (stmt, new_stmt, gsi);
if (j == 0)
STMT_VINFO_VEC_STMT (stmt_info) = new_stmt;
@@ -3645,8 +3700,8 @@ vectorizable_conversion (tree stmt, block_stmt_iterator *bsi,
Return FALSE if not a vectorizable STMT, TRUE otherwise. */
bool
-vectorizable_assignment (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt,
- slp_tree slp_node)
+vectorizable_assignment (gimple stmt, gimple_stmt_iterator *gsi,
+ gimple *vec_stmt, slp_tree slp_node)
{
tree vec_dest;
tree scalar_dest;
@@ -3655,7 +3710,8 @@ vectorizable_assignment (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt,
tree vectype = STMT_VINFO_VECTYPE (stmt_info);
loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
tree new_temp;
- tree def, def_stmt;
+ tree def;
+ gimple def_stmt;
enum vect_def_type dt[2] = {vect_unknown_def_type, vect_unknown_def_type};
int nunits = TYPE_VECTOR_SUBPARTS (vectype);
int ncopies = LOOP_VINFO_VECT_FACTOR (loop_vinfo) / nunits;
@@ -3679,14 +3735,19 @@ vectorizable_assignment (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt,
return false;
/* Is vectorizable assignment? */
- if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT)
+ if (!is_gimple_assign (stmt))
return false;
- scalar_dest = GIMPLE_STMT_OPERAND (stmt, 0);
+ scalar_dest = gimple_assign_lhs (stmt);
if (TREE_CODE (scalar_dest) != SSA_NAME)
return false;
- op = GIMPLE_STMT_OPERAND (stmt, 1);
+ if (gimple_assign_single_p (stmt)
+ || gimple_assign_rhs_code (stmt) == PAREN_EXPR)
+ op = gimple_assign_rhs1 (stmt);
+ else
+ return false;
+
if (!vect_is_simple_use (op, loop_vinfo, &def_stmt, &def, &dt[0]))
{
if (vect_print_dump_info (REPORT_DETAILS))
@@ -3716,14 +3777,14 @@ vectorizable_assignment (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt,
/* Arguments are ready. create the new vector stmt. */
for (i = 0; VEC_iterate (tree, vec_oprnds, i, vop); i++)
{
- *vec_stmt = build_gimple_modify_stmt (vec_dest, vop);
+ *vec_stmt = gimple_build_assign (vec_dest, vop);
new_temp = make_ssa_name (vec_dest, *vec_stmt);
- GIMPLE_STMT_OPERAND (*vec_stmt, 0) = new_temp;
- vect_finish_stmt_generation (stmt, *vec_stmt, bsi);
+ gimple_assign_set_lhs (*vec_stmt, new_temp);
+ vect_finish_stmt_generation (stmt, *vec_stmt, gsi);
STMT_VINFO_VEC_STMT (stmt_info) = *vec_stmt;
if (slp_node)
- VEC_quick_push (tree, SLP_TREE_VEC_STMTS (slp_node), *vec_stmt);
+ VEC_quick_push (gimple, SLP_TREE_VEC_STMTS (slp_node), *vec_stmt);
}
VEC_free (tree, heap, vec_oprnds);
@@ -3766,8 +3827,8 @@ vect_min_worthwhile_factor (enum tree_code code)
Return FALSE if not a vectorizable STMT, TRUE otherwise. */
bool
-vectorizable_induction (tree phi, block_stmt_iterator *bsi ATTRIBUTE_UNUSED,
- tree *vec_stmt)
+vectorizable_induction (gimple phi, gimple_stmt_iterator *gsi ATTRIBUTE_UNUSED,
+ gimple *vec_stmt)
{
stmt_vec_info stmt_info = vinfo_for_stmt (phi);
tree vectype = STMT_VINFO_VECTYPE (stmt_info);
@@ -3787,7 +3848,7 @@ vectorizable_induction (tree phi, block_stmt_iterator *bsi ATTRIBUTE_UNUSED,
gcc_assert (STMT_VINFO_DEF_TYPE (stmt_info) == vect_induction_def);
- if (TREE_CODE (phi) != PHI_NODE)
+ if (gimple_code (phi) != GIMPLE_PHI)
return false;
if (!vec_stmt) /* transformation not required. */
@@ -3818,12 +3879,11 @@ vectorizable_induction (tree phi, block_stmt_iterator *bsi ATTRIBUTE_UNUSED,
Return FALSE if not a vectorizable STMT, TRUE otherwise. */
bool
-vectorizable_operation (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt,
- slp_tree slp_node)
+vectorizable_operation (gimple stmt, gimple_stmt_iterator *gsi,
+ gimple *vec_stmt, slp_tree slp_node)
{
tree vec_dest;
tree scalar_dest;
- tree operation;
tree op0, op1 = NULL;
tree vec_oprnd1 = NULL_TREE;
stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
@@ -3837,9 +3897,10 @@ vectorizable_operation (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt,
optab optab;
int icode;
enum machine_mode optab_op2_mode;
- tree def, def_stmt;
+ tree def;
+ gimple def_stmt;
enum vect_def_type dt[2] = {vect_unknown_def_type, vect_unknown_def_type};
- tree new_stmt = NULL_TREE;
+ gimple new_stmt = NULL;
stmt_vec_info prev_stmt_info;
int nunits_in = TYPE_VECTOR_SUBPARTS (vectype);
int nunits_out;
@@ -3872,13 +3933,13 @@ vectorizable_operation (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt,
return false;
/* Is STMT a vectorizable binary/unary operation? */
- if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT)
+ if (!is_gimple_assign (stmt))
return false;
- if (TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 0)) != SSA_NAME)
+ if (TREE_CODE (gimple_assign_lhs (stmt)) != SSA_NAME)
return false;
- scalar_dest = GIMPLE_STMT_OPERAND (stmt, 0);
+ scalar_dest = gimple_assign_lhs (stmt);
vectype_out = get_vectype_for_scalar_type (TREE_TYPE (scalar_dest));
if (!vectype_out)
return false;
@@ -3886,8 +3947,7 @@ vectorizable_operation (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt,
if (nunits_out != nunits_in)
return false;
- operation = GIMPLE_STMT_OPERAND (stmt, 1);
- code = TREE_CODE (operation);
+ code = gimple_assign_rhs_code (stmt);
/* For pointer addition, we should use the normal plus for
the vector addition. */
@@ -3895,7 +3955,7 @@ vectorizable_operation (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt,
code = PLUS_EXPR;
/* Support only unary or binary operations. */
- op_type = TREE_OPERAND_LENGTH (operation);
+ op_type = TREE_CODE_LENGTH (code);
if (op_type != unary_op && op_type != binary_op)
{
if (vect_print_dump_info (REPORT_DETAILS))
@@ -3903,7 +3963,7 @@ vectorizable_operation (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt,
return false;
}
- op0 = TREE_OPERAND (operation, 0);
+ op0 = gimple_assign_rhs1 (stmt);
if (!vect_is_simple_use (op0, loop_vinfo, &def_stmt, &def, &dt[0]))
{
if (vect_print_dump_info (REPORT_DETAILS))
@@ -3913,7 +3973,7 @@ vectorizable_operation (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt,
if (op_type == binary_op)
{
- op1 = TREE_OPERAND (operation, 1);
+ op1 = gimple_assign_rhs2 (stmt);
if (!vect_is_simple_use (op1, loop_vinfo, &def_stmt, &def, &dt[1]))
{
if (vect_print_dump_info (REPORT_DETAILS))
@@ -4140,21 +4200,14 @@ vectorizable_operation (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt,
/* Arguments are ready. Create the new vector stmt. */
for (i = 0; VEC_iterate (tree, vec_oprnds0, i, vop0); i++)
{
- if (op_type == binary_op)
- {
- vop1 = VEC_index (tree, vec_oprnds1, i);
- new_stmt = build_gimple_modify_stmt (vec_dest,
- build2 (code, vectype, vop0, vop1));
- }
- else
- new_stmt = build_gimple_modify_stmt (vec_dest,
- build1 (code, vectype, vop0));
-
+ vop1 = ((op_type == binary_op)
+ ? VEC_index (tree, vec_oprnds1, i) : NULL);
+ new_stmt = gimple_build_assign_with_ops (code, vec_dest, vop0, vop1);
new_temp = make_ssa_name (vec_dest, new_stmt);
- GIMPLE_STMT_OPERAND (new_stmt, 0) = new_temp;
- vect_finish_stmt_generation (stmt, new_stmt, bsi);
+ gimple_assign_set_lhs (new_stmt, new_temp);
+ vect_finish_stmt_generation (stmt, new_stmt, gsi);
if (slp_node)
- VEC_quick_push (tree, SLP_TREE_VEC_STMTS (slp_node), new_stmt);
+ VEC_quick_push (gimple, SLP_TREE_VEC_STMTS (slp_node), new_stmt);
}
if (j == 0)
@@ -4181,12 +4234,11 @@ vectorizable_operation (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt,
Return FALSE if not a vectorizable STMT, TRUE otherwise. */
bool
-vectorizable_type_demotion (tree stmt, block_stmt_iterator *bsi,
- tree *vec_stmt)
+vectorizable_type_demotion (gimple stmt, gimple_stmt_iterator *gsi,
+ gimple *vec_stmt)
{
tree vec_dest;
tree scalar_dest;
- tree operation;
tree op0;
tree vec_oprnd0=NULL, vec_oprnd1=NULL;
stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
@@ -4194,16 +4246,16 @@ vectorizable_type_demotion (tree stmt, block_stmt_iterator *bsi,
struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
enum tree_code code, code1 = ERROR_MARK;
tree new_temp;
- tree def, def_stmt;
+ tree def;
+ gimple def_stmt;
enum vect_def_type dt[2] = {vect_unknown_def_type, vect_unknown_def_type};
- tree new_stmt;
+ gimple new_stmt;
stmt_vec_info prev_stmt_info;
int nunits_in;
int nunits_out;
tree vectype_out;
int ncopies;
int j;
- tree expr;
tree vectype_in;
if (!STMT_VINFO_RELEVANT_P (stmt_info))
@@ -4213,24 +4265,23 @@ vectorizable_type_demotion (tree stmt, block_stmt_iterator *bsi,
return false;
/* Is STMT a vectorizable type-demotion operation? */
- if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT)
+ if (!is_gimple_assign (stmt))
return false;
- if (TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 0)) != SSA_NAME)
+ if (TREE_CODE (gimple_assign_lhs (stmt)) != SSA_NAME)
return false;
- operation = GIMPLE_STMT_OPERAND (stmt, 1);
- code = TREE_CODE (operation);
+ code = gimple_assign_rhs_code (stmt);
if (code != NOP_EXPR && code != CONVERT_EXPR)
return false;
- op0 = TREE_OPERAND (operation, 0);
+ op0 = gimple_assign_rhs1 (stmt);
vectype_in = get_vectype_for_scalar_type (TREE_TYPE (op0));
if (!vectype_in)
return false;
nunits_in = TYPE_VECTOR_SUBPARTS (vectype_in);
- scalar_dest = GIMPLE_STMT_OPERAND (stmt, 0);
+ scalar_dest = gimple_assign_lhs (stmt);
vectype_out = get_vectype_for_scalar_type (TREE_TYPE (scalar_dest));
if (!vectype_out)
return false;
@@ -4306,11 +4357,11 @@ vectorizable_type_demotion (tree stmt, block_stmt_iterator *bsi,
}
/* Arguments are ready. Create the new vector stmt. */
- expr = build2 (code1, vectype_out, vec_oprnd0, vec_oprnd1);
- new_stmt = build_gimple_modify_stmt (vec_dest, expr);
+ new_stmt = gimple_build_assign_with_ops (code1, vec_dest, vec_oprnd0,
+ vec_oprnd1);
new_temp = make_ssa_name (vec_dest, new_stmt);
- GIMPLE_STMT_OPERAND (new_stmt, 0) = new_temp;
- vect_finish_stmt_generation (stmt, new_stmt, bsi);
+ gimple_assign_set_lhs (new_stmt, new_temp);
+ vect_finish_stmt_generation (stmt, new_stmt, gsi);
if (j == 0)
STMT_VINFO_VEC_STMT (stmt_info) = new_stmt;
@@ -4334,12 +4385,11 @@ vectorizable_type_demotion (tree stmt, block_stmt_iterator *bsi,
Return FALSE if not a vectorizable STMT, TRUE otherwise. */
bool
-vectorizable_type_promotion (tree stmt, block_stmt_iterator *bsi,
- tree *vec_stmt)
+vectorizable_type_promotion (gimple stmt, gimple_stmt_iterator *gsi,
+ gimple *vec_stmt)
{
tree vec_dest;
tree scalar_dest;
- tree operation;
tree op0, op1 = NULL;
tree vec_oprnd0=NULL, vec_oprnd1=NULL;
stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
@@ -4348,9 +4398,10 @@ vectorizable_type_promotion (tree stmt, block_stmt_iterator *bsi,
enum tree_code code, code1 = ERROR_MARK, code2 = ERROR_MARK;
tree decl1 = NULL_TREE, decl2 = NULL_TREE;
int op_type;
- tree def, def_stmt;
+ tree def;
+ gimple def_stmt;
enum vect_def_type dt[2] = {vect_unknown_def_type, vect_unknown_def_type};
- tree new_stmt;
+ gimple new_stmt;
stmt_vec_info prev_stmt_info;
int nunits_in;
int nunits_out;
@@ -4366,25 +4417,24 @@ vectorizable_type_promotion (tree stmt, block_stmt_iterator *bsi,
return false;
/* Is STMT a vectorizable type-promotion operation? */
- if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT)
+ if (!is_gimple_assign (stmt))
return false;
- if (TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 0)) != SSA_NAME)
+ if (TREE_CODE (gimple_assign_lhs (stmt)) != SSA_NAME)
return false;
- operation = GIMPLE_STMT_OPERAND (stmt, 1);
- code = TREE_CODE (operation);
+ code = gimple_assign_rhs_code (stmt);
if (code != NOP_EXPR && code != CONVERT_EXPR
&& code != WIDEN_MULT_EXPR)
return false;
- op0 = TREE_OPERAND (operation, 0);
+ op0 = gimple_assign_rhs1 (stmt);
vectype_in = get_vectype_for_scalar_type (TREE_TYPE (op0));
if (!vectype_in)
return false;
nunits_in = TYPE_VECTOR_SUBPARTS (vectype_in);
- scalar_dest = GIMPLE_STMT_OPERAND (stmt, 0);
+ scalar_dest = gimple_assign_lhs (stmt);
vectype_out = get_vectype_for_scalar_type (TREE_TYPE (scalar_dest));
if (!vectype_out)
return false;
@@ -4420,7 +4470,7 @@ vectorizable_type_promotion (tree stmt, block_stmt_iterator *bsi,
op_type = TREE_CODE_LENGTH (code);
if (op_type == binary_op)
{
- op1 = TREE_OPERAND (operation, 1);
+ op1 = gimple_assign_rhs2 (stmt);
if (!vect_is_simple_use (op1, loop_vinfo, &def_stmt, &def, &dt[1]))
{
if (vect_print_dump_info (REPORT_DETAILS))
@@ -4482,7 +4532,7 @@ vectorizable_type_promotion (tree stmt, block_stmt_iterator *bsi,
or a using a tree-code. */
/* Generate first half of the widened result: */
new_stmt = vect_gen_widened_results_half (code1, vectype_out, decl1,
- vec_oprnd0, vec_oprnd1, op_type, vec_dest, bsi, stmt);
+ vec_oprnd0, vec_oprnd1, op_type, vec_dest, gsi, stmt);
if (j == 0)
STMT_VINFO_VEC_STMT (stmt_info) = new_stmt;
else
@@ -4491,7 +4541,7 @@ vectorizable_type_promotion (tree stmt, block_stmt_iterator *bsi,
/* Generate second half of the widened result: */
new_stmt = vect_gen_widened_results_half (code2, vectype_out, decl2,
- vec_oprnd0, vec_oprnd1, op_type, vec_dest, bsi, stmt);
+ vec_oprnd0, vec_oprnd1, op_type, vec_dest, gsi, stmt);
STMT_VINFO_RELATED_STMT (prev_stmt_info) = new_stmt;
prev_stmt_info = vinfo_for_stmt (new_stmt);
@@ -4605,17 +4655,19 @@ vect_strided_store_supported (tree vectype)
static bool
vect_permute_store_chain (VEC(tree,heap) *dr_chain,
unsigned int length,
- tree stmt,
- block_stmt_iterator *bsi,
+ gimple stmt,
+ gimple_stmt_iterator *gsi,
VEC(tree,heap) **result_chain)
{
- tree perm_dest, perm_stmt, vect1, vect2, high, low;
+ tree perm_dest, vect1, vect2, high, low;
+ gimple perm_stmt;
tree vectype = STMT_VINFO_VECTYPE (vinfo_for_stmt (stmt));
- tree scalar_dest, tmp;
+ tree scalar_dest;
int i;
unsigned int j;
+ enum tree_code high_code, low_code;
- scalar_dest = GIMPLE_STMT_OPERAND (stmt, 0);
+ scalar_dest = gimple_assign_lhs (stmt);
/* Check that the operation is supported. */
if (!vect_strided_store_supported (vectype))
@@ -4639,13 +4691,20 @@ vect_permute_store_chain (VEC(tree,heap) *dr_chain,
DECL_GIMPLE_REG_P (perm_dest) = 1;
add_referenced_var (perm_dest);
if (BYTES_BIG_ENDIAN)
- tmp = build2 (VEC_INTERLEAVE_HIGH_EXPR, vectype, vect1, vect2);
+ {
+ high_code = VEC_INTERLEAVE_HIGH_EXPR;
+ low_code = VEC_INTERLEAVE_LOW_EXPR;
+ }
else
- tmp = build2 (VEC_INTERLEAVE_LOW_EXPR, vectype, vect1, vect2);
- perm_stmt = build_gimple_modify_stmt (perm_dest, tmp);
+ {
+ low_code = VEC_INTERLEAVE_HIGH_EXPR;
+ high_code = VEC_INTERLEAVE_LOW_EXPR;
+ }
+ perm_stmt = gimple_build_assign_with_ops (high_code, perm_dest,
+ vect1, vect2);
high = make_ssa_name (perm_dest, perm_stmt);
- GIMPLE_STMT_OPERAND (perm_stmt, 0) = high;
- vect_finish_stmt_generation (stmt, perm_stmt, bsi);
+ gimple_assign_set_lhs (perm_stmt, high);
+ vect_finish_stmt_generation (stmt, perm_stmt, gsi);
VEC_replace (tree, *result_chain, 2*j, high);
/* Create interleaving stmt:
@@ -4656,14 +4715,11 @@ vect_permute_store_chain (VEC(tree,heap) *dr_chain,
perm_dest = create_tmp_var (vectype, "vect_inter_low");
DECL_GIMPLE_REG_P (perm_dest) = 1;
add_referenced_var (perm_dest);
- if (BYTES_BIG_ENDIAN)
- tmp = build2 (VEC_INTERLEAVE_LOW_EXPR, vectype, vect1, vect2);
- else
- tmp = build2 (VEC_INTERLEAVE_HIGH_EXPR, vectype, vect1, vect2);
- perm_stmt = build_gimple_modify_stmt (perm_dest, tmp);
+ perm_stmt = gimple_build_assign_with_ops (low_code, perm_dest,
+ vect1, vect2);
low = make_ssa_name (perm_dest, perm_stmt);
- GIMPLE_STMT_OPERAND (perm_stmt, 0) = low;
- vect_finish_stmt_generation (stmt, perm_stmt, bsi);
+ gimple_assign_set_lhs (perm_stmt, low);
+ vect_finish_stmt_generation (stmt, perm_stmt, gsi);
VEC_replace (tree, *result_chain, 2*j+1, low);
}
dr_chain = VEC_copy (tree, heap, *result_chain);
@@ -4681,7 +4737,7 @@ vect_permute_store_chain (VEC(tree,heap) *dr_chain,
Return FALSE if not a vectorizable STMT, TRUE otherwise. */
bool
-vectorizable_store (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt,
+vectorizable_store (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
slp_tree slp_node)
{
tree scalar_dest;
@@ -4696,14 +4752,15 @@ vectorizable_store (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt,
enum machine_mode vec_mode;
tree dummy;
enum dr_alignment_support alignment_support_scheme;
- tree def, def_stmt;
+ tree def;
+ gimple def_stmt;
enum vect_def_type dt;
stmt_vec_info prev_stmt_info = NULL;
tree dataref_ptr = NULL_TREE;
int nunits = TYPE_VECTOR_SUBPARTS (vectype);
int ncopies = LOOP_VINFO_VECT_FACTOR (loop_vinfo) / nunits;
int j;
- tree next_stmt, first_stmt = NULL_TREE;
+ gimple next_stmt, first_stmt = NULL;
bool strided_store = false;
unsigned int group_size, i;
VEC(tree,heap) *dr_chain = NULL, *oprnds = NULL, *result_chain = NULL;
@@ -4736,16 +4793,17 @@ vectorizable_store (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt,
/* Is vectorizable store? */
- if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT)
+ if (!is_gimple_assign (stmt))
return false;
- scalar_dest = GIMPLE_STMT_OPERAND (stmt, 0);
+ scalar_dest = gimple_assign_lhs (stmt);
if (TREE_CODE (scalar_dest) != ARRAY_REF
&& TREE_CODE (scalar_dest) != INDIRECT_REF
&& !STMT_VINFO_STRIDED_ACCESS (stmt_info))
return false;
- op = GIMPLE_STMT_OPERAND (stmt, 1);
+ gcc_assert (gimple_assign_single_p (stmt));
+ op = gimple_assign_rhs1 (stmt);
if (!vect_is_simple_use (op, loop_vinfo, &def_stmt, &def, &dt))
{
if (vect_print_dump_info (REPORT_DETAILS))
@@ -4795,7 +4853,8 @@ vectorizable_store (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt,
next_stmt = DR_GROUP_NEXT_DR (stmt_info);
while (next_stmt)
{
- op = GIMPLE_STMT_OPERAND (next_stmt, 1);
+ gcc_assert (gimple_assign_single_p (next_stmt));
+ op = gimple_assign_rhs1 (next_stmt);
if (!vect_is_simple_use (op, loop_vinfo, &def_stmt, &def, &dt))
{
if (vect_print_dump_info (REPORT_DETAILS))
@@ -4833,7 +4892,7 @@ vectorizable_store (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt,
< DR_GROUP_SIZE (vinfo_for_stmt (first_stmt))
&& !slp)
{
- *vec_stmt = NULL_TREE;
+ *vec_stmt = NULL;
return true;
}
@@ -4906,8 +4965,8 @@ vectorizable_store (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt,
prev_stmt_info = NULL;
for (j = 0; j < ncopies; j++)
{
- tree new_stmt;
- tree ptr_incr;
+ gimple new_stmt;
+ gimple ptr_incr;
if (j == 0)
{
@@ -4936,7 +4995,8 @@ vectorizable_store (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt,
there is no interleaving, GROUP_SIZE is 1, and only one
iteration of the loop will be executed. */
gcc_assert (next_stmt);
- op = GIMPLE_STMT_OPERAND (next_stmt, 1);
+ gcc_assert (gimple_assign_single_p (next_stmt));
+ op = gimple_assign_rhs1 (next_stmt);
vec_oprnd = vect_get_vec_def_for_operand (op, next_stmt,
NULL);
@@ -4972,14 +5032,14 @@ vectorizable_store (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt,
VEC_replace(tree, oprnds, i, vec_oprnd);
}
dataref_ptr =
- bump_vector_ptr (dataref_ptr, ptr_incr, bsi, stmt, NULL_TREE);
+ bump_vector_ptr (dataref_ptr, ptr_incr, gsi, stmt, NULL_TREE);
}
if (strided_store)
{
result_chain = VEC_alloc (tree, heap, group_size);
/* Permute. */
- if (!vect_permute_store_chain (dr_chain, group_size, stmt, bsi,
+ if (!vect_permute_store_chain (dr_chain, group_size, stmt, gsi,
&result_chain))
return false;
}
@@ -4989,7 +5049,7 @@ vectorizable_store (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt,
{
if (i > 0)
/* Bump the vector pointer. */
- dataref_ptr = bump_vector_ptr (dataref_ptr, ptr_incr, bsi, stmt,
+ dataref_ptr = bump_vector_ptr (dataref_ptr, ptr_incr, gsi, stmt,
NULL_TREE);
if (slp)
@@ -5001,8 +5061,8 @@ vectorizable_store (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt,
data_ref = build_fold_indirect_ref (dataref_ptr);
/* Arguments are ready. Create the new vector stmt. */
- new_stmt = build_gimple_modify_stmt (data_ref, vec_oprnd);
- vect_finish_stmt_generation (stmt, new_stmt, bsi);
+ new_stmt = gimple_build_assign (data_ref, vec_oprnd);
+ vect_finish_stmt_generation (stmt, new_stmt, gsi);
mark_symbols_for_renaming (new_stmt);
if (j == 0)
@@ -5078,7 +5138,7 @@ vectorizable_store (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt,
Return value - the result of the loop-header phi node. */
static tree
-vect_setup_realignment (tree stmt, block_stmt_iterator *bsi,
+vect_setup_realignment (gimple stmt, gimple_stmt_iterator *gsi,
tree *realignment_token,
enum dr_alignment_support alignment_support_scheme,
tree init_addr,
@@ -5089,22 +5149,22 @@ vect_setup_realignment (tree stmt, block_stmt_iterator *bsi,
loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
edge pe;
- tree scalar_dest = GIMPLE_STMT_OPERAND (stmt, 0);
+ tree scalar_dest = gimple_assign_lhs (stmt);
tree vec_dest;
- tree inc;
+ gimple inc;
tree ptr;
tree data_ref;
- tree new_stmt;
+ gimple new_stmt;
basic_block new_bb;
tree msq_init = NULL_TREE;
tree new_temp;
- tree phi_stmt;
+ gimple phi_stmt;
tree msq = NULL_TREE;
- tree stmts = NULL_TREE;
+ gimple_seq stmts = NULL;
bool inv_p;
bool compute_in_loop = false;
bool nested_in_vect_loop = nested_in_vect_loop_p (loop, stmt);
- struct loop *containing_loop = (bb_for_stmt (stmt))->loop_father;
+ struct loop *containing_loop = (gimple_bb (stmt))->loop_father;
struct loop *loop_for_initial_load;
gcc_assert (alignment_support_scheme == dr_explicit_realign
@@ -5188,13 +5248,13 @@ vect_setup_realignment (tree stmt, block_stmt_iterator *bsi,
ptr = vect_create_data_ref_ptr (stmt, loop_for_initial_load, NULL_TREE,
&init_addr, &inc, true, &inv_p);
data_ref = build1 (ALIGN_INDIRECT_REF, vectype, ptr);
- new_stmt = build_gimple_modify_stmt (vec_dest, data_ref);
+ new_stmt = gimple_build_assign (vec_dest, data_ref);
new_temp = make_ssa_name (vec_dest, new_stmt);
- GIMPLE_STMT_OPERAND (new_stmt, 0) = new_temp;
+ gimple_assign_set_lhs (new_stmt, new_temp);
mark_symbols_for_renaming (new_stmt);
- new_bb = bsi_insert_on_edge_immediate (pe, new_stmt);
+ new_bb = gsi_insert_on_edge_immediate (pe, new_stmt);
gcc_assert (!new_bb);
- msq_init = GIMPLE_STMT_OPERAND (new_stmt, 0);
+ msq_init = gimple_assign_lhs (new_stmt);
}
/* 4. Create realignment token using a target builtin, if available.
@@ -5214,29 +5274,29 @@ vect_setup_realignment (tree stmt, block_stmt_iterator *bsi,
init_addr = vect_create_addr_base_for_vector_ref (stmt, &stmts,
NULL_TREE, loop);
pe = loop_preheader_edge (loop);
- new_bb = bsi_insert_on_edge_immediate (pe, stmts);
+ new_bb = gsi_insert_seq_on_edge_immediate (pe, stmts);
gcc_assert (!new_bb);
}
builtin_decl = targetm.vectorize.builtin_mask_for_load ();
- new_stmt = build_call_expr (builtin_decl, 1, init_addr);
- vec_dest = vect_create_destination_var (scalar_dest,
- TREE_TYPE (new_stmt));
- new_stmt = build_gimple_modify_stmt (vec_dest, new_stmt);
+ new_stmt = gimple_build_call (builtin_decl, 1, init_addr);
+ vec_dest =
+ vect_create_destination_var (scalar_dest,
+ gimple_call_return_type (new_stmt));
new_temp = make_ssa_name (vec_dest, new_stmt);
- GIMPLE_STMT_OPERAND (new_stmt, 0) = new_temp;
+ gimple_call_set_lhs (new_stmt, new_temp);
if (compute_in_loop)
- bsi_insert_before (bsi, new_stmt, BSI_SAME_STMT);
+ gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT);
else
{
/* Generate the misalignment computation outside LOOP. */
pe = loop_preheader_edge (loop);
- new_bb = bsi_insert_on_edge_immediate (pe, new_stmt);
+ new_bb = gsi_insert_on_edge_immediate (pe, new_stmt);
gcc_assert (!new_bb);
}
- *realignment_token = GIMPLE_STMT_OPERAND (new_stmt, 0);
+ *realignment_token = gimple_call_lhs (new_stmt);
/* The result of the CALL_EXPR to this builtin is determined from
the value of the parameter and no global variables are touched
@@ -5257,7 +5317,7 @@ vect_setup_realignment (tree stmt, block_stmt_iterator *bsi,
pe = loop_preheader_edge (containing_loop);
vec_dest = vect_create_destination_var (scalar_dest, vectype);
- msq = make_ssa_name (vec_dest, NULL_TREE);
+ msq = make_ssa_name (vec_dest, NULL);
phi_stmt = create_phi_node (msq, containing_loop->header);
SSA_NAME_DEF_STMT (msq) = phi_stmt;
add_phi_arg (phi_stmt, msq_init, pe);
@@ -5393,13 +5453,13 @@ vect_strided_load_supported (tree vectype)
static bool
vect_permute_load_chain (VEC(tree,heap) *dr_chain,
unsigned int length,
- tree stmt,
- block_stmt_iterator *bsi,
+ gimple stmt,
+ gimple_stmt_iterator *gsi,
VEC(tree,heap) **result_chain)
{
- tree perm_dest, perm_stmt, data_ref, first_vect, second_vect;
+ tree perm_dest, data_ref, first_vect, second_vect;
+ gimple perm_stmt;
tree vectype = STMT_VINFO_VECTYPE (vinfo_for_stmt (stmt));
- tree tmp;
int i;
unsigned int j;
@@ -5420,13 +5480,13 @@ vect_permute_load_chain (VEC(tree,heap) *dr_chain,
DECL_GIMPLE_REG_P (perm_dest) = 1;
add_referenced_var (perm_dest);
- tmp = build2 (VEC_EXTRACT_EVEN_EXPR, vectype,
- first_vect, second_vect);
- perm_stmt = build_gimple_modify_stmt (perm_dest, tmp);
+ perm_stmt = gimple_build_assign_with_ops (VEC_EXTRACT_EVEN_EXPR,
+ perm_dest, first_vect,
+ second_vect);
data_ref = make_ssa_name (perm_dest, perm_stmt);
- GIMPLE_STMT_OPERAND (perm_stmt, 0) = data_ref;
- vect_finish_stmt_generation (stmt, perm_stmt, bsi);
+ gimple_assign_set_lhs (perm_stmt, data_ref);
+ vect_finish_stmt_generation (stmt, perm_stmt, gsi);
mark_symbols_for_renaming (perm_stmt);
VEC_replace (tree, *result_chain, j/2, data_ref);
@@ -5436,12 +5496,12 @@ vect_permute_load_chain (VEC(tree,heap) *dr_chain,
DECL_GIMPLE_REG_P (perm_dest) = 1;
add_referenced_var (perm_dest);
- tmp = build2 (VEC_EXTRACT_ODD_EXPR, vectype,
- first_vect, second_vect);
- perm_stmt = build_gimple_modify_stmt (perm_dest, tmp);
+ perm_stmt = gimple_build_assign_with_ops (VEC_EXTRACT_ODD_EXPR,
+ perm_dest, first_vect,
+ second_vect);
data_ref = make_ssa_name (perm_dest, perm_stmt);
- GIMPLE_STMT_OPERAND (perm_stmt, 0) = data_ref;
- vect_finish_stmt_generation (stmt, perm_stmt, bsi);
+ gimple_assign_set_lhs (perm_stmt, data_ref);
+ vect_finish_stmt_generation (stmt, perm_stmt, gsi);
mark_symbols_for_renaming (perm_stmt);
VEC_replace (tree, *result_chain, j/2+length/2, data_ref);
@@ -5460,12 +5520,12 @@ vect_permute_load_chain (VEC(tree,heap) *dr_chain,
*/
static bool
-vect_transform_strided_load (tree stmt, VEC(tree,heap) *dr_chain, int size,
- block_stmt_iterator *bsi)
+vect_transform_strided_load (gimple stmt, VEC(tree,heap) *dr_chain, int size,
+ gimple_stmt_iterator *gsi)
{
stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
- tree first_stmt = DR_GROUP_FIRST_DR (stmt_info);
- tree next_stmt, new_stmt;
+ gimple first_stmt = DR_GROUP_FIRST_DR (stmt_info);
+ gimple next_stmt, new_stmt;
VEC(tree,heap) *result_chain = NULL;
unsigned int i, gap_count;
tree tmp_data_ref;
@@ -5475,7 +5535,7 @@ vect_transform_strided_load (tree stmt, VEC(tree,heap) *dr_chain, int size,
vectors, that are ready for vector computation. */
result_chain = VEC_alloc (tree, heap, size);
/* Permute. */
- if (!vect_permute_load_chain (dr_chain, size, stmt, bsi, &result_chain))
+ if (!vect_permute_load_chain (dr_chain, size, stmt, gsi, &result_chain))
return false;
/* Put a permuted data-ref in the VECTORIZED_STMT field.
@@ -5512,9 +5572,10 @@ vect_transform_strided_load (tree stmt, VEC(tree,heap) *dr_chain, int size,
STMT_VINFO_VEC_STMT (vinfo_for_stmt (next_stmt)) = new_stmt;
else
{
- tree prev_stmt = STMT_VINFO_VEC_STMT (vinfo_for_stmt (next_stmt));
- tree rel_stmt = STMT_VINFO_RELATED_STMT (
- vinfo_for_stmt (prev_stmt));
+ gimple prev_stmt =
+ STMT_VINFO_VEC_STMT (vinfo_for_stmt (next_stmt));
+ gimple rel_stmt =
+ STMT_VINFO_RELATED_STMT (vinfo_for_stmt (prev_stmt));
while (rel_stmt)
{
prev_stmt = rel_stmt;
@@ -5546,44 +5607,44 @@ vect_transform_strided_load (tree stmt, VEC(tree,heap) *dr_chain, int size,
Return FALSE if not a vectorizable STMT, TRUE otherwise. */
bool
-vectorizable_load (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt,
+vectorizable_load (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
slp_tree slp_node)
{
tree scalar_dest;
tree vec_dest = NULL;
tree data_ref = NULL;
- tree op;
stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
stmt_vec_info prev_stmt_info;
loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
- struct loop *containing_loop = (bb_for_stmt (stmt))->loop_father;
+ struct loop *containing_loop = (gimple_bb (stmt))->loop_father;
bool nested_in_vect_loop = nested_in_vect_loop_p (loop, stmt);
struct data_reference *dr = STMT_VINFO_DATA_REF (stmt_info), *first_dr;
tree vectype = STMT_VINFO_VECTYPE (stmt_info);
tree new_temp;
int mode;
- tree new_stmt = NULL_TREE;
+ gimple new_stmt = NULL;
tree dummy;
enum dr_alignment_support alignment_support_scheme;
tree dataref_ptr = NULL_TREE;
- tree ptr_incr;
+ gimple ptr_incr;
int nunits = TYPE_VECTOR_SUBPARTS (vectype);
int ncopies = LOOP_VINFO_VECT_FACTOR (loop_vinfo) / nunits;
int i, j, group_size;
tree msq = NULL_TREE, lsq;
tree offset = NULL_TREE;
tree realignment_token = NULL_TREE;
- tree phi = NULL_TREE;
+ gimple phi = NULL;
VEC(tree,heap) *dr_chain = NULL;
bool strided_load = false;
- tree first_stmt;
+ gimple first_stmt;
tree scalar_type;
bool inv_p;
bool compute_in_loop = false;
struct loop *at_loop;
int vec_num;
bool slp = (slp_node != NULL);
+ enum tree_code code;
/* FORNOW: SLP with multiple types is not supported. The SLP analysis verifies
this, so we can safely override NCOPIES with 1 here. */
@@ -5607,16 +5668,16 @@ vectorizable_load (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt,
return false;
/* Is vectorizable load? */
- if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT)
+ if (!is_gimple_assign (stmt))
return false;
- scalar_dest = GIMPLE_STMT_OPERAND (stmt, 0);
+ scalar_dest = gimple_assign_lhs (stmt);
if (TREE_CODE (scalar_dest) != SSA_NAME)
return false;
- op = GIMPLE_STMT_OPERAND (stmt, 1);
- if (TREE_CODE (op) != ARRAY_REF
- && TREE_CODE (op) != INDIRECT_REF
+ code = gimple_assign_rhs_code (stmt);
+ if (code != ARRAY_REF
+ && code != INDIRECT_REF
&& !STMT_VINFO_STRIDED_ACCESS (stmt_info))
return false;
@@ -5818,7 +5879,7 @@ vectorizable_load (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt,
|| alignment_support_scheme == dr_explicit_realign)
&& !compute_in_loop)
{
- msq = vect_setup_realignment (first_stmt, bsi, &realignment_token,
+ msq = vect_setup_realignment (first_stmt, gsi, &realignment_token,
alignment_support_scheme, NULL_TREE,
&at_loop);
if (alignment_support_scheme == dr_explicit_realign_optimized)
@@ -5841,12 +5902,12 @@ vectorizable_load (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt,
&inv_p);
else
dataref_ptr =
- bump_vector_ptr (dataref_ptr, ptr_incr, bsi, stmt, NULL_TREE);
+ bump_vector_ptr (dataref_ptr, ptr_incr, gsi, stmt, NULL_TREE);
for (i = 0; i < vec_num; i++)
{
if (i > 0)
- dataref_ptr = bump_vector_ptr (dataref_ptr, ptr_incr, bsi, stmt,
+ dataref_ptr = bump_vector_ptr (dataref_ptr, ptr_incr, gsi, stmt,
NULL_TREE);
/* 2. Create the vector-load in the loop. */
@@ -5872,24 +5933,24 @@ vectorizable_load (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt,
tree vs_minus_1 = size_int (TYPE_VECTOR_SUBPARTS (vectype) - 1);
if (compute_in_loop)
- msq = vect_setup_realignment (first_stmt, bsi,
+ msq = vect_setup_realignment (first_stmt, gsi,
&realignment_token,
dr_explicit_realign,
dataref_ptr, NULL);
data_ref = build1 (ALIGN_INDIRECT_REF, vectype, dataref_ptr);
vec_dest = vect_create_destination_var (scalar_dest, vectype);
- new_stmt = build_gimple_modify_stmt (vec_dest, data_ref);
+ new_stmt = gimple_build_assign (vec_dest, data_ref);
new_temp = make_ssa_name (vec_dest, new_stmt);
- GIMPLE_STMT_OPERAND (new_stmt, 0) = new_temp;
- vect_finish_stmt_generation (stmt, new_stmt, bsi);
+ gimple_assign_set_lhs (new_stmt, new_temp);
+ vect_finish_stmt_generation (stmt, new_stmt, gsi);
copy_virtual_operands (new_stmt, stmt);
mark_symbols_for_renaming (new_stmt);
msq = new_temp;
bump = size_binop (MULT_EXPR, vs_minus_1,
TYPE_SIZE_UNIT (scalar_type));
- ptr = bump_vector_ptr (dataref_ptr, NULL_TREE, bsi, stmt, bump);
+ ptr = bump_vector_ptr (dataref_ptr, NULL, gsi, stmt, bump);
data_ref = build1 (ALIGN_INDIRECT_REF, vectype, ptr);
break;
}
@@ -5900,10 +5961,10 @@ vectorizable_load (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt,
gcc_unreachable ();
}
vec_dest = vect_create_destination_var (scalar_dest, vectype);
- new_stmt = build_gimple_modify_stmt (vec_dest, data_ref);
+ new_stmt = gimple_build_assign (vec_dest, data_ref);
new_temp = make_ssa_name (vec_dest, new_stmt);
- GIMPLE_STMT_OPERAND (new_stmt, 0) = new_temp;
- vect_finish_stmt_generation (stmt, new_stmt, bsi);
+ gimple_assign_set_lhs (new_stmt, new_temp);
+ vect_finish_stmt_generation (stmt, new_stmt, gsi);
mark_symbols_for_renaming (new_stmt);
/* 3. Handle explicit realignment if necessary/supported. Create in
@@ -5911,19 +5972,22 @@ vectorizable_load (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt,
if (alignment_support_scheme == dr_explicit_realign_optimized
|| alignment_support_scheme == dr_explicit_realign)
{
- lsq = GIMPLE_STMT_OPERAND (new_stmt, 0);
+ tree tmp;
+
+ lsq = gimple_assign_lhs (new_stmt);
if (!realignment_token)
realignment_token = dataref_ptr;
vec_dest = vect_create_destination_var (scalar_dest, vectype);
- new_stmt = build3 (REALIGN_LOAD_EXPR, vectype, msq, lsq,
- realignment_token);
- new_stmt = build_gimple_modify_stmt (vec_dest, new_stmt);
+ tmp = build3 (REALIGN_LOAD_EXPR, vectype, msq, lsq,
+ realignment_token);
+ new_stmt = gimple_build_assign (vec_dest, tmp);
new_temp = make_ssa_name (vec_dest, new_stmt);
- GIMPLE_STMT_OPERAND (new_stmt, 0) = new_temp;
- vect_finish_stmt_generation (stmt, new_stmt, bsi);
+ gimple_assign_set_lhs (new_stmt, new_temp);
+ vect_finish_stmt_generation (stmt, new_stmt, gsi);
if (alignment_support_scheme == dr_explicit_realign_optimized)
{
+ gcc_assert (phi);
if (i == vec_num - 1 && j == ncopies - 1)
add_phi_arg (phi, lsq, loop_latch_edge (containing_loop));
msq = lsq;
@@ -5944,19 +6008,19 @@ vectorizable_load (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt,
/* CHECKME: bitpos depends on endianess? */
bitpos = bitsize_zero_node;
vec_inv = build3 (BIT_FIELD_REF, scalar_type, new_temp,
- bitsize, bitpos);
+ bitsize, bitpos);
vec_dest =
vect_create_destination_var (scalar_dest, NULL_TREE);
- new_stmt = build_gimple_modify_stmt (vec_dest, vec_inv);
+ new_stmt = gimple_build_assign (vec_dest, vec_inv);
new_temp = make_ssa_name (vec_dest, new_stmt);
- GIMPLE_STMT_OPERAND (new_stmt, 0) = new_temp;
- vect_finish_stmt_generation (stmt, new_stmt, bsi);
+ gimple_assign_set_lhs (new_stmt, new_temp);
+ vect_finish_stmt_generation (stmt, new_stmt, gsi);
for (k = nunits - 1; k >= 0; --k)
t = tree_cons (NULL_TREE, new_temp, t);
/* FIXME: use build_constructor directly. */
vec_inv = build_constructor_from_list (vectype, t);
- new_temp = vect_init_vector (stmt, vec_inv, vectype, bsi);
+ new_temp = vect_init_vector (stmt, vec_inv, vectype, gsi);
new_stmt = SSA_NAME_DEF_STMT (new_temp);
}
else
@@ -5970,7 +6034,7 @@ vectorizable_load (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt,
/* Store vector loads in the corresponding SLP_NODE. */
if (slp)
- VEC_quick_push (tree, SLP_TREE_VEC_STMTS (slp_node), new_stmt);
+ VEC_quick_push (gimple, SLP_TREE_VEC_STMTS (slp_node), new_stmt);
}
/* FORNOW: SLP with multiple types is unsupported. */
@@ -5979,7 +6043,7 @@ vectorizable_load (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt,
if (strided_load)
{
- if (!vect_transform_strided_load (stmt, dr_chain, group_size, bsi))
+ if (!vect_transform_strided_load (stmt, dr_chain, group_size, gsi))
return false;
*vec_stmt = STMT_VINFO_VEC_STMT (stmt_info);
VEC_free (tree, heap, dr_chain);
@@ -6008,37 +6072,42 @@ vectorizable_load (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt,
it can be supported. */
bool
-vectorizable_live_operation (tree stmt,
- block_stmt_iterator *bsi ATTRIBUTE_UNUSED,
- tree *vec_stmt ATTRIBUTE_UNUSED)
+vectorizable_live_operation (gimple stmt,
+ gimple_stmt_iterator *gsi ATTRIBUTE_UNUSED,
+ gimple *vec_stmt ATTRIBUTE_UNUSED)
{
- tree operation;
stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
int i;
int op_type;
tree op;
- tree def, def_stmt;
+ tree def;
+ gimple def_stmt;
enum vect_def_type dt;
+ enum tree_code code;
+ enum gimple_rhs_class rhs_class;
gcc_assert (STMT_VINFO_LIVE_P (stmt_info));
if (STMT_VINFO_DEF_TYPE (stmt_info) == vect_reduction_def)
return false;
- if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT)
+ if (!is_gimple_assign (stmt))
return false;
- if (TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 0)) != SSA_NAME)
+ if (TREE_CODE (gimple_assign_lhs (stmt)) != SSA_NAME)
return false;
/* FORNOW. CHECKME. */
if (nested_in_vect_loop_p (loop, stmt))
return false;
- operation = GIMPLE_STMT_OPERAND (stmt, 1);
- op_type = TREE_OPERAND_LENGTH (operation);
+ code = gimple_assign_rhs_code (stmt);
+ op_type = TREE_CODE_LENGTH (code);
+ rhs_class = get_gimple_rhs_class (code);
+ gcc_assert (rhs_class != GIMPLE_UNARY_RHS || op_type == unary_op);
+ gcc_assert (rhs_class != GIMPLE_BINARY_RHS || op_type == binary_op);
/* FORNOW: support only if all uses are invariant. This means
that the scalar operations can remain in place, unvectorized.
@@ -6046,7 +6115,10 @@ vectorizable_live_operation (tree stmt,
for (i = 0; i < op_type; i++)
{
- op = TREE_OPERAND (operation, i);
+ if (rhs_class == GIMPLE_SINGLE_RHS)
+ op = TREE_OPERAND (gimple_op (stmt, 1), i);
+ else
+ op = gimple_op (stmt, i + 1);
if (op && !vect_is_simple_use (op, loop_vinfo, &def_stmt, &def, &dt))
{
if (vect_print_dump_info (REPORT_DETAILS))
@@ -6087,7 +6159,7 @@ vect_is_simple_cond (tree cond, loop_vec_info loop_vinfo)
if (TREE_CODE (lhs) == SSA_NAME)
{
- tree lhs_def_stmt = SSA_NAME_DEF_STMT (lhs);
+ gimple lhs_def_stmt = SSA_NAME_DEF_STMT (lhs);
if (!vect_is_simple_use (lhs, loop_vinfo, &lhs_def_stmt, &def, &dt))
return false;
}
@@ -6097,7 +6169,7 @@ vect_is_simple_cond (tree cond, loop_vec_info loop_vinfo)
if (TREE_CODE (rhs) == SSA_NAME)
{
- tree rhs_def_stmt = SSA_NAME_DEF_STMT (rhs);
+ gimple rhs_def_stmt = SSA_NAME_DEF_STMT (rhs);
if (!vect_is_simple_use (rhs, loop_vinfo, &rhs_def_stmt, &def, &dt))
return false;
}
@@ -6118,7 +6190,8 @@ vect_is_simple_cond (tree cond, loop_vec_info loop_vinfo)
Return FALSE if not a vectorizable STMT, TRUE otherwise. */
bool
-vectorizable_condition (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt)
+vectorizable_condition (gimple stmt, gimple_stmt_iterator *gsi,
+ gimple *vec_stmt)
{
tree scalar_dest = NULL_TREE;
tree vec_dest = NULL_TREE;
@@ -6135,6 +6208,7 @@ vectorizable_condition (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt)
enum vect_def_type dt;
int nunits = TYPE_VECTOR_SUBPARTS (vectype);
int ncopies = LOOP_VINFO_VECT_FACTOR (loop_vinfo) / nunits;
+ enum tree_code code;
gcc_assert (ncopies >= 1);
if (ncopies > 1)
@@ -6159,14 +6233,16 @@ vectorizable_condition (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt)
}
/* Is vectorizable conditional operation? */
- if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT)
+ if (!is_gimple_assign (stmt))
return false;
- op = GIMPLE_STMT_OPERAND (stmt, 1);
+ code = gimple_assign_rhs_code (stmt);
- if (TREE_CODE (op) != COND_EXPR)
+ if (code != COND_EXPR)
return false;
+ gcc_assert (gimple_assign_single_p (stmt));
+ op = gimple_assign_rhs1 (stmt);
cond_expr = TREE_OPERAND (op, 0);
then_clause = TREE_OPERAND (op, 1);
else_clause = TREE_OPERAND (op, 2);
@@ -6181,7 +6257,7 @@ vectorizable_condition (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt)
if (TREE_CODE (then_clause) == SSA_NAME)
{
- tree then_def_stmt = SSA_NAME_DEF_STMT (then_clause);
+ gimple then_def_stmt = SSA_NAME_DEF_STMT (then_clause);
if (!vect_is_simple_use (then_clause, loop_vinfo,
&then_def_stmt, &def, &dt))
return false;
@@ -6193,7 +6269,7 @@ vectorizable_condition (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt)
if (TREE_CODE (else_clause) == SSA_NAME)
{
- tree else_def_stmt = SSA_NAME_DEF_STMT (else_clause);
+ gimple else_def_stmt = SSA_NAME_DEF_STMT (else_clause);
if (!vect_is_simple_use (else_clause, loop_vinfo,
&else_def_stmt, &def, &dt))
return false;
@@ -6215,7 +6291,7 @@ vectorizable_condition (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt)
/* Transform */
/* Handle def. */
- scalar_dest = GIMPLE_STMT_OPERAND (stmt, 0);
+ scalar_dest = gimple_assign_lhs (stmt);
vec_dest = vect_create_destination_var (scalar_dest, vectype);
/* Handle cond expr. */
@@ -6232,10 +6308,10 @@ vectorizable_condition (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt)
vec_cond_expr = build3 (VEC_COND_EXPR, vectype,
vec_compare, vec_then_clause, vec_else_clause);
- *vec_stmt = build_gimple_modify_stmt (vec_dest, vec_cond_expr);
+ *vec_stmt = gimple_build_assign (vec_dest, vec_cond_expr);
new_temp = make_ssa_name (vec_dest, *vec_stmt);
- GIMPLE_STMT_OPERAND (*vec_stmt, 0) = new_temp;
- vect_finish_stmt_generation (stmt, *vec_stmt, bsi);
+ gimple_assign_set_lhs (*vec_stmt, new_temp);
+ vect_finish_stmt_generation (stmt, *vec_stmt, gsi);
return true;
}
@@ -6246,57 +6322,57 @@ vectorizable_condition (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt)
Create a vectorized stmt to replace STMT, and insert it at BSI. */
static bool
-vect_transform_stmt (tree stmt, block_stmt_iterator *bsi, bool *strided_store,
- slp_tree slp_node)
+vect_transform_stmt (gimple stmt, gimple_stmt_iterator *gsi,
+ bool *strided_store, slp_tree slp_node)
{
bool is_store = false;
- tree vec_stmt = NULL_TREE;
+ gimple vec_stmt = NULL;
stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
- tree orig_stmt_in_pattern;
+ gimple orig_stmt_in_pattern;
bool done;
switch (STMT_VINFO_TYPE (stmt_info))
{
case type_demotion_vec_info_type:
gcc_assert (!slp_node);
- done = vectorizable_type_demotion (stmt, bsi, &vec_stmt);
+ done = vectorizable_type_demotion (stmt, gsi, &vec_stmt);
gcc_assert (done);
break;
case type_promotion_vec_info_type:
gcc_assert (!slp_node);
- done = vectorizable_type_promotion (stmt, bsi, &vec_stmt);
+ done = vectorizable_type_promotion (stmt, gsi, &vec_stmt);
gcc_assert (done);
break;
case type_conversion_vec_info_type:
- done = vectorizable_conversion (stmt, bsi, &vec_stmt, slp_node);
+ done = vectorizable_conversion (stmt, gsi, &vec_stmt, slp_node);
gcc_assert (done);
break;
case induc_vec_info_type:
gcc_assert (!slp_node);
- done = vectorizable_induction (stmt, bsi, &vec_stmt);
+ done = vectorizable_induction (stmt, gsi, &vec_stmt);
gcc_assert (done);
break;
case op_vec_info_type:
- done = vectorizable_operation (stmt, bsi, &vec_stmt, slp_node);
+ done = vectorizable_operation (stmt, gsi, &vec_stmt, slp_node);
gcc_assert (done);
break;
case assignment_vec_info_type:
- done = vectorizable_assignment (stmt, bsi, &vec_stmt, slp_node);
+ done = vectorizable_assignment (stmt, gsi, &vec_stmt, slp_node);
gcc_assert (done);
break;
case load_vec_info_type:
- done = vectorizable_load (stmt, bsi, &vec_stmt, slp_node);
+ done = vectorizable_load (stmt, gsi, &vec_stmt, slp_node);
gcc_assert (done);
break;
case store_vec_info_type:
- done = vectorizable_store (stmt, bsi, &vec_stmt, slp_node);
+ done = vectorizable_store (stmt, gsi, &vec_stmt, slp_node);
gcc_assert (done);
if (STMT_VINFO_STRIDED_ACCESS (stmt_info))
{
@@ -6314,18 +6390,18 @@ vect_transform_stmt (tree stmt, block_stmt_iterator *bsi, bool *strided_store,
case condition_vec_info_type:
gcc_assert (!slp_node);
- done = vectorizable_condition (stmt, bsi, &vec_stmt);
+ done = vectorizable_condition (stmt, gsi, &vec_stmt);
gcc_assert (done);
break;
case call_vec_info_type:
gcc_assert (!slp_node);
- done = vectorizable_call (stmt, bsi, &vec_stmt);
+ done = vectorizable_call (stmt, gsi, &vec_stmt);
break;
case reduc_vec_info_type:
gcc_assert (!slp_node);
- done = vectorizable_reduction (stmt, bsi, &vec_stmt);
+ done = vectorizable_reduction (stmt, gsi, &vec_stmt);
gcc_assert (done);
break;
@@ -6341,7 +6417,7 @@ vect_transform_stmt (tree stmt, block_stmt_iterator *bsi, bool *strided_store,
if (STMT_VINFO_LIVE_P (stmt_info)
&& STMT_VINFO_TYPE (stmt_info) != reduc_vec_info_type)
{
- done = vectorizable_live_operation (stmt, bsi, &vec_stmt);
+ done = vectorizable_live_operation (stmt, gsi, &vec_stmt);
gcc_assert (done);
}
@@ -6375,19 +6451,20 @@ vect_transform_stmt (tree stmt, block_stmt_iterator *bsi, bool *strided_store,
static tree
vect_build_loop_niters (loop_vec_info loop_vinfo)
{
- tree ni_name, stmt, var;
+ tree ni_name, var;
+ gimple_seq stmts = NULL;
edge pe;
struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
tree ni = unshare_expr (LOOP_VINFO_NITERS (loop_vinfo));
var = create_tmp_var (TREE_TYPE (ni), "niters");
add_referenced_var (var);
- ni_name = force_gimple_operand (ni, &stmt, false, var);
+ ni_name = force_gimple_operand (ni, &stmts, false, var);
pe = loop_preheader_edge (loop);
- if (stmt)
+ if (stmts)
{
- basic_block new_bb = bsi_insert_on_edge_immediate (pe, stmt);
+ basic_block new_bb = gsi_insert_seq_on_edge_immediate (pe, stmts);
gcc_assert (!new_bb);
}
@@ -6412,7 +6489,8 @@ vect_generate_tmps_on_preheader (loop_vec_info loop_vinfo,
edge pe;
basic_block new_bb;
- tree stmt, ni_name;
+ gimple_seq stmts;
+ tree ni_name;
tree var;
tree ratio_name;
tree ratio_mult_vf_name;
@@ -6437,9 +6515,10 @@ vect_generate_tmps_on_preheader (loop_vec_info loop_vinfo,
var = create_tmp_var (TREE_TYPE (ni), "bnd");
add_referenced_var (var);
- ratio_name = force_gimple_operand (ratio_name, &stmt, true, var);
+ stmts = NULL;
+ ratio_name = force_gimple_operand (ratio_name, &stmts, true, var);
pe = loop_preheader_edge (loop);
- new_bb = bsi_insert_on_edge_immediate (pe, stmt);
+ new_bb = gsi_insert_seq_on_edge_immediate (pe, stmts);
gcc_assert (!new_bb);
}
@@ -6452,10 +6531,11 @@ vect_generate_tmps_on_preheader (loop_vec_info loop_vinfo,
var = create_tmp_var (TREE_TYPE (ni), "ratio_mult_vf");
add_referenced_var (var);
- ratio_mult_vf_name = force_gimple_operand (ratio_mult_vf_name, &stmt,
+ stmts = NULL;
+ ratio_mult_vf_name = force_gimple_operand (ratio_mult_vf_name, &stmts,
true, var);
pe = loop_preheader_edge (loop);
- new_bb = bsi_insert_on_edge_immediate (pe, stmt);
+ new_bb = gsi_insert_seq_on_edge_immediate (pe, stmts);
gcc_assert (!new_bb);
}
@@ -6514,7 +6594,8 @@ vect_update_ivs_after_vectorizer (loop_vec_info loop_vinfo, tree niters,
{
struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
basic_block exit_bb = single_exit (loop)->dest;
- tree phi, phi1;
+ gimple phi, phi1;
+ gimple_stmt_iterator gsi, gsi1;
basic_block update_bb = update_e->dest;
/* gcc_assert (vect_can_advance_ivs_p (loop_vinfo)); */
@@ -6522,21 +6603,23 @@ vect_update_ivs_after_vectorizer (loop_vec_info loop_vinfo, tree niters,
/* Make sure there exists a single-predecessor exit bb: */
gcc_assert (single_pred_p (exit_bb));
- for (phi = phi_nodes (loop->header), phi1 = phi_nodes (update_bb);
- phi && phi1;
- phi = PHI_CHAIN (phi), phi1 = PHI_CHAIN (phi1))
+ for (gsi = gsi_start_phis (loop->header), gsi1 = gsi_start_phis (update_bb);
+ !gsi_end_p (gsi) && !gsi_end_p (gsi1);
+ gsi_next (&gsi), gsi_next (&gsi1))
{
tree access_fn = NULL;
tree evolution_part;
tree init_expr;
tree step_expr;
tree var, ni, ni_name;
- block_stmt_iterator last_bsi;
+ gimple_stmt_iterator last_gsi;
+ phi = gsi_stmt (gsi);
+ phi1 = gsi_stmt (gsi1);
if (vect_print_dump_info (REPORT_DETAILS))
{
fprintf (vect_dump, "vect_update_ivs_after_vectorizer: phi: ");
- print_generic_expr (vect_dump, phi, TDF_SLIM);
+ print_gimple_stmt (vect_dump, phi, 0, TDF_SLIM);
}
/* Skip virtual phi's. */
@@ -6588,9 +6671,9 @@ vect_update_ivs_after_vectorizer (loop_vec_info loop_vinfo, tree niters,
var = create_tmp_var (TREE_TYPE (init_expr), "tmp");
add_referenced_var (var);
- last_bsi = bsi_last (exit_bb);
- ni_name = force_gimple_operand_bsi (&last_bsi, ni, false, var,
- true, BSI_SAME_STMT);
+ last_gsi = gsi_last_bb (exit_bb);
+ ni_name = force_gimple_operand_gsi (&last_gsi, ni, false, var,
+ true, GSI_SAME_STMT);
/* Fix phi expressions in the successor bb. */
SET_PHI_ARG_DEF (phi1, update_e->dest_idx, ni_name);
@@ -6665,7 +6748,7 @@ vect_do_peeling_for_loop_bound (loop_vec_info loop_vinfo, tree *ratio)
/* If cost model check not done during versioning and
peeling for alignment. */
- if (!VEC_length (tree, LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo))
+ if (!VEC_length (gimple, LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo))
&& !VEC_length (ddr_p, LOOP_VINFO_MAY_ALIAS_DDRS (loop_vinfo))
&& !LOOP_PEELING_FOR_ALIGNMENT (loop_vinfo))
{
@@ -6745,11 +6828,12 @@ vect_gen_niters_for_prolog_loop (loop_vec_info loop_vinfo, tree loop_niters)
{
struct data_reference *dr = LOOP_VINFO_UNALIGNED_DR (loop_vinfo);
struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
- tree var, stmt;
+ tree var;
+ gimple_seq stmts;
tree iters, iters_name;
edge pe;
basic_block new_bb;
- tree dr_stmt = DR_STMT (dr);
+ gimple dr_stmt = DR_STMT (dr);
stmt_vec_info stmt_info = vinfo_for_stmt (dr_stmt);
tree vectype = STMT_VINFO_VECTYPE (stmt_info);
int vectype_align = TYPE_ALIGN (vectype) / BITS_PER_UNIT;
@@ -6776,7 +6860,7 @@ vect_gen_niters_for_prolog_loop (loop_vec_info loop_vinfo, tree loop_niters)
}
else
{
- tree new_stmts = NULL_TREE;
+ gimple_seq new_stmts = NULL;
tree start_addr = vect_create_addr_base_for_vector_ref (dr_stmt,
&new_stmts, NULL_TREE, loop);
tree ptr_type = TREE_TYPE (start_addr);
@@ -6790,7 +6874,7 @@ vect_gen_niters_for_prolog_loop (loop_vec_info loop_vinfo, tree loop_niters)
tree byte_misalign;
tree elem_misalign;
- new_bb = bsi_insert_on_edge_immediate (pe, new_stmts);
+ new_bb = gsi_insert_seq_on_edge_immediate (pe, new_stmts);
gcc_assert (!new_bb);
/* Create: byte_misalign = addr & (vectype_size - 1) */
@@ -6822,12 +6906,13 @@ vect_gen_niters_for_prolog_loop (loop_vec_info loop_vinfo, tree loop_niters)
var = create_tmp_var (niters_type, "prolog_loop_niters");
add_referenced_var (var);
- iters_name = force_gimple_operand (iters, &stmt, false, var);
+ stmts = NULL;
+ iters_name = force_gimple_operand (iters, &stmts, false, var);
/* Insert stmt on loop preheader edge. */
- if (stmt)
+ if (stmts)
{
- basic_block new_bb = bsi_insert_on_edge_immediate (pe, stmt);
+ basic_block new_bb = gsi_insert_seq_on_edge_immediate (pe, stmts);
gcc_assert (!new_bb);
}
@@ -6905,7 +6990,7 @@ vect_do_peeling_for_alignment (loop_vec_info loop_vinfo)
/* If cost model check not done during versioning. */
- if (!VEC_length (tree, LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo))
+ if (!VEC_length (gimple, LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo))
&& !VEC_length (ddr_p, LOOP_VINFO_MAY_ALIAS_DDRS (loop_vinfo)))
{
check_profitability = true;
@@ -6971,12 +7056,12 @@ vect_do_peeling_for_alignment (loop_vec_info loop_vinfo)
static void
vect_create_cond_for_align_checks (loop_vec_info loop_vinfo,
tree *cond_expr,
- tree *cond_expr_stmt_list)
+ gimple_seq *cond_expr_stmt_list)
{
struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
- VEC(tree,heap) *may_misalign_stmts
+ VEC(gimple,heap) *may_misalign_stmts
= LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo);
- tree ref_stmt, tmp;
+ gimple ref_stmt;
int mask = LOOP_VINFO_PTR_MASK (loop_vinfo);
tree mask_cst;
unsigned int i;
@@ -6984,7 +7069,8 @@ vect_create_cond_for_align_checks (loop_vec_info loop_vinfo,
tree int_ptrsize_type;
char tmp_name[20];
tree or_tmp_name = NULL_TREE;
- tree and_tmp, and_tmp_name, and_stmt;
+ tree and_tmp, and_tmp_name;
+ gimple and_stmt;
tree ptrsize_zero;
tree part_cond_expr;
@@ -7001,28 +7087,28 @@ vect_create_cond_for_align_checks (loop_vec_info loop_vinfo,
/* Create expression (mask & (dr_1 || ... || dr_n)) where dr_i is the address
of the first vector of the i'th data reference. */
- for (i = 0; VEC_iterate (tree, may_misalign_stmts, i, ref_stmt); i++)
+ for (i = 0; VEC_iterate (gimple, may_misalign_stmts, i, ref_stmt); i++)
{
- tree new_stmt_list = NULL_TREE;
+ gimple_seq new_stmt_list = NULL;
tree addr_base;
- tree addr_tmp, addr_tmp_name, addr_stmt;
- tree or_tmp, new_or_tmp_name, or_stmt;
+ tree addr_tmp, addr_tmp_name;
+ tree or_tmp, new_or_tmp_name;
+ gimple addr_stmt, or_stmt;
/* create: addr_tmp = (int)(address_of_first_vector) */
- addr_base = vect_create_addr_base_for_vector_ref (ref_stmt,
- &new_stmt_list, NULL_TREE, loop);
-
- if (new_stmt_list != NULL_TREE)
- append_to_statement_list_force (new_stmt_list, cond_expr_stmt_list);
+ addr_base =
+ vect_create_addr_base_for_vector_ref (ref_stmt, &new_stmt_list,
+ NULL_TREE, loop);
+ if (new_stmt_list != NULL)
+ gimple_seq_add_seq (cond_expr_stmt_list, new_stmt_list);
sprintf (tmp_name, "%s%d", "addr2int", i);
addr_tmp = create_tmp_var (int_ptrsize_type, tmp_name);
add_referenced_var (addr_tmp);
- addr_tmp_name = make_ssa_name (addr_tmp, NULL_TREE);
- addr_stmt = fold_convert (int_ptrsize_type, addr_base);
- addr_stmt = build_gimple_modify_stmt (addr_tmp_name, addr_stmt);
+ addr_tmp_name = make_ssa_name (addr_tmp, NULL);
+ addr_stmt = gimple_build_assign (addr_tmp_name, addr_base);
SSA_NAME_DEF_STMT (addr_tmp_name) = addr_stmt;
- append_to_statement_list_force (addr_stmt, cond_expr_stmt_list);
+ gimple_seq_add_stmt (cond_expr_stmt_list, addr_stmt);
/* The addresses are OR together. */
@@ -7032,12 +7118,12 @@ vect_create_cond_for_align_checks (loop_vec_info loop_vinfo,
sprintf (tmp_name, "%s%d", "orptrs", i);
or_tmp = create_tmp_var (int_ptrsize_type, tmp_name);
add_referenced_var (or_tmp);
- new_or_tmp_name = make_ssa_name (or_tmp, NULL_TREE);
- tmp = build2 (BIT_IOR_EXPR, int_ptrsize_type,
- or_tmp_name, addr_tmp_name);
- or_stmt = build_gimple_modify_stmt (new_or_tmp_name, tmp);
+ new_or_tmp_name = make_ssa_name (or_tmp, NULL);
+ or_stmt = gimple_build_assign_with_ops (BIT_IOR_EXPR,
+ new_or_tmp_name,
+ or_tmp_name, addr_tmp_name);
SSA_NAME_DEF_STMT (new_or_tmp_name) = or_stmt;
- append_to_statement_list_force (or_stmt, cond_expr_stmt_list);
+ gimple_seq_add_stmt (cond_expr_stmt_list, or_stmt);
or_tmp_name = new_or_tmp_name;
}
else
@@ -7050,12 +7136,12 @@ vect_create_cond_for_align_checks (loop_vec_info loop_vinfo,
/* create: and_tmp = or_tmp & mask */
and_tmp = create_tmp_var (int_ptrsize_type, "andmask" );
add_referenced_var (and_tmp);
- and_tmp_name = make_ssa_name (and_tmp, NULL_TREE);
+ and_tmp_name = make_ssa_name (and_tmp, NULL);
- tmp = build2 (BIT_AND_EXPR, int_ptrsize_type, or_tmp_name, mask_cst);
- and_stmt = build_gimple_modify_stmt (and_tmp_name, tmp);
+ and_stmt = gimple_build_assign_with_ops (BIT_AND_EXPR, and_tmp_name,
+ or_tmp_name, mask_cst);
SSA_NAME_DEF_STMT (and_tmp_name) = and_stmt;
- append_to_statement_list_force (and_stmt, cond_expr_stmt_list);
+ gimple_seq_add_stmt (cond_expr_stmt_list, and_stmt);
/* Make and_tmp the left operand of the conditional test against zero.
if and_tmp has a nonzero bit then some address is unaligned. */
@@ -7124,7 +7210,7 @@ vect_vfa_segment_size (struct data_reference *dr, tree vect_factor)
static void
vect_create_cond_for_alias_checks (loop_vec_info loop_vinfo,
tree * cond_expr,
- tree * cond_expr_stmt_list)
+ gimple_seq * cond_expr_stmt_list)
{
struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
VEC (ddr_p, heap) * may_alias_ddrs =
@@ -7151,10 +7237,10 @@ vect_create_cond_for_alias_checks (loop_vec_info loop_vinfo,
for (i = 0; VEC_iterate (ddr_p, may_alias_ddrs, i, ddr); i++)
{
struct data_reference *dr_a, *dr_b;
- tree dr_group_first_a, dr_group_first_b;
+ gimple dr_group_first_a, dr_group_first_b;
tree addr_base_a, addr_base_b;
tree segment_length_a, segment_length_b;
- tree stmt_a, stmt_b;
+ gimple stmt_a, stmt_b;
dr_a = DDR_A (ddr);
stmt_a = DR_STMT (DDR_A (ddr));
@@ -7209,7 +7295,7 @@ vect_create_cond_for_alias_checks (loop_vec_info loop_vinfo,
if (*cond_expr)
*cond_expr = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
- *cond_expr, part_cond_expr);
+ *cond_expr, part_cond_expr);
else
*cond_expr = part_cond_expr;
}
@@ -7241,15 +7327,16 @@ vect_loop_versioning (loop_vec_info loop_vinfo)
struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
struct loop *nloop;
tree cond_expr = NULL_TREE;
- tree cond_expr_stmt_list = NULL_TREE;
+ gimple_seq cond_expr_stmt_list = NULL;
basic_block condition_bb;
- block_stmt_iterator cond_exp_bsi;
+ gimple_stmt_iterator gsi, cond_exp_gsi;
basic_block merge_bb;
basic_block new_exit_bb;
edge new_exit_e, e;
- tree orig_phi, new_phi, arg;
+ gimple orig_phi, new_phi;
+ tree arg;
unsigned prob = 4 * REG_BR_PROB_BASE / 5;
- tree gimplify_stmt_list;
+ gimple_seq gimplify_stmt_list = NULL;
tree scalar_loop_iters = LOOP_VINFO_NITERS (loop_vinfo);
int min_profitable_iters = 0;
unsigned int th;
@@ -7267,7 +7354,7 @@ vect_loop_versioning (loop_vec_info loop_vinfo)
cond_expr = force_gimple_operand (cond_expr, &cond_expr_stmt_list,
false, NULL_TREE);
- if (VEC_length (tree, LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo)))
+ if (VEC_length (gimple, LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo)))
vect_create_cond_for_align_checks (loop_vinfo, &cond_expr,
&cond_expr_stmt_list);
@@ -7278,9 +7365,8 @@ vect_loop_versioning (loop_vec_info loop_vinfo)
cond_expr =
fold_build2 (NE_EXPR, boolean_type_node, cond_expr, integer_zero_node);
cond_expr =
- force_gimple_operand (cond_expr, &gimplify_stmt_list, true,
- NULL_TREE);
- append_to_statement_list (gimplify_stmt_list, &cond_expr_stmt_list);
+ force_gimple_operand (cond_expr, &gimplify_stmt_list, true, NULL_TREE);
+ gimple_seq_add_seq (&cond_expr_stmt_list, gimplify_stmt_list);
initialize_original_copy_tables ();
nloop = loop_version (loop, cond_expr, &condition_bb,
@@ -7301,9 +7387,9 @@ vect_loop_versioning (loop_vec_info loop_vinfo)
new_exit_e = single_exit (loop);
e = EDGE_SUCC (new_exit_bb, 0);
- for (orig_phi = phi_nodes (merge_bb); orig_phi;
- orig_phi = PHI_CHAIN (orig_phi))
+ for (gsi = gsi_start_phis (merge_bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
+ orig_phi = gsi_stmt (gsi);
new_phi = create_phi_node (SSA_NAME_VAR (PHI_RESULT (orig_phi)),
new_exit_bb);
arg = PHI_ARG_DEF_FROM_EDGE (orig_phi, e);
@@ -7316,8 +7402,8 @@ vect_loop_versioning (loop_vec_info loop_vinfo)
update_ssa (TODO_update_ssa);
if (cond_expr_stmt_list)
{
- cond_exp_bsi = bsi_last (condition_bb);
- bsi_insert_before (&cond_exp_bsi, cond_expr_stmt_list, BSI_SAME_STMT);
+ cond_exp_gsi = gsi_last_bb (condition_bb);
+ gsi_insert_seq_before (&cond_exp_gsi, cond_expr_stmt_list, GSI_SAME_STMT);
}
}
@@ -7325,17 +7411,17 @@ vect_loop_versioning (loop_vec_info loop_vinfo)
stmt_vec_info. */
static void
-vect_remove_stores (tree first_stmt)
+vect_remove_stores (gimple first_stmt)
{
- tree next = first_stmt;
- tree tmp;
- block_stmt_iterator next_si;
+ gimple next = first_stmt;
+ gimple tmp;
+ gimple_stmt_iterator next_si;
while (next)
{
/* Free the attached stmt_vec_info and remove the stmt. */
- next_si = bsi_for_stmt (next);
- bsi_remove (&next_si, true);
+ next_si = gsi_for_stmt (next);
+ gsi_remove (&next_si, true);
tmp = DR_GROUP_NEXT_DR (vinfo_for_stmt (next));
free_stmt_vec_info (next);
next = tmp;
@@ -7348,9 +7434,9 @@ vect_remove_stores (tree first_stmt)
static bool
vect_schedule_slp_instance (slp_tree node, unsigned int vec_stmts_size)
{
- tree stmt;
+ gimple stmt;
bool strided_store, is_store;
- block_stmt_iterator si;
+ gimple_stmt_iterator si;
stmt_vec_info stmt_info;
if (!node)
@@ -7359,18 +7445,18 @@ vect_schedule_slp_instance (slp_tree node, unsigned int vec_stmts_size)
vect_schedule_slp_instance (SLP_TREE_LEFT (node), vec_stmts_size);
vect_schedule_slp_instance (SLP_TREE_RIGHT (node), vec_stmts_size);
- stmt = VEC_index(tree, SLP_TREE_SCALAR_STMTS (node), 0);
+ stmt = VEC_index(gimple, SLP_TREE_SCALAR_STMTS (node), 0);
stmt_info = vinfo_for_stmt (stmt);
- SLP_TREE_VEC_STMTS (node) = VEC_alloc (tree, heap, vec_stmts_size);
+ SLP_TREE_VEC_STMTS (node) = VEC_alloc (gimple, heap, vec_stmts_size);
SLP_TREE_NUMBER_OF_VEC_STMTS (node) = vec_stmts_size;
if (vect_print_dump_info (REPORT_DETAILS))
{
fprintf (vect_dump, "------>vectorizing SLP node starting from: ");
- print_generic_expr (vect_dump, stmt, TDF_SLIM);
+ print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
}
- si = bsi_for_stmt (stmt);
+ si = gsi_for_stmt (stmt);
is_store = vect_transform_stmt (stmt, &si, &strided_store, node);
if (is_store)
{
@@ -7436,7 +7522,7 @@ vect_transform_loop (loop_vec_info loop_vinfo)
struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo);
int nbbs = loop->num_nodes;
- block_stmt_iterator si;
+ gimple_stmt_iterator si;
int i;
tree ratio = NULL;
int vectorization_factor = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
@@ -7447,7 +7533,7 @@ vect_transform_loop (loop_vec_info loop_vinfo)
if (vect_print_dump_info (REPORT_DETAILS))
fprintf (vect_dump, "=== vec_transform_loop ===");
- if (VEC_length (tree, LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo))
+ if (VEC_length (gimple, LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo))
|| VEC_length (ddr_p, LOOP_VINFO_MAY_ALIAS_DDRS (loop_vinfo)))
vect_loop_versioning (loop_vinfo);
@@ -7493,14 +7579,15 @@ vect_transform_loop (loop_vec_info loop_vinfo)
{
basic_block bb = bbs[i];
stmt_vec_info stmt_info;
- tree phi;
+ gimple phi;
- for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
+ for (si = gsi_start_phis (bb); !gsi_end_p (si); gsi_next (&si))
{
+ phi = gsi_stmt (si);
if (vect_print_dump_info (REPORT_DETAILS))
{
fprintf (vect_dump, "------>vectorizing phi: ");
- print_generic_expr (vect_dump, phi, TDF_SLIM);
+ print_gimple_stmt (vect_dump, phi, 0, TDF_SLIM);
}
stmt_info = vinfo_for_stmt (phi);
if (!stmt_info)
@@ -7523,15 +7610,15 @@ vect_transform_loop (loop_vec_info loop_vinfo)
}
}
- for (si = bsi_start (bb); !bsi_end_p (si);)
+ for (si = gsi_start_bb (bb); !gsi_end_p (si);)
{
- tree stmt = bsi_stmt (si);
+ gimple stmt = gsi_stmt (si);
bool is_store;
if (vect_print_dump_info (REPORT_DETAILS))
{
fprintf (vect_dump, "------>vectorizing statement: ");
- print_generic_expr (vect_dump, stmt, TDF_SLIM);
+ print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
}
stmt_info = vinfo_for_stmt (stmt);
@@ -7541,14 +7628,14 @@ vect_transform_loop (loop_vec_info loop_vinfo)
need to be vectorized. */
if (!stmt_info)
{
- bsi_next (&si);
+ gsi_next (&si);
continue;
}
if (!STMT_VINFO_RELEVANT_P (stmt_info)
&& !STMT_VINFO_LIVE_P (stmt_info))
{
- bsi_next (&si);
+ gsi_next (&si);
continue;
}
@@ -7580,7 +7667,7 @@ vect_transform_loop (loop_vec_info loop_vinfo)
vect_schedule_slp_instance and their vinfo is destroyed. */
if (is_store)
{
- bsi_next (&si);
+ gsi_next (&si);
continue;
}
}
@@ -7588,7 +7675,7 @@ vect_transform_loop (loop_vec_info loop_vinfo)
/* Hybrid SLP stmts must be vectorized in addition to SLP. */
if (PURE_SLP_STMT (stmt_info))
{
- bsi_next (&si);
+ gsi_next (&si);
continue;
}
}
@@ -7607,18 +7694,18 @@ vect_transform_loop (loop_vec_info loop_vinfo)
interleaving chain was completed - free all the stores in
the chain. */
vect_remove_stores (DR_GROUP_FIRST_DR (stmt_info));
- bsi_remove (&si, true);
+ gsi_remove (&si, true);
continue;
}
else
{
/* Free the attached stmt_vec_info and remove the stmt. */
free_stmt_vec_info (stmt);
- bsi_remove (&si, true);
+ gsi_remove (&si, true);
continue;
}
}
- bsi_next (&si);
+ gsi_next (&si);
} /* stmts in BB */
} /* BBs in loop */
diff --git a/gcc/tree-vectorizer.c b/gcc/tree-vectorizer.c
index 5bfa30b21d4..3526de45bb3 100644
--- a/gcc/tree-vectorizer.c
+++ b/gcc/tree-vectorizer.c
@@ -144,6 +144,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-data-ref.h"
#include "tree-scalar-evolution.h"
#include "input.h"
+#include "hashtab.h"
#include "tree-vectorizer.h"
#include "tree-pass.h"
@@ -163,6 +164,10 @@ static LOC vect_loop_location;
/* Bitmap of virtual variables to be renamed. */
bitmap vect_memsyms_to_rename;
+
+/* Vector mapping GIMPLE stmt to stmt_vec_info. */
+VEC(vec_void_p,heap) *stmt_vec_info_vec;
+
/*************************************************************************
Simple Loop Peeling Utilities
@@ -198,18 +203,17 @@ rename_use_op (use_operand_p op_p)
static void
rename_variables_in_bb (basic_block bb)
{
- tree phi;
- block_stmt_iterator bsi;
- tree stmt;
+ gimple_stmt_iterator gsi;
+ gimple stmt;
use_operand_p use_p;
ssa_op_iter iter;
edge e;
edge_iterator ei;
struct loop *loop = bb->loop_father;
- for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
- stmt = bsi_stmt (bsi);
+ stmt = gsi_stmt (gsi);
FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_ALL_USES)
rename_use_op (use_p);
}
@@ -218,8 +222,8 @@ rename_variables_in_bb (basic_block bb)
{
if (!flow_bb_inside_loop_p (loop, e->dest))
continue;
- for (phi = phi_nodes (e->dest); phi; phi = PHI_CHAIN (phi))
- rename_use_op (PHI_ARG_DEF_PTR_FROM_EDGE (phi, e));
+ for (gsi = gsi_start_phis (e->dest); !gsi_end_p (gsi); gsi_next (&gsi))
+ rename_use_op (PHI_ARG_DEF_PTR_FROM_EDGE (gsi_stmt (gsi), e));
}
}
@@ -253,13 +257,14 @@ slpeel_update_phis_for_duplicate_loop (struct loop *orig_loop,
struct loop *new_loop, bool after)
{
tree new_ssa_name;
- tree phi_new, phi_orig;
+ gimple phi_new, phi_orig;
tree def;
edge orig_loop_latch = loop_latch_edge (orig_loop);
edge orig_entry_e = loop_preheader_edge (orig_loop);
edge new_loop_exit_e = single_exit (new_loop);
edge new_loop_entry_e = loop_preheader_edge (new_loop);
edge entry_arg_e = (after ? orig_loop_latch : orig_entry_e);
+ gimple_stmt_iterator gsi_new, gsi_orig;
/*
step 1. For each loop-header-phi:
@@ -290,11 +295,14 @@ slpeel_update_phis_for_duplicate_loop (struct loop *orig_loop,
/* Scan the phis in the headers of the old and new loops
(they are organized in exactly the same order). */
- for (phi_new = phi_nodes (new_loop->header),
- phi_orig = phi_nodes (orig_loop->header);
- phi_new && phi_orig;
- phi_new = PHI_CHAIN (phi_new), phi_orig = PHI_CHAIN (phi_orig))
+ for (gsi_new = gsi_start_phis (new_loop->header),
+ gsi_orig = gsi_start_phis (orig_loop->header);
+ !gsi_end_p (gsi_new) && !gsi_end_p (gsi_orig);
+ gsi_next (&gsi_new), gsi_next (&gsi_orig))
{
+ phi_new = gsi_stmt (gsi_new);
+ phi_orig = gsi_stmt (gsi_orig);
+
/* step 1. */
def = PHI_ARG_DEF_FROM_EDGE (phi_orig, entry_arg_e);
add_phi_arg (phi_new, def, new_loop_entry_e);
@@ -485,8 +493,8 @@ slpeel_update_phi_nodes_for_guard1 (edge guard_edge, struct loop *loop,
bool is_new_loop, basic_block *new_exit_bb,
bitmap *defs)
{
- tree orig_phi, new_phi;
- tree update_phi, update_phi2;
+ gimple orig_phi, new_phi;
+ gimple update_phi, update_phi2;
tree guard_arg, loop_arg;
basic_block new_merge_bb = guard_edge->dest;
edge e = EDGE_SUCC (new_merge_bb, 0);
@@ -495,16 +503,21 @@ slpeel_update_phi_nodes_for_guard1 (edge guard_edge, struct loop *loop,
edge new_exit_e;
tree current_new_name;
tree name;
+ gimple_stmt_iterator gsi_orig, gsi_update;
/* Create new bb between loop and new_merge_bb. */
*new_exit_bb = split_edge (single_exit (loop));
new_exit_e = EDGE_SUCC (*new_exit_bb, 0);
- for (orig_phi = phi_nodes (orig_bb), update_phi = phi_nodes (update_bb);
- orig_phi && update_phi;
- orig_phi = PHI_CHAIN (orig_phi), update_phi = PHI_CHAIN (update_phi))
+ for (gsi_orig = gsi_start_phis (orig_bb),
+ gsi_update = gsi_start_phis (update_bb);
+ !gsi_end_p (gsi_orig) && !gsi_end_p (gsi_update);
+ gsi_next (&gsi_orig), gsi_next (&gsi_update))
{
+ orig_phi = gsi_stmt (gsi_orig);
+ update_phi = gsi_stmt (gsi_update);
+
/* Virtual phi; Mark it for renaming. We actually want to call
mar_sym_for_renaming, but since all ssa renaming datastructures
are going to be freed before we get to call ssa_update, we just
@@ -578,8 +591,6 @@ slpeel_update_phi_nodes_for_guard1 (edge guard_edge, struct loop *loop,
set_current_def (current_new_name, PHI_RESULT (new_phi));
bitmap_set_bit (*defs, SSA_NAME_VERSION (current_new_name));
}
-
- set_phi_nodes (new_merge_bb, phi_reverse (phi_nodes (new_merge_bb)));
}
@@ -613,8 +624,8 @@ static void
slpeel_update_phi_nodes_for_guard2 (edge guard_edge, struct loop *loop,
bool is_new_loop, basic_block *new_exit_bb)
{
- tree orig_phi, new_phi;
- tree update_phi, update_phi2;
+ gimple orig_phi, new_phi;
+ gimple update_phi, update_phi2;
tree guard_arg, loop_arg;
basic_block new_merge_bb = guard_edge->dest;
edge e = EDGE_SUCC (new_merge_bb, 0);
@@ -623,15 +634,16 @@ slpeel_update_phi_nodes_for_guard2 (edge guard_edge, struct loop *loop,
tree orig_def, orig_def_new_name;
tree new_name, new_name2;
tree arg;
+ gimple_stmt_iterator gsi;
/* Create new bb between loop and new_merge_bb. */
*new_exit_bb = split_edge (single_exit (loop));
new_exit_e = EDGE_SUCC (*new_exit_bb, 0);
- for (update_phi = phi_nodes (update_bb); update_phi;
- update_phi = PHI_CHAIN (update_phi))
+ for (gsi = gsi_start_phis (update_bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
+ update_phi = gsi_stmt (gsi);
orig_phi = update_phi;
orig_def = PHI_ARG_DEF_FROM_EDGE (orig_phi, e);
/* This loop-closed-phi actually doesn't represent a use
@@ -732,8 +744,6 @@ slpeel_update_phi_nodes_for_guard2 (edge guard_edge, struct loop *loop,
== guard_arg);
SET_PHI_ARG_DEF (update_phi2, guard_edge->dest_idx, PHI_RESULT (new_phi));
}
-
- set_phi_nodes (new_merge_bb, phi_reverse (phi_nodes (new_merge_bb)));
}
@@ -745,35 +755,40 @@ slpeel_update_phi_nodes_for_guard2 (edge guard_edge, struct loop *loop,
void
slpeel_make_loop_iterate_ntimes (struct loop *loop, tree niters)
{
- tree indx_before_incr, indx_after_incr, cond_stmt, cond;
- tree orig_cond;
+ tree indx_before_incr, indx_after_incr;
+ gimple cond_stmt;
+ gimple orig_cond;
edge exit_edge = single_exit (loop);
- block_stmt_iterator loop_cond_bsi;
- block_stmt_iterator incr_bsi;
+ gimple_stmt_iterator loop_cond_gsi;
+ gimple_stmt_iterator incr_gsi;
bool insert_after;
tree init = build_int_cst (TREE_TYPE (niters), 0);
tree step = build_int_cst (TREE_TYPE (niters), 1);
LOC loop_loc;
+ enum tree_code code;
orig_cond = get_loop_exit_condition (loop);
gcc_assert (orig_cond);
- loop_cond_bsi = bsi_for_stmt (orig_cond);
+ loop_cond_gsi = gsi_for_stmt (orig_cond);
- standard_iv_increment_position (loop, &incr_bsi, &insert_after);
+ standard_iv_increment_position (loop, &incr_gsi, &insert_after);
create_iv (init, step, NULL_TREE, loop,
- &incr_bsi, insert_after, &indx_before_incr, &indx_after_incr);
+ &incr_gsi, insert_after, &indx_before_incr, &indx_after_incr);
+
+ indx_after_incr = force_gimple_operand_gsi (&loop_cond_gsi, indx_after_incr,
+ true, NULL_TREE, true,
+ GSI_SAME_STMT);
+ niters = force_gimple_operand_gsi (&loop_cond_gsi, niters, true, NULL_TREE,
+ true, GSI_SAME_STMT);
- if (exit_edge->flags & EDGE_TRUE_VALUE) /* 'then' edge exits the loop. */
- cond = build2 (GE_EXPR, boolean_type_node, indx_after_incr, niters);
- else /* 'then' edge loops back. */
- cond = build2 (LT_EXPR, boolean_type_node, indx_after_incr, niters);
+ code = (exit_edge->flags & EDGE_TRUE_VALUE) ? GE_EXPR : LT_EXPR;
+ cond_stmt = gimple_build_cond (code, indx_after_incr, niters, NULL_TREE,
+ NULL_TREE);
- cond_stmt = build3 (COND_EXPR, TREE_TYPE (orig_cond), cond,
- NULL_TREE, NULL_TREE);
- bsi_insert_before (&loop_cond_bsi, cond_stmt, BSI_SAME_STMT);
+ gsi_insert_before (&loop_cond_gsi, cond_stmt, GSI_SAME_STMT);
/* Remove old loop exit test: */
- bsi_remove (&loop_cond_bsi, true);
+ gsi_remove (&loop_cond_gsi, true);
loop_loc = find_loop_location (loop);
if (dump_file && (dump_flags & TDF_DETAILS))
@@ -781,7 +796,7 @@ slpeel_make_loop_iterate_ntimes (struct loop *loop, tree niters)
if (loop_loc != UNKNOWN_LOC)
fprintf (dump_file, "\nloop at %s:%d: ",
LOC_FILE (loop_loc), LOC_LINE (loop_loc));
- print_generic_expr (dump_file, cond_stmt, TDF_SLIM);
+ print_gimple_stmt (dump_file, cond_stmt, 0, TDF_SLIM);
}
loop->nb_iterations = niters;
@@ -799,8 +814,10 @@ slpeel_tree_duplicate_loop_to_edge_cfg (struct loop *loop, edge e)
bool at_exit;
bool was_imm_dom;
basic_block exit_dest;
- tree phi, phi_arg;
+ gimple phi;
+ tree phi_arg;
edge exit, new_exit;
+ gimple_stmt_iterator gsi;
at_exit = (e == single_exit (loop));
if (!at_exit && e != loop_preheader_edge (loop))
@@ -837,8 +854,9 @@ slpeel_tree_duplicate_loop_to_edge_cfg (struct loop *loop, edge e)
/* Duplicating phi args at exit bbs as coming
also from exit of duplicated loop. */
- for (phi = phi_nodes (exit_dest); phi; phi = PHI_CHAIN (phi))
+ for (gsi = gsi_start_phis (exit_dest); !gsi_end_p (gsi); gsi_next (&gsi))
{
+ phi = gsi_stmt (gsi);
phi_arg = PHI_ARG_DEF_FROM_EDGE (phi, single_exit (loop));
if (phi_arg)
{
@@ -880,8 +898,11 @@ slpeel_tree_duplicate_loop_to_edge_cfg (struct loop *loop, edge e)
/* We have to add phi args to the loop->header here as coming
from new_exit_e edge. */
- for (phi = phi_nodes (loop->header); phi; phi = PHI_CHAIN (phi))
+ for (gsi = gsi_start_phis (loop->header);
+ !gsi_end_p (gsi);
+ gsi_next (&gsi))
{
+ phi = gsi_stmt (gsi);
phi_arg = PHI_ARG_DEF_FROM_EDGE (phi, entry_e);
if (phi_arg)
add_phi_arg (phi, phi_arg, new_exit_e);
@@ -908,26 +929,26 @@ static edge
slpeel_add_loop_guard (basic_block guard_bb, tree cond, basic_block exit_bb,
basic_block dom_bb)
{
- block_stmt_iterator bsi;
+ gimple_stmt_iterator gsi;
edge new_e, enter_e;
- tree cond_stmt;
- tree gimplify_stmt_list;
+ gimple cond_stmt;
+ gimple_seq gimplify_stmt_list = NULL;
enter_e = EDGE_SUCC (guard_bb, 0);
enter_e->flags &= ~EDGE_FALLTHRU;
enter_e->flags |= EDGE_FALSE_VALUE;
- bsi = bsi_last (guard_bb);
+ gsi = gsi_last_bb (guard_bb);
cond =
force_gimple_operand (cond, &gimplify_stmt_list, true,
NULL_TREE);
- cond_stmt = build3 (COND_EXPR, void_type_node, cond,
- NULL_TREE, NULL_TREE);
+ cond_stmt = gimple_build_cond (NE_EXPR, cond, integer_zero_node,
+ NULL_TREE, NULL_TREE);
if (gimplify_stmt_list)
- bsi_insert_after (&bsi, gimplify_stmt_list, BSI_NEW_STMT);
+ gsi_insert_seq_after (&gsi, gimplify_stmt_list, GSI_NEW_STMT);
- bsi = bsi_last (guard_bb);
- bsi_insert_after (&bsi, cond_stmt, BSI_NEW_STMT);
+ gsi = gsi_last_bb (guard_bb);
+ gsi_insert_after (&gsi, cond_stmt, GSI_NEW_STMT);
/* Add new edge to connect guard block to the merge/loop-exit block. */
new_e = make_edge (guard_bb, exit_bb, EDGE_TRUE_VALUE);
@@ -949,8 +970,8 @@ slpeel_can_duplicate_loop_p (const struct loop *loop, const_edge e)
{
edge exit_e = single_exit (loop);
edge entry_e = loop_preheader_edge (loop);
- tree orig_cond = get_loop_exit_condition (loop);
- block_stmt_iterator loop_exit_bsi = bsi_last (exit_e->src);
+ gimple orig_cond = get_loop_exit_condition (loop);
+ gimple_stmt_iterator loop_exit_gsi = gsi_last_bb (exit_e->src);
if (need_ssa_update_p ())
return false;
@@ -963,7 +984,7 @@ slpeel_can_duplicate_loop_p (const struct loop *loop, const_edge e)
|| !empty_block_p (loop->latch)
|| !single_exit (loop)
/* Verify that new loop exit condition can be trivially modified. */
- || (!orig_cond || orig_cond != bsi_stmt (loop_exit_bsi))
+ || (!orig_cond || orig_cond != gsi_stmt (loop_exit_gsi))
|| (e != exit_e && e != entry_e))
return false;
@@ -1017,12 +1038,12 @@ set_prologue_iterations (basic_block bb_before_first_loop,
{
edge e;
basic_block cond_bb, then_bb;
- tree var, prologue_after_cost_adjust_name, stmt;
- block_stmt_iterator bsi;
- tree newphi;
+ tree var, prologue_after_cost_adjust_name;
+ gimple_stmt_iterator gsi;
+ gimple newphi;
edge e_true, e_false, e_fallthru;
- tree cond_stmt;
- tree gimplify_stmt_list;
+ gimple cond_stmt;
+ gimple_seq gimplify_stmt_list = NULL, stmts = NULL;
tree cost_pre_condition = NULL_TREE;
tree scalar_loop_iters =
unshare_expr (LOOP_VINFO_NITERS_UNCHANGED (loop_vec_info_for_loop (loop)));
@@ -1050,25 +1071,25 @@ set_prologue_iterations (basic_block bb_before_first_loop,
cost_pre_condition =
force_gimple_operand (cost_pre_condition, &gimplify_stmt_list,
true, NULL_TREE);
- cond_stmt = build3 (COND_EXPR, void_type_node, cost_pre_condition,
- NULL_TREE, NULL_TREE);
+ cond_stmt = gimple_build_cond (NE_EXPR, cost_pre_condition,
+ integer_zero_node, NULL_TREE, NULL_TREE);
- bsi = bsi_last (cond_bb);
+ gsi = gsi_last_bb (cond_bb);
if (gimplify_stmt_list)
- bsi_insert_after (&bsi, gimplify_stmt_list, BSI_NEW_STMT);
+ gsi_insert_seq_after (&gsi, gimplify_stmt_list, GSI_NEW_STMT);
- bsi = bsi_last (cond_bb);
- bsi_insert_after (&bsi, cond_stmt, BSI_NEW_STMT);
+ gsi = gsi_last_bb (cond_bb);
+ gsi_insert_after (&gsi, cond_stmt, GSI_NEW_STMT);
var = create_tmp_var (TREE_TYPE (scalar_loop_iters),
"prologue_after_cost_adjust");
add_referenced_var (var);
prologue_after_cost_adjust_name =
- force_gimple_operand (scalar_loop_iters, &stmt, false, var);
+ force_gimple_operand (scalar_loop_iters, &stmts, false, var);
- bsi = bsi_last (then_bb);
- if (stmt)
- bsi_insert_after (&bsi, stmt, BSI_NEW_STMT);
+ gsi = gsi_last_bb (then_bb);
+ if (stmts)
+ gsi_insert_seq_after (&gsi, stmts, GSI_NEW_STMT);
newphi = create_phi_node (var, bb_before_first_loop);
add_phi_arg (newphi, prologue_after_cost_adjust_name, e_fallthru);
@@ -1150,7 +1171,7 @@ slpeel_tree_peel_loop_to_edge (struct loop *loop,
cfg_hooks->split_edge, the function tree_split_edge
is actually called and, when calling cfg_hooks->duplicate_block,
the function tree_duplicate_bb is called. */
- tree_register_cfg_hooks ();
+ gimple_register_cfg_hooks ();
/* 1. Generate a copy of LOOP and put it on E (E is the entry/exit of LOOP).
@@ -1381,18 +1402,17 @@ slpeel_tree_peel_loop_to_edge (struct loop *loop,
LOC
find_loop_location (struct loop *loop)
{
- tree node = NULL_TREE;
+ gimple stmt = NULL;
basic_block bb;
- block_stmt_iterator si;
+ gimple_stmt_iterator si;
if (!loop)
return UNKNOWN_LOC;
- node = get_loop_exit_condition (loop);
+ stmt = get_loop_exit_condition (loop);
- if (node && CAN_HAVE_LOCATION_P (node) && EXPR_HAS_LOCATION (node)
- && EXPR_FILENAME (node) && EXPR_LINENO (node))
- return EXPR_LOC (node);
+ if (stmt && gimple_location (stmt) != UNKNOWN_LOC)
+ return gimple_location (stmt);
/* If we got here the loop is probably not "well formed",
try to estimate the loop location */
@@ -1402,11 +1422,11 @@ find_loop_location (struct loop *loop)
bb = loop->header;
- for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
+ for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
{
- node = bsi_stmt (si);
- if (node && CAN_HAVE_LOCATION_P (node) && EXPR_HAS_LOCATION (node))
- return EXPR_LOC (node);
+ stmt = gsi_stmt (si);
+ if (gimple_location (stmt) != UNKNOWN_LOC)
+ return gimple_location (stmt);
}
return UNKNOWN_LOC;
@@ -1504,7 +1524,7 @@ vect_print_dump_info (enum verbosity_levels vl)
Create and initialize a new stmt_vec_info struct for STMT. */
stmt_vec_info
-new_stmt_vec_info (tree stmt, loop_vec_info loop_vinfo)
+new_stmt_vec_info (gimple stmt, loop_vec_info loop_vinfo)
{
stmt_vec_info res;
res = (stmt_vec_info) xcalloc (1, sizeof (struct _stmt_vec_info));
@@ -1526,7 +1546,8 @@ new_stmt_vec_info (tree stmt, loop_vec_info loop_vinfo)
STMT_VINFO_DR_STEP (res) = NULL;
STMT_VINFO_DR_ALIGNED_TO (res) = NULL;
- if (TREE_CODE (stmt) == PHI_NODE && is_loop_header_bb_p (bb_for_stmt (stmt)))
+ if (gimple_code (stmt) == GIMPLE_PHI
+ && is_loop_header_bb_p (gimple_bb (stmt)))
STMT_VINFO_DEF_TYPE (res) = vect_unknown_def_type;
else
STMT_VINFO_DEF_TYPE (res) = vect_loop_def;
@@ -1534,22 +1555,39 @@ new_stmt_vec_info (tree stmt, loop_vec_info loop_vinfo)
STMT_VINFO_INSIDE_OF_LOOP_COST (res) = 0;
STMT_VINFO_OUTSIDE_OF_LOOP_COST (res) = 0;
STMT_SLP_TYPE (res) = 0;
- DR_GROUP_FIRST_DR (res) = NULL_TREE;
- DR_GROUP_NEXT_DR (res) = NULL_TREE;
+ DR_GROUP_FIRST_DR (res) = NULL;
+ DR_GROUP_NEXT_DR (res) = NULL;
DR_GROUP_SIZE (res) = 0;
DR_GROUP_STORE_COUNT (res) = 0;
DR_GROUP_GAP (res) = 0;
- DR_GROUP_SAME_DR_STMT (res) = NULL_TREE;
+ DR_GROUP_SAME_DR_STMT (res) = NULL;
DR_GROUP_READ_WRITE_DEPENDENCE (res) = false;
return res;
}
+/* Create a hash table for stmt_vec_info. */
+
+void
+init_stmt_vec_info_vec (void)
+{
+ gcc_assert (!stmt_vec_info_vec);
+ stmt_vec_info_vec = VEC_alloc (vec_void_p, heap, 50);
+}
+
+/* Free hash table for stmt_vec_info. */
+
+void
+free_stmt_vec_info_vec (void)
+{
+ gcc_assert (stmt_vec_info_vec);
+ VEC_free (vec_void_p, heap, stmt_vec_info_vec);
+}
/* Free stmt vectorization related info. */
void
-free_stmt_vec_info (tree stmt)
+free_stmt_vec_info (gimple stmt)
{
stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
@@ -1557,8 +1595,8 @@ free_stmt_vec_info (tree stmt)
return;
VEC_free (dr_p, heap, STMT_VINFO_SAME_ALIGN_REFS (stmt_info));
+ set_vinfo_for_stmt (stmt, NULL);
free (stmt_info);
- set_stmt_info (stmt_ann (stmt), NULL);
}
@@ -1586,7 +1624,7 @@ new_loop_vec_info (struct loop *loop)
{
loop_vec_info res;
basic_block *bbs;
- block_stmt_iterator si;
+ gimple_stmt_iterator si;
unsigned int i, nbbs;
res = (loop_vec_info) xcalloc (1, sizeof (struct _loop_vec_info));
@@ -1598,7 +1636,6 @@ new_loop_vec_info (struct loop *loop)
for (i = 0; i < loop->num_nodes; i++)
{
basic_block bb = bbs[i];
- tree phi;
/* BBs in a nested inner-loop will have been already processed (because
we will have called vect_analyze_loop_form for any nested inner-loop).
@@ -1611,18 +1648,21 @@ new_loop_vec_info (struct loop *loop)
{
/* Inner-loop bb. */
gcc_assert (loop->inner && bb->loop_father == loop->inner);
- for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
+ for (si = gsi_start_phis (bb); !gsi_end_p (si); gsi_next (&si))
{
+ gimple phi = gsi_stmt (si);
stmt_vec_info stmt_info = vinfo_for_stmt (phi);
- loop_vec_info inner_loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
+ loop_vec_info inner_loop_vinfo =
+ STMT_VINFO_LOOP_VINFO (stmt_info);
gcc_assert (loop->inner == LOOP_VINFO_LOOP (inner_loop_vinfo));
STMT_VINFO_LOOP_VINFO (stmt_info) = res;
}
- for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
+ for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
{
- tree stmt = bsi_stmt (si);
+ gimple stmt = gsi_stmt (si);
stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
- loop_vec_info inner_loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
+ loop_vec_info inner_loop_vinfo =
+ STMT_VINFO_LOOP_VINFO (stmt_info);
gcc_assert (loop->inner == LOOP_VINFO_LOOP (inner_loop_vinfo));
STMT_VINFO_LOOP_VINFO (stmt_info) = res;
}
@@ -1630,17 +1670,18 @@ new_loop_vec_info (struct loop *loop)
else
{
/* bb in current nest. */
- for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
+ for (si = gsi_start_phis (bb); !gsi_end_p (si); gsi_next (&si))
{
- stmt_ann_t ann = get_stmt_ann (phi);
- set_stmt_info (ann, new_stmt_vec_info (phi, res));
+ gimple phi = gsi_stmt (si);
+ gimple_set_uid (phi, 0);
+ set_vinfo_for_stmt (phi, new_stmt_vec_info (phi, res));
}
- for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
+ for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
{
- tree stmt = bsi_stmt (si);
- stmt_ann_t ann = stmt_ann (stmt);
- set_stmt_info (ann, new_stmt_vec_info (stmt, res));
+ gimple stmt = gsi_stmt (si);
+ gimple_set_uid (stmt, 0);
+ set_vinfo_for_stmt (stmt, new_stmt_vec_info (stmt, res));
}
}
}
@@ -1667,10 +1708,12 @@ new_loop_vec_info (struct loop *loop)
LOOP_VINFO_DDRS (res) = VEC_alloc (ddr_p, heap, 10 * 10);
LOOP_VINFO_UNALIGNED_DR (res) = NULL;
LOOP_VINFO_MAY_MISALIGN_STMTS (res) =
- VEC_alloc (tree, heap, PARAM_VALUE (PARAM_VECT_MAX_VERSION_FOR_ALIGNMENT_CHECKS));
+ VEC_alloc (gimple, heap,
+ PARAM_VALUE (PARAM_VECT_MAX_VERSION_FOR_ALIGNMENT_CHECKS));
LOOP_VINFO_MAY_ALIAS_DDRS (res) =
- VEC_alloc (ddr_p, heap, PARAM_VALUE (PARAM_VECT_MAX_VERSION_FOR_ALIAS_CHECKS));
- LOOP_VINFO_STRIDED_STORES (res) = VEC_alloc (tree, heap, 10);
+ VEC_alloc (ddr_p, heap,
+ PARAM_VALUE (PARAM_VECT_MAX_VERSION_FOR_ALIAS_CHECKS));
+ LOOP_VINFO_STRIDED_STORES (res) = VEC_alloc (gimple, heap, 10);
LOOP_VINFO_SLP_INSTANCES (res) = VEC_alloc (slp_instance, heap, 10);
LOOP_VINFO_SLP_UNROLLING_FACTOR (res) = 1;
@@ -1689,7 +1732,7 @@ destroy_loop_vec_info (loop_vec_info loop_vinfo, bool clean_stmts)
struct loop *loop;
basic_block *bbs;
int nbbs;
- block_stmt_iterator si;
+ gimple_stmt_iterator si;
int j;
VEC (slp_instance, heap) *slp_instances;
slp_instance instance;
@@ -1707,7 +1750,7 @@ destroy_loop_vec_info (loop_vec_info loop_vinfo, bool clean_stmts)
free (LOOP_VINFO_BBS (loop_vinfo));
free_data_refs (LOOP_VINFO_DATAREFS (loop_vinfo));
free_dependence_relations (LOOP_VINFO_DDRS (loop_vinfo));
- VEC_free (tree, heap, LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo));
+ VEC_free (gimple, heap, LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo));
free (loop_vinfo);
loop->aux = NULL;
@@ -1717,14 +1760,13 @@ destroy_loop_vec_info (loop_vec_info loop_vinfo, bool clean_stmts)
for (j = 0; j < nbbs; j++)
{
basic_block bb = bbs[j];
- tree phi;
- for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
- free_stmt_vec_info (phi);
+ for (si = gsi_start_phis (bb); !gsi_end_p (si); gsi_next (&si))
+ free_stmt_vec_info (gsi_stmt (si));
- for (si = bsi_start (bb); !bsi_end_p (si); )
+ for (si = gsi_start_bb (bb); !gsi_end_p (si); )
{
- tree stmt = bsi_stmt (si);
+ gimple stmt = gsi_stmt (si);
stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
if (stmt_info)
@@ -1732,7 +1774,7 @@ destroy_loop_vec_info (loop_vec_info loop_vinfo, bool clean_stmts)
/* Check if this is a "pattern stmt" (introduced by the
vectorizer during the pattern recognition pass). */
bool remove_stmt_p = false;
- tree orig_stmt = STMT_VINFO_RELATED_STMT (stmt_info);
+ gimple orig_stmt = STMT_VINFO_RELATED_STMT (stmt_info);
if (orig_stmt)
{
stmt_vec_info orig_stmt_info = vinfo_for_stmt (orig_stmt);
@@ -1746,22 +1788,22 @@ destroy_loop_vec_info (loop_vec_info loop_vinfo, bool clean_stmts)
/* Remove dead "pattern stmts". */
if (remove_stmt_p)
- bsi_remove (&si, true);
+ gsi_remove (&si, true);
}
- bsi_next (&si);
+ gsi_next (&si);
}
}
free (LOOP_VINFO_BBS (loop_vinfo));
free_data_refs (LOOP_VINFO_DATAREFS (loop_vinfo));
free_dependence_relations (LOOP_VINFO_DDRS (loop_vinfo));
- VEC_free (tree, heap, LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo));
+ VEC_free (gimple, heap, LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo));
VEC_free (ddr_p, heap, LOOP_VINFO_MAY_ALIAS_DDRS (loop_vinfo));
slp_instances = LOOP_VINFO_SLP_INSTANCES (loop_vinfo);
for (j = 0; VEC_iterate (slp_instance, slp_instances, j, instance); j++)
vect_free_slp_tree (SLP_INSTANCE_TREE (instance));
VEC_free (slp_instance, heap, LOOP_VINFO_SLP_INSTANCES (loop_vinfo));
- VEC_free (tree, heap, LOOP_VINFO_STRIDED_STORES (loop_vinfo));
+ VEC_free (gimple, heap, LOOP_VINFO_STRIDED_STORES (loop_vinfo));
free (loop_vinfo);
loop->aux = NULL;
@@ -1850,7 +1892,7 @@ get_vectype_for_scalar_type (tree scalar_type)
enum dr_alignment_support
vect_supportable_dr_alignment (struct data_reference *dr)
{
- tree stmt = DR_STMT (dr);
+ gimple stmt = DR_STMT (dr);
stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
tree vectype = STMT_VINFO_VECTYPE (stmt_info);
enum machine_mode mode = (int) TYPE_MODE (vectype);
@@ -1972,14 +2014,14 @@ vect_supportable_dr_alignment (struct data_reference *dr)
in reduction/induction computations). */
bool
-vect_is_simple_use (tree operand, loop_vec_info loop_vinfo, tree *def_stmt,
+vect_is_simple_use (tree operand, loop_vec_info loop_vinfo, gimple *def_stmt,
tree *def, enum vect_def_type *dt)
{
basic_block bb;
stmt_vec_info stmt_vinfo;
struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
- *def_stmt = NULL_TREE;
+ *def_stmt = NULL;
*def = NULL_TREE;
if (vect_print_dump_info (REPORT_DETAILS))
@@ -2014,7 +2056,7 @@ vect_is_simple_use (tree operand, loop_vec_info loop_vinfo, tree *def_stmt,
}
*def_stmt = SSA_NAME_DEF_STMT (operand);
- if (*def_stmt == NULL_TREE )
+ if (*def_stmt == NULL)
{
if (vect_print_dump_info (REPORT_DETAILS))
fprintf (vect_dump, "no def_stmt.");
@@ -2024,27 +2066,19 @@ vect_is_simple_use (tree operand, loop_vec_info loop_vinfo, tree *def_stmt,
if (vect_print_dump_info (REPORT_DETAILS))
{
fprintf (vect_dump, "def_stmt: ");
- print_generic_expr (vect_dump, *def_stmt, TDF_SLIM);
+ print_gimple_stmt (vect_dump, *def_stmt, 0, TDF_SLIM);
}
/* empty stmt is expected only in case of a function argument.
- (Otherwise - we expect a phi_node or a GIMPLE_MODIFY_STMT). */
- if (IS_EMPTY_STMT (*def_stmt))
+ (Otherwise - we expect a phi_node or a GIMPLE_ASSIGN). */
+ if (gimple_nop_p (*def_stmt))
{
- tree arg = TREE_OPERAND (*def_stmt, 0);
- if (is_gimple_min_invariant (arg))
- {
- *def = operand;
- *dt = vect_invariant_def;
- return true;
- }
-
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "Unexpected empty stmt.");
- return false;
+ *def = operand;
+ *dt = vect_invariant_def;
+ return true;
}
- bb = bb_for_stmt (*def_stmt);
+ bb = gimple_bb (*def_stmt);
if (!flow_bb_inside_loop_p (loop, bb))
*dt = vect_invariant_def;
else
@@ -2063,16 +2097,21 @@ vect_is_simple_use (tree operand, loop_vec_info loop_vinfo, tree *def_stmt,
if (vect_print_dump_info (REPORT_DETAILS))
fprintf (vect_dump, "type of def: %d.",*dt);
- switch (TREE_CODE (*def_stmt))
+ switch (gimple_code (*def_stmt))
{
- case PHI_NODE:
- *def = PHI_RESULT (*def_stmt);
+ case GIMPLE_PHI:
+ *def = gimple_phi_result (*def_stmt);
break;
- case GIMPLE_MODIFY_STMT:
- *def = GIMPLE_STMT_OPERAND (*def_stmt, 0);
+ case GIMPLE_ASSIGN:
+ *def = gimple_assign_lhs (*def_stmt);
break;
+ case GIMPLE_CALL:
+ *def = gimple_call_lhs (*def_stmt);
+ if (*def != NULL)
+ break;
+ /* FALLTHRU */
default:
if (vect_print_dump_info (REPORT_DETAILS))
fprintf (vect_dump, "unsupported defining stmt: ");
@@ -2102,7 +2141,7 @@ vect_is_simple_use (tree operand, loop_vec_info loop_vinfo, tree *def_stmt,
CODE1 and CODE2 are CALL_EXPR. */
bool
-supportable_widening_operation (enum tree_code code, tree stmt, tree vectype,
+supportable_widening_operation (enum tree_code code, gimple stmt, tree vectype,
tree *decl1, tree *decl2,
enum tree_code *code1, enum tree_code *code2)
{
@@ -2113,8 +2152,7 @@ supportable_widening_operation (enum tree_code code, tree stmt, tree vectype,
enum machine_mode vec_mode;
enum insn_code icode1, icode2;
optab optab1, optab2;
- tree expr = GIMPLE_STMT_OPERAND (stmt, 1);
- tree type = TREE_TYPE (expr);
+ tree type = gimple_expr_type (stmt);
tree wide_vectype = get_vectype_for_scalar_type (type);
enum tree_code c1, c2;
@@ -2256,14 +2294,13 @@ supportable_widening_operation (enum tree_code code, tree stmt, tree vectype,
bool
supportable_narrowing_operation (enum tree_code code,
- const_tree stmt, const_tree vectype,
+ const_gimple stmt, const_tree vectype,
enum tree_code *code1)
{
enum machine_mode vec_mode;
enum insn_code icode1;
optab optab1;
- tree expr = GIMPLE_STMT_OPERAND (stmt, 1);
- tree type = TREE_TYPE (expr);
+ tree type = gimple_expr_type (stmt);
tree narrow_vectype = get_vectype_for_scalar_type (type);
enum tree_code c1;
@@ -2340,6 +2377,15 @@ reduction_code_for_scalar_code (enum tree_code code,
}
}
+/* Error reporting helper for vect_is_simple_reduction below. GIMPLE statement
+ STMT is printed with a message MSG. */
+
+static void
+report_vect_op (gimple stmt, const char *msg)
+{
+ fprintf (vect_dump, "%s", msg);
+ print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
+}
/* Function vect_is_simple_reduction
@@ -2360,17 +2406,16 @@ reduction_code_for_scalar_code (enum tree_code code,
Condition 1 is tested here.
Conditions 2,3 are tested in vect_mark_stmts_to_be_vectorized. */
-tree
-vect_is_simple_reduction (loop_vec_info loop_info, tree phi)
+gimple
+vect_is_simple_reduction (loop_vec_info loop_info, gimple phi)
{
- struct loop *loop = (bb_for_stmt (phi))->loop_father;
+ struct loop *loop = (gimple_bb (phi))->loop_father;
struct loop *vect_loop = LOOP_VINFO_LOOP (loop_info);
edge latch_e = loop_latch_edge (loop);
tree loop_arg = PHI_ARG_DEF_FROM_EDGE (phi, latch_e);
- tree def_stmt, def1, def2;
+ gimple def_stmt, def1, def2;
enum tree_code code;
- int op_type;
- tree operation, op1, op2;
+ tree op1, op2;
tree type;
int nloop_uses;
tree name;
@@ -2383,8 +2428,8 @@ vect_is_simple_reduction (loop_vec_info loop_info, tree phi)
nloop_uses = 0;
FOR_EACH_IMM_USE_FAST (use_p, imm_iter, name)
{
- tree use_stmt = USE_STMT (use_p);
- if (flow_bb_inside_loop_p (loop, bb_for_stmt (use_stmt))
+ gimple use_stmt = USE_STMT (use_p);
+ if (flow_bb_inside_loop_p (loop, gimple_bb (use_stmt))
&& vinfo_for_stmt (use_stmt)
&& !is_pattern_stmt_p (vinfo_for_stmt (use_stmt)))
nloop_uses++;
@@ -2392,7 +2437,7 @@ vect_is_simple_reduction (loop_vec_info loop_info, tree phi)
{
if (vect_print_dump_info (REPORT_DETAILS))
fprintf (vect_dump, "reduction used in loop.");
- return NULL_TREE;
+ return NULL;
}
}
@@ -2403,7 +2448,7 @@ vect_is_simple_reduction (loop_vec_info loop_info, tree phi)
fprintf (vect_dump, "reduction: not ssa_name: ");
print_generic_expr (vect_dump, loop_arg, TDF_SLIM);
}
- return NULL_TREE;
+ return NULL;
}
def_stmt = SSA_NAME_DEF_STMT (loop_arg);
@@ -2411,22 +2456,22 @@ vect_is_simple_reduction (loop_vec_info loop_info, tree phi)
{
if (vect_print_dump_info (REPORT_DETAILS))
fprintf (vect_dump, "reduction: no def_stmt.");
- return NULL_TREE;
+ return NULL;
}
- if (TREE_CODE (def_stmt) != GIMPLE_MODIFY_STMT)
+ if (!is_gimple_assign (def_stmt))
{
if (vect_print_dump_info (REPORT_DETAILS))
- print_generic_expr (vect_dump, def_stmt, TDF_SLIM);
- return NULL_TREE;
+ print_gimple_stmt (vect_dump, def_stmt, 0, TDF_SLIM);
+ return NULL;
}
- name = GIMPLE_STMT_OPERAND (def_stmt, 0);
+ name = gimple_assign_lhs (def_stmt);
nloop_uses = 0;
FOR_EACH_IMM_USE_FAST (use_p, imm_iter, name)
{
- tree use_stmt = USE_STMT (use_p);
- if (flow_bb_inside_loop_p (loop, bb_for_stmt (use_stmt))
+ gimple use_stmt = USE_STMT (use_p);
+ if (flow_bb_inside_loop_p (loop, gimple_bb (use_stmt))
&& vinfo_for_stmt (use_stmt)
&& !is_pattern_stmt_p (vinfo_for_stmt (use_stmt)))
nloop_uses++;
@@ -2434,47 +2479,37 @@ vect_is_simple_reduction (loop_vec_info loop_info, tree phi)
{
if (vect_print_dump_info (REPORT_DETAILS))
fprintf (vect_dump, "reduction used in loop.");
- return NULL_TREE;
+ return NULL;
}
}
- operation = GIMPLE_STMT_OPERAND (def_stmt, 1);
- code = TREE_CODE (operation);
+ code = gimple_assign_rhs_code (def_stmt);
+
if (!commutative_tree_code (code) || !associative_tree_code (code))
{
if (vect_print_dump_info (REPORT_DETAILS))
- {
- fprintf (vect_dump, "reduction: not commutative/associative: ");
- print_generic_expr (vect_dump, operation, TDF_SLIM);
- }
- return NULL_TREE;
+ report_vect_op (def_stmt, "reduction: not commutative/associative: ");
+ return NULL;
}
- op_type = TREE_OPERAND_LENGTH (operation);
- if (op_type != binary_op)
+ if (get_gimple_rhs_class (code) != GIMPLE_BINARY_RHS)
{
if (vect_print_dump_info (REPORT_DETAILS))
- {
- fprintf (vect_dump, "reduction: not binary operation: ");
- print_generic_expr (vect_dump, operation, TDF_SLIM);
- }
- return NULL_TREE;
+ report_vect_op (def_stmt, "reduction: not binary operation: ");
+ return NULL;
}
- op1 = TREE_OPERAND (operation, 0);
- op2 = TREE_OPERAND (operation, 1);
+ op1 = gimple_assign_rhs1 (def_stmt);
+ op2 = gimple_assign_rhs2 (def_stmt);
if (TREE_CODE (op1) != SSA_NAME || TREE_CODE (op2) != SSA_NAME)
{
if (vect_print_dump_info (REPORT_DETAILS))
- {
- fprintf (vect_dump, "reduction: uses not ssa_names: ");
- print_generic_expr (vect_dump, operation, TDF_SLIM);
- }
- return NULL_TREE;
+ report_vect_op (def_stmt, "reduction: uses not ssa_names: ");
+ return NULL;
}
/* Check that it's ok to change the order of the computation. */
- type = TREE_TYPE (operation);
+ type = TREE_TYPE (gimple_assign_lhs (def_stmt));
if (TYPE_MAIN_VARIANT (type) != TYPE_MAIN_VARIANT (TREE_TYPE (op1))
|| TYPE_MAIN_VARIANT (type) != TYPE_MAIN_VARIANT (TREE_TYPE (op2)))
{
@@ -2487,7 +2522,7 @@ vect_is_simple_reduction (loop_vec_info loop_info, tree phi)
fprintf (vect_dump, ",");
print_generic_expr (vect_dump, TREE_TYPE (op2), TDF_SLIM);
}
- return NULL_TREE;
+ return NULL;
}
/* Generally, when vectorizing a reduction we change the order of the
@@ -2503,32 +2538,24 @@ vect_is_simple_reduction (loop_vec_info loop_info, tree phi)
{
/* Changing the order of operations changes the semantics. */
if (vect_print_dump_info (REPORT_DETAILS))
- {
- fprintf (vect_dump, "reduction: unsafe fp math optimization: ");
- print_generic_expr (vect_dump, operation, TDF_SLIM);
- }
- return NULL_TREE;
+ report_vect_op (def_stmt, "reduction: unsafe fp math optimization: ");
+ return NULL;
}
else if (INTEGRAL_TYPE_P (type) && TYPE_OVERFLOW_TRAPS (type)
&& !nested_in_vect_loop_p (vect_loop, def_stmt))
{
/* Changing the order of operations changes the semantics. */
if (vect_print_dump_info (REPORT_DETAILS))
- {
- fprintf (vect_dump, "reduction: unsafe int math optimization: ");
- print_generic_expr (vect_dump, operation, TDF_SLIM);
- }
- return NULL_TREE;
+ report_vect_op (def_stmt, "reduction: unsafe int math optimization: ");
+ return NULL;
}
else if (SAT_FIXED_POINT_TYPE_P (type))
{
/* Changing the order of operations changes the semantics. */
if (vect_print_dump_info (REPORT_DETAILS))
- {
- fprintf (vect_dump, "reduction: unsafe fixed-point math optimization: ");
- print_generic_expr (vect_dump, operation, TDF_SLIM);
- }
- return NULL_TREE;
+ report_vect_op (def_stmt,
+ "reduction: unsafe fixed-point math optimization: ");
+ return NULL;
}
/* reduction is safe. we're dealing with one of the following:
@@ -2537,14 +2564,11 @@ vect_is_simple_reduction (loop_vec_info loop_info, tree phi)
*/
def1 = SSA_NAME_DEF_STMT (op1);
def2 = SSA_NAME_DEF_STMT (op2);
- if (!def1 || !def2 || IS_EMPTY_STMT (def1) || IS_EMPTY_STMT (def2))
+ if (!def1 || !def2 || gimple_nop_p (def1) || gimple_nop_p (def2))
{
if (vect_print_dump_info (REPORT_DETAILS))
- {
- fprintf (vect_dump, "reduction: no defs for operands: ");
- print_generic_expr (vect_dump, operation, TDF_SLIM);
- }
- return NULL_TREE;
+ report_vect_op (def_stmt, "reduction: no defs for operands: ");
+ return NULL;
}
@@ -2553,48 +2577,40 @@ vect_is_simple_reduction (loop_vec_info loop_info, tree phi)
or it's an induction (defined by a loop-header phi-node). */
if (def2 == phi
- && flow_bb_inside_loop_p (loop, bb_for_stmt (def1))
- && (TREE_CODE (def1) == GIMPLE_MODIFY_STMT
+ && flow_bb_inside_loop_p (loop, gimple_bb (def1))
+ && (is_gimple_assign (def1)
|| STMT_VINFO_DEF_TYPE (vinfo_for_stmt (def1)) == vect_induction_def
- || (TREE_CODE (def1) == PHI_NODE
+ || (gimple_code (def1) == GIMPLE_PHI
&& STMT_VINFO_DEF_TYPE (vinfo_for_stmt (def1)) == vect_loop_def
- && !is_loop_header_bb_p (bb_for_stmt (def1)))))
+ && !is_loop_header_bb_p (gimple_bb (def1)))))
{
if (vect_print_dump_info (REPORT_DETAILS))
- {
- fprintf (vect_dump, "detected reduction:");
- print_generic_expr (vect_dump, operation, TDF_SLIM);
- }
+ report_vect_op (def_stmt, "detected reduction:");
return def_stmt;
}
else if (def1 == phi
- && flow_bb_inside_loop_p (loop, bb_for_stmt (def2))
- && (TREE_CODE (def2) == GIMPLE_MODIFY_STMT
+ && flow_bb_inside_loop_p (loop, gimple_bb (def2))
+ && (is_gimple_assign (def2)
|| STMT_VINFO_DEF_TYPE (vinfo_for_stmt (def2)) == vect_induction_def
- || (TREE_CODE (def2) == PHI_NODE
+ || (gimple_code (def2) == GIMPLE_PHI
&& STMT_VINFO_DEF_TYPE (vinfo_for_stmt (def2)) == vect_loop_def
- && !is_loop_header_bb_p (bb_for_stmt (def2)))))
+ && !is_loop_header_bb_p (gimple_bb (def2)))))
{
/* Swap operands (just for simplicity - so that the rest of the code
can assume that the reduction variable is always the last (second)
argument). */
if (vect_print_dump_info (REPORT_DETAILS))
- {
- fprintf (vect_dump, "detected reduction: need to swap operands:");
- print_generic_expr (vect_dump, operation, TDF_SLIM);
- }
- swap_tree_operands (def_stmt, &TREE_OPERAND (operation, 0),
- &TREE_OPERAND (operation, 1));
+ report_vect_op (def_stmt ,
+ "detected reduction: need to swap operands:");
+ swap_tree_operands (def_stmt, gimple_assign_rhs1_ptr (def_stmt),
+ gimple_assign_rhs2_ptr (def_stmt));
return def_stmt;
}
else
{
if (vect_print_dump_info (REPORT_DETAILS))
- {
- fprintf (vect_dump, "reduction: unknown pattern.");
- print_generic_expr (vect_dump, operation, TDF_SLIM);
- }
- return NULL_TREE;
+ report_vect_op (def_stmt, "reduction: unknown pattern.");
+ return NULL;
}
}
@@ -2673,6 +2689,8 @@ vectorize_loops (void)
need to be renamed. */
vect_memsyms_to_rename = BITMAP_ALLOC (NULL);
+ init_stmt_vec_info_vec ();
+
/* ----------- Analyze loops. ----------- */
/* If some loop was duplicated, it gets bigger number
@@ -2717,6 +2735,8 @@ vectorize_loops (void)
loop->aux = NULL;
}
+ free_stmt_vec_info_vec ();
+
return num_vectorized_loops > 0 ? TODO_cleanup_cfg : 0;
}
diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h
index 1c082f85bef..ea80a8d3d30 100644
--- a/gcc/tree-vectorizer.h
+++ b/gcc/tree-vectorizer.h
@@ -89,9 +89,9 @@ typedef struct _slp_tree {
struct _slp_tree *left;
struct _slp_tree *right;
/* A group of scalar stmts to be vectorized together. */
- VEC (tree, heap) *stmts;
+ VEC (gimple, heap) *stmts;
/* Vectorized stmt/s. */
- VEC (tree, heap) *vec_stmts;
+ VEC (gimple, heap) *vec_stmts;
/* Number of vector stmts that are created to replace the group of scalar
stmts. It is calculated during the transformation phase as the number of
scalar elements in one scalar iteration (GROUP_SIZE) multiplied by VF
@@ -200,14 +200,14 @@ typedef struct _loop_vec_info {
/* Statements in the loop that have data references that are candidates for a
runtime (loop versioning) misalignment check. */
- VEC(tree,heap) *may_misalign_stmts;
+ VEC(gimple,heap) *may_misalign_stmts;
/* The loop location in the source. */
LOC loop_line_number;
/* All interleaving chains of stores in the loop, represented by the first
stmt in the chain. */
- VEC(tree, heap) *strided_stores;
+ VEC(gimple, heap) *strided_stores;
/* All SLP instances in the loop. This is a subset of the set of STRIDED_STORES
of the loop. */
@@ -255,10 +255,10 @@ loop_vec_info_for_loop (struct loop *loop)
}
static inline bool
-nested_in_vect_loop_p (struct loop *loop, tree stmt)
+nested_in_vect_loop_p (struct loop *loop, gimple stmt)
{
return (loop->inner
- && (loop->inner == (bb_for_stmt (stmt))->loop_father));
+ && (loop->inner == (gimple_bb (stmt))->loop_father));
}
/*-----------------------------------------------------------------*/
@@ -329,7 +329,7 @@ typedef struct _stmt_vec_info {
enum stmt_vec_info_type type;
/* The stmt to which this info struct refers to. */
- tree stmt;
+ gimple stmt;
/* The loop_vec_info with respect to which STMT is vectorized. */
loop_vec_info loop_vinfo;
@@ -347,7 +347,7 @@ typedef struct _stmt_vec_info {
tree vectype;
/* The vectorized version of the stmt. */
- tree vectorized_stmt;
+ gimple vectorized_stmt;
/** The following is relevant only for stmts that contain a non-scalar
@@ -378,7 +378,7 @@ typedef struct _stmt_vec_info {
related_stmt of the "pattern stmt" points back to this stmt (which is
the last stmt in the original sequence of stmts that constitutes the
pattern). */
- tree related_stmt;
+ gimple related_stmt;
/* List of datarefs that are known to have the same alignment as the dataref
of this stmt. */
@@ -389,9 +389,9 @@ typedef struct _stmt_vec_info {
/* Interleaving info. */
/* First data-ref in the interleaving group. */
- tree first_dr;
+ gimple first_dr;
/* Pointer to the next data-ref in the group. */
- tree next_dr;
+ gimple next_dr;
/* The size of the interleaving group. */
unsigned int size;
/* For stores, number of stores from this group seen. We vectorize the last
@@ -402,7 +402,7 @@ typedef struct _stmt_vec_info {
unsigned int gap;
/* In case that two or more stmts share data-ref, this is the pointer to the
previously detected stmt with the same dr. */
- tree same_dr_stmt;
+ gimple same_dr_stmt;
/* For loads only, if there is a store with the same location, this field is
TRUE. */
bool read_write_dep;
@@ -522,27 +522,46 @@ typedef struct _stmt_vec_info {
#define TARG_VEC_STORE_COST 1
#endif
-static inline void set_stmt_info (stmt_ann_t ann, stmt_vec_info stmt_info);
-static inline stmt_vec_info vinfo_for_stmt (tree stmt);
+/* Avoid GTY(()) on stmt_vec_info. */
+typedef void *vec_void_p;
+DEF_VEC_P (vec_void_p);
+DEF_VEC_ALLOC_P (vec_void_p, heap);
-static inline void
-set_stmt_info (stmt_ann_t ann, stmt_vec_info stmt_info)
+extern VEC(vec_void_p,heap) *stmt_vec_info_vec;
+
+void init_stmt_vec_info_vec (void);
+void free_stmt_vec_info_vec (void);
+
+static inline stmt_vec_info
+vinfo_for_stmt (gimple stmt)
{
- if (ann)
- ann->common.aux = (char *) stmt_info;
+ unsigned int uid = gimple_uid (stmt);
+ if (uid == 0)
+ return NULL;
+
+ gcc_assert (uid <= VEC_length (vec_void_p, stmt_vec_info_vec));
+ return (stmt_vec_info) VEC_index (vec_void_p, stmt_vec_info_vec, uid - 1);
}
-static inline stmt_vec_info
-vinfo_for_stmt (tree stmt)
+static inline void
+set_vinfo_for_stmt (gimple stmt, stmt_vec_info info)
{
- stmt_ann_t ann = stmt_ann (stmt);
- return ann ? (stmt_vec_info) ann->common.aux : NULL;
+ unsigned int uid = gimple_uid (stmt);
+ if (uid == 0)
+ {
+ gcc_assert (info);
+ uid = VEC_length (vec_void_p, stmt_vec_info_vec) + 1;
+ gimple_set_uid (stmt, uid);
+ VEC_safe_push (vec_void_p, heap, stmt_vec_info_vec, (vec_void_p) info);
+ }
+ else
+ VEC_replace (vec_void_p, stmt_vec_info_vec, uid - 1, (vec_void_p) info);
}
static inline bool
is_pattern_stmt_p (stmt_vec_info stmt_info)
{
- tree related_stmt;
+ gimple related_stmt;
stmt_vec_info related_stmt_info;
related_stmt = STMT_VINFO_RELATED_STMT (stmt_info);
@@ -643,24 +662,24 @@ extern void slpeel_verify_cfg_after_peeling (struct loop *, struct loop *);
*************************************************************************/
/** In tree-vectorizer.c **/
extern tree get_vectype_for_scalar_type (tree);
-extern bool vect_is_simple_use (tree, loop_vec_info, tree *, tree *,
+extern bool vect_is_simple_use (tree, loop_vec_info, gimple *, tree *,
enum vect_def_type *);
extern bool vect_is_simple_iv_evolution (unsigned, tree, tree *, tree *);
-extern tree vect_is_simple_reduction (loop_vec_info, tree);
+extern gimple vect_is_simple_reduction (loop_vec_info, gimple);
extern bool vect_can_force_dr_alignment_p (const_tree, unsigned int);
extern enum dr_alignment_support vect_supportable_dr_alignment
(struct data_reference *);
extern bool reduction_code_for_scalar_code (enum tree_code, enum tree_code *);
-extern bool supportable_widening_operation (enum tree_code, tree, tree,
+extern bool supportable_widening_operation (enum tree_code, gimple, tree,
tree *, tree *, enum tree_code *, enum tree_code *);
-extern bool supportable_narrowing_operation (enum tree_code, const_tree,
+extern bool supportable_narrowing_operation (enum tree_code, const_gimple,
const_tree, enum tree_code *);
/* Creation and deletion of loop and stmt info structs. */
extern loop_vec_info new_loop_vec_info (struct loop *loop);
extern void destroy_loop_vec_info (loop_vec_info, bool);
-extern stmt_vec_info new_stmt_vec_info (tree stmt, loop_vec_info);
-extern void free_stmt_vec_info (tree stmt);
+extern stmt_vec_info new_stmt_vec_info (gimple stmt, loop_vec_info);
+extern void free_stmt_vec_info (gimple stmt);
/** In tree-vect-analyze.c **/
@@ -673,28 +692,33 @@ extern loop_vec_info vect_analyze_loop_form (struct loop *);
/* Pattern recognition functions.
Additional pattern recognition functions can (and will) be added
in the future. */
-typedef tree (* vect_recog_func_ptr) (tree, tree *, tree *);
+typedef gimple (* vect_recog_func_ptr) (gimple, tree *, tree *);
#define NUM_PATTERNS 4
void vect_pattern_recog (loop_vec_info);
/** In tree-vect-transform.c **/
-extern bool vectorizable_load (tree, block_stmt_iterator *, tree *, slp_tree);
-extern bool vectorizable_store (tree, block_stmt_iterator *, tree *, slp_tree);
-extern bool vectorizable_operation (tree, block_stmt_iterator *, tree *,
+extern bool vectorizable_load (gimple, gimple_stmt_iterator *, gimple *,
+ slp_tree);
+extern bool vectorizable_store (gimple, gimple_stmt_iterator *, gimple *,
+ slp_tree);
+extern bool vectorizable_operation (gimple, gimple_stmt_iterator *, gimple *,
slp_tree);
-extern bool vectorizable_type_promotion (tree, block_stmt_iterator *, tree *);
-extern bool vectorizable_type_demotion (tree, block_stmt_iterator *, tree *);
-extern bool vectorizable_conversion (tree, block_stmt_iterator *,
- tree *, slp_tree);
-extern bool vectorizable_assignment (tree, block_stmt_iterator *, tree *,
+extern bool vectorizable_type_promotion (gimple, gimple_stmt_iterator *,
+ gimple *);
+extern bool vectorizable_type_demotion (gimple, gimple_stmt_iterator *,
+ gimple *);
+extern bool vectorizable_conversion (gimple, gimple_stmt_iterator *, gimple *,
+ slp_tree);
+extern bool vectorizable_assignment (gimple, gimple_stmt_iterator *, gimple *,
slp_tree);
-extern tree vectorizable_function (tree, tree, tree);
-extern bool vectorizable_call (tree, block_stmt_iterator *, tree *);
-extern bool vectorizable_condition (tree, block_stmt_iterator *, tree *);
-extern bool vectorizable_live_operation (tree, block_stmt_iterator *, tree *);
-extern bool vectorizable_reduction (tree, block_stmt_iterator *, tree *);
-extern bool vectorizable_induction (tree, block_stmt_iterator *, tree *);
+extern tree vectorizable_function (gimple, tree, tree);
+extern bool vectorizable_call (gimple, gimple_stmt_iterator *, gimple *);
+extern bool vectorizable_condition (gimple, gimple_stmt_iterator *, gimple *);
+extern bool vectorizable_live_operation (gimple, gimple_stmt_iterator *,
+ gimple *);
+extern bool vectorizable_reduction (gimple, gimple_stmt_iterator *, gimple *);
+extern bool vectorizable_induction (gimple, gimple_stmt_iterator *, gimple *);
extern int vect_estimate_min_profitable_iters (loop_vec_info);
extern void vect_model_simple_cost (stmt_vec_info, int, enum vect_def_type *,
slp_tree);
diff --git a/gcc/tree-vn.c b/gcc/tree-vn.c
deleted file mode 100644
index 7ec19cd4b39..00000000000
--- a/gcc/tree-vn.c
+++ /dev/null
@@ -1,406 +0,0 @@
-/* Value Numbering routines for tree expressions.
- Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007, 2008 Free Software
- Foundation, Inc.
- Contributed by Daniel Berlin <dan@dberlin.org>, Steven Bosscher
- <stevenb@suse.de> and Diego Novillo <dnovillo@redhat.com>
-
-This file is part of GCC.
-
-GCC is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 3, or (at your option)
-any later version.
-
-GCC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING3. If not see
-<http://www.gnu.org/licenses/>. */
-
-#include "config.h"
-#include "system.h"
-#include "coretypes.h"
-#include "tm.h"
-#include "ggc.h"
-#include "tree.h"
-#include "tree-flow.h"
-#include "hashtab.h"
-#include "langhooks.h"
-#include "tree-pass.h"
-#include "tree-dump.h"
-#include "diagnostic.h"
-#include "tree-ssa-sccvn.h"
-
-/* Most of this is PRE specific. The real grunt work is done in
- tree-ssa-sccvn.c. This is where the lookup and insertion
- functions, etc, can be found. */
-
-/* Create and return a new value handle node of type TYPE. */
-
-tree
-make_value_handle (tree type)
-{
- static unsigned int id = 0;
- tree vh;
-
- vh = build0 (VALUE_HANDLE, type);
- VALUE_HANDLE_ID (vh) = id++;
- return vh;
-}
-
-/* Compare two expressions E1 and E2 and return true if they are
- equal. */
-
-bool
-expressions_equal_p (tree e1, tree e2)
-{
- tree te1, te2;
-
- if (e1 == e2)
- return true;
-
- te1 = TREE_TYPE (e1);
- te2 = TREE_TYPE (e2);
-
- if (TREE_CODE (e1) == TREE_LIST && TREE_CODE (e2) == TREE_LIST)
- {
- tree lop1 = e1;
- tree lop2 = e2;
- for (lop1 = e1, lop2 = e2;
- lop1 || lop2;
- lop1 = TREE_CHAIN (lop1), lop2 = TREE_CHAIN (lop2))
- {
- if (!lop1 || !lop2)
- return false;
- if (!expressions_equal_p (TREE_VALUE (lop1), TREE_VALUE (lop2)))
- return false;
- }
- return true;
-
- }
- else if (TREE_CODE (e1) == TREE_CODE (e2)
- && operand_equal_p (e1, e2, OEP_PURE_SAME))
- return true;
-
- return false;
-}
-
-/* Set the value handle for expression E to value V. */
-
-void
-set_value_handle (tree e, tree v)
-{
- if (TREE_CODE (e) == SSA_NAME)
- SSA_NAME_VALUE (e) = v;
- else if (EXPR_P (e) || DECL_P (e) || TREE_CODE (e) == TREE_LIST
- || GIMPLE_STMT_P (e)
- || TREE_CODE (e) == CONSTRUCTOR)
- get_tree_common_ann (e)->value_handle = v;
- else
- /* Do nothing. Constants are their own value handles. */
- gcc_assert (is_gimple_min_invariant (e));
-}
-
-/* Print out the "Created value <x> for <Y>" statement to the
- dump_file.
- This is factored because both versions of lookup use it, and it
- obscures the real work going on in those functions. */
-
-static void
-print_creation_to_file (tree v, tree expr, VEC (tree, gc) *vuses)
-{
- fprintf (dump_file, "Created value ");
- print_generic_expr (dump_file, v, dump_flags);
- fprintf (dump_file, " for ");
- print_generic_expr (dump_file, expr, dump_flags);
-
- if (vuses && VEC_length (tree, vuses) != 0)
- {
- size_t i;
- tree vuse;
-
- fprintf (dump_file, " vuses: (");
- for (i = 0; VEC_iterate (tree, vuses, i, vuse); i++)
- {
- print_generic_expr (dump_file, vuse, dump_flags);
- if (VEC_length (tree, vuses) - 1 != i)
- fprintf (dump_file, ",");
- }
- fprintf (dump_file, ")");
- }
- fprintf (dump_file, "\n");
-}
-
-/* Sort the VUSE array so that we can do equality comparisons
- quicker on two vuse vecs. */
-
-void
-sort_vuses (VEC (tree,gc) *vuses)
-{
- if (VEC_length (tree, vuses) > 1)
- qsort (VEC_address (tree, vuses),
- VEC_length (tree, vuses),
- sizeof (tree),
- operand_build_cmp);
-}
-
-/* Sort the VUSE array so that we can do equality comparisons
- quicker on two vuse vecs. */
-
-void
-sort_vuses_heap (VEC (tree,heap) *vuses)
-{
- if (VEC_length (tree, vuses) > 1)
- qsort (VEC_address (tree, vuses),
- VEC_length (tree, vuses),
- sizeof (tree),
- operand_build_cmp);
-}
-
-/* Insert EXPR into VALUE_TABLE with value VAL, and add expression
- EXPR to the value set for value VAL. */
-
-void
-vn_add (tree expr, tree val)
-{
- switch (TREE_CODE_CLASS (TREE_CODE (expr)))
- {
- case tcc_comparison:
- case tcc_binary:
- vn_nary_op_insert (expr, val);
- break;
- case tcc_unary:
- vn_nary_op_insert (expr, val);
- break;
- /* In the case of array-refs of constants, for example, we can
- end up with no vuses. */
- case tcc_reference:
- vn_reference_insert (expr, val, NULL);
- break;
- /* The *only* time CALL_EXPR should appear here is
- when it has no vuses. */
- case tcc_vl_exp:
- case tcc_exceptional:
- case tcc_expression:
- case tcc_declaration:
- if (TREE_CODE (expr) == CALL_EXPR || DECL_P (expr))
- {
- vn_reference_insert (expr, val, NULL);
- break;
- }
- else if (TREE_CODE (expr) == SSA_NAME)
- {
- SSA_NAME_VALUE (expr) = val;
- break;
- }
- switch (TREE_CODE (expr))
- {
- case ADDR_EXPR:
- case TRUTH_AND_EXPR:
- case TRUTH_OR_EXPR:
- case TRUTH_XOR_EXPR:
- case TRUTH_NOT_EXPR:
- vn_nary_op_insert (expr, val);
- break;
- default:
- gcc_unreachable ();
- }
- break;
- default:
- gcc_unreachable ();
- }
- set_value_handle (expr, val);
- if (TREE_CODE (val) == VALUE_HANDLE)
- add_to_value (val, expr);
-}
-
-/* Insert EXPR into the value numbering tables with value VAL, and
- add expression EXPR to the value set for value VAL. VUSES
- represents the virtual use operands associated with EXPR. It is
- used when computing a hash value for EXPR. */
-
-void
-vn_add_with_vuses (tree expr, tree val, VEC (tree, gc) *vuses)
-{
- if (!vuses)
- {
- vn_add (expr, val);
- return;
- }
- vn_reference_insert (expr, val, vuses);
-
- set_value_handle (expr, val);
- if (TREE_CODE (val) == VALUE_HANDLE)
- add_to_value (val, expr);
-}
-
-/* Lookup EXPR in the value numbering tables and return the result, if
- we have one. */
-
-tree
-vn_lookup (tree expr)
-{
- /* Constants are their own value. */
- if (is_gimple_min_invariant (expr) || TREE_CODE (expr) == FIELD_DECL)
- return expr;
-
- switch (TREE_CODE_CLASS (TREE_CODE (expr)))
- {
- case tcc_comparison:
- case tcc_binary:
- return vn_nary_op_lookup (expr);
- case tcc_unary:
- return vn_nary_op_lookup (expr);
- break;
- /* In the case of array-refs of constants, for example, we can
- end up with no vuses. */
- case tcc_reference:
- return vn_reference_lookup (expr, NULL, false);
- break;
- /* It is possible to have CALL_EXPR with no vuses for things
- like "cos", and these will fall into vn_lookup. */
- case tcc_vl_exp:
- case tcc_exceptional:
- case tcc_expression:
- case tcc_declaration:
- if (TREE_CODE (expr) == CALL_EXPR || DECL_P (expr))
- return vn_reference_lookup (expr, NULL, false);
- else if (TREE_CODE (expr) == SSA_NAME)
- return SSA_NAME_VALUE (expr);
- switch (TREE_CODE (expr))
- {
- case ADDR_EXPR:
- case TRUTH_AND_EXPR:
- case TRUTH_OR_EXPR:
- case TRUTH_XOR_EXPR:
- case TRUTH_NOT_EXPR:
- return vn_nary_op_lookup (expr);
- default:
- gcc_unreachable ();
- }
- break;
- default:
- gcc_unreachable ();
- }
- return NULL;
-}
-
-/* Search in the value numbering tables for an existing instance of
- expression EXPR, and return its value, or NULL if none has been set. STMT
- represents the stmt associated with EXPR. It is used when computing the
- hash value for EXPR for reference operations. */
-
-tree
-vn_lookup_with_stmt (tree expr, tree stmt)
-{
- if (stmt == NULL)
- return vn_lookup (expr);
-
- /* Constants are their own value. */
- if (is_gimple_min_invariant (expr) || TREE_CODE (expr) == FIELD_DECL)
- return expr;
-
- return vn_lookup_with_vuses (expr, shared_vuses_from_stmt (stmt));
-}
-
-/* Search in VALUE_TABLE for an existing instance of expression EXPR,
- and return its value, or NULL if none has been set. VUSES is the
- list of virtual use operands associated with EXPR. It is used when
- computing the hash value for EXPR. */
-
-tree
-vn_lookup_with_vuses (tree expr, VEC (tree, gc) *vuses)
-{
- if (!vuses || !VEC_length (tree, vuses))
- return vn_lookup (expr);
-
- if (is_gimple_min_invariant (expr) || TREE_CODE (expr) == FIELD_DECL)
- return expr;
-
- /* We may not walk the use-def chains here as the alias oracle cannot
- properly deal with VALUE_HANDLE tree nodes we feed it here. */
- return vn_reference_lookup (expr, vuses, false);
-}
-
-static tree
-create_value_handle_for_expr (tree expr, VEC(tree, gc) *vuses)
-{
- tree v;
-
- v = make_value_handle (TREE_TYPE (expr));
-
- if (dump_file && (dump_flags & TDF_DETAILS))
- print_creation_to_file (v, expr, vuses);
- return v;
-}
-
-/* Like vn_lookup, but creates a new value for the operation if one
- does not exist. */
-
-tree
-vn_lookup_or_add (tree expr)
-{
- tree v = vn_lookup (expr);
-
- if (v == NULL_TREE)
- {
- v = create_value_handle_for_expr (expr, NULL);
- vn_add (expr, v);
- }
- else
- set_value_handle (expr, v);
-
- return v;
-}
-
-/* Like vn_lookup, but handles reference operations as well by using
- STMT to get the set of vuses. */
-
-tree
-vn_lookup_or_add_with_stmt (tree expr, tree stmt)
-{
- tree v;
- if (!stmt)
- return vn_lookup_or_add (expr);
-
- v = vn_lookup_with_stmt (expr, stmt);
- if (v == NULL_TREE)
- {
- VEC (tree, gc) *vuses = copy_vuses_from_stmt (stmt);
- v = create_value_handle_for_expr (expr, vuses);
- vn_add_with_vuses (expr, v, vuses);
- }
- else
- set_value_handle (expr, v);
-
- return v;
-}
-
-/* Like vn_lookup, but creates a new value for expression EXPR, if
- EXPR doesn't already have a value. Return the existing/created
- value for EXPR. STMT represents the stmt associated with EXPR. It is used
- when computing the hash value for EXPR. */
-
-tree
-vn_lookup_or_add_with_vuses (tree expr, VEC (tree, gc) *vuses)
-{
- tree v;
-
- if (!vuses || VEC_length (tree, vuses) == 0)
- return vn_lookup_or_add (expr);
-
- v = vn_lookup_with_vuses (expr, vuses);
- if (v == NULL_TREE)
- {
- v = create_value_handle_for_expr (expr, vuses);
- vn_add_with_vuses (expr, v, vuses);
- }
- else
- set_value_handle (expr, v);
-
- return v;
-}
-
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index 404531f4504..40bec2e1d4d 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -38,6 +38,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-ssa-propagate.h"
#include "tree-chrec.h"
+
/* Set of SSA names found during the dominator traversal of a
sub-graph in find_assert_locations. */
static sbitmap found_in_subgraph;
@@ -64,7 +65,7 @@ struct assert_locus_d
edge e;
/* Pointer to the statement that generated this assertion. */
- block_stmt_iterator si;
+ gimple_stmt_iterator si;
/* Predicate code for the ASSERT_EXPR. Must be COMPARISON_CLASS_P. */
enum tree_code comp_code;
@@ -104,7 +105,7 @@ static value_range_t **vr_value;
static int *vr_phi_edge_counts;
typedef struct {
- tree stmt;
+ gimple stmt;
tree vec;
} switch_update;
@@ -276,6 +277,18 @@ is_overflow_infinity (const_tree val)
&& (vrp_val_is_min (val) || vrp_val_is_max (val)));
}
+/* Return whether STMT has a constant rhs that is_overflow_infinity. */
+
+static inline bool
+stmt_overflow_infinity (gimple stmt)
+{
+ if (is_gimple_assign (stmt)
+ && get_gimple_rhs_class (gimple_assign_rhs_code (stmt)) ==
+ GIMPLE_SINGLE_RHS)
+ return is_overflow_infinity (gimple_assign_rhs1 (stmt));
+ return false;
+}
+
/* If VAL is now an overflow infinity, return VAL. Otherwise, return
the same value with TREE_OVERFLOW clear. This can be used to avoid
confusing a regular value with an overflow value. */
@@ -777,21 +790,143 @@ vrp_expr_computes_nonnegative (tree expr, bool *strict_overflow_p)
&& ssa_name_nonnegative_p (expr)));
}
+/* Return true if the result of assignment STMT is know to be non-negative.
+ If the return value is based on the assumption that signed overflow is
+ undefined, set *STRICT_OVERFLOW_P to true; otherwise, don't change
+ *STRICT_OVERFLOW_P.*/
+
+static bool
+gimple_assign_nonnegative_warnv_p (gimple stmt, bool *strict_overflow_p)
+{
+ enum tree_code code = gimple_assign_rhs_code (stmt);
+ switch (get_gimple_rhs_class (code))
+ {
+ case GIMPLE_UNARY_RHS:
+ return tree_unary_nonnegative_warnv_p (gimple_assign_rhs_code (stmt),
+ gimple_expr_type (stmt),
+ gimple_assign_rhs1 (stmt),
+ strict_overflow_p);
+ case GIMPLE_BINARY_RHS:
+ return tree_binary_nonnegative_warnv_p (gimple_assign_rhs_code (stmt),
+ gimple_expr_type (stmt),
+ gimple_assign_rhs1 (stmt),
+ gimple_assign_rhs2 (stmt),
+ strict_overflow_p);
+ case GIMPLE_SINGLE_RHS:
+ return tree_single_nonnegative_warnv_p (gimple_assign_rhs1 (stmt),
+ strict_overflow_p);
+ case GIMPLE_INVALID_RHS:
+ gcc_unreachable ();
+ default:
+ gcc_unreachable ();
+ }
+}
+
+/* Return true if return value of call STMT is know to be non-negative.
+ If the return value is based on the assumption that signed overflow is
+ undefined, set *STRICT_OVERFLOW_P to true; otherwise, don't change
+ *STRICT_OVERFLOW_P.*/
+
+static bool
+gimple_call_nonnegative_warnv_p (gimple stmt, bool *strict_overflow_p)
+{
+ tree arg0 = gimple_call_num_args (stmt) > 0 ?
+ gimple_call_arg (stmt, 0) : NULL_TREE;
+ tree arg1 = gimple_call_num_args (stmt) > 1 ?
+ gimple_call_arg (stmt, 1) : NULL_TREE;
+
+ return tree_call_nonnegative_warnv_p (gimple_expr_type (stmt),
+ gimple_call_fndecl (stmt),
+ arg0,
+ arg1,
+ strict_overflow_p);
+}
+
+/* Return true if STMT is know to to compute a non-negative value.
+ If the return value is based on the assumption that signed overflow is
+ undefined, set *STRICT_OVERFLOW_P to true; otherwise, don't change
+ *STRICT_OVERFLOW_P.*/
+
+static bool
+gimple_stmt_nonnegative_warnv_p (gimple stmt, bool *strict_overflow_p)
+{
+ switch (gimple_code (stmt))
+ {
+ case GIMPLE_ASSIGN:
+ return gimple_assign_nonnegative_warnv_p (stmt, strict_overflow_p);
+ case GIMPLE_CALL:
+ return gimple_call_nonnegative_warnv_p (stmt, strict_overflow_p);
+ default:
+ gcc_unreachable ();
+ }
+}
+
+/* Return true if the result of assignment STMT is know to be non-zero.
+ If the return value is based on the assumption that signed overflow is
+ undefined, set *STRICT_OVERFLOW_P to true; otherwise, don't change
+ *STRICT_OVERFLOW_P.*/
+
+static bool
+gimple_assign_nonzero_warnv_p (gimple stmt, bool *strict_overflow_p)
+{
+ enum tree_code code = gimple_assign_rhs_code (stmt);
+ switch (get_gimple_rhs_class (code))
+ {
+ case GIMPLE_UNARY_RHS:
+ return tree_unary_nonzero_warnv_p (gimple_assign_rhs_code (stmt),
+ gimple_expr_type (stmt),
+ gimple_assign_rhs1 (stmt),
+ strict_overflow_p);
+ case GIMPLE_BINARY_RHS:
+ return tree_binary_nonzero_warnv_p (gimple_assign_rhs_code (stmt),
+ gimple_expr_type (stmt),
+ gimple_assign_rhs1 (stmt),
+ gimple_assign_rhs2 (stmt),
+ strict_overflow_p);
+ case GIMPLE_SINGLE_RHS:
+ return tree_single_nonzero_warnv_p (gimple_assign_rhs1 (stmt),
+ strict_overflow_p);
+ case GIMPLE_INVALID_RHS:
+ gcc_unreachable ();
+ default:
+ gcc_unreachable ();
+ }
+}
+
+/* Return true if STMT is know to to compute a non-zero value.
+ If the return value is based on the assumption that signed overflow is
+ undefined, set *STRICT_OVERFLOW_P to true; otherwise, don't change
+ *STRICT_OVERFLOW_P.*/
+
+static bool
+gimple_stmt_nonzero_warnv_p (gimple stmt, bool *strict_overflow_p)
+{
+ switch (gimple_code (stmt))
+ {
+ case GIMPLE_ASSIGN:
+ return gimple_assign_nonzero_warnv_p (stmt, strict_overflow_p);
+ case GIMPLE_CALL:
+ return gimple_alloca_call_p (stmt);
+ default:
+ gcc_unreachable ();
+ }
+}
+
/* Like tree_expr_nonzero_warnv_p, but this function uses value ranges
obtained so far. */
static bool
-vrp_expr_computes_nonzero (tree expr, bool *strict_overflow_p)
+vrp_stmt_computes_nonzero (gimple stmt, bool *strict_overflow_p)
{
- if (tree_expr_nonzero_warnv_p (expr, strict_overflow_p)
- || (TREE_CODE (expr) == SSA_NAME
- && ssa_name_nonzero_p (expr)))
+ if (gimple_stmt_nonzero_warnv_p (stmt, strict_overflow_p))
return true;
/* If we have an expression of the form &X->a, then the expression
is nonnull if X is nonnull. */
- if (TREE_CODE (expr) == ADDR_EXPR)
+ if (is_gimple_assign (stmt)
+ && gimple_assign_rhs_code (stmt) == ADDR_EXPR)
{
+ tree expr = gimple_assign_rhs1 (stmt);
tree base = get_base_address (TREE_OPERAND (expr, 0));
if (base != NULL_TREE
@@ -2709,10 +2844,9 @@ extract_range_from_comparison (value_range_t *vr, enum tree_code code,
tree type, tree op0, tree op1)
{
bool sop = false;
- tree val = vrp_evaluate_conditional_warnv_with_ops (code,
- op0,
- op1,
- false, &sop);
+ tree val;
+
+ val = vrp_evaluate_conditional_warnv_with_ops (code, op0, op1, false, &sop);
/* A disadvantage of using a special infinity as an overflow
representation is that we lose the ability to record overflow
@@ -2735,56 +2869,67 @@ extract_range_from_comparison (value_range_t *vr, enum tree_code code,
set_value_range_to_truthvalue (vr, type);
}
+/* Try to derive a nonnegative or nonzero range out of STMT relying
+ primarily on generic routines in fold in conjunction with range data.
+ Store the result in *VR */
-/* Try to compute a useful range out of expression EXPR and store it
+static void
+extract_range_basic (value_range_t *vr, gimple stmt)
+{
+ bool sop = false;
+ tree type = gimple_expr_type (stmt);
+
+ if (INTEGRAL_TYPE_P (type)
+ && gimple_stmt_nonnegative_warnv_p (stmt, &sop))
+ set_value_range_to_nonnegative (vr, type,
+ sop || stmt_overflow_infinity (stmt));
+ else if (vrp_stmt_computes_nonzero (stmt, &sop)
+ && !sop)
+ set_value_range_to_nonnull (vr, type);
+ else
+ set_value_range_to_varying (vr);
+}
+
+
+/* Try to compute a useful range out of assignment STMT and store it
in *VR. */
static void
-extract_range_from_expr (value_range_t *vr, tree expr)
+extract_range_from_assignment (value_range_t *vr, gimple stmt)
{
- enum tree_code code = TREE_CODE (expr);
+ enum tree_code code = gimple_assign_rhs_code (stmt);
if (code == ASSERT_EXPR)
- extract_range_from_assert (vr, expr);
+ extract_range_from_assert (vr, gimple_assign_rhs1 (stmt));
else if (code == SSA_NAME)
- extract_range_from_ssa_name (vr, expr);
+ extract_range_from_ssa_name (vr, gimple_assign_rhs1 (stmt));
else if (TREE_CODE_CLASS (code) == tcc_binary
|| code == TRUTH_AND_EXPR
|| code == TRUTH_OR_EXPR
|| code == TRUTH_XOR_EXPR)
- extract_range_from_binary_expr (vr, TREE_CODE (expr), TREE_TYPE (expr),
- TREE_OPERAND (expr, 0),
- TREE_OPERAND (expr, 1));
+ extract_range_from_binary_expr (vr, gimple_assign_rhs_code (stmt),
+ gimple_expr_type (stmt),
+ gimple_assign_rhs1 (stmt),
+ gimple_assign_rhs2 (stmt));
else if (TREE_CODE_CLASS (code) == tcc_unary)
- extract_range_from_unary_expr (vr, TREE_CODE (expr), TREE_TYPE (expr),
- TREE_OPERAND (expr, 0));
+ extract_range_from_unary_expr (vr, gimple_assign_rhs_code (stmt),
+ gimple_expr_type (stmt),
+ gimple_assign_rhs1 (stmt));
else if (code == COND_EXPR)
- extract_range_from_cond_expr (vr, expr);
+ extract_range_from_cond_expr (vr, gimple_assign_rhs1 (stmt));
else if (TREE_CODE_CLASS (code) == tcc_comparison)
- extract_range_from_comparison (vr, TREE_CODE (expr), TREE_TYPE (expr),
- TREE_OPERAND (expr, 0),
- TREE_OPERAND (expr, 1));
- else if (is_gimple_min_invariant (expr))
- set_value_range_to_value (vr, expr, NULL);
+ extract_range_from_comparison (vr, gimple_assign_rhs_code (stmt),
+ gimple_expr_type (stmt),
+ gimple_assign_rhs1 (stmt),
+ gimple_assign_rhs2 (stmt));
+ else if (get_gimple_rhs_class (code) == GIMPLE_SINGLE_RHS
+ && is_gimple_min_invariant (gimple_assign_rhs1 (stmt)))
+ set_value_range_to_value (vr, gimple_assign_rhs1 (stmt), NULL);
else
set_value_range_to_varying (vr);
- /* If we got a varying range from the tests above, try a final
- time to derive a nonnegative or nonzero range. This time
- relying primarily on generic routines in fold in conjunction
- with range data. */
if (vr->type == VR_VARYING)
- {
- bool sop = false;
-
- if (INTEGRAL_TYPE_P (TREE_TYPE (expr))
- && vrp_expr_computes_nonnegative (expr, &sop))
- set_value_range_to_nonnegative (vr, TREE_TYPE (expr),
- sop || is_overflow_infinity (expr));
- else if (vrp_expr_computes_nonzero (expr, &sop)
- && !sop)
- set_value_range_to_nonnull (vr, TREE_TYPE (expr));
- }
+ extract_range_basic (vr, stmt);
}
/* Given a range VR, a LOOP and a variable VAR, determine whether it
@@ -2792,8 +2937,8 @@ extract_range_from_expr (value_range_t *vr, tree expr)
for VAR. If so, update VR with the new limits. */
static void
-adjust_range_with_scev (value_range_t *vr, struct loop *loop, tree stmt,
- tree var)
+adjust_range_with_scev (value_range_t *vr, struct loop *loop,
+ gimple stmt, tree var)
{
tree init, step, chrec, tmin, tmax, min, max, type;
enum ev_direction dir;
@@ -2926,7 +3071,7 @@ adjust_range_with_scev (value_range_t *vr, struct loop *loop, tree stmt,
overflow. */
static bool
-vrp_var_may_overflow (tree var, tree stmt)
+vrp_var_may_overflow (tree var, gimple stmt)
{
struct loop *l;
tree chrec, init, step;
@@ -3374,31 +3519,32 @@ debug_all_value_ranges (void)
create a new SSA name N and return the assertion assignment
'V = ASSERT_EXPR <V, V OP W>'. */
-static tree
+static gimple
build_assert_expr_for (tree cond, tree v)
{
- tree n, assertion;
+ tree n;
+ gimple assertion;
gcc_assert (TREE_CODE (v) == SSA_NAME);
- n = duplicate_ssa_name (v, NULL_TREE);
+ n = duplicate_ssa_name (v, NULL);
if (COMPARISON_CLASS_P (cond))
{
tree a = build2 (ASSERT_EXPR, TREE_TYPE (v), v, cond);
- assertion = build_gimple_modify_stmt (n, a);
+ assertion = gimple_build_assign (n, a);
}
else if (TREE_CODE (cond) == TRUTH_NOT_EXPR)
{
/* Given !V, build the assignment N = false. */
tree op0 = TREE_OPERAND (cond, 0);
gcc_assert (op0 == v);
- assertion = build_gimple_modify_stmt (n, boolean_false_node);
+ assertion = gimple_build_assign (n, boolean_false_node);
}
else if (TREE_CODE (cond) == SSA_NAME)
{
/* Given V, build the assignment N = true. */
gcc_assert (v == cond);
- assertion = build_gimple_modify_stmt (n, boolean_true_node);
+ assertion = gimple_build_assign (n, boolean_true_node);
}
else
gcc_unreachable ();
@@ -3419,10 +3565,11 @@ build_assert_expr_for (tree cond, tree v)
point values. */
static inline bool
-fp_predicate (const_tree expr)
+fp_predicate (gimple stmt)
{
- return (COMPARISON_CLASS_P (expr)
- && FLOAT_TYPE_P (TREE_TYPE (TREE_OPERAND (expr, 0))));
+ GIMPLE_CHECK (stmt, GIMPLE_COND);
+
+ return FLOAT_TYPE_P (TREE_TYPE (gimple_cond_lhs (stmt)));
}
@@ -3432,7 +3579,7 @@ fp_predicate (const_tree expr)
inferred. */
static bool
-infer_value_range (tree stmt, tree op, enum tree_code *comp_code_p, tree *val_p)
+infer_value_range (gimple stmt, tree op, enum tree_code *comp_code_p, tree *val_p)
{
*val_p = NULL_TREE;
*comp_code_p = ERROR_MARK;
@@ -3444,19 +3591,21 @@ infer_value_range (tree stmt, tree op, enum tree_code *comp_code_p, tree *val_p)
/* Similarly, don't infer anything from statements that may throw
exceptions. */
- if (tree_could_throw_p (stmt))
+ if (stmt_could_throw_p (stmt))
return false;
/* If STMT is the last statement of a basic block with no
successors, there is no point inferring anything about any of its
operands. We would not be able to find a proper insertion point
for the assertion, anyway. */
- if (stmt_ends_bb_p (stmt) && EDGE_COUNT (bb_for_stmt (stmt)->succs) == 0)
+ if (stmt_ends_bb_p (stmt) && EDGE_COUNT (gimple_bb (stmt)->succs) == 0)
return false;
/* We can only assume that a pointer dereference will yield
non-NULL if -fdelete-null-pointer-checks is enabled. */
- if (flag_delete_null_pointer_checks && POINTER_TYPE_P (TREE_TYPE (op)))
+ if (flag_delete_null_pointer_checks
+ && POINTER_TYPE_P (TREE_TYPE (op))
+ && gimple_code (stmt) != GIMPLE_ASM)
{
unsigned num_uses, num_loads, num_stores;
@@ -3493,7 +3642,7 @@ dump_asserts_for (FILE *file, tree name)
while (loc)
{
fprintf (file, "\t");
- print_generic_expr (file, bsi_stmt (loc->si), 0);
+ print_gimple_stmt (file, gsi_stmt (loc->si), 0, 0);
fprintf (file, "\n\tBB #%d", loc->bb->index);
if (loc->e)
{
@@ -3563,7 +3712,7 @@ register_new_assert_for (tree name, tree expr,
tree val,
basic_block bb,
edge e,
- block_stmt_iterator si)
+ gimple_stmt_iterator si)
{
assert_locus_t n, loc, last_loc;
bool found;
@@ -3573,8 +3722,8 @@ register_new_assert_for (tree name, tree expr,
gcc_assert (bb == NULL || e == NULL);
if (e == NULL)
- gcc_assert (TREE_CODE (bsi_stmt (si)) != COND_EXPR
- && TREE_CODE (bsi_stmt (si)) != SWITCH_EXPR);
+ gcc_assert (gimple_code (gsi_stmt (si)) != GIMPLE_COND
+ && gimple_code (gsi_stmt (si)) != GIMPLE_SWITCH);
#endif
/* The new assertion A will be inserted at BB or E. We need to
@@ -3746,7 +3895,7 @@ extract_code_and_val_from_cond_with_ops (tree name, enum tree_code cond_code,
Return true if an assertion for NAME could be registered. */
static bool
-register_edge_assert_for_2 (tree name, edge e, block_stmt_iterator bsi,
+register_edge_assert_for_2 (tree name, edge e, gimple_stmt_iterator bsi,
enum tree_code cond_code,
tree cond_op0, tree cond_op1, bool invert)
{
@@ -3778,30 +3927,29 @@ register_edge_assert_for_2 (tree name, edge e, block_stmt_iterator bsi,
&& TREE_CODE (val) == INTEGER_CST
&& TYPE_UNSIGNED (TREE_TYPE (val)))
{
- tree def_stmt = SSA_NAME_DEF_STMT (name);
+ gimple def_stmt = SSA_NAME_DEF_STMT (name);
tree cst2 = NULL_TREE, name2 = NULL_TREE, name3 = NULL_TREE;
/* Extract CST2 from the (optional) addition. */
- if (TREE_CODE (def_stmt) == GIMPLE_MODIFY_STMT
- && TREE_CODE (GIMPLE_STMT_OPERAND (def_stmt, 1)) == PLUS_EXPR)
+ if (is_gimple_assign (def_stmt)
+ && gimple_assign_rhs_code (def_stmt) == PLUS_EXPR)
{
- name2 = TREE_OPERAND (GIMPLE_STMT_OPERAND (def_stmt, 1), 0);
- cst2 = TREE_OPERAND (GIMPLE_STMT_OPERAND (def_stmt, 1), 1);
+ name2 = gimple_assign_rhs1 (def_stmt);
+ cst2 = gimple_assign_rhs2 (def_stmt);
if (TREE_CODE (name2) == SSA_NAME
&& TREE_CODE (cst2) == INTEGER_CST)
def_stmt = SSA_NAME_DEF_STMT (name2);
}
/* Extract NAME2 from the (optional) sign-changing cast. */
- if (TREE_CODE (def_stmt) == GIMPLE_MODIFY_STMT
- && CONVERT_EXPR_P (GIMPLE_STMT_OPERAND (def_stmt, 1)))
+ if (gimple_assign_cast_p (def_stmt))
{
- tree rhs = GIMPLE_STMT_OPERAND (def_stmt, 1);
- if (CONVERT_EXPR_P (rhs)
- && ! TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (rhs, 0)))
- && (TYPE_PRECISION (TREE_TYPE (rhs))
- == TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (rhs, 0)))))
- name3 = TREE_OPERAND (GIMPLE_STMT_OPERAND (def_stmt, 1), 0);
+ if ((gimple_assign_rhs_code (def_stmt) == NOP_EXPR
+ || gimple_assign_rhs_code (def_stmt) == CONVERT_EXPR)
+ && ! TYPE_UNSIGNED (TREE_TYPE (gimple_assign_rhs1 (def_stmt)))
+ && (TYPE_PRECISION (gimple_expr_type (def_stmt))
+ == TYPE_PRECISION (TREE_TYPE (gimple_assign_rhs1 (def_stmt)))))
+ name3 = gimple_assign_rhs1 (def_stmt);
}
/* If name3 is used later, create an ASSERT_EXPR for it. */
@@ -3878,10 +4026,11 @@ register_edge_assert_for_2 (tree name, edge e, block_stmt_iterator bsi,
static bool
register_edge_assert_for_1 (tree op, enum tree_code code,
- edge e, block_stmt_iterator bsi)
+ edge e, gimple_stmt_iterator bsi)
{
bool retval = false;
- tree op_def, rhs, val;
+ gimple op_def;
+ tree val;
enum tree_code rhs_code;
/* We only care about SSA_NAMEs. */
@@ -3905,17 +4054,16 @@ register_edge_assert_for_1 (tree op, enum tree_code code,
a truth operation or some bit operations, then we may be able
to register information about the operands of that assignment. */
op_def = SSA_NAME_DEF_STMT (op);
- if (TREE_CODE (op_def) != GIMPLE_MODIFY_STMT)
+ if (gimple_code (op_def) != GIMPLE_ASSIGN)
return retval;
- rhs = GIMPLE_STMT_OPERAND (op_def, 1);
- rhs_code = TREE_CODE (rhs);
+ rhs_code = gimple_assign_rhs_code (op_def);
- if (COMPARISON_CLASS_P (rhs))
+ if (TREE_CODE_CLASS (rhs_code) == tcc_comparison)
{
bool invert = (code == EQ_EXPR ? true : false);
- tree op0 = TREE_OPERAND (rhs, 0);
- tree op1 = TREE_OPERAND (rhs, 1);
+ tree op0 = gimple_assign_rhs1 (op_def);
+ tree op1 = gimple_assign_rhs2 (op_def);
if (TREE_CODE (op0) == SSA_NAME)
retval |= register_edge_assert_for_2 (op0, e, bsi, rhs_code, op0, op1,
@@ -3925,34 +4073,36 @@ register_edge_assert_for_1 (tree op, enum tree_code code,
invert);
}
else if ((code == NE_EXPR
- && (TREE_CODE (rhs) == TRUTH_AND_EXPR
- || TREE_CODE (rhs) == BIT_AND_EXPR))
+ && (gimple_assign_rhs_code (op_def) == TRUTH_AND_EXPR
+ || gimple_assign_rhs_code (op_def) == BIT_AND_EXPR))
|| (code == EQ_EXPR
- && (TREE_CODE (rhs) == TRUTH_OR_EXPR
- || TREE_CODE (rhs) == BIT_IOR_EXPR)))
+ && (gimple_assign_rhs_code (op_def) == TRUTH_OR_EXPR
+ || gimple_assign_rhs_code (op_def) == BIT_IOR_EXPR)))
{
/* Recurse on each operand. */
- retval |= register_edge_assert_for_1 (TREE_OPERAND (rhs, 0),
+ retval |= register_edge_assert_for_1 (gimple_assign_rhs1 (op_def),
code, e, bsi);
- retval |= register_edge_assert_for_1 (TREE_OPERAND (rhs, 1),
+ retval |= register_edge_assert_for_1 (gimple_assign_rhs2 (op_def),
code, e, bsi);
}
- else if (TREE_CODE (rhs) == TRUTH_NOT_EXPR)
+ else if (gimple_assign_rhs_code (op_def) == TRUTH_NOT_EXPR)
{
/* Recurse, flipping CODE. */
code = invert_tree_comparison (code, false);
- retval |= register_edge_assert_for_1 (TREE_OPERAND (rhs, 0),
+ retval |= register_edge_assert_for_1 (gimple_assign_rhs1 (op_def),
code, e, bsi);
}
- else if (TREE_CODE (rhs) == SSA_NAME)
+ else if (gimple_assign_rhs_code (op_def) == SSA_NAME)
{
/* Recurse through the copy. */
- retval |= register_edge_assert_for_1 (rhs, code, e, bsi);
+ retval |= register_edge_assert_for_1 (gimple_assign_rhs1 (op_def),
+ code, e, bsi);
}
- else if (CONVERT_EXPR_P (rhs))
+ else if (gimple_assign_rhs_code (op_def) == NOP_EXPR
+ || gimple_assign_rhs_code (op_def) == CONVERT_EXPR)
{
/* Recurse through the type conversion. */
- retval |= register_edge_assert_for_1 (TREE_OPERAND (rhs, 0),
+ retval |= register_edge_assert_for_1 (gimple_assign_rhs1 (op_def),
code, e, bsi);
}
@@ -3964,7 +4114,7 @@ register_edge_assert_for_1 (tree op, enum tree_code code,
Return true if an assertion for NAME could be registered. */
static bool
-register_edge_assert_for (tree name, edge e, block_stmt_iterator si,
+register_edge_assert_for (tree name, edge e, gimple_stmt_iterator si,
enum tree_code cond_code, tree cond_op0,
tree cond_op1)
{
@@ -3999,14 +4149,14 @@ register_edge_assert_for (tree name, edge e, block_stmt_iterator si,
if (((comp_code == EQ_EXPR && integer_onep (val))
|| (comp_code == NE_EXPR && integer_zerop (val))))
{
- tree def_stmt = SSA_NAME_DEF_STMT (name);
+ gimple def_stmt = SSA_NAME_DEF_STMT (name);
- if (TREE_CODE (def_stmt) == GIMPLE_MODIFY_STMT
- && (TREE_CODE (GIMPLE_STMT_OPERAND (def_stmt, 1)) == TRUTH_AND_EXPR
- || TREE_CODE (GIMPLE_STMT_OPERAND (def_stmt, 1)) == BIT_AND_EXPR))
+ if (is_gimple_assign (def_stmt)
+ && (gimple_assign_rhs_code (def_stmt) == TRUTH_AND_EXPR
+ || gimple_assign_rhs_code (def_stmt) == BIT_AND_EXPR))
{
- tree op0 = TREE_OPERAND (GIMPLE_STMT_OPERAND (def_stmt, 1), 0);
- tree op1 = TREE_OPERAND (GIMPLE_STMT_OPERAND (def_stmt, 1), 1);
+ tree op0 = gimple_assign_rhs1 (def_stmt);
+ tree op1 = gimple_assign_rhs2 (def_stmt);
retval |= register_edge_assert_for_1 (op0, NE_EXPR, e, si);
retval |= register_edge_assert_for_1 (op1, NE_EXPR, e, si);
}
@@ -4018,18 +4168,17 @@ register_edge_assert_for (tree name, edge e, block_stmt_iterator si,
if (((comp_code == EQ_EXPR && integer_zerop (val))
|| (comp_code == NE_EXPR && integer_onep (val))))
{
- tree def_stmt = SSA_NAME_DEF_STMT (name);
+ gimple def_stmt = SSA_NAME_DEF_STMT (name);
- if (TREE_CODE (def_stmt) == GIMPLE_MODIFY_STMT
- && (TREE_CODE (GIMPLE_STMT_OPERAND (def_stmt, 1)) == TRUTH_OR_EXPR
+ if (is_gimple_assign (def_stmt)
+ && (gimple_assign_rhs_code (def_stmt) == TRUTH_OR_EXPR
/* For BIT_IOR_EXPR only if NAME == 0 both operands have
necessarily zero value. */
|| (comp_code == EQ_EXPR
- && (TREE_CODE (GIMPLE_STMT_OPERAND (def_stmt, 1))
- == BIT_IOR_EXPR))))
+ && (gimple_assign_rhs_code (def_stmt) == BIT_IOR_EXPR))))
{
- tree op0 = TREE_OPERAND (GIMPLE_STMT_OPERAND (def_stmt, 1), 0);
- tree op1 = TREE_OPERAND (GIMPLE_STMT_OPERAND (def_stmt, 1), 1);
+ tree op0 = gimple_assign_rhs1 (def_stmt);
+ tree op1 = gimple_assign_rhs2 (def_stmt);
retval |= register_edge_assert_for_1 (op0, EQ_EXPR, e, si);
retval |= register_edge_assert_for_1 (op1, EQ_EXPR, e, si);
}
@@ -4050,17 +4199,17 @@ static bool find_assert_locations (basic_block bb);
list of assertions for the corresponding operands. */
static bool
-find_conditional_asserts (basic_block bb, tree last)
+find_conditional_asserts (basic_block bb, gimple last)
{
bool need_assert;
- block_stmt_iterator bsi;
+ gimple_stmt_iterator bsi;
tree op;
edge_iterator ei;
edge e;
ssa_op_iter iter;
need_assert = false;
- bsi = bsi_for_stmt (last);
+ bsi = gsi_for_stmt (last);
/* Look for uses of the operands in each of the sub-graphs
rooted at BB. We need to check each of the outgoing edges
@@ -4104,15 +4253,10 @@ find_conditional_asserts (basic_block bb, tree last)
conditional predicate. */
FOR_EACH_SSA_TREE_OPERAND (op, last, iter, SSA_OP_USE)
{
- tree cond = COND_EXPR_COND (last);
- if (op != cond)
- need_assert |= register_edge_assert_for (op, e, bsi,
- TREE_CODE (cond),
- TREE_OPERAND (cond, 0),
- TREE_OPERAND (cond, 1));
- else
- need_assert |= register_edge_assert_for (op, e, bsi, EQ_EXPR, op,
- boolean_true_node);
+ need_assert |= register_edge_assert_for (op, e, bsi,
+ gimple_cond_code (last),
+ gimple_cond_lhs (last),
+ gimple_cond_rhs (last));
}
}
@@ -4160,26 +4304,26 @@ compare_case_labels (const void *p1, const void *p2)
list of assertions for the corresponding operands. */
static bool
-find_switch_asserts (basic_block bb, tree last)
+find_switch_asserts (basic_block bb, gimple last)
{
bool need_assert;
- block_stmt_iterator bsi;
+ gimple_stmt_iterator bsi;
tree op;
edge e;
- tree vec = SWITCH_LABELS (last), vec2;
- size_t n = TREE_VEC_LENGTH (vec);
+ tree vec2;
+ size_t n = gimple_switch_num_labels(last);
unsigned int idx;
need_assert = false;
- bsi = bsi_for_stmt (last);
- op = TREE_OPERAND (last, 0);
+ bsi = gsi_for_stmt (last);
+ op = gimple_switch_index (last);
if (TREE_CODE (op) != SSA_NAME)
return false;
/* Build a vector of case labels sorted by destination label. */
vec2 = make_tree_vec (n);
for (idx = 0; idx < n; ++idx)
- TREE_VEC_ELT (vec2, idx) = TREE_VEC_ELT (vec, idx);
+ TREE_VEC_ELT (vec2, idx) = gimple_switch_label (last, idx);
qsort (&TREE_VEC_ELT (vec2, 0), n, sizeof (tree), compare_case_labels);
for (idx = 0; idx < n; ++idx)
@@ -4319,8 +4463,9 @@ find_switch_asserts (basic_block bb, tree last)
static bool
find_assert_locations (basic_block bb)
{
- block_stmt_iterator si;
- tree last, phi;
+ gimple_stmt_iterator si;
+ gimple last;
+ gimple phi;
bool need_assert;
basic_block son;
@@ -4332,10 +4477,11 @@ find_assert_locations (basic_block bb)
need_assert = false;
/* Traverse all PHI nodes in BB marking used operands. */
- for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
+ for (si = gsi_start_phis (bb); !gsi_end_p(si); gsi_next (&si))
{
use_operand_p arg_p;
ssa_op_iter i;
+ phi = gsi_stmt (si);
FOR_EACH_PHI_ARG (arg_p, phi, i, SSA_OP_USE)
{
@@ -4350,13 +4496,14 @@ find_assert_locations (basic_block bb)
/* Traverse all the statements in BB marking used names and looking
for statements that may infer assertions for their used operands. */
- last = NULL_TREE;
- for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
+ last = NULL;
+ for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
{
- tree stmt, op;
+ gimple stmt;
+ tree op;
ssa_op_iter i;
- stmt = bsi_stmt (si);
+ stmt = gsi_stmt (si);
/* See if we can derive an assertion for any of STMT's operands. */
FOR_EACH_SSA_TREE_OPERAND (op, stmt, i, SSA_OP_USE)
@@ -4385,20 +4532,16 @@ find_assert_locations (basic_block bb)
if (comp_code == NE_EXPR && integer_zerop (value))
{
tree t = op;
- tree def_stmt = SSA_NAME_DEF_STMT (t);
+ gimple def_stmt = SSA_NAME_DEF_STMT (t);
- while (TREE_CODE (def_stmt) == GIMPLE_MODIFY_STMT
+ while (is_gimple_assign (def_stmt)
+ && gimple_assign_rhs_code (def_stmt) == NOP_EXPR
&& TREE_CODE
- (GIMPLE_STMT_OPERAND (def_stmt, 1)) == NOP_EXPR
- && TREE_CODE
- (TREE_OPERAND (GIMPLE_STMT_OPERAND (def_stmt, 1),
- 0)) == SSA_NAME
+ (gimple_assign_rhs1 (def_stmt)) == SSA_NAME
&& POINTER_TYPE_P
- (TREE_TYPE (TREE_OPERAND
- (GIMPLE_STMT_OPERAND (def_stmt,
- 1), 0))))
+ (TREE_TYPE (gimple_assign_rhs1 (def_stmt))))
{
- t = TREE_OPERAND (GIMPLE_STMT_OPERAND (def_stmt, 1), 0);
+ t = gimple_assign_rhs1 (def_stmt);
def_stmt = SSA_NAME_DEF_STMT (t);
/* Note we want to register the assert for the
@@ -4433,13 +4576,13 @@ find_assert_locations (basic_block bb)
involving integer operands, recurse into each of the sub-graphs
rooted at BB to determine if we need to add ASSERT_EXPRs. */
if (last
- && TREE_CODE (last) == COND_EXPR
- && !fp_predicate (COND_EXPR_COND (last))
+ && gimple_code (last) == GIMPLE_COND
+ && !fp_predicate (last)
&& !ZERO_SSA_OPERANDS (last, SSA_OP_USE))
need_assert |= find_conditional_asserts (bb, last);
if (last
- && TREE_CODE (last) == SWITCH_EXPR
+ && gimple_code (last) == GIMPLE_SWITCH
&& !ZERO_SSA_OPERANDS (last, SSA_OP_USE))
need_assert |= find_switch_asserts (bb, last);
@@ -4460,32 +4603,33 @@ static bool
process_assert_insertions_for (tree name, assert_locus_t loc)
{
/* Build the comparison expression NAME_i COMP_CODE VAL. */
- tree stmt, cond, assert_expr;
+ gimple stmt;
+ tree cond;
+ gimple assert_stmt;
edge_iterator ei;
edge e;
cond = build2 (loc->comp_code, boolean_type_node, loc->expr, loc->val);
- assert_expr = build_assert_expr_for (cond, name);
-
+ assert_stmt = build_assert_expr_for (cond, name);
if (loc->e)
{
/* We have been asked to insert the assertion on an edge. This
is used only by COND_EXPR and SWITCH_EXPR assertions. */
#if defined ENABLE_CHECKING
- gcc_assert (TREE_CODE (bsi_stmt (loc->si)) == COND_EXPR
- || TREE_CODE (bsi_stmt (loc->si)) == SWITCH_EXPR);
+ gcc_assert (gimple_code (gsi_stmt (loc->si)) == GIMPLE_COND
+ || gimple_code (gsi_stmt (loc->si)) == GIMPLE_SWITCH);
#endif
- bsi_insert_on_edge (loc->e, assert_expr);
+ gsi_insert_on_edge (loc->e, assert_stmt);
return true;
}
/* Otherwise, we can insert right after LOC->SI iff the
statement must not be the last statement in the block. */
- stmt = bsi_stmt (loc->si);
+ stmt = gsi_stmt (loc->si);
if (!stmt_ends_bb_p (stmt))
{
- bsi_insert_after (&loc->si, assert_expr, BSI_SAME_STMT);
+ gsi_insert_after (&loc->si, assert_stmt, GSI_SAME_STMT);
return false;
}
@@ -4496,7 +4640,7 @@ process_assert_insertions_for (tree name, assert_locus_t loc)
FOR_EACH_EDGE (e, ei, loc->bb->succs)
if (!(e->flags & EDGE_ABNORMAL))
{
- bsi_insert_on_edge (e, assert_expr);
+ gsi_insert_on_edge (e, assert_stmt);
return true;
}
@@ -4535,7 +4679,7 @@ process_assert_insertions (void)
}
if (update_edges_p)
- bsi_commit_edge_inserts ();
+ gsi_commit_edge_inserts ();
statistics_counter_event (cfun, "Number of ASSERT_EXPR expressions inserted",
num_asserts);
@@ -4622,7 +4766,7 @@ insert_range_assertions (void)
IGNORE_OFF_BY_ONE is true if the ARRAY_REF is inside a ADDR_EXPR. */
static void
-check_array_ref (tree ref, location_t* locus, bool ignore_off_by_one)
+check_array_ref (tree ref, const location_t *location, bool ignore_off_by_one)
{
value_range_t* vr = NULL;
tree low_sub, up_sub;
@@ -4662,7 +4806,7 @@ check_array_ref (tree ref, location_t* locus, bool ignore_off_by_one)
&& tree_int_cst_lt (low_sub, low_bound))
{
warning (OPT_Warray_bounds,
- "%Harray subscript is outside array bounds", locus);
+ "%Harray subscript is outside array bounds", location);
TREE_NO_WARNING (ref) = 1;
}
}
@@ -4677,14 +4821,14 @@ check_array_ref (tree ref, location_t* locus, bool ignore_off_by_one)
up_sub)))
{
warning (OPT_Warray_bounds, "%Harray subscript is above array bounds",
- locus);
+ location);
TREE_NO_WARNING (ref) = 1;
}
else if (TREE_CODE (low_sub) == INTEGER_CST
&& tree_int_cst_lt (low_sub, low_bound))
{
warning (OPT_Warray_bounds, "%Harray subscript is below array bounds",
- locus);
+ location);
TREE_NO_WARNING (ref) = 1;
}
}
@@ -4693,14 +4837,20 @@ check_array_ref (tree ref, location_t* locus, bool ignore_off_by_one)
address of an ARRAY_REF, and call check_array_ref on it. */
static void
-search_for_addr_array(tree t, location_t* location)
+search_for_addr_array(tree t, const location_t *location)
{
while (TREE_CODE (t) == SSA_NAME)
{
- t = SSA_NAME_DEF_STMT (t);
- if (TREE_CODE (t) != GIMPLE_MODIFY_STMT)
+ gimple g = SSA_NAME_DEF_STMT (t);
+
+ if (gimple_code (g) != GIMPLE_ASSIGN)
return;
- t = GIMPLE_STMT_OPERAND (t, 1);
+
+ if (get_gimple_rhs_class (gimple_assign_rhs_code (g)) !=
+ GIMPLE_SINGLE_RHS)
+ return;
+
+ t = gimple_assign_rhs1 (g);
}
@@ -4729,14 +4879,8 @@ static tree
check_array_bounds (tree *tp, int *walk_subtree, void *data)
{
tree t = *tp;
- tree stmt = (tree)data;
- location_t *location = EXPR_LOCUS (stmt);
-
- if (!EXPR_HAS_LOCATION (stmt))
- {
- *walk_subtree = FALSE;
- return NULL_TREE;
- }
+ struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
+ const location_t *location = (const location_t *) wi->info;
*walk_subtree = TRUE;
@@ -4746,14 +4890,6 @@ check_array_bounds (tree *tp, int *walk_subtree, void *data)
if (TREE_CODE (t) == INDIRECT_REF
|| (TREE_CODE (t) == RETURN_EXPR && TREE_OPERAND (t, 0)))
search_for_addr_array (TREE_OPERAND (t, 0), location);
- else if (TREE_CODE (t) == CALL_EXPR)
- {
- tree arg;
- call_expr_arg_iterator iter;
-
- FOR_EACH_CALL_EXPR_ARG (arg, iter, t)
- search_for_addr_array (arg, location);
- }
if (TREE_CODE (t) == ADDR_EXPR)
*walk_subtree = FALSE;
@@ -4768,7 +4904,7 @@ static void
check_all_array_refs (void)
{
basic_block bb;
- block_stmt_iterator si;
+ gimple_stmt_iterator si;
FOR_EACH_BB (bb)
{
@@ -4776,21 +4912,46 @@ check_all_array_refs (void)
if (single_pred_p (bb))
{
basic_block pred_bb = EDGE_PRED (bb, 0)->src;
- tree ls = NULL_TREE;
+ gimple ls = NULL;
- if (!bsi_end_p (bsi_last (pred_bb)))
- ls = bsi_stmt (bsi_last (pred_bb));
+ if (!gsi_end_p (gsi_last_bb (pred_bb)))
+ ls = gsi_stmt (gsi_last_bb (pred_bb));
- if (ls && TREE_CODE (ls) == COND_EXPR
- && ((COND_EXPR_COND (ls) == boolean_false_node
+ if (ls && gimple_code (ls) == GIMPLE_COND
+ && ((gimple_cond_false_p (ls)
&& (EDGE_PRED (bb, 0)->flags & EDGE_TRUE_VALUE))
- || (COND_EXPR_COND (ls) == boolean_true_node
+ || (gimple_cond_true_p (ls)
&& (EDGE_PRED (bb, 0)->flags & EDGE_FALSE_VALUE))))
continue;
}
- for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
- walk_tree (bsi_stmt_ptr (si), check_array_bounds,
- bsi_stmt (si), NULL);
+ for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
+ {
+ gimple stmt = gsi_stmt (si);
+ const location_t *location = gimple_location_ptr (stmt);
+ struct walk_stmt_info wi;
+ if (!gimple_has_location (stmt))
+ continue;
+
+ if (is_gimple_call (stmt))
+ {
+ size_t i;
+ size_t n = gimple_call_num_args (stmt);
+ for (i = 0; i < n; i++)
+ {
+ tree arg = gimple_call_arg (stmt, i);
+ search_for_addr_array (arg, location);
+ }
+ }
+ else
+ {
+ memset (&wi, 0, sizeof (wi));
+ wi.info = CONST_CAST (void *, (const void *) location);
+
+ walk_gimple_op (gsi_stmt (si),
+ check_array_bounds,
+ &wi);
+ }
+ }
}
}
@@ -4822,21 +4983,22 @@ static void
remove_range_assertions (void)
{
basic_block bb;
- block_stmt_iterator si;
+ gimple_stmt_iterator si;
/* Note that the BSI iterator bump happens at the bottom of the
loop and no bump is necessary if we're removing the statement
referenced by the current BSI. */
FOR_EACH_BB (bb)
- for (si = bsi_start (bb); !bsi_end_p (si);)
+ for (si = gsi_start_bb (bb); !gsi_end_p (si);)
{
- tree stmt = bsi_stmt (si);
- tree use_stmt;
+ gimple stmt = gsi_stmt (si);
+ gimple use_stmt;
- if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT
- && TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 1)) == ASSERT_EXPR)
+ if (is_gimple_assign (stmt)
+ && gimple_assign_rhs_code (stmt) == ASSERT_EXPR)
{
- tree rhs = GIMPLE_STMT_OPERAND (stmt, 1), var;
+ tree rhs = gimple_assign_rhs1 (stmt);
+ tree var;
tree cond = fold (ASSERT_EXPR_COND (rhs));
use_operand_p use_p;
imm_use_iterator iter;
@@ -4846,7 +5008,7 @@ remove_range_assertions (void)
/* Propagate the RHS into every use of the LHS. */
var = ASSERT_EXPR_VAR (rhs);
FOR_EACH_IMM_USE_STMT (use_stmt, iter,
- GIMPLE_STMT_OPERAND (stmt, 0))
+ gimple_assign_lhs (stmt))
FOR_EACH_IMM_USE_ON_STMT (use_p, iter)
{
SET_USE (use_p, var);
@@ -4854,11 +5016,11 @@ remove_range_assertions (void)
}
/* And finally, remove the copy, it is not needed. */
- bsi_remove (&si, true);
+ gsi_remove (&si, true);
release_defs (stmt);
}
else
- bsi_next (&si);
+ gsi_next (&si);
}
sbitmap_free (blocks_visited);
@@ -4868,32 +5030,31 @@ remove_range_assertions (void)
/* Return true if STMT is interesting for VRP. */
static bool
-stmt_interesting_for_vrp (tree stmt)
+stmt_interesting_for_vrp (gimple stmt)
{
- if (TREE_CODE (stmt) == PHI_NODE
- && is_gimple_reg (PHI_RESULT (stmt))
- && (INTEGRAL_TYPE_P (TREE_TYPE (PHI_RESULT (stmt)))
- || POINTER_TYPE_P (TREE_TYPE (PHI_RESULT (stmt)))))
+ if (gimple_code (stmt) == GIMPLE_PHI
+ && is_gimple_reg (gimple_phi_result (stmt))
+ && (INTEGRAL_TYPE_P (TREE_TYPE (gimple_phi_result (stmt)))
+ || POINTER_TYPE_P (TREE_TYPE (gimple_phi_result (stmt)))))
return true;
- else if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT)
+ else if (is_gimple_assign (stmt) || is_gimple_call (stmt))
{
- tree lhs = GIMPLE_STMT_OPERAND (stmt, 0);
- tree rhs = GIMPLE_STMT_OPERAND (stmt, 1);
+ tree lhs = gimple_get_lhs (stmt);
/* In general, assignments with virtual operands are not useful
for deriving ranges, with the obvious exception of calls to
builtin functions. */
- if (TREE_CODE (lhs) == SSA_NAME
+ if (lhs && TREE_CODE (lhs) == SSA_NAME
&& (INTEGRAL_TYPE_P (TREE_TYPE (lhs))
|| POINTER_TYPE_P (TREE_TYPE (lhs)))
- && ((TREE_CODE (rhs) == CALL_EXPR
- && TREE_CODE (CALL_EXPR_FN (rhs)) == ADDR_EXPR
- && DECL_P (TREE_OPERAND (CALL_EXPR_FN (rhs), 0))
- && DECL_IS_BUILTIN (TREE_OPERAND (CALL_EXPR_FN (rhs), 0)))
+ && ((is_gimple_call (stmt)
+ && gimple_call_fndecl (stmt) != NULL_TREE
+ && DECL_IS_BUILTIN (gimple_call_fndecl (stmt)))
|| ZERO_SSA_OPERANDS (stmt, SSA_OP_ALL_VIRTUALS)))
return true;
}
- else if (TREE_CODE (stmt) == COND_EXPR || TREE_CODE (stmt) == SWITCH_EXPR)
+ else if (gimple_code (stmt) == GIMPLE_COND
+ || gimple_code (stmt) == GIMPLE_SWITCH)
return true;
return false;
@@ -4912,24 +5073,24 @@ vrp_initialize (void)
FOR_EACH_BB (bb)
{
- block_stmt_iterator si;
- tree phi;
+ gimple_stmt_iterator si;
- for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
+ for (si = gsi_start_phis (bb); !gsi_end_p (si); gsi_next (&si))
{
+ gimple phi = gsi_stmt (si);
if (!stmt_interesting_for_vrp (phi))
{
tree lhs = PHI_RESULT (phi);
set_value_range_to_varying (get_value_range (lhs));
- DONT_SIMULATE_AGAIN (phi) = true;
+ prop_set_simulate_again (phi, false);
}
else
- DONT_SIMULATE_AGAIN (phi) = false;
+ prop_set_simulate_again (phi, true);
}
- for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
+ for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
{
- tree stmt = bsi_stmt (si);
+ gimple stmt = gsi_stmt (si);
if (!stmt_interesting_for_vrp (stmt))
{
@@ -4937,11 +5098,11 @@ vrp_initialize (void)
tree def;
FOR_EACH_SSA_TREE_OPERAND (def, stmt, i, SSA_OP_DEF)
set_value_range_to_varying (get_value_range (def));
- DONT_SIMULATE_AGAIN (stmt) = true;
+ prop_set_simulate_again (stmt, false);
}
else
{
- DONT_SIMULATE_AGAIN (stmt) = false;
+ prop_set_simulate_again (stmt, true);
}
}
}
@@ -4952,13 +5113,12 @@ vrp_initialize (void)
the SSA name in *OUTPUT_P. */
static enum ssa_prop_result
-vrp_visit_assignment (tree stmt, tree *output_p)
+vrp_visit_assignment_or_call (gimple stmt, tree *output_p)
{
- tree lhs, rhs, def;
+ tree def, lhs;
ssa_op_iter iter;
-
- lhs = GIMPLE_STMT_OPERAND (stmt, 0);
- rhs = GIMPLE_STMT_OPERAND (stmt, 1);
+ enum gimple_code code = gimple_code (stmt);
+ lhs = gimple_get_lhs (stmt);
/* We only keep track of ranges in integral and pointer types. */
if (TREE_CODE (lhs) == SSA_NAME
@@ -4972,7 +5132,10 @@ vrp_visit_assignment (tree stmt, tree *output_p)
struct loop *l;
value_range_t new_vr = { VR_UNDEFINED, NULL_TREE, NULL_TREE, NULL };
- extract_range_from_expr (&new_vr, rhs);
+ if (code == GIMPLE_CALL)
+ extract_range_basic (&new_vr, stmt);
+ else
+ extract_range_from_assignment (&new_vr, stmt);
/* If STMT is inside a loop, we may be able to know something
else about the range of LHS by examining scalar evolution
@@ -5233,15 +5396,12 @@ vrp_evaluate_conditional_warnv_with_ops (enum tree_code code, tree op0,
if (use_equiv_p)
{
if (TREE_CODE (op0) == SSA_NAME && TREE_CODE (op1) == SSA_NAME)
- return compare_names (code, op0, op1,
- strict_overflow_p);
+ return compare_names (code, op0, op1, strict_overflow_p);
else if (TREE_CODE (op0) == SSA_NAME)
- return compare_name_with_value (code, op0, op1,
- strict_overflow_p);
+ return compare_name_with_value (code, op0, op1, strict_overflow_p);
else if (TREE_CODE (op1) == SSA_NAME)
return (compare_name_with_value
- (swap_tree_comparison (code), op1, op0,
- strict_overflow_p));
+ (swap_tree_comparison (code), op1, op0, strict_overflow_p));
}
else
{
@@ -5251,15 +5411,12 @@ vrp_evaluate_conditional_warnv_with_ops (enum tree_code code, tree op0,
vr1 = (TREE_CODE (op1) == SSA_NAME) ? get_value_range (op1) : NULL;
if (vr0 && vr1)
- return compare_ranges (code, vr0, vr1,
- strict_overflow_p);
+ return compare_ranges (code, vr0, vr1, strict_overflow_p);
else if (vr0 && vr1 == NULL)
- return compare_range_with_value (code, vr0, op1,
- strict_overflow_p);
+ return compare_range_with_value (code, vr0, op1, strict_overflow_p);
else if (vr0 == NULL && vr1)
return (compare_range_with_value
- (swap_tree_comparison (code), vr1, op0,
- strict_overflow_p));
+ (swap_tree_comparison (code), vr1, op0, strict_overflow_p));
}
return NULL_TREE;
}
@@ -5272,17 +5429,13 @@ vrp_evaluate_conditional_warnv_with_ops (enum tree_code code, tree op0,
appropriate. */
tree
-vrp_evaluate_conditional (enum tree_code code, tree op0, tree op1, tree stmt)
+vrp_evaluate_conditional (enum tree_code code, tree op0, tree op1, gimple stmt)
{
bool sop;
tree ret;
sop = false;
- ret = vrp_evaluate_conditional_warnv_with_ops (code,
- op0,
- op1,
- true,
- &sop);
+ ret = vrp_evaluate_conditional_warnv_with_ops (code, op0, op1, true, &sop);
if (ret && sop)
{
@@ -5304,13 +5457,13 @@ vrp_evaluate_conditional (enum tree_code code, tree op0, tree op1, tree stmt)
if (issue_strict_overflow_warning (wc))
{
- location_t locus;
+ location_t location;
- if (!EXPR_HAS_LOCATION (stmt))
- locus = input_location;
+ if (!gimple_has_location (stmt))
+ location = input_location;
else
- locus = EXPR_LOCATION (stmt);
- warning (OPT_Wstrict_overflow, "%H%s", &locus, warnmsg);
+ location = gimple_location (stmt);
+ warning (OPT_Wstrict_overflow, "%H%s", &location, warnmsg);
}
}
@@ -5344,14 +5497,14 @@ vrp_evaluate_conditional (enum tree_code code, tree op0, tree op1, tree stmt)
if (warnmsg)
{
- location_t locus;
+ location_t location;
- if (!EXPR_HAS_LOCATION (stmt))
- locus = input_location;
+ if (!gimple_has_location (stmt))
+ location = input_location;
else
- locus = EXPR_LOCATION (stmt);
+ location = gimple_location (stmt);
- warning (OPT_Wtype_limits, "%H%s", &locus, warnmsg);
+ warning (OPT_Wtype_limits, "%H%s", &location, warnmsg);
}
}
@@ -5365,13 +5518,12 @@ vrp_evaluate_conditional (enum tree_code code, tree op0, tree op1, tree stmt)
SSA_PROP_VARYING. */
static enum ssa_prop_result
-vrp_visit_cond_stmt (tree stmt, edge *taken_edge_p)
+vrp_visit_cond_stmt (gimple stmt, edge *taken_edge_p)
{
- tree cond, val;
+ tree val;
bool sop;
*taken_edge_p = NULL;
- cond = COND_EXPR_COND (stmt);
if (dump_file && (dump_flags & TDF_DETAILS))
{
@@ -5379,7 +5531,7 @@ vrp_visit_cond_stmt (tree stmt, edge *taken_edge_p)
ssa_op_iter i;
fprintf (dump_file, "\nVisiting conditional with predicate: ");
- print_generic_expr (dump_file, cond, 0);
+ print_gimple_stmt (dump_file, stmt, 0, 0);
fprintf (dump_file, "\nWith known ranges\n");
FOR_EACH_SSA_TREE_OPERAND (use, stmt, i, SSA_OP_USE)
@@ -5437,22 +5589,14 @@ vrp_visit_cond_stmt (tree stmt, edge *taken_edge_p)
4 more predicates folded in SPEC. */
sop = false;
- if (TREE_CODE (cond) == SSA_NAME)
- val = vrp_evaluate_conditional_warnv_with_ops (EQ_EXPR,
- cond,
- boolean_true_node,
- false,
- &sop);
- else
- val = vrp_evaluate_conditional_warnv_with_ops (TREE_CODE (cond),
- TREE_OPERAND (cond, 0),
- TREE_OPERAND (cond, 1),
- false,
- &sop);
+ val = vrp_evaluate_conditional_warnv_with_ops (gimple_cond_code (stmt),
+ gimple_cond_lhs (stmt),
+ gimple_cond_rhs (stmt),
+ false, &sop);
if (val)
{
if (!sop)
- *taken_edge_p = find_taken_edge (bb_for_stmt (stmt), val);
+ *taken_edge_p = find_taken_edge (gimple_bb (stmt), val);
else
{
if (dump_file && (dump_flags & TDF_DETAILS))
@@ -5477,7 +5621,7 @@ vrp_visit_cond_stmt (tree stmt, edge *taken_edge_p)
/* Searches the case label vector VEC for the index *IDX of the CASE_LABEL
that includes the value VAL. The search is restricted to the range
- [START_IDX, n - 2] where n is the size of VEC (n - 1 is the default label).
+ [START_IDX, n - 1] where n is the size of VEC.
If there is a CASE_LABEL for VAL, its index is placed in IDX and true is
returned.
@@ -5485,25 +5629,25 @@ vrp_visit_cond_stmt (tree stmt, edge *taken_edge_p)
If there is no CASE_LABEL for VAL and the is one that is larger than VAL,
it is placed in IDX and false is returned.
- If VAL is larger than any CASE_LABEL, n - 1 is placed on IDX and false is
+ If VAL is larger than any CASE_LABEL, n is placed on IDX and false is
returned. */
static bool
-find_case_label_index (tree vec, size_t start_idx, tree val, size_t *idx)
+find_case_label_index (gimple stmt, size_t start_idx, tree val, size_t *idx)
{
- size_t n = TREE_VEC_LENGTH (vec);
+ size_t n = gimple_switch_num_labels (stmt);
size_t low, high;
/* Find case label for minimum of the value range or the next one.
At each iteration we are searching in [low, high - 1]. */
- for (low = start_idx, high = n - 1; high != low; )
+ for (low = start_idx, high = n; high != low; )
{
tree t;
int cmp;
- /* Note that i != high, so we never ask for n - 1. */
+ /* Note that i != high, so we never ask for n. */
size_t i = (high + low) / 2;
- t = TREE_VEC_ELT (vec, i);
+ t = gimple_switch_label (stmt, i);
/* Cache the result of comparing CASE_LOW and val. */
cmp = tree_int_cst_compare (CASE_LOW (t), val);
@@ -5539,11 +5683,12 @@ find_case_label_index (tree vec, size_t start_idx, tree val, size_t *idx)
Returns true if the default label is not needed. */
static bool
-find_case_label_range (tree vec, tree min, tree max, size_t *min_idx, size_t *max_idx)
+find_case_label_range (gimple stmt, tree min, tree max, size_t *min_idx,
+ size_t *max_idx)
{
size_t i, j;
- bool min_take_default = !find_case_label_index (vec, 0, min, &i);
- bool max_take_default = !find_case_label_index (vec, i, max, &j);
+ bool min_take_default = !find_case_label_index (stmt, 1, min, &i);
+ bool max_take_default = !find_case_label_index (stmt, i, max, &j);
if (i == j
&& min_take_default
@@ -5566,20 +5711,20 @@ find_case_label_range (tree vec, tree min, tree max, size_t *min_idx, size_t *ma
/* If the case label range is continuous, we do not need
the default case label. Verify that. */
- high = CASE_LOW (TREE_VEC_ELT (vec, i));
- if (CASE_HIGH (TREE_VEC_ELT (vec, i)))
- high = CASE_HIGH (TREE_VEC_ELT (vec, i));
+ high = CASE_LOW (gimple_switch_label (stmt, i));
+ if (CASE_HIGH (gimple_switch_label (stmt, i)))
+ high = CASE_HIGH (gimple_switch_label (stmt, i));
for (k = i + 1; k <= j; ++k)
{
- low = CASE_LOW (TREE_VEC_ELT (vec, k));
+ low = CASE_LOW (gimple_switch_label (stmt, k));
if (!integer_onep (int_const_binop (MINUS_EXPR, low, high, 0)))
{
take_default = true;
break;
}
high = low;
- if (CASE_HIGH (TREE_VEC_ELT (vec, k)))
- high = CASE_HIGH (TREE_VEC_ELT (vec, k));
+ if (CASE_HIGH (gimple_switch_label (stmt, k)))
+ high = CASE_HIGH (gimple_switch_label (stmt, k));
}
*min_idx = i;
@@ -5594,16 +5739,15 @@ find_case_label_range (tree vec, tree min, tree max, size_t *min_idx, size_t *ma
SSA_PROP_VARYING. */
static enum ssa_prop_result
-vrp_visit_switch_stmt (tree stmt, edge *taken_edge_p)
+vrp_visit_switch_stmt (gimple stmt, edge *taken_edge_p)
{
tree op, val;
value_range_t *vr;
size_t i = 0, j = 0, n;
- tree vec;
bool take_default;
*taken_edge_p = NULL;
- op = TREE_OPERAND (stmt, 0);
+ op = gimple_switch_index (stmt);
if (TREE_CODE (op) != SSA_NAME)
return SSA_PROP_VARYING;
@@ -5622,26 +5766,26 @@ vrp_visit_switch_stmt (tree stmt, edge *taken_edge_p)
return SSA_PROP_VARYING;
/* Find the single edge that is taken from the switch expression. */
- vec = SWITCH_LABELS (stmt);
- n = TREE_VEC_LENGTH (vec);
+ n = gimple_switch_num_labels (stmt);
- take_default = !find_case_label_range (vec, vr->min, vr->max, &i, &j);
+ take_default = !find_case_label_range (stmt, vr->min, vr->max, &i, &j);
/* Check if the range spans no CASE_LABEL. If so, we only reach the default
label */
if (j < i)
{
gcc_assert (take_default);
- val = TREE_VEC_ELT (vec, n - 1);
+ val = gimple_switch_default_label (stmt);
}
else
{
/* Check if labels with index i to j and maybe the default label
are all reaching the same label. */
- val = TREE_VEC_ELT (vec, i);
+ val = gimple_switch_label (stmt, i);
if (take_default
- && CASE_LABEL (TREE_VEC_ELT (vec, n - 1)) != CASE_LABEL (val))
+ && CASE_LABEL (gimple_switch_default_label (stmt))
+ != CASE_LABEL (val))
{
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, " not a single destination for this "
@@ -5650,7 +5794,7 @@ vrp_visit_switch_stmt (tree stmt, edge *taken_edge_p)
}
for (++i; i <= j; ++i)
{
- if (CASE_LABEL (TREE_VEC_ELT (vec, i)) != CASE_LABEL (val))
+ if (CASE_LABEL (gimple_switch_label (stmt, i)) != CASE_LABEL (val))
{
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, " not a single destination for this "
@@ -5660,7 +5804,7 @@ vrp_visit_switch_stmt (tree stmt, edge *taken_edge_p)
}
}
- *taken_edge_p = find_edge (bb_for_stmt (stmt),
+ *taken_edge_p = find_edge (gimple_bb (stmt),
label_to_block (CASE_LABEL (val)));
if (dump_file && (dump_flags & TDF_DETAILS))
@@ -5683,37 +5827,33 @@ vrp_visit_switch_stmt (tree stmt, edge *taken_edge_p)
If STMT produces a varying value, return SSA_PROP_VARYING. */
static enum ssa_prop_result
-vrp_visit_stmt (tree stmt, edge *taken_edge_p, tree *output_p)
+vrp_visit_stmt (gimple stmt, edge *taken_edge_p, tree *output_p)
{
tree def;
ssa_op_iter iter;
- stmt_ann_t ann;
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "\nVisiting statement:\n");
- print_generic_stmt (dump_file, stmt, dump_flags);
+ print_gimple_stmt (dump_file, stmt, 0, dump_flags);
fprintf (dump_file, "\n");
}
- ann = stmt_ann (stmt);
- if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT)
+ if (is_gimple_assign (stmt) || is_gimple_call (stmt))
{
- tree rhs = GIMPLE_STMT_OPERAND (stmt, 1);
-
/* In general, assignments with virtual operands are not useful
for deriving ranges, with the obvious exception of calls to
builtin functions. */
- if ((TREE_CODE (rhs) == CALL_EXPR
- && TREE_CODE (CALL_EXPR_FN (rhs)) == ADDR_EXPR
- && DECL_P (TREE_OPERAND (CALL_EXPR_FN (rhs), 0))
- && DECL_IS_BUILTIN (TREE_OPERAND (CALL_EXPR_FN (rhs), 0)))
+
+ if ((is_gimple_call (stmt)
+ && gimple_call_fndecl (stmt) != NULL_TREE
+ && DECL_IS_BUILTIN (gimple_call_fndecl (stmt)))
|| ZERO_SSA_OPERANDS (stmt, SSA_OP_ALL_VIRTUALS))
- return vrp_visit_assignment (stmt, output_p);
+ return vrp_visit_assignment_or_call (stmt, output_p);
}
- else if (TREE_CODE (stmt) == COND_EXPR)
+ else if (gimple_code (stmt) == GIMPLE_COND)
return vrp_visit_cond_stmt (stmt, taken_edge_p);
- else if (TREE_CODE (stmt) == SWITCH_EXPR)
+ else if (gimple_code (stmt) == GIMPLE_SWITCH)
return vrp_visit_switch_stmt (stmt, taken_edge_p);
/* All other statements produce nothing of interest for VRP, so mark
@@ -5876,9 +6016,9 @@ give_up:
value ranges, set a new range for the LHS of PHI. */
static enum ssa_prop_result
-vrp_visit_phi_node (tree phi)
+vrp_visit_phi_node (gimple phi)
{
- int i;
+ size_t i;
tree lhs = PHI_RESULT (phi);
value_range_t *lhs_vr = get_value_range (lhs);
value_range_t vr_result = { VR_UNDEFINED, NULL_TREE, NULL_TREE, NULL };
@@ -5889,19 +6029,19 @@ vrp_visit_phi_node (tree phi)
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "\nVisiting PHI node: ");
- print_generic_expr (dump_file, phi, dump_flags);
+ print_gimple_stmt (dump_file, phi, 0, dump_flags);
}
edges = 0;
- for (i = 0; i < PHI_NUM_ARGS (phi); i++)
+ for (i = 0; i < gimple_phi_num_args (phi); i++)
{
- edge e = PHI_ARG_EDGE (phi, i);
+ edge e = gimple_phi_arg_edge (phi, i);
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file,
"\n Argument #%d (%d -> %d %sexecutable)\n",
- i, e->src->index, e->dest->index,
+ (int) i, e->src->index, e->dest->index,
(e->flags & EDGE_EXECUTABLE) ? "" : "not ");
}
@@ -6027,13 +6167,15 @@ varying:
than zero and the second operand is an exact power of two. */
static void
-simplify_div_or_mod_using_ranges (tree stmt, tree rhs, enum tree_code rhs_code)
+simplify_div_or_mod_using_ranges (gimple stmt)
{
+ enum tree_code rhs_code = gimple_assign_rhs_code (stmt);
tree val = NULL;
- tree op = TREE_OPERAND (rhs, 0);
- value_range_t *vr = get_value_range (TREE_OPERAND (rhs, 0));
+ tree op0 = gimple_assign_rhs1 (stmt);
+ tree op1 = gimple_assign_rhs2 (stmt);
+ value_range_t *vr = get_value_range (gimple_assign_rhs1 (stmt));
- if (TYPE_UNSIGNED (TREE_TYPE (op)))
+ if (TYPE_UNSIGNED (TREE_TYPE (op0)))
{
val = integer_one_node;
}
@@ -6048,39 +6190,41 @@ simplify_div_or_mod_using_ranges (tree stmt, tree rhs, enum tree_code rhs_code)
&& integer_onep (val)
&& issue_strict_overflow_warning (WARN_STRICT_OVERFLOW_MISC))
{
- location_t locus;
+ location_t location;
- if (!EXPR_HAS_LOCATION (stmt))
- locus = input_location;
+ if (!gimple_has_location (stmt))
+ location = input_location;
else
- locus = EXPR_LOCATION (stmt);
+ location = gimple_location (stmt);
warning (OPT_Wstrict_overflow,
("%Hassuming signed overflow does not occur when "
"simplifying / or %% to >> or &"),
- &locus);
+ &location);
}
}
if (val && integer_onep (val))
{
tree t;
- tree op0 = TREE_OPERAND (rhs, 0);
- tree op1 = TREE_OPERAND (rhs, 1);
if (rhs_code == TRUNC_DIV_EXPR)
{
t = build_int_cst (NULL_TREE, tree_log2 (op1));
- t = build2 (RSHIFT_EXPR, TREE_TYPE (op0), op0, t);
+ gimple_assign_set_rhs_code (stmt, RSHIFT_EXPR);
+ gimple_assign_set_rhs1 (stmt, op0);
+ gimple_assign_set_rhs2 (stmt, t);
}
else
{
t = build_int_cst (TREE_TYPE (op1), 1);
t = int_const_binop (MINUS_EXPR, op1, t, 0);
t = fold_convert (TREE_TYPE (op0), t);
- t = build2 (BIT_AND_EXPR, TREE_TYPE (op0), op0, t);
+
+ gimple_assign_set_rhs_code (stmt, BIT_AND_EXPR);
+ gimple_assign_set_rhs1 (stmt, op0);
+ gimple_assign_set_rhs2 (stmt, t);
}
- GIMPLE_STMT_OPERAND (stmt, 1) = t;
update_stmt (stmt);
}
}
@@ -6090,12 +6234,12 @@ simplify_div_or_mod_using_ranges (tree stmt, tree rhs, enum tree_code rhs_code)
ABS_EXPR into a NEGATE_EXPR. */
static void
-simplify_abs_using_ranges (tree stmt, tree rhs)
+simplify_abs_using_ranges (gimple stmt)
{
tree val = NULL;
- tree op = TREE_OPERAND (rhs, 0);
+ tree op = gimple_assign_rhs1 (stmt);
tree type = TREE_TYPE (op);
- value_range_t *vr = get_value_range (TREE_OPERAND (rhs, 0));
+ value_range_t *vr = get_value_range (op);
if (TYPE_UNSIGNED (type))
{
@@ -6124,28 +6268,25 @@ simplify_abs_using_ranges (tree stmt, tree rhs)
if (val
&& (integer_onep (val) || integer_zerop (val)))
{
- tree t;
-
if (sop && issue_strict_overflow_warning (WARN_STRICT_OVERFLOW_MISC))
{
- location_t locus;
+ location_t location;
- if (!EXPR_HAS_LOCATION (stmt))
- locus = input_location;
+ if (!gimple_has_location (stmt))
+ location = input_location;
else
- locus = EXPR_LOCATION (stmt);
+ location = gimple_location (stmt);
warning (OPT_Wstrict_overflow,
("%Hassuming signed overflow does not occur when "
"simplifying abs (X) to X or -X"),
- &locus);
+ &location);
}
+ gimple_assign_set_rhs1 (stmt, op);
if (integer_onep (val))
- t = build1 (NEGATE_EXPR, TREE_TYPE (op), op);
+ gimple_assign_set_rhs_code (stmt, NEGATE_EXPR);
else
- t = op;
-
- GIMPLE_STMT_OPERAND (stmt, 1) = t;
+ gimple_assign_set_rhs_code (stmt, SSA_NAME);
update_stmt (stmt);
}
}
@@ -6224,12 +6365,11 @@ test_for_singularity (enum tree_code cond_code, tree op0,
the original conditional. */
static void
-simplify_cond_using_ranges (tree stmt)
+simplify_cond_using_ranges (gimple stmt)
{
- tree cond = COND_EXPR_COND (stmt);
- tree op0 = TREE_OPERAND (cond, 0);
- tree op1 = TREE_OPERAND (cond, 1);
- enum tree_code cond_code = TREE_CODE (cond);
+ tree op0 = gimple_cond_lhs (stmt);
+ tree op1 = gimple_cond_rhs (stmt);
+ enum tree_code cond_code = gimple_cond_code (stmt);
if (cond_code != NE_EXPR
&& cond_code != EQ_EXPR
@@ -6250,17 +6390,19 @@ simplify_cond_using_ranges (tree stmt)
if (dump_file)
{
fprintf (dump_file, "Simplified relational ");
- print_generic_expr (dump_file, cond, 0);
+ print_gimple_stmt (dump_file, stmt, 0, 0);
fprintf (dump_file, " into ");
}
- COND_EXPR_COND (stmt)
- = build2 (EQ_EXPR, boolean_type_node, op0, new);
+ gimple_cond_set_code (stmt, EQ_EXPR);
+ gimple_cond_set_lhs (stmt, op0);
+ gimple_cond_set_rhs (stmt, new);
+
update_stmt (stmt);
if (dump_file)
{
- print_generic_expr (dump_file, COND_EXPR_COND (stmt), 0);
+ print_gimple_stmt (dump_file, stmt, 0, 0);
fprintf (dump_file, "\n");
}
return;
@@ -6278,17 +6420,19 @@ simplify_cond_using_ranges (tree stmt)
if (dump_file)
{
fprintf (dump_file, "Simplified relational ");
- print_generic_expr (dump_file, cond, 0);
+ print_gimple_stmt (dump_file, stmt, 0, 0);
fprintf (dump_file, " into ");
}
- COND_EXPR_COND (stmt)
- = build2 (NE_EXPR, boolean_type_node, op0, new);
+ gimple_cond_set_code (stmt, NE_EXPR);
+ gimple_cond_set_lhs (stmt, op0);
+ gimple_cond_set_rhs (stmt, new);
+
update_stmt (stmt);
if (dump_file)
{
- print_generic_expr (dump_file, COND_EXPR_COND (stmt), 0);
+ print_gimple_stmt (dump_file, stmt, 0, 0);
fprintf (dump_file, "\n");
}
return;
@@ -6302,15 +6446,15 @@ simplify_cond_using_ranges (tree stmt)
argument. */
static void
-simplify_switch_using_ranges (tree stmt)
+simplify_switch_using_ranges (gimple stmt)
{
- tree op = TREE_OPERAND (stmt, 0);
+ tree op = gimple_switch_index (stmt);
value_range_t *vr;
bool take_default;
edge e;
edge_iterator ei;
size_t i = 0, j = 0, n, n2;
- tree vec, vec2;
+ tree vec2;
switch_update su;
if (TREE_CODE (op) != SSA_NAME)
@@ -6324,35 +6468,36 @@ simplify_switch_using_ranges (tree stmt)
return;
/* Find case label for min/max of the value range. */
- vec = SWITCH_LABELS (stmt);
- n = TREE_VEC_LENGTH (vec);
- take_default = !find_case_label_range (vec, vr->min, vr->max, &i, &j);
+ n = gimple_switch_num_labels (stmt);
+ take_default = !find_case_label_range (stmt, vr->min, vr->max, &i, &j);
/* Bail out if this is just all edges taken. */
- if (i == 0
- && j == n - 2
+ if (i == 1
+ && j == n - 1
&& take_default)
return;
/* Build a new vector of taken case labels. */
vec2 = make_tree_vec (j - i + 1 + (int)take_default);
- for (n2 = 0; i <= j; ++i, ++n2)
- TREE_VEC_ELT (vec2, n2) = TREE_VEC_ELT (vec, i);
+ n2 = 0;
/* Add the default edge, if necessary. */
if (take_default)
- TREE_VEC_ELT (vec2, n2++) = TREE_VEC_ELT (vec, n - 1);
+ TREE_VEC_ELT (vec2, n2++) = gimple_switch_default_label (stmt);
+
+ for (; i <= j; ++i, ++n2)
+ TREE_VEC_ELT (vec2, n2) = gimple_switch_label (stmt, i);
/* Mark needed edges. */
for (i = 0; i < n2; ++i)
{
- e = find_edge (bb_for_stmt (stmt),
+ e = find_edge (gimple_bb (stmt),
label_to_block (CASE_LABEL (TREE_VEC_ELT (vec2, i))));
e->aux = (void *)-1;
}
/* Queue not needed edges for later removal. */
- FOR_EACH_EDGE (e, ei, bb_for_stmt (stmt)->succs)
+ FOR_EACH_EDGE (e, ei, gimple_bb (stmt)->succs)
{
if (e->aux == (void *)-1)
{
@@ -6376,31 +6521,29 @@ simplify_switch_using_ranges (tree stmt)
/* Simplify STMT using ranges if possible. */
void
-simplify_stmt_using_ranges (tree stmt)
+simplify_stmt_using_ranges (gimple stmt)
{
- if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT)
+ if (is_gimple_assign (stmt))
{
- tree rhs = GIMPLE_STMT_OPERAND (stmt, 1);
- enum tree_code rhs_code = TREE_CODE (rhs);
+ enum tree_code rhs_code = gimple_assign_rhs_code (stmt);
/* Transform TRUNC_DIV_EXPR and TRUNC_MOD_EXPR into RSHIFT_EXPR
and BIT_AND_EXPR respectively if the first operand is greater
than zero and the second operand is an exact power of two. */
if ((rhs_code == TRUNC_DIV_EXPR || rhs_code == TRUNC_MOD_EXPR)
- && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (rhs, 0)))
- && integer_pow2p (TREE_OPERAND (rhs, 1)))
- simplify_div_or_mod_using_ranges (stmt, rhs, rhs_code);
+ && INTEGRAL_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (stmt)))
+ && integer_pow2p (gimple_assign_rhs2 (stmt)))
+ simplify_div_or_mod_using_ranges (stmt);
/* Transform ABS (X) into X or -X as appropriate. */
if (rhs_code == ABS_EXPR
- && TREE_CODE (TREE_OPERAND (rhs, 0)) == SSA_NAME
- && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (rhs, 0))))
- simplify_abs_using_ranges (stmt, rhs);
+ && TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME
+ && INTEGRAL_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (stmt))))
+ simplify_abs_using_ranges (stmt);
}
- else if (TREE_CODE (stmt) == COND_EXPR
- && COMPARISON_CLASS_P (COND_EXPR_COND (stmt)))
+ else if (gimple_code (stmt) == GIMPLE_COND)
simplify_cond_using_ranges (stmt);
- else if (TREE_CODE (stmt) == SWITCH_EXPR)
+ else if (gimple_code (stmt) == GIMPLE_SWITCH)
simplify_switch_using_ranges (stmt);
}
@@ -6417,26 +6560,17 @@ static VEC(tree,heap) *stack;
for any overflow warnings. */
static tree
-simplify_stmt_for_jump_threading (tree stmt, tree within_stmt)
+simplify_stmt_for_jump_threading (gimple stmt, gimple within_stmt)
{
- tree conditional;
/* We only use VRP information to simplify conditionals. This is
overly conservative, but it's unclear if doing more would be
worth the compile time cost. */
- if (TREE_CODE (stmt) != COND_EXPR)
+ if (gimple_code (stmt) != GIMPLE_COND)
return NULL;
- conditional = COND_EXPR_COND (stmt);
- if (TREE_CODE (conditional) == SSA_NAME)
- return vrp_evaluate_conditional (EQ_EXPR,
- conditional,
- boolean_true_node,
- within_stmt);
- else
- return vrp_evaluate_conditional (TREE_CODE (conditional),
- TREE_OPERAND (conditional, 0),
- TREE_OPERAND (conditional, 1),
- within_stmt);
+ return vrp_evaluate_conditional (gimple_cond_code (stmt),
+ gimple_cond_lhs (stmt),
+ gimple_cond_rhs (stmt), within_stmt);
}
/* Blocks which have more than one predecessor and more than
@@ -6463,7 +6597,7 @@ static void
identify_jump_threads (void)
{
basic_block bb;
- tree dummy;
+ gimple dummy;
int i;
edge e;
@@ -6491,8 +6625,9 @@ identify_jump_threads (void)
/* To avoid lots of silly node creation, we create a single
conditional and just modify it in-place when attempting to
thread jumps. */
- dummy = build2 (EQ_EXPR, boolean_type_node, NULL, NULL);
- dummy = build3 (COND_EXPR, void_type_node, dummy, NULL, NULL);
+ dummy = gimple_build_cond (EQ_EXPR,
+ integer_zero_node, integer_zero_node,
+ NULL, NULL);
/* Walk through all the blocks finding those which present a
potential jump threading opportunity. We could set this up
@@ -6502,7 +6637,7 @@ identify_jump_threads (void)
point in compilation. */
FOR_EACH_BB (bb)
{
- tree last, cond;
+ gimple last;
/* If the generic jump threading code does not find this block
interesting, then there is nothing to do. */
@@ -6512,21 +6647,17 @@ identify_jump_threads (void)
/* We only care about blocks ending in a COND_EXPR. While there
may be some value in handling SWITCH_EXPR here, I doubt it's
terribly important. */
- last = bsi_stmt (bsi_last (bb));
- if (TREE_CODE (last) != COND_EXPR)
+ last = gsi_stmt (gsi_last_bb (bb));
+ if (gimple_code (last) != GIMPLE_COND)
continue;
/* We're basically looking for any kind of conditional with
integral type arguments. */
- cond = COND_EXPR_COND (last);
- if ((TREE_CODE (cond) == SSA_NAME
- && INTEGRAL_TYPE_P (TREE_TYPE (cond)))
- || (COMPARISON_CLASS_P (cond)
- && TREE_CODE (TREE_OPERAND (cond, 0)) == SSA_NAME
- && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (cond, 0)))
- && (TREE_CODE (TREE_OPERAND (cond, 1)) == SSA_NAME
- || is_gimple_min_invariant (TREE_OPERAND (cond, 1)))
- && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (cond, 1)))))
+ if (TREE_CODE (gimple_cond_lhs (last)) == SSA_NAME
+ && INTEGRAL_TYPE_P (TREE_TYPE (gimple_cond_lhs (last)))
+ && (TREE_CODE (gimple_cond_rhs (last)) == SSA_NAME
+ || is_gimple_min_invariant (gimple_cond_rhs (last)))
+ && INTEGRAL_TYPE_P (TREE_TYPE (gimple_cond_rhs (last))))
{
edge_iterator ei;
@@ -6541,8 +6672,7 @@ identify_jump_threads (void)
if (e->flags & (EDGE_DFS_BACK | EDGE_COMPLEX))
continue;
- thread_across_edge (dummy, e, true,
- &stack,
+ thread_across_edge (dummy, e, true, &stack,
simplify_stmt_for_jump_threading);
}
}
@@ -6718,7 +6848,13 @@ execute_vrp (void)
remove_edge (e);
/* Update SWITCH_EXPR case label vector. */
for (i = 0; VEC_iterate (switch_update, to_update_switch_stmts, i, su); ++i)
- SWITCH_LABELS (su->stmt) = su->vec;
+ {
+ size_t j;
+ size_t n = TREE_VEC_LENGTH (su->vec);
+ gimple_switch_set_num_labels (su->stmt, n);
+ for (j = 0; j < n; j++)
+ gimple_switch_set_label (su->stmt, j, TREE_VEC_ELT (su->vec, j));
+ }
if (VEC_length (edge, to_remove_edges) > 0)
free_dominance_info (CDI_DOMINATORS);
@@ -6728,7 +6864,6 @@ execute_vrp (void)
scev_finalize ();
loop_optimizer_finalize ();
-
return 0;
}
diff --git a/gcc/tree.c b/gcc/tree.c
index 97b53bd951c..cdecd707f00 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -105,8 +105,7 @@ const char *const tree_code_class_strings[] =
"binary",
"statement",
"vl_exp",
- "expression",
- "gimple_stmt"
+ "expression"
};
/* obstack.[ch] explicitly declined to prototype this. */
@@ -132,14 +131,12 @@ static const char * const tree_node_kind_names[] = {
"temp_tree_lists",
"vecs",
"binfos",
- "phi_nodes",
"ssa names",
"constructors",
"random kinds",
"lang_decl kinds",
"lang_type kinds",
"omp clauses",
- "gimple statements"
};
#endif /* GATHER_STATISTICS */
@@ -175,6 +172,16 @@ static GTY (()) tree int_cst_node;
static GTY ((if_marked ("ggc_marked_p"), param_is (union tree_node)))
htab_t int_cst_hash_table;
+/* Hash table for optimization flags and target option flags. Use the same
+ hash table for both sets of options. Nodes for building the current
+ optimization and target option nodes. The assumption is most of the time
+ the options created will already be in the hash table, so we avoid
+ allocating and freeing up a node repeatably. */
+static GTY (()) tree cl_optimization_node;
+static GTY (()) tree cl_target_option_node;
+static GTY ((if_marked ("ggc_marked_p"), param_is (union tree_node)))
+ htab_t cl_option_hash_table;
+
/* General tree->tree mapping structure for use in hash tables. */
@@ -196,6 +203,8 @@ static int type_hash_eq (const void *, const void *);
static hashval_t type_hash_hash (const void *);
static hashval_t int_cst_hash_hash (const void *);
static int int_cst_hash_eq (const void *, const void *);
+static hashval_t cl_option_hash_hash (const void *);
+static int cl_option_hash_eq (const void *, const void *);
static void print_type_hash_statistics (void);
static void print_debug_expr_statistics (void);
static void print_value_expr_statistics (void);
@@ -273,6 +282,12 @@ init_ttree (void)
int_cst_node = make_node (INTEGER_CST);
+ cl_option_hash_table = htab_create_ggc (64, cl_option_hash_hash,
+ cl_option_hash_eq, NULL);
+
+ cl_optimization_node = make_node (OPTIMIZATION_NODE);
+ cl_target_option_node = make_node (TARGET_OPTION_NODE);
+
tree_contains_struct[FUNCTION_DECL][TS_DECL_NON_COMMON] = 1;
tree_contains_struct[TRANSLATION_UNIT_DECL][TS_DECL_NON_COMMON] = 1;
tree_contains_struct[TYPE_DECL][TS_DECL_NON_COMMON] = 1;
@@ -347,40 +362,82 @@ decl_assembler_name (tree decl)
/* Compare ASMNAME with the DECL_ASSEMBLER_NAME of DECL. */
bool
-decl_assembler_name_equal (tree decl, tree asmname)
+decl_assembler_name_equal (tree decl, const_tree asmname)
{
tree decl_asmname = DECL_ASSEMBLER_NAME (decl);
+ const char *decl_str;
+ const char *asmname_str;
+ bool test = false;
if (decl_asmname == asmname)
return true;
+ decl_str = IDENTIFIER_POINTER (decl_asmname);
+ asmname_str = IDENTIFIER_POINTER (asmname);
+
+
/* If the target assembler name was set by the user, things are trickier.
We have a leading '*' to begin with. After that, it's arguable what
is the correct thing to do with -fleading-underscore. Arguably, we've
historically been doing the wrong thing in assemble_alias by always
printing the leading underscore. Since we're not changing that, make
sure user_label_prefix follows the '*' before matching. */
- if (IDENTIFIER_POINTER (decl_asmname)[0] == '*')
+ if (decl_str[0] == '*')
+ {
+ size_t ulp_len = strlen (user_label_prefix);
+
+ decl_str ++;
+
+ if (ulp_len == 0)
+ test = true;
+ else if (strncmp (decl_str, user_label_prefix, ulp_len) == 0)
+ decl_str += ulp_len, test=true;
+ else
+ decl_str --;
+ }
+ if (asmname_str[0] == '*')
+ {
+ size_t ulp_len = strlen (user_label_prefix);
+
+ asmname_str ++;
+
+ if (ulp_len == 0)
+ test = true;
+ else if (strncmp (asmname_str, user_label_prefix, ulp_len) == 0)
+ asmname_str += ulp_len, test=true;
+ else
+ asmname_str --;
+ }
+
+ if (!test)
+ return false;
+ return strcmp (decl_str, asmname_str) == 0;
+}
+
+/* Hash asmnames ignoring the user specified marks. */
+
+hashval_t
+decl_assembler_name_hash (const_tree asmname)
+{
+ if (IDENTIFIER_POINTER (asmname)[0] == '*')
{
- const char *decl_str = IDENTIFIER_POINTER (decl_asmname) + 1;
+ const char *decl_str = IDENTIFIER_POINTER (asmname) + 1;
size_t ulp_len = strlen (user_label_prefix);
if (ulp_len == 0)
;
else if (strncmp (decl_str, user_label_prefix, ulp_len) == 0)
decl_str += ulp_len;
- else
- return false;
- return strcmp (decl_str, IDENTIFIER_POINTER (asmname)) == 0;
+ return htab_hash_string (decl_str);
}
- return false;
+ return htab_hash_string (IDENTIFIER_POINTER (asmname));
}
/* Compute the number of bytes occupied by a tree with code CODE.
This function cannot be used for nodes that have variable sizes,
- including TREE_VEC, PHI_NODE, STRING_CST, and CALL_EXPR. */
+ including TREE_VEC, STRING_CST, and CALL_EXPR. */
size_t
tree_code_size (enum tree_code code)
{
@@ -428,10 +485,6 @@ tree_code_size (enum tree_code code)
return (sizeof (struct tree_exp)
+ (TREE_CODE_LENGTH (code) - 1) * sizeof (tree));
- case tcc_gimple_stmt:
- return (sizeof (struct gimple_stmt)
- + (TREE_CODE_LENGTH (code) - 1) * sizeof (char *));
-
case tcc_constant: /* a constant */
switch (code)
{
@@ -455,15 +508,15 @@ tree_code_size (enum tree_code code)
case PLACEHOLDER_EXPR: return sizeof (struct tree_common);
case TREE_VEC:
- case OMP_CLAUSE:
- case PHI_NODE: gcc_unreachable ();
+ case OMP_CLAUSE: gcc_unreachable ();
case SSA_NAME: return sizeof (struct tree_ssa_name);
case STATEMENT_LIST: return sizeof (struct tree_statement_list);
case BLOCK: return sizeof (struct tree_block);
- case VALUE_HANDLE: return sizeof (struct tree_value_handle);
case CONSTRUCTOR: return sizeof (struct tree_constructor);
+ case OPTIMIZATION_NODE: return sizeof (struct tree_optimization_option);
+ case TARGET_OPTION_NODE: return sizeof (struct tree_target_option);
default:
return lang_hooks.tree_size (code);
@@ -482,10 +535,6 @@ tree_size (const_tree node)
const enum tree_code code = TREE_CODE (node);
switch (code)
{
- case PHI_NODE:
- return (sizeof (struct tree_phi_node)
- + (PHI_ARG_CAPACITY (node) - 1) * sizeof (struct phi_arg_d));
-
case TREE_BINFO:
return (offsetof (struct tree_binfo, base_binfos)
+ VEC_embedded_size (tree, BINFO_N_BASE_BINFOS (node)));
@@ -513,9 +562,8 @@ tree_size (const_tree node)
/* Return a newly allocated node of code CODE. For decl and type
nodes, some other fields are initialized. The rest of the node is
- initialized to zero. This function cannot be used for PHI_NODE,
- TREE_VEC or OMP_CLAUSE nodes, which is enforced by asserts in
- tree_code_size.
+ initialized to zero. This function cannot be used for TREE_VEC or
+ OMP_CLAUSE nodes, which is enforced by asserts in tree_code_size.
Achoo! I got a code in the node. */
@@ -557,10 +605,6 @@ make_node_stat (enum tree_code code MEM_STAT_DECL)
kind = c_kind;
break;
- case tcc_gimple_stmt:
- kind = gimple_stmt_kind;
- break;
-
case tcc_exceptional: /* something random, like an identifier. */
switch (code)
{
@@ -576,10 +620,6 @@ make_node_stat (enum tree_code code MEM_STAT_DECL)
kind = binfo_kind;
break;
- case PHI_NODE:
- kind = phi_kind;
- break;
-
case SSA_NAME:
kind = ssa_name_kind;
break;
@@ -622,8 +662,6 @@ make_node_stat (enum tree_code code MEM_STAT_DECL)
break;
case tcc_declaration:
- if (CODE_CONTAINS_STRUCT (code, TS_DECL_WITH_VIS))
- DECL_IN_SYSTEM_HEADER (t) = in_system_header;
if (CODE_CONTAINS_STRUCT (code, TS_DECL_COMMON))
{
if (code == FUNCTION_DECL)
@@ -680,17 +718,6 @@ make_node_stat (enum tree_code code MEM_STAT_DECL)
}
break;
- case tcc_gimple_stmt:
- switch (code)
- {
- case GIMPLE_MODIFY_STMT:
- TREE_SIDE_EFFECTS (t) = 1;
- break;
-
- default:
- break;
- }
-
default:
/* Other classes need no special treatment. */
break;
@@ -715,8 +742,7 @@ copy_node_stat (tree node MEM_STAT_DECL)
t = (tree) ggc_alloc_zone_pass_stat (length, &tree_zone);
memcpy (t, node, length);
- if (!GIMPLE_TUPLE_P (node))
- TREE_CHAIN (t) = 0;
+ TREE_CHAIN (t) = 0;
TREE_ASM_WRITTEN (t) = 0;
TREE_VISITED (t) = 0;
t->base.ann = 0;
@@ -1984,10 +2010,6 @@ expr_align (const_tree t)
align1 = TYPE_ALIGN (TREE_TYPE (t));
return MAX (align0, align1);
- case GIMPLE_MODIFY_STMT:
- /* We should never ask for the alignment of a gimple statement. */
- gcc_unreachable ();
-
case SAVE_EXPR: case COMPOUND_EXPR: case MODIFY_EXPR:
case INIT_EXPR: case TARGET_EXPR: case WITH_CLEANUP_EXPR:
case CLEANUP_POINT_EXPR:
@@ -2359,8 +2381,6 @@ tree_node_structure (const_tree t)
case tcc_statement:
case tcc_vl_exp:
return TS_EXP;
- case tcc_gimple_stmt:
- return TS_GIMPLE_STATEMENT;
default: /* tcc_constant and tcc_exceptional */
break;
}
@@ -2374,21 +2394,19 @@ tree_node_structure (const_tree t)
case VECTOR_CST: return TS_VECTOR;
case STRING_CST: return TS_STRING;
/* tcc_exceptional cases. */
- /* FIXME tuples: eventually this should be TS_BASE. For now, nothing
- returns TS_BASE. */
case ERROR_MARK: return TS_COMMON;
case IDENTIFIER_NODE: return TS_IDENTIFIER;
case TREE_LIST: return TS_LIST;
case TREE_VEC: return TS_VEC;
- case PHI_NODE: return TS_PHI_NODE;
case SSA_NAME: return TS_SSA_NAME;
case PLACEHOLDER_EXPR: return TS_COMMON;
case STATEMENT_LIST: return TS_STATEMENT_LIST;
case BLOCK: return TS_BLOCK;
case CONSTRUCTOR: return TS_CONSTRUCTOR;
case TREE_BINFO: return TS_BINFO;
- case VALUE_HANDLE: return TS_VALUE_HANDLE;
case OMP_CLAUSE: return TS_OMP_CLAUSE;
+ case OPTIMIZATION_NODE: return TS_OPTIMIZATION;
+ case TARGET_OPTION_NODE: return TS_TARGET_OPTION;
default:
gcc_unreachable ();
@@ -3229,15 +3247,6 @@ build2_stat (enum tree_code code, tree tt, tree arg0, tree arg1 MEM_STAT_DECL)
gcc_assert (TREE_CODE_LENGTH (code) == 2);
-#if 1
- /* FIXME tuples: Statement's aren't expressions! */
- if (code == GIMPLE_MODIFY_STMT)
- return build_gimple_modify_stmt_stat (arg0, arg1 PASS_MEM_STAT);
-#else
- /* Must use build_gimple_modify_stmt to construct GIMPLE_MODIFY_STMTs. */
- gcc_assert (code != GIMPLE_MODIFY_STMT);
-#endif
-
if ((code == MINUS_EXPR || code == PLUS_EXPR || code == MULT_EXPR)
&& arg0 && arg1 && tt && POINTER_TYPE_P (tt))
gcc_assert (TREE_CODE (arg0) == INTEGER_CST && TREE_CODE (arg1) == INTEGER_CST);
@@ -3276,21 +3285,6 @@ build2_stat (enum tree_code code, tree tt, tree arg0, tree arg1 MEM_STAT_DECL)
}
-/* Build a GIMPLE_MODIFY_STMT node. This tree code doesn't have a
- type, so we can't use build2 (a.k.a. build2_stat). */
-
-tree
-build_gimple_modify_stmt_stat (tree arg0, tree arg1 MEM_STAT_DECL)
-{
- tree t;
-
- t = make_node_stat (GIMPLE_MODIFY_STMT PASS_MEM_STAT);
- /* ?? We don't care about setting flags for tuples... */
- GIMPLE_STMT_OPERAND (t, 0) = arg0;
- GIMPLE_STMT_OPERAND (t, 1) = arg1;
- return t;
-}
-
tree
build3_stat (enum tree_code code, tree tt, tree arg0, tree arg1,
tree arg2 MEM_STAT_DECL)
@@ -3524,6 +3518,7 @@ expand_location (source_location loc)
xloc.file = NULL;
xloc.line = 0;
xloc.column = 0;
+ xloc.sysp = 0;
}
else
{
@@ -3531,6 +3526,7 @@ expand_location (source_location loc)
xloc.file = map->to_file;
xloc.line = SOURCE_LINE (map, loc);
xloc.column = SOURCE_COLUMN (map, loc);
+ xloc.sysp = map->sysp != 0;
};
return xloc;
}
@@ -3539,79 +3535,14 @@ expand_location (source_location loc)
/* Source location accessor functions. */
-/* The source location of this expression. Non-tree_exp nodes such as
- decls and constants can be shared among multiple locations, so
- return nothing. */
-location_t
-expr_location (const_tree node)
-{
- if (GIMPLE_STMT_P (node))
- return GIMPLE_STMT_LOCUS (node);
- return EXPR_P (node) ? node->exp.locus : UNKNOWN_LOCATION;
-}
-
-void
-set_expr_location (tree node, location_t locus)
-{
- if (GIMPLE_STMT_P (node))
- GIMPLE_STMT_LOCUS (node) = locus;
- else
- EXPR_CHECK (node)->exp.locus = locus;
-}
-
-bool
-expr_has_location (const_tree node)
-{
- return expr_location (node) != UNKNOWN_LOCATION;
-}
-
-source_location *
-expr_locus (const_tree node)
-{
- if (GIMPLE_STMT_P (node))
- return CONST_CAST (source_location *, &GIMPLE_STMT_LOCUS (node));
- return (EXPR_P (node)
- ? CONST_CAST (source_location *, &node->exp.locus)
- : (source_location *) NULL);
-}
-
void
set_expr_locus (tree node, source_location *loc)
{
if (loc == NULL)
- {
- if (GIMPLE_STMT_P (node))
- GIMPLE_STMT_LOCUS (node) = UNKNOWN_LOCATION;
- else
- EXPR_CHECK (node)->exp.locus = UNKNOWN_LOCATION;
- }
+ EXPR_CHECK (node)->exp.locus = UNKNOWN_LOCATION;
else
- {
- if (GIMPLE_STMT_P (node))
- GIMPLE_STMT_LOCUS (node) = *loc;
- else
- EXPR_CHECK (node)->exp.locus = *loc;
- }
-}
-
-/* Return the file name of the location of NODE. */
-const char *
-expr_filename (const_tree node)
-{
- if (GIMPLE_STMT_P (node))
- return LOCATION_FILE (GIMPLE_STMT_LOCUS (node));
- return LOCATION_FILE (EXPR_CHECK (node)->exp.locus);
+ EXPR_CHECK (node)->exp.locus = *loc;
}
-
-/* Return the line number of the location of NODE. */
-int
-expr_lineno (const_tree node)
-{
- if (GIMPLE_STMT_P (node))
- return LOCATION_LINE (GIMPLE_STMT_LOCUS (node));
- return LOCATION_LINE (EXPR_CHECK (node)->exp.locus);
-}
-
/* Return a declaration like DDECL except that its DECL_ATTRIBUTES
is ATTRIBUTE. */
@@ -3639,7 +3570,7 @@ build_decl_attribute_variant (tree ddecl, tree attribute)
/* Produce good hash value combining VAL and VAL2. */
-static inline hashval_t
+hashval_t
iterative_hash_hashval_t (hashval_t val, hashval_t val2)
{
/* the golden ratio; an arbitrary value. */
@@ -5312,7 +5243,7 @@ commutative_tree_code (enum tree_code code)
}
/* Generate a hash value for an expression. This can be used iteratively
- by passing a previous result as the "val" argument.
+ by passing a previous result as the VAL argument.
This function is intended to produce the same hash for expressions which
would compare equal using operand_equal_p. */
@@ -5358,7 +5289,6 @@ iterative_hash_expr (const_tree t, hashval_t val)
return iterative_hash_expr (TREE_VECTOR_CST_ELTS (t), val);
case SSA_NAME:
- case VALUE_HANDLE:
/* we can just compare by pointer. */
return iterative_hash_pointer (t, val);
@@ -5441,6 +5371,29 @@ iterative_hash_expr (const_tree t, hashval_t val)
break;
}
}
+
+/* Generate a hash value for a pair of expressions. This can be used
+ iteratively by passing a previous result as the VAL argument.
+
+ The same hash value is always returned for a given pair of expressions,
+ regardless of the order in which they are presented. This is useful in
+ hashing the operands of commutative functions. */
+
+hashval_t
+iterative_hash_exprs_commutative (const_tree t1,
+ const_tree t2, hashval_t val)
+{
+ hashval_t one = iterative_hash_expr (t1, 0);
+ hashval_t two = iterative_hash_expr (t2, 0);
+ hashval_t t;
+
+ if (one > two)
+ t = one, one = two, two = t;
+ val = iterative_hash_hashval_t (one, val);
+ val = iterative_hash_hashval_t (two, val);
+
+ return val;
+}
/* Constructors for pointer, array and function types.
(RECORD_TYPE, UNION_TYPE and ENUMERAL_TYPE nodes are
@@ -5460,6 +5413,11 @@ build_pointer_type_for_mode (tree to_type, enum machine_mode mode,
if (to_type == error_mark_node)
return error_mark_node;
+ /* If the pointed-to type has the may_alias attribute set, force
+ a TYPE_REF_CAN_ALIAS_ALL pointer to be generated. */
+ if (lookup_attribute ("may_alias", TYPE_ATTRIBUTES (to_type)))
+ can_alias_all = true;
+
/* In some cases, languages will have things that aren't a POINTER_TYPE
(such as a RECORD_TYPE for fat pointers in Ada) as TYPE_POINTER_TO.
In that case, return that type without regard to the rest of our
@@ -5516,6 +5474,14 @@ build_reference_type_for_mode (tree to_type, enum machine_mode mode,
{
tree t;
+ if (to_type == error_mark_node)
+ return error_mark_node;
+
+ /* If the pointed-to type has the may_alias attribute set, force
+ a TYPE_REF_CAN_ALIAS_ALL pointer to be generated. */
+ if (lookup_attribute ("may_alias", TYPE_ATTRIBUTES (to_type)))
+ can_alias_all = true;
+
/* In some cases, languages will have things that aren't a REFERENCE_TYPE
(such as a RECORD_TYPE for fat pointers in Ada) as TYPE_REFERENCE_TO.
In that case, return that type without regard to the rest of our
@@ -6415,8 +6381,7 @@ get_type_static_bounds (const_tree type, mpz_t min, mpz_t max)
}
}
-/* auto_var_in_fn_p is called to determine whether VAR is an automatic
- variable defined in function FN. */
+/* Return true if VAR is an automatic variable defined in function FN. */
bool
auto_var_in_fn_p (const_tree var, const_tree fn)
@@ -7054,18 +7019,6 @@ tree_vec_elt_check_failed (int idx, int len, const char *file, int line,
idx + 1, len, function, trim_filename (file), line);
}
-/* Similar to above, except that the check is for the bounds of a PHI_NODE's
- (dynamically sized) vector. */
-
-void
-phi_node_elt_check_failed (int idx, int len, const char *file, int line,
- const char *function)
-{
- internal_error
- ("tree check: accessed elt %d of phi_node with %d elts in %s, at %s:%d",
- idx + 1, len, function, trim_filename (file), line);
-}
-
/* Similar to above, except that the check is for the bounds of the operand
vector of an expression node EXP. */
@@ -8616,6 +8569,10 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data,
WALK_SUBTREE_TAIL (TREE_OPERAND (*tp, len));
}
+ case CHANGE_DYNAMIC_TYPE_EXPR:
+ WALK_SUBTREE (CHANGE_DYNAMIC_TYPE_NEW_TYPE (*tp));
+ WALK_SUBTREE_TAIL (CHANGE_DYNAMIC_TYPE_LOCATION (*tp));
+
case DECL_EXPR:
/* If this is a TYPE_DECL, walk into the fields of the type that it's
defining. We only want to walk into these fields of a type in this
@@ -8687,8 +8644,7 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data,
/* FALLTHRU */
default:
- if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (code))
- || IS_GIMPLE_STMT_CODE_CLASS (TREE_CODE_CLASS (code)))
+ if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (code)))
{
int i, len;
@@ -8700,8 +8656,8 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data,
if (len)
{
for (i = 0; i < len - 1; ++i)
- WALK_SUBTREE (GENERIC_TREE_OPERAND (*tp, i));
- WALK_SUBTREE_TAIL (GENERIC_TREE_OPERAND (*tp, len - 1));
+ WALK_SUBTREE (TREE_OPERAND (*tp, i));
+ WALK_SUBTREE_TAIL (TREE_OPERAND (*tp, len - 1));
}
}
/* If this is a type, walk the needed fields in the type. */
@@ -8733,31 +8689,6 @@ walk_tree_without_duplicates_1 (tree *tp, walk_tree_fn func, void *data,
}
-/* Return true if STMT is an empty statement or contains nothing but
- empty statements. */
-
-bool
-empty_body_p (tree stmt)
-{
- tree_stmt_iterator i;
- tree body;
-
- if (IS_EMPTY_STMT (stmt))
- return true;
- else if (TREE_CODE (stmt) == BIND_EXPR)
- body = BIND_EXPR_BODY (stmt);
- else if (TREE_CODE (stmt) == STATEMENT_LIST)
- body = stmt;
- else
- return false;
-
- for (i = tsi_start (body); !tsi_end_p (i); tsi_next (&i))
- if (!empty_body_p (tsi_stmt (i)))
- return false;
-
- return true;
-}
-
tree *
tree_block (tree t)
{
@@ -8765,28 +8696,10 @@ tree_block (tree t)
if (IS_EXPR_CODE_CLASS (c))
return &t->exp.block;
- else if (IS_GIMPLE_STMT_CODE_CLASS (c))
- return &GIMPLE_STMT_BLOCK (t);
gcc_unreachable ();
return NULL;
}
-tree *
-generic_tree_operand (tree node, int i)
-{
- if (GIMPLE_STMT_P (node))
- return &GIMPLE_STMT_OPERAND (node, i);
- return &TREE_OPERAND (node, i);
-}
-
-tree *
-generic_tree_type (tree node)
-{
- if (GIMPLE_STMT_P (node))
- return &void_type_node;
- return &TREE_TYPE (node);
-}
-
/* Build and return a TREE_LIST of arguments in the CALL_EXPR exp.
FIXME: don't use this function. It exists for compatibility with
the old representation of CALL_EXPRs where a list was used to hold the
@@ -8802,6 +8715,46 @@ call_expr_arglist (tree exp)
return arglist;
}
+
+/* Create a nameless artificial label and put it in the current function
+ context. Returns the newly created label. */
+
+tree
+create_artificial_label (void)
+{
+ tree lab = build_decl (LABEL_DECL, NULL_TREE, void_type_node);
+
+ DECL_ARTIFICIAL (lab) = 1;
+ DECL_IGNORED_P (lab) = 1;
+ DECL_CONTEXT (lab) = current_function_decl;
+ return lab;
+}
+
+/* Given a tree, try to return a useful variable name that we can use
+ to prefix a temporary that is being assigned the value of the tree.
+ I.E. given <temp> = &A, return A. */
+
+const char *
+get_name (tree t)
+{
+ tree stripped_decl;
+
+ stripped_decl = t;
+ STRIP_NOPS (stripped_decl);
+ if (DECL_P (stripped_decl) && DECL_NAME (stripped_decl))
+ return IDENTIFIER_POINTER (DECL_NAME (stripped_decl));
+ else
+ {
+ switch (TREE_CODE (stripped_decl))
+ {
+ case ADDR_EXPR:
+ return get_name (TREE_OPERAND (stripped_decl, 0));
+ default:
+ return NULL;
+ }
+ }
+}
+
/* Return true if TYPE has a variable argument list. */
bool
@@ -8890,4 +8843,132 @@ block_nonartificial_location (tree block)
return ret;
}
+/* These are the hash table functions for the hash table of OPTIMIZATION_NODEq
+ nodes. */
+
+/* Return the hash code code X, an OPTIMIZATION_NODE or TARGET_OPTION code. */
+
+static hashval_t
+cl_option_hash_hash (const void *x)
+{
+ const_tree const t = (const_tree) x;
+ const char *p;
+ size_t i;
+ size_t len = 0;
+ hashval_t hash = 0;
+
+ if (TREE_CODE (t) == OPTIMIZATION_NODE)
+ {
+ p = (const char *)TREE_OPTIMIZATION (t);
+ len = sizeof (struct cl_optimization);
+ }
+
+ else if (TREE_CODE (t) == TARGET_OPTION_NODE)
+ {
+ p = (const char *)TREE_TARGET_OPTION (t);
+ len = sizeof (struct cl_target_option);
+ }
+
+ else
+ gcc_unreachable ();
+
+ /* assume most opt flags are just 0/1, some are 2-3, and a few might be
+ something else. */
+ for (i = 0; i < len; i++)
+ if (p[i])
+ hash = (hash << 4) ^ ((i << 2) | p[i]);
+
+ return hash;
+}
+
+/* Return nonzero if the value represented by *X (an OPTIMIZATION or
+ TARGET_OPTION tree node) is the same as that given by *Y, which is the
+ same. */
+
+static int
+cl_option_hash_eq (const void *x, const void *y)
+{
+ const_tree const xt = (const_tree) x;
+ const_tree const yt = (const_tree) y;
+ const char *xp;
+ const char *yp;
+ size_t len;
+
+ if (TREE_CODE (xt) != TREE_CODE (yt))
+ return 0;
+
+ if (TREE_CODE (xt) == OPTIMIZATION_NODE)
+ {
+ xp = (const char *)TREE_OPTIMIZATION (xt);
+ yp = (const char *)TREE_OPTIMIZATION (yt);
+ len = sizeof (struct cl_optimization);
+ }
+
+ else if (TREE_CODE (xt) == TARGET_OPTION_NODE)
+ {
+ xp = (const char *)TREE_TARGET_OPTION (xt);
+ yp = (const char *)TREE_TARGET_OPTION (yt);
+ len = sizeof (struct cl_target_option);
+ }
+
+ else
+ gcc_unreachable ();
+
+ return (memcmp (xp, yp, len) == 0);
+}
+
+/* Build an OPTIMIZATION_NODE based on the current options. */
+
+tree
+build_optimization_node (void)
+{
+ tree t;
+ void **slot;
+
+ /* Use the cache of optimization nodes. */
+
+ cl_optimization_save (TREE_OPTIMIZATION (cl_optimization_node));
+
+ slot = htab_find_slot (cl_option_hash_table, cl_optimization_node, INSERT);
+ t = (tree) *slot;
+ if (!t)
+ {
+ /* Insert this one into the hash table. */
+ t = cl_optimization_node;
+ *slot = t;
+
+ /* Make a new node for next time round. */
+ cl_optimization_node = make_node (OPTIMIZATION_NODE);
+ }
+
+ return t;
+}
+
+/* Build a TARGET_OPTION_NODE based on the current options. */
+
+tree
+build_target_option_node (void)
+{
+ tree t;
+ void **slot;
+
+ /* Use the cache of optimization nodes. */
+
+ cl_target_option_save (TREE_TARGET_OPTION (cl_target_option_node));
+
+ slot = htab_find_slot (cl_option_hash_table, cl_target_option_node, INSERT);
+ t = (tree) *slot;
+ if (!t)
+ {
+ /* Insert this one into the hash table. */
+ t = cl_target_option_node;
+ *slot = t;
+
+ /* Make a new node for next time round. */
+ cl_target_option_node = make_node (TARGET_OPTION_NODE);
+ }
+
+ return t;
+}
+
#include "gt-tree.h"
diff --git a/gcc/tree.def b/gcc/tree.def
index 7474f2e68f1..e9c891754bb 100644
--- a/gcc/tree.def
+++ b/gcc/tree.def
@@ -882,14 +882,6 @@ DEFTREECODE (ASM_EXPR, "asm_expr", tcc_statement, 4)
nodes to implement SSA versioning. */
DEFTREECODE (SSA_NAME, "ssa_name", tcc_exceptional, 0)
-/* SSA PHI operator. PHI_RESULT is the new SSA_NAME node created by
- the PHI node. PHI_ARG_LENGTH is the number of arguments.
- PHI_ARG_ELT returns the Ith tuple <ssa_name, edge> from the
- argument list. Each tuple contains the incoming reaching
- definition (SSA_NAME node) and the edge via which that definition
- is coming through. */
-DEFTREECODE (PHI_NODE, "phi_node", tcc_exceptional, 0)
-
/* Used to represent a typed exception handler. CATCH_TYPES is the type (or
list of types) handled, and CATCH_BODY is the code for the handler. */
DEFTREECODE (CATCH_EXPR, "catch_expr", tcc_statement, 2)
@@ -925,12 +917,6 @@ DEFTREECODE (POLYNOMIAL_CHREC, "polynomial_chrec", tcc_expression, 3)
Use the interface in tree-iterator.h to access this node. */
DEFTREECODE (STATEMENT_LIST, "statement_list", tcc_exceptional, 0)
-/* Value handles. Artificial nodes to represent expressions in
- partial redundancy elimination (tree-ssa-pre.c). These nodes are
- used for expression canonicalization. If two expressions compute
- the same value, they will be assigned the same value handle. */
-DEFTREECODE (VALUE_HANDLE, "value_handle", tcc_exceptional, 0)
-
/* Predicate assertion. Artificial expression generated by the optimizers
to keep track of predicate values. This expression may only appear on
the RHS of assignments.
@@ -991,32 +977,15 @@ DEFTREECODE (TARGET_MEM_REF, "target_mem_ref", tcc_reference, 7)
exposed to TREE_RANGE_CHECK. */
/* OpenMP - #pragma omp parallel [clause1 ... clauseN]
Operand 0: OMP_PARALLEL_BODY: Code to be executed by all threads.
- Operand 1: OMP_PARALLEL_CLAUSES: List of clauses.
- Operand 2: OMP_PARALLEL_FN: FUNCTION_DECL used when outlining the
- body of the parallel region. Only valid after
- pass_lower_omp.
- Operand 3: OMP_PARALLEL_DATA_ARG: Local variable in the parent
- function containing data to be shared with the child
- function. */
+ Operand 1: OMP_PARALLEL_CLAUSES: List of clauses. */
-DEFTREECODE (OMP_PARALLEL, "omp_parallel", tcc_statement, 4)
+DEFTREECODE (OMP_PARALLEL, "omp_parallel", tcc_statement, 2)
/* OpenMP - #pragma omp task [clause1 ... clauseN]
Operand 0: OMP_TASK_BODY: Code to be executed by all threads.
- Operand 1: OMP_TASK_CLAUSES: List of clauses.
- Operand 2: OMP_TASK_FN: FUNCTION_DECL used when outlining the
- body of the task region. Only valid after
- pass_lower_omp.
- Operand 3: OMP_TASK_DATA_ARG: Local variable in the parent
- function containing data to be shared with the child
- function.
- Operand 4: OMP_TASK_COPYFN: FUNCTION_DECL used for constructing
- firstprivate variables.
- Operand 5: OMP_TASK_ARG_SIZE: Length of the task argument block.
- Operand 6: OMP_TASK_ARG_ALIGN: Required alignment of the task
- argument block. */
-
-DEFTREECODE (OMP_TASK, "omp_task", tcc_statement, 7)
+ Operand 1: OMP_TASK_CLAUSES: List of clauses. */
+
+DEFTREECODE (OMP_TASK, "omp_task", tcc_statement, 2)
/* OpenMP - #pragma omp for [clause1 ... clauseN]
Operand 0: OMP_FOR_BODY: Loop body.
@@ -1032,7 +1001,7 @@ DEFTREECODE (OMP_TASK, "omp_task", tcc_statement, 7)
OMP_FOR structured block, but are evaluated before the loop
body begins.
- VAR must be a signed integer variable, which is implicitly thread
+ VAR must be an integer or pointer variable, which is implicitly thread
private. N1, N2 and INCR are required to be loop invariant integer
expressions that are evaluated without any synchronization.
The evaluation order, frequency of evaluation and side-effects are
@@ -1041,14 +1010,8 @@ DEFTREECODE (OMP_FOR, "omp_for", tcc_statement, 6)
/* OpenMP - #pragma omp sections [clause1 ... clauseN]
Operand 0: OMP_SECTIONS_BODY: Sections body.
- Operand 1: OMP_SECTIONS_CLAUSES: List of clauses.
- Operand 2: OMP_SECTIONS_CONTROL: The control variable used for deciding
- which of the sections to execute. */
-DEFTREECODE (OMP_SECTIONS, "omp_sections", tcc_statement, 3)
-
-/* This tree immediately follows OMP_SECTIONS, and represents the switch
- used to decide which branch is taken. */
-DEFTREECODE (OMP_SECTIONS_SWITCH, "omp_sections_switch", tcc_statement, 0)
+ Operand 1: OMP_SECTIONS_CLAUSES: List of clauses. */
+DEFTREECODE (OMP_SECTIONS, "omp_sections", tcc_statement, 2)
/* OpenMP - #pragma omp single
Operand 0: OMP_SINGLE_BODY: Single section body.
@@ -1072,14 +1035,6 @@ DEFTREECODE (OMP_ORDERED, "omp_ordered", tcc_statement, 1)
Operand 1: OMP_CRITICAL_NAME: Identifier for critical section. */
DEFTREECODE (OMP_CRITICAL, "omp_critical", tcc_statement, 2)
-/* Return from an OpenMP directive. */
-DEFTREECODE (OMP_RETURN, "omp_return", tcc_statement, 0)
-
-/* OpenMP - An intermediate tree code to mark the location of the
- loop or sections iteration in the partially lowered code.
- The arguments are definition and use of the control variable. */
-DEFTREECODE (OMP_CONTINUE, "omp_continue", tcc_statement, 2)
-
/* OpenMP - #pragma omp atomic
Operand 0: The address at which the atomic operation is to be performed.
This address should be stabilized with save_expr.
@@ -1088,18 +1043,6 @@ DEFTREECODE (OMP_CONTINUE, "omp_continue", tcc_statement, 2)
build_fold_indirect_ref of the address. */
DEFTREECODE (OMP_ATOMIC, "omp_atomic", tcc_statement, 2)
-/* Codes used for lowering of OMP_ATOMIC. Although the form of the OMP_ATOMIC
- statement is very simple (just in form mem op= expr), various implicit
- conversions may cause the expression become more complex, so that it does
- not fit the gimple grammar very well. To overcome this problem, OMP_ATOMIC
- is rewritten as a sequence of two codes in gimplification:
-
- OMP_LOAD (tmp, mem)
- val = some computations involving tmp;
- OMP_STORE (val) */
-DEFTREECODE (OMP_ATOMIC_LOAD, "omp_atomic_load", tcc_statement, 2)
-DEFTREECODE (OMP_ATOMIC_STORE, "omp_atomic_store", tcc_statement, 1)
-
/* OpenMP clauses. */
DEFTREECODE (OMP_CLAUSE, "omp_clause", tcc_exceptional, 0)
@@ -1146,11 +1089,6 @@ DEFTREECODE (WIDEN_MULT_EXPR, "widen_mult_expr", tcc_binary, 2)
DEFTREECODE (VEC_LSHIFT_EXPR, "vec_lshift_expr", tcc_binary, 2)
DEFTREECODE (VEC_RSHIFT_EXPR, "vec_rshift_expr", tcc_binary, 2)
-/* GIMPLE tree codes. */
-
-/* Assignment expression. Operand 0 is the what to set; 1, the new value. */
-DEFTREECODE (GIMPLE_MODIFY_STMT, "gimple_modify_stmt", tcc_gimple_stmt, 2)
-
/* Widening vector multiplication.
The two operands are vectors with N elements of size S. Multiplying the
elements of the two vectors will result in N products of size 2*S.
@@ -1200,6 +1138,13 @@ DEFTREECODE (VEC_INTERLEAVE_LOW_EXPR, "vec_interleavelow_expr", tcc_binary, 2)
all conditional branches leading to execution paths executing the
PREDICT_EXPR will get predicted by the specified predictor. */
DEFTREECODE (PREDICT_EXPR, "predict_expr", tcc_unary, 1)
+
+/* OPTIMIZATION_NODE. Node to store the optimization options. */
+DEFTREECODE (OPTIMIZATION_NODE, "optimization_node", tcc_exceptional, 0)
+
+/* TARGET_OPTION_NODE. Node to store the target specific options. */
+DEFTREECODE (TARGET_OPTION_NODE, "target_option_node", tcc_exceptional, 0)
+
/*
Local variables:
mode:c
diff --git a/gcc/tree.h b/gcc/tree.h
index 49c05666393..2fb05ae310f 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -29,6 +29,7 @@ along with GCC; see the file COPYING3. If not see
#include "vec.h"
#include "double-int.h"
#include "alias.h"
+#include "options.h"
/* Codes of tree nodes */
@@ -68,8 +69,7 @@ enum tree_code_class {
but usually no interesting value. */
tcc_vl_exp, /* A function call or other expression with a
variable-length operand vector. */
- tcc_expression, /* Any other expression. */
- tcc_gimple_stmt /* A GIMPLE statement. */
+ tcc_expression /* Any other expression. */
};
/* Each tree code class has an associated string representation.
@@ -173,32 +173,10 @@ extern const enum tree_code_class tree_code_type[];
#define IS_EXPR_CODE_CLASS(CLASS)\
((CLASS) >= tcc_reference && (CLASS) <= tcc_expression)
-/* Returns nonzero iff CLASS is a GIMPLE statement. */
-
-#define IS_GIMPLE_STMT_CODE_CLASS(CLASS) ((CLASS) == tcc_gimple_stmt)
-
/* Returns nonzero iff NODE is an expression of some kind. */
#define EXPR_P(NODE) IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (NODE)))
-/* Returns nonzero iff NODE is an OpenMP directive. */
-
-#define OMP_DIRECTIVE_P(NODE) \
- (TREE_CODE (NODE) == OMP_PARALLEL \
- || TREE_CODE (NODE) == OMP_TASK \
- || TREE_CODE (NODE) == OMP_FOR \
- || TREE_CODE (NODE) == OMP_SECTIONS \
- || TREE_CODE (NODE) == OMP_SECTIONS_SWITCH \
- || TREE_CODE (NODE) == OMP_SINGLE \
- || TREE_CODE (NODE) == OMP_SECTION \
- || TREE_CODE (NODE) == OMP_MASTER \
- || TREE_CODE (NODE) == OMP_ORDERED \
- || TREE_CODE (NODE) == OMP_CRITICAL \
- || TREE_CODE (NODE) == OMP_RETURN \
- || TREE_CODE (NODE) == OMP_ATOMIC_LOAD \
- || TREE_CODE (NODE) == OMP_ATOMIC_STORE \
- || TREE_CODE (NODE) == OMP_CONTINUE)
-
/* Number of argument-words in each kind of tree-node. */
extern const unsigned char tree_code_length[];
@@ -406,8 +384,6 @@ struct tree_base GTY(())
unsigned spare : 23;
- /* FIXME tuples: Eventually, we need to move this somewhere external to
- the trees. */
union tree_ann_d *ann;
};
@@ -418,16 +394,6 @@ struct tree_common GTY(())
tree type;
};
-/* GIMPLE_MODIFY_STMT */
-struct gimple_stmt GTY(())
-{
- struct tree_base base;
- location_t locus;
- tree block;
- /* FIXME tuples: Eventually this should be of type ``struct gimple_expr''. */
- tree GTY ((length ("TREE_CODE_LENGTH (TREE_CODE (&%h))"))) operands[1];
-};
-
/* The following table lists the uses of each of the above flags and
for which types of nodes they are defined.
@@ -477,7 +443,7 @@ struct gimple_stmt GTY(())
POINTER_TYPE, REFERENCE_TYPE
MOVE_NONTEMPORAL in
- GIMPLE_MODIFY_STMT
+ MODIFY_EXPR
CASE_HIGH_SEEN in
CASE_LABEL_EXPR
@@ -523,9 +489,6 @@ struct gimple_stmt GTY(())
DECL_BY_REFERENCE in
PARM_DECL, RESULT_DECL
- OMP_RETURN_NOWAIT in
- OMP_RETURN
-
OMP_SECTION_LAST in
OMP_SECTION
@@ -815,14 +778,6 @@ enum tree_node_structure_enum {
__FUNCTION__); \
__t; })
-#define GIMPLE_STMT_CHECK(T) __extension__ \
-({ __typeof (T) const __t = (T); \
- char const __c = TREE_CODE_CLASS (TREE_CODE (__t)); \
- if (!IS_GIMPLE_STMT_CODE_CLASS (__c)) \
- tree_class_check_failed (__t, tcc_gimple_stmt, __FILE__, __LINE__,\
- __FUNCTION__); \
- __t; })
-
/* These checks have to be special cased. */
#define NON_TYPE_CHECK(T) __extension__ \
({ __typeof (T) const __t = (T); \
@@ -842,17 +797,6 @@ enum tree_node_structure_enum {
__FILE__, __LINE__, __FUNCTION__); \
&__t->vec.a[__i]; }))
-#define PHI_NODE_ELT_CHECK(T, I) __extension__ \
-(*({__typeof (T) const __t = (T); \
- const int __i = (I); \
- if (TREE_CODE (__t) != PHI_NODE) \
- tree_check_failed (__t, __FILE__, __LINE__, __FUNCTION__, \
- PHI_NODE, 0); \
- if (__i < 0 || __i >= __t->phi.capacity) \
- phi_node_elt_check_failed (__i, __t->phi.num_args, \
- __FILE__, __LINE__, __FUNCTION__); \
- &__t->phi.a[__i]; }))
-
#define OMP_CLAUSE_ELT_CHECK(T, I) __extension__ \
(*({__typeof (T) const __t = (T); \
const int __i = (I); \
@@ -868,8 +812,6 @@ enum tree_node_structure_enum {
#define TREE_OPERAND_CHECK(T, I) __extension__ \
(*({__typeof (T) const __t = EXPR_CHECK (T); \
const int __i = (I); \
- if (GIMPLE_TUPLE_P (__t)) \
- gcc_unreachable (); \
if (__i < 0 || __i >= TREE_OPERAND_LENGTH (__t)) \
tree_operand_check_failed (__i, __t, \
__FILE__, __LINE__, __FUNCTION__); \
@@ -885,15 +827,6 @@ enum tree_node_structure_enum {
__FILE__, __LINE__, __FUNCTION__); \
&__t->exp.operands[__i]; }))
-/* Special checks for GIMPLE_STMT_OPERANDs. */
-#define GIMPLE_STMT_OPERAND_CHECK(T, I) __extension__ \
-(*({__typeof (T) const __t = GIMPLE_STMT_CHECK (T); \
- const int __i = (I); \
- if (__i < 0 || __i >= TREE_OPERAND_LENGTH (__t)) \
- tree_operand_check_failed (__i, __t, \
- __FILE__, __LINE__, __FUNCTION__); \
- &__t->gstmt.operands[__i]; }))
-
#define TREE_RTL_OPERAND_CHECK(T, CODE, I) __extension__ \
(*(rtx *) \
({__typeof (T) const __t = (T); \
@@ -916,8 +849,6 @@ enum tree_node_structure_enum {
#define TREE_CHAIN(NODE) __extension__ \
(*({__typeof (NODE) const __t = (NODE); \
- if (GIMPLE_TUPLE_P (__t)) \
- gcc_unreachable (); \
&__t->common.chain; }))
/* In all nodes that are expressions, this is the data type of the expression.
@@ -926,8 +857,6 @@ enum tree_node_structure_enum {
In VECTOR_TYPE nodes, this is the type of the elements. */
#define TREE_TYPE(NODE) __extension__ \
(*({__typeof (NODE) const __t = (NODE); \
- if (GIMPLE_TUPLE_P (__t)) \
- gcc_unreachable (); \
&__t->common.type; }))
extern void tree_contains_struct_check_failed (const_tree,
@@ -985,14 +914,11 @@ extern void omp_clause_range_check_failed (const_tree, const char *, int,
#define TREE_CLASS_CHECK(T, CODE) (T)
#define TREE_RANGE_CHECK(T, CODE1, CODE2) (T)
#define EXPR_CHECK(T) (T)
-#define GIMPLE_STMT_CHECK(T) (T)
#define NON_TYPE_CHECK(T) (T)
#define TREE_VEC_ELT_CHECK(T, I) ((T)->vec.a[I])
#define TREE_OPERAND_CHECK(T, I) ((T)->exp.operands[I])
#define TREE_OPERAND_CHECK_CODE(T, CODE, I) ((T)->exp.operands[I])
-#define GIMPLE_STMT_OPERAND_CHECK(T, I) ((T)->gstmt.operands[I])
#define TREE_RTL_OPERAND_CHECK(T, CODE, I) (*(rtx *) &((T)->exp.operands[I]))
-#define PHI_NODE_ELT_CHECK(T, i) ((T)->phi.a[i])
#define OMP_CLAUSE_ELT_CHECK(T, i) ((T)->omp_clause.ops[i])
#define OMP_CLAUSE_RANGE_CHECK(T, CODE1, CODE2) (T)
#define OMP_CLAUSE_SUBCODE_CHECK(T, CODE) (T)
@@ -1028,27 +954,6 @@ extern void omp_clause_range_check_failed (const_tree, const char *, int,
TREE_CHECK5 (T, INTEGER_TYPE, ENUMERAL_TYPE, BOOLEAN_TYPE, REAL_TYPE, \
FIXED_POINT_TYPE)
-/* Nonzero if NODE is a GIMPLE statement. */
-#define GIMPLE_STMT_P(NODE) \
- (TREE_CODE_CLASS (TREE_CODE ((NODE))) == tcc_gimple_stmt)
-
-/* Nonzero if NODE is a GIMPLE tuple. */
-#define GIMPLE_TUPLE_P(NODE) (GIMPLE_STMT_P (NODE) || TREE_CODE (NODE) == PHI_NODE)
-
-/* A GIMPLE tuple that has a ``locus'' field. */
-#define GIMPLE_TUPLE_HAS_LOCUS_P(NODE) GIMPLE_STMT_P ((NODE))
-
-/* Like TREE_OPERAND but works with GIMPLE stmt tuples as well.
-
- If you know the NODE is a GIMPLE statement, use GIMPLE_STMT_OPERAND. If the
- NODE code is unknown at compile time, use this macro. */
-#define GENERIC_TREE_OPERAND(NODE, I) *(generic_tree_operand ((NODE), (I)))
-
-/* Like TREE_TYPE but returns void_type_node for gimple tuples that have
- no type. */
-
-#define GENERIC_TREE_TYPE(NODE) *(generic_tree_type ((NODE)))
-
/* Here is how primitive or already-canonicalized types' hash codes
are made. */
#define TYPE_HASH(TYPE) (TYPE_UID (TYPE))
@@ -1057,16 +962,12 @@ extern void omp_clause_range_check_failed (const_tree, const char *, int,
used in hash tables which are saved to a PCH. */
#define TREE_HASH(NODE) ((size_t) (NODE) & 0777777)
-/* The TREE_CHAIN but it is able to handle tuples. */
-#define GENERIC_NEXT(NODE) \
- (TREE_CODE (NODE) == PHI_NODE ? PHI_CHAIN (NODE) : \
- GIMPLE_STMT_P (NODE) ? NULL_TREE : TREE_CHAIN (NODE))
+/* Tests if CODE is a conversion expr (NOP_EXPR or CONVERT_EXPR). */
+#define IS_CONVERT_EXPR_CODE_P(CODE) \
+ ((CODE) == NOP_EXPR || (CODE) == CONVERT_EXPR)
-/* Tests if expression is conversion expr (NOP_EXPRs or CONVERT_EXPRs). */
-
-#define CONVERT_EXPR_P(EXP) \
- (TREE_CODE (EXP) == NOP_EXPR \
- || TREE_CODE (EXP) == CONVERT_EXPR)
+/* Similarly, but accept an expressions instead of a tree code. */
+#define CONVERT_EXPR_P(EXP) IS_CONVERT_EXPR_CODE_P (TREE_CODE (EXP))
/* Generate case for NOP_EXPR, CONVERT_EXPR. */
@@ -1082,7 +983,7 @@ extern void omp_clause_range_check_failed (const_tree, const char *, int,
|| TREE_CODE (EXP) == NON_LVALUE_EXPR) \
&& TREE_OPERAND (EXP, 0) != error_mark_node \
&& (TYPE_MODE (TREE_TYPE (EXP)) \
- == TYPE_MODE (GENERIC_TREE_TYPE (TREE_OPERAND (EXP, 0))))) \
+ == TYPE_MODE (TREE_TYPE (TREE_OPERAND (EXP, 0))))) \
(EXP) = TREE_OPERAND (EXP, 0)
/* Like STRIP_NOPS, but don't let the signedness change either. */
@@ -1279,7 +1180,7 @@ extern void omp_clause_range_check_failed (const_tree, const char *, int,
/* In a MODIFY_EXPR, means that the store in the expression is nontemporal. */
#define MOVE_NONTEMPORAL(NODE) \
- (GIMPLE_MODIFY_STMT_CHECK (NODE)->base.static_flag)
+ (EXPR_CHECK (NODE)->base.static_flag)
/* In an INTEGER_CST, REAL_CST, COMPLEX_CST, or VECTOR_CST, this means
there was an overflow in folding. */
@@ -1658,28 +1559,25 @@ struct tree_constructor GTY(())
#define VL_EXP_OPERAND_LENGTH(NODE) \
((int)TREE_INT_CST_LOW (VL_EXP_CHECK (NODE)->exp.operands[0]))
-/* In gimple statements. */
-#define GIMPLE_STMT_OPERAND(NODE, I) GIMPLE_STMT_OPERAND_CHECK (NODE, I)
-#define GIMPLE_STMT_LOCUS(NODE) (GIMPLE_STMT_CHECK (NODE)->gstmt.locus)
-#define GIMPLE_STMT_BLOCK(NODE) (GIMPLE_STMT_CHECK (NODE)->gstmt.block)
-
/* In a LOOP_EXPR node. */
#define LOOP_EXPR_BODY(NODE) TREE_OPERAND_CHECK_CODE (NODE, LOOP_EXPR, 0)
/* The source location of this expression. Non-tree_exp nodes such as
decls and constants can be shared among multiple locations, so
return nothing. */
-#define EXPR_LOCATION(NODE) expr_location ((NODE))
-#define SET_EXPR_LOCATION(NODE, FROM) set_expr_location ((NODE), (FROM))
-#define EXPR_HAS_LOCATION(NODE) expr_has_location ((NODE))
-#define EXPR_LOCUS(NODE) expr_locus ((NODE))
+#define EXPR_LOCATION(NODE) (EXPR_P ((NODE)) ? (NODE)->exp.locus : UNKNOWN_LOCATION)
+#define SET_EXPR_LOCATION(NODE, LOCUS) EXPR_CHECK ((NODE))->exp.locus = (LOCUS)
+#define EXPR_HAS_LOCATION(NODE) (EXPR_LOCATION (NODE) != UNKNOWN_LOCATION)
+#define EXPR_LOCUS(NODE) (EXPR_P (NODE) \
+ ? CONST_CAST (source_location *, &(NODE)->exp.locus) \
+ : (source_location *) NULL)
#define SET_EXPR_LOCUS(NODE, FROM) set_expr_locus ((NODE), (FROM))
-#define EXPR_FILENAME(NODE) (expr_filename ((NODE)))
-#define EXPR_LINENO(NODE) (expr_lineno ((NODE)))
+#define EXPR_FILENAME(NODE) LOCATION_FILE (EXPR_CHECK ((NODE))->exp.locus)
+#define EXPR_LINENO(NODE) LOCATION_LINE (EXPR_CHECK (NODE)->exp.locus)
/* True if a tree is an expression or statement that can have a
location. */
-#define CAN_HAVE_LOCATION_P(NODE) (EXPR_P (NODE) || GIMPLE_STMT_P (NODE))
+#define CAN_HAVE_LOCATION_P(NODE) (EXPR_P (NODE))
/* In a TARGET_EXPR node. */
#define TARGET_EXPR_SLOT(NODE) TREE_OPERAND_CHECK_CODE (NODE, TARGET_EXPR, 0)
@@ -1805,22 +1703,13 @@ struct tree_constructor GTY(())
#define OMP_PARALLEL_BODY(NODE) TREE_OPERAND (OMP_PARALLEL_CHECK (NODE), 0)
#define OMP_PARALLEL_CLAUSES(NODE) TREE_OPERAND (OMP_PARALLEL_CHECK (NODE), 1)
-#define OMP_PARALLEL_FN(NODE) TREE_OPERAND (OMP_PARALLEL_CHECK (NODE), 2)
-#define OMP_PARALLEL_DATA_ARG(NODE) TREE_OPERAND (OMP_PARALLEL_CHECK (NODE), 3)
#define OMP_TASK_BODY(NODE) TREE_OPERAND (OMP_TASK_CHECK (NODE), 0)
#define OMP_TASK_CLAUSES(NODE) TREE_OPERAND (OMP_TASK_CHECK (NODE), 1)
-#define OMP_TASK_FN(NODE) TREE_OPERAND (OMP_TASK_CHECK (NODE), 2)
-#define OMP_TASK_DATA_ARG(NODE) TREE_OPERAND (OMP_TASK_CHECK (NODE), 3)
-#define OMP_TASK_COPYFN(NODE) TREE_OPERAND (OMP_TASK_CHECK (NODE), 4)
-#define OMP_TASK_ARG_SIZE(NODE) TREE_OPERAND (OMP_TASK_CHECK (NODE), 5)
-#define OMP_TASK_ARG_ALIGN(NODE) TREE_OPERAND (OMP_TASK_CHECK (NODE), 6)
#define OMP_TASKREG_CHECK(NODE) TREE_RANGE_CHECK (NODE, OMP_PARALLEL, OMP_TASK)
#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_TASKREG_FN(NODE) TREE_OPERAND (OMP_TASKREG_CHECK (NODE), 2)
-#define OMP_TASKREG_DATA_ARG(NODE) TREE_OPERAND (OMP_TASKREG_CHECK (NODE), 3)
#define OMP_FOR_BODY(NODE) TREE_OPERAND (OMP_FOR_CHECK (NODE), 0)
#define OMP_FOR_CLAUSES(NODE) TREE_OPERAND (OMP_FOR_CHECK (NODE), 1)
@@ -1831,7 +1720,6 @@ struct tree_constructor GTY(())
#define OMP_SECTIONS_BODY(NODE) TREE_OPERAND (OMP_SECTIONS_CHECK (NODE), 0)
#define OMP_SECTIONS_CLAUSES(NODE) TREE_OPERAND (OMP_SECTIONS_CHECK (NODE), 1)
-#define OMP_SECTIONS_CONTROL(NODE) TREE_OPERAND (OMP_SECTIONS_CHECK (NODE), 2)
#define OMP_SECTION_BODY(NODE) TREE_OPERAND (OMP_SECTION_CHECK (NODE), 0)
@@ -1856,13 +1744,6 @@ struct tree_constructor GTY(())
#define OMP_SECTION_LAST(NODE) \
(OMP_SECTION_CHECK (NODE)->base.private_flag)
-/* True on an OMP_RETURN statement if the return does not require a
- thread synchronization via some sort of barrier. The exact barrier
- that would otherwise be emitted is dependent on the OMP statement
- with which this return is associated. */
-#define OMP_RETURN_NOWAIT(NODE) \
- (OMP_RETURN_CHECK (NODE)->base.private_flag)
-
/* True on an OMP_PARALLEL statement if it represents an explicit
combined parallel work-sharing constructs. */
#define OMP_PARALLEL_COMBINED(NODE) \
@@ -1887,6 +1768,8 @@ struct tree_constructor GTY(())
OMP_CLAUSE_OPERAND (OMP_CLAUSE_SUBCODE_CHECK (NODE, \
OMP_CLAUSE_LASTPRIVATE),\
1)
+#define OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ(NODE) \
+ (OMP_CLAUSE_CHECK (NODE))->omp_clause.gimple_reduction_init
#define OMP_CLAUSE_IF_EXPR(NODE) \
OMP_CLAUSE_OPERAND (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_IF), 0)
@@ -1908,6 +1791,10 @@ struct tree_constructor GTY(())
OMP_CLAUSE_OPERAND (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_REDUCTION), 1)
#define OMP_CLAUSE_REDUCTION_MERGE(NODE) \
OMP_CLAUSE_OPERAND (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_REDUCTION), 2)
+#define OMP_CLAUSE_REDUCTION_GIMPLE_INIT(NODE) \
+ (OMP_CLAUSE_CHECK (NODE))->omp_clause.gimple_reduction_init
+#define OMP_CLAUSE_REDUCTION_GIMPLE_MERGE(NODE) \
+ (OMP_CLAUSE_CHECK (NODE))->omp_clause.gimple_reduction_merge
#define OMP_CLAUSE_REDUCTION_PLACEHOLDER(NODE) \
OMP_CLAUSE_OPERAND (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_REDUCTION), 3)
@@ -1951,10 +1838,8 @@ struct tree_exp GTY(())
only field that can be relied upon. */
#define SSA_NAME_VAR(NODE) SSA_NAME_CHECK (NODE)->ssa_name.var
-/* Returns the statement which defines this reference. Note that
- we use the same field when chaining SSA_NAME nodes together on
- the SSA_NAME freelist. */
-#define SSA_NAME_DEF_STMT(NODE) SSA_NAME_CHECK (NODE)->common.chain
+/* Returns the statement which defines this SSA name. */
+#define SSA_NAME_DEF_STMT(NODE) SSA_NAME_CHECK (NODE)->ssa_name.def_stmt
/* Returns the SSA version number of this SSA name. Note that in
tree SSA, version numbers are not per variable and may be recycled. */
@@ -2000,7 +1885,12 @@ typedef struct ssa_use_operand_d GTY(())
{
struct ssa_use_operand_d* GTY((skip(""))) prev;
struct ssa_use_operand_d* GTY((skip(""))) next;
- tree GTY((skip(""))) stmt;
+ /* Immediate uses for a given SSA name are maintained as a cyclic
+ list. To recognize the root of this list, the location field
+ needs to point to the original SSA name. Since statements and
+ SSA names are of different data types, we need this union. See
+ the explanation in struct immediate_use_iterator_d. */
+ union { gimple stmt; tree ssa_name; } GTY((skip(""))) loc;
tree *GTY((skip(""))) use;
} ssa_use_operand_t;
@@ -2014,6 +1904,9 @@ struct tree_ssa_name GTY(())
/* _DECL wrapped by this SSA name. */
tree var;
+ /* Statement that defines this SSA name. */
+ gimple def_stmt;
+
/* SSA version number. */
unsigned int version;
@@ -2031,29 +1924,6 @@ struct tree_ssa_name GTY(())
struct ssa_use_operand_d imm_uses;
};
-/* In a PHI_NODE node. */
-
-/* These 2 macros should be considered off limits for use by developers. If
- you wish to access the use or def fields of a PHI_NODE in the SSA
- optimizers, use the accessor macros found in tree-ssa-operands.h.
- These two macros are to be used only by those accessor macros, and other
- select places where we *absolutely* must take the address of the tree. */
-
-#define PHI_RESULT_TREE(NODE) PHI_NODE_CHECK (NODE)->phi.result
-#define PHI_ARG_DEF_TREE(NODE, I) PHI_NODE_ELT_CHECK (NODE, I).def
-
-/* PHI_NODEs for each basic block are chained together in a single linked
- list. The head of the list is linked from the block annotation, and
- the link to the next PHI is in PHI_CHAIN. */
-#define PHI_CHAIN(NODE) PHI_NODE_CHECK (NODE)->phi.chain
-
-#define PHI_NUM_ARGS(NODE) PHI_NODE_CHECK (NODE)->phi.num_args
-#define PHI_ARG_CAPACITY(NODE) PHI_NODE_CHECK (NODE)->phi.capacity
-#define PHI_ARG_ELT(NODE, I) PHI_NODE_ELT_CHECK (NODE, I)
-#define PHI_ARG_EDGE(NODE, I) (EDGE_PRED (PHI_BB ((NODE)), (I)))
-#define PHI_BB(NODE) PHI_NODE_CHECK (NODE)->phi.bb
-#define PHI_ARG_IMM_USE_NODE(NODE, I) PHI_NODE_ELT_CHECK (NODE, I).imm_use
-
struct phi_arg_d GTY(())
{
/* imm_use MUST be the first element in struct because we do some
@@ -2062,22 +1932,6 @@ struct phi_arg_d GTY(())
tree def;
};
-struct tree_phi_node GTY(())
-{
- struct tree_base common;
- tree chain;
- tree result;
- int num_args;
- int capacity;
-
- /* Basic block holding this PHI node. */
- struct basic_block_def *bb;
-
- /* Arguments of the PHI node. These are maintained in the same
- order as predecessor edge vector BB->PREDS. */
- struct phi_arg_d GTY ((length ("((tree)&%h)->phi.num_args"))) a[1];
-};
-
#define OMP_CLAUSE_CODE(NODE) \
(OMP_CLAUSE_CHECK (NODE))->omp_clause.code
@@ -2100,6 +1954,12 @@ struct tree_omp_clause GTY(())
enum omp_clause_schedule_kind schedule_kind;
enum tree_code reduction_code;
} GTY ((skip)) subcode;
+
+ /* The gimplification of OMP_CLAUSE_REDUCTION_{INIT,MERGE} for omp-low's
+ usage. */
+ gimple_seq gimple_reduction_init;
+ gimple_seq gimple_reduction_merge;
+
tree GTY ((length ("omp_clause_num_ops[OMP_CLAUSE_CODE ((tree)&%h)]"))) ops[1];
};
@@ -3052,7 +2912,7 @@ struct tree_parm_decl GTY(())
/* Nonzero for a given ..._DECL node means that no warnings should be
generated just because this node is unused. */
#define DECL_IN_SYSTEM_HEADER(NODE) \
- (DECL_WITH_VIS_CHECK (NODE)->decl_with_vis.in_system_header_flag)
+ (in_system_header_at (DECL_SOURCE_LOCATION (NODE)))
/* Used to indicate that this DECL has weak linkage. */
#define DECL_WEAK(NODE) (DECL_WITH_VIS_CHECK (NODE)->decl_with_vis.weak_flag)
@@ -3180,7 +3040,6 @@ struct tree_decl_with_vis GTY(())
unsigned shadowed_for_var_p : 1;
/* Don't belong to VAR_DECL exclusively. */
- unsigned in_system_header_flag : 1;
unsigned weak_flag:1;
unsigned seen_in_bind_expr : 1;
unsigned comdat_flag : 1;
@@ -3192,7 +3051,7 @@ struct tree_decl_with_vis GTY(())
/* Belongs to VAR_DECL exclusively. */
ENUM_BITFIELD(tls_model) tls_model : 3;
- /* 11 unused bits. */
+ /* 12 unused bits. */
};
/* In a VAR_DECL that's static,
@@ -3410,6 +3269,16 @@ struct tree_decl_non_common GTY(())
#define DECL_ARGUMENTS(NODE) (FUNCTION_DECL_CHECK (NODE)->decl_non_common.arguments)
#define DECL_ARGUMENT_FLD(NODE) (DECL_NON_COMMON_CHECK (NODE)->decl_non_common.arguments)
+/* In FUNCTION_DECL, the function specific target options to use when compiling
+ this function. */
+#define DECL_FUNCTION_SPECIFIC_TARGET(NODE) \
+ (FUNCTION_DECL_CHECK (NODE)->function_decl.function_specific_target)
+
+/* In FUNCTION_DECL, the function specific optimization options to use when
+ compiling this function. */
+#define DECL_FUNCTION_SPECIFIC_OPTIMIZATION(NODE) \
+ (FUNCTION_DECL_CHECK (NODE)->function_decl.function_specific_optimization)
+
/* FUNCTION_DECL inherits from DECL_NON_COMMON because of the use of the
arguments/result/saved_tree fields by front ends. It was either inherit
FUNCTION_DECL from non_common, or inherit non_common from FUNCTION_DECL,
@@ -3421,6 +3290,10 @@ struct tree_function_decl GTY(())
struct function *f;
+ /* Function specific options that are used by this function. */
+ tree function_specific_target; /* target options */
+ tree function_specific_optimization; /* optimization options */
+
/* In a FUNCTION_DECL for which DECL_BUILT_IN holds, this is
DECL_FUNCTION_CODE. Otherwise unused.
??? The bitfield needs to be able to hold all target function
@@ -3493,26 +3366,39 @@ struct tree_statement_list
struct tree_statement_list_node *tail;
};
-#define VALUE_HANDLE_ID(NODE) \
- (VALUE_HANDLE_CHECK (NODE)->value_handle.id)
-#define VALUE_HANDLE_EXPR_SET(NODE) \
- (VALUE_HANDLE_CHECK (NODE)->value_handle.expr_set)
+/* Optimization options used by a function. */
-/* Defined and used in tree-ssa-pre.c. */
-
-struct tree_value_handle GTY(())
+struct tree_optimization_option GTY(())
{
struct tree_common common;
- /* The set of expressions represented by this handle. */
- struct bitmap_set * GTY ((skip)) expr_set;
+ /* The optimization options used by the user. */
+ struct cl_optimization opts;
+};
+
+#define TREE_OPTIMIZATION(NODE) \
+ (&OPTIMIZATION_NODE_CHECK (NODE)->optimization.opts)
+
+/* Return a tree node that encapsulates the current optimization options. */
+extern tree build_optimization_node (void);
- /* Unique ID for this value handle. IDs are handed out in a
- conveniently dense form starting at 0, so that we can make
- bitmaps of value handles. */
- unsigned int id;
+/* Target options used by a function. */
+
+struct tree_target_option GTY(())
+{
+ struct tree_common common;
+
+ /* The optimization options used by the user. */
+ struct cl_target_option opts;
};
+
+#define TREE_TARGET_OPTION(NODE) \
+ (&TARGET_OPTION_NODE_CHECK (NODE)->target_option.opts)
+
+/* Return a tree node that encapsulates the current target options. */
+extern tree build_target_option_node (void);
+
/* Define the overall contents of a tree node.
It may be any of the structures declared above
@@ -3548,16 +3434,15 @@ union tree_node GTY ((ptr_alias (union lang_tree_node),
struct tree_vec GTY ((tag ("TS_VEC"))) vec;
struct tree_exp GTY ((tag ("TS_EXP"))) exp;
struct tree_ssa_name GTY ((tag ("TS_SSA_NAME"))) ssa_name;
- struct tree_phi_node GTY ((tag ("TS_PHI_NODE"))) phi;
struct tree_block GTY ((tag ("TS_BLOCK"))) block;
struct tree_binfo GTY ((tag ("TS_BINFO"))) binfo;
struct tree_statement_list GTY ((tag ("TS_STATEMENT_LIST"))) stmt_list;
- struct gimple_stmt GTY ((tag ("TS_GIMPLE_STATEMENT"))) gstmt;
- struct tree_value_handle GTY ((tag ("TS_VALUE_HANDLE"))) value_handle;
struct tree_constructor GTY ((tag ("TS_CONSTRUCTOR"))) constructor;
struct tree_memory_tag GTY ((tag ("TS_MEMORY_TAG"))) mtag;
struct tree_omp_clause GTY ((tag ("TS_OMP_CLAUSE"))) omp_clause;
struct tree_memory_partition_tag GTY ((tag ("TS_MEMORY_PARTITION_TAG"))) mpt;
+ struct tree_optimization_option GTY ((tag ("TS_OPTIMIZATION"))) optimization;
+ struct tree_target_option GTY ((tag ("TS_TARGET_OPTION"))) target_option;
};
/* Standard named or nameless data types of the C compiler. */
@@ -3705,6 +3590,15 @@ enum tree_index
TI_SAT_UDA_TYPE,
TI_SAT_UTA_TYPE,
+ TI_OPTIMIZATION_DEFAULT,
+ TI_OPTIMIZATION_CURRENT,
+ TI_OPTIMIZATION_COLD,
+ TI_OPTIMIZATION_HOT,
+ TI_TARGET_OPTION_DEFAULT,
+ TI_TARGET_OPTION_CURRENT,
+ TI_CURRENT_OPTION_PRAGMA,
+ TI_CURRENT_OPTIMIZE_PRAGMA,
+
TI_MAX
};
@@ -3872,6 +3766,22 @@ extern GTY(()) tree global_trees[TI_MAX];
#define main_identifier_node global_trees[TI_MAIN_IDENTIFIER]
#define MAIN_NAME_P(NODE) (IDENTIFIER_NODE_CHECK (NODE) == main_identifier_node)
+/* Optimization options (OPTIMIZATION_NODE) to use for default, current, cold,
+ and hot functions. */
+#define optimization_default_node global_trees[TI_OPTIMIZATION_DEFAULT]
+#define optimization_current_node global_trees[TI_OPTIMIZATION_CURRENT]
+#define optimization_cold_node global_trees[TI_OPTIMIZATION_COLD]
+#define optimization_hot_node global_trees[TI_OPTIMIZATION_HOT]
+
+/* Default/current target options (TARGET_OPTION_NODE). */
+#define target_option_default_node global_trees[TI_TARGET_OPTION_DEFAULT]
+#define target_option_current_node global_trees[TI_TARGET_OPTION_CURRENT]
+
+/* Default tree list option(), optimize() pragmas to be linked into the
+ attribute list. */
+#define current_option_pragma global_trees[TI_CURRENT_OPTION_PRAGMA]
+#define current_optimize_pragma global_trees[TI_CURRENT_OPTIMIZE_PRAGMA]
+
/* An enumeration of the standard C integer types. These must be
ordered so that shorter types appear before longer ones, and so
that signed types appear before unsigned ones, for the correct
@@ -3945,7 +3855,8 @@ enum ptrmemfunc_vbit_where_t
#define NULL_TREE (tree) NULL
extern tree decl_assembler_name (tree);
-extern bool decl_assembler_name_equal (tree decl, tree asmname);
+extern bool decl_assembler_name_equal (tree decl, const_tree asmname);
+extern hashval_t decl_assembler_name_hash (const_tree asmname);
/* Compute the number of bytes occupied by 'node'. This routine only
looks at TREE_CODE and, if the code is TREE_VEC, TREE_VEC_LENGTH. */
@@ -3953,8 +3864,8 @@ extern bool decl_assembler_name_equal (tree decl, tree asmname);
extern size_t tree_size (const_tree);
/* Compute the number of bytes occupied by a tree with code CODE. This
- function cannot be used for TREE_VEC or PHI_NODE codes, which are of
- variable length. */
+ function cannot be used for TREE_VEC codes, which are of variable
+ length. */
extern size_t tree_code_size (enum tree_code);
/* Lowest level primitive for allocating a node.
@@ -4030,10 +3941,6 @@ extern tree build7_stat (enum tree_code, tree, tree, tree, tree, tree,
#define build7(c,t1,t2,t3,t4,t5,t6,t7,t8) \
build7_stat (c,t1,t2,t3,t4,t5,t6,t7,t8 MEM_STAT_INFO)
-extern tree build_gimple_modify_stmt_stat (tree, tree MEM_STAT_DECL);
-#define build_gimple_modify_stmt(t1,t2) \
- build_gimple_modify_stmt_stat (t1,t2 MEM_STAT_INFO)
-
extern tree build_int_cst (tree, HOST_WIDE_INT);
extern tree build_int_cst_type (tree, HOST_WIDE_INT);
extern tree build_int_cstu (tree, unsigned HOST_WIDE_INT);
@@ -4768,15 +4675,19 @@ extern bool commutative_tree_code (enum tree_code);
extern tree upper_bound_in_type (tree, tree);
extern tree lower_bound_in_type (tree, tree);
extern int operand_equal_for_phi_arg_p (const_tree, const_tree);
-extern bool empty_body_p (tree);
extern tree call_expr_arg (tree, int);
extern tree *call_expr_argp (tree, int);
extern tree call_expr_arglist (tree);
+extern tree create_artificial_label (void);
+extern const char *get_name (tree);
extern bool stdarg_p (tree);
extern bool prototype_p (tree);
extern int function_args_count (tree);
extern bool auto_var_in_fn_p (const_tree, const_tree);
+/* In gimplify.c */
+extern tree unshare_expr (tree);
+
/* In stmt.c */
extern void expand_expr_stmt (tree);
@@ -4830,10 +4741,11 @@ extern tree fold_ignored_result (tree);
extern tree fold_abs_const (tree, tree);
extern tree fold_indirect_ref_1 (tree, tree);
extern void fold_defer_overflow_warnings (void);
-extern void fold_undefer_overflow_warnings (bool, const_tree, int);
+extern void fold_undefer_overflow_warnings (bool, const_gimple, int);
extern void fold_undefer_and_ignore_overflow_warnings (void);
extern bool fold_deferring_overflow_warnings_p (void);
extern tree maybe_fold_offset_to_reference (tree, tree, tree);
+extern tree maybe_fold_stmt_addition (tree, tree, tree);
extern tree force_fit_type_double (tree, unsigned HOST_WIDE_INT, HOST_WIDE_INT,
int, bool);
@@ -4899,7 +4811,6 @@ extern tree constant_boolean_node (int, tree);
extern tree build_low_bits_mask (tree, unsigned);
extern bool tree_swap_operands_p (const_tree, const_tree, bool);
-extern void swap_tree_operands (tree, tree *, tree *);
extern enum tree_code swap_tree_comparison (enum tree_code);
extern bool ptr_difference_const (tree, tree, HOST_WIDE_INT *);
@@ -4916,8 +4827,7 @@ extern bool tree_binary_nonnegative_warnv_p (enum tree_code, tree, tree, tree,
bool *);
extern bool tree_single_nonnegative_warnv_p (tree t, bool *strict_overflow_p);
extern bool tree_invalid_nonnegative_warnv_p (tree t, bool *strict_overflow_p);
-extern bool tree_call_nonnegative_warnv_p (enum tree_code code, tree, tree,
- tree, tree, bool *);
+extern bool tree_call_nonnegative_warnv_p (tree, tree, tree, tree, bool *);
extern bool tree_expr_nonzero_warnv_p (tree, bool *);
@@ -4943,12 +4853,14 @@ extern tree build_call_expr (tree, int, ...);
extern tree mathfn_built_in (tree, enum built_in_function fn);
extern tree strip_float_extensions (tree);
extern tree c_strlen (tree, int);
-extern tree std_gimplify_va_arg_expr (tree, tree, tree *, tree *);
+extern tree std_gimplify_va_arg_expr (tree, tree, gimple_seq *, gimple_seq *);
extern tree build_va_arg_indirect_ref (tree);
extern tree build_string_literal (int, const char *);
extern bool validate_arglist (const_tree, ...);
extern rtx builtin_memset_read_str (void *, HOST_WIDE_INT, enum machine_mode);
extern int get_pointer_alignment (tree, unsigned int);
+extern tree fold_call_stmt (gimple, bool);
+extern tree gimple_fold_builtin_snprintf_chk (gimple, tree, enum built_in_function);
/* In convert.c */
extern tree strip_float_extensions (tree);
@@ -4965,6 +4877,9 @@ extern int tree_log2 (const_tree);
extern int tree_floor_log2 (const_tree);
extern int simple_cst_equal (const_tree, const_tree);
extern hashval_t iterative_hash_expr (const_tree, hashval_t);
+extern hashval_t iterative_hash_exprs_commutative (const_tree,
+ const_tree, hashval_t);
+extern hashval_t iterative_hash_hashval_t (hashval_t, hashval_t);
extern int compare_tree_int (const_tree, unsigned HOST_WIDE_INT);
extern int type_list_equal (const_tree, const_tree);
extern int chain_member (const_tree, const_tree);
@@ -4995,18 +4910,9 @@ extern tree build_addr (tree, tree);
extern bool fields_compatible_p (const_tree, const_tree);
extern tree find_compatible_field (tree, tree);
-extern location_t expr_location (const_tree);
-extern void set_expr_location (tree, location_t);
-extern bool expr_has_location (const_tree);
-
-extern location_t *expr_locus (const_tree);
extern void set_expr_locus (tree, source_location *);
-extern const char *expr_filename (const_tree);
-extern int expr_lineno (const_tree);
extern tree *tree_block (tree);
-extern tree *generic_tree_operand (tree, int);
-extern tree *generic_tree_type (tree);
extern location_t *block_nonartificial_location (tree);
/* In function.c */
@@ -5027,7 +4933,7 @@ extern void preserve_temp_slots (rtx);
extern int aggregate_value_p (const_tree, const_tree);
extern void push_function_context (void);
extern void pop_function_context (void);
-extern tree gimplify_parameters (void);
+extern gimple_seq gimplify_parameters (void);
/* In print-rtl.c */
#ifdef BUFSIZ
@@ -5085,6 +4991,7 @@ extern int flags_from_decl_or_type (const_tree);
extern int call_expr_flags (const_tree);
extern int setjmp_call_p (const_tree);
+extern bool gimple_alloca_call_p (const_gimple);
extern bool alloca_call_p (const_tree);
extern bool must_pass_in_stack_var_size (enum machine_mode, const_tree);
extern bool must_pass_in_stack_var_size_or_pad (enum machine_mode, const_tree);
@@ -5143,12 +5050,6 @@ extern void expand_anon_union_decl (tree, tree, tree);
extern tree tree_overlaps_hard_reg_set (tree, HARD_REG_SET *);
#endif
-/* In gimplify.c. */
-extern tree create_artificial_label (void);
-extern void gimplify_function_tree (tree);
-extern const char *get_name (const_tree);
-extern tree unshare_expr (tree);
-extern void sort_case_labels (tree);
/* Interface of the DWARF2 unwind info support. */
@@ -5230,14 +5131,12 @@ typedef enum
temp_list_kind,
vec_kind,
binfo_kind,
- phi_kind,
ssa_name_kind,
constr_kind,
x_kind,
lang_decl,
lang_type,
omp_clause_kind,
- gimple_stmt_kind,
all_kinds
} tree_node_kind;
diff --git a/gcc/treestruct.def b/gcc/treestruct.def
index fb93e2c9dd4..0f3dbbdfb2a 100644
--- a/gcc/treestruct.def
+++ b/gcc/treestruct.def
@@ -59,8 +59,10 @@ DEFTREESTRUCT(TS_BLOCK, "block")
DEFTREESTRUCT(TS_BINFO, "binfo")
DEFTREESTRUCT(TS_STATEMENT_LIST, "statement list")
DEFTREESTRUCT(TS_GIMPLE_STATEMENT, "gimple statement")
-DEFTREESTRUCT(TS_VALUE_HANDLE, "value handle")
DEFTREESTRUCT(TS_CONSTRUCTOR, "constructor")
DEFTREESTRUCT(TS_MEMORY_TAG, "memory tag")
DEFTREESTRUCT(TS_OMP_CLAUSE, "omp clause")
DEFTREESTRUCT(TS_MEMORY_PARTITION_TAG, "memory partition tag")
+DEFTREESTRUCT(TS_OPTIMIZATION, "optimization options")
+DEFTREESTRUCT(TS_TARGET_OPTION, "target options")
+
diff --git a/gcc/unwind-pe.h b/gcc/unwind-pe.h
index 9c56af08486..6924e8c1732 100644
--- a/gcc/unwind-pe.h
+++ b/gcc/unwind-pe.h
@@ -71,6 +71,9 @@
include leb128. */
static unsigned int
+size_of_encoded_value (unsigned char encoding) __attribute__ ((unused));
+
+static unsigned int
size_of_encoded_value (unsigned char encoding)
{
if (encoding == DW_EH_PE_omit)
diff --git a/gcc/value-prof.c b/gcc/value-prof.c
index a16e7d48378..b94a3f96b47 100644
--- a/gcc/value-prof.c
+++ b/gcc/value-prof.c
@@ -78,22 +78,21 @@ static struct value_prof_hooks *value_prof_hooks;
same information as above. */
-static tree tree_divmod_fixed_value (tree, tree, tree, tree,
- tree, int, gcov_type, gcov_type);
-static tree tree_mod_pow2 (tree, tree, tree, tree, int, gcov_type, gcov_type);
-static tree tree_mod_subtract (tree, tree, tree, tree, int, int, int,
- gcov_type, gcov_type, gcov_type);
-static bool tree_divmod_fixed_value_transform (tree);
-static bool tree_mod_pow2_value_transform (tree);
-static bool tree_mod_subtract_transform (tree);
-static bool tree_stringops_transform (block_stmt_iterator *);
-static bool tree_ic_transform (tree);
+static tree gimple_divmod_fixed_value (gimple, tree, int, gcov_type, gcov_type);
+static tree gimple_mod_pow2 (gimple, int, gcov_type, gcov_type);
+static tree gimple_mod_subtract (gimple, int, int, int, gcov_type, gcov_type,
+ gcov_type);
+static bool gimple_divmod_fixed_value_transform (gimple_stmt_iterator *);
+static bool gimple_mod_pow2_value_transform (gimple_stmt_iterator *);
+static bool gimple_mod_subtract_transform (gimple_stmt_iterator *);
+static bool gimple_stringops_transform (gimple_stmt_iterator *);
+static bool gimple_ic_transform (gimple);
/* Allocate histogram value. */
static histogram_value
gimple_alloc_histogram_value (struct function *fun ATTRIBUTE_UNUSED,
- enum hist_type type, tree stmt, tree value)
+ enum hist_type type, gimple stmt, tree value)
{
histogram_value hist = (histogram_value) xcalloc (1, sizeof (*hist));
hist->hvalue.value = value;
@@ -115,13 +114,13 @@ histogram_hash (const void *x)
static int
histogram_eq (const void *x, const void *y)
{
- return ((const_histogram_value) x)->hvalue.stmt == (const_tree)y;
+ return ((const_histogram_value) x)->hvalue.stmt == (const_gimple) y;
}
/* Set histogram for STMT. */
static void
-set_histogram_value (struct function *fun, tree stmt, histogram_value hist)
+set_histogram_value (struct function *fun, gimple stmt, histogram_value hist)
{
void **loc;
if (!hist && !VALUE_HISTOGRAMS (fun))
@@ -144,7 +143,7 @@ set_histogram_value (struct function *fun, tree stmt, histogram_value hist)
/* Get histogram list for STMT. */
histogram_value
-gimple_histogram_value (struct function *fun, tree stmt)
+gimple_histogram_value (struct function *fun, gimple stmt)
{
if (!VALUE_HISTOGRAMS (fun))
return NULL;
@@ -155,16 +154,19 @@ gimple_histogram_value (struct function *fun, tree stmt)
/* Add histogram for STMT. */
void
-gimple_add_histogram_value (struct function *fun, tree stmt, histogram_value hist)
+gimple_add_histogram_value (struct function *fun, gimple stmt,
+ histogram_value hist)
{
hist->hvalue.next = gimple_histogram_value (fun, stmt);
set_histogram_value (fun, stmt, hist);
}
+
/* Remove histogram HIST from STMT's histogram list. */
void
-gimple_remove_histogram_value (struct function *fun, tree stmt, histogram_value hist)
+gimple_remove_histogram_value (struct function *fun, gimple stmt,
+ histogram_value hist)
{
histogram_value hist2 = gimple_histogram_value (fun, stmt);
if (hist == hist2)
@@ -184,13 +186,16 @@ gimple_remove_histogram_value (struct function *fun, tree stmt, histogram_value
free (hist);
}
+
/* Lookup histogram of type TYPE in the STMT. */
histogram_value
-gimple_histogram_value_of_type (struct function *fun, tree stmt, enum hist_type type)
+gimple_histogram_value_of_type (struct function *fun, gimple stmt,
+ enum hist_type type)
{
histogram_value hist;
- for (hist = gimple_histogram_value (fun, stmt); hist; hist = hist->hvalue.next)
+ for (hist = gimple_histogram_value (fun, stmt); hist;
+ hist = hist->hvalue.next)
if (hist->type == type)
return hist;
return NULL;
@@ -302,7 +307,7 @@ dump_histogram_value (FILE *dump_file, histogram_value hist)
/* Dump all histograms attached to STMT to DUMP_FILE. */
void
-dump_histograms_for_stmt (struct function *fun, FILE *dump_file, tree stmt)
+dump_histograms_for_stmt (struct function *fun, FILE *dump_file, gimple stmt)
{
histogram_value hist;
for (hist = gimple_histogram_value (fun, stmt); hist; hist = hist->hvalue.next)
@@ -312,7 +317,7 @@ dump_histograms_for_stmt (struct function *fun, FILE *dump_file, tree stmt)
/* Remove all histograms associated with STMT. */
void
-gimple_remove_stmt_histograms (struct function *fun, tree stmt)
+gimple_remove_stmt_histograms (struct function *fun, gimple stmt)
{
histogram_value val;
while ((val = gimple_histogram_value (fun, stmt)) != NULL)
@@ -322,8 +327,8 @@ gimple_remove_stmt_histograms (struct function *fun, tree stmt)
/* Duplicate all histograms associates with OSTMT to STMT. */
void
-gimple_duplicate_stmt_histograms (struct function *fun, tree stmt,
- struct function *ofun, tree ostmt)
+gimple_duplicate_stmt_histograms (struct function *fun, gimple stmt,
+ struct function *ofun, gimple ostmt)
{
histogram_value val;
for (val = gimple_histogram_value (ofun, ostmt); val != NULL; val = val->hvalue.next)
@@ -341,7 +346,7 @@ gimple_duplicate_stmt_histograms (struct function *fun, tree stmt,
/* Move all histograms associated with OSTMT to STMT. */
void
-gimple_move_stmt_histograms (struct function *fun, tree stmt, tree ostmt)
+gimple_move_stmt_histograms (struct function *fun, gimple stmt, gimple ostmt)
{
histogram_value val = gimple_histogram_value (fun, ostmt);
if (val)
@@ -370,36 +375,38 @@ visit_hist (void **slot, void *data)
{
error ("Dead histogram");
dump_histogram_value (stderr, hist);
- debug_generic_stmt (hist->hvalue.stmt);
+ debug_gimple_stmt (hist->hvalue.stmt);
error_found = true;
}
return 1;
}
+
/* Verify sanity of the histograms. */
void
verify_histograms (void)
{
basic_block bb;
- block_stmt_iterator bsi;
+ gimple_stmt_iterator gsi;
histogram_value hist;
struct pointer_set_t *visited_hists;
error_found = false;
visited_hists = pointer_set_create ();
FOR_EACH_BB (bb)
- for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
- tree stmt = bsi_stmt (bsi);
+ gimple stmt = gsi_stmt (gsi);
- for (hist = gimple_histogram_value (cfun, stmt); hist; hist = hist->hvalue.next)
+ for (hist = gimple_histogram_value (cfun, stmt); hist;
+ hist = hist->hvalue.next)
{
if (hist->hvalue.stmt != stmt)
{
- error ("Histogram value statement does not correspond to statement"
- " it is associated with");
- debug_generic_stmt (stmt);
+ error ("Histogram value statement does not correspond to "
+ "the statement it is associated with");
+ debug_gimple_stmt (stmt);
dump_histogram_value (stderr, hist);
error_found = true;
}
@@ -439,38 +446,45 @@ free_histograms (void)
}
}
-/* The overall number of invocations of the counter should match execution count
- of basic block. Report it as error rather than internal error as it might
- mean that user has misused the profile somehow. */
+
+/* The overall number of invocations of the counter should match
+ execution count of basic block. Report it as error rather than
+ internal error as it might mean that user has misused the profile
+ somehow. */
+
static bool
-check_counter (tree stmt, const char * name, gcov_type all, gcov_type bb_count)
+check_counter (gimple stmt, const char *name, gcov_type all, gcov_type bb_count)
{
if (all != bb_count)
{
- location_t * locus;
- locus = (stmt != NULL && EXPR_HAS_LOCATION (stmt)
- ? EXPR_LOCUS (stmt)
- : &DECL_SOURCE_LOCATION (current_function_decl));
- error ("%HCorrupted value profile: %s profiler overall count (%d) does not match BB count (%d)",
- locus, name, (int)all, (int)bb_count);
+ location_t locus;
+ locus = (stmt != NULL)
+ ? gimple_location (stmt)
+ : DECL_SOURCE_LOCATION (current_function_decl);
+ error ("%HCorrupted value profile: %s profiler overall count (%d) "
+ "does not match BB count (%d)", &locus, name, (int)all,
+ (int)bb_count);
return true;
}
+
return false;
}
-/* Tree based transformations. */
+
+/* GIMPLE based transformations. */
+
static bool
-tree_value_profile_transformations (void)
+gimple_value_profile_transformations (void)
{
basic_block bb;
- block_stmt_iterator bsi;
+ gimple_stmt_iterator gsi;
bool changed = false;
FOR_EACH_BB (bb)
{
- for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
- tree stmt = bsi_stmt (bsi);
+ gimple stmt = gsi_stmt (gsi);
histogram_value th = gimple_histogram_value (cfun, stmt);
if (!th)
continue;
@@ -478,7 +492,7 @@ tree_value_profile_transformations (void)
if (dump_file)
{
fprintf (dump_file, "Trying transformations on stmt ");
- print_generic_stmt (dump_file, stmt, TDF_SLIM);
+ print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
dump_histograms_for_stmt (cfun, dump_file, stmt);
}
@@ -490,19 +504,19 @@ tree_value_profile_transformations (void)
current statement remain valid (although possibly
modified) upon return. */
if (flag_value_profile_transformations
- && (tree_mod_subtract_transform (stmt)
- || tree_divmod_fixed_value_transform (stmt)
- || tree_mod_pow2_value_transform (stmt)
- || tree_stringops_transform (&bsi)
- || tree_ic_transform (stmt)))
+ && (gimple_mod_subtract_transform (&gsi)
+ || gimple_divmod_fixed_value_transform (&gsi)
+ || gimple_mod_pow2_value_transform (&gsi)
+ || gimple_stringops_transform (&gsi)
+ || gimple_ic_transform (stmt)))
{
- stmt = bsi_stmt (bsi);
+ stmt = gsi_stmt (gsi);
changed = true;
/* Original statement may no longer be in the same block. */
- if (bb != bb_for_stmt (stmt))
+ if (bb != gimple_bb (stmt))
{
- bb = bb_for_stmt (stmt);
- bsi = bsi_for_stmt (stmt);
+ bb = gimple_bb (stmt);
+ gsi = gsi_for_stmt (stmt);
}
}
}
@@ -516,57 +530,61 @@ tree_value_profile_transformations (void)
return changed;
}
-/* Generate code for transformation 1 (with OPERATION, operands OP1
- and OP2, whose value is expected to be VALUE, parent modify-expr STMT and
- probability of taking the optimal path PROB, which is equivalent to COUNT/ALL
- within roundoff error). This generates the result into a temp and returns
- the temp; it does not replace or alter the original STMT. */
+
+/* Generate code for transformation 1 (with parent gimple assignment
+ STMT and probability of taking the optimal path PROB, which is
+ equivalent to COUNT/ALL within roundoff error). This generates the
+ result into a temp and returns the temp; it does not replace or
+ alter the original STMT. */
+
static tree
-tree_divmod_fixed_value (tree stmt, tree operation,
- tree op1, tree op2, tree value, int prob, gcov_type count,
- gcov_type all)
+gimple_divmod_fixed_value (gimple stmt, tree value, int prob, gcov_type count,
+ gcov_type all)
{
- tree stmt1, stmt2, stmt3;
+ gimple stmt1, stmt2, stmt3, label1, label2;
tree tmp1, tmp2, tmpv;
tree label_decl1 = create_artificial_label ();
tree label_decl2 = create_artificial_label ();
- tree label1, label2;
- tree bb1end, bb2end, bb3end;
+ gimple bb1end, bb2end, bb3end;
basic_block bb, bb2, bb3, bb4;
- tree optype = TREE_TYPE (operation);
+ tree optype, op1, op2;
edge e12, e13, e23, e24, e34;
- block_stmt_iterator bsi;
+ gimple_stmt_iterator gsi;
+
+ gcc_assert (is_gimple_assign (stmt)
+ && (gimple_assign_rhs_code (stmt) == TRUNC_DIV_EXPR
+ || gimple_assign_rhs_code (stmt) == TRUNC_MOD_EXPR));
+
+ optype = TREE_TYPE (gimple_assign_lhs (stmt));
+ op1 = gimple_assign_rhs1 (stmt);
+ op2 = gimple_assign_rhs2 (stmt);
- bb = bb_for_stmt (stmt);
- bsi = bsi_for_stmt (stmt);
+ bb = gimple_bb (stmt);
+ gsi = gsi_for_stmt (stmt);
tmpv = create_tmp_var (optype, "PROF");
tmp1 = create_tmp_var (optype, "PROF");
- stmt1 = build_gimple_modify_stmt (tmpv, fold_convert (optype, value));
- stmt2 = build_gimple_modify_stmt (tmp1, op2);
- stmt3 = build3 (COND_EXPR, void_type_node,
- build2 (NE_EXPR, boolean_type_node, tmp1, tmpv),
- NULL_TREE, NULL_TREE);
- bsi_insert_before (&bsi, stmt1, BSI_SAME_STMT);
- bsi_insert_before (&bsi, stmt2, BSI_SAME_STMT);
- bsi_insert_before (&bsi, stmt3, BSI_SAME_STMT);
+ stmt1 = gimple_build_assign (tmpv, fold_convert (optype, value));
+ stmt2 = gimple_build_assign (tmp1, op2);
+ stmt3 = gimple_build_cond (NE_EXPR, tmp1, tmpv, NULL_TREE, NULL_TREE);
+ gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
+ gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
+ gsi_insert_before (&gsi, stmt3, GSI_SAME_STMT);
bb1end = stmt3;
tmp2 = create_tmp_var (optype, "PROF");
- label1 = build1 (LABEL_EXPR, void_type_node, label_decl1);
- stmt1 = build_gimple_modify_stmt (tmp2,
- build2 (TREE_CODE (operation), optype,
- op1, tmpv));
- bsi_insert_before (&bsi, label1, BSI_SAME_STMT);
- bsi_insert_before (&bsi, stmt1, BSI_SAME_STMT);
+ label1 = gimple_build_label (label_decl1);
+ stmt1 = gimple_build_assign_with_ops (gimple_assign_rhs_code (stmt), tmp2,
+ op1, tmpv);
+ gsi_insert_before (&gsi, label1, GSI_SAME_STMT);
+ gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
bb2end = stmt1;
- label2 = build1 (LABEL_EXPR, void_type_node, label_decl2);
- stmt1 = build_gimple_modify_stmt (tmp2,
- build2 (TREE_CODE (operation), optype,
- op1, op2));
- bsi_insert_before (&bsi, label2, BSI_SAME_STMT);
- bsi_insert_before (&bsi, stmt1, BSI_SAME_STMT);
+ label2 = gimple_build_label (label_decl2);
+ stmt1 = gimple_build_assign_with_ops (gimple_assign_rhs_code (stmt), tmp2,
+ op1, op2);
+ gsi_insert_before (&gsi, label2, GSI_SAME_STMT);
+ gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
bb3end = stmt1;
/* Fix CFG. */
@@ -602,35 +620,33 @@ tree_divmod_fixed_value (tree stmt, tree operation,
return tmp2;
}
+
/* Do transform 1) on INSN if applicable. */
+
static bool
-tree_divmod_fixed_value_transform (tree stmt)
+gimple_divmod_fixed_value_transform (gimple_stmt_iterator *si)
{
histogram_value histogram;
enum tree_code code;
gcov_type val, count, all;
- tree modify, op, op1, op2, result, value, tree_val;
+ tree result, value, tree_val;
gcov_type prob;
+ gimple stmt;
- modify = stmt;
- if (TREE_CODE (stmt) == RETURN_EXPR
- && TREE_OPERAND (stmt, 0)
- && TREE_CODE (TREE_OPERAND (stmt, 0)) == GIMPLE_MODIFY_STMT)
- modify = TREE_OPERAND (stmt, 0);
- if (TREE_CODE (modify) != GIMPLE_MODIFY_STMT)
+ stmt = gsi_stmt (*si);
+ if (gimple_code (stmt) != GIMPLE_ASSIGN)
return false;
- op = GIMPLE_STMT_OPERAND (modify, 1);
- if (!INTEGRAL_TYPE_P (TREE_TYPE (op)))
+
+ if (!INTEGRAL_TYPE_P (TREE_TYPE (gimple_assign_lhs (stmt))))
return false;
- code = TREE_CODE (op);
+
+ code = gimple_assign_rhs_code (stmt);
if (code != TRUNC_DIV_EXPR && code != TRUNC_MOD_EXPR)
return false;
- op1 = TREE_OPERAND (op, 0);
- op2 = TREE_OPERAND (op, 1);
-
- histogram = gimple_histogram_value_of_type (cfun, stmt, HIST_TYPE_SINGLE_VALUE);
+ histogram = gimple_histogram_value_of_type (cfun, stmt,
+ HIST_TYPE_SINGLE_VALUE);
if (!histogram)
return false;
@@ -643,11 +659,12 @@ tree_divmod_fixed_value_transform (tree stmt)
/* We require that count is at least half of all; this means
that for the transformation to fire the value must be constant
at least 50% of time (and 75% gives the guarantee of usage). */
- if (simple_cst_equal (op2, value) != 1 || 2 * count < all
- || !maybe_hot_bb_p (bb_for_stmt (stmt)))
+ if (simple_cst_equal (gimple_assign_rhs2 (stmt), value) != 1
+ || 2 * count < all
+ || !maybe_hot_bb_p (gimple_bb (stmt)))
return false;
- if (check_counter (stmt, "value", all, bb_for_stmt (stmt)->count))
+ if (check_counter (stmt, "value", all, gimple_bb (stmt)->count))
return false;
/* Compute probability of taking the optimal path. */
@@ -659,7 +676,7 @@ tree_divmod_fixed_value_transform (tree stmt)
tree_val = build_int_cst_wide (get_gcov_type (),
(unsigned HOST_WIDE_INT) val,
val >> (HOST_BITS_PER_WIDE_INT - 1) >> 1);
- result = tree_divmod_fixed_value (stmt, op, op1, op2, tree_val, prob, count, all);
+ result = gimple_divmod_fixed_value (stmt, tree_val, prob, count, all);
if (dump_file)
{
@@ -668,68 +685,68 @@ tree_divmod_fixed_value_transform (tree stmt)
fprintf (dump_file, "=");
print_generic_expr (dump_file, tree_val, TDF_SLIM);
fprintf (dump_file, " transformation on insn ");
- print_generic_stmt (dump_file, stmt, TDF_SLIM);
+ print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
}
- GIMPLE_STMT_OPERAND (modify, 1) = result;
+ gimple_assign_set_rhs_from_tree (si, result);
return true;
}
-/* Generate code for transformation 2 (with OPERATION, operands OP1
- and OP2, parent modify-expr STMT and probability of taking the optimal
- path PROB, which is equivalent to COUNT/ALL within roundoff error).
- This generates the result into a temp and returns
+/* Generate code for transformation 2 (with parent gimple assign STMT and
+ probability of taking the optimal path PROB, which is equivalent to COUNT/ALL
+ within roundoff error). This generates the result into a temp and returns
the temp; it does not replace or alter the original STMT. */
static tree
-tree_mod_pow2 (tree stmt, tree operation, tree op1, tree op2, int prob,
- gcov_type count, gcov_type all)
+gimple_mod_pow2 (gimple stmt, int prob, gcov_type count, gcov_type all)
{
- tree stmt1, stmt2, stmt3, stmt4;
+ gimple stmt1, stmt2, stmt3, stmt4;
tree tmp2, tmp3;
tree label_decl1 = create_artificial_label ();
tree label_decl2 = create_artificial_label ();
- tree label1, label2;
- tree bb1end, bb2end, bb3end;
+ gimple label1, label2;
+ gimple bb1end, bb2end, bb3end;
basic_block bb, bb2, bb3, bb4;
- tree optype = TREE_TYPE (operation);
+ tree optype, op1, op2;
edge e12, e13, e23, e24, e34;
- block_stmt_iterator bsi;
- tree result = create_tmp_var (optype, "PROF");
+ gimple_stmt_iterator gsi;
+ tree result;
- bb = bb_for_stmt (stmt);
- bsi = bsi_for_stmt (stmt);
+ gcc_assert (is_gimple_assign (stmt)
+ && gimple_assign_rhs_code (stmt) == TRUNC_MOD_EXPR);
+ optype = TREE_TYPE (gimple_assign_lhs (stmt));
+ op1 = gimple_assign_rhs1 (stmt);
+ op2 = gimple_assign_rhs2 (stmt);
+
+ bb = gimple_bb (stmt);
+ gsi = gsi_for_stmt (stmt);
+
+ result = create_tmp_var (optype, "PROF");
tmp2 = create_tmp_var (optype, "PROF");
tmp3 = create_tmp_var (optype, "PROF");
- stmt2 = build_gimple_modify_stmt (tmp2,
- build2 (PLUS_EXPR, optype, op2,
- build_int_cst (optype, -1)));
- stmt3 = build_gimple_modify_stmt (tmp3,
- build2 (BIT_AND_EXPR, optype, tmp2, op2));
- stmt4 = build3 (COND_EXPR, void_type_node,
- build2 (NE_EXPR, boolean_type_node,
- tmp3, build_int_cst (optype, 0)),
- NULL_TREE, NULL_TREE);
- bsi_insert_before (&bsi, stmt2, BSI_SAME_STMT);
- bsi_insert_before (&bsi, stmt3, BSI_SAME_STMT);
- bsi_insert_before (&bsi, stmt4, BSI_SAME_STMT);
+ stmt2 = gimple_build_assign_with_ops (PLUS_EXPR, tmp2, op2,
+ build_int_cst (optype, -1));
+ stmt3 = gimple_build_assign_with_ops (BIT_AND_EXPR, tmp3, tmp2, op2);
+ stmt4 = gimple_build_cond (NE_EXPR, tmp3, build_int_cst (optype, 0),
+ NULL_TREE, NULL_TREE);
+ gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
+ gsi_insert_before (&gsi, stmt3, GSI_SAME_STMT);
+ gsi_insert_before (&gsi, stmt4, GSI_SAME_STMT);
bb1end = stmt4;
- /* tmp2 == op2-1 inherited from previous block */
- label1 = build1 (LABEL_EXPR, void_type_node, label_decl1);
- stmt1 = build_gimple_modify_stmt (result,
- build2 (BIT_AND_EXPR, optype, op1, tmp2));
- bsi_insert_before (&bsi, label1, BSI_SAME_STMT);
- bsi_insert_before (&bsi, stmt1, BSI_SAME_STMT);
+ /* tmp2 == op2-1 inherited from previous block. */
+ label1 = gimple_build_label (label_decl1);
+ stmt1 = gimple_build_assign_with_ops (BIT_AND_EXPR, result, op1, tmp2);
+ gsi_insert_before (&gsi, label1, GSI_SAME_STMT);
+ gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
bb2end = stmt1;
- label2 = build1 (LABEL_EXPR, void_type_node, label_decl2);
- stmt1 = build_gimple_modify_stmt (result,
- build2 (TREE_CODE (operation), optype,
- op1, op2));
- bsi_insert_before (&bsi, label2, BSI_SAME_STMT);
- bsi_insert_before (&bsi, stmt1, BSI_SAME_STMT);
+ label2 = gimple_build_label (label_decl2);
+ stmt1 = gimple_build_assign_with_ops (gimple_assign_rhs_code (stmt), result,
+ op1, op2);
+ gsi_insert_before (&gsi, label2, GSI_SAME_STMT);
+ gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
bb3end = stmt1;
/* Fix CFG. */
@@ -767,32 +784,28 @@ tree_mod_pow2 (tree stmt, tree operation, tree op1, tree op2, int prob,
/* Do transform 2) on INSN if applicable. */
static bool
-tree_mod_pow2_value_transform (tree stmt)
+gimple_mod_pow2_value_transform (gimple_stmt_iterator *si)
{
histogram_value histogram;
enum tree_code code;
gcov_type count, wrong_values, all;
- tree modify, op, op1, op2, result, value;
+ tree lhs_type, result, value;
gcov_type prob;
+ gimple stmt;
- modify = stmt;
- if (TREE_CODE (stmt) == RETURN_EXPR
- && TREE_OPERAND (stmt, 0)
- && TREE_CODE (TREE_OPERAND (stmt, 0)) == GIMPLE_MODIFY_STMT)
- modify = TREE_OPERAND (stmt, 0);
- if (TREE_CODE (modify) != GIMPLE_MODIFY_STMT)
+ stmt = gsi_stmt (*si);
+ if (gimple_code (stmt) != GIMPLE_ASSIGN)
return false;
- op = GIMPLE_STMT_OPERAND (modify, 1);
- if (!INTEGRAL_TYPE_P (TREE_TYPE (op)))
+
+ lhs_type = TREE_TYPE (gimple_assign_lhs (stmt));
+ if (!INTEGRAL_TYPE_P (lhs_type))
return false;
- code = TREE_CODE (op);
+
+ code = gimple_assign_rhs_code (stmt);
- if (code != TRUNC_MOD_EXPR || !TYPE_UNSIGNED (TREE_TYPE (op)))
+ if (code != TRUNC_MOD_EXPR || !TYPE_UNSIGNED (lhs_type))
return false;
- op1 = TREE_OPERAND (op, 0);
- op2 = TREE_OPERAND (op, 1);
-
histogram = gimple_histogram_value_of_type (cfun, stmt, HIST_TYPE_POW2);
if (!histogram)
return false;
@@ -804,20 +817,21 @@ tree_mod_pow2_value_transform (tree stmt)
gimple_remove_histogram_value (cfun, stmt, histogram);
/* We require that we hit a power of 2 at least half of all evaluations. */
- if (simple_cst_equal (op2, value) != 1 || count < wrong_values
- || !maybe_hot_bb_p (bb_for_stmt (stmt)))
+ if (simple_cst_equal (gimple_assign_rhs2 (stmt), value) != 1
+ || count < wrong_values
+ || !maybe_hot_bb_p (gimple_bb (stmt)))
return false;
if (dump_file)
{
fprintf (dump_file, "Mod power of 2 transformation on insn ");
- print_generic_stmt (dump_file, stmt, TDF_SLIM);
+ print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
}
/* Compute probability of taking the optimal path. */
all = count + wrong_values;
- if (check_counter (stmt, "pow2", all, bb_for_stmt (stmt)->count))
+ if (check_counter (stmt, "pow2", all, gimple_bb (stmt)->count))
return false;
if (all > 0)
@@ -825,81 +839,80 @@ tree_mod_pow2_value_transform (tree stmt)
else
prob = 0;
- result = tree_mod_pow2 (stmt, op, op1, op2, prob, count, all);
+ result = gimple_mod_pow2 (stmt, prob, count, all);
- GIMPLE_STMT_OPERAND (modify, 1) = result;
+ gimple_assign_set_rhs_from_tree (si, result);
return true;
}
-/* Generate code for transformations 3 and 4 (with OPERATION, operands OP1
- and OP2, parent modify-expr STMT, and NCOUNTS the number of cases to
- support. Currently only NCOUNTS==0 or 1 is supported and this is
- built into this interface. The probabilities of taking the optimal
- paths are PROB1 and PROB2, which are equivalent to COUNT1/ALL and
+/* Generate code for transformations 3 and 4 (with parent gimple assign STMT, and
+ NCOUNTS the number of cases to support. Currently only NCOUNTS==0 or 1 is
+ supported and this is built into this interface. The probabilities of taking
+ the optimal paths are PROB1 and PROB2, which are equivalent to COUNT1/ALL and
COUNT2/ALL respectively within roundoff error). This generates the
result into a temp and returns the temp; it does not replace or alter
the original STMT. */
/* FIXME: Generalize the interface to handle NCOUNTS > 1. */
static tree
-tree_mod_subtract (tree stmt, tree operation, tree op1, tree op2,
- int prob1, int prob2, int ncounts,
- gcov_type count1, gcov_type count2, gcov_type all)
+gimple_mod_subtract (gimple stmt, int prob1, int prob2, int ncounts,
+ gcov_type count1, gcov_type count2, gcov_type all)
{
- tree stmt1, stmt2, stmt3;
+ gimple stmt1, stmt2, stmt3;
tree tmp1;
tree label_decl1 = create_artificial_label ();
tree label_decl2 = create_artificial_label ();
tree label_decl3 = create_artificial_label ();
- tree label1, label2, label3;
- tree bb1end, bb2end = NULL_TREE, bb3end;
+ gimple label1, label2, label3;
+ gimple bb1end, bb2end = NULL, bb3end;
basic_block bb, bb2, bb3, bb4;
- tree optype = TREE_TYPE (operation);
+ tree optype, op1, op2;
edge e12, e23 = 0, e24, e34, e14;
- block_stmt_iterator bsi;
- tree result = create_tmp_var (optype, "PROF");
+ gimple_stmt_iterator gsi;
+ tree result;
+
+ gcc_assert (is_gimple_assign (stmt)
+ && gimple_assign_rhs_code (stmt) == TRUNC_MOD_EXPR);
- bb = bb_for_stmt (stmt);
- bsi = bsi_for_stmt (stmt);
+ optype = TREE_TYPE (gimple_assign_lhs (stmt));
+ op1 = gimple_assign_rhs1 (stmt);
+ op2 = gimple_assign_rhs2 (stmt);
+ bb = gimple_bb (stmt);
+ gsi = gsi_for_stmt (stmt);
+
+ result = create_tmp_var (optype, "PROF");
tmp1 = create_tmp_var (optype, "PROF");
- stmt1 = build_gimple_modify_stmt (result, op1);
- stmt2 = build_gimple_modify_stmt (tmp1, op2);
- stmt3 = build3 (COND_EXPR, void_type_node,
- build2 (LT_EXPR, boolean_type_node, result, tmp1),
- NULL_TREE, NULL_TREE);
- bsi_insert_before (&bsi, stmt1, BSI_SAME_STMT);
- bsi_insert_before (&bsi, stmt2, BSI_SAME_STMT);
- bsi_insert_before (&bsi, stmt3, BSI_SAME_STMT);
+ stmt1 = gimple_build_assign (result, op1);
+ stmt2 = gimple_build_assign (tmp1, op2);
+ stmt3 = gimple_build_cond (LT_EXPR, result, tmp1, NULL_TREE, NULL_TREE);
+ gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
+ gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
+ gsi_insert_before (&gsi, stmt3, GSI_SAME_STMT);
bb1end = stmt3;
if (ncounts) /* Assumed to be 0 or 1 */
{
- label1 = build1 (LABEL_EXPR, void_type_node, label_decl1);
- stmt1 = build_gimple_modify_stmt (result,
- build2 (MINUS_EXPR, optype,
- result, tmp1));
- stmt2 = build3 (COND_EXPR, void_type_node,
- build2 (LT_EXPR, boolean_type_node, result, tmp1),
- NULL_TREE, NULL_TREE);
- bsi_insert_before (&bsi, label1, BSI_SAME_STMT);
- bsi_insert_before (&bsi, stmt1, BSI_SAME_STMT);
- bsi_insert_before (&bsi, stmt2, BSI_SAME_STMT);
+ label1 = gimple_build_label (label_decl1);
+ stmt1 = gimple_build_assign_with_ops (MINUS_EXPR, result, result, tmp1);
+ stmt2 = gimple_build_cond (LT_EXPR, result, tmp1, NULL_TREE, NULL_TREE);
+ gsi_insert_before (&gsi, label1, GSI_SAME_STMT);
+ gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
+ gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
bb2end = stmt2;
}
/* Fallback case. */
- label2 = build1 (LABEL_EXPR, void_type_node, label_decl2);
- stmt1 = build_gimple_modify_stmt (result,
- build2 (TREE_CODE (operation), optype,
- result, tmp1));
- bsi_insert_before (&bsi, label2, BSI_SAME_STMT);
- bsi_insert_before (&bsi, stmt1, BSI_SAME_STMT);
+ label2 = gimple_build_label (label_decl2);
+ stmt1 = gimple_build_assign_with_ops (gimple_assign_rhs_code (stmt), result,
+ result, tmp1);
+ gsi_insert_before (&gsi, label2, GSI_SAME_STMT);
+ gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
bb3end = stmt1;
- label3 = build1 (LABEL_EXPR, void_type_node, label_decl3);
- bsi_insert_before (&bsi, label3, BSI_SAME_STMT);
+ label3 = gimple_build_label (label_decl3);
+ gsi_insert_before (&gsi, label3, GSI_SAME_STMT);
/* Fix CFG. */
/* Edge e23 connects bb2 to bb3, etc. */
@@ -947,36 +960,34 @@ tree_mod_subtract (tree stmt, tree operation, tree op1, tree op2,
return result;
}
-/* Do transforms 3) and 4) on INSN if applicable. */
+
+/* Do transforms 3) and 4) on the statement pointed-to by SI if applicable. */
+
static bool
-tree_mod_subtract_transform (tree stmt)
+gimple_mod_subtract_transform (gimple_stmt_iterator *si)
{
histogram_value histogram;
enum tree_code code;
gcov_type count, wrong_values, all;
- tree modify, op, op1, op2, result, value;
+ tree lhs_type, result, value;
gcov_type prob1, prob2;
unsigned int i, steps;
gcov_type count1, count2;
+ gimple stmt;
- modify = stmt;
- if (TREE_CODE (stmt) == RETURN_EXPR
- && TREE_OPERAND (stmt, 0)
- && TREE_CODE (TREE_OPERAND (stmt, 0)) == GIMPLE_MODIFY_STMT)
- modify = TREE_OPERAND (stmt, 0);
- if (TREE_CODE (modify) != GIMPLE_MODIFY_STMT)
+ stmt = gsi_stmt (*si);
+ if (gimple_code (stmt) != GIMPLE_ASSIGN)
return false;
- op = GIMPLE_STMT_OPERAND (modify, 1);
- if (!INTEGRAL_TYPE_P (TREE_TYPE (op)))
+
+ lhs_type = TREE_TYPE (gimple_assign_lhs (stmt));
+ if (!INTEGRAL_TYPE_P (lhs_type))
return false;
- code = TREE_CODE (op);
+
+ code = gimple_assign_rhs_code (stmt);
- if (code != TRUNC_MOD_EXPR || !TYPE_UNSIGNED (TREE_TYPE (op)))
+ if (code != TRUNC_MOD_EXPR || !TYPE_UNSIGNED (lhs_type))
return false;
- op1 = TREE_OPERAND (op, 0);
- op2 = TREE_OPERAND (op, 1);
-
histogram = gimple_histogram_value_of_type (cfun, stmt, HIST_TYPE_INTERVAL);
if (!histogram)
return false;
@@ -995,7 +1006,7 @@ tree_mod_subtract_transform (tree stmt)
count2 = histogram->hvalue.counters[1];
/* Compute probability of taking the optimal path. */
- if (check_counter (stmt, "interval", all, bb_for_stmt (stmt)->count))
+ if (check_counter (stmt, "interval", all, gimple_bb (stmt)->count))
{
gimple_remove_histogram_value (cfun, stmt, histogram);
return false;
@@ -1011,14 +1022,14 @@ tree_mod_subtract_transform (tree stmt)
break;
}
if (i == steps
- || !maybe_hot_bb_p (bb_for_stmt (stmt)))
+ || !maybe_hot_bb_p (gimple_bb (stmt)))
return false;
gimple_remove_histogram_value (cfun, stmt, histogram);
if (dump_file)
{
fprintf (dump_file, "Mod subtract transformation on insn ");
- print_generic_stmt (dump_file, stmt, TDF_SLIM);
+ print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
}
/* Compute probability of taking the optimal path(s). */
@@ -1034,10 +1045,9 @@ tree_mod_subtract_transform (tree stmt)
/* In practice, "steps" is always 2. This interface reflects this,
and will need to be changed if "steps" can change. */
- result = tree_mod_subtract (stmt, op, op1, op2, prob1, prob2, i,
- count1, count2, all);
+ result = gimple_mod_subtract (stmt, prob1, prob2, i, count1, count2, all);
- GIMPLE_STMT_OPERAND (modify, 1) = result;
+ gimple_assign_set_rhs_from_tree (si, result);
return true;
}
@@ -1082,52 +1092,48 @@ find_func_by_pid (int pid)
old call
*/
-static tree
-tree_ic (tree stmt, tree call, struct cgraph_node* direct_call,
- int prob, gcov_type count, gcov_type all)
+static gimple
+gimple_ic (gimple stmt, gimple call, struct cgraph_node *direct_call,
+ int prob, gcov_type count, gcov_type all)
{
- tree stmt1, stmt2, stmt3;
+ gimple stmt1, stmt2, stmt3;
tree tmp1, tmpv, tmp;
tree label_decl1 = create_artificial_label ();
tree label_decl2 = create_artificial_label ();
- tree label1, label2;
- tree bb1end, bb2end, bb3end;
- tree new_call;
+ gimple label1, label2;
+ gimple bb1end, bb2end, bb3end;
basic_block bb, bb2, bb3, bb4;
tree optype = build_pointer_type (void_type_node);
edge e12, e13, e23, e24, e34;
- block_stmt_iterator bsi;
+ gimple_stmt_iterator gsi;
int region;
- bb = bb_for_stmt (stmt);
- bsi = bsi_for_stmt (stmt);
+ bb = gimple_bb (stmt);
+ gsi = gsi_for_stmt (stmt);
tmpv = create_tmp_var (optype, "PROF");
tmp1 = create_tmp_var (optype, "PROF");
- stmt1 = build_gimple_modify_stmt (tmpv,
- unshare_expr (CALL_EXPR_FN (call)));
+ stmt1 = gimple_build_assign (tmpv, unshare_expr (gimple_call_fn (call)));
+
tmp = fold_convert (optype, build_addr (direct_call->decl,
current_function_decl));
- stmt2 = build_gimple_modify_stmt (tmp1, tmp);
- stmt3 = build3 (COND_EXPR, void_type_node,
- build2 (NE_EXPR, boolean_type_node, tmp1, tmpv),
- NULL_TREE, NULL_TREE);
- bsi_insert_before (&bsi, stmt1, BSI_SAME_STMT);
- bsi_insert_before (&bsi, stmt2, BSI_SAME_STMT);
- bsi_insert_before (&bsi, stmt3, BSI_SAME_STMT);
+ stmt2 = gimple_build_assign (tmp1, tmp);
+ stmt3 = gimple_build_cond (NE_EXPR, tmp1, tmpv, NULL_TREE, NULL_TREE);
+ gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
+ gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
+ gsi_insert_before (&gsi, stmt3, GSI_SAME_STMT);
bb1end = stmt3;
- label1 = build1 (LABEL_EXPR, void_type_node, label_decl1);
- stmt1 = unshare_expr (stmt);
- new_call = get_call_expr_in (stmt1);
- CALL_EXPR_FN (new_call) = build_addr (direct_call->decl,
- current_function_decl);
- bsi_insert_before (&bsi, label1, BSI_SAME_STMT);
- bsi_insert_before (&bsi, stmt1, BSI_SAME_STMT);
+ label1 = gimple_build_label (label_decl1);
+ stmt1 = gimple_copy (stmt);
+ gimple_call_set_fn (stmt,
+ build_addr (direct_call->decl, current_function_decl));
+ gsi_insert_before (&gsi, label1, GSI_SAME_STMT);
+ gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
bb2end = stmt1;
- label2 = build1 (LABEL_EXPR, void_type_node, label_decl2);
- bsi_insert_before (&bsi, label2, BSI_SAME_STMT);
+ label2 = gimple_build_label (label_decl2);
+ gsi_insert_before (&gsi, label2, GSI_SAME_STMT);
bb3end = stmt;
/* Fix CFG. */
@@ -1161,15 +1167,15 @@ tree_ic (tree stmt, tree call, struct cgraph_node* direct_call,
/* Fix eh edges */
region = lookup_stmt_eh_region (stmt);
- if (region >=0 && tree_could_throw_p (stmt1))
+ if (region >= 0 && stmt_could_throw_p (stmt1))
{
add_stmt_to_eh_region (stmt1, region);
make_eh_edges (stmt1);
}
- if (region >=0 && tree_could_throw_p (stmt))
+ if (region >= 0 && stmt_could_throw_p (stmt))
{
- tree_purge_dead_eh_edges (bb4);
+ gimple_purge_dead_eh_edges (bb4);
make_eh_edges (stmt);
}
@@ -1183,22 +1189,21 @@ tree_ic (tree stmt, tree call, struct cgraph_node* direct_call,
*/
static bool
-tree_ic_transform (tree stmt)
+gimple_ic_transform (gimple stmt)
{
histogram_value histogram;
gcov_type val, count, all;
gcov_type prob;
- tree call, callee, modify;
+ tree callee;
+ gimple modify;
struct cgraph_node *direct_call;
- call = get_call_expr_in (stmt);
-
- if (!call || TREE_CODE (call) != CALL_EXPR)
+ if (gimple_code (stmt) != GIMPLE_CALL)
return false;
- callee = CALL_EXPR_FN (call);
+ callee = gimple_call_fn (stmt);
- if (TREE_CODE (callee) == ADDR_EXPR)
+ if (TREE_CODE (callee) == FUNCTION_DECL)
return false;
histogram = gimple_histogram_value_of_type (cfun, stmt, HIST_TYPE_INDIR_CALL);
@@ -1222,18 +1227,18 @@ tree_ic_transform (tree stmt)
if (direct_call == NULL)
return false;
- modify = tree_ic (stmt, call, direct_call, prob, count, all);
+ modify = gimple_ic (stmt, stmt, direct_call, prob, count, all);
if (dump_file)
{
fprintf (dump_file, "Indirect call -> direct call ");
- print_generic_expr (dump_file, call, TDF_SLIM);
+ print_generic_expr (dump_file, gimple_call_fn (stmt), TDF_SLIM);
fprintf (dump_file, "=> ");
print_generic_expr (dump_file, direct_call->decl, TDF_SLIM);
fprintf (dump_file, " transformation on insn ");
- print_generic_stmt (dump_file, stmt, TDF_SLIM);
+ print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
fprintf (dump_file, " to ");
- print_generic_stmt (dump_file, modify, TDF_SLIM);
+ print_gimple_stmt (dump_file, modify, 0, TDF_SLIM);
fprintf (dump_file, "hist->count "HOST_WIDEST_INT_PRINT_DEC
" hist->all "HOST_WIDEST_INT_PRINT_DEC"\n", count, all);
}
@@ -1243,7 +1248,7 @@ tree_ic_transform (tree stmt)
/* Return true if the stringop CALL with FNDECL shall be profiled. */
static bool
-interesting_stringop_to_profile_p (tree fndecl, tree call)
+interesting_stringop_to_profile_p (tree fndecl, gimple call)
{
enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
@@ -1255,16 +1260,14 @@ interesting_stringop_to_profile_p (tree fndecl, tree call)
{
case BUILT_IN_MEMCPY:
case BUILT_IN_MEMPCPY:
- return validate_arglist (call,
- POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
- VOID_TYPE);
+ return validate_gimple_arglist (call, POINTER_TYPE, POINTER_TYPE,
+ INTEGER_TYPE, VOID_TYPE);
case BUILT_IN_MEMSET:
- return validate_arglist (call,
- POINTER_TYPE, INTEGER_TYPE, INTEGER_TYPE,
- VOID_TYPE);
+ return validate_gimple_arglist (call, POINTER_TYPE, INTEGER_TYPE,
+ INTEGER_TYPE, VOID_TYPE);
case BUILT_IN_BZERO:
- return validate_arglist (call, POINTER_TYPE, INTEGER_TYPE,
- VOID_TYPE);
+ return validate_gimple_arglist (call, POINTER_TYPE, INTEGER_TYPE,
+ VOID_TYPE);
default:
gcc_unreachable ();
}
@@ -1279,27 +1282,26 @@ interesting_stringop_to_profile_p (tree fndecl, tree call)
assuming constant propagation of VALUE will happen later.
*/
static void
-tree_stringop_fixed_value (tree stmt, tree value, int prob, gcov_type count,
+gimple_stringop_fixed_value (gimple stmt, tree value, int prob, gcov_type count,
gcov_type all)
{
- tree stmt1, stmt2, stmt3;
+ gimple stmt1, stmt2, stmt3;
tree tmp1, tmpv;
tree label_decl1 = create_artificial_label ();
tree label_decl2 = create_artificial_label ();
- tree label1, label2;
- tree bb1end, bb2end;
+ gimple label1, label2;
+ gimple bb1end, bb2end;
basic_block bb, bb2, bb3, bb4;
edge e12, e13, e23, e24, e34;
- block_stmt_iterator bsi;
- tree call = get_call_expr_in (stmt);
- tree blck_size = CALL_EXPR_ARG (call, 2);
+ gimple_stmt_iterator gsi;
+ tree blck_size = gimple_call_arg (stmt, 2);
tree optype = TREE_TYPE (blck_size);
int region;
- bb = bb_for_stmt (stmt);
- bsi = bsi_for_stmt (stmt);
+ bb = gimple_bb (stmt);
+ gsi = gsi_for_stmt (stmt);
- if (bsi_end_p (bsi))
+ if (gsi_end_p (gsi))
{
edge_iterator ei;
for (ei = ei_start (bb->succs); (e34 = ei_safe_edge (ei)); )
@@ -1309,34 +1311,31 @@ tree_stringop_fixed_value (tree stmt, tree value, int prob, gcov_type count,
else
{
e34 = split_block (bb, stmt);
- bsi = bsi_for_stmt (stmt);
+ gsi = gsi_for_stmt (stmt);
}
bb4 = e34->dest;
tmpv = create_tmp_var (optype, "PROF");
tmp1 = create_tmp_var (optype, "PROF");
- stmt1 = build_gimple_modify_stmt (tmpv, fold_convert (optype, value));
- stmt2 = build_gimple_modify_stmt (tmp1, blck_size);
- stmt3 = build3 (COND_EXPR, void_type_node,
- build2 (NE_EXPR, boolean_type_node, tmp1, tmpv),
- NULL_TREE, NULL_TREE);
- bsi_insert_before (&bsi, stmt1, BSI_SAME_STMT);
- bsi_insert_before (&bsi, stmt2, BSI_SAME_STMT);
- bsi_insert_before (&bsi, stmt3, BSI_SAME_STMT);
+ stmt1 = gimple_build_assign (tmpv, fold_convert (optype, value));
+ stmt2 = gimple_build_assign (tmp1, blck_size);
+ stmt3 = gimple_build_cond (NE_EXPR, tmp1, tmpv, NULL_TREE, NULL_TREE);
+ gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
+ gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
+ gsi_insert_before (&gsi, stmt3, GSI_SAME_STMT);
bb1end = stmt3;
- label1 = build1 (LABEL_EXPR, void_type_node, label_decl1);
- stmt1 = unshare_expr (stmt);
- call = get_call_expr_in (stmt1);
- CALL_EXPR_ARG (call, 2) = value;
- bsi_insert_before (&bsi, label1, BSI_SAME_STMT);
- bsi_insert_before (&bsi, stmt1, BSI_SAME_STMT);
+ label1 = gimple_build_label (label_decl1);
+ stmt1 = gimple_copy (stmt);
+ gimple_call_set_arg (stmt1, 2, value);
+ gsi_insert_before (&gsi, label1, GSI_SAME_STMT);
+ gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
region = lookup_stmt_eh_region (stmt);
if (region >= 0)
add_stmt_to_eh_region (stmt1, region);
bb2end = stmt1;
- label2 = build1 (LABEL_EXPR, void_type_node, label_decl2);
- bsi_insert_before (&bsi, label2, BSI_SAME_STMT);
+ label2 = gimple_build_label (label_decl2);
+ gsi_insert_before (&gsi, label2, GSI_SAME_STMT);
/* Fix CFG. */
/* Edge e23 connects bb2 to bb3, etc. */
@@ -1369,10 +1368,9 @@ tree_stringop_fixed_value (tree stmt, tree value, int prob, gcov_type count,
/* Find values inside STMT for that we want to measure histograms for
division/modulo optimization. */
static bool
-tree_stringops_transform (block_stmt_iterator *bsi)
+gimple_stringops_transform (gimple_stmt_iterator *gsi)
{
- tree stmt = bsi_stmt (*bsi);
- tree call = get_call_expr_in (stmt);
+ gimple stmt = gsi_stmt (*gsi);
tree fndecl;
tree blck_size;
enum built_in_function fcode;
@@ -1384,19 +1382,19 @@ tree_stringops_transform (block_stmt_iterator *bsi)
gcov_type prob;
tree tree_val;
- if (!call)
+ if (gimple_code (stmt) != GIMPLE_CALL)
return false;
- fndecl = get_callee_fndecl (call);
+ fndecl = gimple_call_fndecl (stmt);
if (!fndecl)
return false;
fcode = DECL_FUNCTION_CODE (fndecl);
- if (!interesting_stringop_to_profile_p (fndecl, call))
+ if (!interesting_stringop_to_profile_p (fndecl, stmt))
return false;
if (fcode == BUILT_IN_BZERO)
- blck_size = CALL_EXPR_ARG (call, 1);
+ blck_size = gimple_call_arg (stmt, 1);
else
- blck_size = CALL_EXPR_ARG (call, 2);
+ blck_size = gimple_call_arg (stmt, 2);
if (TREE_CODE (blck_size) == INTEGER_CST)
return false;
@@ -1411,28 +1409,28 @@ tree_stringops_transform (block_stmt_iterator *bsi)
/* We require that count is at least half of all; this means
that for the transformation to fire the value must be constant
at least 80% of time. */
- if ((6 * count / 5) < all || !maybe_hot_bb_p (bb_for_stmt (stmt)))
+ if ((6 * count / 5) < all || !maybe_hot_bb_p (gimple_bb (stmt)))
return false;
- if (check_counter (stmt, "value", all, bb_for_stmt (stmt)->count))
+ if (check_counter (stmt, "value", all, gimple_bb (stmt)->count))
return false;
if (all > 0)
prob = (count * REG_BR_PROB_BASE + all / 2) / all;
else
prob = 0;
- dest = CALL_EXPR_ARG (call, 0);
+ dest = gimple_call_arg (stmt, 0);
dest_align = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
switch (fcode)
{
case BUILT_IN_MEMCPY:
case BUILT_IN_MEMPCPY:
- src = CALL_EXPR_ARG (call, 1);
+ src = gimple_call_arg (stmt, 1);
src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
if (!can_move_by_pieces (val, MIN (dest_align, src_align)))
return false;
break;
case BUILT_IN_MEMSET:
if (!can_store_by_pieces (val, builtin_memset_read_str,
- CALL_EXPR_ARG (call, 1),
+ gimple_call_arg (stmt, 1),
dest_align, true))
return false;
break;
@@ -1452,15 +1450,15 @@ tree_stringops_transform (block_stmt_iterator *bsi)
{
fprintf (dump_file, "Single value %i stringop transformation on ",
(int)val);
- print_generic_stmt (dump_file, stmt, TDF_SLIM);
+ print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
}
- tree_stringop_fixed_value (stmt, tree_val, prob, count, all);
+ gimple_stringop_fixed_value (stmt, tree_val, prob, count, all);
return true;
}
void
-stringop_block_profile (tree stmt, unsigned int *expected_align,
+stringop_block_profile (gimple stmt, unsigned int *expected_align,
HOST_WIDE_INT *expected_size)
{
histogram_value histogram;
@@ -1520,31 +1518,25 @@ struct value_prof_hooks {
/* Find values inside STMT for that we want to measure histograms for
division/modulo optimization. */
static void
-tree_divmod_values_to_profile (tree stmt, histogram_values *values)
+gimple_divmod_values_to_profile (gimple stmt, histogram_values *values)
{
- tree assign, lhs, rhs, divisor, op0, type;
+ tree lhs, divisor, op0, type;
histogram_value hist;
- if (TREE_CODE (stmt) == RETURN_EXPR)
- assign = TREE_OPERAND (stmt, 0);
- else
- assign = stmt;
-
- if (!assign
- || TREE_CODE (assign) != GIMPLE_MODIFY_STMT)
+ if (gimple_code (stmt) != GIMPLE_ASSIGN)
return;
- lhs = GIMPLE_STMT_OPERAND (assign, 0);
+
+ lhs = gimple_assign_lhs (stmt);
type = TREE_TYPE (lhs);
if (!INTEGRAL_TYPE_P (type))
return;
- rhs = GIMPLE_STMT_OPERAND (assign, 1);
- switch (TREE_CODE (rhs))
+ switch (gimple_assign_rhs_code (stmt))
{
case TRUNC_DIV_EXPR:
case TRUNC_MOD_EXPR:
- divisor = TREE_OPERAND (rhs, 1);
- op0 = TREE_OPERAND (rhs, 0);
+ divisor = gimple_assign_rhs2 (stmt);
+ op0 = gimple_assign_rhs1 (stmt);
VEC_reserve (histogram_value, heap, *values, 3);
@@ -1552,12 +1544,13 @@ tree_divmod_values_to_profile (tree stmt, histogram_values *values)
/* Check for the case where the divisor is the same value most
of the time. */
VEC_quick_push (histogram_value, *values,
- gimple_alloc_histogram_value (cfun, HIST_TYPE_SINGLE_VALUE,
+ gimple_alloc_histogram_value (cfun,
+ HIST_TYPE_SINGLE_VALUE,
stmt, divisor));
/* For mod, check whether it is not often a noop (or replaceable by
a few subtractions). */
- if (TREE_CODE (rhs) == TRUNC_MOD_EXPR
+ if (gimple_assign_rhs_code (stmt) == TRUNC_MOD_EXPR
&& TYPE_UNSIGNED (type))
{
tree val;
@@ -1584,19 +1577,16 @@ tree_divmod_values_to_profile (tree stmt, histogram_values *values)
indirect/virtual call optimization. */
static void
-tree_indirect_call_to_profile (tree stmt, histogram_values *values)
+gimple_indirect_call_to_profile (gimple stmt, histogram_values *values)
{
- tree call;
- tree callee;
-
- call = get_call_expr_in (stmt);
+ tree callee;
- if (!call || TREE_CODE (call) != CALL_EXPR)
+ if (gimple_code (stmt) != GIMPLE_CALL)
return;
- callee = CALL_EXPR_FN (call);
+ callee = gimple_call_fn (stmt);
- if (TREE_CODE (callee) == ADDR_EXPR)
+ if (TREE_CODE (callee) == FUNCTION_DECL)
return;
VEC_reserve (histogram_value, heap, *values, 3);
@@ -1611,29 +1601,28 @@ tree_indirect_call_to_profile (tree stmt, histogram_values *values)
/* Find values inside STMT for that we want to measure histograms for
string operations. */
static void
-tree_stringops_values_to_profile (tree stmt, histogram_values *values)
+gimple_stringops_values_to_profile (gimple stmt, histogram_values *values)
{
- tree call = get_call_expr_in (stmt);
tree fndecl;
tree blck_size;
tree dest;
enum built_in_function fcode;
- if (!call)
+ if (gimple_code (stmt) != GIMPLE_CALL)
return;
- fndecl = get_callee_fndecl (call);
+ fndecl = gimple_call_fndecl (stmt);
if (!fndecl)
return;
fcode = DECL_FUNCTION_CODE (fndecl);
- if (!interesting_stringop_to_profile_p (fndecl, call))
+ if (!interesting_stringop_to_profile_p (fndecl, stmt))
return;
- dest = CALL_EXPR_ARG (call, 0);
+ dest = gimple_call_arg (stmt, 0);
if (fcode == BUILT_IN_BZERO)
- blck_size = CALL_EXPR_ARG (call, 1);
+ blck_size = gimple_call_arg (stmt, 1);
else
- blck_size = CALL_EXPR_ARG (call, 2);
+ blck_size = gimple_call_arg (stmt, 2);
if (TREE_CODE (blck_size) != INTEGER_CST)
{
@@ -1654,28 +1643,28 @@ tree_stringops_values_to_profile (tree stmt, histogram_values *values)
them to list VALUES. */
static void
-tree_values_to_profile (tree stmt, histogram_values *values)
+gimple_values_to_profile (gimple stmt, histogram_values *values)
{
if (flag_value_profile_transformations)
{
- tree_divmod_values_to_profile (stmt, values);
- tree_stringops_values_to_profile (stmt, values);
- tree_indirect_call_to_profile (stmt, values);
+ gimple_divmod_values_to_profile (stmt, values);
+ gimple_stringops_values_to_profile (stmt, values);
+ gimple_indirect_call_to_profile (stmt, values);
}
}
static void
-tree_find_values_to_profile (histogram_values *values)
+gimple_find_values_to_profile (histogram_values *values)
{
basic_block bb;
- block_stmt_iterator bsi;
+ gimple_stmt_iterator gsi;
unsigned i;
histogram_value hist = NULL;
*values = NULL;
FOR_EACH_BB (bb)
- for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
- tree_values_to_profile (bsi_stmt (bsi), values);
+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+ gimple_values_to_profile (gsi_stmt (gsi), values);
for (i = 0; VEC_iterate (histogram_value, *values, i, hist); i++)
{
@@ -1715,22 +1704,22 @@ tree_find_values_to_profile (histogram_values *values)
if (dump_file)
{
fprintf (dump_file, "Stmt ");
- print_generic_expr (dump_file, hist->hvalue.stmt, TDF_SLIM);
+ print_gimple_stmt (dump_file, hist->hvalue.stmt, 0, TDF_SLIM);
dump_histogram_value (dump_file, hist);
}
}
}
-static struct value_prof_hooks tree_value_prof_hooks = {
- tree_find_values_to_profile,
- tree_value_profile_transformations
+static struct value_prof_hooks gimple_value_prof_hooks = {
+ gimple_find_values_to_profile,
+ gimple_value_profile_transformations
};
void
-tree_register_value_prof_hooks (void)
+gimple_register_value_prof_hooks (void)
{
gcc_assert (current_ir_type () == IR_GIMPLE);
- value_prof_hooks = &tree_value_prof_hooks;
+ value_prof_hooks = &gimple_value_prof_hooks;
}
/* IR-independent entry points. */
diff --git a/gcc/value-prof.h b/gcc/value-prof.h
index 2ab9df1cb53..e66f4e2046a 100644
--- a/gcc/value-prof.h
+++ b/gcc/value-prof.h
@@ -46,7 +46,7 @@ struct histogram_value_t
struct
{
tree value; /* The value to profile. */
- tree stmt; /* Insn containing the value. */
+ gimple stmt; /* Insn containing the value. */
gcov_type *counters; /* Pointer to first counter. */
struct histogram_value_t *next; /* Linked list pointer. */
} hvalue;
@@ -71,7 +71,7 @@ DEF_VEC_ALLOC_P(histogram_value,heap);
typedef VEC(histogram_value,heap) *histogram_values;
/* Hooks registration. */
-extern void tree_register_value_prof_hooks (void);
+extern void gimple_register_value_prof_hooks (void);
/* IR-independent entry points. */
extern void find_values_to_profile (histogram_values *);
@@ -109,17 +109,19 @@ struct profile_hooks {
void (*gen_ior_profiler) (histogram_value, unsigned, unsigned);
};
-histogram_value gimple_histogram_value (struct function *, tree);
-histogram_value gimple_histogram_value_of_type (struct function *, tree, enum hist_type);
-void gimple_add_histogram_value (struct function *, tree, histogram_value);
-void dump_histograms_for_stmt (struct function *, FILE *, tree);
-void gimple_remove_histogram_value (struct function *, tree, histogram_value);
-void gimple_remove_stmt_histograms (struct function *, tree);
-void gimple_duplicate_stmt_histograms (struct function *, tree, struct function *, tree);
-void gimple_move_stmt_histograms (struct function *, tree, tree);
+histogram_value gimple_histogram_value (struct function *, gimple);
+histogram_value gimple_histogram_value_of_type (struct function *, gimple,
+ enum hist_type);
+void gimple_add_histogram_value (struct function *, gimple, histogram_value);
+void dump_histograms_for_stmt (struct function *, FILE *, gimple);
+void gimple_remove_histogram_value (struct function *, gimple, histogram_value);
+void gimple_remove_stmt_histograms (struct function *, gimple);
+void gimple_duplicate_stmt_histograms (struct function *, gimple,
+ struct function *, gimple);
+void gimple_move_stmt_histograms (struct function *, gimple, gimple);
void verify_histograms (void);
void free_histograms (void);
-void stringop_block_profile (tree, unsigned int *, HOST_WIDE_INT *);
+void stringop_block_profile (gimple, unsigned int *, HOST_WIDE_INT *);
/* In profile.c. */
extern void init_branch_prob (void);
diff --git a/gcc/varasm.c b/gcc/varasm.c
index d8c611444d3..941716f73bd 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -470,9 +470,9 @@ static int
section_entry_eq (const void *p1, const void *p2)
{
const section *old = (const section *) p1;
- const char *new = (const char *) p2;
+ const char *new_name = (const char *) p2;
- return strcmp (old->named.name, new) == 0;
+ return strcmp (old->named.name, new_name) == 0;
}
static hashval_t
@@ -498,9 +498,9 @@ static int
object_block_entry_eq (const void *p1, const void *p2)
{
const struct object_block *old = (const struct object_block *) p1;
- const section *new = (const section *) p2;
+ const section *new_section = (const section *) p2;
- return old->sect == new;
+ return old->sect == new_section;
}
static hashval_t
@@ -2228,7 +2228,7 @@ contains_pointers_p (tree type)
}
}
-/* In unit-at-a-time mode, we delay assemble_external processing until
+/* We delay assemble_external processing until
the compilation unit is finalized. This is the best we can do for
right now (i.e. stage 3 of GCC 4.0) - the right thing is to delay
it all the way to final. See PR 17982 for further discussion. */
@@ -5380,7 +5380,10 @@ assemble_alias (tree decl, tree target)
/* If the target has already been emitted, we don't have to queue the
alias. This saves a tad of memory. */
- target_decl = find_decl_and_mark_needed (decl, target);
+ if (cgraph_global_info_ready)
+ target_decl = find_decl_and_mark_needed (decl, target);
+ else
+ target_decl= NULL;
if (target_decl && TREE_ASM_WRITTEN (target_decl))
do_assemble_alias (decl, target);
else
diff --git a/gcc/varpool.c b/gcc/varpool.c
index 4149c1d1d21..1d1cc9ed630 100644
--- a/gcc/varpool.c
+++ b/gcc/varpool.c
@@ -32,7 +32,7 @@ along with GCC; see the file COPYING3. If not see
#include "debug.h"
#include "target.h"
#include "output.h"
-#include "tree-gimple.h"
+#include "gimple.h"
#include "tree-flow.h"
/* This file contains basic routines manipulating variable pool.
@@ -61,7 +61,7 @@ struct varpool_node *varpool_nodes;
maintained in forward order. GTY is needed to make it friendly to
PCH.
- During unit-at-a-time compilation we construct the queue of needed variables
+ During compilation we construct the queue of needed variables
twice: first time it is during cgraph construction, second time it is at the
end of compilation in VARPOOL_REMOVE_UNREFERENCED_DECLS so we can avoid
optimized out variables being output.
@@ -214,17 +214,13 @@ varpool_reset_queue (void)
/* Determine if variable DECL is needed. That is, visible to something
either outside this translation unit, something magic in the system
- configury, or (if not doing unit-at-a-time) to something we haven't
- seen yet. */
+ configury */
bool
decide_is_variable_needed (struct varpool_node *node, tree decl)
{
/* If the user told us it is used, then it must be so. */
if (node->externally_visible || node->force_output)
return true;
- if (!flag_unit_at_a_time
- && lookup_attribute ("used", DECL_ATTRIBUTES (decl)))
- return true;
/* ??? If the assembler name is set by hand, it is possible to assemble
the name later after finalizing the function and the fact is noticed
@@ -257,7 +253,7 @@ decide_is_variable_needed (struct varpool_node *node, tree decl)
/* When not reordering top level variables, we have to assume that
we are going to keep everything. */
- if (flag_unit_at_a_time && flag_toplevel_reorder)
+ if (flag_toplevel_reorder)
return false;
/* We want to emit COMDAT variables only when absolutely necessary. */
@@ -280,7 +276,7 @@ varpool_finalize_decl (tree decl)
if this function has already run. */
if (node->finalized)
{
- if (cgraph_global_info_ready || (!flag_unit_at_a_time && !flag_openmp))
+ if (cgraph_global_info_ready)
varpool_assemble_pending_decls ();
return;
}
@@ -295,7 +291,7 @@ varpool_finalize_decl (tree decl)
there. */
else if (TREE_PUBLIC (decl) && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl))
varpool_mark_needed_node (node);
- if (cgraph_global_info_ready || (!flag_unit_at_a_time && !flag_openmp))
+ if (cgraph_global_info_ready)
varpool_assemble_pending_decls ();
}
@@ -357,7 +353,13 @@ varpool_assemble_decl (struct varpool_node *node)
&& (TREE_CODE (decl) != VAR_DECL || !DECL_HAS_VALUE_EXPR_P (decl)))
{
assemble_variable (decl, 0, 1, 0);
- return TREE_ASM_WRITTEN (decl);
+ if (TREE_ASM_WRITTEN (decl))
+ {
+ node->next_needed = varpool_assembled_nodes_queue;
+ varpool_assembled_nodes_queue = node;
+ node->finalized = 1;
+ return true;
+ }
}
return false;
@@ -423,12 +425,7 @@ varpool_assemble_pending_decls (void)
varpool_nodes_queue = varpool_nodes_queue->next_needed;
if (varpool_assemble_decl (node))
- {
- changed = true;
- node->next_needed = varpool_assembled_nodes_queue;
- varpool_assembled_nodes_queue = node;
- node->finalized = 1;
- }
+ changed = true;
else
node->next_needed = NULL;
}
@@ -438,6 +435,26 @@ varpool_assemble_pending_decls (void)
return changed;
}
+/* Remove all elements from the queue so we can re-use it for debug output. */
+void
+varpool_empty_needed_queue (void)
+{
+ /* EH might mark decls as needed during expansion. This should be safe since
+ we don't create references to new function, but it should not be used
+ elsewhere. */
+ varpool_analyze_pending_decls ();
+
+ while (varpool_nodes_queue)
+ {
+ struct varpool_node *node = varpool_nodes_queue;
+ varpool_nodes_queue = varpool_nodes_queue->next_needed;
+ node->next_needed = NULL;
+ }
+ /* varpool_nodes_queue is now empty, clear the pointer to the last element
+ in the queue. */
+ varpool_last_needed_node = NULL;
+}
+
/* Output all variables enqueued to be assembled. */
void
varpool_output_debug_info (void)
diff --git a/include/ChangeLog b/include/ChangeLog
index bf1af8da2cc..1636e982f79 100644
--- a/include/ChangeLog
+++ b/include/ChangeLog
@@ -1,3 +1,14 @@
+2008-07-07 Joel Brobecker <brobecker@adacore.com>
+
+ * safe-ctype.h: Add #include of ctype.h before redefining
+ the ctype.h macros.
+
+2008-07-04 Joel Brobecker <brobecker@adacore.com>
+
+ * safe-ctype.h: Remove #error when detecting that ctype.h has been
+ included. Redefine the various macros provided by ctype.h as
+ undefined variables.
+
2008-06-23 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* libiberty.h (XALLOCA, XDUP, XALLOCAVEC, XDUPVEC, XALLOCAVAR,
diff --git a/include/safe-ctype.h b/include/safe-ctype.h
index e59b357ccfb..0266bf1aa26 100644
--- a/include/safe-ctype.h
+++ b/include/safe-ctype.h
@@ -35,10 +35,6 @@ Boston, MA 02110-1301, USA. */
#ifndef SAFE_CTYPE_H
#define SAFE_CTYPE_H
-#ifdef isalpha
- #error "safe-ctype.h and ctype.h may not be used simultaneously"
-#endif
-
/* Determine host character set. */
#define HOST_CHARSET_UNKNOWN 0
#define HOST_CHARSET_ASCII 1
@@ -116,4 +112,39 @@ extern const unsigned char _sch_tolower[256];
#define TOUPPER(c) _sch_toupper[(c) & 0xff]
#define TOLOWER(c) _sch_tolower[(c) & 0xff]
+/* Prevent the users of safe-ctype.h from accidently using the routines
+ from ctype.h. Initially, the approach was to produce an error when
+ detecting that ctype.h has been included. But this was causing
+ trouble as ctype.h might get indirectly included as a result of
+ including another system header (for instance gnulib's stdint.h).
+ So we include ctype.h here and then immediately redefine its macros. */
+
+#include <ctype.h>
+#undef isalpha
+#define isalpha(c) do_not_use_isalpha_with_safe_ctype
+#undef isalnum
+#define isalnum(c) do_not_use_isalnum_with_safe_ctype
+#undef iscntrl
+#define iscntrl(c) do_not_use_iscntrl_with_safe_ctype
+#undef isdigit
+#define isdigit(c) do_not_use_isdigit_with_safe_ctype
+#undef isgraph
+#define isgraph(c) do_not_use_isgraph_with_safe_ctype
+#undef islower
+#define islower(c) do_not_use_islower_with_safe_ctype
+#undef isprint
+#define isprint(c) do_not_use_isprint_with_safe_ctype
+#undef ispunct
+#define ispunct(c) do_not_use_ispunct_with_safe_ctype
+#undef isspace
+#define isspace(c) do_not_use_isspace_with_safe_ctype
+#undef isupper
+#define isupper(c) do_not_use_isupper_with_safe_ctype
+#undef isxdigit
+#define isxdigit(c) do_not_use_isxdigit_with_safe_ctype
+#undef toupper
+#define toupper(c) do_not_use_toupper_with_safe_ctype
+#undef tolower
+#define tolower(c) do_not_use_tolower_with_safe_ctype
+
#endif /* SAFE_CTYPE_H */
diff --git a/libcpp/ChangeLog b/libcpp/ChangeLog
index 2d29a309566..cb1de791edc 100644
--- a/libcpp/ChangeLog
+++ b/libcpp/ChangeLog
@@ -1,3 +1,48 @@
+2008-07-22 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
+
+ PR 28079
+ * directives.c (strtolinenum): Handle overflow.
+ (do_line): Give a warning if line number overflowed.
+ (do_linemarker): Update call to strtolinenum.
+
+2008-07-21 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
+
+ * include/line-map.h (linenum_type): New typedef.
+ (struct line_map): Use it.
+ (SOURCE_LINE): Second arguments is a LOCATION not a LINE.
+ (SOURCE_COLUMN): Likewise.
+ * macro.c (_cpp_builtin_macro_text): Use linenum_type. Don't store
+ source_location values in a variable of type linenum_type.
+ * directives.c (struct if_stack): Use linenum_type.
+ (strtoul_for_line): Rename as strtolinenum.
+ (do_line): Use linenum_type.
+ (do_linemarker): Use linenum_type and strtolinenum.
+ (_cpp_do_file_change): Use linenum_t.
+ * line-map.c (linemap_add): Likewise.
+ (linemap_line_start): Likewise.
+ * traditional.c (struct fun_macro): 'line' is a source_location.
+ * errors.c (print_location): Use linenum_type.
+ * directives-only.c (_cpp_preprocess_dir_only): Likewise.
+ * internal.h (CPP_INCREMENT_LINE): Likewise.
+ * lex.c (_cpp_skip_block_comment): Use source_location.
+
+2008-07-14 Ben Elliston <bje@au.ibm.com>
+
+ * include/cpplib.h (NODE_CONDITIONAL): New.
+ (struct cpp_callbacks): New macro_to_expand field.
+ (struct cpp_hashnode): Adjust size of flags and type fields.
+ (cpp_peek_token): Prototype.
+ * lex.c (cpp_peek_token): New function.
+ (_cpp_temp_token): Protect pre-existing lookaheads.
+ * macro.c (cpp_get_token): Expand any conditional macros.
+ (_cpp_backup_tokens_direct): New.
+ (_cpp_backup_tokens): Call _cpp_backup_tokens_direct.
+ (warn_of_redefinition): Silently allow redefined conditional
+ macros.
+ (_cpp_create_definition): Remove the conditional flag when a user
+ defines one of the conditional macros.
+ * internal.h (_cpp_backup_tokens_direct): New prototype.
+
2008-06-13 Andrew Haley <aph@redhat.com>
PR preprocessor/33305
diff --git a/libcpp/directives-only.c b/libcpp/directives-only.c
index d50cebbdae3..addd9a755dc 100644
--- a/libcpp/directives-only.c
+++ b/libcpp/directives-only.c
@@ -42,7 +42,8 @@ _cpp_preprocess_dir_only (cpp_reader *pfile,
const unsigned char *cur, *base, *next_line, *rlimit;
cppchar_t c, last_c;
unsigned flags;
- int lines, col;
+ linenum_type lines;
+ int col;
source_location loc;
restart:
diff --git a/libcpp/directives.c b/libcpp/directives.c
index 370f4ff5b0d..9e0744b23d9 100644
--- a/libcpp/directives.c
+++ b/libcpp/directives.c
@@ -32,7 +32,7 @@ Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
struct if_stack
{
struct if_stack *next;
- unsigned int line; /* Line where condition started. */
+ linenum_type line; /* Line where condition started. */
const cpp_hashnode *mi_cmacro;/* macro name for #ifndef around entire file */
bool skip_elses; /* Can future #else / #elif be skipped? */
bool was_skipping; /* If were skipping on entry. */
@@ -102,7 +102,7 @@ static char *glue_header_name (cpp_reader *);
static const char *parse_include (cpp_reader *, int *, const cpp_token ***);
static void push_conditional (cpp_reader *, int, int, const cpp_hashnode *);
static unsigned int read_flag (cpp_reader *, unsigned int);
-static int strtoul_for_line (const uchar *, unsigned int, unsigned long *);
+static bool strtolinenum (const uchar *, size_t, linenum_type *, bool *);
static void do_diagnostic (cpp_reader *, int, int);
static cpp_hashnode *lex_macro_node (cpp_reader *, bool);
static int undefine_macros (cpp_reader *, cpp_hashnode *, void *);
@@ -837,23 +837,30 @@ read_flag (cpp_reader *pfile, unsigned int last)
}
/* Subroutine of do_line and do_linemarker. Convert a number in STR,
- of length LEN, to binary; store it in NUMP, and return 0 if the
- number was well-formed, 1 if not. Temporary, hopefully. */
-static int
-strtoul_for_line (const uchar *str, unsigned int len, long unsigned int *nump)
+ of length LEN, to binary; store it in NUMP, and return false if the
+ number was well-formed, true if not. WRAPPED is set to true if the
+ number did not fit into 'unsigned long'. */
+static bool
+strtolinenum (const uchar *str, size_t len, linenum_type *nump, bool *wrapped)
{
- unsigned long reg = 0;
+ linenum_type reg = 0;
+ linenum_type reg_prev = 0;
+
uchar c;
+ *wrapped = false;
while (len--)
{
c = *str++;
if (!ISDIGIT (c))
- return 1;
+ return true;
reg *= 10;
reg += c - '0';
+ if (reg < reg_prev)
+ *wrapped = true;
+ reg_prev = reg;
}
*nump = reg;
- return 0;
+ return false;
}
/* Interpret #line command.
@@ -871,16 +878,17 @@ do_line (cpp_reader *pfile)
unsigned char map_sysp = map->sysp;
const cpp_token *token;
const char *new_file = map->to_file;
- unsigned long new_lineno;
+ linenum_type new_lineno;
/* C99 raised the minimum limit on #line numbers. */
- unsigned int cap = CPP_OPTION (pfile, c99) ? 2147483647 : 32767;
+ linenum_type cap = CPP_OPTION (pfile, c99) ? 2147483647 : 32767;
+ bool wrapped;
/* #line commands expand macros. */
token = cpp_get_token (pfile);
if (token->type != CPP_NUMBER
- || strtoul_for_line (token->val.str.text, token->val.str.len,
- &new_lineno))
+ || strtolinenum (token->val.str.text, token->val.str.len,
+ &new_lineno, &wrapped))
{
if (token->type == CPP_EOF)
cpp_error (pfile, CPP_DL_ERROR, "unexpected end of file after #line");
@@ -891,8 +899,10 @@ do_line (cpp_reader *pfile)
return;
}
- if (CPP_PEDANTIC (pfile) && (new_lineno == 0 || new_lineno > cap))
+ if (CPP_PEDANTIC (pfile) && (new_lineno == 0 || new_lineno > cap || wrapped))
cpp_error (pfile, CPP_DL_PEDWARN, "line number out of range");
+ else if (wrapped)
+ cpp_error (pfile, CPP_DL_WARNING, "line number out of range");
token = cpp_get_token (pfile);
if (token->type == CPP_STRING)
@@ -925,10 +935,11 @@ do_linemarker (cpp_reader *pfile)
const struct line_map *map = &line_table->maps[line_table->used - 1];
const cpp_token *token;
const char *new_file = map->to_file;
- unsigned long new_lineno;
+ linenum_type new_lineno;
unsigned int new_sysp = map->sysp;
enum lc_reason reason = LC_RENAME;
int flag;
+ bool wrapped;
/* Back up so we can get the number again. Putting this in
_cpp_handle_directive risks two calls to _cpp_backup_tokens in
@@ -938,8 +949,8 @@ do_linemarker (cpp_reader *pfile)
/* #line commands expand macros. */
token = cpp_get_token (pfile);
if (token->type != CPP_NUMBER
- || strtoul_for_line (token->val.str.text, token->val.str.len,
- &new_lineno))
+ || strtolinenum (token->val.str.text, token->val.str.len,
+ &new_lineno, &wrapped))
{
/* Unlike #line, there does not seem to be a way to get an EOF
here. So, it should be safe to always spell the token. */
@@ -999,7 +1010,7 @@ do_linemarker (cpp_reader *pfile)
and zero otherwise. */
void
_cpp_do_file_change (cpp_reader *pfile, enum lc_reason reason,
- const char *to_file, unsigned int file_line,
+ const char *to_file, linenum_type file_line,
unsigned int sysp)
{
const struct line_map *map = linemap_add (pfile->line_table, reason, sysp,
diff --git a/libcpp/errors.c b/libcpp/errors.c
index 5e8e637276d..e3d56292848 100644
--- a/libcpp/errors.c
+++ b/libcpp/errors.c
@@ -42,7 +42,7 @@ print_location (cpp_reader *pfile, source_location line, unsigned int col)
else
{
const struct line_map *map;
- unsigned int lin;
+ linenum_type lin;
map = linemap_lookup (pfile->line_table, line);
linemap_print_containing_files (pfile->line_table, map);
diff --git a/libcpp/include/cpplib.h b/libcpp/include/cpplib.h
index 92ab291db2c..a79c26dd6b8 100644
--- a/libcpp/include/cpplib.h
+++ b/libcpp/include/cpplib.h
@@ -484,6 +484,10 @@ struct cpp_callbacks
void (*read_pch) (cpp_reader *, const char *, int, const char *);
missing_header_cb missing_header;
+ /* Context-sensitive macro support. Returns macro (if any) that should
+ be expanded. */
+ cpp_hashnode * (*macro_to_expand) (cpp_reader *, const cpp_token *);
+
/* Called to emit a diagnostic if client_diagnostic option is true.
This callback receives the translated message. */
void (*error) (cpp_reader *, int, const char *, va_list *)
@@ -558,6 +562,7 @@ extern const char *progname;
#define NODE_DISABLED (1 << 5) /* A disabled macro. */
#define NODE_MACRO_ARG (1 << 6) /* Used during #define processing. */
#define NODE_USED (1 << 7) /* Dumped with -dU. */
+#define NODE_CONDITIONAL (1 << 8) /* Conditional macro */
/* Different flavors of hash node. */
enum node_type
@@ -629,8 +634,8 @@ struct cpp_hashnode GTY(())
then index into directive table.
Otherwise, a NODE_OPERATOR. */
unsigned char rid_code; /* Rid code - for front ends. */
- ENUM_BITFIELD(node_type) type : 8; /* CPP node type. */
- unsigned char flags; /* CPP flags. */
+ ENUM_BITFIELD(node_type) type : 7; /* CPP node type. */
+ unsigned int flags : 9; /* CPP flags. */
union _cpp_hashnode_value GTY ((desc ("CPP_HASHNODE_VALUE_IDX (%1)"))) value;
};
@@ -717,6 +722,7 @@ extern const cpp_token *cpp_get_token_with_location (cpp_reader *,
extern const unsigned char *cpp_macro_definition (cpp_reader *,
const cpp_hashnode *);
extern void _cpp_backup_tokens (cpp_reader *, unsigned int);
+extern const cpp_token *cpp_peek_token (cpp_reader *, int);
/* Evaluate a CPP_CHAR or CPP_WCHAR token. */
extern cppchar_t cpp_interpret_charconst (cpp_reader *, const cpp_token *,
diff --git a/libcpp/include/line-map.h b/libcpp/include/line-map.h
index 3378315238f..81e888bc20f 100644
--- a/libcpp/include/line-map.h
+++ b/libcpp/include/line-map.h
@@ -34,6 +34,9 @@ Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
(e.g. a #line directive in C). */
enum lc_reason {LC_ENTER = 0, LC_LEAVE, LC_RENAME};
+/* The type of line numbers. */
+typedef unsigned int linenum_type;
+
/* A logical line/column number, i.e. an "index" into a line_map. */
/* Long-term, we want to use this to replace struct location_s (in input.h),
and effectively typedef source_location location_t. */
@@ -57,7 +60,7 @@ typedef void *(*line_map_realloc) (void *, size_t);
struct line_map GTY(())
{
const char *to_file;
- unsigned int to_line;
+ linenum_type to_line;
source_location start_location;
int included_from;
ENUM_BITFIELD (lc_reason) reason : CHAR_BIT;
@@ -119,7 +122,7 @@ extern void linemap_check_files_exited (struct line_maps *);
the highest_location). */
extern source_location linemap_line_start
-(struct line_maps *set, unsigned int to_line, unsigned int max_column_hint);
+(struct 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.
@@ -134,7 +137,7 @@ extern source_location linemap_line_start
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,
- const char *to_file, unsigned int to_line);
+ const char *to_file, linenum_type to_line);
/* Given a logical line, returns the map from which the corresponding
(source file, line) pair can be deduced. */
@@ -148,11 +151,11 @@ extern void linemap_print_containing_files (struct line_maps *,
const struct line_map *);
/* Converts a map and a source_location to source line. */
-#define SOURCE_LINE(MAP, LINE) \
- ((((LINE) - (MAP)->start_location) >> (MAP)->column_bits) + (MAP)->to_line)
+#define SOURCE_LINE(MAP, LOC) \
+ ((((LOC) - (MAP)->start_location) >> (MAP)->column_bits) + (MAP)->to_line)
-#define SOURCE_COLUMN(MAP, LINE) \
- (((LINE) - (MAP)->start_location) & ((1 << (MAP)->column_bits) - 1))
+#define SOURCE_COLUMN(MAP, LOC) \
+ (((LOC) - (MAP)->start_location) & ((1 << (MAP)->column_bits) - 1))
/* Returns the last source line within a map. This is the (last) line
of the #include, or other directive, that caused a map change. */
diff --git a/libcpp/internal.h b/libcpp/internal.h
index 65cac325186..c5bf35eab84 100644
--- a/libcpp/internal.h
+++ b/libcpp/internal.h
@@ -68,7 +68,7 @@ struct cset_converter
#define CPP_INCREMENT_LINE(PFILE, COLS_HINT) do { \
const struct line_maps *line_table = PFILE->line_table; \
const struct line_map *map = &line_table->maps[line_table->used-1]; \
- unsigned int line = SOURCE_LINE (map, line_table->highest_line); \
+ linenum_type line = SOURCE_LINE (map, line_table->highest_line); \
linemap_line_start (PFILE->line_table, line + 1, COLS_HINT); \
} while (0)
@@ -532,6 +532,7 @@ extern const unsigned char *_cpp_builtin_macro_text (cpp_reader *,
extern int _cpp_warn_if_unused_macro (cpp_reader *, cpp_hashnode *, void *);
extern void _cpp_push_token_context (cpp_reader *, cpp_hashnode *,
const cpp_token *, unsigned int);
+extern void _cpp_backup_tokens_direct (cpp_reader *, unsigned int);
/* In identifiers.c */
extern void _cpp_init_hashtable (cpp_reader *, hash_table *);
@@ -584,7 +585,7 @@ extern int _cpp_do__Pragma (cpp_reader *);
extern void _cpp_init_directives (cpp_reader *);
extern void _cpp_init_internal_pragmas (cpp_reader *);
extern void _cpp_do_file_change (cpp_reader *, enum lc_reason, const char *,
- unsigned int, unsigned int);
+ linenum_type, unsigned int);
extern void _cpp_pop_buffer (cpp_reader *);
/* In directives.c */
diff --git a/libcpp/lex.c b/libcpp/lex.c
index 70897fd57db..2eb66bd6342 100644
--- a/libcpp/lex.c
+++ b/libcpp/lex.c
@@ -384,7 +384,7 @@ static int
skip_line_comment (cpp_reader *pfile)
{
cpp_buffer *buffer = pfile->buffer;
- unsigned int orig_line = pfile->line_table->highest_line;
+ source_location orig_line = pfile->line_table->highest_line;
while (*buffer->cur != '\n')
buffer->cur++;
@@ -734,6 +734,49 @@ next_tokenrun (tokenrun *run)
return run->next;
}
+/* Look ahead in the input stream. */
+const cpp_token *
+cpp_peek_token (cpp_reader *pfile, int index)
+{
+ cpp_context *context = pfile->context;
+ const cpp_token *peektok;
+ int count;
+
+ /* First, scan through any pending cpp_context objects. */
+ while (context->prev)
+ {
+ ptrdiff_t sz = (context->direct_p
+ ? LAST (context).token - FIRST (context).token
+ : LAST (context).ptoken - FIRST (context).ptoken);
+
+ if (index < (int) sz)
+ return (context->direct_p
+ ? FIRST (context).token + index
+ : *(FIRST (context).ptoken + index));
+
+ index -= (int) sz;
+ context = context->prev;
+ }
+
+ /* We will have to read some new tokens after all (and do so
+ without invalidating preceding tokens). */
+ count = index;
+ pfile->keep_tokens++;
+
+ do
+ {
+ peektok = _cpp_lex_token (pfile);
+ if (peektok->type == CPP_EOF)
+ return peektok;
+ }
+ while (index--);
+
+ _cpp_backup_tokens_direct (pfile, count + 1);
+ pfile->keep_tokens--;
+
+ return peektok;
+}
+
/* Allocate a single token that is invalidated at the same time as the
rest of the tokens on the line. Has its line and col set to the
same as the last lexed token, so that diagnostics appear in the
@@ -742,9 +785,30 @@ cpp_token *
_cpp_temp_token (cpp_reader *pfile)
{
cpp_token *old, *result;
+ ptrdiff_t sz = pfile->cur_run->limit - pfile->cur_token;
+ ptrdiff_t la = (ptrdiff_t) pfile->lookaheads;
old = pfile->cur_token - 1;
- if (pfile->cur_token == pfile->cur_run->limit)
+ /* Any pre-existing lookaheads must not be clobbered. */
+ if (la)
+ {
+ if (sz <= la)
+ {
+ tokenrun *next = next_tokenrun (pfile->cur_run);
+
+ if (sz < la)
+ memmove (next->base + 1, next->base,
+ (la - sz) * sizeof (cpp_token));
+
+ next->base[0] = pfile->cur_run->limit[-1];
+ }
+
+ if (sz > 1)
+ memmove (pfile->cur_token + 1, pfile->cur_token,
+ MIN (la, sz - 1) * sizeof (cpp_token));
+ }
+
+ if (!sz && pfile->cur_token == pfile->cur_run->limit)
{
pfile->cur_run = next_tokenrun (pfile->cur_run);
pfile->cur_token = pfile->cur_run->base;
diff --git a/libcpp/line-map.c b/libcpp/line-map.c
index 2c6d2510e61..964a7cd9a77 100644
--- a/libcpp/line-map.c
+++ b/libcpp/line-map.c
@@ -85,7 +85,7 @@ linemap_free (struct line_maps *set)
const struct line_map *
linemap_add (struct line_maps *set, enum lc_reason reason,
- unsigned int sysp, const char *to_file, unsigned int to_line)
+ unsigned int sysp, const char *to_file, linenum_type to_line)
{
struct line_map *map;
source_location start_location = set->highest_location + 1;
@@ -182,13 +182,13 @@ linemap_add (struct line_maps *set, enum lc_reason reason,
}
source_location
-linemap_line_start (struct line_maps *set, unsigned int to_line,
+linemap_line_start (struct line_maps *set, linenum_type to_line,
unsigned int max_column_hint)
{
struct line_map *map = &set->maps[set->used - 1];
source_location highest = set->highest_location;
source_location r;
- unsigned int last_line = SOURCE_LINE (map, set->highest_line);
+ linenum_type last_line = SOURCE_LINE (map, set->highest_line);
int line_delta = to_line - last_line;
bool add_map = false;
if (line_delta < 0
diff --git a/libcpp/macro.c b/libcpp/macro.c
index edc2856551a..9a470ef460b 100644
--- a/libcpp/macro.c
+++ b/libcpp/macro.c
@@ -118,7 +118,7 @@ _cpp_builtin_macro_text (cpp_reader *pfile, cpp_hashnode *node)
{
const struct line_map *map;
const uchar *result = NULL;
- unsigned int number = 1;
+ linenum_type number = 1;
switch (node->value.builtin)
{
@@ -200,11 +200,10 @@ _cpp_builtin_macro_text (cpp_reader *pfile, cpp_hashnode *node)
/* If __LINE__ is embedded in a macro, it must expand to the
line of the macro's invocation, not its definition.
Otherwise things like assert() will not work properly. */
- if (CPP_OPTION (pfile, traditional))
- number = pfile->line_table->highest_line;
- else
- number = pfile->cur_token[-1].src_loc;
- number = SOURCE_LINE (map, number);
+ number = SOURCE_LINE (map,
+ CPP_OPTION (pfile, traditional)
+ ? pfile->line_table->highest_line
+ : pfile->cur_token[-1].src_loc);
break;
/* __STDC__ has the value 1 under normal circumstances.
@@ -1251,16 +1250,21 @@ cpp_get_token (cpp_reader *pfile)
if (!(node->flags & NODE_DISABLED))
{
- int ret;
+ int ret = 0;
/* If not in a macro context, and we're going to start an
expansion, record the location. */
if (can_set && !context->macro)
pfile->invocation_location = result->src_loc;
if (pfile->state.prevent_expansion)
break;
- ret = enter_macro_context (pfile, node, result);
- if (ret)
- {
+
+ /* Conditional macros require that a predicate be evaluated
+ first. */
+ if (((!(node->flags & NODE_CONDITIONAL))
+ || (pfile->cb.macro_to_expand
+ && (node = pfile->cb.macro_to_expand (pfile, result))))
+ && (ret = enter_macro_context (pfile, node, result)))
+ {
if (pfile->state.in_directive || ret == 2)
continue;
return padding_token (pfile, result);
@@ -1338,26 +1342,31 @@ cpp_scan_nooutput (cpp_reader *pfile)
pfile->state.prevent_expansion--;
}
+/* Step back one or more tokens obtained from the lexer. */
+void
+_cpp_backup_tokens_direct (cpp_reader *pfile, unsigned int count)
+{
+ pfile->lookaheads += count;
+ while (count--)
+ {
+ pfile->cur_token--;
+ if (pfile->cur_token == pfile->cur_run->base
+ /* Possible with -fpreprocessed and no leading #line. */
+ && pfile->cur_run->prev != NULL)
+ {
+ pfile->cur_run = pfile->cur_run->prev;
+ pfile->cur_token = pfile->cur_run->limit;
+ }
+ }
+}
+
/* Step back one (or more) tokens. Can only step back more than 1 if
they are from the lexer, and not from macro expansion. */
void
_cpp_backup_tokens (cpp_reader *pfile, unsigned int count)
{
if (pfile->context->prev == NULL)
- {
- pfile->lookaheads += count;
- while (count--)
- {
- pfile->cur_token--;
- if (pfile->cur_token == pfile->cur_run->base
- /* Possible with -fpreprocessed and no leading #line. */
- && pfile->cur_run->prev != NULL)
- {
- pfile->cur_run = pfile->cur_run->prev;
- pfile->cur_token = pfile->cur_run->limit;
- }
- }
- }
+ _cpp_backup_tokens_direct (pfile, count);
else
{
if (count != 1)
@@ -1383,6 +1392,11 @@ warn_of_redefinition (cpp_reader *pfile, const cpp_hashnode *node,
if (node->flags & NODE_WARN)
return true;
+ /* Redefinitions of conditional (context-sensitive) macros, on
+ the other hand, must be allowed silently. */
+ if (node->flags & NODE_CONDITIONAL)
+ return false;
+
/* Redefinition of a macro is allowed if and only if the old and new
definitions are the same. (6.10.3 paragraph 2). */
macro1 = node->value.macro;
@@ -1815,6 +1829,10 @@ _cpp_create_definition (cpp_reader *pfile, cpp_hashnode *node)
&& ustrcmp (NODE_NAME (node), (const uchar *) "__STDC_CONSTANT_MACROS"))
node->flags |= NODE_WARN;
+ /* If user defines one of the conditional macros, remove the
+ conditional flag */
+ node->flags &= ~NODE_CONDITIONAL;
+
return ok;
}
diff --git a/libcpp/traditional.c b/libcpp/traditional.c
index 1a384253a90..d23fffe72ca 100644
--- a/libcpp/traditional.c
+++ b/libcpp/traditional.c
@@ -60,7 +60,7 @@ struct fun_macro
size_t offset;
/* The line the macro name appeared on. */
- unsigned int line;
+ source_location line;
/* Zero-based index of argument being currently lexed. */
unsigned int argc;
diff --git a/libffi/ChangeLog b/libffi/ChangeLog
index 05188245ea4..850bbd4b35b 100644
--- a/libffi/ChangeLog
+++ b/libffi/ChangeLog
@@ -1,3 +1,8 @@
+2008-07-16 Kaz Kojima <kkojima@gcc.gnu.org>
+
+ * src/sh/ffi.c (ffi_prep_closure_loc): Turn INSN into an unsigned
+ int.
+
2008-06-17 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
* configure: Regenerate.
diff --git a/libffi/src/sh/ffi.c b/libffi/src/sh/ffi.c
index 0cb8c72ccf6..850fde0a022 100644
--- a/libffi/src/sh/ffi.c
+++ b/libffi/src/sh/ffi.c
@@ -1,5 +1,6 @@
/* -----------------------------------------------------------------------
- ffi.c - Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007 Kaz Kojima
+ ffi.c - Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008
+ Kaz Kojima
SuperH Foreign Function Interface
@@ -459,7 +460,7 @@ ffi_prep_closure_loc (ffi_closure* closure,
void *codeloc)
{
unsigned int *tramp;
- unsigned short insn;
+ unsigned int insn;
FFI_ASSERT (cif->abi == FFI_GCC_SYSV);
diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog
index 47f304ff9b0..348afc5d227 100644
--- a/libgcc/ChangeLog
+++ b/libgcc/ChangeLog
@@ -1,3 +1,28 @@
+2008-07-08 H.J. Lu <hongjiu.lu@intel.com>
+
+ * config/i386/64/t-softfp-compat: Update comments.
+
+2008-07-07 H.J. Lu <hongjiu.lu@intel.com>
+
+ * config/i386/64/_divtc3-compat.c: Moved to ...
+ * config/i386/64/_divtc3.c: Here.
+
+ * config/i386/64/_multc3-compat.c: Moved to ...
+ * config/i386/64/_multc3.c: Here.
+
+ * config/i386/64/_powitf2-compat.c: Moved to ...
+ * config/i386/64/_powitf2.c: Here.
+
+ * config/i386/64/t-softfp-compat (libgcc2-tf-compats): Add
+ .c suffix instead of -compat.c.
+
+2008-07-05 Uros Bizjak <ubizjak@gmail.com>
+
+ * config/i386/32/sfp-machine.h (_FP_MUL_MEAT_S): Remove.
+ (_FP_MUL_MEAT_D): Ditto.
+ (_FP_DIV_MEAT_S): Ditto.
+ (_FP_DIV_MEAT_D): Ditto.
+
2008-07-03 Richard Sandiford <rdsandiford@googlemail.com>
* Makefile.in: Add support for __sync_* libgcc functions.
diff --git a/libgcc/config/i386/32/sfp-machine.h b/libgcc/config/i386/32/sfp-machine.h
index a872546d966..746ae7c1287 100644
--- a/libgcc/config/i386/32/sfp-machine.h
+++ b/libgcc/config/i386/32/sfp-machine.h
@@ -8,88 +8,80 @@
typedef int __gcc_CMPtype __attribute__ ((mode (__libgcc_cmp_return__)));
#define CMPtype __gcc_CMPtype
-#define __FP_FRAC_ADD_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0) \
- __asm__ ("add{l} {%11,%3|%3,%11}\n\t" \
- "adc{l} {%9,%2|%2,%9}\n\t" \
- "adc{l} {%7,%1|%1,%7}\n\t" \
- "adc{l} {%5,%0|%0,%5}" \
- : "=r" ((USItype) (r3)), \
- "=&r" ((USItype) (r2)), \
- "=&r" ((USItype) (r1)), \
- "=&r" ((USItype) (r0)) \
- : "%0" ((USItype) (x3)), \
- "g" ((USItype) (y3)), \
- "%1" ((USItype) (x2)), \
- "g" ((USItype) (y2)), \
- "%2" ((USItype) (x1)), \
- "g" ((USItype) (y1)), \
- "%3" ((USItype) (x0)), \
+#define __FP_FRAC_ADD_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0) \
+ __asm__ ("add{l} {%11,%3|%3,%11}\n\t" \
+ "adc{l} {%9,%2|%2,%9}\n\t" \
+ "adc{l} {%7,%1|%1,%7}\n\t" \
+ "adc{l} {%5,%0|%0,%5}" \
+ : "=r" ((USItype) (r3)), \
+ "=&r" ((USItype) (r2)), \
+ "=&r" ((USItype) (r1)), \
+ "=&r" ((USItype) (r0)) \
+ : "%0" ((USItype) (x3)), \
+ "g" ((USItype) (y3)), \
+ "%1" ((USItype) (x2)), \
+ "g" ((USItype) (y2)), \
+ "%2" ((USItype) (x1)), \
+ "g" ((USItype) (y1)), \
+ "%3" ((USItype) (x0)), \
"g" ((USItype) (y0)))
-
-#define __FP_FRAC_ADD_3(r2,r1,r0,x2,x1,x0,y2,y1,y0) \
- __asm__ ("add{l} {%8,%2|%2,%8}\n\t" \
- "adc{l} {%6,%1|%1,%6}\n\t" \
- "adc{l} {%4,%0|%0,%4}" \
- : "=r" ((USItype) (r2)), \
- "=&r" ((USItype) (r1)), \
- "=&r" ((USItype) (r0)) \
- : "%0" ((USItype) (x2)), \
- "g" ((USItype) (y2)), \
- "%1" ((USItype) (x1)), \
- "g" ((USItype) (y1)), \
- "%2" ((USItype) (x0)), \
+#define __FP_FRAC_ADD_3(r2,r1,r0,x2,x1,x0,y2,y1,y0) \
+ __asm__ ("add{l} {%8,%2|%2,%8}\n\t" \
+ "adc{l} {%6,%1|%1,%6}\n\t" \
+ "adc{l} {%4,%0|%0,%4}" \
+ : "=r" ((USItype) (r2)), \
+ "=&r" ((USItype) (r1)), \
+ "=&r" ((USItype) (r0)) \
+ : "%0" ((USItype) (x2)), \
+ "g" ((USItype) (y2)), \
+ "%1" ((USItype) (x1)), \
+ "g" ((USItype) (y1)), \
+ "%2" ((USItype) (x0)), \
"g" ((USItype) (y0)))
-/* FIXME: The last constraint should be "g" instead of "im" if reload
- works properly. */
-#define __FP_FRAC_SUB_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0) \
- __asm__ ("sub{l} {%11,%3|%3,%11}\n\t" \
- "sbb{l} {%9,%2|%2,%9}\n\t" \
- "sbb{l} {%7,%1|%1,%7}\n\t" \
- "sbb{l} {%5,%0|%0,%5}" \
- : "=r" ((USItype) (r3)), \
- "=&r" ((USItype) (r2)), \
- "=&r" ((USItype) (r1)), \
- "=&r" ((USItype) (r0)) \
- : "0" ((USItype) (x3)), \
- "g" ((USItype) (y3)), \
- "1" ((USItype) (x2)), \
- "g" ((USItype) (y2)), \
- "2" ((USItype) (x1)), \
- "g" ((USItype) (y1)), \
- "3" ((USItype) (x0)), \
+/* FIXME: Change last operand constraint
+ from "im" to "g" when reload works properly. */
+#define __FP_FRAC_SUB_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0) \
+ __asm__ ("sub{l} {%11,%3|%3,%11}\n\t" \
+ "sbb{l} {%9,%2|%2,%9}\n\t" \
+ "sbb{l} {%7,%1|%1,%7}\n\t" \
+ "sbb{l} {%5,%0|%0,%5}" \
+ : "=r" ((USItype) (r3)), \
+ "=&r" ((USItype) (r2)), \
+ "=&r" ((USItype) (r1)), \
+ "=&r" ((USItype) (r0)) \
+ : "0" ((USItype) (x3)), \
+ "g" ((USItype) (y3)), \
+ "1" ((USItype) (x2)), \
+ "g" ((USItype) (y2)), \
+ "2" ((USItype) (x1)), \
+ "g" ((USItype) (y1)), \
+ "3" ((USItype) (x0)), \
"im" ((USItype) (y0)))
-
-#define __FP_FRAC_SUB_3(r2,r1,r0,x2,x1,x0,y2,y1,y0) \
- __asm__ ("sub{l} {%8,%2|%2,%8}\n\t" \
- "sbb{l} {%6,%1|%1,%6}\n\t" \
- "sbb{l} {%4,%0|%0,%4}" \
- : "=r" ((USItype) (r2)), \
- "=&r" ((USItype) (r1)), \
- "=&r" ((USItype) (r0)) \
- : "0" ((USItype) (x2)), \
- "g" ((USItype) (y2)), \
- "1" ((USItype) (x1)), \
- "g" ((USItype) (y1)), \
- "2" ((USItype) (x0)), \
+#define __FP_FRAC_SUB_3(r2,r1,r0,x2,x1,x0,y2,y1,y0) \
+ __asm__ ("sub{l} {%8,%2|%2,%8}\n\t" \
+ "sbb{l} {%6,%1|%1,%6}\n\t" \
+ "sbb{l} {%4,%0|%0,%4}" \
+ : "=r" ((USItype) (r2)), \
+ "=&r" ((USItype) (r1)), \
+ "=&r" ((USItype) (r0)) \
+ : "0" ((USItype) (x2)), \
+ "g" ((USItype) (y2)), \
+ "1" ((USItype) (x1)), \
+ "g" ((USItype) (y1)), \
+ "2" ((USItype) (x0)), \
"g" ((USItype) (y0)))
-#define _FP_MUL_MEAT_S(R,X,Y) \
- _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_S,R,X,Y,umul_ppmm)
-#define _FP_MUL_MEAT_D(R,X,Y) \
- _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm)
#define _FP_MUL_MEAT_Q(R,X,Y) \
_FP_MUL_MEAT_4_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
-#define _FP_DIV_MEAT_S(R,X,Y) _FP_DIV_MEAT_1_udiv(S,R,X,Y)
-#define _FP_DIV_MEAT_D(R,X,Y) _FP_DIV_MEAT_2_udiv(D,R,X,Y)
#define _FP_DIV_MEAT_Q(R,X,Y) _FP_DIV_MEAT_4_udiv(Q,R,X,Y)
#define _FP_NANFRAC_S _FP_QNANBIT_S
#define _FP_NANFRAC_D _FP_QNANBIT_D, 0
-/* Even if XFmode is 12byte, we have to pad it to 16byte since soft-fp
- emulation is done in 16byte. */
+/* Even if XFmode is 12byte, we have to pad it to
+ 16byte since soft-fp emulation is done in 16byte. */
#define _FP_NANFRAC_E _FP_QNANBIT_E, 0, 0, 0
#define _FP_NANFRAC_Q _FP_QNANBIT_Q, 0, 0, 0
#define _FP_NANSIGN_S 1
diff --git a/libgcc/config/i386/64/_divtc3-compat.c b/libgcc/config/i386/64/_divtc3.c
index 57ee350b7cd..57ee350b7cd 100644
--- a/libgcc/config/i386/64/_divtc3-compat.c
+++ b/libgcc/config/i386/64/_divtc3.c
diff --git a/libgcc/config/i386/64/_multc3-compat.c b/libgcc/config/i386/64/_multc3.c
index 49141a9384f..49141a9384f 100644
--- a/libgcc/config/i386/64/_multc3-compat.c
+++ b/libgcc/config/i386/64/_multc3.c
diff --git a/libgcc/config/i386/64/_powitf2-compat.c b/libgcc/config/i386/64/_powitf2.c
index 3bc3c904de7..3bc3c904de7 100644
--- a/libgcc/config/i386/64/_powitf2-compat.c
+++ b/libgcc/config/i386/64/_powitf2.c
diff --git a/libgcc/config/i386/64/t-softfp-compat b/libgcc/config/i386/64/t-softfp-compat
index e8cda296cbd..afaa526ae29 100644
--- a/libgcc/config/i386/64/t-softfp-compat
+++ b/libgcc/config/i386/64/t-softfp-compat
@@ -1,5 +1,8 @@
-# Filter out the following TImode functions and provide backward binary
-# compatibility.
+# When TFmode was first added to x86-64 in gcc 4.3.0, some TFmode
+# support functions got improper versions by accident. Here we
+# correct the version and provide backward binary compatibility.
+
+# Filter out the following TFmode functions.
tf-compats = getf2.c letf2.c eqtf2.c
tf-functions := $(addprefix $(gcc_srcdir)/config/soft-fp/, $(tf-compats))
LIB2ADD := $(filter-out $(tf-functions), $(LIB2ADD))
@@ -8,5 +11,5 @@ LIB2ADD += $(addprefix $(srcdir)/config/i386/64/, $(tf-compats))
# Replace _divtc3, _multc3 and _powitf2.
libgcc2-tf-functions = _divtc3 _multc3 _powitf2
LIB2FUNCS_EXCLUDE += $(libgcc2-tf-functions)
-libgcc2-tf-compats = $(addsuffix -compat.c, $(libgcc2-tf-functions))
+libgcc2-tf-compats = $(addsuffix .c, $(libgcc2-tf-functions))
LIB2ADD += $(addprefix $(srcdir)/config/i386/64/, $(libgcc2-tf-compats))
diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog
index 6e3a729fc7a..0eb171ce4b0 100644
--- a/libgfortran/ChangeLog
+++ b/libgfortran/ChangeLog
@@ -1,3 +1,93 @@
+2008-07-27 Tobias Burnus <burnus@net-b.de>
+
+ PR fortran/36132
+ PR fortran/29952
+ PR fortran/36909
+ * runtime/error.c: New function runtime_error_at.
+ * gfortran.map: Ditto.
+ * libgfortran.h: Ditto.
+
+2008-07-22 Jerry DeLisle <jvdelisle@gcc.gnu.org>
+
+ PR fortran/36852
+ * io/list_read.c: If variable rank is zero, do not adjust the found
+ namelist object pointer.
+
+2008-07-22 Daniel Kraft <d@domob.eu>
+
+ PR fortran/29835
+ * io/format.c (struct format_data): New member error_element.
+ (unexpected_element): Added '%c' to message.
+ (next_char): Keep track of last parsed character in fmt->error_element.
+ (format_error): If the message is unexpected_element, output the
+ offending character, too.
+
+2008-07-22 Thomas Koenig <tkoenig@gcc.gnu.org>
+
+ PR libfortran/36890
+ * io/file_pos.c: Declare READ_CHUNK as signed to avoid
+ signed/unsigned comparison warning in formatted_backspace.
+
+2008-07-21 Thomas Koenig <tkoenig@gcc.gnu.org>
+
+ PR libfortran/36773
+ * intrinsics/cshift0.c (cshift0): Return early if size of array
+ is zero.
+ * intrinsics/eoshift0.c (eoshift0): Return early if size of
+ return array is zero.
+ * intrinsics/eoshift2.c (eoshift2): Likewise.
+ * m4/eoshift1.m4 (eoshift1): Return early if size of array
+ is zero.
+ * m4/eoshift3.m4 (eoshift3): Likewise.
+ * m4/eoshift2.m4 (eoshift2): Return early if size of return
+ array is zero.
+ * m4/eoshift4.m4 (eoshift2): Return early if size of return
+ array is zero.
+ * generated/cshift1_16.c: Regenerated.
+ * generated/cshift1_4.c: Regenerated.
+ * generated/cshift1_8.c: Regenerated.
+ * generated/eoshift1_16.c: Regenerated.
+ * generated/eoshift1_4.c: Regenerated.
+ * generated/eoshift1_8.c: Regenerated.
+ * generated/eoshift3_16.c: Regenerated.
+ * generated/eoshift3_4.c: Regenerated.
+ * generated/eoshift3_8.c: Regenerated.
+
+2008-07-20 Jerry DeLisle <jvdelisle@gcc.gnu.org>
+
+ PR fortran/36857
+ * io/write_float.def: Comment out locale dependent code and fix general
+ comments.
+
+2008-07-07 Thomas Koenig <tkoenig@gcc.gnu.org>
+
+ PR fortran/36341
+ PR fortran/34670
+ * m4/matmul.m4: Add bounds checking.
+ * m4/matmull.m4: Likewise.
+ * generated/matmul_c10.c: Regenerated.
+ * generated/matmul_c16.c: Regenerated.
+ * generated/matmul_c4.c: Regenerated.
+ * generated/matmul_c8.c: Regenerated.
+ * generated/matmul_i1.c: Regenerated.
+ * generated/matmul_i16.c: Regenerated.
+ * generated/matmul_i2.c: Regenerated.
+ * generated/matmul_i4.c: Regenerated.
+ * generated/matmul_i8.c: Regenerated.
+ * generated/matmul_l16.c: Regenerated.
+ * generated/matmul_l4.c: Regenerated.
+ * generated/matmul_l8.c: Regenerated.
+ * generated/matmul_r10.c: Regenerated.
+ * generated/matmul_r16.c: Regenerated.
+ * generated/matmul_r4.c: Regenerated.
+ * generated/matmul_r8.c: Regenerated.
+
+2008-07-07 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
+
+ * acinclude.m4 (LIBGFOR_CHECK_GTHR_DEFAULT): Fix configure cache
+ variable name.
+ * configure: Regenerate.
+
2008-07-01 Jerry DeLisle <jvdelisle@gcc.gnu.org>
PR fortran/36676
diff --git a/libgfortran/acinclude.m4 b/libgfortran/acinclude.m4
index d1994b49d90..9f8ae54fab6 100644
--- a/libgfortran/acinclude.m4
+++ b/libgfortran/acinclude.m4
@@ -86,10 +86,10 @@ if (foovar > 10) return __sync_add_and_fetch (&foovar, -1);],
dnl Check if threads are supported.
AC_DEFUN([LIBGFOR_CHECK_GTHR_DEFAULT], [
AC_CACHE_CHECK([configured target thread model],
- target_thread_file, [
-target_thread_file=`$CC -v 2>&1 | sed -n 's/^Thread model: //p'`])
+ libgfor_cv_target_thread_file, [
+libgfor_cv_target_thread_file=`$CC -v 2>&1 | sed -n 's/^Thread model: //p'`])
- if test $target_thread_file != single; then
+ if test $libgfor_cv_target_thread_file != single; then
AC_DEFINE(HAVE_GTHR_DEFAULT, 1,
[Define if the compiler has a thread header that is non single.])
fi])
diff --git a/libgfortran/configure b/libgfortran/configure
index 176632426b8..0bd9a22d43f 100755
--- a/libgfortran/configure
+++ b/libgfortran/configure
@@ -33157,16 +33157,16 @@ _ACEOF
echo "$as_me:$LINENO: checking configured target thread model" >&5
echo $ECHO_N "checking configured target thread model... $ECHO_C" >&6
-if test "${target_thread_file+set}" = set; then
+if test "${libgfor_cv_target_thread_file+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
-target_thread_file=`$CC -v 2>&1 | sed -n 's/^Thread model: //p'`
+libgfor_cv_target_thread_file=`$CC -v 2>&1 | sed -n 's/^Thread model: //p'`
fi
-echo "$as_me:$LINENO: result: $target_thread_file" >&5
-echo "${ECHO_T}$target_thread_file" >&6
+echo "$as_me:$LINENO: result: $libgfor_cv_target_thread_file" >&5
+echo "${ECHO_T}$libgfor_cv_target_thread_file" >&6
- if test $target_thread_file != single; then
+ if test $libgfor_cv_target_thread_file != single; then
cat >>confdefs.h <<\_ACEOF
#define HAVE_GTHR_DEFAULT 1
diff --git a/libgfortran/generated/cshift1_16.c b/libgfortran/generated/cshift1_16.c
index 2943c3ed86d..06e27468e85 100644
--- a/libgfortran/generated/cshift1_16.c
+++ b/libgfortran/generated/cshift1_16.c
@@ -67,6 +67,7 @@ cshift1 (gfc_array_char * const restrict ret,
index_type n;
int which;
GFC_INTEGER_16 sh;
+ index_type arraysize;
if (pwhich)
which = *pwhich - 1;
@@ -76,11 +77,13 @@ cshift1 (gfc_array_char * const restrict ret,
if (which < 0 || (which + 1) > GFC_DESCRIPTOR_RANK (array))
runtime_error ("Argument 'DIM' is out of range in call to 'CSHIFT'");
+ arraysize = size0 ((array_t *)array);
+
if (ret->data == NULL)
{
int i;
- ret->data = internal_malloc_size (size * size0 ((array_t *)array));
+ ret->data = internal_malloc_size (size * arraysize);
ret->offset = 0;
ret->dtype = array->dtype;
for (i = 0; i < GFC_DESCRIPTOR_RANK (array); i++)
@@ -95,6 +98,9 @@ cshift1 (gfc_array_char * const restrict ret,
}
}
+ if (arraysize == 0)
+ return;
+
extent[0] = 1;
count[0] = 0;
n = 0;
diff --git a/libgfortran/generated/cshift1_4.c b/libgfortran/generated/cshift1_4.c
index 3f4f9e0bf25..3be3c3c15a6 100644
--- a/libgfortran/generated/cshift1_4.c
+++ b/libgfortran/generated/cshift1_4.c
@@ -67,6 +67,7 @@ cshift1 (gfc_array_char * const restrict ret,
index_type n;
int which;
GFC_INTEGER_4 sh;
+ index_type arraysize;
if (pwhich)
which = *pwhich - 1;
@@ -76,11 +77,13 @@ cshift1 (gfc_array_char * const restrict ret,
if (which < 0 || (which + 1) > GFC_DESCRIPTOR_RANK (array))
runtime_error ("Argument 'DIM' is out of range in call to 'CSHIFT'");
+ arraysize = size0 ((array_t *)array);
+
if (ret->data == NULL)
{
int i;
- ret->data = internal_malloc_size (size * size0 ((array_t *)array));
+ ret->data = internal_malloc_size (size * arraysize);
ret->offset = 0;
ret->dtype = array->dtype;
for (i = 0; i < GFC_DESCRIPTOR_RANK (array); i++)
@@ -95,6 +98,9 @@ cshift1 (gfc_array_char * const restrict ret,
}
}
+ if (arraysize == 0)
+ return;
+
extent[0] = 1;
count[0] = 0;
n = 0;
diff --git a/libgfortran/generated/cshift1_8.c b/libgfortran/generated/cshift1_8.c
index 4d246e54d95..b444a691acc 100644
--- a/libgfortran/generated/cshift1_8.c
+++ b/libgfortran/generated/cshift1_8.c
@@ -67,6 +67,7 @@ cshift1 (gfc_array_char * const restrict ret,
index_type n;
int which;
GFC_INTEGER_8 sh;
+ index_type arraysize;
if (pwhich)
which = *pwhich - 1;
@@ -76,11 +77,13 @@ cshift1 (gfc_array_char * const restrict ret,
if (which < 0 || (which + 1) > GFC_DESCRIPTOR_RANK (array))
runtime_error ("Argument 'DIM' is out of range in call to 'CSHIFT'");
+ arraysize = size0 ((array_t *)array);
+
if (ret->data == NULL)
{
int i;
- ret->data = internal_malloc_size (size * size0 ((array_t *)array));
+ ret->data = internal_malloc_size (size * arraysize);
ret->offset = 0;
ret->dtype = array->dtype;
for (i = 0; i < GFC_DESCRIPTOR_RANK (array); i++)
@@ -95,6 +98,9 @@ cshift1 (gfc_array_char * const restrict ret,
}
}
+ if (arraysize == 0)
+ return;
+
extent[0] = 1;
count[0] = 0;
n = 0;
diff --git a/libgfortran/generated/eoshift1_16.c b/libgfortran/generated/eoshift1_16.c
index 63b75bdbd6b..fd145c12e6e 100644
--- a/libgfortran/generated/eoshift1_16.c
+++ b/libgfortran/generated/eoshift1_16.c
@@ -102,6 +102,11 @@ eoshift1 (gfc_array_char * const restrict ret,
ret->dim[i].stride = (ret->dim[i-1].ubound + 1) * ret->dim[i-1].stride;
}
}
+ else
+ {
+ if (size0 ((array_t *) ret) == 0)
+ return;
+ }
n = 0;
for (dim = 0; dim < GFC_DESCRIPTOR_RANK (array); dim++)
diff --git a/libgfortran/generated/eoshift1_4.c b/libgfortran/generated/eoshift1_4.c
index 58ce7e9f5dd..d78c40a1113 100644
--- a/libgfortran/generated/eoshift1_4.c
+++ b/libgfortran/generated/eoshift1_4.c
@@ -102,6 +102,11 @@ eoshift1 (gfc_array_char * const restrict ret,
ret->dim[i].stride = (ret->dim[i-1].ubound + 1) * ret->dim[i-1].stride;
}
}
+ else
+ {
+ if (size0 ((array_t *) ret) == 0)
+ return;
+ }
n = 0;
for (dim = 0; dim < GFC_DESCRIPTOR_RANK (array); dim++)
diff --git a/libgfortran/generated/eoshift1_8.c b/libgfortran/generated/eoshift1_8.c
index 0e9c2f1442a..06d55323369 100644
--- a/libgfortran/generated/eoshift1_8.c
+++ b/libgfortran/generated/eoshift1_8.c
@@ -102,6 +102,11 @@ eoshift1 (gfc_array_char * const restrict ret,
ret->dim[i].stride = (ret->dim[i-1].ubound + 1) * ret->dim[i-1].stride;
}
}
+ else
+ {
+ if (size0 ((array_t *) ret) == 0)
+ return;
+ }
n = 0;
for (dim = 0; dim < GFC_DESCRIPTOR_RANK (array); dim++)
diff --git a/libgfortran/generated/eoshift3_16.c b/libgfortran/generated/eoshift3_16.c
index 214f3783d4f..66a507773ac 100644
--- a/libgfortran/generated/eoshift3_16.c
+++ b/libgfortran/generated/eoshift3_16.c
@@ -103,6 +103,11 @@ eoshift3 (gfc_array_char * const restrict ret,
ret->dim[i].stride = (ret->dim[i-1].ubound + 1) * ret->dim[i-1].stride;
}
}
+ else
+ {
+ if (size0 ((array_t *) ret) == 0)
+ return;
+ }
extent[0] = 1;
diff --git a/libgfortran/generated/eoshift3_4.c b/libgfortran/generated/eoshift3_4.c
index e96ef2504b0..3579cffd483 100644
--- a/libgfortran/generated/eoshift3_4.c
+++ b/libgfortran/generated/eoshift3_4.c
@@ -103,6 +103,11 @@ eoshift3 (gfc_array_char * const restrict ret,
ret->dim[i].stride = (ret->dim[i-1].ubound + 1) * ret->dim[i-1].stride;
}
}
+ else
+ {
+ if (size0 ((array_t *) ret) == 0)
+ return;
+ }
extent[0] = 1;
diff --git a/libgfortran/generated/eoshift3_8.c b/libgfortran/generated/eoshift3_8.c
index dc39b94eb97..de969a0c92b 100644
--- a/libgfortran/generated/eoshift3_8.c
+++ b/libgfortran/generated/eoshift3_8.c
@@ -103,6 +103,11 @@ eoshift3 (gfc_array_char * const restrict ret,
ret->dim[i].stride = (ret->dim[i-1].ubound + 1) * ret->dim[i-1].stride;
}
}
+ else
+ {
+ if (size0 ((array_t *) ret) == 0)
+ return;
+ }
extent[0] = 1;
diff --git a/libgfortran/generated/matmul_c10.c b/libgfortran/generated/matmul_c10.c
index 08c2044dd8b..0e378626f96 100644
--- a/libgfortran/generated/matmul_c10.c
+++ b/libgfortran/generated/matmul_c10.c
@@ -135,6 +135,47 @@ matmul_c10 (gfc_array_c10 * const restrict retarray,
= internal_malloc_size (sizeof (GFC_COMPLEX_10) * size0 ((array_t *) retarray));
retarray->offset = 0;
}
+ else if (compile_options.bounds_check)
+ {
+ index_type ret_extent, arg_extent;
+
+ if (GFC_DESCRIPTOR_RANK (a) == 1)
+ {
+ arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic: is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ else if (GFC_DESCRIPTOR_RANK (b) == 1)
+ {
+ arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic: is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ else
+ {
+ arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic for dimension 1:"
+ " is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+
+ arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound;
+ ret_extent = retarray->dim[1].ubound + 1 - retarray->dim[1].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic for dimension 2:"
+ " is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ }
if (GFC_DESCRIPTOR_RANK (retarray) == 1)
diff --git a/libgfortran/generated/matmul_c16.c b/libgfortran/generated/matmul_c16.c
index 6a2a6390967..34cc51dbd78 100644
--- a/libgfortran/generated/matmul_c16.c
+++ b/libgfortran/generated/matmul_c16.c
@@ -135,6 +135,47 @@ matmul_c16 (gfc_array_c16 * const restrict retarray,
= internal_malloc_size (sizeof (GFC_COMPLEX_16) * size0 ((array_t *) retarray));
retarray->offset = 0;
}
+ else if (compile_options.bounds_check)
+ {
+ index_type ret_extent, arg_extent;
+
+ if (GFC_DESCRIPTOR_RANK (a) == 1)
+ {
+ arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic: is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ else if (GFC_DESCRIPTOR_RANK (b) == 1)
+ {
+ arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic: is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ else
+ {
+ arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic for dimension 1:"
+ " is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+
+ arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound;
+ ret_extent = retarray->dim[1].ubound + 1 - retarray->dim[1].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic for dimension 2:"
+ " is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ }
if (GFC_DESCRIPTOR_RANK (retarray) == 1)
diff --git a/libgfortran/generated/matmul_c4.c b/libgfortran/generated/matmul_c4.c
index 6dcf6fea56a..fdfea1df955 100644
--- a/libgfortran/generated/matmul_c4.c
+++ b/libgfortran/generated/matmul_c4.c
@@ -135,6 +135,47 @@ matmul_c4 (gfc_array_c4 * const restrict retarray,
= internal_malloc_size (sizeof (GFC_COMPLEX_4) * size0 ((array_t *) retarray));
retarray->offset = 0;
}
+ else if (compile_options.bounds_check)
+ {
+ index_type ret_extent, arg_extent;
+
+ if (GFC_DESCRIPTOR_RANK (a) == 1)
+ {
+ arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic: is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ else if (GFC_DESCRIPTOR_RANK (b) == 1)
+ {
+ arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic: is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ else
+ {
+ arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic for dimension 1:"
+ " is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+
+ arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound;
+ ret_extent = retarray->dim[1].ubound + 1 - retarray->dim[1].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic for dimension 2:"
+ " is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ }
if (GFC_DESCRIPTOR_RANK (retarray) == 1)
diff --git a/libgfortran/generated/matmul_c8.c b/libgfortran/generated/matmul_c8.c
index 8bc619d879f..9d6694922f1 100644
--- a/libgfortran/generated/matmul_c8.c
+++ b/libgfortran/generated/matmul_c8.c
@@ -135,6 +135,47 @@ matmul_c8 (gfc_array_c8 * const restrict retarray,
= internal_malloc_size (sizeof (GFC_COMPLEX_8) * size0 ((array_t *) retarray));
retarray->offset = 0;
}
+ else if (compile_options.bounds_check)
+ {
+ index_type ret_extent, arg_extent;
+
+ if (GFC_DESCRIPTOR_RANK (a) == 1)
+ {
+ arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic: is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ else if (GFC_DESCRIPTOR_RANK (b) == 1)
+ {
+ arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic: is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ else
+ {
+ arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic for dimension 1:"
+ " is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+
+ arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound;
+ ret_extent = retarray->dim[1].ubound + 1 - retarray->dim[1].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic for dimension 2:"
+ " is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ }
if (GFC_DESCRIPTOR_RANK (retarray) == 1)
diff --git a/libgfortran/generated/matmul_i1.c b/libgfortran/generated/matmul_i1.c
index ca16ed40b2f..34fd7c51b78 100644
--- a/libgfortran/generated/matmul_i1.c
+++ b/libgfortran/generated/matmul_i1.c
@@ -135,6 +135,47 @@ matmul_i1 (gfc_array_i1 * const restrict retarray,
= internal_malloc_size (sizeof (GFC_INTEGER_1) * size0 ((array_t *) retarray));
retarray->offset = 0;
}
+ else if (compile_options.bounds_check)
+ {
+ index_type ret_extent, arg_extent;
+
+ if (GFC_DESCRIPTOR_RANK (a) == 1)
+ {
+ arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic: is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ else if (GFC_DESCRIPTOR_RANK (b) == 1)
+ {
+ arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic: is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ else
+ {
+ arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic for dimension 1:"
+ " is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+
+ arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound;
+ ret_extent = retarray->dim[1].ubound + 1 - retarray->dim[1].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic for dimension 2:"
+ " is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ }
if (GFC_DESCRIPTOR_RANK (retarray) == 1)
diff --git a/libgfortran/generated/matmul_i16.c b/libgfortran/generated/matmul_i16.c
index 33c62ae4152..0c7c5d8f396 100644
--- a/libgfortran/generated/matmul_i16.c
+++ b/libgfortran/generated/matmul_i16.c
@@ -135,6 +135,47 @@ matmul_i16 (gfc_array_i16 * const restrict retarray,
= internal_malloc_size (sizeof (GFC_INTEGER_16) * size0 ((array_t *) retarray));
retarray->offset = 0;
}
+ else if (compile_options.bounds_check)
+ {
+ index_type ret_extent, arg_extent;
+
+ if (GFC_DESCRIPTOR_RANK (a) == 1)
+ {
+ arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic: is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ else if (GFC_DESCRIPTOR_RANK (b) == 1)
+ {
+ arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic: is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ else
+ {
+ arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic for dimension 1:"
+ " is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+
+ arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound;
+ ret_extent = retarray->dim[1].ubound + 1 - retarray->dim[1].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic for dimension 2:"
+ " is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ }
if (GFC_DESCRIPTOR_RANK (retarray) == 1)
diff --git a/libgfortran/generated/matmul_i2.c b/libgfortran/generated/matmul_i2.c
index e3119acbd41..5d55847edce 100644
--- a/libgfortran/generated/matmul_i2.c
+++ b/libgfortran/generated/matmul_i2.c
@@ -135,6 +135,47 @@ matmul_i2 (gfc_array_i2 * const restrict retarray,
= internal_malloc_size (sizeof (GFC_INTEGER_2) * size0 ((array_t *) retarray));
retarray->offset = 0;
}
+ else if (compile_options.bounds_check)
+ {
+ index_type ret_extent, arg_extent;
+
+ if (GFC_DESCRIPTOR_RANK (a) == 1)
+ {
+ arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic: is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ else if (GFC_DESCRIPTOR_RANK (b) == 1)
+ {
+ arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic: is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ else
+ {
+ arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic for dimension 1:"
+ " is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+
+ arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound;
+ ret_extent = retarray->dim[1].ubound + 1 - retarray->dim[1].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic for dimension 2:"
+ " is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ }
if (GFC_DESCRIPTOR_RANK (retarray) == 1)
diff --git a/libgfortran/generated/matmul_i4.c b/libgfortran/generated/matmul_i4.c
index a1b8c50f051..a80f14940c8 100644
--- a/libgfortran/generated/matmul_i4.c
+++ b/libgfortran/generated/matmul_i4.c
@@ -135,6 +135,47 @@ matmul_i4 (gfc_array_i4 * const restrict retarray,
= internal_malloc_size (sizeof (GFC_INTEGER_4) * size0 ((array_t *) retarray));
retarray->offset = 0;
}
+ else if (compile_options.bounds_check)
+ {
+ index_type ret_extent, arg_extent;
+
+ if (GFC_DESCRIPTOR_RANK (a) == 1)
+ {
+ arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic: is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ else if (GFC_DESCRIPTOR_RANK (b) == 1)
+ {
+ arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic: is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ else
+ {
+ arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic for dimension 1:"
+ " is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+
+ arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound;
+ ret_extent = retarray->dim[1].ubound + 1 - retarray->dim[1].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic for dimension 2:"
+ " is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ }
if (GFC_DESCRIPTOR_RANK (retarray) == 1)
diff --git a/libgfortran/generated/matmul_i8.c b/libgfortran/generated/matmul_i8.c
index eee73ac88f0..91499c793e6 100644
--- a/libgfortran/generated/matmul_i8.c
+++ b/libgfortran/generated/matmul_i8.c
@@ -135,6 +135,47 @@ matmul_i8 (gfc_array_i8 * const restrict retarray,
= internal_malloc_size (sizeof (GFC_INTEGER_8) * size0 ((array_t *) retarray));
retarray->offset = 0;
}
+ else if (compile_options.bounds_check)
+ {
+ index_type ret_extent, arg_extent;
+
+ if (GFC_DESCRIPTOR_RANK (a) == 1)
+ {
+ arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic: is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ else if (GFC_DESCRIPTOR_RANK (b) == 1)
+ {
+ arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic: is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ else
+ {
+ arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic for dimension 1:"
+ " is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+
+ arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound;
+ ret_extent = retarray->dim[1].ubound + 1 - retarray->dim[1].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic for dimension 2:"
+ " is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ }
if (GFC_DESCRIPTOR_RANK (retarray) == 1)
diff --git a/libgfortran/generated/matmul_l16.c b/libgfortran/generated/matmul_l16.c
index b2b86ecfed1..b604edfb2ca 100644
--- a/libgfortran/generated/matmul_l16.c
+++ b/libgfortran/generated/matmul_l16.c
@@ -99,6 +99,47 @@ matmul_l16 (gfc_array_l16 * const restrict retarray,
= internal_malloc_size (sizeof (GFC_LOGICAL_16) * size0 ((array_t *) retarray));
retarray->offset = 0;
}
+ else if (compile_options.bounds_check)
+ {
+ index_type ret_extent, arg_extent;
+
+ if (GFC_DESCRIPTOR_RANK (a) == 1)
+ {
+ arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic: is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ else if (GFC_DESCRIPTOR_RANK (b) == 1)
+ {
+ arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic: is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ else
+ {
+ arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic for dimension 1:"
+ " is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+
+ arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound;
+ ret_extent = retarray->dim[1].ubound + 1 - retarray->dim[1].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic for dimension 2:"
+ " is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ }
abase = a->data;
a_kind = GFC_DESCRIPTOR_SIZE (a);
diff --git a/libgfortran/generated/matmul_l4.c b/libgfortran/generated/matmul_l4.c
index 9a6cb1d357d..5aed0fe2ba0 100644
--- a/libgfortran/generated/matmul_l4.c
+++ b/libgfortran/generated/matmul_l4.c
@@ -99,6 +99,47 @@ matmul_l4 (gfc_array_l4 * const restrict retarray,
= internal_malloc_size (sizeof (GFC_LOGICAL_4) * size0 ((array_t *) retarray));
retarray->offset = 0;
}
+ else if (compile_options.bounds_check)
+ {
+ index_type ret_extent, arg_extent;
+
+ if (GFC_DESCRIPTOR_RANK (a) == 1)
+ {
+ arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic: is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ else if (GFC_DESCRIPTOR_RANK (b) == 1)
+ {
+ arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic: is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ else
+ {
+ arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic for dimension 1:"
+ " is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+
+ arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound;
+ ret_extent = retarray->dim[1].ubound + 1 - retarray->dim[1].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic for dimension 2:"
+ " is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ }
abase = a->data;
a_kind = GFC_DESCRIPTOR_SIZE (a);
diff --git a/libgfortran/generated/matmul_l8.c b/libgfortran/generated/matmul_l8.c
index 7d4e35e82e3..26baad32136 100644
--- a/libgfortran/generated/matmul_l8.c
+++ b/libgfortran/generated/matmul_l8.c
@@ -99,6 +99,47 @@ matmul_l8 (gfc_array_l8 * const restrict retarray,
= internal_malloc_size (sizeof (GFC_LOGICAL_8) * size0 ((array_t *) retarray));
retarray->offset = 0;
}
+ else if (compile_options.bounds_check)
+ {
+ index_type ret_extent, arg_extent;
+
+ if (GFC_DESCRIPTOR_RANK (a) == 1)
+ {
+ arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic: is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ else if (GFC_DESCRIPTOR_RANK (b) == 1)
+ {
+ arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic: is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ else
+ {
+ arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic for dimension 1:"
+ " is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+
+ arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound;
+ ret_extent = retarray->dim[1].ubound + 1 - retarray->dim[1].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic for dimension 2:"
+ " is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ }
abase = a->data;
a_kind = GFC_DESCRIPTOR_SIZE (a);
diff --git a/libgfortran/generated/matmul_r10.c b/libgfortran/generated/matmul_r10.c
index 58dfe75814f..931e2bdc0f0 100644
--- a/libgfortran/generated/matmul_r10.c
+++ b/libgfortran/generated/matmul_r10.c
@@ -135,6 +135,47 @@ matmul_r10 (gfc_array_r10 * const restrict retarray,
= internal_malloc_size (sizeof (GFC_REAL_10) * size0 ((array_t *) retarray));
retarray->offset = 0;
}
+ else if (compile_options.bounds_check)
+ {
+ index_type ret_extent, arg_extent;
+
+ if (GFC_DESCRIPTOR_RANK (a) == 1)
+ {
+ arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic: is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ else if (GFC_DESCRIPTOR_RANK (b) == 1)
+ {
+ arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic: is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ else
+ {
+ arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic for dimension 1:"
+ " is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+
+ arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound;
+ ret_extent = retarray->dim[1].ubound + 1 - retarray->dim[1].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic for dimension 2:"
+ " is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ }
if (GFC_DESCRIPTOR_RANK (retarray) == 1)
diff --git a/libgfortran/generated/matmul_r16.c b/libgfortran/generated/matmul_r16.c
index a6a93be91fb..16ec175be0c 100644
--- a/libgfortran/generated/matmul_r16.c
+++ b/libgfortran/generated/matmul_r16.c
@@ -135,6 +135,47 @@ matmul_r16 (gfc_array_r16 * const restrict retarray,
= internal_malloc_size (sizeof (GFC_REAL_16) * size0 ((array_t *) retarray));
retarray->offset = 0;
}
+ else if (compile_options.bounds_check)
+ {
+ index_type ret_extent, arg_extent;
+
+ if (GFC_DESCRIPTOR_RANK (a) == 1)
+ {
+ arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic: is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ else if (GFC_DESCRIPTOR_RANK (b) == 1)
+ {
+ arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic: is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ else
+ {
+ arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic for dimension 1:"
+ " is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+
+ arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound;
+ ret_extent = retarray->dim[1].ubound + 1 - retarray->dim[1].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic for dimension 2:"
+ " is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ }
if (GFC_DESCRIPTOR_RANK (retarray) == 1)
diff --git a/libgfortran/generated/matmul_r4.c b/libgfortran/generated/matmul_r4.c
index 1154d41a33f..47d976415d0 100644
--- a/libgfortran/generated/matmul_r4.c
+++ b/libgfortran/generated/matmul_r4.c
@@ -135,6 +135,47 @@ matmul_r4 (gfc_array_r4 * const restrict retarray,
= internal_malloc_size (sizeof (GFC_REAL_4) * size0 ((array_t *) retarray));
retarray->offset = 0;
}
+ else if (compile_options.bounds_check)
+ {
+ index_type ret_extent, arg_extent;
+
+ if (GFC_DESCRIPTOR_RANK (a) == 1)
+ {
+ arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic: is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ else if (GFC_DESCRIPTOR_RANK (b) == 1)
+ {
+ arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic: is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ else
+ {
+ arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic for dimension 1:"
+ " is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+
+ arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound;
+ ret_extent = retarray->dim[1].ubound + 1 - retarray->dim[1].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic for dimension 2:"
+ " is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ }
if (GFC_DESCRIPTOR_RANK (retarray) == 1)
diff --git a/libgfortran/generated/matmul_r8.c b/libgfortran/generated/matmul_r8.c
index 7bce2533b41..a359ffd8fd3 100644
--- a/libgfortran/generated/matmul_r8.c
+++ b/libgfortran/generated/matmul_r8.c
@@ -135,6 +135,47 @@ matmul_r8 (gfc_array_r8 * const restrict retarray,
= internal_malloc_size (sizeof (GFC_REAL_8) * size0 ((array_t *) retarray));
retarray->offset = 0;
}
+ else if (compile_options.bounds_check)
+ {
+ index_type ret_extent, arg_extent;
+
+ if (GFC_DESCRIPTOR_RANK (a) == 1)
+ {
+ arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic: is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ else if (GFC_DESCRIPTOR_RANK (b) == 1)
+ {
+ arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic: is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ else
+ {
+ arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic for dimension 1:"
+ " is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+
+ arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound;
+ ret_extent = retarray->dim[1].ubound + 1 - retarray->dim[1].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic for dimension 2:"
+ " is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ }
if (GFC_DESCRIPTOR_RANK (retarray) == 1)
diff --git a/libgfortran/gfortran.map b/libgfortran/gfortran.map
index 0671b60fb86..93973d5b338 100644
--- a/libgfortran/gfortran.map
+++ b/libgfortran/gfortran.map
@@ -1072,6 +1072,7 @@ GFORTRAN_1.1 {
_gfortran_pack_char4;
_gfortran_pack_s_char4;
_gfortran_reshape_char4;
+ _gfortran_runtime_warning_at;
_gfortran_selected_char_kind;
_gfortran_select_string_char4;
_gfortran_spread_char4;
diff --git a/libgfortran/intrinsics/cshift0.c b/libgfortran/intrinsics/cshift0.c
index 76ce97e0f10..ac26e86cf5f 100644
--- a/libgfortran/intrinsics/cshift0.c
+++ b/libgfortran/intrinsics/cshift0.c
@@ -97,10 +97,43 @@ cshift0 (gfc_array_char * ret, const gfc_array_char * array,
index_type len;
index_type n;
int whichloop;
+ index_type arraysize;
if (which < 1 || which > GFC_DESCRIPTOR_RANK (array))
runtime_error ("Argument 'DIM' is out of range in call to 'CSHIFT'");
+ arraysize = size0 ((array_t *) array);
+
+ if (ret->data == NULL)
+ {
+ int i;
+
+ ret->offset = 0;
+ ret->dtype = array->dtype;
+ for (i = 0; i < GFC_DESCRIPTOR_RANK (array); i++)
+ {
+ ret->dim[i].lbound = 0;
+ ret->dim[i].ubound = array->dim[i].ubound - array->dim[i].lbound;
+
+ if (i == 0)
+ ret->dim[i].stride = 1;
+ else
+ ret->dim[i].stride = (ret->dim[i-1].ubound + 1)
+ * ret->dim[i-1].stride;
+ }
+
+ if (arraysize > 0)
+ ret->data = internal_malloc_size (size * arraysize);
+ else
+ {
+ ret->data = internal_malloc_size (1);
+ return;
+ }
+ }
+
+ if (arraysize == 0)
+ return;
+
which = which - 1;
sstride[0] = 0;
rstride[0] = 0;
@@ -142,34 +175,6 @@ cshift0 (gfc_array_char * ret, const gfc_array_char * array,
soffset = size;
len = 0;
- if (ret->data == NULL)
- {
- int i;
- index_type arraysize = size0 ((array_t *)array);
-
- ret->offset = 0;
- ret->dtype = array->dtype;
- for (i = 0; i < GFC_DESCRIPTOR_RANK (array); i++)
- {
- ret->dim[i].lbound = 0;
- ret->dim[i].ubound = array->dim[i].ubound - array->dim[i].lbound;
-
- if (i == 0)
- ret->dim[i].stride = 1;
- else
- ret->dim[i].stride = (ret->dim[i-1].ubound + 1)
- * ret->dim[i-1].stride;
- }
-
- if (arraysize > 0)
- ret->data = internal_malloc_size (size * arraysize);
- else
- {
- ret->data = internal_malloc_size (1);
- return;
- }
- }
-
for (dim = 0; dim < GFC_DESCRIPTOR_RANK (array); dim++)
{
if (dim == which)
diff --git a/libgfortran/intrinsics/eoshift0.c b/libgfortran/intrinsics/eoshift0.c
index ac7a0ba85b6..fd216b1084b 100644
--- a/libgfortran/intrinsics/eoshift0.c
+++ b/libgfortran/intrinsics/eoshift0.c
@@ -84,6 +84,11 @@ eoshift0 (gfc_array_char * ret, const gfc_array_char * array,
ret->dim[i].stride = (ret->dim[i-1].ubound + 1) * ret->dim[i-1].stride;
}
}
+ else
+ {
+ if (size0 ((array_t *) ret) == 0)
+ return;
+ }
which = which - 1;
diff --git a/libgfortran/intrinsics/eoshift2.c b/libgfortran/intrinsics/eoshift2.c
index 239d9714a99..aa66a8dfe00 100644
--- a/libgfortran/intrinsics/eoshift2.c
+++ b/libgfortran/intrinsics/eoshift2.c
@@ -63,6 +63,7 @@ eoshift2 (gfc_array_char *ret, const gfc_array_char *array,
index_type dim;
index_type len;
index_type n;
+ index_type arraysize;
/* The compiler cannot figure out that these are set, initialize
them to avoid warnings. */
@@ -70,11 +71,13 @@ eoshift2 (gfc_array_char *ret, const gfc_array_char *array,
soffset = 0;
roffset = 0;
+ arraysize = size0 ((array_t *) array);
+
if (ret->data == NULL)
{
int i;
- ret->data = internal_malloc_size (size * size0 ((array_t *)array));
+ ret->data = internal_malloc_size (size * arraysize);
ret->offset = 0;
ret->dtype = array->dtype;
for (i = 0; i < GFC_DESCRIPTOR_RANK (array); i++)
@@ -88,6 +91,14 @@ eoshift2 (gfc_array_char *ret, const gfc_array_char *array,
ret->dim[i].stride = (ret->dim[i-1].ubound + 1) * ret->dim[i-1].stride;
}
}
+ else
+ {
+ if (size0 ((array_t *) ret) == 0)
+ return;
+ }
+
+ if (arraysize == 0 && filler == NULL)
+ return;
which = which - 1;
diff --git a/libgfortran/io/file_pos.c b/libgfortran/io/file_pos.c
index f4864884f33..89c67365429 100644
--- a/libgfortran/io/file_pos.c
+++ b/libgfortran/io/file_pos.c
@@ -39,7 +39,7 @@ Boston, MA 02110-1301, USA. */
record, and we have to sift backwards to find the newline before
that or the start of the file, whichever comes first. */
-static const unsigned int READ_CHUNK = 4096;
+static const int READ_CHUNK = 4096;
static void
formatted_backspace (st_parameter_filepos *fpp, gfc_unit *u)
diff --git a/libgfortran/io/format.c b/libgfortran/io/format.c
index cf299c161a4..02ce2913bd2 100644
--- a/libgfortran/io/format.c
+++ b/libgfortran/io/format.c
@@ -50,6 +50,7 @@ typedef struct format_data
{
char *format_string, *string;
const char *error;
+ char error_element;
format_token saved_token;
int value, format_string_len, reversion_ok;
fnode *avail;
@@ -67,7 +68,7 @@ static const fnode colon_node = { FMT_COLON, 0, NULL, NULL, {{ 0, 0, 0 }}, 0,
static const char posint_required[] = "Positive width required in format",
period_required[] = "Period required in format",
nonneg_required[] = "Nonnegative width required in format",
- unexpected_element[] = "Unexpected element in format",
+ unexpected_element[] = "Unexpected element '%c' in format\n",
unexpected_end[] = "Unexpected end of format string",
bad_string[] = "Unterminated character constant in format",
bad_hollerith[] = "Hollerith constant extends past the end of the format",
@@ -89,7 +90,7 @@ next_char (format_data *fmt, int literal)
return -1;
fmt->format_string_len--;
- c = toupper (*fmt->format_string++);
+ fmt->error_element = c = toupper (*fmt->format_string++);
}
while ((c == ' ' || c == '\t') && !literal);
@@ -948,7 +949,10 @@ format_error (st_parameter_dt *dtp, const fnode *f, const char *message)
if (f != NULL)
fmt->format_string = f->source;
- sprintf (buffer, "%s\n", message);
+ if (message == unexpected_element)
+ sprintf (buffer, message, fmt->error_element);
+ else
+ sprintf (buffer, "%s\n", message);
j = fmt->format_string - dtp->format;
diff --git a/libgfortran/io/list_read.c b/libgfortran/io/list_read.c
index ba8de9750e1..34e2ac0698a 100644
--- a/libgfortran/io/list_read.c
+++ b/libgfortran/io/list_read.c
@@ -2791,7 +2791,7 @@ get_name:
if (nl->type == GFC_DTYPE_DERIVED)
nml_touch_nodes (nl);
- if (component_flag)
+ if (component_flag && nl->var_rank > 0)
nl = first_nl;
/* Make sure no extraneous qualifiers are there. */
diff --git a/libgfortran/io/write_float.def b/libgfortran/io/write_float.def
index 090bd712eb4..ed4c45f6277 100644
--- a/libgfortran/io/write_float.def
+++ b/libgfortran/io/write_float.def
@@ -99,32 +99,13 @@ output_float (st_parameter_dt *dtp, const fnode *f, char *buffer, size_t size,
if (d < 0)
internal_error (&dtp->common, "Unspecified precision");
- /* Use sprintf to print the number in the format +D.DDDDe+ddd
- For an N digit exponent, this gives us (MIN_FIELD_WIDTH-5)-N digits
- after the decimal point, plus another one before the decimal point. */
-
sign = calculate_sign (dtp, sign_bit);
-
- /* # The result will always contain a decimal point, even if no
- * digits follow it
- *
- * - The converted value is to be left adjusted on the field boundary
- *
- * + A sign (+ or -) always be placed before a number
- *
- * MIN_FIELD_WIDTH minimum field width
- *
- * * (ndigits-1) is used as the precision
- *
- * e format: [-]d.ddde±dd where there is one digit before the
- * decimal-point character and the number of digits after it is
- * equal to the precision. The exponent always contains at least two
- * digits; if the value is zero, the exponent is 00.
- */
-
- /* Check the given string has punctuation in the correct places. */
- if (d != 0 && (buffer[2] != '.' || buffer[ndigits + 2] != 'e'))
- internal_error (&dtp->common, "printf is broken");
+
+ /* The following code checks the given string has punctuation in the correct
+ places. Uncomment if needed for debugging.
+ if (d != 0 && ((buffer[2] != '.' && buffer[2] != ',')
+ || buffer[ndigits + 2] != 'e'))
+ internal_error (&dtp->common, "printf is broken"); */
/* Read the exponent back in. */
e = atoi (&buffer[ndigits + 3]) + 1;
@@ -702,8 +683,30 @@ OUTPUT_FLOAT_FMT_G(16)
#undef OUTPUT_FLOAT_FMT_G
+
/* Define a macro to build code for write_float. */
+ /* Note: Before output_float is called, sprintf is used to print to buffer the
+ number in the format +D.DDDDe+ddd. For an N digit exponent, this gives us
+ (MIN_FIELD_WIDTH-5)-N digits after the decimal point, plus another one
+ before the decimal point.
+
+ # The result will always contain a decimal point, even if no
+ digits follow it
+
+ - The converted value is to be left adjusted on the field boundary
+
+ + A sign (+ or -) always be placed before a number
+
+ MIN_FIELD_WIDTH minimum field width
+
+ * (ndigits-1) is used as the precision
+
+ e format: [-]d.ddde±dd where there is one digit before the
+ decimal-point character and the number of digits after it is
+ equal to the precision. The exponent always contains at least two
+ digits; if the value is zero, the exponent is 00. */
+
#ifdef HAVE_SNPRINTF
#define DTOA \
diff --git a/libgfortran/libgfortran.h b/libgfortran/libgfortran.h
index 10439bd3e5a..7c497004a81 100644
--- a/libgfortran/libgfortran.h
+++ b/libgfortran/libgfortran.h
@@ -643,6 +643,9 @@ extern void runtime_error_at (const char *, const char *, ...)
__attribute__ ((noreturn, format (printf, 2, 3)));
iexport_proto(runtime_error_at);
+extern void runtime_warning_at (const char *, const char *, ...);
+iexport_proto(runtime_warning_at);
+
extern void internal_error (st_parameter_common *, const char *)
__attribute__ ((noreturn));
internal_proto(internal_error);
diff --git a/libgfortran/m4/cshift1.m4 b/libgfortran/m4/cshift1.m4
index 28fae596bd4..861debeed2c 100644
--- a/libgfortran/m4/cshift1.m4
+++ b/libgfortran/m4/cshift1.m4
@@ -68,6 +68,7 @@ cshift1 (gfc_array_char * const restrict ret,
index_type n;
int which;
'atype_name` sh;
+ index_type arraysize;
if (pwhich)
which = *pwhich - 1;
@@ -77,11 +78,13 @@ cshift1 (gfc_array_char * const restrict ret,
if (which < 0 || (which + 1) > GFC_DESCRIPTOR_RANK (array))
runtime_error ("Argument ''`DIM''` is out of range in call to ''`CSHIFT''`");
+ arraysize = size0 ((array_t *)array);
+
if (ret->data == NULL)
{
int i;
- ret->data = internal_malloc_size (size * size0 ((array_t *)array));
+ ret->data = internal_malloc_size (size * arraysize);
ret->offset = 0;
ret->dtype = array->dtype;
for (i = 0; i < GFC_DESCRIPTOR_RANK (array); i++)
@@ -96,6 +99,9 @@ cshift1 (gfc_array_char * const restrict ret,
}
}
+ if (arraysize == 0)
+ return;
+
extent[0] = 1;
count[0] = 0;
n = 0;
diff --git a/libgfortran/m4/eoshift1.m4 b/libgfortran/m4/eoshift1.m4
index 8ce24eff0f5..01ca57ec68d 100644
--- a/libgfortran/m4/eoshift1.m4
+++ b/libgfortran/m4/eoshift1.m4
@@ -103,6 +103,11 @@ eoshift1 (gfc_array_char * const restrict ret,
ret->dim[i].stride = (ret->dim[i-1].ubound + 1) * ret->dim[i-1].stride;
}
}
+ else
+ {
+ if (size0 ((array_t *) ret) == 0)
+ return;
+ }
n = 0;
for (dim = 0; dim < GFC_DESCRIPTOR_RANK (array); dim++)
diff --git a/libgfortran/m4/eoshift3.m4 b/libgfortran/m4/eoshift3.m4
index 081ff927277..6a6929ca0c7 100644
--- a/libgfortran/m4/eoshift3.m4
+++ b/libgfortran/m4/eoshift3.m4
@@ -104,6 +104,11 @@ eoshift3 (gfc_array_char * const restrict ret,
ret->dim[i].stride = (ret->dim[i-1].ubound + 1) * ret->dim[i-1].stride;
}
}
+ else
+ {
+ if (size0 ((array_t *) ret) == 0)
+ return;
+ }
extent[0] = 1;
diff --git a/libgfortran/m4/matmul.m4 b/libgfortran/m4/matmul.m4
index 181efa3b654..a43b430c2e3 100644
--- a/libgfortran/m4/matmul.m4
+++ b/libgfortran/m4/matmul.m4
@@ -136,6 +136,47 @@ matmul_'rtype_code` ('rtype` * const restrict retarray,
= internal_malloc_size (sizeof ('rtype_name`) * size0 ((array_t *) retarray));
retarray->offset = 0;
}
+ else if (compile_options.bounds_check)
+ {
+ index_type ret_extent, arg_extent;
+
+ if (GFC_DESCRIPTOR_RANK (a) == 1)
+ {
+ arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic: is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ else if (GFC_DESCRIPTOR_RANK (b) == 1)
+ {
+ arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic: is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ else
+ {
+ arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic for dimension 1:"
+ " is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+
+ arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound;
+ ret_extent = retarray->dim[1].ubound + 1 - retarray->dim[1].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic for dimension 2:"
+ " is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ }
'
sinclude(`matmul_asm_'rtype_code`.m4')dnl
`
diff --git a/libgfortran/m4/matmull.m4 b/libgfortran/m4/matmull.m4
index 54afa8a238e..800444564f7 100644
--- a/libgfortran/m4/matmull.m4
+++ b/libgfortran/m4/matmull.m4
@@ -100,6 +100,47 @@ matmul_'rtype_code` ('rtype` * const restrict retarray,
= internal_malloc_size (sizeof ('rtype_name`) * size0 ((array_t *) retarray));
retarray->offset = 0;
}
+ else if (compile_options.bounds_check)
+ {
+ index_type ret_extent, arg_extent;
+
+ if (GFC_DESCRIPTOR_RANK (a) == 1)
+ {
+ arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic: is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ else if (GFC_DESCRIPTOR_RANK (b) == 1)
+ {
+ arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic: is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ else
+ {
+ arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound;
+ ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic for dimension 1:"
+ " is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+
+ arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound;
+ ret_extent = retarray->dim[1].ubound + 1 - retarray->dim[1].lbound;
+ if (arg_extent != ret_extent)
+ runtime_error ("Incorrect extent in return array in"
+ " MATMUL intrinsic for dimension 2:"
+ " is %ld, should be %ld",
+ (long int) ret_extent, (long int) arg_extent);
+ }
+ }
abase = a->data;
a_kind = GFC_DESCRIPTOR_SIZE (a);
diff --git a/libgfortran/runtime/error.c b/libgfortran/runtime/error.c
index 8cd966fa23f..0b9c16705eb 100644
--- a/libgfortran/runtime/error.c
+++ b/libgfortran/runtime/error.c
@@ -285,6 +285,21 @@ runtime_error_at (const char *where, const char *message, ...)
iexport(runtime_error_at);
+void
+runtime_warning_at (const char *where, const char *message, ...)
+{
+ va_list ap;
+
+ st_printf ("%s\n", where);
+ st_printf ("Fortran runtime warning: ");
+ va_start (ap, message);
+ st_vprintf (message, ap);
+ va_end (ap);
+ st_printf ("\n");
+}
+iexport(runtime_warning_at);
+
+
/* void internal_error()-- These are this-can't-happen errors
* that indicate something deeply wrong. */
diff --git a/libgomp/ChangeLog b/libgomp/ChangeLog
index 2d7516b528c..ded506b0636 100644
--- a/libgomp/ChangeLog
+++ b/libgomp/ChangeLog
@@ -1,3 +1,16 @@
+2008-07-16 Jakub Jelinek <jakub@redhat.com>
+
+ * team.c (gomp_team_end): Free team immediately if it has
+ just one thread.
+
+2008-07-08 David Edelsohn <edelsohn@gnu.org>
+
+ * testsuite/libgomp.c++/c++.exp: Append multilib library path.
+ * testsuite/libgomp.fortran/fortran.exp: Same.
+ * testsuite/libgomp.c/c.exp: Same.
+ * testsuite/lib/libgomp.exp: Append AIX libgcc pthread multilib
+ directory to library path first.
+
2008-06-29 Krister Walfridsson <krister.walfridsson@gmail.com>
* env.c (parse_stacksize): Add cast to avoid warning.
diff --git a/libgomp/team.c b/libgomp/team.c
index 18b02e72f90..224236c6604 100644
--- a/libgomp/team.c
+++ b/libgomp/team.c
@@ -498,7 +498,8 @@ gomp_team_end (void)
gomp_mutex_destroy (&team->work_share_list_free_lock);
#endif
- if (__builtin_expect (thr->ts.team != NULL, 0))
+ if (__builtin_expect (thr->ts.team != NULL, 0)
+ || __builtin_expect (team->nthreads == 1, 0))
free_team (team);
else
{
diff --git a/libgomp/testsuite/lib/libgomp.exp b/libgomp/testsuite/lib/libgomp.exp
index 274ee17f0a7..9aa891f202d 100644
--- a/libgomp/testsuite/lib/libgomp.exp
+++ b/libgomp/testsuite/lib/libgomp.exp
@@ -96,6 +96,10 @@ proc libgomp_init { args } {
# Compute what needs to be added to the existing LD_LIBRARY_PATH.
if {$gccdir != ""} {
+ # Add AIX pthread directory first.
+ if { [llength [glob -nocomplain ${gccdir}/pthread/libgcc_s*.a]] >= 1 } {
+ append always_ld_library_path ":${gccdir}/pthread"
+ }
append always_ld_library_path ":${gccdir}"
set compiler [lindex $GCC_UNDER_TEST 0]
diff --git a/libgomp/testsuite/libgomp.c++/c++.exp b/libgomp/testsuite/libgomp.c++/c++.exp
index f3f42de6619..d9872cc1ef3 100644
--- a/libgomp/testsuite/libgomp.c++/c++.exp
+++ b/libgomp/testsuite/libgomp.c++/c++.exp
@@ -29,6 +29,7 @@ if { $lang_test_file_found } {
set tests [lsort [glob -nocomplain $srcdir/$subdir/*.C]]
set ld_library_path "$always_ld_library_path:${blddir}/${lang_library_path}"
+ append ld_library_path [gcc-set-multilib-library-path $GCC_UNDER_TEST]
set_ld_library_path_env_vars
set flags_file "${blddir}/../libstdc++-v3/scripts/testsuite_flags"
diff --git a/libgomp/testsuite/libgomp.c/c.exp b/libgomp/testsuite/libgomp.c/c.exp
index 9eaab6252c3..4085d0c07e0 100644
--- a/libgomp/testsuite/libgomp.c/c.exp
+++ b/libgomp/testsuite/libgomp.c/c.exp
@@ -18,6 +18,7 @@ dg-init
set tests [lsort [find $srcdir/$subdir *.c]]
set ld_library_path $always_ld_library_path
+append ld_library_path [gcc-set-multilib-library-path $GCC_UNDER_TEST]
set_ld_library_path_env_vars
# Main loop.
diff --git a/libgomp/testsuite/libgomp.fortran/fortran.exp b/libgomp/testsuite/libgomp.fortran/fortran.exp
index b7d6b1072e7..293ccbc6531 100644
--- a/libgomp/testsuite/libgomp.fortran/fortran.exp
+++ b/libgomp/testsuite/libgomp.fortran/fortran.exp
@@ -13,6 +13,7 @@ if [file exists "${blddir}/${lang_test_file}"] {
set tests [lsort [find $srcdir/$subdir *.\[fF\]{,90,95,03,08}]]
set ld_library_path "$always_ld_library_path:${blddir}/${lang_library_path}"
+ append ld_library_path [gcc-set-multilib-library-path $GCC_UNDER_TEST]
set_ld_library_path_env_vars
# Main loop.
diff --git a/libiberty/ChangeLog b/libiberty/ChangeLog
index b77e66df94c..bf52f9eb491 100644
--- a/libiberty/ChangeLog
+++ b/libiberty/ChangeLog
@@ -1,3 +1,10 @@
+2008-07-24 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
+
+ * maint-tool (deps): Output config.h instead of stamp-h.
+ * Makefile.in: Rebuild deps.
+ (maintainer-clean-subdir): Depend on stamp-h rather than config.h.
+ Reverts 2007-07-11 change.
+
2008-06-19 Eric Blake <ebb9@byu.net>
Adjust strsignal to POSIX 200x prototype.
diff --git a/libiberty/Makefile.in b/libiberty/Makefile.in
index 40a1d47718b..e18aff75363 100644
--- a/libiberty/Makefile.in
+++ b/libiberty/Makefile.in
@@ -475,13 +475,13 @@ stamp-h: $(srcdir)/config.in config.status Makefile
config.status: $(srcdir)/configure
$(SHELL) ./config.status --recheck
-# Depending on stamp-h makes sure that config.status has been re-run
+# Depending on config.h makes sure that config.status has been re-run
# if needed. This prevents problems with parallel builds, in case
# subdirectories need to run config.status also.
all-subdir check-subdir installcheck-subdir info-subdir \
install-info-subdir clean-info-subdir dvi-subdir pdf-subdir install-subdir \
etags-subdir mostlyclean-subdir clean-subdir distclean-subdir \
-maintainer-clean-subdir: stamp-h
+maintainer-clean-subdir: config.h
@subdirs='$(SUBDIRS)'; \
target=`echo $@ | sed -e 's/-subdir//'`; \
for dir in $$subdirs ; do \
@@ -498,40 +498,41 @@ $(CONFIGURED_OFILES): stamp-picdir
# The dependencies in the remainder of this file are automatically
# generated by "make maint-deps". Manual edits will be lost.
-./_doprnt.o: $(srcdir)/_doprnt.c stamp-h $(INCDIR)/ansidecl.h \
+./_doprnt.o: $(srcdir)/_doprnt.c config.h $(INCDIR)/ansidecl.h \
$(INCDIR)/safe-ctype.h
if [ x"$(PICFLAG)" != x ]; then \
$(COMPILE.c) $(PICFLAG) $(srcdir)/_doprnt.c -o pic/$@; \
else true; fi
$(COMPILE.c) $(srcdir)/_doprnt.c $(OUTPUT_OPTION)
-./alloca.o: $(srcdir)/alloca.c stamp-h $(INCDIR)/ansidecl.h $(INCDIR)/libiberty.h
+./alloca.o: $(srcdir)/alloca.c config.h $(INCDIR)/ansidecl.h \
+ $(INCDIR)/libiberty.h
if [ x"$(PICFLAG)" != x ]; then \
$(COMPILE.c) $(PICFLAG) $(srcdir)/alloca.c -o pic/$@; \
else true; fi
$(COMPILE.c) $(srcdir)/alloca.c $(OUTPUT_OPTION)
-./argv.o: $(srcdir)/argv.c stamp-h $(INCDIR)/ansidecl.h $(INCDIR)/libiberty.h \
+./argv.o: $(srcdir)/argv.c config.h $(INCDIR)/ansidecl.h $(INCDIR)/libiberty.h \
$(INCDIR)/safe-ctype.h
if [ x"$(PICFLAG)" != x ]; then \
$(COMPILE.c) $(PICFLAG) $(srcdir)/argv.c -o pic/$@; \
else true; fi
$(COMPILE.c) $(srcdir)/argv.c $(OUTPUT_OPTION)
-./asprintf.o: $(srcdir)/asprintf.c stamp-h $(INCDIR)/ansidecl.h \
+./asprintf.o: $(srcdir)/asprintf.c config.h $(INCDIR)/ansidecl.h \
$(INCDIR)/libiberty.h
if [ x"$(PICFLAG)" != x ]; then \
$(COMPILE.c) $(PICFLAG) $(srcdir)/asprintf.c -o pic/$@; \
else true; fi
$(COMPILE.c) $(srcdir)/asprintf.c $(OUTPUT_OPTION)
-./atexit.o: $(srcdir)/atexit.c stamp-h
+./atexit.o: $(srcdir)/atexit.c config.h
if [ x"$(PICFLAG)" != x ]; then \
$(COMPILE.c) $(PICFLAG) $(srcdir)/atexit.c -o pic/$@; \
else true; fi
$(COMPILE.c) $(srcdir)/atexit.c $(OUTPUT_OPTION)
-./basename.o: $(srcdir)/basename.c stamp-h $(INCDIR)/ansidecl.h \
+./basename.o: $(srcdir)/basename.c config.h $(INCDIR)/ansidecl.h \
$(INCDIR)/libiberty.h $(INCDIR)/safe-ctype.h
if [ x"$(PICFLAG)" != x ]; then \
$(COMPILE.c) $(PICFLAG) $(srcdir)/basename.c -o pic/$@; \
@@ -550,7 +551,7 @@ $(CONFIGURED_OFILES): stamp-picdir
else true; fi
$(COMPILE.c) $(srcdir)/bcopy.c $(OUTPUT_OPTION)
-./bsearch.o: $(srcdir)/bsearch.c stamp-h $(INCDIR)/ansidecl.h
+./bsearch.o: $(srcdir)/bsearch.c config.h $(INCDIR)/ansidecl.h
if [ x"$(PICFLAG)" != x ]; then \
$(COMPILE.c) $(PICFLAG) $(srcdir)/bsearch.c -o pic/$@; \
else true; fi
@@ -568,20 +569,21 @@ $(CONFIGURED_OFILES): stamp-picdir
else true; fi
$(COMPILE.c) $(srcdir)/calloc.c $(OUTPUT_OPTION)
-./choose-temp.o: $(srcdir)/choose-temp.c stamp-h $(INCDIR)/ansidecl.h \
+./choose-temp.o: $(srcdir)/choose-temp.c config.h $(INCDIR)/ansidecl.h \
$(INCDIR)/libiberty.h
if [ x"$(PICFLAG)" != x ]; then \
$(COMPILE.c) $(PICFLAG) $(srcdir)/choose-temp.c -o pic/$@; \
else true; fi
$(COMPILE.c) $(srcdir)/choose-temp.c $(OUTPUT_OPTION)
-./clock.o: $(srcdir)/clock.c stamp-h
+./clock.o: $(srcdir)/clock.c config.h
if [ x"$(PICFLAG)" != x ]; then \
$(COMPILE.c) $(PICFLAG) $(srcdir)/clock.c -o pic/$@; \
else true; fi
$(COMPILE.c) $(srcdir)/clock.c $(OUTPUT_OPTION)
-./concat.o: $(srcdir)/concat.c stamp-h $(INCDIR)/ansidecl.h $(INCDIR)/libiberty.h
+./concat.o: $(srcdir)/concat.c config.h $(INCDIR)/ansidecl.h \
+ $(INCDIR)/libiberty.h
if [ x"$(PICFLAG)" != x ]; then \
$(COMPILE.c) $(PICFLAG) $(srcdir)/concat.c -o pic/$@; \
else true; fi
@@ -593,7 +595,7 @@ $(CONFIGURED_OFILES): stamp-picdir
else true; fi
$(COMPILE.c) $(srcdir)/copysign.c $(OUTPUT_OPTION)
-./cp-demangle.o: $(srcdir)/cp-demangle.c stamp-h $(INCDIR)/ansidecl.h \
+./cp-demangle.o: $(srcdir)/cp-demangle.c config.h $(INCDIR)/ansidecl.h \
$(srcdir)/cp-demangle.h $(INCDIR)/demangle.h \
$(INCDIR)/dyn-string.h $(INCDIR)/getopt.h $(INCDIR)/libiberty.h
if [ x"$(PICFLAG)" != x ]; then \
@@ -601,7 +603,7 @@ $(CONFIGURED_OFILES): stamp-picdir
else true; fi
$(COMPILE.c) $(srcdir)/cp-demangle.c $(OUTPUT_OPTION)
-./cp-demint.o: $(srcdir)/cp-demint.c stamp-h $(INCDIR)/ansidecl.h \
+./cp-demint.o: $(srcdir)/cp-demint.c config.h $(INCDIR)/ansidecl.h \
$(srcdir)/cp-demangle.h $(INCDIR)/demangle.h \
$(INCDIR)/libiberty.h
if [ x"$(PICFLAG)" != x ]; then \
@@ -609,7 +611,7 @@ $(CONFIGURED_OFILES): stamp-picdir
else true; fi
$(COMPILE.c) $(srcdir)/cp-demint.c $(OUTPUT_OPTION)
-./cplus-dem.o: $(srcdir)/cplus-dem.c stamp-h $(INCDIR)/ansidecl.h \
+./cplus-dem.o: $(srcdir)/cplus-dem.c config.h $(INCDIR)/ansidecl.h \
$(INCDIR)/demangle.h $(INCDIR)/libiberty.h \
$(INCDIR)/safe-ctype.h
if [ x"$(PICFLAG)" != x ]; then \
@@ -617,14 +619,14 @@ $(CONFIGURED_OFILES): stamp-picdir
else true; fi
$(COMPILE.c) $(srcdir)/cplus-dem.c $(OUTPUT_OPTION)
-./dyn-string.o: $(srcdir)/dyn-string.c stamp-h $(INCDIR)/ansidecl.h \
+./dyn-string.o: $(srcdir)/dyn-string.c config.h $(INCDIR)/ansidecl.h \
$(INCDIR)/dyn-string.h $(INCDIR)/libiberty.h
if [ x"$(PICFLAG)" != x ]; then \
$(COMPILE.c) $(PICFLAG) $(srcdir)/dyn-string.c -o pic/$@; \
else true; fi
$(COMPILE.c) $(srcdir)/dyn-string.c $(OUTPUT_OPTION)
-./fdmatch.o: $(srcdir)/fdmatch.c stamp-h $(INCDIR)/ansidecl.h \
+./fdmatch.o: $(srcdir)/fdmatch.c config.h $(INCDIR)/ansidecl.h \
$(INCDIR)/libiberty.h
if [ x"$(PICFLAG)" != x ]; then \
$(COMPILE.c) $(PICFLAG) $(srcdir)/fdmatch.c -o pic/$@; \
@@ -637,93 +639,94 @@ $(CONFIGURED_OFILES): stamp-picdir
else true; fi
$(COMPILE.c) $(srcdir)/ffs.c $(OUTPUT_OPTION)
-./fibheap.o: $(srcdir)/fibheap.c stamp-h $(INCDIR)/ansidecl.h $(INCDIR)/fibheap.h \
- $(INCDIR)/libiberty.h
+./fibheap.o: $(srcdir)/fibheap.c config.h $(INCDIR)/ansidecl.h \
+ $(INCDIR)/fibheap.h $(INCDIR)/libiberty.h
if [ x"$(PICFLAG)" != x ]; then \
$(COMPILE.c) $(PICFLAG) $(srcdir)/fibheap.c -o pic/$@; \
else true; fi
$(COMPILE.c) $(srcdir)/fibheap.c $(OUTPUT_OPTION)
-./filename_cmp.o: $(srcdir)/filename_cmp.c stamp-h $(INCDIR)/filenames.h \
+./filename_cmp.o: $(srcdir)/filename_cmp.c config.h $(INCDIR)/filenames.h \
$(INCDIR)/safe-ctype.h
if [ x"$(PICFLAG)" != x ]; then \
$(COMPILE.c) $(PICFLAG) $(srcdir)/filename_cmp.c -o pic/$@; \
else true; fi
$(COMPILE.c) $(srcdir)/filename_cmp.c $(OUTPUT_OPTION)
-./floatformat.o: $(srcdir)/floatformat.c stamp-h $(INCDIR)/ansidecl.h \
+./floatformat.o: $(srcdir)/floatformat.c config.h $(INCDIR)/ansidecl.h \
$(INCDIR)/floatformat.h $(INCDIR)/libiberty.h
if [ x"$(PICFLAG)" != x ]; then \
$(COMPILE.c) $(PICFLAG) $(srcdir)/floatformat.c -o pic/$@; \
else true; fi
$(COMPILE.c) $(srcdir)/floatformat.c $(OUTPUT_OPTION)
-./fnmatch.o: $(srcdir)/fnmatch.c stamp-h $(INCDIR)/fnmatch.h \
+./fnmatch.o: $(srcdir)/fnmatch.c config.h $(INCDIR)/fnmatch.h \
$(INCDIR)/safe-ctype.h
if [ x"$(PICFLAG)" != x ]; then \
$(COMPILE.c) $(PICFLAG) $(srcdir)/fnmatch.c -o pic/$@; \
else true; fi
$(COMPILE.c) $(srcdir)/fnmatch.c $(OUTPUT_OPTION)
-./fopen_unlocked.o: $(srcdir)/fopen_unlocked.c stamp-h $(INCDIR)/ansidecl.h \
+./fopen_unlocked.o: $(srcdir)/fopen_unlocked.c config.h $(INCDIR)/ansidecl.h \
$(INCDIR)/libiberty.h
if [ x"$(PICFLAG)" != x ]; then \
$(COMPILE.c) $(PICFLAG) $(srcdir)/fopen_unlocked.c -o pic/$@; \
else true; fi
$(COMPILE.c) $(srcdir)/fopen_unlocked.c $(OUTPUT_OPTION)
-./getcwd.o: $(srcdir)/getcwd.c stamp-h
+./getcwd.o: $(srcdir)/getcwd.c config.h
if [ x"$(PICFLAG)" != x ]; then \
$(COMPILE.c) $(PICFLAG) $(srcdir)/getcwd.c -o pic/$@; \
else true; fi
$(COMPILE.c) $(srcdir)/getcwd.c $(OUTPUT_OPTION)
-./getopt.o: $(srcdir)/getopt.c stamp-h $(INCDIR)/ansidecl.h $(INCDIR)/getopt.h
+./getopt.o: $(srcdir)/getopt.c config.h $(INCDIR)/ansidecl.h $(INCDIR)/getopt.h
if [ x"$(PICFLAG)" != x ]; then \
$(COMPILE.c) $(PICFLAG) $(srcdir)/getopt.c -o pic/$@; \
else true; fi
$(COMPILE.c) $(srcdir)/getopt.c $(OUTPUT_OPTION)
-./getopt1.o: $(srcdir)/getopt1.c stamp-h $(INCDIR)/getopt.h
+./getopt1.o: $(srcdir)/getopt1.c config.h $(INCDIR)/getopt.h
if [ x"$(PICFLAG)" != x ]; then \
$(COMPILE.c) $(PICFLAG) $(srcdir)/getopt1.c -o pic/$@; \
else true; fi
$(COMPILE.c) $(srcdir)/getopt1.c $(OUTPUT_OPTION)
-./getpagesize.o: $(srcdir)/getpagesize.c stamp-h
+./getpagesize.o: $(srcdir)/getpagesize.c config.h
if [ x"$(PICFLAG)" != x ]; then \
$(COMPILE.c) $(PICFLAG) $(srcdir)/getpagesize.c -o pic/$@; \
else true; fi
$(COMPILE.c) $(srcdir)/getpagesize.c $(OUTPUT_OPTION)
-./getpwd.o: $(srcdir)/getpwd.c stamp-h $(INCDIR)/ansidecl.h $(INCDIR)/libiberty.h
+./getpwd.o: $(srcdir)/getpwd.c config.h $(INCDIR)/ansidecl.h \
+ $(INCDIR)/libiberty.h
if [ x"$(PICFLAG)" != x ]; then \
$(COMPILE.c) $(PICFLAG) $(srcdir)/getpwd.c -o pic/$@; \
else true; fi
$(COMPILE.c) $(srcdir)/getpwd.c $(OUTPUT_OPTION)
-./getruntime.o: $(srcdir)/getruntime.c stamp-h $(INCDIR)/ansidecl.h \
+./getruntime.o: $(srcdir)/getruntime.c config.h $(INCDIR)/ansidecl.h \
$(INCDIR)/libiberty.h
if [ x"$(PICFLAG)" != x ]; then \
$(COMPILE.c) $(PICFLAG) $(srcdir)/getruntime.c -o pic/$@; \
else true; fi
$(COMPILE.c) $(srcdir)/getruntime.c $(OUTPUT_OPTION)
-./gettimeofday.o: $(srcdir)/gettimeofday.c stamp-h $(INCDIR)/ansidecl.h \
+./gettimeofday.o: $(srcdir)/gettimeofday.c config.h $(INCDIR)/ansidecl.h \
$(INCDIR)/libiberty.h
if [ x"$(PICFLAG)" != x ]; then \
$(COMPILE.c) $(PICFLAG) $(srcdir)/gettimeofday.c -o pic/$@; \
else true; fi
$(COMPILE.c) $(srcdir)/gettimeofday.c $(OUTPUT_OPTION)
-./hashtab.o: $(srcdir)/hashtab.c stamp-h $(INCDIR)/ansidecl.h $(INCDIR)/hashtab.h \
- $(INCDIR)/libiberty.h
+./hashtab.o: $(srcdir)/hashtab.c config.h $(INCDIR)/ansidecl.h \
+ $(INCDIR)/hashtab.h $(INCDIR)/libiberty.h
if [ x"$(PICFLAG)" != x ]; then \
$(COMPILE.c) $(PICFLAG) $(srcdir)/hashtab.c -o pic/$@; \
else true; fi
$(COMPILE.c) $(srcdir)/hashtab.c $(OUTPUT_OPTION)
-./hex.o: $(srcdir)/hex.c stamp-h $(INCDIR)/ansidecl.h $(INCDIR)/libiberty.h \
+./hex.o: $(srcdir)/hex.c config.h $(INCDIR)/ansidecl.h $(INCDIR)/libiberty.h \
$(INCDIR)/safe-ctype.h
if [ x"$(PICFLAG)" != x ]; then \
$(COMPILE.c) $(PICFLAG) $(srcdir)/hex.c -o pic/$@; \
@@ -742,7 +745,7 @@ $(CONFIGURED_OFILES): stamp-picdir
else true; fi
$(COMPILE.c) $(srcdir)/insque.c $(OUTPUT_OPTION)
-./lbasename.o: $(srcdir)/lbasename.c stamp-h $(INCDIR)/ansidecl.h \
+./lbasename.o: $(srcdir)/lbasename.c config.h $(INCDIR)/ansidecl.h \
$(INCDIR)/filenames.h $(INCDIR)/libiberty.h \
$(INCDIR)/safe-ctype.h
if [ x"$(PICFLAG)" != x ]; then \
@@ -750,28 +753,28 @@ $(CONFIGURED_OFILES): stamp-picdir
else true; fi
$(COMPILE.c) $(srcdir)/lbasename.c $(OUTPUT_OPTION)
-./lrealpath.o: $(srcdir)/lrealpath.c stamp-h $(INCDIR)/ansidecl.h \
+./lrealpath.o: $(srcdir)/lrealpath.c config.h $(INCDIR)/ansidecl.h \
$(INCDIR)/libiberty.h
if [ x"$(PICFLAG)" != x ]; then \
$(COMPILE.c) $(PICFLAG) $(srcdir)/lrealpath.c -o pic/$@; \
else true; fi
$(COMPILE.c) $(srcdir)/lrealpath.c $(OUTPUT_OPTION)
-./make-relative-prefix.o: $(srcdir)/make-relative-prefix.c stamp-h \
+./make-relative-prefix.o: $(srcdir)/make-relative-prefix.c config.h \
$(INCDIR)/ansidecl.h $(INCDIR)/libiberty.h
if [ x"$(PICFLAG)" != x ]; then \
$(COMPILE.c) $(PICFLAG) $(srcdir)/make-relative-prefix.c -o pic/$@; \
else true; fi
$(COMPILE.c) $(srcdir)/make-relative-prefix.c $(OUTPUT_OPTION)
-./make-temp-file.o: $(srcdir)/make-temp-file.c stamp-h $(INCDIR)/ansidecl.h \
+./make-temp-file.o: $(srcdir)/make-temp-file.c config.h $(INCDIR)/ansidecl.h \
$(INCDIR)/libiberty.h
if [ x"$(PICFLAG)" != x ]; then \
$(COMPILE.c) $(PICFLAG) $(srcdir)/make-temp-file.c -o pic/$@; \
else true; fi
$(COMPILE.c) $(srcdir)/make-temp-file.c $(OUTPUT_OPTION)
-./md5.o: $(srcdir)/md5.c stamp-h $(INCDIR)/ansidecl.h $(INCDIR)/md5.h
+./md5.o: $(srcdir)/md5.c config.h $(INCDIR)/ansidecl.h $(INCDIR)/md5.h
if [ x"$(PICFLAG)" != x ]; then \
$(COMPILE.c) $(PICFLAG) $(srcdir)/md5.c -o pic/$@; \
else true; fi
@@ -813,7 +816,7 @@ $(CONFIGURED_OFILES): stamp-picdir
else true; fi
$(COMPILE.c) $(srcdir)/memset.c $(OUTPUT_OPTION)
-./mkstemps.o: $(srcdir)/mkstemps.c stamp-h $(INCDIR)/ansidecl.h
+./mkstemps.o: $(srcdir)/mkstemps.c config.h $(INCDIR)/ansidecl.h
if [ x"$(PICFLAG)" != x ]; then \
$(COMPILE.c) $(PICFLAG) $(srcdir)/mkstemps.c -o pic/$@; \
else true; fi
@@ -825,41 +828,41 @@ $(CONFIGURED_OFILES): stamp-picdir
else true; fi
$(COMPILE.c) $(srcdir)/msdos.c $(OUTPUT_OPTION)
-./objalloc.o: $(srcdir)/objalloc.c stamp-h $(INCDIR)/ansidecl.h \
+./objalloc.o: $(srcdir)/objalloc.c config.h $(INCDIR)/ansidecl.h \
$(INCDIR)/objalloc.h
if [ x"$(PICFLAG)" != x ]; then \
$(COMPILE.c) $(PICFLAG) $(srcdir)/objalloc.c -o pic/$@; \
else true; fi
$(COMPILE.c) $(srcdir)/objalloc.c $(OUTPUT_OPTION)
-./obstack.o: $(srcdir)/obstack.c stamp-h $(INCDIR)/obstack.h
+./obstack.o: $(srcdir)/obstack.c config.h $(INCDIR)/obstack.h
if [ x"$(PICFLAG)" != x ]; then \
$(COMPILE.c) $(PICFLAG) $(srcdir)/obstack.c -o pic/$@; \
else true; fi
$(COMPILE.c) $(srcdir)/obstack.c $(OUTPUT_OPTION)
-./partition.o: $(srcdir)/partition.c stamp-h $(INCDIR)/ansidecl.h \
+./partition.o: $(srcdir)/partition.c config.h $(INCDIR)/ansidecl.h \
$(INCDIR)/libiberty.h $(INCDIR)/partition.h
if [ x"$(PICFLAG)" != x ]; then \
$(COMPILE.c) $(PICFLAG) $(srcdir)/partition.c -o pic/$@; \
else true; fi
$(COMPILE.c) $(srcdir)/partition.c $(OUTPUT_OPTION)
-./pex-common.o: $(srcdir)/pex-common.c stamp-h $(INCDIR)/ansidecl.h \
+./pex-common.o: $(srcdir)/pex-common.c config.h $(INCDIR)/ansidecl.h \
$(INCDIR)/libiberty.h $(srcdir)/pex-common.h
if [ x"$(PICFLAG)" != x ]; then \
$(COMPILE.c) $(PICFLAG) $(srcdir)/pex-common.c -o pic/$@; \
else true; fi
$(COMPILE.c) $(srcdir)/pex-common.c $(OUTPUT_OPTION)
-./pex-djgpp.o: $(srcdir)/pex-djgpp.c stamp-h $(INCDIR)/ansidecl.h \
+./pex-djgpp.o: $(srcdir)/pex-djgpp.c config.h $(INCDIR)/ansidecl.h \
$(INCDIR)/libiberty.h $(srcdir)/pex-common.h
if [ x"$(PICFLAG)" != x ]; then \
$(COMPILE.c) $(PICFLAG) $(srcdir)/pex-djgpp.c -o pic/$@; \
else true; fi
$(COMPILE.c) $(srcdir)/pex-djgpp.c $(OUTPUT_OPTION)
-./pex-msdos.o: $(srcdir)/pex-msdos.c stamp-h $(INCDIR)/ansidecl.h \
+./pex-msdos.o: $(srcdir)/pex-msdos.c config.h $(INCDIR)/ansidecl.h \
$(INCDIR)/libiberty.h $(srcdir)/pex-common.h \
$(INCDIR)/safe-ctype.h
if [ x"$(PICFLAG)" != x ]; then \
@@ -867,42 +870,42 @@ $(CONFIGURED_OFILES): stamp-picdir
else true; fi
$(COMPILE.c) $(srcdir)/pex-msdos.c $(OUTPUT_OPTION)
-./pex-one.o: $(srcdir)/pex-one.c stamp-h $(INCDIR)/ansidecl.h \
+./pex-one.o: $(srcdir)/pex-one.c config.h $(INCDIR)/ansidecl.h \
$(INCDIR)/libiberty.h
if [ x"$(PICFLAG)" != x ]; then \
$(COMPILE.c) $(PICFLAG) $(srcdir)/pex-one.c -o pic/$@; \
else true; fi
$(COMPILE.c) $(srcdir)/pex-one.c $(OUTPUT_OPTION)
-./pex-unix.o: $(srcdir)/pex-unix.c stamp-h $(INCDIR)/ansidecl.h \
+./pex-unix.o: $(srcdir)/pex-unix.c config.h $(INCDIR)/ansidecl.h \
$(INCDIR)/libiberty.h $(srcdir)/pex-common.h
if [ x"$(PICFLAG)" != x ]; then \
$(COMPILE.c) $(PICFLAG) $(srcdir)/pex-unix.c -o pic/$@; \
else true; fi
$(COMPILE.c) $(srcdir)/pex-unix.c $(OUTPUT_OPTION)
-./pex-win32.o: $(srcdir)/pex-win32.c stamp-h $(INCDIR)/ansidecl.h \
+./pex-win32.o: $(srcdir)/pex-win32.c config.h $(INCDIR)/ansidecl.h \
$(INCDIR)/libiberty.h $(srcdir)/pex-common.h
if [ x"$(PICFLAG)" != x ]; then \
$(COMPILE.c) $(PICFLAG) $(srcdir)/pex-win32.c -o pic/$@; \
else true; fi
$(COMPILE.c) $(srcdir)/pex-win32.c $(OUTPUT_OPTION)
-./pexecute.o: $(srcdir)/pexecute.c stamp-h $(INCDIR)/ansidecl.h \
+./pexecute.o: $(srcdir)/pexecute.c config.h $(INCDIR)/ansidecl.h \
$(INCDIR)/libiberty.h
if [ x"$(PICFLAG)" != x ]; then \
$(COMPILE.c) $(PICFLAG) $(srcdir)/pexecute.c -o pic/$@; \
else true; fi
$(COMPILE.c) $(srcdir)/pexecute.c $(OUTPUT_OPTION)
-./physmem.o: $(srcdir)/physmem.c stamp-h $(INCDIR)/ansidecl.h \
+./physmem.o: $(srcdir)/physmem.c config.h $(INCDIR)/ansidecl.h \
$(INCDIR)/libiberty.h
if [ x"$(PICFLAG)" != x ]; then \
$(COMPILE.c) $(PICFLAG) $(srcdir)/physmem.c -o pic/$@; \
else true; fi
$(COMPILE.c) $(srcdir)/physmem.c $(OUTPUT_OPTION)
-./putenv.o: $(srcdir)/putenv.c stamp-h $(INCDIR)/ansidecl.h
+./putenv.o: $(srcdir)/putenv.c config.h $(INCDIR)/ansidecl.h
if [ x"$(PICFLAG)" != x ]; then \
$(COMPILE.c) $(PICFLAG) $(srcdir)/putenv.c -o pic/$@; \
else true; fi
@@ -914,14 +917,14 @@ $(CONFIGURED_OFILES): stamp-picdir
else true; fi
$(COMPILE.c) $(srcdir)/random.c $(OUTPUT_OPTION)
-./regex.o: $(srcdir)/regex.c stamp-h $(INCDIR)/ansidecl.h $(INCDIR)/xregex.h \
+./regex.o: $(srcdir)/regex.c config.h $(INCDIR)/ansidecl.h $(INCDIR)/xregex.h \
$(INCDIR)/xregex2.h
if [ x"$(PICFLAG)" != x ]; then \
$(COMPILE.c) $(PICFLAG) $(srcdir)/regex.c -o pic/$@; \
else true; fi
$(COMPILE.c) $(srcdir)/regex.c $(OUTPUT_OPTION)
-./rename.o: $(srcdir)/rename.c stamp-h $(INCDIR)/ansidecl.h
+./rename.o: $(srcdir)/rename.c config.h $(INCDIR)/ansidecl.h
if [ x"$(PICFLAG)" != x ]; then \
$(COMPILE.c) $(PICFLAG) $(srcdir)/rename.c -o pic/$@; \
else true; fi
@@ -940,13 +943,13 @@ $(CONFIGURED_OFILES): stamp-picdir
else true; fi
$(COMPILE.c) $(srcdir)/safe-ctype.c $(OUTPUT_OPTION)
-./setenv.o: $(srcdir)/setenv.c stamp-h $(INCDIR)/ansidecl.h
+./setenv.o: $(srcdir)/setenv.c config.h $(INCDIR)/ansidecl.h
if [ x"$(PICFLAG)" != x ]; then \
$(COMPILE.c) $(PICFLAG) $(srcdir)/setenv.c -o pic/$@; \
else true; fi
$(COMPILE.c) $(srcdir)/setenv.c $(OUTPUT_OPTION)
-./sha1.o: $(srcdir)/sha1.c stamp-h $(INCDIR)/sha1.h
+./sha1.o: $(srcdir)/sha1.c config.h $(INCDIR)/ansidecl.h $(INCDIR)/sha1.h
if [ x"$(PICFLAG)" != x ]; then \
$(COMPILE.c) $(PICFLAG) $(srcdir)/sha1.c -o pic/$@; \
else true; fi
@@ -964,20 +967,21 @@ $(CONFIGURED_OFILES): stamp-picdir
else true; fi
$(COMPILE.c) $(srcdir)/snprintf.c $(OUTPUT_OPTION)
-./sort.o: $(srcdir)/sort.c stamp-h $(INCDIR)/ansidecl.h $(INCDIR)/libiberty.h \
+./sort.o: $(srcdir)/sort.c config.h $(INCDIR)/ansidecl.h $(INCDIR)/libiberty.h \
$(INCDIR)/sort.h
if [ x"$(PICFLAG)" != x ]; then \
$(COMPILE.c) $(PICFLAG) $(srcdir)/sort.c -o pic/$@; \
else true; fi
$(COMPILE.c) $(srcdir)/sort.c $(OUTPUT_OPTION)
-./spaces.o: $(srcdir)/spaces.c stamp-h $(INCDIR)/ansidecl.h $(INCDIR)/libiberty.h
+./spaces.o: $(srcdir)/spaces.c config.h $(INCDIR)/ansidecl.h \
+ $(INCDIR)/libiberty.h
if [ x"$(PICFLAG)" != x ]; then \
$(COMPILE.c) $(PICFLAG) $(srcdir)/spaces.c -o pic/$@; \
else true; fi
$(COMPILE.c) $(srcdir)/spaces.c $(OUTPUT_OPTION)
-./splay-tree.o: $(srcdir)/splay-tree.c stamp-h $(INCDIR)/ansidecl.h \
+./splay-tree.o: $(srcdir)/splay-tree.c config.h $(INCDIR)/ansidecl.h \
$(INCDIR)/libiberty.h $(INCDIR)/splay-tree.h
if [ x"$(PICFLAG)" != x ]; then \
$(COMPILE.c) $(PICFLAG) $(srcdir)/splay-tree.c -o pic/$@; \
@@ -1014,7 +1018,7 @@ $(CONFIGURED_OFILES): stamp-picdir
else true; fi
$(COMPILE.c) $(srcdir)/strdup.c $(OUTPUT_OPTION)
-./strerror.o: $(srcdir)/strerror.c stamp-h $(INCDIR)/ansidecl.h \
+./strerror.o: $(srcdir)/strerror.c config.h $(INCDIR)/ansidecl.h \
$(INCDIR)/libiberty.h
if [ x"$(PICFLAG)" != x ]; then \
$(COMPILE.c) $(PICFLAG) $(srcdir)/strerror.c -o pic/$@; \
@@ -1045,7 +1049,7 @@ $(CONFIGURED_OFILES): stamp-picdir
else true; fi
$(COMPILE.c) $(srcdir)/strrchr.c $(OUTPUT_OPTION)
-./strsignal.o: $(srcdir)/strsignal.c stamp-h $(INCDIR)/ansidecl.h \
+./strsignal.o: $(srcdir)/strsignal.c config.h $(INCDIR)/ansidecl.h \
$(INCDIR)/libiberty.h
if [ x"$(PICFLAG)" != x ]; then \
$(COMPILE.c) $(PICFLAG) $(srcdir)/strsignal.c -o pic/$@; \
@@ -1064,13 +1068,13 @@ $(CONFIGURED_OFILES): stamp-picdir
else true; fi
$(COMPILE.c) $(srcdir)/strtod.c $(OUTPUT_OPTION)
-./strtol.o: $(srcdir)/strtol.c stamp-h $(INCDIR)/safe-ctype.h
+./strtol.o: $(srcdir)/strtol.c config.h $(INCDIR)/safe-ctype.h
if [ x"$(PICFLAG)" != x ]; then \
$(COMPILE.c) $(PICFLAG) $(srcdir)/strtol.c -o pic/$@; \
else true; fi
$(COMPILE.c) $(srcdir)/strtol.c $(OUTPUT_OPTION)
-./strtoul.o: $(srcdir)/strtoul.c stamp-h $(INCDIR)/ansidecl.h \
+./strtoul.o: $(srcdir)/strtoul.c config.h $(INCDIR)/ansidecl.h \
$(INCDIR)/safe-ctype.h
if [ x"$(PICFLAG)" != x ]; then \
$(COMPILE.c) $(PICFLAG) $(srcdir)/strtoul.c -o pic/$@; \
@@ -1090,14 +1094,14 @@ $(CONFIGURED_OFILES): stamp-picdir
else true; fi
$(COMPILE.c) $(srcdir)/tmpnam.c $(OUTPUT_OPTION)
-./unlink-if-ordinary.o: $(srcdir)/unlink-if-ordinary.c stamp-h \
+./unlink-if-ordinary.o: $(srcdir)/unlink-if-ordinary.c config.h \
$(INCDIR)/ansidecl.h $(INCDIR)/libiberty.h
if [ x"$(PICFLAG)" != x ]; then \
$(COMPILE.c) $(PICFLAG) $(srcdir)/unlink-if-ordinary.c -o pic/$@; \
else true; fi
$(COMPILE.c) $(srcdir)/unlink-if-ordinary.c $(OUTPUT_OPTION)
-./vasprintf.o: $(srcdir)/vasprintf.c stamp-h $(INCDIR)/ansidecl.h \
+./vasprintf.o: $(srcdir)/vasprintf.c config.h $(INCDIR)/ansidecl.h \
$(INCDIR)/libiberty.h
if [ x"$(PICFLAG)" != x ]; then \
$(COMPILE.c) $(PICFLAG) $(srcdir)/vasprintf.c -o pic/$@; \
@@ -1122,7 +1126,7 @@ $(CONFIGURED_OFILES): stamp-picdir
else true; fi
$(COMPILE.c) $(srcdir)/vprintf.c $(OUTPUT_OPTION)
-./vsnprintf.o: $(srcdir)/vsnprintf.c stamp-h $(INCDIR)/ansidecl.h \
+./vsnprintf.o: $(srcdir)/vsnprintf.c config.h $(INCDIR)/ansidecl.h \
$(INCDIR)/libiberty.h
if [ x"$(PICFLAG)" != x ]; then \
$(COMPILE.c) $(PICFLAG) $(srcdir)/vsnprintf.c -o pic/$@; \
@@ -1135,54 +1139,54 @@ $(CONFIGURED_OFILES): stamp-picdir
else true; fi
$(COMPILE.c) $(srcdir)/vsprintf.c $(OUTPUT_OPTION)
-./waitpid.o: $(srcdir)/waitpid.c stamp-h $(INCDIR)/ansidecl.h
+./waitpid.o: $(srcdir)/waitpid.c config.h $(INCDIR)/ansidecl.h
if [ x"$(PICFLAG)" != x ]; then \
$(COMPILE.c) $(PICFLAG) $(srcdir)/waitpid.c -o pic/$@; \
else true; fi
$(COMPILE.c) $(srcdir)/waitpid.c $(OUTPUT_OPTION)
-./xatexit.o: $(srcdir)/xatexit.c stamp-h $(INCDIR)/ansidecl.h \
+./xatexit.o: $(srcdir)/xatexit.c config.h $(INCDIR)/ansidecl.h \
$(INCDIR)/libiberty.h
if [ x"$(PICFLAG)" != x ]; then \
$(COMPILE.c) $(PICFLAG) $(srcdir)/xatexit.c -o pic/$@; \
else true; fi
$(COMPILE.c) $(srcdir)/xatexit.c $(OUTPUT_OPTION)
-./xexit.o: $(srcdir)/xexit.c stamp-h $(INCDIR)/ansidecl.h $(INCDIR)/libiberty.h
+./xexit.o: $(srcdir)/xexit.c config.h $(INCDIR)/ansidecl.h $(INCDIR)/libiberty.h
if [ x"$(PICFLAG)" != x ]; then \
$(COMPILE.c) $(PICFLAG) $(srcdir)/xexit.c -o pic/$@; \
else true; fi
$(COMPILE.c) $(srcdir)/xexit.c $(OUTPUT_OPTION)
-./xmalloc.o: $(srcdir)/xmalloc.c stamp-h $(INCDIR)/ansidecl.h \
+./xmalloc.o: $(srcdir)/xmalloc.c config.h $(INCDIR)/ansidecl.h \
$(INCDIR)/libiberty.h
if [ x"$(PICFLAG)" != x ]; then \
$(COMPILE.c) $(PICFLAG) $(srcdir)/xmalloc.c -o pic/$@; \
else true; fi
$(COMPILE.c) $(srcdir)/xmalloc.c $(OUTPUT_OPTION)
-./xmemdup.o: $(srcdir)/xmemdup.c stamp-h $(INCDIR)/ansidecl.h \
+./xmemdup.o: $(srcdir)/xmemdup.c config.h $(INCDIR)/ansidecl.h \
$(INCDIR)/libiberty.h
if [ x"$(PICFLAG)" != x ]; then \
$(COMPILE.c) $(PICFLAG) $(srcdir)/xmemdup.c -o pic/$@; \
else true; fi
$(COMPILE.c) $(srcdir)/xmemdup.c $(OUTPUT_OPTION)
-./xstrdup.o: $(srcdir)/xstrdup.c stamp-h $(INCDIR)/ansidecl.h \
+./xstrdup.o: $(srcdir)/xstrdup.c config.h $(INCDIR)/ansidecl.h \
$(INCDIR)/libiberty.h
if [ x"$(PICFLAG)" != x ]; then \
$(COMPILE.c) $(PICFLAG) $(srcdir)/xstrdup.c -o pic/$@; \
else true; fi
$(COMPILE.c) $(srcdir)/xstrdup.c $(OUTPUT_OPTION)
-./xstrerror.o: $(srcdir)/xstrerror.c stamp-h $(INCDIR)/ansidecl.h \
+./xstrerror.o: $(srcdir)/xstrerror.c config.h $(INCDIR)/ansidecl.h \
$(INCDIR)/libiberty.h
if [ x"$(PICFLAG)" != x ]; then \
$(COMPILE.c) $(PICFLAG) $(srcdir)/xstrerror.c -o pic/$@; \
else true; fi
$(COMPILE.c) $(srcdir)/xstrerror.c $(OUTPUT_OPTION)
-./xstrndup.o: $(srcdir)/xstrndup.c stamp-h $(INCDIR)/ansidecl.h \
+./xstrndup.o: $(srcdir)/xstrndup.c config.h $(INCDIR)/ansidecl.h \
$(INCDIR)/libiberty.h
if [ x"$(PICFLAG)" != x ]; then \
$(COMPILE.c) $(PICFLAG) $(srcdir)/xstrndup.c -o pic/$@; \
diff --git a/libiberty/maint-tool b/libiberty/maint-tool
index a460b5570e5..e6e87070d37 100644
--- a/libiberty/maint-tool
+++ b/libiberty/maint-tool
@@ -226,6 +226,7 @@ sub deps {
$mine{$f} = "\$(INCDIR)/$f";
$deps{$f} = join(' ', &deps_for("$incdir/$f"));
}
+ $mine{'config.h'} = "config.h";
opendir(INC, $srcdir);
while ($f = readdir INC) {
@@ -233,8 +234,7 @@ sub deps {
$mine{$f} = "\$(srcdir)/$f";
$deps{$f} = join(' ', &deps_for("$srcdir/$f"));
}
-
- $mine{'config.h'} = "stamp-h";
+ $mine{'config.h'} = "config.h";
open(IN, "$srcdir/Makefile.in");
open(OUT, ">$srcdir/Makefile.tmp");
diff --git a/libjava/ChangeLog b/libjava/ChangeLog
index d0c1d068dbb..13649995233 100644
--- a/libjava/ChangeLog
+++ b/libjava/ChangeLog
@@ -1,3 +1,21 @@
+2008-07-16 Roger Sayle <roger@eyesopen.com>
+ Paolo Bonzini <bonzini@gnu.org>
+
+ * scripts/jar.in: Fix portability problems with Solaris /bin/sh.
+
+2008-07-08 Matthias Klose <doko@ubuntu.com>
+
+ * libtool-version: Bump soversion.
+
+2008-07-07 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
+
+ * gnu/gcj/convert/make-trie.h: New.
+ * gnu/gcj/convert/gen-from-JIS.c: Include it.
+ * gnu/gcj/convert/make-trie.c: Likewise.
+ Fix typos and compiler warnings, diagnose a missing argument.
+ * Makefile.am (gen_from_JIS_SOURCES): Add gnu/gcj/convert/make-trie.h.
+ * Makefile.in: Regenerate.
+
2008-06-30 Joshua Sumali <jsumali@redhat.com>
Andrew Haley <aph@redhat.com>
diff --git a/libjava/Makefile.am b/libjava/Makefile.am
index c074f5752a0..ce6dbd201f7 100644
--- a/libjava/Makefile.am
+++ b/libjava/Makefile.am
@@ -727,7 +727,8 @@ noinst_PROGRAMS = gen-from-JIS
gen_from_JIS_SOURCES = \
gnu/gcj/convert/gen-from-JIS.c \
- gnu/gcj/convert/make-trie.c
+ gnu/gcj/convert/make-trie.c \
+ gnu/gcj/convert/make-trie.h
gen_from_JIS_DEPENDENCIES = \
gnu/gcj/convert/JIS0201.h \
diff --git a/libjava/Makefile.in b/libjava/Makefile.in
index ba487885efc..4aab2bcc835 100644
--- a/libjava/Makefile.in
+++ b/libjava/Makefile.in
@@ -471,7 +471,7 @@ gcj_dbtool_OBJECTS = $(am_gcj_dbtool_OBJECTS)
am_gcjh_OBJECTS =
gcjh_OBJECTS = $(am_gcjh_OBJECTS)
am__gen_from_JIS_SOURCES_DIST = gnu/gcj/convert/gen-from-JIS.c \
- gnu/gcj/convert/make-trie.c
+ gnu/gcj/convert/make-trie.c gnu/gcj/convert/make-trie.h
@MAINTAINER_MODE_TRUE@@NATIVE_TRUE@am_gen_from_JIS_OBJECTS = gnu/gcj/convert/gen-from-JIS.$(OBJEXT) \
@MAINTAINER_MODE_TRUE@@NATIVE_TRUE@ gnu/gcj/convert/make-trie.$(OBJEXT)
gen_from_JIS_OBJECTS = $(am_gen_from_JIS_OBJECTS)
@@ -8176,7 +8176,8 @@ extra_headers = java/lang/Object.h java/lang/Class.h
install_data_local_split = 50
@MAINTAINER_MODE_TRUE@@NATIVE_TRUE@gen_from_JIS_SOURCES = \
@MAINTAINER_MODE_TRUE@@NATIVE_TRUE@ gnu/gcj/convert/gen-from-JIS.c \
-@MAINTAINER_MODE_TRUE@@NATIVE_TRUE@ gnu/gcj/convert/make-trie.c
+@MAINTAINER_MODE_TRUE@@NATIVE_TRUE@ gnu/gcj/convert/make-trie.c \
+@MAINTAINER_MODE_TRUE@@NATIVE_TRUE@ gnu/gcj/convert/make-trie.h
@MAINTAINER_MODE_TRUE@@NATIVE_TRUE@gen_from_JIS_DEPENDENCIES = \
@MAINTAINER_MODE_TRUE@@NATIVE_TRUE@ gnu/gcj/convert/JIS0201.h \
diff --git a/libjava/classpath/ChangeLog b/libjava/classpath/ChangeLog
index 10a167cb08c..f8e2d43ee2c 100644
--- a/libjava/classpath/ChangeLog
+++ b/libjava/classpath/ChangeLog
@@ -1,3 +1,10 @@
+2008-07-15 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
+
+ * m4/acinclude.m4 (CLASSPATH_COND_IF): New macro.
+ * configure.ac: Use it.
+ * configure: Regenerate.
+ * tools/Makefile.am (!CREATE_WRAPPERS): Update comment.
+
2008-06-11 Andrew Haley <aph@redhat.com>
* native/jawt/Makefile.am,
diff --git a/libjava/classpath/configure b/libjava/classpath/configure
index 966fcbd54f9..4a39d32c2b4 100755
--- a/libjava/classpath/configure
+++ b/libjava/classpath/configure
@@ -28343,9 +28343,11 @@ fi
ac_config_files="$ac_config_files Makefile doc/Makefile doc/api/Makefile external/Makefile external/sax/Makefile external/w3c_dom/Makefile external/relaxngDatatype/Makefile external/jsr166/Makefile gnu/classpath/Configuration.java gnu/java/security/Configuration.java include/Makefile native/Makefile native/fdlibm/Makefile native/jawt/Makefile native/jni/Makefile native/jni/classpath/Makefile native/jni/java-io/Makefile native/jni/java-lang/Makefile native/jni/java-net/Makefile native/jni/java-nio/Makefile native/jni/java-util/Makefile native/jni/gtk-peer/Makefile native/jni/gconf-peer/Makefile native/jni/gstreamer-peer/Makefile native/jni/qt-peer/Makefile native/jni/xmlj/Makefile native/jni/midi-alsa/Makefile native/jni/midi-dssi/Makefile native/jni/native-lib/Makefile native/plugin/Makefile resource/Makefile resource/META-INF/services/java.util.prefs.PreferencesFactory resource/META-INF/services/javax.sound.sampled.spi.AudioFileReader resource/META-INF/services/javax.sound.sampled.spi.MixerProvider scripts/Makefile scripts/classpath.spec lib/Makefile lib/gen-classlist.sh lib/copy-vmresources.sh scripts/check_jni_methods.sh tools/Makefile examples/Makefile examples/Makefile.jawt examples/Makefile.java2d"
-if test "x${COMPILE_WRAPPERS}" = xno
-then
- ac_config_files="$ac_config_files tools/gappletviewer tools/gjarsigner tools/gkeytool tools/gjar tools/gnative2ascii tools/gserialver tools/grmiregistry tools/gtnameserv tools/gorbd tools/grmid tools/grmic tools/gjavah"
+if test "x${COMPILE_WRAPPERS}" = xyes; then
+ :
+ else
+ ac_config_files="$ac_config_files tools/gappletviewer tools/gjarsigner tools/gkeytool tools/gjar tools/gnative2ascii tools/gserialver tools/grmiregistry tools/gtnameserv tools/gorbd tools/grmid tools/grmic tools/gjavah"
+
ac_config_commands="$ac_config_commands gappletviewer"
@@ -28371,7 +28373,9 @@ then
ac_config_commands="$ac_config_commands gjavah"
-fi
+
+ fi
+
ac_config_commands="$ac_config_commands gen-classlist"
diff --git a/libjava/classpath/configure.ac b/libjava/classpath/configure.ac
index a14d2c128c3..54a3efce22f 100644
--- a/libjava/classpath/configure.ac
+++ b/libjava/classpath/configure.ac
@@ -1059,9 +1059,8 @@ examples/Makefile
examples/Makefile.jawt
examples/Makefile.java2d])
-if test "x${COMPILE_WRAPPERS}" = xno
-then
-AC_CONFIG_FILES([tools/gappletviewer
+CLASSPATH_COND_IF([CREATE_WRAPPERS], [test "x${COMPILE_WRAPPERS}" = xyes], [],
+[AC_CONFIG_FILES([tools/gappletviewer
tools/gjarsigner
tools/gkeytool
tools/gjar
@@ -1073,6 +1072,7 @@ tools/gorbd
tools/grmid
tools/grmic
tools/gjavah])
+
AC_CONFIG_COMMANDS([gappletviewer],[chmod 755 tools/gappletviewer])
AC_CONFIG_COMMANDS([gjarsigner],[chmod 755 tools/gjarsigner])
AC_CONFIG_COMMANDS([gkeytool],[chmod 755 tools/gkeytool])
@@ -1085,7 +1085,7 @@ AC_CONFIG_COMMANDS([gorbd],[chmod 755 tools/gorbd])
AC_CONFIG_COMMANDS([grmid],[chmod 755 tools/grmid])
AC_CONFIG_COMMANDS([grmic],[chmod 755 tools/grmic])
AC_CONFIG_COMMANDS([gjavah], [chmod 755 tools/gjavah])
-fi
+])
AC_CONFIG_COMMANDS([gen-classlist],[chmod 755 lib/gen-classlist.sh])
AC_CONFIG_COMMANDS([copy-vmresources],[chmod 755 lib/copy-vmresources.sh])
diff --git a/libjava/classpath/m4/acinclude.m4 b/libjava/classpath/m4/acinclude.m4
index 6c4eacda486..9f98f1c37f6 100644
--- a/libjava/classpath/m4/acinclude.m4
+++ b/libjava/classpath/m4/acinclude.m4
@@ -246,3 +246,19 @@ EOF
rm -f $JAVA_TEST $CLASS_TEST
AC_SUBST(JAVAC_MEM_OPT)
])
+
+dnl ---------------------------------------------------------------
+dnl CLASSPATH_COND_IF(COND, SHELL-CONDITION, [IF-TRUE], [IF-FALSE])
+dnl ---------------------------------------------------------------
+dnl Automake 1.11 can emit conditional rules for AC_CONFIG_FILES,
+dnl using AM_COND_IF. This wrapper uses it if it is available,
+dnl otherwise falls back to code compatible with Automake 1.9.6.
+AC_DEFUN([CLASSPATH_COND_IF],
+[m4_ifdef([AM_COND_IF],
+ [AM_COND_IF([$1], [$3], [$4])],
+ [if $2; then
+ m4_default([$3], [:])
+ else
+ m4_default([$4], [:])
+ fi
+])])
diff --git a/libjava/classpath/tools/Makefile.am b/libjava/classpath/tools/Makefile.am
index 94228271e93..81953bc66ee 100755
--- a/libjava/classpath/tools/Makefile.am
+++ b/libjava/classpath/tools/Makefile.am
@@ -89,7 +89,8 @@ noinst_SCRIPTS = gappletviewer gjarsigner gkeytool \
gjar gnative2ascii gserialver gjavah grmiregistry \
gtnameserv gorbd grmid grmic
bin_PROGRAMS =
-## FIXME: revisit this with a newer automake.
+## FIXME: remove these unneeded dependency lines once we can
+## require Automake 1.11.
gappletviewer: gappletviewer.in
gjarsigner: gjarsigner.in
gkeytool: gkeytool.in
diff --git a/libjava/gnu/gcj/convert/gen-from-JIS.c b/libjava/gnu/gcj/convert/gen-from-JIS.c
index 13745805ab8..d4cca14474e 100644
--- a/libjava/gnu/gcj/convert/gen-from-JIS.c
+++ b/libjava/gnu/gcj/convert/gen-from-JIS.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1999 Free Software Foundation
+/* Copyright (C) 1999, 2008 Free Software Foundation
This file is part of libgcj.
@@ -7,6 +7,10 @@ Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
details. */
#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include "make-trie.h"
+
struct chval
{
unsigned char b1; /* 1st byte */
@@ -59,6 +63,11 @@ main(int argc, char** argv)
int low1_uc = 0xFFFF, high1_uc = 0;
int low2_uc = 0xFFFF, high2_uc = 0;
int i; int row, col;
+ if (argc < 2)
+ {
+ fprintf (stderr, "missing argument!\n");
+ exit (-1);
+ }
if (strcmp (argv[1], "JIS0208") == 0)
chtab = chtab_0208;
else if (strcmp (argv[1], "JIS0212") == 0)
@@ -106,8 +115,7 @@ main(int argc, char** argv)
fprintf(out,"/* This file is automatically generated from %s.TXT. */\n",
argv[1]);
- fprintf(out,"#pragma GCC java_exceptions\n",
- argv[1]);
+ fprintf(out,"#pragma GCC java_exceptions\n");
fprintf(out, "unsigned short %s_to_Unicode[%d][%d] = {\n",
argv[1], max1 - min1 + 1, max2 - min2 + 1);
i = 0;
@@ -156,7 +164,7 @@ main(int argc, char** argv)
}
else
{
- fprintf (stderr, "error - char table our of order!\n");
+ fprintf (stderr, "error - char table out of order!\n");
exit (-1);
}
if (col != max2)
diff --git a/libjava/gnu/gcj/convert/make-trie.c b/libjava/gnu/gcj/convert/make-trie.c
index e89f70c5c9f..fe2d7892641 100644
--- a/libjava/gnu/gcj/convert/make-trie.c
+++ b/libjava/gnu/gcj/convert/make-trie.c
@@ -8,6 +8,7 @@ details. */
#include <stdio.h>
#include <stdlib.h>
+#include "make-trie.h"
typedef struct trie_node
{
diff --git a/libjava/gnu/gcj/convert/make-trie.h b/libjava/gnu/gcj/convert/make-trie.h
new file mode 100644
index 00000000000..bbe20a5ccd8
--- /dev/null
+++ b/libjava/gnu/gcj/convert/make-trie.h
@@ -0,0 +1,13 @@
+/* Copyright (C) 2008 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+#include <stddef.h>
+
+extern void print_table (char *name, FILE *out);
+
+extern void enter (int key, int value);
diff --git a/libjava/libtool-version b/libjava/libtool-version
index 964dc4f4f01..db361f7b168 100644
--- a/libjava/libtool-version
+++ b/libjava/libtool-version
@@ -3,4 +3,4 @@
# a separate file so that version updates don't involve re-running
# automake.
# CURRENT:REVISION:AGE
-9:0:0
+10:0:0
diff --git a/libjava/scripts/jar.in b/libjava/scripts/jar.in
index 82ea10c2912..e9cb9f5822e 100644
--- a/libjava/scripts/jar.in
+++ b/libjava/scripts/jar.in
@@ -96,7 +96,7 @@ copy () {
return 0
fi
- if test -e "$2"/"$1"; then
+ if test -f "$2"/"$1"; then
error "$1": Duplicate entry.
fi
dir=`dirname "$1"`
@@ -249,8 +249,7 @@ jar_list_verbose () {
}
# mkdir -p emulation based on the mkinstalldirs script.
-mkdir_p ()
-{
+func_mkdir_p () {
for file
do
case $file in
@@ -290,7 +289,7 @@ mkdir_p ()
if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then
mkdir_p='mkdir -p'
else
- mkdir_p='mkdir_p'
+ mkdir_p='func_mkdir_p'
test -d ./-p && rmdir ./-p
test -d ./--version && rmdir ./--version
fi
diff --git a/libobjc/ChangeLog b/libobjc/ChangeLog
index 44743b62b88..6c3dd17d094 100644
--- a/libobjc/ChangeLog
+++ b/libobjc/ChangeLog
@@ -1,3 +1,16 @@
+2008-07-18 Matthias Klose <doko@ubuntu.com>
+
+ * Makefile.in: Ignore missing ../boehm-gc/threads.mk.
+
+2008-07-18 Matthias Klose <doko@ubuntu.com>
+
+ * Makefile.in: Include ../boehm-gc/threads.mk.
+ (OBJC_BOEHM_GC_LIBS): Define, (libobjc_gc$(libsuffix).la): Use it.
+
+2008-07-06 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
+
+ * Makefile.in (install-info): New stub target.
+
2008-06-17 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
* configure: Regenerate.
diff --git a/libobjc/Makefile.in b/libobjc/Makefile.in
index ee9f6a1f3c5..0cd77d37bc1 100644
--- a/libobjc/Makefile.in
+++ b/libobjc/Makefile.in
@@ -1,6 +1,6 @@
# Makefile for GNU Objective C runtime library.
# Copyright 1993, 1995, 1996, 1997, 1998, 1999, 2001, 2002, 2003, 2004,
-# 2005, 2006 Free Software Foundation, Inc.
+# 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
#This file is part of GCC.
@@ -48,6 +48,8 @@ extra_ldflags_libobjc = @extra_ldflags_libobjc@
top_builddir = .
+-include ../boehm-gc/threads.mk
+
libdir = $(exec_prefix)/lib
libsubdir = $(libdir)/gcc/$(target_noncanonical)/$(gcc_version)
@@ -95,6 +97,7 @@ OBJC_GCFLAGS=-DOBJC_WITH_GC=1
OBJC_THREAD_FILE=thr-objc
OBJC_BOEHM_GC=@OBJC_BOEHM_GC@
OBJC_BOEHM_GC_INCLUDES=@OBJC_BOEHM_GC_INCLUDES@
+OBJC_BOEHM_GC_LIBS=../boehm-gc/libgcjgc_convenience.la $(thread_libs_and_flags)
INCLUDES = -I$(srcdir)/objc -I$(srcdir)/$(MULTISRCTOP)../gcc \
-I$(srcdir)/$(MULTISRCTOP)../gcc/config \
@@ -270,9 +273,10 @@ exception_gc.lo: exception.c
doc: info dvi pdf html
# No install-html or install-pdf support
-.PHONY: install-html install-pdf
+.PHONY: install-html install-pdf install-info
install-html:
install-pdf:
+install-info:
LTLDFLAGS = $(shell $(SHELL) $(top_srcdir)/../libtool-ldflags $(LDFLAGS))
@@ -283,7 +287,7 @@ libobjc$(libsuffix).la: $(OBJS)
$(LTLDFLAGS)
libobjc_gc$(libsuffix).la: $(OBJS_GC)
- $(LIBTOOL_LINK) $(CC) -o $@ $(OBJS_GC) \
+ $(LIBTOOL_LINK) $(CC) -o $@ $(OBJS_GC) $(OBJC_BOEHM_GC_LIBS) \
-rpath $(toolexeclibdir) \
-version-info $(LIBOBJC_GC_VERSION) $(extra_ldflags_libobjc) \
$(LTLDFLAGS)
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index a937a52aa92..ab9183c4115 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,372 @@
+2008-07-24 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR libstdc++/36924
+ Revert:
+ 2008-07-23 Chris Fairles <chris.fairles@gmail.com>
+
+ * acinclude.m4 ([GLIBCXX_CHECK_CLOCK_GETTIME]): Define GLIBCXX_LIBS.
+ Holds the lib that defines clock_gettime (-lrt or -lposix4).
+ * src/Makefile.am: Use it.
+ * configure: Regenerate.
+ * configure.in: Likewise.
+ * Makefile.in: Likewise.
+ * src/Makefile.in: Likewise.
+ * libsup++/Makefile.in: Likewise.
+ * po/Makefile.in: Likewise.
+ * doc/Makefile.in: Likewise.
+
+2008-07-23 Chris Fairles <chris.fairles@gmail.com>
+
+ * include/std/condition_variable: Update to N2691 WD.
+ * include/std/mutex: Likewise.
+ * testsuite/30_threads/mutex/cons/assign_neg.cc: Adjust line numbers.
+ * testsuite/30_threads/mutex/cons/copy_neg.cc: Likewise.
+ * testsuite/30_threads/recursive_mutex/cons/assign_neg.cc: Likewise.
+ * testsuite/30_threads/recursive_mutex/cons/copy_neg.cc: Likewise.
+
+2008-07-23 Chris Fairles <chris.fairles@gmail.com>
+
+ * acinclude.m4 ([GLIBCXX_CHECK_CLOCK_GETTIME]): Define GLIBCXX_LIBS.
+ Holds the lib that defines clock_gettime (-lrt or -lposix4).
+ * src/Makefile.am: Use it.
+ * configure: Regenerate.
+ * configure.in: Likewise.
+ * Makefile.in: Likewise.
+ * src/Makefile.in: Likewise.
+ * libsup++/Makefile.in: Likewise.
+ * po/Makefile.in: Likewise.
+ * doc/Makefile.in: Likewise.
+
+2008-07-22 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * include/ext/sso_string_base.h
+ (__sso_string_base<>::__sso_string_base(std::initializer_list<_CharT>,
+ const _Alloc&)): Remove.
+ * include/ext/rc_string_base.h
+ (__rc_string_base<>::__rc_string_base(std::initializer_list<_CharT>,
+ const _Alloc&)): Likewise.
+ * include/ext/vstring.h
+ (__versa_string<>::__versa_string(std::initializer_list<_CharT>,
+ const _Alloc&)): Adjust.
+
+2008-07-21 Jason Merrill <jason@redhat.com>
+
+ Add initializer_list support as per N2679.
+ * include/debug/unordered_map: Add initializer_list support.
+ * include/debug/safe_association.h: Likewise.
+ * include/debug/unordered_set: Likewise.
+ * include/debug/vector: Likewise.
+ * include/debug/deque: Likewise.
+ * include/debug/map.h: Likewise.
+ * include/debug/set.h: Likewise.
+ * include/debug/string: Likewise.
+ * include/debug/list: Likewise.
+ * include/debug/multimap.h: Likewise.
+ * include/tr1_impl/unordered_map: Likewise.
+ * include/tr1_impl/hashtable: Likewise.
+ * include/tr1_impl/unordered_set: Likewise.
+ * include/tr1_impl/regex: Likewise.
+ * include/std/valarray: Likewise.
+ * include/std/unordered_map: Likewise.
+ * include/std/unordered_set: Likewise.
+ * include/bits/stl_list.h: Likewise.
+ * include/bits/stl_map.h: Likewise.
+ * include/bits/stl_set.h: Likewise.
+ * include/bits/basic_string.h: Likewise.
+ * include/bits/basic_string.tcc: Likewise.
+ * include/bits/stl_multimap.h: Likewise.
+ * include/bits/stl_vector.h: Likewise.
+ * include/bits/stl_deque.h: Likewise.
+ * include/bits/stl_multiset.h: Likewise.
+ * include/bits/stl_bvector.h: Likewise.
+ * include/ext/vstring.h: Likewise.
+ * include/ext/rc_string_base.h: Likewise.
+ * include/ext/sso_string_base.h: Likewise.
+ * src/Makefile.am (w?string-inst): Build with -std=gnu++0x.
+ * src/Makefile.in: Likewise.
+ * config/abi/pre/gnu.ver: Add new w?string exports.
+ * testsuite/21_strings/basic_string/init-list.cc: New test.
+ * testsuite/23_containers/vector/init-list.cc: New test.
+ * testsuite/23_containers/deque/init-list.cc: New test.
+ * testsuite/23_containers/list/init-list.cc: New test.
+ * testsuite/23_containers/map/init-list.cc: New test.
+ * testsuite/23_containers/multimap/init-list.cc: New test.
+ * testsuite/23_containers/set/init-list.cc: New test.
+ * testsuite/23_containers/multiset/init-list.cc: New test.
+ * testsuite/23_containers/unordered_map/init-list.cc: New test.
+ * testsuite/23_containers/unordered_multimap/init-list.cc: New test.
+ * testsuite/23_containers/unordered_set/init-list.cc: New test.
+ * testsuite/23_containers/unordered_multiset/init-list.cc: New test.
+ * testsuite/26_numerics/valarray/init-list.cc: New test.
+ * testsuite/28_regex/init-list.cc: New test.
+ * testsuite/ext/vstring/init-list.cc: New test.
+ * testsuite/23_containers/vector/requirements/dr438/assign_neg.cc:
+ Update error lineno.
+ * testsuite/23_containers/vector/requirements/dr438/insert_neg.cc:
+ Update error lineno.
+ * testsuite/23_containers/vector/requirements/dr438/
+ constructor_1_neg.cc: Update error lineno.
+ * testsuite/23_containers/vector/requirements/dr438/
+ constructor_2_neg.cc: Update error lineno.
+ * testsuite/23_containers/deque/requirements/dr438/assign_neg.cc:
+ Update error lineno.
+ * testsuite/23_containers/deque/requirements/dr438/insert_neg.cc:
+ Update error lineno.
+ * testsuite/23_containers/deque/requirements/dr438/constructor_1_neg.cc:
+ Update error lineno.
+ * testsuite/23_containers/deque/requirements/dr438/constructor_2_neg.cc:
+ Update error lineno.
+ * testsuite/23_containers/list/requirements/dr438/assign_neg.cc:
+ Update error lineno.
+ * testsuite/23_containers/list/requirements/dr438/insert_neg.cc:
+ Update error lineno.
+ * testsuite/23_containers/list/requirements/dr438/constructor_1_neg.cc:
+ Update error lineno.
+ * testsuite/23_containers/list/requirements/dr438/constructor_2_neg.cc:
+ Update error lineno.
+
+2008-07-21 Mark Mitchell <mark@codesourcery.com>
+
+ * config/os/gnu-linux/arm-eabi-extra.ver: New file.
+ * configure.host: Use it for arm*-*-linux-*eabi.
+
+2008-07-19 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * include/ext/pb_ds/detail/binomial_heap_base_/debug_fn_imps.hpp
+ (assert_node_consistent): Avoid ambiguous else warning.
+
+ * include/ext/pb_ds/detail/debug_map_base.hpp: Include <iostream>.
+
+ * include/bits/c++config: In debug-mode (and parallel-mode) set
+ _GLIBCXX_EXTERN_TEMPLATE to -1, not 0, thus disabling extern
+ templates only for basic_string (per libstdc++/21674).
+ * include/bits/basic_string.tcc: Use extern templates when
+ _GLIBCXX_EXTERN_TEMPLATE > 0.
+
+2008-07-18 Kris Van Hees <kris.van.hees@oracle.com>
+ Holger Hopp <holger.hopp@sap.com>
+
+ * config/abi/pre/gnu.ver: Support char16_t and char32_t.
+ * testsuite/util/testsuite_abi.cc (check_version): Add
+ CXXABI_1.3.3 to known_versions.
+
+2008-07-16 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * include/debug/vector (insert(iterator, _Tp&&), push_back(_Tp&&)):
+ Enable only when _Tp != bool.
+
+ * testsuite/25_algorithms/heap/1.cc: Avoid unused variable warnings.
+
+2008-07-18 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * testsuite/lib/libstdc++.exp (check_v3_target_c_std): Avoid unused
+ variable warnings leading to spurious fails of the test.
+
+2008-07-16 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * testsuite/30_threads/recursive_mutex/cons/assign_neg.cc: Adjust
+ dg-error lines.
+ * testsuite/30_threads/recursive_mutex/cons/copy_neg.cc: Likewise.
+ * testsuite/20_util/duration/cons/1_neg.cc: Likewise.
+
+ * include/tr1_impl/type_traits: Fix comment typo.
+
+2008-07-16 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * include/bits/unique_ptr.h: Remove stray character.
+
+2008-07-15 Benjamin Kosnik <bkoz@redhat.com>
+
+ * doc/doxygen/user.cfg.in: Add complex, ratio,
+ intializer_list.
+ (PREDEFINED): Add _GLIBCXX_USE_C99_STDINT_TR1.
+ * doc/doxygen/doxygroups.cc: Add std::chrono.
+ * include/bits/unique_ptr.h (default_delete, unique_ptr): Add markup.
+ * libsupc++/initializer_list (initializer_list): Same.
+ * include/std/ratio: Same.
+ * include/std/chrono: Same.
+ * include/std/complex: Disambiguate file markup.
+
+2008-07-15 Chris Fairles <chris.fairles@gmail.com>
+
+ * include/std/chrono: New, as per N2661.
+ * src/chrono.cc: New.
+ * include/Makefile.am: Update.
+ * src/Makefile.am: Likewise.
+ * include/Makefile.in: Regenerate.
+ * src/Makefile.in: Likewise.
+ * acinclude.m4: Add tests for clock_gettime and gettimeofday that
+ define _GLIBCXX_HAS_CLOCK_GETTIME and/or _GLIBCXX_HAS_GETTIMEOFDAY.
+ * configure.ac: Use them.
+ * configure: Regenerate.
+ * config.h.in: Likewise.
+ * config/abi/pre/gnu.ver: Add symbols for system_clock::now() and
+ system_clock::is_monotonic.
+ * testsuite/20_util/duration/cons/1.cc: New.
+ * testsuite/20_util/duration/cons/2.cc: Likewise.
+ * testsuite/20_util/duration/cons/1_neg.cc: Likewise.
+ * testsuite/20_util/duration/requirements/explicit_instantiation/
+ explicit_instantiation.cc: Likewise.
+ * testsuite/20_util/duration/arithmetic/1.cc: Likewise.
+ * testsuite/20_util/duration/arithmetic/2.cc: Likewise.
+ * testsuite/20_util/duration/comparisons/1.cc: Likewise.
+ * testsuite/20_util/time_point/requirements/explicit_instantiation/
+ explicit_instantiation.cc: Likewise.
+ * testsuite/20_util/time_point/1.cc: Likewise.
+ * testsuite/20_util/time_point/2.cc: Likewise.
+ * testsuite/20_util/time_point/3.cc: Likewise.
+ * testsuite/20_util/clocks/1.cc: Likewise.
+ * testsuite/17_intro/headers/c++200x/all_multiple_inclusion.cc: Add
+ missing headers.
+ * testsuite/17_intro/headers/c++200x/all.cc: Likewise.
+ * include/precompiled/stdc++.h: Likewise and remove <date_time>.
+ * doc/doxygen/user.cfg.in: Likewise.
+
+2008-07-15 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR libstdc++/36832
+ * include/ext/rope (_Destroy_const): Add.
+ (rope<>::copy): Call it.
+ * testsuite/ext/rope/36832.cc: New.
+
+2008-07-15 Johannes Singler <singler@ira.uka.de>
+
+ * include/parallel/find_selectors.h:
+ Correct name for include guard #ifndef.
+ * include/parallel/balanced_quicksort.h: Likewise.
+ * include/parallel/unique_copy.h: Likewise.
+ * include/parallel/multiway_mergesort.h: Likewise.
+ * include/parallel/checkers.h: Likewise.
+ * include/parallel/[various files]:
+ Add/correct comment for #endif of include guard (at end of file)
+
+2008-07-12 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * include/std/date_time: Remove, per N2549, in WP.
+ * src/date_time.cc: Likewise.
+ * config/abi/pre/gnu.ver: Remove <date_time> symbols.
+ * include/Makefile.am: Remove date_time in std headers.
+ * src/Makefile.am: Remove date_time.cc to source files.
+ * include/Makefile.in: Regenerate.
+ * src/Makefile.in: Likewise.
+ * testsuite/31_date_time/headers/date_time/types_std.cc: Remove.
+ * testsuite/31_date_time/headers/date_time/std_c++0x_neg.cc: Likewise.
+ * testsuite/31_date_time/headers/date_time/functions_std.cc: Likewise.
+ * testsuite/31_date_time/headers/date_time/synopsis.cc: Likewise.
+ * testsuite/31_date_time/nanoseconds/requirements/traits.cc: Likewise.
+ * testsuite/31_date_time/nanoseconds/requirements/duration.cc: Likewise.
+ * testsuite/31_date_time/system_time/requirements: Likewise.
+ * testsuite/31_date_time/system_time/requirements/traits.cc: Likewise.
+ * testsuite/17_intro/headers/c++200x/all.cc: Adjust.
+ * testsuite/17_intro/headers/c++200x/all_multiple_inclusion.cc: Adjust.
+
+2008-07-10 Johannes Singler <singler@ira.uka.de>
+
+ * include/parallel/balanced_quicksort.h:
+ (qsb_divide) Replace "*end" by "*(end - 1)" in assertion.
+
+2008-07-09 Benjamin Kosnik <bkoz@redhat.com>
+
+ PR libstdc++/36451
+ * doc/xml/manual/allocator.xml: Fix links.
+ * doc/html/*: Regenerate.
+
+2008-07-09 Joseph Myers <joseph@codesourcery.com>
+
+ * libsupc++/unwind-cxx.h (__is_gxx_forced_unwind_class,
+ __GXX_INIT_FORCED_UNWIND_CLASS): Define for ARM EABI unwinder.
+ * libsupc++/eh_personality.cc (PERSONALITY_FUNCTION): Call
+ __GXX_INIT_FORCED_UNWIND_CLASS for forced unwind with ARM EABI
+ unwinder.
+ * libsupc++/eh_arm.cc (__cxa_type_match): Use
+ __is_gxx_forced_unwind_class to check for forced unwind.
+
+2008-07-09 Andreas Beckmann <gcc@abeckmann.de>
+
+ PR libstdc++/36552
+ * include/ext/pb_ds/detail/left_child_next_sibling_heap_/
+ null_metadata.hpp: Remove self-include.
+
+2008-07-09 Joseph Myers <joseph@codesourcery.com>
+
+ * testsuite/20_util/make_signed/requirements/typedefs-2.cc,
+ testsuite/20_util/make_unsigned/requirements/typedefs-2.cc: Use
+ -Wl,--no-enum-size-warning for arm*-*-linux*eabi.
+
+2008-07-09 Johannes Singler <singler@ira.uka.de>
+
+ PR libstdc++/36729
+ * include/parallel/random_shuffle.h:
+ (sequential_random_shuffle) Copy data back.
+ * testsuite/25_algorithms/random_shuffle/1.cc:
+ New. Generic random_shuffle functionality test.
+
+2008-07-08 Chris Fairles <chris.fairles@gmail.com>
+
+ * include/std/type_traits: Add common_type.
+ * testsuite/20_util/common_type/requirements/
+ explicit_instantiation.cc: New.
+ * testsuite/20_util/common_type/requirements/
+ typedefs-1.cc: Likewise.
+
+2008-07-07 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * testsuite/lib/libstdc++.exp (check_v3_target_stdint): New.
+ * testsuite/lib/dg-options.exp (dg-require-cstdint): New.
+ * testsuite/20_util/ratio/cons/cons1.cc: Use it.
+ * testsuite/20_util/ratio/cons/cons_overflow.cc: Likewise.
+ * testsuite/20_util/ratio/operations/ops1.cc: Likewise.
+ * testsuite/20_util/ratio/operations/ops2.cc: Likewise.
+ * testsuite/20_util/ratio/operations/ops3.cc: Likewise.
+ * testsuite/20_util/ratio/operations/ops_overflow.cc: Likewise.
+ * testsuite/20_util/ratio/comparisons/comp1.cc: Likewise.
+ * testsuite/20_util/ratio/comparisons/comp2.cc: Likewise.
+
+ * include/std/type_traits: Fix comment typo.
+
+2008-07-06 Roger Sayle <roger@eyesopen.com>
+
+ * include/std/system_error (is_error_code_enum): Use identifier
+ _Tp instead of _T to avoid conflict with system macro on Darwin.
+ (is_error_condition_enum): Likewise.
+
+2008-07-05 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * include/bits/postypes.h: Do not include <stdint.h>.
+
+ * include/Makefile.am: Reorder.
+
+2008-07-05 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * include/std/ratio: Prefer __INTMAX_MAX__ to INTMAX_MAX (INTMAX_MIN).
+
+2008-07-05 Chris Fairles <chris.fairles@gmail.com>
+
+ * include/std/ratio: Documentation for std::ratio class. Add conditions
+ to ratio_less to prevent overflow.
+ * testsuite/20_util/ratio/comparisons/comp2.cc: New.
+ * testsuite/20_util/ratio/cons/cons_overflow.cc: Update dg-error line
+ numbers.
+
+2008-07-04 Chris Fairles <chris.fairles@gmail.com>
+
+ * include/std/ratio: New, per N2661.
+ * include/Makefile.am: Update.
+ * include/Makefile.in: Regenerate.
+ * testsuite/20_util/ratio/cons/cons1.cc: New.
+ * testsuite/20_util/ratio/cons/cons_overflow.cc: Likewise.
+ * testsuite/20_util/ratio/operations/ops1.cc: Likewise.
+ * testsuite/20_util/ratio/operations/ops2.cc: Likewise.
+ * testsuite/20_util/ratio/operations/ops3.cc: Likewise.
+ * testsuite/20_util/ratio/operations/ops_overflow.cc: Likewise.
+ * testsuite/20_util/ratio/comparisons/comp1.cc: Likewise.
+
+2008-07-04 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR libstdc++/36616
+ * testsuite/22_locale/time_put/put/char/4.cc: Just use es_ES instead.
+ * testsuite/22_locale/time_put/put/wchar_t/4.cc: Likewise.
+
2008-07-03 Paolo Carlini <paolo.carlini@oracle.com>
* testsuite/21_strings/basic_string/numeric_conversions/char/stof.cc:
diff --git a/libstdc++-v3/acinclude.m4 b/libstdc++-v3/acinclude.m4
index a68ab9be2a8..e998471c446 100644
--- a/libstdc++-v3/acinclude.m4
+++ b/libstdc++-v3/acinclude.m4
@@ -1009,6 +1009,94 @@ AC_DEFUN([GLIBCXX_ENABLE_C99], [
dnl
+dnl Check for IEEE Std 1003.1-2001 clock_gettime required for
+dnl 20.8.5 [time.clock] in the current C++0X working draft.
+dnl
+AC_DEFUN([GLIBCXX_CHECK_CLOCK_GETTIME], [
+
+ AC_LANG_SAVE
+ AC_LANG_CPLUSPLUS
+ ac_save_CXXFLAGS="$CXXFLAGS"
+ CXXFLAGS="$CXXFLAGS -fno-exceptions"
+
+ AC_CHECK_HEADERS(unistd.h, ac_has_unistd_h=yes, ac_has_unistd_h=no)
+
+ ac_has_clock_monotonic=no;
+ ac_has_clock_realtime=no;
+ if test x"$ac_has_unistd_h" = x"yes"; then
+ AC_MSG_CHECKING([for monotonic clock])
+ AC_TRY_LINK(
+ [#include <unistd.h>
+ #include <time.h>
+ ],
+ [#if _POSIX_TIMERS > 0 && defined(_POSIX_MONOTONIC_CLOCK)
+ timespec tp;
+ #endif
+ clock_gettime(CLOCK_MONOTONIC, &tp);
+ ], [ac_has_clock_monotonic=yes], [ac_has_clock_monotonic=no])
+
+ AC_MSG_RESULT($ac_has_clock_monotonic)
+
+ AC_MSG_CHECKING([for realtime clock])
+ AC_TRY_LINK(
+ [#include <unistd.h>
+ #include <time.h>
+ ],
+ [#if _POSIX_TIMERS > 0
+ timespec tp;
+ #endif
+ clock_gettime(CLOCK_REALTIME, &tp);
+ ], [ac_has_clock_realtime=yes], [ac_has_clock_realtime=no])
+
+ AC_MSG_RESULT($ac_has_clock_realtime)
+ fi
+
+ if test x"$ac_has_clock_monotonic" = x"yes"; then
+ AC_DEFINE(_GLIBCXX_USE_CLOCK_MONOTONIC, 1,
+ [ Defined if clock_gettime has monotonic clock support. ])
+ fi
+
+ if test x"$ac_has_clock_realtime" = x"yes"; then
+ AC_DEFINE(_GLIBCXX_USE_CLOCK_REALTIME, 1,
+ [ Defined if clock_gettime has realtime clock support. ])
+ fi
+
+ CXXFLAGS="$ac_save_CXXFLAGS"
+ AC_LANG_RESTORE
+])
+
+dnl
+dnl Check for IEEE Std 1003.1-2001 gettimeofday required for
+dnl 20.8.5 [time.clock] in the current C++0X working draft.
+dnl
+AC_DEFUN([GLIBCXX_CHECK_GETTIMEOFDAY], [
+
+ AC_LANG_SAVE
+ AC_LANG_CPLUSPLUS
+ ac_save_CXXFLAGS="$CXXFLAGS"
+ CXXFLAGS="$CXXFLAGS -fno-exceptions"
+
+ ac_has_gettimeofday=no;
+ AC_CHECK_HEADERS(sys/time.h, ac_has_sys_time_h=yes, ac_has_sys_time_h=no)
+ if test x"$ac_has_sys_time_h" = x"yes"; then
+ AC_MSG_CHECKING([for gettimeofday])
+ AC_TRY_LINK([#include <sys/time.h>],
+ [timeval tv; gettimeofday(&tv, 0);],
+ [ac_has_gettimeofday=yes], [ac_has_gettimeofday=no])
+
+ AC_MSG_RESULT($ac_has_gettimeofday)
+ fi
+
+ if test x"$ac_has_gettimeofday" = x"yes"; then
+ AC_DEFINE(_GLIBCXX_USE_GETTIMEOFDAY, 1,
+ [ Defined if gettimeofday is available. ])
+ fi
+
+ CXXFLAGS="$ac_save_CXXFLAGS"
+ AC_LANG_RESTORE
+])
+
+dnl
dnl Check for ISO/IEC 9899:1999 "C99" support to ISO/IEC DTR 19768 "TR1"
dnl facilities in Chapter 8, "C compatibility".
dnl
diff --git a/libstdc++-v3/config.h.in b/libstdc++-v3/config.h.in
index d107f481be7..256637abcec 100644
--- a/libstdc++-v3/config.h.in
+++ b/libstdc++-v3/config.h.in
@@ -811,6 +811,15 @@
namespace std::tr1. */
#undef _GLIBCXX_USE_C99_STDINT_TR1
+/* Defined if clock_gettime has monotonic clock support. */
+#undef _GLIBCXX_USE_CLOCK_MONOTONIC
+
+/* Defined if clock_gettime has realtime clock support. */
+#undef _GLIBCXX_USE_CLOCK_REALTIME
+
+/* Defined if gettimeofday is available. */
+#undef _GLIBCXX_USE_GETTIMEOFDAY
+
/* Define if LFS support is available. */
#undef _GLIBCXX_USE_LFS
diff --git a/libstdc++-v3/config/abi/pre/gnu.ver b/libstdc++-v3/config/abi/pre/gnu.ver
index 4578ce513fc..7b31a1cfa47 100644
--- a/libstdc++-v3/config/abi/pre/gnu.ver
+++ b/libstdc++-v3/config/abi/pre/gnu.ver
@@ -147,9 +147,12 @@ GLIBCXX_3.4 {
# Names not in an 'extern' block are mangled names.
# std::string
- _ZNSsC*;
+ _ZNSsC[12][EI][PRjmvN]*;
_ZNSsD*;
- _ZNSs[0-9][a-z]*;
+ _ZNSs[0-58-9][a-z]*;
+ _ZNSs[67][a-z]*E[PRcjmv]*;
+ _ZNSs7[a-z]*EES2_[NPRjm]*;
+ _ZNSs7[a-z]*EES2_S[12]*;
_ZNSs12_Alloc_hiderC*;
_ZNSs12_M_leak_hardEv;
_ZNSs12_S_constructE[jm]cRKSaIcE;
@@ -172,9 +175,9 @@ GLIBCXX_3.4 {
_ZNSs4_Rep20_S_empty_rep_storageE;
_ZNSs4_Rep11_S_max_sizeE;
_ZNSs4_Rep11_S_terminalE;
- _ZNSsaSE*;
+ _ZNSsaSE[PRc]*;
_ZNSsixE*;
- _ZNSspLE*;
+ _ZNSspLE[PRc]*;
_ZNKSs[0-9][a-z]*;
_ZNKSs[0-9][0-9][a-z]*;
_ZNKSs[a-z]*;
@@ -189,9 +192,12 @@ GLIBCXX_3.4 {
_ZStplIcSt11char_traitsIcESaIcEESbIT_T0_T1_E*;
# std::wstring
- _ZNSbIwSt11char_traitsIwESaIwEEC*;
+ _ZNSbIwSt11char_traitsIwESaIwEEC[12][EI][PRjmvN]*;
_ZNSbIwSt11char_traitsIwESaIwEED*;
- _ZNSbIwSt11char_traitsIwESaIwEE[0-9][a-z]*;
+ _ZNSbIwSt11char_traitsIwESaIwEE[0-58-9][a-z]*;
+ _ZNSbIwSt11char_traitsIwESaIwEE[67][a-z]*E[PRwjmv]*;
+ _ZNSbIwSt11char_traitsIwESaIwEE7[a-z]*EES6_[NPRjm]*;
+ _ZNSbIwSt11char_traitsIwESaIwEE7[a-z]*EES6_S[56]*;
_ZNSbIwSt11char_traitsIwESaIwEE12_Alloc_hiderC*;
_ZNSbIwSt11char_traitsIwESaIwEE12_M_leak_hardEv;
_ZNSbIwSt11char_traitsIwESaIwEE12_S_constructE[jm]wRKS1_;
@@ -214,9 +220,9 @@ GLIBCXX_3.4 {
_ZNSbIwSt11char_traitsIwESaIwEE4_Rep20_S_empty_rep_storageE;
_ZNSbIwSt11char_traitsIwESaIwEE4_Rep11_S_max_sizeE;
_ZNSbIwSt11char_traitsIwESaIwEE4_Rep11_S_terminalE;
- _ZNSbIwSt11char_traitsIwESaIwEEaSE*;
+ _ZNSbIwSt11char_traitsIwESaIwEEaSE[PRw]*;
_ZNSbIwSt11char_traitsIwESaIwEEixE*;
- _ZNSbIwSt11char_traitsIwESaIwEEpLE*;
+ _ZNSbIwSt11char_traitsIwESaIwEEpLE[PRw]*;
_ZNKSbIwSt11char_traitsIwESaIwEE[0-9][a-z]*;
_ZNKSbIwSt11char_traitsIwESaIwEE[0-9][0-9][a-z]*;
_ZNKSbIwSt11char_traitsIwESaIwEE[a-z]*;
@@ -882,20 +888,31 @@ GLIBCXX_3.4.11 {
_ZSt20__throw_system_errorPKc;
_ZSt20__throw_system_errori;
- # date_time
- _ZSt15get_system_timev;
-
- _ZNSt11nanoseconds16seconds_per_tickE;
- _ZNSt11nanoseconds16ticks_per_secondE;
- _ZNSt11nanoseconds12is_subsecondE;
-
- _ZNSt11system_time16seconds_per_tickE;
- _ZNSt11system_time16ticks_per_secondE;
- _ZNSt11system_time12is_subsecondE;
-
# char16_t and char32_t
_ZNSt14numeric_limitsIu8char*;
+ # chrono
+ _ZNSt6chrono12system_clock12is_monotonicE;
+ _ZNSt6chrono12system_clock3nowEv;
+
+ # string/wstring initializer_list overloads
+ _ZNSs6appendESt16initializer_listIcE;
+ _ZNSs6assignESt16initializer_listIcE;
+ _ZNSs6insertEN9__gnu_cxx17__normal_iteratorIPcSsEESt16initializer_listIcE;
+ _ZNSs7replaceEN9__gnu_cxx17__normal_iteratorIPcSsEES2_St16initializer_listIcE;
+ _ZNSsC1ESt16initializer_listIcERKSaIcE;
+ _ZNSsC2ESt16initializer_listIcERKSaIcE;
+ _ZNSsaSESt16initializer_listIcE;
+ _ZNSspLESt16initializer_listIcE;
+ _ZNSbIwSt11char_traitsIwESaIwEE6appendESt16initializer_listIwE;
+ _ZNSbIwSt11char_traitsIwESaIwEE6assignESt16initializer_listIwE;
+ _ZNSbIwSt11char_traitsIwESaIwEE6insertEN9__gnu_cxx17__normal_iteratorIPwS2_EESt16initializer_listIwE;
+ _ZNSbIwSt11char_traitsIwESaIwEE7replaceEN9__gnu_cxx17__normal_iteratorIPwS2_EES6_St16initializer_listIwE;
+ _ZNSbIwSt11char_traitsIwESaIwEEC1ESt16initializer_listIwERKS1_;
+ _ZNSbIwSt11char_traitsIwESaIwEEC2ESt16initializer_listIwERKS1_;
+ _ZNSbIwSt11char_traitsIwESaIwEEaSESt16initializer_listIwE;
+ _ZNSbIwSt11char_traitsIwESaIwEEpLESt16initializer_listIwE;
+
} GLIBCXX_3.4.10;
# Symbols in the support library (libsupc++) have their own tag.
@@ -1019,3 +1036,15 @@ CXXABI_1.3.2 {
_ZTIN10__cxxabiv119__foreign_exceptionE;
} CXXABI_1.3.1;
+
+CXXABI_1.3.3 {
+
+ # typeinfo for char16_t and char32_t
+ _ZTIu8char16_t;
+ _ZTIPu8char16_t;
+ _ZTIPKu8char16_t;
+ _ZTIu8char32_t;
+ _ZTIPu8char32_t;
+ _ZTIPKu8char32_t;
+
+} CXXABI_1.3.2;
diff --git a/libstdc++-v3/config/os/gnu-linux/arm-eabi-extra.ver b/libstdc++-v3/config/os/gnu-linux/arm-eabi-extra.ver
new file mode 100644
index 00000000000..5c7dc19e6e0
--- /dev/null
+++ b/libstdc++-v3/config/os/gnu-linux/arm-eabi-extra.ver
@@ -0,0 +1,18 @@
+# Appended to version file.
+
+CXXABI_ARM_1.3.3 {
+ # ARM ABI helper functions provided in libsupc++.
+ __aeabi_atexit;
+ __aeabi_vec_ctor_nocookie_nodtor;
+ __aeabi_vec_ctor_cookie_nodtor;
+ __aeabi_vec_cctor_nocookie_nodtor;
+ __aeabi_vec_new_cookie_noctor;
+ __aeabi_vec_new_nocookie;
+ __aeabi_vec_new_cookie_nodtor;
+ __aeabi_vec_new_cookie;
+ __aeabi_vec_dtor;
+ __aeabi_vec_dtor_cookie;
+ __aeabi_vec_delete;
+ __aeabi_vec_delete3;
+ __aeabi_vec_delete3_nodtor;
+};
diff --git a/libstdc++-v3/configure b/libstdc++-v3/configure
index 5a960cd2561..901a2dc1e4f 100755
--- a/libstdc++-v3/configure
+++ b/libstdc++-v3/configure
@@ -40947,6 +40947,571 @@ _ACEOF
+ # For clock_gettime support.
+
+
+
+
+ ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ ac_save_CXXFLAGS="$CXXFLAGS"
+ CXXFLAGS="$CXXFLAGS -fno-exceptions"
+
+
+for ac_header in unistd.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+else
+ # Is the header compilable?
+echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_header_compiler=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_cxx_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ ac_header_preproc=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_cxx_preproc_warn_flag in
+ yes:no: )
+ { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
+ ;;
+ no:yes:* )
+ { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+ (
+ cat <<\_ASBOX
+## ----------------------------------------- ##
+## Report this to the package-unused lists. ##
+## ----------------------------------------- ##
+_ASBOX
+ ) |
+ sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+esac
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ eval "$as_ac_Header=\$ac_header_preproc"
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+ ac_has_unistd_h=yes
+else
+ ac_has_unistd_h=no
+fi
+
+done
+
+
+ ac_has_clock_monotonic=no;
+ ac_has_clock_realtime=no;
+ if test x"$ac_has_unistd_h" = x"yes"; then
+ echo "$as_me:$LINENO: checking for monotonic clock" >&5
+echo $ECHO_N "checking for monotonic clock... $ECHO_C" >&6
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <unistd.h>
+ #include <time.h>
+
+int
+main ()
+{
+#if _POSIX_TIMERS > 0 && defined(_POSIX_MONOTONIC_CLOCK)
+ timespec tp;
+ #endif
+ clock_gettime(CLOCK_MONOTONIC, &tp);
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_has_clock_monotonic=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_has_clock_monotonic=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+
+ echo "$as_me:$LINENO: result: $ac_has_clock_monotonic" >&5
+echo "${ECHO_T}$ac_has_clock_monotonic" >&6
+
+ echo "$as_me:$LINENO: checking for realtime clock" >&5
+echo $ECHO_N "checking for realtime clock... $ECHO_C" >&6
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <unistd.h>
+ #include <time.h>
+
+int
+main ()
+{
+#if _POSIX_TIMERS > 0
+ timespec tp;
+ #endif
+ clock_gettime(CLOCK_REALTIME, &tp);
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_has_clock_realtime=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_has_clock_realtime=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+
+ echo "$as_me:$LINENO: result: $ac_has_clock_realtime" >&5
+echo "${ECHO_T}$ac_has_clock_realtime" >&6
+ fi
+
+ if test x"$ac_has_clock_monotonic" = x"yes"; then
+
+cat >>confdefs.h <<\_ACEOF
+#define _GLIBCXX_USE_CLOCK_MONOTONIC 1
+_ACEOF
+
+ fi
+
+ if test x"$ac_has_clock_realtime" = x"yes"; then
+
+cat >>confdefs.h <<\_ACEOF
+#define _GLIBCXX_USE_CLOCK_REALTIME 1
+_ACEOF
+
+ fi
+
+ CXXFLAGS="$ac_save_CXXFLAGS"
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+ # For gettimeofday support.
+
+
+
+
+ ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ ac_save_CXXFLAGS="$CXXFLAGS"
+ CXXFLAGS="$CXXFLAGS -fno-exceptions"
+
+ ac_has_gettimeofday=no;
+
+for ac_header in sys/time.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+else
+ # Is the header compilable?
+echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_header_compiler=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_cxx_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ ac_header_preproc=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_cxx_preproc_warn_flag in
+ yes:no: )
+ { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
+ ;;
+ no:yes:* )
+ { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+ (
+ cat <<\_ASBOX
+## ----------------------------------------- ##
+## Report this to the package-unused lists. ##
+## ----------------------------------------- ##
+_ASBOX
+ ) |
+ sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+esac
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ eval "$as_ac_Header=\$ac_header_preproc"
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+ ac_has_sys_time_h=yes
+else
+ ac_has_sys_time_h=no
+fi
+
+done
+
+ if test x"$ac_has_sys_time_h" = x"yes"; then
+ echo "$as_me:$LINENO: checking for gettimeofday" >&5
+echo $ECHO_N "checking for gettimeofday... $ECHO_C" >&6
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <sys/time.h>
+int
+main ()
+{
+timeval tv; gettimeofday(&tv, 0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_has_gettimeofday=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_has_gettimeofday=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+
+ echo "$as_me:$LINENO: result: $ac_has_gettimeofday" >&5
+echo "${ECHO_T}$ac_has_gettimeofday" >&6
+ fi
+
+ if test x"$ac_has_gettimeofday" = x"yes"; then
+
+cat >>confdefs.h <<\_ACEOF
+#define _GLIBCXX_USE_GETTIMEOFDAY 1
+_ACEOF
+
+ fi
+
+ CXXFLAGS="$ac_save_CXXFLAGS"
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
# For TLS support.
# Check whether --enable-tls or --disable-tls was given.
diff --git a/libstdc++-v3/configure.ac b/libstdc++-v3/configure.ac
index 19501aac1be..b23e17714dd 100644
--- a/libstdc++-v3/configure.ac
+++ b/libstdc++-v3/configure.ac
@@ -161,6 +161,12 @@ if $GLIBCXX_IS_NATIVE; then
# For dev/random and dev/urandom for TR1.
GLIBCXX_CHECK_RANDOM_TR1
+ # For clock_gettime support.
+ GLIBCXX_CHECK_CLOCK_GETTIME
+
+ # For gettimeofday support.
+ GLIBCXX_CHECK_GETTIMEOFDAY
+
# For TLS support.
GCC_CHECK_TLS
diff --git a/libstdc++-v3/configure.host b/libstdc++-v3/configure.host
index f2c75db7195..e368a99926d 100644
--- a/libstdc++-v3/configure.host
+++ b/libstdc++-v3/configure.host
@@ -308,6 +308,11 @@ case "${host}" in
abi_baseline_pair=${try_cpu}-linux-gnu
fi
esac
+ case "${host}" in
+ arm*-*-linux-*eabi)
+ port_specific_symbol_files="\$(srcdir)/../config/os/gnu-linux/arm-eabi-extra.ver"
+ ;;
+ esac
;;
powerpc*-*-darwin*)
port_specific_symbol_files="\$(srcdir)/../config/os/bsd/darwin/ppc-extra.ver"
diff --git a/libstdc++-v3/doc/doxygen/doxygroups.cc b/libstdc++-v3/doc/doxygen/doxygroups.cc
index d0adec9e5fb..d94c9e50b3e 100644
--- a/libstdc++-v3/doc/doxygen/doxygroups.cc
+++ b/libstdc++-v3/doc/doxygen/doxygroups.cc
@@ -28,12 +28,15 @@
/** @namespace std::tr1::__detail
* @brief Implementation details not part of the namespace std::tr1 interface.
*/
-/** @namespace std::regex_constants
- * @brief ISO C++ 0x entities sub namespace for regex.
+/** @namespace std::chrono
+ * @brief ISO C++ 0x entities sub namespace for time and date.
*/
/** @namespace std::placeholders
* @brief ISO C++ 0x entities sub namespace for functional.
*/
+/** @namespace std::regex_constants
+ * @brief ISO C++ 0x entities sub namespace for regex.
+*/
/** @namespace std::this_thread
* @brief ISO C++ 0x entities sub namespace for thread.
*/
diff --git a/libstdc++-v3/doc/doxygen/user.cfg.in b/libstdc++-v3/doc/doxygen/user.cfg.in
index 3c59dcbb831..23204850e11 100644
--- a/libstdc++-v3/doc/doxygen/user.cfg.in
+++ b/libstdc++-v3/doc/doxygen/user.cfg.in
@@ -463,13 +463,15 @@ WARN_LOGFILE =
INPUT = @srcdir@/libsupc++/cxxabi.h \
@srcdir@/libsupc++/cxxabi-forced.h \
@srcdir@/libsupc++/exception \
+ @srcdir@/libsupc++/initializer_list \
@srcdir@/libsupc++/new \
@srcdir@/libsupc++/typeinfo \
include/algorithm \
include/array \
include/bitset \
+ include/chrono \
+ include/complex \
include/condition_variable \
- include/date_time \
include/deque \
include/fstream \
include/functional \
@@ -489,6 +491,7 @@ INPUT = @srcdir@/libsupc++/cxxabi.h \
include/ostream \
include/queue \
include/random \
+ include/ratio \
include/regex \
include/set \
include/sstream \
@@ -1167,6 +1170,7 @@ INCLUDE_FILE_PATTERNS =
PREDEFINED = __cplusplus \
__GTHREADS \
+ __GXX_EXPERIMENTAL_CXX0X__ \
"_GLIBCXX_STD_P= " \
"_GLIBCXX_STD_D= " \
_GLIBCXX_STD=std \
@@ -1182,16 +1186,18 @@ PREDEFINED = __cplusplus \
_GLIBCXX_DEPRECATED \
_GLIBCXX_USE_WCHAR_T \
_GLIBCXX_USE_LONG_LONG \
+ _GLIBCXX_USE_C99_STDINT_TR1 \
__glibcxx_function_requires=// \
__glibcxx_class_requires=// \
__glibcxx_class_requires2=// \
__glibcxx_class_requires3=// \
__glibcxx_class_requires4=//
-# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
-# this tag can be used to specify a list of macro names that should be expanded.
-# The macro definition that is found in the sources will be used.
-# Use the PREDEFINED tag if you want to use a different macro definition.
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES
+# then this tag can be used to specify a list of macro names that
+# should be expanded. The macro definition that is found in the
+# sources will be used. Use the PREDEFINED tag if you want to use a
+# different macro definition.
EXPAND_AS_DEFINED =
diff --git a/libstdc++-v3/doc/html/api.html b/libstdc++-v3/doc/html/api.html
index 64bc65ac7df..26bebed1a39 100644
--- a/libstdc++-v3/doc/html/api.html
+++ b/libstdc++-v3/doc/html/api.html
@@ -5,7 +5,7 @@
<a class="ulink" href="http://www.fsf.org/" target="_top">FSF
</a>
- </p></div><div><div class="legalnotice"><a id="id566509"></a><p>
+ </p></div><div><div class="legalnotice"><a id="id344716"></a><p>
<a class="ulink" href="17_intro/license.html" target="_top">License
</a>
</p></div></div></div><hr /></div><p>
diff --git a/libstdc++-v3/doc/html/manual/abi.html b/libstdc++-v3/doc/html/manual/abi.html
index 33050723d6f..bceda223735 100644
--- a/libstdc++-v3/doc/html/manual/abi.html
+++ b/libstdc++-v3/doc/html/manual/abi.html
@@ -436,54 +436,54 @@ gcc test.c -g -O2 -L. -lone -ltwo /usr/lib/libstdc++.so.5 /usr/lib/libstdc++.so.
<a class="ulink" href="http://gcc.gnu.org/PR24660" target="_top">24660: versioning weak symbols in libstdc++</a>
</p><p>
<a class="ulink" href="http://gcc.gnu.org/PR19664" target="_top">19664: libstdc++ headers should have pop/push of the visibility around the declarations</a>
-</p></div><div class="bibliography"><div class="titlepage"><div><div><h3 class="title"><a id="abi.biblio"></a>Bibliography</h3></div></div></div><div class="biblioentry"><a id="id585919"></a><p><span class="title"><i>
+</p></div><div class="bibliography"><div class="titlepage"><div><div><h3 class="title"><a id="abi.biblio"></a>Bibliography</h3></div></div></div><div class="biblioentry"><a id="id473963"></a><p><span class="title"><i>
ABIcheck, a vague idea of checking ABI compatibility
</i>. </span><span class="biblioid">
<a class="ulink" href="http://abicheck.sourceforge.net/" target="_top">
</a>
- . </span></p></div><div class="biblioentry"><a id="id585937"></a><p><span class="title"><i>
+ . </span></p></div><div class="biblioentry"><a id="id473980"></a><p><span class="title"><i>
C++ ABI Reference
</i>. </span><span class="biblioid">
<a class="ulink" href="http://www.codesourcery.com/cxx-abi" target="_top">
</a>
- . </span></p></div><div class="biblioentry"><a id="id585954"></a><p><span class="title"><i>
+ . </span></p></div><div class="biblioentry"><a id="id473998"></a><p><span class="title"><i>
Intel® Compilers for Linux* -Compatibility with the GNU Compilers
</i>. </span><span class="biblioid">
<a class="ulink" href="http://developer.intel.com/software/products/compilers/techtopics/LinuxCompilersCompatibility.htm" target="_top">
</a>
- . </span></p></div><div class="biblioentry"><a id="id585972"></a><p><span class="title"><i>
+ . </span></p></div><div class="biblioentry"><a id="id474016"></a><p><span class="title"><i>
Intel® Compilers for Linux* -Compatibility with the GNU Compilers
</i>. </span><span class="biblioid">
<a class="ulink" href="http://developer.intel.com/software/products/compilers/techtopics/LinuxCompilersCompatibility.htm" target="_top">
</a>
- . </span></p></div><div class="biblioentry"><a id="id585990"></a><p><span class="title"><i>
+ . </span></p></div><div class="biblioentry"><a id="id369651"></a><p><span class="title"><i>
Sun Solaris 2.9 : Linker and Libraries Guide (document 816-1386)
</i>. </span><span class="biblioid">
<a class="ulink" href="http://docs.sun.com/?p=/doc/816-1386&amp;a=load" target="_top">
</a>
- . </span></p></div><div class="biblioentry"><a id="id586006"></a><p><span class="title"><i>
+ . </span></p></div><div class="biblioentry"><a id="id369667"></a><p><span class="title"><i>
Sun Solaris 2.9 : C++ Migration Guide (document 816-2459)
</i>. </span><span class="biblioid">
<a class="ulink" href="http://docs.sun.com/db/prod/solaris.9" target="_top">
</a>
- . </span></p></div><div class="biblioentry"><a id="id586024"></a><p><span class="title"><i>
+ . </span></p></div><div class="biblioentry"><a id="id369685"></a><p><span class="title"><i>
ELF Symbol Versioning
</i>. </span><span class="author"><span class="firstname">Ulrich</span> <span class="surname">Drepper</span>. </span><span class="biblioid">
<a class="ulink" href="http://people.redhat.com/drepper/symbol-versioning" target="_top">
</a>
- . </span></p></div><div class="biblioentry"><a id="id586052"></a><p><span class="title"><i>
+ . </span></p></div><div class="biblioentry"><a id="id369713"></a><p><span class="title"><i>
C++ ABI for the ARM Architecture
</i>. </span><span class="biblioid">
<a class="ulink" href="http://www.arm.com/miscPDFs/8033.pdf" target="_top">
</a>
- . </span></p></div><div class="biblioentry"><a id="id586069"></a><p><span class="title"><i>
+ . </span></p></div><div class="biblioentry"><a id="id369730"></a><p><span class="title"><i>
Dynamic Shared Objects: Survey and Issues
</i>. </span><span class="subtitle">
ISO C++ J16/06-0046
. </span><span class="author"><span class="firstname">Benjamin</span> <span class="surname">Kosnik</span>. </span><span class="biblioid">
<a class="ulink" href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1976.html" target="_top">
</a>
- . </span></p></div><div class="biblioentry"><a id="id586102"></a><p><span class="title"><i>
+ . </span></p></div><div class="biblioentry"><a id="id369763"></a><p><span class="title"><i>
Versioning With Namespaces
</i>. </span><span class="subtitle">
ISO C++ J16/06-0083
diff --git a/libstdc++-v3/doc/html/manual/api.html b/libstdc++-v3/doc/html/manual/api.html
index 7e5fc59faaf..4b093b1cbf4 100644
--- a/libstdc++-v3/doc/html/manual/api.html
+++ b/libstdc++-v3/doc/html/manual/api.html
@@ -72,11 +72,11 @@ _Alloc_traits</code> have been removed.
<span class="type">__alloc</span> to select an underlying allocator that
satisfied memory allocation requests. The selection of this
underlying allocator was not user-configurable.
- </p><div class="table"><a id="id586703"></a><p class="title"><b>Table B.1. Extension Allocators</b></p><div class="table-contents"><table summary="Extension Allocators" border="1"><colgroup><col align="left" /><col align="left" /><col align="left" /><col align="left" /></colgroup><thead><tr><th align="left">Allocator (3.4)</th><th align="left">Header (3.4)</th><th align="left">Allocator (3.[0-3])</th><th align="left">Header (3.[0-3])</th></tr></thead><tbody><tr><td align="left"><code class="classname">__gnu_cxx::new_allocator&lt;T&gt;</code></td><td align="left"><code class="filename">ext/new_allocator.h</code></td><td align="left"><code class="classname">std::__new_alloc</code></td><td align="left"><code class="filename">memory</code></td></tr><tr><td align="left"><code class="classname">__gnu_cxx::malloc_allocator&lt;T&gt;</code></td><td align="left"><code class="filename">ext/malloc_allocator.h</code></td><td align="left"><code class="classname">std::__malloc_alloc_template&lt;int&gt;</code></td><td align="left"><code class="filename">memory</code></td></tr><tr><td align="left"><code class="classname">__gnu_cxx::debug_allocator&lt;T&gt;</code></td><td align="left"><code class="filename">ext/debug_allocator.h</code></td><td align="left"><code class="classname">std::debug_alloc&lt;T&gt;</code></td><td align="left"><code class="filename">memory</code></td></tr><tr><td align="left"><code class="classname">__gnu_cxx::__pool_alloc&lt;T&gt;</code></td><td align="left"><code class="filename">ext/pool_allocator.h</code></td><td align="left"><code class="classname">std::__default_alloc_template&lt;bool,int&gt;</code></td><td align="left"><code class="filename">memory</code></td></tr><tr><td align="left"><code class="classname">__gnu_cxx::__mt_alloc&lt;T&gt;</code></td><td align="left"><code class="filename">ext/mt_allocator.h</code></td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left"><code class="classname">__gnu_cxx::bitmap_allocator&lt;T&gt;</code></td><td align="left"><code class="filename">ext/bitmap_allocator.h</code></td><td align="left"> </td><td align="left"> </td></tr></tbody></table></div></div><br class="table-break" /><p> Releases after gcc-3.4 have continued to add to the collection
+ </p><div class="table"><a id="id418406"></a><p class="title"><b>Table B.1. Extension Allocators</b></p><div class="table-contents"><table summary="Extension Allocators" border="1"><colgroup><col align="left" /><col align="left" /><col align="left" /><col align="left" /></colgroup><thead><tr><th align="left">Allocator (3.4)</th><th align="left">Header (3.4)</th><th align="left">Allocator (3.[0-3])</th><th align="left">Header (3.[0-3])</th></tr></thead><tbody><tr><td align="left"><code class="classname">__gnu_cxx::new_allocator&lt;T&gt;</code></td><td align="left"><code class="filename">ext/new_allocator.h</code></td><td align="left"><code class="classname">std::__new_alloc</code></td><td align="left"><code class="filename">memory</code></td></tr><tr><td align="left"><code class="classname">__gnu_cxx::malloc_allocator&lt;T&gt;</code></td><td align="left"><code class="filename">ext/malloc_allocator.h</code></td><td align="left"><code class="classname">std::__malloc_alloc_template&lt;int&gt;</code></td><td align="left"><code class="filename">memory</code></td></tr><tr><td align="left"><code class="classname">__gnu_cxx::debug_allocator&lt;T&gt;</code></td><td align="left"><code class="filename">ext/debug_allocator.h</code></td><td align="left"><code class="classname">std::debug_alloc&lt;T&gt;</code></td><td align="left"><code class="filename">memory</code></td></tr><tr><td align="left"><code class="classname">__gnu_cxx::__pool_alloc&lt;T&gt;</code></td><td align="left"><code class="filename">ext/pool_allocator.h</code></td><td align="left"><code class="classname">std::__default_alloc_template&lt;bool,int&gt;</code></td><td align="left"><code class="filename">memory</code></td></tr><tr><td align="left"><code class="classname">__gnu_cxx::__mt_alloc&lt;T&gt;</code></td><td align="left"><code class="filename">ext/mt_allocator.h</code></td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left"><code class="classname">__gnu_cxx::bitmap_allocator&lt;T&gt;</code></td><td align="left"><code class="filename">ext/bitmap_allocator.h</code></td><td align="left"> </td><td align="left"> </td></tr></tbody></table></div></div><br class="table-break" /><p> Releases after gcc-3.4 have continued to add to the collection
of available allocators. All of these new allocators are
standard-style. The following table includes details, along with
the first released version of GCC that included the extension allocator.
- </p><div class="table"><a id="id596348"></a><p class="title"><b>Table B.2. Extension Allocators Continued</b></p><div class="table-contents"><table summary="Extension Allocators Continued" border="1"><colgroup><col align="left" /><col align="left" /><col align="left" /></colgroup><thead><tr><th align="left">Allocator</th><th align="left">Include</th><th align="left">Version</th></tr></thead><tbody><tr><td align="left"><code class="classname">__gnu_cxx::array_allocator&lt;T&gt;</code></td><td align="left"><code class="filename">ext/array_allocator.h</code></td><td align="left">4.0.0</td></tr><tr><td align="left"><code class="classname">__gnu_cxx::throw_allocator&lt;T&gt;</code></td><td align="left"><code class="filename">ext/throw_allocator.h</code></td><td align="left">4.2.0</td></tr></tbody></table></div></div><br class="table-break" /><p>
+ </p><div class="table"><a id="id476738"></a><p class="title"><b>Table B.2. Extension Allocators Continued</b></p><div class="table-contents"><table summary="Extension Allocators Continued" border="1"><colgroup><col align="left" /><col align="left" /><col align="left" /></colgroup><thead><tr><th align="left">Allocator</th><th align="left">Include</th><th align="left">Version</th></tr></thead><tbody><tr><td align="left"><code class="classname">__gnu_cxx::array_allocator&lt;T&gt;</code></td><td align="left"><code class="filename">ext/array_allocator.h</code></td><td align="left">4.0.0</td></tr><tr><td align="left"><code class="classname">__gnu_cxx::throw_allocator&lt;T&gt;</code></td><td align="left"><code class="filename">ext/throw_allocator.h</code></td><td align="left">4.2.0</td></tr></tbody></table></div></div><br class="table-break" /><p>
Debug mode first appears.
</p><p>
Precompiled header support <acronym class="acronym">PCH</acronym> support.
diff --git a/libstdc++-v3/doc/html/manual/backwards.html b/libstdc++-v3/doc/html/manual/backwards.html
index a124e09bae0..4e7f6e33c98 100644
--- a/libstdc++-v3/doc/html/manual/backwards.html
+++ b/libstdc++-v3/doc/html/manual/backwards.html
@@ -14,8 +14,8 @@ ISO Standard (e.g., statistical analysis). While there are a lot of
really useful things that are used by a lot of people, the Standards
Committee couldn't include everything, and so a lot of those
“<span class="quote">obvious</span>” classes didn't get included.
-</p><p>Known Issues include many of the limitations of its immediate ancestor.</p><p>Portability notes and known implementation limitations are as follows.</p><div class="sect3" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="id587031"></a>No <code class="code">ios_base</code></h4></div></div></div><p> At least some older implementations don't have <code class="code">std::ios_base</code>, so you should use <code class="code">std::ios::badbit</code>, <code class="code">std::ios::failbit</code> and <code class="code">std::ios::eofbit</code> and <code class="code">std::ios::goodbit</code>.
-</p></div><div class="sect3" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="id587063"></a>No <code class="code">cout</code> in <code class="code">ostream.h</code>, no <code class="code">cin</code> in <code class="code">istream.h</code></h4></div></div></div><p>
+</p><p>Known Issues include many of the limitations of its immediate ancestor.</p><p>Portability notes and known implementation limitations are as follows.</p><div class="sect3" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="id442299"></a>No <code class="code">ios_base</code></h4></div></div></div><p> At least some older implementations don't have <code class="code">std::ios_base</code>, so you should use <code class="code">std::ios::badbit</code>, <code class="code">std::ios::failbit</code> and <code class="code">std::ios::eofbit</code> and <code class="code">std::ios::goodbit</code>.
+</p></div><div class="sect3" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="id442331"></a>No <code class="code">cout</code> in <code class="code">ostream.h</code>, no <code class="code">cin</code> in <code class="code">istream.h</code></h4></div></div></div><p>
In earlier versions of the standard,
<code class="filename">fstream.h</code>,
<code class="filename">ostream.h</code>
@@ -41,7 +41,7 @@ considered replaced and rewritten.
archived. The code is considered replaced and rewritten.
</p><p>
Portability notes and known implementation limitations are as follows.
-</p><div class="sect3" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="id596996"></a>Namespace <code class="code">std::</code> not supported</h4></div></div></div><p>
+</p><div class="sect3" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="id386246"></a>Namespace <code class="code">std::</code> not supported</h4></div></div></div><p>
Some care is required to support C++ compiler and or library
implementation that do not have the standard library in
<code class="code">namespace std</code>.
@@ -105,7 +105,7 @@ AC_DEFUN([AC_CXX_NAMESPACE_STD], [
AC_DEFINE(HAVE_NAMESPACE_STD,,[Define if g++ supports namespace std. ])
fi
])
-</pre></div><div class="sect3" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="id597119"></a>Illegal iterator usage</h4></div></div></div><p>
+</pre></div><div class="sect3" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="id386369"></a>Illegal iterator usage</h4></div></div></div><p>
The following illustrate implementation-allowed illegal iterator
use, and then correct use.
</p><div class="itemizedlist"><ul type="disc"><li><p>
@@ -118,7 +118,7 @@ AC_DEFUN([AC_CXX_NAMESPACE_STD], [
</p></li><li><p>
<code class="code">if (iterator)</code> won't work any more =&gt; use
<code class="code">if (iterator != iterator_type())</code>
- </p></li></ul></div></div><div class="sect3" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="id597180"></a><code class="code">isspace</code> from <code class="filename">cctype</code> is a macro
+ </p></li></ul></div></div><div class="sect3" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="id386430"></a><code class="code">isspace</code> from <code class="filename">cctype</code> is a macro
</h4></div></div></div><p>
Glibc 2.0.x and 2.1.x define <code class="filename">ctype.h</code> functionality as macros
(isspace, isalpha etc.).
@@ -151,7 +151,7 @@ std:: (__ctype_b[(int) ( ( 'X' ) )] &amp; (unsigned short int) _ISspace ) ;
(<code class="filename">ctype.h</code>) and the
definitions in namespace <code class="code">std::</code>
(<code class="code">&lt;cctype&gt;</code>).
-</p></div><div class="sect3" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="id597274"></a>No <code class="code">vector::at</code>, <code class="code">deque::at</code>, <code class="code">string::at</code></h4></div></div></div><p>
+</p></div><div class="sect3" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="id496113"></a>No <code class="code">vector::at</code>, <code class="code">deque::at</code>, <code class="code">string::at</code></h4></div></div></div><p>
One solution is to add an autoconf-test for this:
</p><pre class="programlisting">
AC_MSG_CHECKING(for container::at)
@@ -177,7 +177,7 @@ AC_DEFINE(HAVE_CONTAINER_AT)],
</pre><p>
If you are using other (non-GNU) compilers it might be a good idea
to check for <code class="code">string::at</code> separately.
-</p></div><div class="sect3" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="id564872"></a>No <code class="code">std::char_traits&lt;char&gt;::eof</code></h4></div></div></div><p>
+</p></div><div class="sect3" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="id496151"></a>No <code class="code">std::char_traits&lt;char&gt;::eof</code></h4></div></div></div><p>
Use some kind of autoconf test, plus this:
</p><pre class="programlisting">
#ifdef HAVE_CHAR_TRAITS
@@ -185,7 +185,7 @@ AC_DEFINE(HAVE_CONTAINER_AT)],
#else
#define CPP_EOF EOF
#endif
-</pre></div><div class="sect3" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="id564890"></a>No <code class="code">string::clear</code></h4></div></div></div><p>
+</pre></div><div class="sect3" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="id496169"></a>No <code class="code">string::clear</code></h4></div></div></div><p>
There are two functions for deleting the contents of a string:
<code class="code">clear</code> and <code class="code">erase</code> (the latter returns the
string).
@@ -203,12 +203,12 @@ erase(size_type __pos = 0, size_type __n = npos)
Unfortunately, <code class="code">clear</code> is not implemented in this
version, so you should use <code class="code">erase</code> (which is probably
faster than <code class="code">operator=(charT*)</code>).
-</p></div><div class="sect3" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="id564936"></a>
+</p></div><div class="sect3" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="id496214"></a>
Removal of <code class="code">ostream::form</code> and <code class="code">istream::scan</code>
extensions
</h4></div></div></div><p>
These are no longer supported. Please use stringstreams instead.
-</p></div><div class="sect3" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="id564955"></a>No <code class="code">basic_stringbuf</code>, <code class="code">basic_stringstream</code></h4></div></div></div><p>
+</p></div><div class="sect3" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="id496234"></a>No <code class="code">basic_stringbuf</code>, <code class="code">basic_stringstream</code></h4></div></div></div><p>
Although the ISO standard <code class="code">i/ostringstream</code>-classes are
provided, (<code class="filename">sstream</code>), for
compatibility with older implementations the pre-ISO
@@ -296,14 +296,14 @@ any = temp;
Another example of using stringstreams is in <a class="link" href="bk01pt05ch13s05.html" title="Shrink to Fit">this howto</a>.
</p><p> There is additional information in the libstdc++-v2 info files, in
particular “<span class="quote">info iostream</span>”.
-</p></div><div class="sect3" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="id565107"></a>Little or no wide character support</h4></div></div></div><p>
+</p></div><div class="sect3" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="id496386"></a>Little or no wide character support</h4></div></div></div><p>
Classes <code class="classname">wstring</code> and
<code class="classname">char_traits&lt;wchar_t&gt;</code> are
not supported.
- </p></div><div class="sect3" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="id565126"></a>No templatized iostreams</h4></div></div></div><p>
+ </p></div><div class="sect3" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="id364967"></a>No templatized iostreams</h4></div></div></div><p>
Classes <code class="classname">wfilebuf</code> and
<code class="classname">wstringstream</code> are not supported.
- </p></div><div class="sect3" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="id565145"></a>Thread safety issues</h4></div></div></div><p>
+ </p></div><div class="sect3" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="id364986"></a>Thread safety issues</h4></div></div></div><p>
Earlier GCC releases had a somewhat different approach to
threading configuration and proper compilation. Before GCC 3.0,
configuration of the threading model was dictated by compiler
@@ -361,7 +361,7 @@ libstdc++-v3.
of the SGI STL (version 3.3), with extensive changes.
</p><p>A more formal description of the V3 goals can be found in the
official <a class="ulink" href="../17_intro/DESIGN" target="_top">design document</a>.
- </p><p>Portability notes and known implementation limitations are as follows.</p><div class="sect3" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="id593953"></a>Pre-ISO headers moved to backwards or removed</h4></div></div></div><p> The pre-ISO C++ headers
+ </p><p>Portability notes and known implementation limitations are as follows.</p><div class="sect3" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="id365104"></a>Pre-ISO headers moved to backwards or removed</h4></div></div></div><p> The pre-ISO C++ headers
(<code class="code">iostream.h</code>, <code class="code">defalloc.h</code> etc.) are
available, unlike previous libstdc++ versions, but inclusion
generates a warning that you are using deprecated headers.
@@ -433,7 +433,7 @@ like <code class="filename">vector.h</code> can be replaced with <code class="fi
directive <code class="code">using namespace std;</code> can be put at the global
scope. This should be enough to get this code compiling, assuming the
other usage is correct.
-</p></div><div class="sect3" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="id594036"></a>Extension headers hash_map, hash_set moved to ext or backwards</h4></div></div></div><p>At this time most of the features of the SGI STL extension have been
+</p></div><div class="sect3" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="id365186"></a>Extension headers hash_map, hash_set moved to ext or backwards</h4></div></div></div><p>At this time most of the features of the SGI STL extension have been
replaced by standardized libraries.
In particular, the unordered_map and unordered_set containers of TR1
are suitable replacement for the non-standard hash_map and hash_set
@@ -505,7 +505,7 @@ AC_DEFUN([AC_HEADER_EXT_HASH_SET], [
AC_DEFINE(HAVE_EXT_HASH_SET,,[Define if ext/hash_set is present. ])
fi
])
-</pre></div><div class="sect3" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="id594138"></a>No <code class="code">ios::nocreate/ios::noreplace</code>.
+</pre></div><div class="sect3" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="id363795"></a>No <code class="code">ios::nocreate/ios::noreplace</code>.
</h4></div></div></div><p> The existence of <code class="code">ios::nocreate</code> being used for
input-streams has been confirmed, most probably because the author
thought it would be more correct to specify nocreate explicitly. So
@@ -516,7 +516,7 @@ open the file for reading, check if it has been opened, and then
decide whether you want to create/replace or not. To my knowledge,
even older implementations support <code class="code">app</code>, <code class="code">ate</code>
and <code class="code">trunc</code> (except for <code class="code">app</code> ?).
-</p></div><div class="sect3" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="id594186"></a>
+</p></div><div class="sect3" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="id363843"></a>
No <code class="code">stream::attach(int fd)</code>
</h4></div></div></div><p>
Phil Edwards writes: It was considered and rejected for the ISO
@@ -539,7 +539,7 @@ No <code class="code">stream::attach(int fd)</code>
For another example of this, refer to
<a class="ulink" href="http://www.josuttis.com/cppcode/fdstream.html" target="_top">fdstream example</a>
by Nicolai Josuttis.
-</p></div><div class="sect3" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="id677873"></a>
+</p></div><div class="sect3" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="id363907"></a>
Support for C++98 dialect.
</h4></div></div></div><p>Check for complete library coverage of the C++1998/2003 standard.
</p><pre class="programlisting">
@@ -607,7 +607,7 @@ AC_DEFUN([AC_HEADER_STDCXX_98], [
AC_DEFINE(STDCXX_98_HEADERS,,[Define if ISO C++ 1998 header files are present. ])
fi
])
-</pre></div><div class="sect3" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="id677900"></a>
+</pre></div><div class="sect3" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="id363935"></a>
Support for C++TR1 dialect.
</h4></div></div></div><p>Check for library coverage of the TR1 standard.
</p><pre class="programlisting">
@@ -684,7 +684,7 @@ AC_DEFUN([AC_HEADER_TR1_UNORDERED_SET], [
AC_DEFINE(HAVE_TR1_UNORDERED_SET,,[Define if tr1/unordered_set is present. ])
fi
])
-</pre></div><div class="sect3" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="id677944"></a>
+</pre></div><div class="sect3" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="id363978"></a>
Support for C++0x dialect.
</h4></div></div></div><p>Check for baseline language coverage in the compiler for the C++0xstandard.
</p><pre class="programlisting">
@@ -896,27 +896,27 @@ AC_DEFUN([AC_HEADER_UNORDERED_SET], [
AC_DEFINE(HAVE_UNORDERED_SET,,[Define if unordered_set is present. ])
fi
])
-</pre></div><div class="sect3" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="id678022"></a>
+</pre></div><div class="sect3" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="id364056"></a>
Container::iterator_type is not necessarily Container::value_type*
</h4></div></div></div><p>
This is a change in behavior from the previous version. Now, most
<span class="type">iterator_type</span> typedefs in container classes are POD
objects, not <span class="type">value_type</span> pointers.
-</p></div></div><div class="bibliography"><div class="titlepage"><div><div><h3 class="title"><a id="backwards.biblio"></a>Bibliography</h3></div></div></div><div class="biblioentry"><a id="id678053"></a><p>[<abbr class="abbrev">
+</p></div></div><div class="bibliography"><div class="titlepage"><div><div><h3 class="title"><a id="backwards.biblio"></a>Bibliography</h3></div></div></div><div class="biblioentry"><a id="id364087"></a><p>[<abbr class="abbrev">
kegel41
</abbr>] <span class="title"><i>
Migrating to GCC 4.1
</i>. </span><span class="author"><span class="firstname">Dan</span> <span class="surname">Kegel</span>. </span><span class="biblioid">
<a class="ulink" href="http://www.kegel.com/gcc/gcc4.html" target="_top">
</a>
- . </span></p></div><div class="biblioentry"><a id="id678085"></a><p>[<abbr class="abbrev">
+ . </span></p></div><div class="biblioentry"><a id="id374201"></a><p>[<abbr class="abbrev">
kegel41
</abbr>] <span class="title"><i>
Building the Whole Debian Archive with GCC 4.1: A Summary
</i>. </span><span class="author"><span class="firstname">Martin</span> <span class="surname">Michlmayr</span>. </span><span class="biblioid">
<a class="ulink" href="http://lists.debian.org/debian-gcc/2006/03/msg00405.html" target="_top">
</a>
- . </span></p></div><div class="biblioentry"><a id="id678118"></a><p>[<abbr class="abbrev">
+ . </span></p></div><div class="biblioentry"><a id="id374234"></a><p>[<abbr class="abbrev">
lbl32
</abbr>] <span class="title"><i>
Migration guide for GCC-3.2
diff --git a/libstdc++-v3/doc/html/manual/bitmap_allocator.html b/libstdc++-v3/doc/html/manual/bitmap_allocator.html
index fdaed21319d..5e6458dcd29 100644
--- a/libstdc++-v3/doc/html/manual/bitmap_allocator.html
+++ b/libstdc++-v3/doc/html/manual/bitmap_allocator.html
@@ -103,7 +103,7 @@ else return false.</p></li></ol></div><p>
</p><p>
Consider a block of size 64 ints. In memory, it would look like this:
(assume a 32-bit system where, size_t is a 32-bit entity).
- </p><div class="table"><a id="id570814"></a><p class="title"><b>Table 32.1. Bitmap Allocator Memory Map</b></p><div class="table-contents"><table summary="Bitmap Allocator Memory Map" border="1"><colgroup><col align="left" /><col align="left" /><col align="left" /><col align="left" /><col align="left" /></colgroup><tbody><tr><td align="left">268</td><td align="left">0</td><td align="left">4294967295</td><td align="left">4294967295</td><td align="left">Data -&gt; Space for 64 ints</td></tr></tbody></table></div></div><br class="table-break" /><p>
+ </p><div class="table"><a id="id390307"></a><p class="title"><b>Table 32.1. Bitmap Allocator Memory Map</b></p><div class="table-contents"><table summary="Bitmap Allocator Memory Map" border="1"><colgroup><col align="left" /><col align="left" /><col align="left" /><col align="left" /><col align="left" /></colgroup><tbody><tr><td align="left">268</td><td align="left">0</td><td align="left">4294967295</td><td align="left">4294967295</td><td align="left">Data -&gt; Space for 64 ints</td></tr></tbody></table></div></div><br class="table-break" /><p>
The first Column(268) represents the size of the Block in bytes as
seen by the Bitmap Allocator. Internally, a global free list is
used to keep track of the free blocks used and given back by the
diff --git a/libstdc++-v3/doc/html/manual/bk01pt01ch01.html b/libstdc++-v3/doc/html/manual/bk01pt01ch01.html
index 23f4da4f4d3..688f019c03a 100644
--- a/libstdc++-v3/doc/html/manual/bk01pt01ch01.html
+++ b/libstdc++-v3/doc/html/manual/bk01pt01ch01.html
@@ -6101,7 +6101,7 @@ In this implementation the header names are prefixed by
</p><p>
This page describes the TR1 support in mainline GCC SVN, not in any particular
release.
-</p><div class="table"><a id="id619193"></a><p class="title"><b>Table 1.1. C++ TR1 Implementation Status</b></p><div class="table-contents"><table summary="C++ TR1 Implementation Status" border="1"><colgroup><col align="left" /><col align="left" /><col align="left" /><col align="left" /><col align="left" /><col align="left" /></colgroup><thead><tr><th align="left">Section</th><th align="left">Description</th><th align="left">Done</th><th align="left">Broken</th><th align="left">Missing</th><th align="left">Comments</th></tr></thead><tbody><tr><td align="left"><span class="emphasis"><em>2</em></span></td><td colspan="5" align="left"><span class="emphasis"><em>General Utilities</em></span></td></tr><tr><td align="left">2.1</td><td align="left">Reference wrappers</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">2.1.1</td><td align="left">Additions to header <code class="code">&lt;functional&gt;</code> synopsis</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">2.1.2</td><td align="left">Class template <code class="code">reference_wrapper</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">2.1.2.1</td><td align="left"><code class="code">reference_wrapper</code> construct/copy/destroy</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">2.1.2.2</td><td align="left"><code class="code">reference_wrapper</code> assignment</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">2.1.2.3</td><td align="left"><code class="code">reference_wrapper</code> access</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">2.1.2.4</td><td align="left"><code class="code">reference_wrapper</code> invocation</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">2.1.2.5</td><td align="left"><code class="code">reference_wrapper</code> helper functions</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">2.2</td><td align="left">Smart pointers</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">2.2.1</td><td align="left">Additions to header <code class="code">&lt;memory&gt;</code> synopsis</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">2.2.2</td><td align="left">Class <code class="code">bad_weak_ptr</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">2.2.3</td><td align="left">Class template <code class="code">shared_ptr</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left">See Footnotes</td></tr><tr><td align="left">2.2.3.1</td><td align="left"><code class="code">shared_ptr</code> constructors</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">2.2.3.2</td><td align="left"><code class="code">shared_ptr</code> destructor</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">2.2.3.3</td><td align="left"><code class="code">shared_ptr</code> assignment</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">2.2.3.4</td><td align="left"><code class="code">shared_ptr</code> modifiers</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">2.2.3.5</td><td align="left"><code class="code">shared_ptr</code> observers</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">2.2.3.6</td><td align="left"><code class="code">shared_ptr</code> comparison</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">2.2.3.7</td><td align="left"><code class="code">shared_ptr</code> I/O</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">2.2.3.8</td><td align="left"><code class="code">shared_ptr</code> specialized algorithms</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">2.2.3.9</td><td align="left"><code class="code">shared_ptr</code> casts</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">2.2.3.10</td><td align="left"><code class="code">get_deleter</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">2.2.4</td><td align="left">Class template <code class="code">weak_ptr</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">2.2.4.1</td><td align="left"><code class="code">weak_ptr</code> constructors</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">2.2.4.2</td><td align="left"><code class="code">weak_ptr</code> destructor</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">2.2.4.3</td><td align="left"><code class="code">weak_ptr</code> assignment</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">2.2.4.4</td><td align="left"><code class="code">weak_ptr</code> modifiers</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">2.2.4.5</td><td align="left"><code class="code">weak_ptr</code> observers</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">2.2.4.6</td><td align="left"><code class="code">weak_ptr</code> comparison</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">2.2.4.7</td><td align="left"><code class="code">weak_ptr</code> specialized algorithms</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">2.2.5</td><td align="left">Class template <code class="code">enable_shared_from_this</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left"><span class="emphasis"><em>3</em></span></td><td colspan="5" align="left"><span class="emphasis"><em>Function Objects</em></span></td></tr><tr><td align="left">3.1</td><td align="left">Definitions</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">3.2</td><td align="left">Additions to <code class="code">&lt;functional&gt; synopsis</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">3.3</td><td align="left">Requirements</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">3.4</td><td align="left">Function return types</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">3.5</td><td align="left">Function template <code class="code">mem_fn</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">3.6</td><td align="left">Function object binders</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">3.6.1</td><td align="left">Class template <code class="code">is_bind_expression</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">3.6.2</td><td align="left">Class template <code class="code">is_placeholder</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">3.6.3</td><td align="left">Function template <code class="code">bind</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">3.6.4</td><td align="left">Placeholders</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">3.7</td><td align="left">Polymorphic function wrappers</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">3.7.1</td><td align="left">Class <code class="code">bad_function_call<code class="code"></code></code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">3.7.1.1</td><td align="left"><code class="code">bad_function_call</code> constructor</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">3.7.2</td><td align="left">Class template <code class="code">function</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">3.7.2.1</td><td align="left"><code class="code">function</code> construct/copy/destroy</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">3.7.2.2</td><td align="left"><code class="code">function</code> modifiers</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">3.7.2.3</td><td align="left"><code class="code">function</code> capacity</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">3.7.2.4</td><td align="left"><code class="code">function</code> invocation</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">3.7.2.5</td><td align="left"><code class="code">function</code> target access</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">3.7.2.6</td><td align="left">undefined operators</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">3.7.2.7</td><td align="left">null pointer comparison operators</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">3.7.2.8</td><td align="left">specialized algorithms</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left"><span class="emphasis"><em>4</em></span></td><td colspan="5" align="left"><span class="emphasis"><em>Metaprogramming and type traits</em></span></td></tr><tr><td align="left">4.1</td><td align="left">Requirements</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">4.2</td><td align="left">Header <code class="code">&lt;type_traits&gt;</code> synopsis</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">4.3</td><td align="left">Helper classes</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">4.4</td><td align="left">General Requirements</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">4.5</td><td align="left">Unary Type Traits</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">4.5.1</td><td align="left">Primary Type Categories</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">4.5.2</td><td align="left">Composite type traits</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">4.5.3</td><td align="left">Type properties</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">4.6</td><td align="left">Relationships between types</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">4.7</td><td align="left">Transformations between types</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">4.7.1</td><td align="left">Const-volatile modifications</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">4.7.2</td><td align="left">Reference modifications</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">4.7.3</td><td align="left">Array modifications</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">4.7.4</td><td align="left">Pointer modifications</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">4.8</td><td align="left">Other transformations</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">4.9</td><td align="left">Implementation requirements</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left"><span class="emphasis"><em>5</em></span></td><td colspan="5" align="left"><span class="emphasis"><em>Numerical Facilities</em></span></td></tr><tr><td align="left">5.1</td><td align="left">Random number generation</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.1.1</td><td align="left">Requirements</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.1.2</td><td align="left">Header <code class="code">&lt;random&gt;</code> synopsis</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.1.3</td><td align="left">Class template <code class="code">variate_generator</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.1.4</td><td align="left">Random number engine class templates</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.1.4.1</td><td align="left">Class template <code class="code">linear_congruential</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.1.4.2</td><td align="left">Class template <code class="code">mersenne_twister</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.1.4.3</td><td align="left">Class template <code class="code">subtract_with_carry</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.1.4.4</td><td align="left">Class template <code class="code">subtract_with_carry_01</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.1.4.5</td><td align="left">Class template <code class="code">discard_block</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.1.4.6</td><td align="left">Class template <code class="code">xor_combine</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left">operator()() per N2079</td></tr><tr><td align="left">5.1.5</td><td align="left">Engines with predefined parameters</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.1.6</td><td align="left">Class <code class="code">random_device</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.1.7</td><td align="left">Random distribution class templates</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.1.7.1</td><td align="left">Class template <code class="code">uniform_int</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.1.7.2</td><td align="left">Class <code class="code">bernoulli_distribution</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.1.7.3</td><td align="left">Class template <code class="code">geometric_distribution</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.1.7.4</td><td align="left">Class template <code class="code">poisson_distribution</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.1.7.5</td><td align="left">Class template <code class="code">binomial_distribution</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.1.7.6</td><td align="left">Class template <code class="code">uniform_real</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.1.7.7</td><td align="left">Class template <code class="code">exponential_distribution</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.1.7.8</td><td align="left">Class template <code class="code">normal_distribution</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.1.7.9</td><td align="left">Class template <code class="code">gamma_distribution</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.2</td><td align="left">Mathematical special functions</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.2.1</td><td align="left">Additions to header <code class="code">&lt;cmath&gt;</code> synopsis</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.2.1.1</td><td align="left">associated Laguerre polynomials</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.2.1.2</td><td align="left">associated Legendre functions</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.2.1.3</td><td align="left">beta function</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.2.1.4</td><td align="left">(complete) elliptic integral of the first kind</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.2.1.5</td><td align="left">(complete) elliptic integral of the second kind</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.2.1.6</td><td align="left">(complete) elliptic integral of the third kind</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.2.1.7</td><td align="left">confluent hypergeometric functions</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.2.1.8</td><td align="left">regular modified cylindrical Bessel functions</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.2.1.9</td><td align="left">cylindrical Bessel functions (of the first kind)</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.2.1.10</td><td align="left">irregular modified cylindrical Bessel functions</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.2.1.11</td><td align="left">cylindrical Neumann functions</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.2.1.12</td><td align="left">(incomplete) elliptic integral of the first kind</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.2.1.13</td><td align="left">(incomplete) elliptic integral of the second kind</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.2.1.14</td><td align="left">(incomplete) elliptic integral of the third kind</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.2.1.15</td><td align="left">exponential integral</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.2.1.16</td><td align="left">Hermite polynomials</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.2.1.17</td><td align="left">hypergeometric functions</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.2.1.18</td><td align="left">Laguerre polynomials</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.2.1.19</td><td align="left">Legendre polynomials</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.2.1.20</td><td align="left">Riemann zeta function</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.2.1.21</td><td align="left">spherical Bessel functions (of the first kind)</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.2.1.22</td><td align="left">spherical associated Legendre functions</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.2.1.23</td><td align="left">spherical Neumann functions</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.2.2</td><td align="left">Additions to header <code class="code">&lt;math.h&gt;</code> synopsis</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left"><span class="emphasis"><em>6</em></span></td><td colspan="5" align="left"><span class="emphasis"><em>Containers</em></span></td></tr><tr><td align="left">6.1</td><td align="left">Tuple types</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">6.1.1</td><td align="left">Header <code class="code">&lt;tuple&gt;</code> synopsis</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">6.1.2</td><td align="left">Additions to header <code class="code">&lt;utility&gt;</code> synopsis</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">6.1.3</td><td align="left">Class template <code class="code">tuple</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">6.1.3.1</td><td align="left">Construction</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">6.1.3.2</td><td align="left">Tuple creation functions</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">6.1.3.3</td><td align="left">Tuple helper classes</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">6.1.3.4</td><td align="left">Element access</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">6.1.3.5</td><td align="left">Relational operators</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">6.1.4</td><td align="left">Pairs</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">6.2</td><td align="left">Fixed size array</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">6.2.1</td><td align="left">Header <code class="code">&lt;array&gt;</code> synopsis</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">6.2.2</td><td align="left">Class template <code class="code">array</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">6.2.2.1</td><td align="left"><code class="code">array</code> constructors, copy, and assignment</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">6.2.2.2</td><td align="left"><code class="code">array</code> specialized algorithms</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">6.2.2.3</td><td align="left"><code class="code">array</code> size</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">6.2.2.4</td><td align="left">Zero sized <code class="code">array</code>s</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">6.2.2.5</td><td align="left">Tuple interface to class template <code class="code">array</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">6.3</td><td align="left">Unordered associative containers</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">6.3.1</td><td align="left">Unordered associative container requirements</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">6.3.1.1</td><td align="left">Exception safety guarantees</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">6.3.2</td><td align="left">Additions to header <code class="code">&lt;functional&gt;</code> synopsis</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">6.3.3</td><td align="left">Class template <code class="code">hash</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">6.3.4</td><td align="left">Unordered associative container classes</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">6.3.4.1</td><td align="left">Header <code class="code">&lt;unordered_set&gt;</code> synopsis</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">6.3.4.2</td><td align="left">Header <code class="code">&lt;unordered_map&gt;</code> synopsis</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">6.3.4.3</td><td align="left">Class template <code class="code">unordered_set</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">6.3.4.3.1</td><td align="left"><code class="code">unordered_set</code> constructors</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">6.3.4.3.2</td><td align="left"><code class="code">unordered_set</code> swap</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">6.3.4.4</td><td align="left">Class template <code class="code">unordered_map</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">6.3.4.4.1</td><td align="left"><code class="code">unordered_map</code> constructors</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">6.3.4.4.2</td><td align="left"><code class="code">unordered_map</code> element access</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">6.3.4.4.3</td><td align="left"><code class="code">unordered_map</code> swap</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">6.3.4.5</td><td align="left">Class template <code class="code">unordered_multiset<code class="code"></code></code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">6.3.4.5.1</td><td align="left"><code class="code">unordered_multiset</code> constructors</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">6.3.4.5.2</td><td align="left"><code class="code">unordered_multiset</code> swap</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">6.3.4.6</td><td align="left">Class template <code class="code">unordered_multimap</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">6.3.4.6.1</td><td align="left"><code class="code">unordered_multimap</code> constructors</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">6.3.4.6.2</td><td align="left"><code class="code">unordered_multimap</code> swap</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left"><span class="emphasis"><em>7</em></span></td><td colspan="5" align="left"><span class="emphasis"><em>Regular Expressions</em></span></td></tr><tr><td align="left">7.1</td><td align="left">Definitions</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">7.2</td><td align="left">Requirements</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">7.3</td><td align="left">Regular expressions summary</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">7.4</td><td align="left">Header <code class="code">&lt;regex&gt;</code> synopsis</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">7.5</td><td align="left">Namespace <code class="code">tr1::regex_constants</code></td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">7.5.1</td><td align="left">Bitmask Type <code class="code">syntax_option_type</code></td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">7.5.2</td><td align="left">Bitmask Type <code class="code">regex_constants::match_flag_type</code></td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">7.5.3</td><td align="left">Implementation defined <code class="code">error_type</code></td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">7.6</td><td align="left">Class <code class="code">regex_error</code></td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">7.7</td><td align="left">Class template <code class="code">regex_traits</code></td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">7.8</td><td align="left">Class template <code class="code">basic_regex</code></td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">7.8.1</td><td align="left"><code class="code">basic_regex</code> constants</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">7.8.2</td><td align="left"><code class="code">basic_regex</code> constructors</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">7.8.3</td><td align="left"><code class="code">basic_regex</code> assign</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">7.8.4</td><td align="left"><code class="code">basic_regex</code> constant operations</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">7.8.5</td><td align="left"><code class="code">basic_regex</code> locale</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">7.8.6</td><td align="left"><code class="code">basic_regex</code> swap</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">7.8.7</td><td align="left"><code class="code">basic_regex</code> non-member functions</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">7.8.7.1</td><td align="left"><code class="code">basic_regex</code> non-member swap</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">7.9</td><td align="left">Class template <code class="code">sub_match</code></td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">7.9.1</td><td align="left"><code class="code">sub_match</code> members</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">7.9.2</td><td align="left"><code class="code">sub_match</code> non-member operators</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">7.10</td><td align="left">Class template <code class="code">match_results</code></td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">7.10.1</td><td align="left"><code class="code">match_results</code> constructors</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">7.10.2</td><td align="left"><code class="code">match_results</code> size</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">7.10.3</td><td align="left"><code class="code">match_results</code> element access</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">7.10.4</td><td align="left"><code class="code">match_results</code> formatting</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">7.10.5</td><td align="left"><code class="code">match_results</code> allocator</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">7.10.6</td><td align="left"><code class="code">match_results</code> swap</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">7.11</td><td align="left">Regular expression algorithms</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">7.11.1</td><td align="left">exceptions</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">7.11.2</td><td align="left"><code class="code">regex_match</code></td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">7.11.3</td><td align="left"><code class="code">regex_search</code></td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">7.11.4</td><td align="left"><code class="code">regex_replace</code></td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">7.12</td><td align="left">Regular expression Iterators</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">7.12.1</td><td align="left">Class template <code class="code">regex_iterator</code></td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">7.12.1.1</td><td align="left"><code class="code">regex_iterator</code> constructors</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">7.12.1.2</td><td align="left"><code class="code">regex_iterator</code> comparisons</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">7.12.1.3</td><td align="left"><code class="code">regex_iterator</code> dereference</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">7.12.1.4</td><td align="left"><code class="code">regex_iterator</code> increment</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">7.12.2</td><td align="left">Class template <code class="code">regex_token_iterator</code></td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">7.12.2.1</td><td align="left"><code class="code">regex_token_iterator</code> constructors</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">7.12.2.2</td><td align="left"><code class="code">regex_token_iterator</code> comparisons</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">7.12.2.3</td><td align="left"><code class="code">regex_token_iterator</code> dereference</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">7.12.2.4</td><td align="left"><code class="code">regex_token_iterator</code> increment</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">7.13</td><td align="left">Modified ECMAScript regular expression grammar</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left"><span class="emphasis"><em>8</em></span></td><td colspan="5" align="left"><span class="emphasis"><em>C Compatibility</em></span></td></tr><tr><td align="left">8.1</td><td align="left">Additions to header <code class="code">&lt;complex&gt;</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.1.1</td><td align="left">Synopsis</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.1.2</td><td align="left">Function <code class="code">acos</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.1.3</td><td align="left">Function <code class="code">asin</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.1.4</td><td align="left">Function <code class="code">atan</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.1.5</td><td align="left">Function <code class="code">acosh</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.1.6</td><td align="left">Function <code class="code">asinh</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.1.7</td><td align="left">Function <code class="code">atanh</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.1.8</td><td align="left">Function <code class="code">fabs</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.1.9</td><td align="left">Additional Overloads</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.2</td><td align="left">Header <code class="code">&lt;ccomplex&gt;</code></td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left">DR 551</td></tr><tr><td align="left">8.3</td><td align="left">Header <code class="code">&lt;complex.h&gt;</code></td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left">DR 551</td></tr><tr><td align="left">8.4</td><td align="left">Additions to header <code class="code">&lt;cctype&gt;</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.4.1</td><td align="left">Synopsis</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.4.2</td><td align="left">Function <code class="code">isblank</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.5</td><td align="left">Additions to header <code class="code">&lt;ctype.h&gt;</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.6</td><td align="left">Header <code class="code">&lt;cfenv&gt;</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.6.1</td><td align="left">Synopsis</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.6.2</td><td align="left">Definitions</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.7</td><td align="left">Header <code class="code">&lt;fenv.h&gt;</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.8</td><td align="left">Additions to header <code class="code">&lt;cfloat&gt;</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.9</td><td align="left">Additions to header <code class="code">&lt;float.h&gt;</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.10</td><td align="left">Additions to header <code class="code">&lt;ios&gt;</code></td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">8.10.1</td><td align="left">Synopsis</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">8.10.2</td><td align="left">Function <code class="code">hexfloat</code></td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">8.11</td><td align="left">Header <code class="code">&lt;cinttypes&gt;</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.11.1</td><td align="left">Synopsis</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left">DR 557</td></tr><tr><td align="left">8.11.2</td><td align="left">Definitions</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.12</td><td align="left">Header <code class="code">&lt;inttypes.h&gt;</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.13</td><td align="left">Additions to header <code class="code">&lt;climits&gt;</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.14</td><td align="left">Additions to header <code class="code">&lt;limits.h&gt;</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.15</td><td align="left">Additions to header <code class="code">&lt;locale&gt;</code></td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">8.16</td><td align="left">Additions to header <code class="code">&lt;cmath&gt;</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.16.1</td><td align="left">Synopsis</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.16.2</td><td align="left">Definitions</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.16.3</td><td align="left">Function template definitions</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.16.4</td><td align="left">Additional overloads</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left">DR 568; DR 550</td></tr><tr><td align="left">8.17</td><td align="left">Additions to header <code class="code">&lt;math.h&gt;</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.18</td><td align="left">Additions to header <code class="code">&lt;cstdarg&gt;</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.19</td><td align="left">Additions to header <code class="code">&lt;stdarg.h&gt;</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.20</td><td align="left">The header <code class="code">&lt;cstdbool&gt;</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.21</td><td align="left">The header <code class="code">&lt;stdbool.h&gt;</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.22</td><td align="left">The header <code class="code">&lt;cstdint&gt;</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.22.1</td><td align="left">Synopsis</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.22.2</td><td align="left">Definitions</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.23</td><td align="left">The header <code class="code">&lt;stdint.h&gt;</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.24</td><td align="left">Additions to header <code class="code">&lt;cstdio&gt;</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.24.1</td><td align="left">Synopsis</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.24.2</td><td align="left">Definitions</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.24.3</td><td align="left">Additional format specifiers</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left">C library responsibility</td></tr><tr><td align="left">8.24.4</td><td align="left">Additions to header <code class="code">&lt;stdio.h&gt;</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.25</td><td align="left">Additions to header <code class="code">&lt;cstdlib&gt;</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.25.1</td><td align="left">Synopsis</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.25.2</td><td align="left">Definitions</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.25.3</td><td align="left">Function <code class="code">abs</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.25.4</td><td align="left">Function <code class="code">div</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.26</td><td align="left">Additions to header <code class="code">&lt;stdlib.h&gt;</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.27</td><td align="left">Header <code class="code">&lt;ctgmath&gt;</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left">DR 551</td></tr><tr><td align="left">8.28</td><td align="left">Header <code class="code">&lt;tgmath.h&gt;</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left">DR 551</td></tr><tr><td align="left">8.29</td><td align="left">Additions to header <code class="code">&lt;ctime&gt;</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left">C library responsibility</td></tr><tr><td align="left">8.30</td><td align="left">Additions to header <code class="code">&lt;cwchar&gt;</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.30.1</td><td align="left">Synopsis</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.30.2</td><td align="left">Definitions</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.30.3</td><td align="left">Additional wide format specifiers</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left">C library responsibility</td></tr><tr><td align="left">8.31</td><td align="left">Additions to header <code class="code">&lt;wchar.h&gt;</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.32</td><td align="left">Additions to header <code class="code">&lt;cwctype&gt;</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.32.1</td><td align="left">Synopsis</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.32.2</td><td align="left">Function <code class="code">iswblank</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.33</td><td align="left">Additions to header <code class="code">&lt;wctype.h&gt;</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr></tbody></table></div></div><br class="table-break" /><p>
+</p><div class="table"><a id="id337485"></a><p class="title"><b>Table 1.1. C++ TR1 Implementation Status</b></p><div class="table-contents"><table summary="C++ TR1 Implementation Status" border="1"><colgroup><col align="left" /><col align="left" /><col align="left" /><col align="left" /><col align="left" /><col align="left" /></colgroup><thead><tr><th align="left">Section</th><th align="left">Description</th><th align="left">Done</th><th align="left">Broken</th><th align="left">Missing</th><th align="left">Comments</th></tr></thead><tbody><tr><td align="left"><span class="emphasis"><em>2</em></span></td><td colspan="5" align="left"><span class="emphasis"><em>General Utilities</em></span></td></tr><tr><td align="left">2.1</td><td align="left">Reference wrappers</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">2.1.1</td><td align="left">Additions to header <code class="code">&lt;functional&gt;</code> synopsis</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">2.1.2</td><td align="left">Class template <code class="code">reference_wrapper</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">2.1.2.1</td><td align="left"><code class="code">reference_wrapper</code> construct/copy/destroy</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">2.1.2.2</td><td align="left"><code class="code">reference_wrapper</code> assignment</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">2.1.2.3</td><td align="left"><code class="code">reference_wrapper</code> access</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">2.1.2.4</td><td align="left"><code class="code">reference_wrapper</code> invocation</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">2.1.2.5</td><td align="left"><code class="code">reference_wrapper</code> helper functions</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">2.2</td><td align="left">Smart pointers</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">2.2.1</td><td align="left">Additions to header <code class="code">&lt;memory&gt;</code> synopsis</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">2.2.2</td><td align="left">Class <code class="code">bad_weak_ptr</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">2.2.3</td><td align="left">Class template <code class="code">shared_ptr</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left">See Footnotes</td></tr><tr><td align="left">2.2.3.1</td><td align="left"><code class="code">shared_ptr</code> constructors</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">2.2.3.2</td><td align="left"><code class="code">shared_ptr</code> destructor</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">2.2.3.3</td><td align="left"><code class="code">shared_ptr</code> assignment</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">2.2.3.4</td><td align="left"><code class="code">shared_ptr</code> modifiers</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">2.2.3.5</td><td align="left"><code class="code">shared_ptr</code> observers</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">2.2.3.6</td><td align="left"><code class="code">shared_ptr</code> comparison</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">2.2.3.7</td><td align="left"><code class="code">shared_ptr</code> I/O</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">2.2.3.8</td><td align="left"><code class="code">shared_ptr</code> specialized algorithms</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">2.2.3.9</td><td align="left"><code class="code">shared_ptr</code> casts</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">2.2.3.10</td><td align="left"><code class="code">get_deleter</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">2.2.4</td><td align="left">Class template <code class="code">weak_ptr</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">2.2.4.1</td><td align="left"><code class="code">weak_ptr</code> constructors</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">2.2.4.2</td><td align="left"><code class="code">weak_ptr</code> destructor</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">2.2.4.3</td><td align="left"><code class="code">weak_ptr</code> assignment</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">2.2.4.4</td><td align="left"><code class="code">weak_ptr</code> modifiers</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">2.2.4.5</td><td align="left"><code class="code">weak_ptr</code> observers</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">2.2.4.6</td><td align="left"><code class="code">weak_ptr</code> comparison</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">2.2.4.7</td><td align="left"><code class="code">weak_ptr</code> specialized algorithms</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">2.2.5</td><td align="left">Class template <code class="code">enable_shared_from_this</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left"><span class="emphasis"><em>3</em></span></td><td colspan="5" align="left"><span class="emphasis"><em>Function Objects</em></span></td></tr><tr><td align="left">3.1</td><td align="left">Definitions</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">3.2</td><td align="left">Additions to <code class="code">&lt;functional&gt; synopsis</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">3.3</td><td align="left">Requirements</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">3.4</td><td align="left">Function return types</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">3.5</td><td align="left">Function template <code class="code">mem_fn</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">3.6</td><td align="left">Function object binders</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">3.6.1</td><td align="left">Class template <code class="code">is_bind_expression</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">3.6.2</td><td align="left">Class template <code class="code">is_placeholder</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">3.6.3</td><td align="left">Function template <code class="code">bind</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">3.6.4</td><td align="left">Placeholders</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">3.7</td><td align="left">Polymorphic function wrappers</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">3.7.1</td><td align="left">Class <code class="code">bad_function_call<code class="code"></code></code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">3.7.1.1</td><td align="left"><code class="code">bad_function_call</code> constructor</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">3.7.2</td><td align="left">Class template <code class="code">function</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">3.7.2.1</td><td align="left"><code class="code">function</code> construct/copy/destroy</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">3.7.2.2</td><td align="left"><code class="code">function</code> modifiers</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">3.7.2.3</td><td align="left"><code class="code">function</code> capacity</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">3.7.2.4</td><td align="left"><code class="code">function</code> invocation</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">3.7.2.5</td><td align="left"><code class="code">function</code> target access</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">3.7.2.6</td><td align="left">undefined operators</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">3.7.2.7</td><td align="left">null pointer comparison operators</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">3.7.2.8</td><td align="left">specialized algorithms</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left"><span class="emphasis"><em>4</em></span></td><td colspan="5" align="left"><span class="emphasis"><em>Metaprogramming and type traits</em></span></td></tr><tr><td align="left">4.1</td><td align="left">Requirements</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">4.2</td><td align="left">Header <code class="code">&lt;type_traits&gt;</code> synopsis</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">4.3</td><td align="left">Helper classes</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">4.4</td><td align="left">General Requirements</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">4.5</td><td align="left">Unary Type Traits</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">4.5.1</td><td align="left">Primary Type Categories</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">4.5.2</td><td align="left">Composite type traits</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">4.5.3</td><td align="left">Type properties</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">4.6</td><td align="left">Relationships between types</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">4.7</td><td align="left">Transformations between types</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">4.7.1</td><td align="left">Const-volatile modifications</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">4.7.2</td><td align="left">Reference modifications</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">4.7.3</td><td align="left">Array modifications</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">4.7.4</td><td align="left">Pointer modifications</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">4.8</td><td align="left">Other transformations</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">4.9</td><td align="left">Implementation requirements</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left"><span class="emphasis"><em>5</em></span></td><td colspan="5" align="left"><span class="emphasis"><em>Numerical Facilities</em></span></td></tr><tr><td align="left">5.1</td><td align="left">Random number generation</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.1.1</td><td align="left">Requirements</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.1.2</td><td align="left">Header <code class="code">&lt;random&gt;</code> synopsis</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.1.3</td><td align="left">Class template <code class="code">variate_generator</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.1.4</td><td align="left">Random number engine class templates</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.1.4.1</td><td align="left">Class template <code class="code">linear_congruential</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.1.4.2</td><td align="left">Class template <code class="code">mersenne_twister</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.1.4.3</td><td align="left">Class template <code class="code">subtract_with_carry</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.1.4.4</td><td align="left">Class template <code class="code">subtract_with_carry_01</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.1.4.5</td><td align="left">Class template <code class="code">discard_block</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.1.4.6</td><td align="left">Class template <code class="code">xor_combine</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left">operator()() per N2079</td></tr><tr><td align="left">5.1.5</td><td align="left">Engines with predefined parameters</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.1.6</td><td align="left">Class <code class="code">random_device</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.1.7</td><td align="left">Random distribution class templates</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.1.7.1</td><td align="left">Class template <code class="code">uniform_int</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.1.7.2</td><td align="left">Class <code class="code">bernoulli_distribution</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.1.7.3</td><td align="left">Class template <code class="code">geometric_distribution</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.1.7.4</td><td align="left">Class template <code class="code">poisson_distribution</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.1.7.5</td><td align="left">Class template <code class="code">binomial_distribution</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.1.7.6</td><td align="left">Class template <code class="code">uniform_real</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.1.7.7</td><td align="left">Class template <code class="code">exponential_distribution</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.1.7.8</td><td align="left">Class template <code class="code">normal_distribution</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.1.7.9</td><td align="left">Class template <code class="code">gamma_distribution</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.2</td><td align="left">Mathematical special functions</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.2.1</td><td align="left">Additions to header <code class="code">&lt;cmath&gt;</code> synopsis</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.2.1.1</td><td align="left">associated Laguerre polynomials</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.2.1.2</td><td align="left">associated Legendre functions</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.2.1.3</td><td align="left">beta function</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.2.1.4</td><td align="left">(complete) elliptic integral of the first kind</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.2.1.5</td><td align="left">(complete) elliptic integral of the second kind</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.2.1.6</td><td align="left">(complete) elliptic integral of the third kind</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.2.1.7</td><td align="left">confluent hypergeometric functions</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.2.1.8</td><td align="left">regular modified cylindrical Bessel functions</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.2.1.9</td><td align="left">cylindrical Bessel functions (of the first kind)</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.2.1.10</td><td align="left">irregular modified cylindrical Bessel functions</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.2.1.11</td><td align="left">cylindrical Neumann functions</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.2.1.12</td><td align="left">(incomplete) elliptic integral of the first kind</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.2.1.13</td><td align="left">(incomplete) elliptic integral of the second kind</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.2.1.14</td><td align="left">(incomplete) elliptic integral of the third kind</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.2.1.15</td><td align="left">exponential integral</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.2.1.16</td><td align="left">Hermite polynomials</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.2.1.17</td><td align="left">hypergeometric functions</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.2.1.18</td><td align="left">Laguerre polynomials</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.2.1.19</td><td align="left">Legendre polynomials</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.2.1.20</td><td align="left">Riemann zeta function</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.2.1.21</td><td align="left">spherical Bessel functions (of the first kind)</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.2.1.22</td><td align="left">spherical associated Legendre functions</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.2.1.23</td><td align="left">spherical Neumann functions</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">5.2.2</td><td align="left">Additions to header <code class="code">&lt;math.h&gt;</code> synopsis</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left"><span class="emphasis"><em>6</em></span></td><td colspan="5" align="left"><span class="emphasis"><em>Containers</em></span></td></tr><tr><td align="left">6.1</td><td align="left">Tuple types</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">6.1.1</td><td align="left">Header <code class="code">&lt;tuple&gt;</code> synopsis</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">6.1.2</td><td align="left">Additions to header <code class="code">&lt;utility&gt;</code> synopsis</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">6.1.3</td><td align="left">Class template <code class="code">tuple</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">6.1.3.1</td><td align="left">Construction</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">6.1.3.2</td><td align="left">Tuple creation functions</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">6.1.3.3</td><td align="left">Tuple helper classes</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">6.1.3.4</td><td align="left">Element access</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">6.1.3.5</td><td align="left">Relational operators</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">6.1.4</td><td align="left">Pairs</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">6.2</td><td align="left">Fixed size array</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">6.2.1</td><td align="left">Header <code class="code">&lt;array&gt;</code> synopsis</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">6.2.2</td><td align="left">Class template <code class="code">array</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">6.2.2.1</td><td align="left"><code class="code">array</code> constructors, copy, and assignment</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">6.2.2.2</td><td align="left"><code class="code">array</code> specialized algorithms</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">6.2.2.3</td><td align="left"><code class="code">array</code> size</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">6.2.2.4</td><td align="left">Zero sized <code class="code">array</code>s</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">6.2.2.5</td><td align="left">Tuple interface to class template <code class="code">array</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">6.3</td><td align="left">Unordered associative containers</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">6.3.1</td><td align="left">Unordered associative container requirements</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">6.3.1.1</td><td align="left">Exception safety guarantees</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">6.3.2</td><td align="left">Additions to header <code class="code">&lt;functional&gt;</code> synopsis</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">6.3.3</td><td align="left">Class template <code class="code">hash</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">6.3.4</td><td align="left">Unordered associative container classes</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">6.3.4.1</td><td align="left">Header <code class="code">&lt;unordered_set&gt;</code> synopsis</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">6.3.4.2</td><td align="left">Header <code class="code">&lt;unordered_map&gt;</code> synopsis</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">6.3.4.3</td><td align="left">Class template <code class="code">unordered_set</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">6.3.4.3.1</td><td align="left"><code class="code">unordered_set</code> constructors</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">6.3.4.3.2</td><td align="left"><code class="code">unordered_set</code> swap</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">6.3.4.4</td><td align="left">Class template <code class="code">unordered_map</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">6.3.4.4.1</td><td align="left"><code class="code">unordered_map</code> constructors</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">6.3.4.4.2</td><td align="left"><code class="code">unordered_map</code> element access</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">6.3.4.4.3</td><td align="left"><code class="code">unordered_map</code> swap</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">6.3.4.5</td><td align="left">Class template <code class="code">unordered_multiset<code class="code"></code></code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">6.3.4.5.1</td><td align="left"><code class="code">unordered_multiset</code> constructors</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">6.3.4.5.2</td><td align="left"><code class="code">unordered_multiset</code> swap</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">6.3.4.6</td><td align="left">Class template <code class="code">unordered_multimap</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">6.3.4.6.1</td><td align="left"><code class="code">unordered_multimap</code> constructors</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">6.3.4.6.2</td><td align="left"><code class="code">unordered_multimap</code> swap</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left"><span class="emphasis"><em>7</em></span></td><td colspan="5" align="left"><span class="emphasis"><em>Regular Expressions</em></span></td></tr><tr><td align="left">7.1</td><td align="left">Definitions</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">7.2</td><td align="left">Requirements</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">7.3</td><td align="left">Regular expressions summary</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">7.4</td><td align="left">Header <code class="code">&lt;regex&gt;</code> synopsis</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">7.5</td><td align="left">Namespace <code class="code">tr1::regex_constants</code></td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">7.5.1</td><td align="left">Bitmask Type <code class="code">syntax_option_type</code></td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">7.5.2</td><td align="left">Bitmask Type <code class="code">regex_constants::match_flag_type</code></td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">7.5.3</td><td align="left">Implementation defined <code class="code">error_type</code></td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">7.6</td><td align="left">Class <code class="code">regex_error</code></td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">7.7</td><td align="left">Class template <code class="code">regex_traits</code></td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">7.8</td><td align="left">Class template <code class="code">basic_regex</code></td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">7.8.1</td><td align="left"><code class="code">basic_regex</code> constants</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">7.8.2</td><td align="left"><code class="code">basic_regex</code> constructors</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">7.8.3</td><td align="left"><code class="code">basic_regex</code> assign</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">7.8.4</td><td align="left"><code class="code">basic_regex</code> constant operations</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">7.8.5</td><td align="left"><code class="code">basic_regex</code> locale</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">7.8.6</td><td align="left"><code class="code">basic_regex</code> swap</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">7.8.7</td><td align="left"><code class="code">basic_regex</code> non-member functions</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">7.8.7.1</td><td align="left"><code class="code">basic_regex</code> non-member swap</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">7.9</td><td align="left">Class template <code class="code">sub_match</code></td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">7.9.1</td><td align="left"><code class="code">sub_match</code> members</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">7.9.2</td><td align="left"><code class="code">sub_match</code> non-member operators</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">7.10</td><td align="left">Class template <code class="code">match_results</code></td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">7.10.1</td><td align="left"><code class="code">match_results</code> constructors</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">7.10.2</td><td align="left"><code class="code">match_results</code> size</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">7.10.3</td><td align="left"><code class="code">match_results</code> element access</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">7.10.4</td><td align="left"><code class="code">match_results</code> formatting</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">7.10.5</td><td align="left"><code class="code">match_results</code> allocator</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">7.10.6</td><td align="left"><code class="code">match_results</code> swap</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">7.11</td><td align="left">Regular expression algorithms</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">7.11.1</td><td align="left">exceptions</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">7.11.2</td><td align="left"><code class="code">regex_match</code></td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">7.11.3</td><td align="left"><code class="code">regex_search</code></td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">7.11.4</td><td align="left"><code class="code">regex_replace</code></td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">7.12</td><td align="left">Regular expression Iterators</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">7.12.1</td><td align="left">Class template <code class="code">regex_iterator</code></td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">7.12.1.1</td><td align="left"><code class="code">regex_iterator</code> constructors</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">7.12.1.2</td><td align="left"><code class="code">regex_iterator</code> comparisons</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">7.12.1.3</td><td align="left"><code class="code">regex_iterator</code> dereference</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">7.12.1.4</td><td align="left"><code class="code">regex_iterator</code> increment</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">7.12.2</td><td align="left">Class template <code class="code">regex_token_iterator</code></td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">7.12.2.1</td><td align="left"><code class="code">regex_token_iterator</code> constructors</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">7.12.2.2</td><td align="left"><code class="code">regex_token_iterator</code> comparisons</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">7.12.2.3</td><td align="left"><code class="code">regex_token_iterator</code> dereference</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">7.12.2.4</td><td align="left"><code class="code">regex_token_iterator</code> increment</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">7.13</td><td align="left">Modified ECMAScript regular expression grammar</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left"><span class="emphasis"><em>8</em></span></td><td colspan="5" align="left"><span class="emphasis"><em>C Compatibility</em></span></td></tr><tr><td align="left">8.1</td><td align="left">Additions to header <code class="code">&lt;complex&gt;</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.1.1</td><td align="left">Synopsis</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.1.2</td><td align="left">Function <code class="code">acos</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.1.3</td><td align="left">Function <code class="code">asin</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.1.4</td><td align="left">Function <code class="code">atan</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.1.5</td><td align="left">Function <code class="code">acosh</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.1.6</td><td align="left">Function <code class="code">asinh</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.1.7</td><td align="left">Function <code class="code">atanh</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.1.8</td><td align="left">Function <code class="code">fabs</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.1.9</td><td align="left">Additional Overloads</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.2</td><td align="left">Header <code class="code">&lt;ccomplex&gt;</code></td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left">DR 551</td></tr><tr><td align="left">8.3</td><td align="left">Header <code class="code">&lt;complex.h&gt;</code></td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left">DR 551</td></tr><tr><td align="left">8.4</td><td align="left">Additions to header <code class="code">&lt;cctype&gt;</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.4.1</td><td align="left">Synopsis</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.4.2</td><td align="left">Function <code class="code">isblank</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.5</td><td align="left">Additions to header <code class="code">&lt;ctype.h&gt;</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.6</td><td align="left">Header <code class="code">&lt;cfenv&gt;</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.6.1</td><td align="left">Synopsis</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.6.2</td><td align="left">Definitions</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.7</td><td align="left">Header <code class="code">&lt;fenv.h&gt;</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.8</td><td align="left">Additions to header <code class="code">&lt;cfloat&gt;</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.9</td><td align="left">Additions to header <code class="code">&lt;float.h&gt;</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.10</td><td align="left">Additions to header <code class="code">&lt;ios&gt;</code></td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">8.10.1</td><td align="left">Synopsis</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">8.10.2</td><td align="left">Function <code class="code">hexfloat</code></td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">8.11</td><td align="left">Header <code class="code">&lt;cinttypes&gt;</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.11.1</td><td align="left">Synopsis</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left">DR 557</td></tr><tr><td align="left">8.11.2</td><td align="left">Definitions</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.12</td><td align="left">Header <code class="code">&lt;inttypes.h&gt;</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.13</td><td align="left">Additions to header <code class="code">&lt;climits&gt;</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.14</td><td align="left">Additions to header <code class="code">&lt;limits.h&gt;</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.15</td><td align="left">Additions to header <code class="code">&lt;locale&gt;</code></td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">8.16</td><td align="left">Additions to header <code class="code">&lt;cmath&gt;</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.16.1</td><td align="left">Synopsis</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.16.2</td><td align="left">Definitions</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.16.3</td><td align="left">Function template definitions</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.16.4</td><td align="left">Additional overloads</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left">DR 568; DR 550</td></tr><tr><td align="left">8.17</td><td align="left">Additions to header <code class="code">&lt;math.h&gt;</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.18</td><td align="left">Additions to header <code class="code">&lt;cstdarg&gt;</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.19</td><td align="left">Additions to header <code class="code">&lt;stdarg.h&gt;</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.20</td><td align="left">The header <code class="code">&lt;cstdbool&gt;</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.21</td><td align="left">The header <code class="code">&lt;stdbool.h&gt;</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.22</td><td align="left">The header <code class="code">&lt;cstdint&gt;</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.22.1</td><td align="left">Synopsis</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.22.2</td><td align="left">Definitions</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.23</td><td align="left">The header <code class="code">&lt;stdint.h&gt;</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.24</td><td align="left">Additions to header <code class="code">&lt;cstdio&gt;</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.24.1</td><td align="left">Synopsis</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.24.2</td><td align="left">Definitions</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.24.3</td><td align="left">Additional format specifiers</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left">C library responsibility</td></tr><tr><td align="left">8.24.4</td><td align="left">Additions to header <code class="code">&lt;stdio.h&gt;</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.25</td><td align="left">Additions to header <code class="code">&lt;cstdlib&gt;</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.25.1</td><td align="left">Synopsis</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.25.2</td><td align="left">Definitions</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.25.3</td><td align="left">Function <code class="code">abs</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.25.4</td><td align="left">Function <code class="code">div</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.26</td><td align="left">Additions to header <code class="code">&lt;stdlib.h&gt;</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.27</td><td align="left">Header <code class="code">&lt;ctgmath&gt;</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left">DR 551</td></tr><tr><td align="left">8.28</td><td align="left">Header <code class="code">&lt;tgmath.h&gt;</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left">DR 551</td></tr><tr><td align="left">8.29</td><td align="left">Additions to header <code class="code">&lt;ctime&gt;</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left">C library responsibility</td></tr><tr><td align="left">8.30</td><td align="left">Additions to header <code class="code">&lt;cwchar&gt;</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.30.1</td><td align="left">Synopsis</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.30.2</td><td align="left">Definitions</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.30.3</td><td align="left">Additional wide format specifiers</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left">C library responsibility</td></tr><tr><td align="left">8.31</td><td align="left">Additions to header <code class="code">&lt;wchar.h&gt;</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.32</td><td align="left">Additions to header <code class="code">&lt;cwctype&gt;</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.32.1</td><td align="left">Synopsis</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.32.2</td><td align="left">Function <code class="code">iswblank</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">8.33</td><td align="left">Additions to header <code class="code">&lt;wctype.h&gt;</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr></tbody></table></div></div><br class="table-break" /><p>
Footnotes
</p><p>
The shared_ptr implementation uses some code from the
@@ -6120,7 +6120,7 @@ presence of the required flag.
</p><p>
This page describes the C++0x support in mainline GCC SVN, not in any
particular release.
-</p><div class="table"><a id="id614832"></a><p class="title"><b>Table 1.2. C++ 200x Implementation Status</b></p><div class="table-contents"><table summary="C++ 200x Implementation Status" border="1"><colgroup><col align="left" /><col align="left" /><col align="left" /><col align="left" /><col align="left" /><col align="left" /></colgroup><thead><tr><th align="left">Section</th><th align="left">Description</th><th align="left">Done</th><th align="left">Broken</th><th align="left">Missing</th><th align="left">Comments</th></tr></thead><tbody><tr><td align="left"><span class="emphasis"><em>20</em></span></td><td colspan="5" align="left"><span class="emphasis"><em>General Utilities</em></span></td></tr><tr><td align="left">20.2</td><td align="left">Utility Components</td><td align="left"> </td><td align="left"> </td><td align="left">incomplete</td><td align="left"> </td></tr><tr><td align="left">20.2.1</td><td align="left">Operators</td><td align="left"> </td><td align="left"> </td><td align="left">partial</td><td align="left"> </td></tr><tr><td align="left">20.2.2</td><td align="left">forward/move helpers</td><td align="left"> </td><td align="left"> </td><td align="left">partial</td><td align="left"> </td></tr><tr><td align="left">20.2.3</td><td align="left">Pairs</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.3</td><td align="left">Header <code class="code">&lt;tuple&gt;</code> synopsis</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.3.1</td><td align="left">Class template <code class="code">tuple</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.3.1.1</td><td align="left">Construction</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.3.1.2</td><td align="left">Tuple creation functions</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.3.1.3</td><td align="left">Tuple helper classes</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.3.1.4</td><td align="left">Element access</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.3.1.5</td><td align="left">Relational operators</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.4</td><td colspan="5" align="left"><span class="emphasis"><em>Metaprogramming and type traits</em></span></td></tr><tr><td align="left">20.4.1</td><td align="left">Requirements</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.4.2</td><td align="left">Header <code class="code">&lt;type_traits&gt;</code> synopsis</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.4.3</td><td align="left">Helper classes</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.4.4</td><td align="left">General Requirements</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.4.5</td><td align="left">Unary Type Traits</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.4.5.1</td><td align="left">Primary Type Categories</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.4.5.2</td><td align="left">Composite type traits</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.4.5.3</td><td align="left">Type properties</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.4.6</td><td align="left">Relationships between types</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.4.7</td><td align="left">Transformations between types</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.4.7.1</td><td align="left">Const-volatile modifications</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.4.7.2</td><td align="left">Reference modifications</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.4.7.3</td><td align="left">Array modifications</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.4.7.4</td><td align="left">Pointer modifications</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.4.8</td><td align="left">Other transformations</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.4.9</td><td align="left">Implementation requirements</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.5 </td><td align="left">Function Objects</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.5</td><td align="left">Additions to header <code class="code">&lt;functional&gt;</code> synopsis</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.5.1</td><td align="left">Definitions</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.5.2</td><td align="left">Requirements</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.5.3</td><td align="left">Base</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.5.4</td><td align="left">Function return types</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.5.5</td><td align="left">Class template <code class="code">reference_wrapper</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.5.5.1</td><td align="left"><code class="code">reference_wrapper</code> construct/copy/destroy</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.5.5.2</td><td align="left"><code class="code">reference_wrapper</code> assignment</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.5.5.3</td><td align="left"><code class="code">reference_wrapper</code> access</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.5.5.4</td><td align="left"><code class="code">reference_wrapper</code> invocation</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.5.5.5</td><td align="left"><code class="code">reference_wrapper</code> helper functions</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.5.14</td><td align="left">Function template <code class="code">mem_fn</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.5.11</td><td align="left">Template function bind</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.5.11.1</td><td align="left">Function object binders</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.5.11.1.1</td><td align="left">Class template <code class="code">is_bind_expression</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.5.11.1.2</td><td align="left">Class template <code class="code">is_placeholder</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.5.11.1.3</td><td align="left">Function template <code class="code">bind</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.5.11.1.4</td><td align="left">Placeholders</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.5.15</td><td align="left">Polymorphic function wrappers</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.5.15.1</td><td align="left">Class <code class="code">bad_function_call<code class="code"></code></code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.5.15.1.1</td><td align="left"><code class="code">bad_function_call</code> constructor</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.5.15.2</td><td align="left">Class template <code class="code">function</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.5.15.2.1</td><td align="left"><code class="code">function</code> construct/copy/destroy</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.5.15.2.2</td><td align="left"><code class="code">function</code> modifiers</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.5.15.2.3</td><td align="left"><code class="code">function</code> capacity</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.5.15.2.4</td><td align="left"><code class="code">function</code> invocation</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.5.15.2.5</td><td align="left"><code class="code">function</code> target access</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.5.15.2.7</td><td align="left">null pointer comparison operators</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.5.15.2.8</td><td align="left">specialized algorithms</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.5.16</td><td align="left">Class template <code class="code">hash</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.6</td><td align="left">Additions to header <code class="code">&lt;memory&gt;</code> synopsis</td><td align="left"> </td><td align="left"> </td><td align="left">partial</td><td align="left">missing <code class="code">unique_ptr</code></td></tr><tr><td align="left">20.6.5</td><td align="left">Class template <code class="code">unique_ptr</code></td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">20.6.6</td><td align="left">Smart pointers</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.6.6.1</td><td align="left">Class <code class="code">bad_weak_ptr</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.6.6.2</td><td align="left">Class template <code class="code">shared_ptr</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left">See Footnotes.</td></tr><tr><td align="left">20.6.6.2.1</td><td align="left"><code class="code">shared_ptr</code> constructors</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.6.6.2.2</td><td align="left"><code class="code">shared_ptr</code> destructor</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.6.6.2.3</td><td align="left"><code class="code">shared_ptr</code> assignment</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.6.6.2.4</td><td align="left"><code class="code">shared_ptr</code> modifiers</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.6.6.2.5</td><td align="left"><code class="code">shared_ptr</code> observers</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.6.6.2.6</td><td align="left"><code class="code">shared_ptr</code> creation</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left">
+</p><div class="table"><a id="id382201"></a><p class="title"><b>Table 1.2. C++ 200x Implementation Status</b></p><div class="table-contents"><table summary="C++ 200x Implementation Status" border="1"><colgroup><col align="left" /><col align="left" /><col align="left" /><col align="left" /><col align="left" /><col align="left" /></colgroup><thead><tr><th align="left">Section</th><th align="left">Description</th><th align="left">Done</th><th align="left">Broken</th><th align="left">Missing</th><th align="left">Comments</th></tr></thead><tbody><tr><td align="left"><span class="emphasis"><em>20</em></span></td><td colspan="5" align="left"><span class="emphasis"><em>General Utilities</em></span></td></tr><tr><td align="left">20.2</td><td align="left">Utility Components</td><td align="left"> </td><td align="left"> </td><td align="left">incomplete</td><td align="left"> </td></tr><tr><td align="left">20.2.1</td><td align="left">Operators</td><td align="left"> </td><td align="left"> </td><td align="left">partial</td><td align="left"> </td></tr><tr><td align="left">20.2.2</td><td align="left">forward/move helpers</td><td align="left"> </td><td align="left"> </td><td align="left">partial</td><td align="left"> </td></tr><tr><td align="left">20.2.3</td><td align="left">Pairs</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.3</td><td align="left">Header <code class="code">&lt;tuple&gt;</code> synopsis</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.3.1</td><td align="left">Class template <code class="code">tuple</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.3.1.1</td><td align="left">Construction</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.3.1.2</td><td align="left">Tuple creation functions</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.3.1.3</td><td align="left">Tuple helper classes</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.3.1.4</td><td align="left">Element access</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.3.1.5</td><td align="left">Relational operators</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.4</td><td colspan="5" align="left"><span class="emphasis"><em>Metaprogramming and type traits</em></span></td></tr><tr><td align="left">20.4.1</td><td align="left">Requirements</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.4.2</td><td align="left">Header <code class="code">&lt;type_traits&gt;</code> synopsis</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.4.3</td><td align="left">Helper classes</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.4.4</td><td align="left">General Requirements</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.4.5</td><td align="left">Unary Type Traits</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.4.5.1</td><td align="left">Primary Type Categories</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.4.5.2</td><td align="left">Composite type traits</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.4.5.3</td><td align="left">Type properties</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.4.6</td><td align="left">Relationships between types</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.4.7</td><td align="left">Transformations between types</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.4.7.1</td><td align="left">Const-volatile modifications</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.4.7.2</td><td align="left">Reference modifications</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.4.7.3</td><td align="left">Array modifications</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.4.7.4</td><td align="left">Pointer modifications</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.4.8</td><td align="left">Other transformations</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.4.9</td><td align="left">Implementation requirements</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.5 </td><td align="left">Function Objects</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.5</td><td align="left">Additions to header <code class="code">&lt;functional&gt;</code> synopsis</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.5.1</td><td align="left">Definitions</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.5.2</td><td align="left">Requirements</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.5.3</td><td align="left">Base</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.5.4</td><td align="left">Function return types</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.5.5</td><td align="left">Class template <code class="code">reference_wrapper</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.5.5.1</td><td align="left"><code class="code">reference_wrapper</code> construct/copy/destroy</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.5.5.2</td><td align="left"><code class="code">reference_wrapper</code> assignment</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.5.5.3</td><td align="left"><code class="code">reference_wrapper</code> access</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.5.5.4</td><td align="left"><code class="code">reference_wrapper</code> invocation</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.5.5.5</td><td align="left"><code class="code">reference_wrapper</code> helper functions</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.5.14</td><td align="left">Function template <code class="code">mem_fn</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.5.11</td><td align="left">Template function bind</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.5.11.1</td><td align="left">Function object binders</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.5.11.1.1</td><td align="left">Class template <code class="code">is_bind_expression</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.5.11.1.2</td><td align="left">Class template <code class="code">is_placeholder</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.5.11.1.3</td><td align="left">Function template <code class="code">bind</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.5.11.1.4</td><td align="left">Placeholders</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.5.15</td><td align="left">Polymorphic function wrappers</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.5.15.1</td><td align="left">Class <code class="code">bad_function_call<code class="code"></code></code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.5.15.1.1</td><td align="left"><code class="code">bad_function_call</code> constructor</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.5.15.2</td><td align="left">Class template <code class="code">function</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.5.15.2.1</td><td align="left"><code class="code">function</code> construct/copy/destroy</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.5.15.2.2</td><td align="left"><code class="code">function</code> modifiers</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.5.15.2.3</td><td align="left"><code class="code">function</code> capacity</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.5.15.2.4</td><td align="left"><code class="code">function</code> invocation</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.5.15.2.5</td><td align="left"><code class="code">function</code> target access</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.5.15.2.7</td><td align="left">null pointer comparison operators</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.5.15.2.8</td><td align="left">specialized algorithms</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.5.16</td><td align="left">Class template <code class="code">hash</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.6</td><td align="left">Additions to header <code class="code">&lt;memory&gt;</code> synopsis</td><td align="left"> </td><td align="left"> </td><td align="left">partial</td><td align="left">missing <code class="code">unique_ptr</code></td></tr><tr><td align="left">20.6.5</td><td align="left">Class template <code class="code">unique_ptr</code></td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">20.6.6</td><td align="left">Smart pointers</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.6.6.1</td><td align="left">Class <code class="code">bad_weak_ptr</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.6.6.2</td><td align="left">Class template <code class="code">shared_ptr</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left">See Footnotes.</td></tr><tr><td align="left">20.6.6.2.1</td><td align="left"><code class="code">shared_ptr</code> constructors</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.6.6.2.2</td><td align="left"><code class="code">shared_ptr</code> destructor</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.6.6.2.3</td><td align="left"><code class="code">shared_ptr</code> assignment</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.6.6.2.4</td><td align="left"><code class="code">shared_ptr</code> modifiers</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.6.6.2.5</td><td align="left"><code class="code">shared_ptr</code> observers</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.6.6.2.6</td><td align="left"><code class="code">shared_ptr</code> creation</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left">
<a class="ulink" href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2351.htm" target="_top">N2351</a>
</td></tr><tr><td align="left">20.6.6.2.7</td><td align="left"><code class="code">shared_ptr</code> comparison</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.6.6.2.8</td><td align="left"><code class="code">shared_ptr</code> I/O</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.6.6.2.9</td><td align="left"><code class="code">shared_ptr</code> specialized algorithms</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.6.6.2.10</td><td align="left"><code class="code">shared_ptr</code> casts</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.6.6.2.11</td><td align="left"><code class="code">get_deleter</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.6.6.3</td><td align="left">Class template <code class="code">weak_ptr</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.6.6.3.1</td><td align="left"><code class="code">weak_ptr</code> constructors</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.6.6.3.2</td><td align="left"><code class="code">weak_ptr</code> destructor</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.6.6.3.3</td><td align="left"><code class="code">weak_ptr</code> assignment</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.6.6.3.4</td><td align="left"><code class="code">weak_ptr</code> modifiers</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.6.6.3.5</td><td align="left"><code class="code">weak_ptr</code> observers</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.6.6.3.6</td><td align="left"><code class="code">weak_ptr</code> comparison</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.6.6.3.7</td><td align="left"><code class="code">weak_ptr</code> specialized algorithms</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">20.6.6.4</td><td align="left">Class template <code class="code">enable_shared_from_this</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left"><span class="emphasis"><em>23</em></span></td><td colspan="5" align="left"><span class="emphasis"><em>Containers</em></span></td></tr><tr><td align="left">23.2.1</td><td align="left">Header <code class="code">&lt;array&gt;</code> synopsis</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">23.2.1</td><td align="left">Class template array</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">23.2.1.1</td><td align="left"><code class="code">array</code> constructors, copy, and assignment</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">23.2.1.2</td><td align="left"><code class="code">array</code> specialized algorithms</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">23.2.1.3</td><td align="left"><code class="code">array </code>size</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">23.2.1.4</td><td align="left"><code class="code">array </code>data</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">23.2.1.5</td><td align="left">Zero sized <code class="code">array</code>s</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">23.2.1.6</td><td align="left">Tuple interface to class template <code class="code">array</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">23.4</td><td align="left">Unordered associative containers</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">23.4.1</td><td align="left">Class template <code class="code">unordered_map</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">23.4.1.1</td><td align="left"><code class="code">unordered_map</code> constructors</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">23.4.1.2</td><td align="left"><code class="code">unordered_map</code> element access</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">23.4.1.3</td><td align="left"><code class="code">unordered_map</code> swap</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">23.4.2</td><td align="left">Class template <code class="code">unordered_multimap</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">23.4.2.1</td><td align="left"><code class="code">unordered_multimap</code> constructors</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">23.4.2.2</td><td align="left"><code class="code">unordered_multimap</code> swap</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">23.4.3</td><td align="left">Class template <code class="code">unordered_set</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">23.4.3.1</td><td align="left"><code class="code">unordered_set</code> constructors</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">23.4.3.2</td><td align="left"><code class="code">unordered_set</code> swap</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">23.4.4</td><td align="left">Class template <code class="code">unordered_multiset<code class="code"></code></code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">23.4.4.1</td><td align="left"><code class="code">unordered_multiset</code> constructors</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">23.4.4.2</td><td align="left"><code class="code">unordered_multiset</code> swap</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left"><span class="emphasis"><em>26</em></span></td><td colspan="5" align="left"><span class="emphasis"><em>Numerics</em></span></td></tr><tr><td align="left">26.4</td><td align="left">Random number generation</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">26.4.1</td><td align="left">Requirements</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">26.4.2</td><td align="left">Header <code class="code">&lt;random&gt;</code> synopsis</td><td align="left"> </td><td align="left"> </td><td align="left">partial</td><td align="left"> </td></tr><tr><td align="left">26.4.3</td><td align="left">Random number engine class templates</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">26.4.3.1</td><td align="left">Class template <code class="code">linear_congruential_engine</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">26.4.3.2</td><td align="left">Class template <code class="code">mersenne_twister_engine</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">26.4.3.3</td><td align="left">Class template <code class="code">subtract_with_carry_engine</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">26.4.4</td><td align="left">Random number engine adaptor class templates</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">26.4.4.1</td><td align="left">Class template <code class="code">discard_block_engine</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">26.4.4.2</td><td align="left">Class template <code class="code">independent_bits_engine</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">26.4.4.3</td><td align="left">Class template <code class="code">shuffle_order_engine</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">26.4.4.4</td><td align="left">Class template <code class="code">xor_combine_engine</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left">operator()() per N2079</td></tr><tr><td align="left">26.4.5</td><td align="left">Engines and engine adaptors with predefined parameters</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">26.4.6</td><td align="left">Class <code class="code">random_device</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">26.4.7</td><td align="left">Utilities</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">26.4.7.1</td><td align="left">Class <code class="code">seed_seq</code></td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">26.4.7.2</td><td align="left">Function template <code class="code">generate_canonical</code></td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">26.4.8</td><td align="left">Random number generation class templates</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">26.4.8.1</td><td align="left">Uniform distributions</td><td align="left"> </td><td align="left"> </td><td align="left">partial</td><td align="left"> </td></tr><tr><td align="left">26.4.8.1</td><td align="left">Class template <code class="code">uniform_int_distribution</code></td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">26.4.8.1</td><td align="left">Class template <code class="code">uniform_real_distribution</code></td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">26.4.8.2</td><td align="left">Bernoulli distributions</td><td align="left"> </td><td align="left"> </td><td align="left">partial</td><td align="left"> </td></tr><tr><td align="left">26.4.8.2.1</td><td align="left">Class <code class="code">bernoulli_distribution</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">26.4.8.2.2</td><td align="left">Class template <code class="code">binomial_distribution</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">26.4.8.2.3</td><td align="left">Class template <code class="code">geometric_distribution</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">26.4.8.2.4</td><td align="left">Class template <code class="code">negative_binomial_distribution</code></td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">26.4.8.3</td><td align="left">Poisson distributions</td><td align="left"> </td><td align="left"> </td><td align="left">partial</td><td align="left"> </td></tr><tr><td align="left">26.4.8.3.1</td><td align="left">Class template <code class="code">poisson_distribution</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">26.4.8.3.2</td><td align="left">Class template <code class="code">exponential_distribution</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">26.4.8.3.3</td><td align="left">Class template <code class="code">gamma_distribution</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">26.4.8.3.4</td><td align="left">Class template <code class="code">weibull_distribution</code></td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">26.4.8.3.5</td><td align="left">Class template <code class="code">extreme_value_distribution</code></td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">26.4.8.4</td><td align="left">Normal distributions</td><td align="left"> </td><td align="left"> </td><td align="left">partial</td><td align="left"> </td></tr><tr><td align="left">26.4.8.4.1</td><td align="left">Class template <code class="code">normal_distribution</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">26.4.8.4.2</td><td align="left">Class template <code class="code">lognormal_distribution</code></td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">26.4.8.4.3</td><td align="left">Class template <code class="code">chi_squared_distribution</code></td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">26.4.8.4.4</td><td align="left">Class template <code class="code">cauchy_distribution</code></td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">26.4.8.4.5</td><td align="left">Class template <code class="code">fisher_f_distribution</code></td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">26.4.8.4.6</td><td align="left">Class template <code class="code">student_t_distribution</code></td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">26.4.8.5</td><td align="left">Sampling distributions</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">26.4.8.5.1</td><td align="left">Class template <code class="code">discrete_distribution</code></td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">26.4.8.5.1</td><td align="left">Class template <code class="code">piecewise_constant_distribution</code></td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">26.4.8.5.1</td><td align="left">Class template <code class="code">general_pdf_distribution</code></td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left"><span class="emphasis"><em>28</em></span></td><td colspan="5" align="left"><span class="emphasis"><em>Regular Expressions</em></span></td></tr><tr><td align="left">28.1</td><td align="left">Definitions</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">28.2</td><td align="left">Requirements</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">28.3</td><td align="left">Regular expressions summary</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">28.4</td><td align="left">Header <code class="code">&lt;regex&gt;</code> synopsis</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">28.5</td><td align="left">Namespace <code class="code">tr1::regex_constants</code></td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">28.5.1</td><td align="left">Bitmask Type <code class="code">syntax_option_type</code></td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">28.5.2</td><td align="left">Bitmask Type <code class="code">regex_constants::match_flag_type</code></td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">28.5.3</td><td align="left">Implementation defined <code class="code">error_type</code></td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">28.6</td><td align="left">Class <code class="code">regex_error</code></td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">28.7</td><td align="left">Class template <code class="code">regex_traits</code></td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">28.8</td><td align="left">Class template <code class="code">basic_regex</code></td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">28.8.1</td><td align="left"><code class="code">basic_regex</code> constants</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">28.8.2</td><td align="left"><code class="code">basic_regex</code> constructors</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">28.8.3</td><td align="left"><code class="code">basic_regex</code> assign</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">28.8.4</td><td align="left"><code class="code">basic_regex</code> constant operations</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">28.8.5</td><td align="left"><code class="code">basic_regex</code> locale</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">28.8.6</td><td align="left"><code class="code">basic_regex</code> swap</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">28.8.7</td><td align="left"><code class="code">basic_regex</code> non-member functions</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">28.8.7.1</td><td align="left"><code class="code">basic_regex</code> non-member swap</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">28.9</td><td align="left">Class template <code class="code">sub_match</code></td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">28.9.1</td><td align="left"><code class="code">sub_match</code> members</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">28.9.2</td><td align="left"><code class="code">sub_match</code> non-member operators</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">28.10</td><td align="left">Class template <code class="code">match_results</code></td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">28.10.1</td><td align="left"><code class="code">match_results</code> constructors</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">28.10.2</td><td align="left"><code class="code">match_results</code> size</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">28.10.3</td><td align="left"><code class="code">match_results</code> element access</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">28.10.4</td><td align="left"><code class="code">match_results</code> formatting</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">28.10.5</td><td align="left"><code class="code">match_results</code> allocator</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">28.10.6</td><td align="left"><code class="code">match_results</code> swap</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">28.11</td><td align="left">Regular expression algorithms</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">28.11.1</td><td align="left">exceptions</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">28.11.2</td><td align="left"><code class="code">regex_match</code></td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">28.11.3</td><td align="left"><code class="code">regex_search</code></td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">28.11.4</td><td align="left"><code class="code">regex_replace</code></td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">28.12</td><td align="left">Regular expression Iterators</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">28.12.1</td><td align="left">Class template <code class="code">regex_iterator</code></td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">28.12.1.1</td><td align="left"><code class="code">regex_iterator</code> constructors</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">28.12.1.2</td><td align="left"><code class="code">regex_iterator</code> comparisons</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">28.12.1.3</td><td align="left"><code class="code">regex_iterator</code> dereference</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">28.12.1.4</td><td align="left"><code class="code">regex_iterator</code> increment</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">28.12.2</td><td align="left">Class template <code class="code">regex_token_iterator</code></td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">28.12.2.1</td><td align="left"><code class="code">regex_token_iterator</code> constructors</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">28.12.2.2</td><td align="left"><code class="code">regex_token_iterator</code> comparisons</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">28.12.2.3</td><td align="left"><code class="code">regex_token_iterator</code> dereference</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">28.12.2.4</td><td align="left"><code class="code">regex_token_iterator</code> increment</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">28.13</td><td align="left">Modified ECMAScript regular expression grammar</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left"><span class="emphasis"><em>C</em></span></td><td colspan="5" align="left"><span class="emphasis"><em>C Compatibility</em></span></td></tr><tr><td align="left">C2.1</td><td align="left">Additions to header <code class="code">&lt;complex&gt;</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">C2.1.1</td><td align="left">Synopsis</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">C2.1.2</td><td align="left">Function <code class="code">acos</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">C2.1.3</td><td align="left">Function <code class="code">asin</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">C2.1.4</td><td align="left">Function <code class="code">atan</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">C2.1.5</td><td align="left">Function <code class="code">acosh</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">C2.1.6</td><td align="left">Function <code class="code">asinh</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">C2.1.7</td><td align="left">Function <code class="code">atanh</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">C2.1.8</td><td align="left">Function <code class="code">fabs</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">C2.1.9</td><td align="left">Additional Overloads</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">C2.2</td><td align="left">Header <code class="code">&lt;ccomplex&gt;</code></td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left">DR 551</td></tr><tr><td align="left">C2.3</td><td align="left">Header <code class="code">&lt;complex.h&gt;</code></td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left">DR 551</td></tr><tr><td align="left">C2.4</td><td align="left">Additions to header <code class="code">&lt;cctype&gt;</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">C2.4.1</td><td align="left">Synopsis</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">C2.4.2</td><td align="left">Function <code class="code">isblank</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">C2.5</td><td align="left">Additions to header <code class="code">&lt;ctype.h&gt;</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">C2.6</td><td align="left">Header <code class="code">&lt;cfenv&gt;</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">C2.6.1</td><td align="left">Synopsis</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">C2.6.2</td><td align="left">Definitions</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">C2.7</td><td align="left">Header <code class="code">&lt;fenv.h&gt;</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">C2.8</td><td align="left">Additions to header <code class="code">&lt;cfloat&gt;</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">C2.9</td><td align="left">Additions to header <code class="code">&lt;float.h&gt;</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">C2.10</td><td align="left">Additions to header <code class="code">&lt;ios&gt;</code></td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">C2.10.1</td><td align="left">Synopsis</td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">C2.10.2</td><td align="left">Function <code class="code">hexfloat</code></td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">C2.11</td><td align="left">Header <code class="code">&lt;cinttypes&gt;</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">C2.11.1</td><td align="left">Synopsis</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left">DR 557</td></tr><tr><td align="left">C2.11.2</td><td align="left">Definitions</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">C2.12</td><td align="left">Header <code class="code">&lt;inttypes.h&gt;</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">C2.13</td><td align="left">Additions to header <code class="code">&lt;climits&gt;</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">C2.14</td><td align="left">Additions to header <code class="code">&lt;limits.h&gt;</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">C2.15</td><td align="left">Additions to header <code class="code">&lt;locale&gt;</code></td><td align="left"> </td><td align="left"> </td><td align="left">missing</td><td align="left"> </td></tr><tr><td align="left">C2.16</td><td align="left">Additions to header <code class="code">&lt;cmath&gt;</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">C2.16.1</td><td align="left">Synopsis</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">C2.16.2</td><td align="left">Definitions</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">C2.16.3</td><td align="left">Function template definitions</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">C2.16.4</td><td align="left">Additional overloads</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left">DR 568; DR 550</td></tr><tr><td align="left">C2.17</td><td align="left">Additions to header <code class="code">&lt;math.h&gt;</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">C2.18</td><td align="left">Additions to header <code class="code">&lt;cstdarg&gt;</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">C2.19</td><td align="left">Additions to header <code class="code">&lt;stdarg.h&gt;</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">C2.20</td><td align="left">The header <code class="code">&lt;cstdbool&gt;</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">C2.21</td><td align="left">The header <code class="code">&lt;stdbool.h&gt;</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">C2.22</td><td align="left">The header <code class="code">&lt;cstdint&gt;</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">C2.22.1</td><td align="left">Synopsis</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">C2.22.2</td><td align="left">Definitions</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">C2.23</td><td align="left">The header <code class="code">&lt;stdint.h&gt;</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">C2.24</td><td align="left">Additions to header <code class="code">&lt;cstdio&gt;</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">C2.24.1</td><td align="left">Synopsis</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">C2.24.2</td><td align="left">Definitions</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">C2.24.3</td><td align="left">Additional format specifiers</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left">C library responsibility</td></tr><tr><td align="left">C2.24.4</td><td align="left">Additions to header <code class="code">&lt;stdio.h&gt;</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">C2.25</td><td align="left">Additions to header <code class="code">&lt;cstdlib&gt;</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">C2.25.1</td><td align="left">Synopsis</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">C2.25.2</td><td align="left">Definitions</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">C2.25.3</td><td align="left">Function <code class="code">abs</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">C2.25.4</td><td align="left">Function <code class="code">div</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">C2.26</td><td align="left">Additions to header <code class="code">&lt;stdlib.h&gt;</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">C2.27</td><td align="left">Header <code class="code">&lt;ctgmath&gt;</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left">DR 551</td></tr><tr><td align="left">C2.28</td><td align="left">Header <code class="code">&lt;tgmath.h&gt;</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left">DR 551</td></tr><tr><td align="left">C2.29</td><td align="left">Additions to header <code class="code">&lt;ctime&gt;</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left">C library responsibility</td></tr><tr><td align="left">C2.30</td><td align="left">Additions to header <code class="code">&lt;cwchar&gt;</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">C2.30.1</td><td align="left">Synopsis</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">C2.30.2</td><td align="left">Definitions</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">C2.30.3</td><td align="left">Additional wide format specifiers</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left">C library responsibility</td></tr><tr><td align="left">C2.31</td><td align="left">Additions to header <code class="code">&lt;wchar.h&gt;</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">C2.32</td><td align="left">Additions to header <code class="code">&lt;cwctype&gt;</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">C2.32.1</td><td align="left">Synopsis</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">C2.32.2</td><td align="left">Function <code class="code">iswblank</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">C2.33</td><td align="left">Additions to header <code class="code">&lt;wctype.h&gt;</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left"><span class="emphasis"><em>D</em></span></td><td colspan="5" align="left"><span class="emphasis"><em>Compatibility Features</em></span></td></tr><tr><td align="left">D.6</td><td align="left">Old iostream members</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr><tr><td align="left">D.8</td><td align="left">Binders</td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"><a class="ulink" href="http://gcc.gnu.org/PR33911" target="_top">33911</a></td></tr><tr><td align="left">D.9</td><td align="left">Class template <code class="code">auto_ptr</code></td><td align="left">done</td><td align="left"> </td><td align="left"> </td><td align="left"><a class="ulink" href="http://gcc.gnu.org/PR33911" target="_top">33911</a></td></tr></tbody></table></div></div><br class="table-break" /><p>
Footnotes
diff --git a/libstdc++-v3/doc/html/manual/bk01pt01ch03s02.html b/libstdc++-v3/doc/html/manual/bk01pt01ch03s02.html
index 7065e20c876..ba8763dec0e 100644
--- a/libstdc++-v3/doc/html/manual/bk01pt01ch03s02.html
+++ b/libstdc++-v3/doc/html/manual/bk01pt01ch03s02.html
@@ -20,14 +20,14 @@
upcoming 200x standard.
</p><p>
C++98/03 include files. These are available in the default compilation mode, i.e. <code class="code">-std=c++98</code> or <code class="code">-std=gnu++98</code>.
- </p><div class="table"><a id="id559438"></a><p class="title"><b>Table 3.1. C++ 1998 Library Headers</b></p><div class="table-contents"><table summary="C++ 1998 Library Headers" border="1"><colgroup><col align="left" /><col align="left" /><col align="left" /><col align="left" /><col /></colgroup><tbody><tr><td align="left"><code class="filename">algorithm</code></td><td align="left"><code class="filename">iomanip</code></td><td align="left"><code class="filename">list</code></td><td align="left"><code class="filename">ostream</code></td><td align="left"><code class="filename">streambuf</code></td></tr><tr><td align="left"><code class="filename">bitset</code></td><td align="left"><code class="filename">ios</code></td><td align="left"><code class="filename">locale</code></td><td align="left"><code class="filename">queue</code></td><td align="left"><code class="filename">string</code></td></tr><tr><td align="left"><code class="filename">complex</code></td><td align="left"><code class="filename">iosfwd</code></td><td align="left"><code class="filename">map</code></td><td align="left"><code class="filename">set</code></td><td align="left"><code class="filename">typeinfo</code></td></tr><tr><td align="left"><code class="filename">deque</code></td><td align="left"><code class="filename">iostream</code></td><td align="left"><code class="filename">memory</code></td><td align="left"><code class="filename">sstream</code></td><td align="left"><code class="filename">utility</code></td></tr><tr><td align="left"><code class="filename">exception</code></td><td align="left"><code class="filename">istream</code></td><td align="left"><code class="filename">new</code></td><td align="left"><code class="filename">stack</code></td><td align="left"><code class="filename">valarray</code></td></tr><tr><td align="left"><code class="filename">fstream</code></td><td align="left"><code class="filename">iterator</code></td><td align="left"><code class="filename">numeric</code></td><td align="left"><code class="filename">stdexcept</code></td><td align="left"><code class="filename">vector</code></td></tr><tr><td align="left"><code class="filename">functional</code></td><td align="left"><code class="filename">limits</code></td><td class="auto-generated"> </td><td class="auto-generated"> </td><td class="auto-generated"> </td></tr></tbody></table></div></div><br class="table-break" /><p></p><div class="table"><a id="id638001"></a><p class="title"><b>Table 3.2. C++ 1998 Library Headers for C Library Facilities</b></p><div class="table-contents"><table summary="C++ 1998 Library Headers for C Library Facilities" border="1"><colgroup><col align="left" /><col align="left" /><col align="left" /><col align="left" /><col /></colgroup><tbody><tr><td align="left"><code class="filename">cassert</code></td><td align="left"><code class="filename">ciso646</code></td><td align="left"><code class="filename">csetjmp</code></td><td align="left"><code class="filename">cstdio</code></td><td align="left"><code class="filename">ctime</code></td></tr><tr><td align="left"><code class="filename">cctype</code></td><td align="left"><code class="filename">climits</code></td><td align="left"><code class="filename">csignal</code></td><td align="left"><code class="filename">cstdlib</code></td><td align="left"><code class="filename">cwchar</code></td></tr><tr><td align="left"><code class="filename">cerrno</code></td><td align="left"><code class="filename">clocale</code></td><td align="left"><code class="filename">cstdarg</code></td><td align="left"><code class="filename">cstring</code></td><td align="left"><code class="filename">cwctype</code></td></tr><tr><td align="left"><code class="filename">cfloat</code></td><td align="left"><code class="filename">cmath</code></td><td align="left"><code class="filename">cstddef</code></td><td class="auto-generated"> </td><td class="auto-generated"> </td></tr></tbody></table></div></div><br class="table-break" /><p>C++0x include files. These are only available in C++0x compilation mode, i.e. <code class="code">-std=c++0x</code> or <code class="code">-std=gnu++0x</code>.
-</p><p></p><div class="table"><a id="id573284"></a><p class="title"><b>Table 3.3. C++ 200x Library Headers</b></p><div class="table-contents"><table summary="C++ 200x Library Headers" border="1"><colgroup><col align="left" /><col align="left" /><col align="left" /><col align="left" /><col /></colgroup><tbody><tr><td align="left"><code class="filename">algorithm</code></td><td align="left"><code class="filename">iomanip</code></td><td align="left"><code class="filename">locale</code></td><td align="left"><code class="filename">regex</code></td><td align="left"><code class="filename">tuple</code></td></tr><tr><td align="left"><code class="filename">array</code></td><td align="left"><code class="filename">ios</code></td><td align="left"><code class="filename">map</code></td><td align="left"><code class="filename">set</code></td><td align="left"><code class="filename">typeinfo</code></td></tr><tr><td align="left"><code class="filename">bitset</code></td><td align="left"><code class="filename">iosfwd</code></td><td align="left"><code class="filename">memory</code></td><td align="left"><code class="filename">sstream</code></td><td align="left"><code class="filename">type_traits</code></td></tr><tr><td align="left"><code class="filename">complex</code></td><td align="left"><code class="filename">iostream</code></td><td align="left"><code class="filename">new</code></td><td align="left"><code class="filename">stack</code></td><td align="left"><code class="filename">unordered_map</code></td></tr><tr><td align="left"><code class="filename">deque</code></td><td align="left"><code class="filename">istream</code></td><td align="left"><code class="filename">numeric</code></td><td align="left"><code class="filename">stdexcept</code></td><td align="left"><code class="filename">unordered_set</code></td></tr><tr><td align="left"><code class="filename">exception</code></td><td align="left"><code class="filename">iterator</code></td><td align="left"><code class="filename">ostream</code></td><td align="left"><code class="filename">streambuf</code></td><td align="left"><code class="filename">utility</code></td></tr><tr><td align="left"><code class="filename">fstream</code></td><td align="left"><code class="filename">limits</code></td><td align="left"><code class="filename">queue</code></td><td align="left"><code class="filename">string</code></td><td align="left"><code class="filename">valarray</code></td></tr><tr><td align="left"><code class="filename">functional</code></td><td align="left"><code class="filename">list</code></td><td align="left"><code class="filename">random</code></td><td align="left"><code class="filename">system_error</code></td><td align="left"><code class="filename">vector</code></td></tr><tr><td align="left"><code class="filename">condition_variable</code></td><td align="left"><code class="filename">mutex</code></td><td align="left"><code class="filename">thread</code></td><td align="left"> </td><td align="left"> </td></tr></tbody></table></div></div><br class="table-break" /><p></p><div class="table"><a id="id555603"></a><p class="title"><b>Table 3.4. C++ 200x Library Headers for C Library Facilities</b></p><div class="table-contents"><table summary="C++ 200x Library Headers for C Library Facilities" border="1"><colgroup><col align="left" /><col align="left" /><col align="left" /><col align="left" /><col align="left" /></colgroup><tbody><tr><td align="left"><code class="filename">cassert</code></td><td align="left"><code class="filename">cfloat</code></td><td align="left"><code class="filename">cmath</code></td><td align="left"><code class="filename">cstddef</code></td><td align="left"><code class="filename">ctgmath</code></td></tr><tr><td align="left"><code class="filename">ccomplex</code></td><td align="left"><code class="filename">cinttypes</code></td><td align="left"><code class="filename">csetjmp</code></td><td align="left"><code class="filename">cstdint</code></td><td align="left"><code class="filename">ctime</code></td></tr><tr><td align="left"><code class="filename">cctype</code></td><td align="left"><code class="filename">ciso646</code></td><td align="left"><code class="filename">csignal</code></td><td align="left"><code class="filename">cstdio</code></td><td align="left"><code class="filename">cuchar</code></td></tr><tr><td align="left"><code class="filename">cerrno</code></td><td align="left"><code class="filename">climits</code></td><td align="left"><code class="filename">cstdarg</code></td><td align="left"><code class="filename">cstdlib</code></td><td align="left"><code class="filename">cwchar</code></td></tr><tr><td align="left"><code class="filename">cfenv</code></td><td align="left"><code class="filename">clocale</code></td><td align="left"><code class="filename">cstdbool</code></td><td align="left"><code class="filename">cstring</code></td><td align="left"><code class="filename">cwctype</code></td></tr><tr><td align="left"><code class="filename">cstdatomic</code></td><td align="left"> </td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr></tbody></table></div></div><br class="table-break" /><p>
+ </p><div class="table"><a id="id394301"></a><p class="title"><b>Table 3.1. C++ 1998 Library Headers</b></p><div class="table-contents"><table summary="C++ 1998 Library Headers" border="1"><colgroup><col align="left" /><col align="left" /><col align="left" /><col align="left" /><col /></colgroup><tbody><tr><td align="left"><code class="filename">algorithm</code></td><td align="left"><code class="filename">iomanip</code></td><td align="left"><code class="filename">list</code></td><td align="left"><code class="filename">ostream</code></td><td align="left"><code class="filename">streambuf</code></td></tr><tr><td align="left"><code class="filename">bitset</code></td><td align="left"><code class="filename">ios</code></td><td align="left"><code class="filename">locale</code></td><td align="left"><code class="filename">queue</code></td><td align="left"><code class="filename">string</code></td></tr><tr><td align="left"><code class="filename">complex</code></td><td align="left"><code class="filename">iosfwd</code></td><td align="left"><code class="filename">map</code></td><td align="left"><code class="filename">set</code></td><td align="left"><code class="filename">typeinfo</code></td></tr><tr><td align="left"><code class="filename">deque</code></td><td align="left"><code class="filename">iostream</code></td><td align="left"><code class="filename">memory</code></td><td align="left"><code class="filename">sstream</code></td><td align="left"><code class="filename">utility</code></td></tr><tr><td align="left"><code class="filename">exception</code></td><td align="left"><code class="filename">istream</code></td><td align="left"><code class="filename">new</code></td><td align="left"><code class="filename">stack</code></td><td align="left"><code class="filename">valarray</code></td></tr><tr><td align="left"><code class="filename">fstream</code></td><td align="left"><code class="filename">iterator</code></td><td align="left"><code class="filename">numeric</code></td><td align="left"><code class="filename">stdexcept</code></td><td align="left"><code class="filename">vector</code></td></tr><tr><td align="left"><code class="filename">functional</code></td><td align="left"><code class="filename">limits</code></td><td class="auto-generated"> </td><td class="auto-generated"> </td><td class="auto-generated"> </td></tr></tbody></table></div></div><br class="table-break" /><p></p><div class="table"><a id="id440630"></a><p class="title"><b>Table 3.2. C++ 1998 Library Headers for C Library Facilities</b></p><div class="table-contents"><table summary="C++ 1998 Library Headers for C Library Facilities" border="1"><colgroup><col align="left" /><col align="left" /><col align="left" /><col align="left" /><col /></colgroup><tbody><tr><td align="left"><code class="filename">cassert</code></td><td align="left"><code class="filename">ciso646</code></td><td align="left"><code class="filename">csetjmp</code></td><td align="left"><code class="filename">cstdio</code></td><td align="left"><code class="filename">ctime</code></td></tr><tr><td align="left"><code class="filename">cctype</code></td><td align="left"><code class="filename">climits</code></td><td align="left"><code class="filename">csignal</code></td><td align="left"><code class="filename">cstdlib</code></td><td align="left"><code class="filename">cwchar</code></td></tr><tr><td align="left"><code class="filename">cerrno</code></td><td align="left"><code class="filename">clocale</code></td><td align="left"><code class="filename">cstdarg</code></td><td align="left"><code class="filename">cstring</code></td><td align="left"><code class="filename">cwctype</code></td></tr><tr><td align="left"><code class="filename">cfloat</code></td><td align="left"><code class="filename">cmath</code></td><td align="left"><code class="filename">cstddef</code></td><td class="auto-generated"> </td><td class="auto-generated"> </td></tr></tbody></table></div></div><br class="table-break" /><p>C++0x include files. These are only available in C++0x compilation mode, i.e. <code class="code">-std=c++0x</code> or <code class="code">-std=gnu++0x</code>.
+</p><p></p><div class="table"><a id="id382991"></a><p class="title"><b>Table 3.3. C++ 200x Library Headers</b></p><div class="table-contents"><table summary="C++ 200x Library Headers" border="1"><colgroup><col align="left" /><col align="left" /><col align="left" /><col align="left" /><col /></colgroup><tbody><tr><td align="left"><code class="filename">algorithm</code></td><td align="left"><code class="filename">iomanip</code></td><td align="left"><code class="filename">locale</code></td><td align="left"><code class="filename">regex</code></td><td align="left"><code class="filename">tuple</code></td></tr><tr><td align="left"><code class="filename">array</code></td><td align="left"><code class="filename">ios</code></td><td align="left"><code class="filename">map</code></td><td align="left"><code class="filename">set</code></td><td align="left"><code class="filename">typeinfo</code></td></tr><tr><td align="left"><code class="filename">bitset</code></td><td align="left"><code class="filename">iosfwd</code></td><td align="left"><code class="filename">memory</code></td><td align="left"><code class="filename">sstream</code></td><td align="left"><code class="filename">type_traits</code></td></tr><tr><td align="left"><code class="filename">complex</code></td><td align="left"><code class="filename">iostream</code></td><td align="left"><code class="filename">new</code></td><td align="left"><code class="filename">stack</code></td><td align="left"><code class="filename">unordered_map</code></td></tr><tr><td align="left"><code class="filename">deque</code></td><td align="left"><code class="filename">istream</code></td><td align="left"><code class="filename">numeric</code></td><td align="left"><code class="filename">stdexcept</code></td><td align="left"><code class="filename">unordered_set</code></td></tr><tr><td align="left"><code class="filename">exception</code></td><td align="left"><code class="filename">iterator</code></td><td align="left"><code class="filename">ostream</code></td><td align="left"><code class="filename">streambuf</code></td><td align="left"><code class="filename">utility</code></td></tr><tr><td align="left"><code class="filename">fstream</code></td><td align="left"><code class="filename">limits</code></td><td align="left"><code class="filename">queue</code></td><td align="left"><code class="filename">string</code></td><td align="left"><code class="filename">valarray</code></td></tr><tr><td align="left"><code class="filename">functional</code></td><td align="left"><code class="filename">list</code></td><td align="left"><code class="filename">random</code></td><td align="left"><code class="filename">system_error</code></td><td align="left"><code class="filename">vector</code></td></tr><tr><td align="left"><code class="filename">condition_variable</code></td><td align="left"><code class="filename">mutex</code></td><td align="left"><code class="filename">thread</code></td><td align="left"> </td><td align="left"> </td></tr></tbody></table></div></div><br class="table-break" /><p></p><div class="table"><a id="id425965"></a><p class="title"><b>Table 3.4. C++ 200x Library Headers for C Library Facilities</b></p><div class="table-contents"><table summary="C++ 200x Library Headers for C Library Facilities" border="1"><colgroup><col align="left" /><col align="left" /><col align="left" /><col align="left" /><col align="left" /></colgroup><tbody><tr><td align="left"><code class="filename">cassert</code></td><td align="left"><code class="filename">cfloat</code></td><td align="left"><code class="filename">cmath</code></td><td align="left"><code class="filename">cstddef</code></td><td align="left"><code class="filename">ctgmath</code></td></tr><tr><td align="left"><code class="filename">ccomplex</code></td><td align="left"><code class="filename">cinttypes</code></td><td align="left"><code class="filename">csetjmp</code></td><td align="left"><code class="filename">cstdint</code></td><td align="left"><code class="filename">ctime</code></td></tr><tr><td align="left"><code class="filename">cctype</code></td><td align="left"><code class="filename">ciso646</code></td><td align="left"><code class="filename">csignal</code></td><td align="left"><code class="filename">cstdio</code></td><td align="left"><code class="filename">cuchar</code></td></tr><tr><td align="left"><code class="filename">cerrno</code></td><td align="left"><code class="filename">climits</code></td><td align="left"><code class="filename">cstdarg</code></td><td align="left"><code class="filename">cstdlib</code></td><td align="left"><code class="filename">cwchar</code></td></tr><tr><td align="left"><code class="filename">cfenv</code></td><td align="left"><code class="filename">clocale</code></td><td align="left"><code class="filename">cstdbool</code></td><td align="left"><code class="filename">cstring</code></td><td align="left"><code class="filename">cwctype</code></td></tr><tr><td align="left"><code class="filename">cstdatomic</code></td><td align="left"> </td><td align="left"> </td><td align="left"> </td><td align="left"> </td></tr></tbody></table></div></div><br class="table-break" /><p>
In addition, TR1 includes as:
-</p><div class="table"><a id="id556833"></a><p class="title"><b>Table 3.5. C++ TR1 Library Headers</b></p><div class="table-contents"><table summary="C++ TR1 Library Headers" border="1"><colgroup><col align="left" /><col align="left" /><col align="left" /><col align="left" /><col align="left" /></colgroup><tbody><tr><td align="left"><code class="filename">tr1/array</code></td><td align="left"><code class="filename">tr1/memory</code></td><td align="left"><code class="filename">tr1/regex</code></td><td align="left"><code class="filename">tr1/type_traits</code></td><td align="left"><code class="filename">tr1/unordered_set</code></td></tr><tr><td align="left"><code class="filename">tr1/complex</code></td><td align="left"><code class="filename">tr1/random</code></td><td align="left"><code class="filename">tr1/tuple</code></td><td align="left"><code class="filename">tr1/unordered_map</code></td><td align="left"><code class="filename">tr1/utility</code></td></tr><tr><td align="left"><code class="filename">tr1/functional</code></td><td class="auto-generated"> </td><td class="auto-generated"> </td><td class="auto-generated"> </td><td class="auto-generated"> </td></tr></tbody></table></div></div><br class="table-break" /><p></p><div class="table"><a id="id548044"></a><p class="title"><b>Table 3.6. C++ TR1 Library Headers for C Library Facilities</b></p><div class="table-contents"><table summary="C++ TR1 Library Headers for C Library Facilities" border="1"><colgroup><col align="left" /><col align="left" /><col align="left" /><col align="left" /><col align="left" /></colgroup><tbody><tr><td align="left"><code class="filename">tr1/cmath</code></td><td align="left"><code class="filename">tr1/cfloat</code></td><td align="left"><code class="filename">tr1/cstdarg</code></td><td align="left"><code class="filename">tr1/cstdio</code></td><td align="left"><code class="filename">tr1/ctime</code></td></tr><tr><td align="left"><code class="filename">tr1/ccomplex</code></td><td align="left"><code class="filename">tr1/cinttypes</code></td><td align="left"><code class="filename">tr1/cstdbool</code></td><td align="left"><code class="filename">tr1/cstdlib</code></td><td align="left"><code class="filename">tr1/cwchar</code></td></tr><tr><td align="left"><code class="filename">tr1/cfenv</code></td><td align="left"><code class="filename">tr1/climits</code></td><td align="left"><code class="filename">tr1/cstdint</code></td><td align="left"><code class="filename">tr1/ctgmath</code></td><td align="left"><code class="filename">tr1/cwctype</code></td></tr></tbody></table></div></div><br class="table-break" /><p>
+</p><div class="table"><a id="id442369"></a><p class="title"><b>Table 3.5. C++ TR1 Library Headers</b></p><div class="table-contents"><table summary="C++ TR1 Library Headers" border="1"><colgroup><col align="left" /><col align="left" /><col align="left" /><col align="left" /><col align="left" /></colgroup><tbody><tr><td align="left"><code class="filename">tr1/array</code></td><td align="left"><code class="filename">tr1/memory</code></td><td align="left"><code class="filename">tr1/regex</code></td><td align="left"><code class="filename">tr1/type_traits</code></td><td align="left"><code class="filename">tr1/unordered_set</code></td></tr><tr><td align="left"><code class="filename">tr1/complex</code></td><td align="left"><code class="filename">tr1/random</code></td><td align="left"><code class="filename">tr1/tuple</code></td><td align="left"><code class="filename">tr1/unordered_map</code></td><td align="left"><code class="filename">tr1/utility</code></td></tr><tr><td align="left"><code class="filename">tr1/functional</code></td><td class="auto-generated"> </td><td class="auto-generated"> </td><td class="auto-generated"> </td><td class="auto-generated"> </td></tr></tbody></table></div></div><br class="table-break" /><p></p><div class="table"><a id="id401478"></a><p class="title"><b>Table 3.6. C++ TR1 Library Headers for C Library Facilities</b></p><div class="table-contents"><table summary="C++ TR1 Library Headers for C Library Facilities" border="1"><colgroup><col align="left" /><col align="left" /><col align="left" /><col align="left" /><col align="left" /></colgroup><tbody><tr><td align="left"><code class="filename">tr1/cmath</code></td><td align="left"><code class="filename">tr1/cfloat</code></td><td align="left"><code class="filename">tr1/cstdarg</code></td><td align="left"><code class="filename">tr1/cstdio</code></td><td align="left"><code class="filename">tr1/ctime</code></td></tr><tr><td align="left"><code class="filename">tr1/ccomplex</code></td><td align="left"><code class="filename">tr1/cinttypes</code></td><td align="left"><code class="filename">tr1/cstdbool</code></td><td align="left"><code class="filename">tr1/cstdlib</code></td><td align="left"><code class="filename">tr1/cwchar</code></td></tr><tr><td align="left"><code class="filename">tr1/cfenv</code></td><td align="left"><code class="filename">tr1/climits</code></td><td align="left"><code class="filename">tr1/cstdint</code></td><td align="left"><code class="filename">tr1/ctgmath</code></td><td align="left"><code class="filename">tr1/cwctype</code></td></tr></tbody></table></div></div><br class="table-break" /><p>
Also included are files for the C++ ABI interface:
-</p><div class="table"><a id="id634486"></a><p class="title"><b>Table 3.7. C++ ABI Headers</b></p><div class="table-contents"><table summary="C++ ABI Headers" border="1"><colgroup><col align="left" /><col align="left" /></colgroup><tbody><tr><td align="left"><code class="filename">cxxabi.h</code></td><td align="left"><code class="filename">cxxabi_forced.h</code></td></tr></tbody></table></div></div><br class="table-break" /><p>
+</p><div class="table"><a id="id435323"></a><p class="title"><b>Table 3.7. C++ ABI Headers</b></p><div class="table-contents"><table summary="C++ ABI Headers" border="1"><colgroup><col align="left" /><col align="left" /></colgroup><tbody><tr><td align="left"><code class="filename">cxxabi.h</code></td><td align="left"><code class="filename">cxxabi_forced.h</code></td></tr></tbody></table></div></div><br class="table-break" /><p>
And a large variety of extensions.
-</p><div class="table"><a id="id624264"></a><p class="title"><b>Table 3.8. Extension Headers</b></p><div class="table-contents"><table summary="Extension Headers" border="1"><colgroup><col align="left" /><col align="left" /><col align="left" /><col align="left" /><col align="left" /></colgroup><tbody><tr><td align="left"><code class="filename">ext/algorithm</code></td><td align="left"><code class="filename">ext/debug_allocator.h</code></td><td align="left"><code class="filename">ext/mt_allocator.h</code></td><td align="left"><code class="filename">ext/pod_char_traits.h</code></td><td align="left"><code class="filename">ext/stdio_sync_filebuf.h</code></td></tr><tr><td align="left"><code class="filename">ext/array_allocator.h</code></td><td align="left"><code class="filename">ext/enc_filebuf.h</code></td><td align="left"><code class="filename">ext/new_allocator.h</code></td><td align="left"><code class="filename">ext/pool_allocator.h</code></td><td align="left"><code class="filename">ext/throw_allocator.h</code></td></tr><tr><td align="left"><code class="filename">ext/atomicity.h</code></td><td align="left"><code class="filename">ext/functional</code></td><td align="left"><code class="filename">ext/numeric</code></td><td align="left"><code class="filename">ext/rb_tree</code></td><td align="left"><code class="filename">ext/typelist.h</code></td></tr><tr><td align="left"><code class="filename">ext/bitmap_allocator.h</code></td><td align="left"><code class="filename">ext/iterator</code></td><td align="left"><code class="filename">ext/numeric_traits.h</code></td><td align="left"><code class="filename">ext/rope</code></td><td align="left"><code class="filename">ext/type_traits.h</code></td></tr><tr><td align="left"><code class="filename">ext/codecvt_specializations.h</code></td><td align="left"><code class="filename">ext/malloc_allocator.h</code></td><td align="left"><code class="filename">ext/pb_ds/assoc_container.h</code></td><td align="left"><code class="filename">ext/slist</code></td><td align="left"><code class="filename">ext/vstring.h</code></td></tr><tr><td align="left"><code class="filename">ext/concurrence.h</code></td><td align="left"><code class="filename">ext/memory</code></td><td align="left"><code class="filename">ext/pb_ds/priority_queue.h</code></td><td align="left"><code class="filename">ext/stdio_filebuf.h</code></td><td class="auto-generated"> </td></tr></tbody></table></div></div><br class="table-break" /><p></p><div class="table"><a id="id648609"></a><p class="title"><b>Table 3.9. Extension Debug Headers</b></p><div class="table-contents"><table summary="Extension Debug Headers" border="1"><colgroup><col align="left" /><col align="left" /><col align="left" /><col align="left" /><col align="left" /></colgroup><tbody><tr><td align="left"><code class="filename">debug/bitset</code></td><td align="left"><code class="filename">debug/list</code></td><td align="left"><code class="filename">debug/set</code></td><td align="left"><code class="filename">debug/unordered_map</code></td><td align="left"><code class="filename">debug/vector</code></td></tr><tr><td align="left"><code class="filename">debug/deque</code></td><td align="left"><code class="filename">debug/map</code></td><td align="left"><code class="filename">debug/string</code></td><td align="left"><code class="filename">debug/unordered_set</code></td><td class="auto-generated"> </td></tr></tbody></table></div></div><br class="table-break" /><p></p><div class="table"><a id="id609186"></a><p class="title"><b>Table 3.10. Extension Parallel Headers</b></p><div class="table-contents"><table summary="Extension Parallel Headers" border="1"><colgroup><col align="left" /><col align="left" /></colgroup><tbody><tr><td align="left"><code class="filename">parallel/algorithm</code></td><td align="left"><code class="filename">parallel/numeric</code></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="sect2" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="manual.intro.using.headers.mixing"></a>Mixing Headers</h3></div></div></div><p> A few simple rules.
+</p><div class="table"><a id="id432329"></a><p class="title"><b>Table 3.8. Extension Headers</b></p><div class="table-contents"><table summary="Extension Headers" border="1"><colgroup><col align="left" /><col align="left" /><col align="left" /><col align="left" /><col align="left" /></colgroup><tbody><tr><td align="left"><code class="filename">ext/algorithm</code></td><td align="left"><code class="filename">ext/debug_allocator.h</code></td><td align="left"><code class="filename">ext/mt_allocator.h</code></td><td align="left"><code class="filename">ext/pod_char_traits.h</code></td><td align="left"><code class="filename">ext/stdio_sync_filebuf.h</code></td></tr><tr><td align="left"><code class="filename">ext/array_allocator.h</code></td><td align="left"><code class="filename">ext/enc_filebuf.h</code></td><td align="left"><code class="filename">ext/new_allocator.h</code></td><td align="left"><code class="filename">ext/pool_allocator.h</code></td><td align="left"><code class="filename">ext/throw_allocator.h</code></td></tr><tr><td align="left"><code class="filename">ext/atomicity.h</code></td><td align="left"><code class="filename">ext/functional</code></td><td align="left"><code class="filename">ext/numeric</code></td><td align="left"><code class="filename">ext/rb_tree</code></td><td align="left"><code class="filename">ext/typelist.h</code></td></tr><tr><td align="left"><code class="filename">ext/bitmap_allocator.h</code></td><td align="left"><code class="filename">ext/iterator</code></td><td align="left"><code class="filename">ext/numeric_traits.h</code></td><td align="left"><code class="filename">ext/rope</code></td><td align="left"><code class="filename">ext/type_traits.h</code></td></tr><tr><td align="left"><code class="filename">ext/codecvt_specializations.h</code></td><td align="left"><code class="filename">ext/malloc_allocator.h</code></td><td align="left"><code class="filename">ext/pb_ds/assoc_container.h</code></td><td align="left"><code class="filename">ext/slist</code></td><td align="left"><code class="filename">ext/vstring.h</code></td></tr><tr><td align="left"><code class="filename">ext/concurrence.h</code></td><td align="left"><code class="filename">ext/memory</code></td><td align="left"><code class="filename">ext/pb_ds/priority_queue.h</code></td><td align="left"><code class="filename">ext/stdio_filebuf.h</code></td><td class="auto-generated"> </td></tr></tbody></table></div></div><br class="table-break" /><p></p><div class="table"><a id="id440887"></a><p class="title"><b>Table 3.9. Extension Debug Headers</b></p><div class="table-contents"><table summary="Extension Debug Headers" border="1"><colgroup><col align="left" /><col align="left" /><col align="left" /><col align="left" /><col align="left" /></colgroup><tbody><tr><td align="left"><code class="filename">debug/bitset</code></td><td align="left"><code class="filename">debug/list</code></td><td align="left"><code class="filename">debug/set</code></td><td align="left"><code class="filename">debug/unordered_map</code></td><td align="left"><code class="filename">debug/vector</code></td></tr><tr><td align="left"><code class="filename">debug/deque</code></td><td align="left"><code class="filename">debug/map</code></td><td align="left"><code class="filename">debug/string</code></td><td align="left"><code class="filename">debug/unordered_set</code></td><td class="auto-generated"> </td></tr></tbody></table></div></div><br class="table-break" /><p></p><div class="table"><a id="id457206"></a><p class="title"><b>Table 3.10. Extension Parallel Headers</b></p><div class="table-contents"><table summary="Extension Parallel Headers" border="1"><colgroup><col align="left" /><col align="left" /></colgroup><tbody><tr><td align="left"><code class="filename">parallel/algorithm</code></td><td align="left"><code class="filename">parallel/numeric</code></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="sect2" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="manual.intro.using.headers.mixing"></a>Mixing Headers</h3></div></div></div><p> A few simple rules.
</p><p>First, mixing different dialects of the standard headers is not
possible. It's an all-or-nothing affair. Thus, code like
</p><pre class="programlisting">
diff --git a/libstdc++-v3/doc/html/manual/bk01pt02pr01.html b/libstdc++-v3/doc/html/manual/bk01pt02pr01.html
index 2d36c3f072f..6f7451e9ae7 100644
--- a/libstdc++-v3/doc/html/manual/bk01pt02pr01.html
+++ b/libstdc++-v3/doc/html/manual/bk01pt02pr01.html
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title></title><meta name="generator" content="DocBook XSL Stylesheets V1.73.2" /><meta name="keywords" content="&#10; ISO C++&#10; , &#10; library&#10; " /><link rel="start" href="../spine.html" title="The GNU C++ Library Documentation" /><link rel="up" href="support.html" title="Part II. Support" /><link rel="prev" href="support.html" title="Part II. Support" /><link rel="next" href="bk01pt02ch04.html" title="Chapter 4. Types" /></head><body><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center"></th></tr><tr><td width="20%" align="left"><a accesskey="p" href="support.html">Prev</a> </td><th width="60%" align="center">Part II. Support</th><td width="20%" align="right"> <a accesskey="n" href="bk01pt02ch04.html">Next</a></td></tr></table><hr /></div><div class="preface" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title"><a id="id580277"></a></h2></div></div></div><p>
+<html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title></title><meta name="generator" content="DocBook XSL Stylesheets V1.73.2" /><meta name="keywords" content="&#10; ISO C++&#10; , &#10; library&#10; " /><link rel="start" href="../spine.html" title="The GNU C++ Library Documentation" /><link rel="up" href="support.html" title="Part II. Support" /><link rel="prev" href="support.html" title="Part II. Support" /><link rel="next" href="bk01pt02ch04.html" title="Chapter 4. Types" /></head><body><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center"></th></tr><tr><td width="20%" align="left"><a accesskey="p" href="support.html">Prev</a> </td><th width="60%" align="center">Part II. Support</th><td width="20%" align="right"> <a accesskey="n" href="bk01pt02ch04.html">Next</a></td></tr></table><hr /></div><div class="preface" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title"><a id="id450521"></a></h2></div></div></div><p>
This part deals with the functions called and objects created
automatically during the course of a program's existence.
</p><p>
diff --git a/libstdc++-v3/doc/html/manual/bk01pt04ch11.html b/libstdc++-v3/doc/html/manual/bk01pt04ch11.html
index 6602bf43f6a..905be71755b 100644
--- a/libstdc++-v3/doc/html/manual/bk01pt04ch11.html
+++ b/libstdc++-v3/doc/html/manual/bk01pt04ch11.html
@@ -90,7 +90,7 @@
or loading and unloading shared objects in memory. As such, using
caching allocators on systems that do not support
<code class="function">abi::__cxa_atexit</code> is not recommended.
- </p></div><div class="sect2" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="allocator.impl"></a>Implementation</h3></div></div></div><div class="sect3" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="id648275"></a>Interface Design</h4></div></div></div><p>
+ </p></div><div class="sect2" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="allocator.impl"></a>Implementation</h3></div></div></div><div class="sect3" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="id388518"></a>Interface Design</h4></div></div></div><p>
The only allocator interface that
is support is the standard C++ interface. As such, all STL
containers have been adjusted, and all external allocators have
@@ -103,7 +103,7 @@
</p><p>
The base class that <code class="classname">allocator</code> is derived from
may not be user-configurable.
-</p></div><div class="sect3" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="id627020"></a>Selecting Default Allocation Policy</h4></div></div></div><p>
+</p></div><div class="sect3" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="id449357"></a>Selecting Default Allocation Policy</h4></div></div></div><p>
It's difficult to pick an allocation strategy that will provide
maximum utility, without excessively penalizing some behavior. In
fact, it's difficult just deciding which typical actions to measure
@@ -140,7 +140,7 @@
The current default choice for
<code class="classname">allocator</code> is
<code class="classname">__gnu_cxx::new_allocator</code>.
- </p></div><div class="sect3" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="id627284"></a>Disabling Memory Caching</h4></div></div></div><p>
+ </p></div><div class="sect3" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="id385486"></a>Disabling Memory Caching</h4></div></div></div><p>
In use, <code class="classname">allocator</code> may allocate and
deallocate using implementation-specified strategies and
heuristics. Because of this, every call to an allocator object's
@@ -298,18 +298,18 @@
</p><p>
A high-performance fixed-size allocator with
exponentially-increasing allocations. It has its own
- documentation, found <a class="ulink" href="../ext/mt_allocator.html" target="_top">here</a>.
+ documentation, found <a class="link" href="bk01pt12ch32.html#manual.ext.allocator.mt" title="mt_allocator">here</a>.
</p></li><li><p>
<code class="classname">bitmap_allocator</code>
</p><p>
A high-performance allocator that uses a bit-map to keep track
of the used and unused memory locations. It has its own
- documentation, found <a class="ulink" href="../ext/ballocator_doc.html" target="_top">here</a>.
- </p></li></ol></div></div><div class="bibliography"><div class="titlepage"><div><div><h3 class="title"><a id="allocator.biblio"></a>Bibliography</h3></div></div></div><div class="biblioentry"><a id="id611696"></a><p><span class="title"><i>
+ documentation, found <a class="link" href="bitmap_allocator.html" title="bitmap_allocator">here</a>.
+ </p></li></ol></div></div><div class="bibliography"><div class="titlepage"><div><div><h3 class="title"><a id="allocator.biblio"></a>Bibliography</h3></div></div></div><div class="biblioentry"><a id="id336934"></a><p><span class="title"><i>
ISO/IEC 14882:1998 Programming languages - C++
</i>. </span>
isoc++_1998
- <span class="pagenums">20.4 Memory. </span></p></div><div class="biblioentry"><a id="id548292"></a><p><span class="title"><i>The Standard Librarian: What Are Allocators Good
+ <span class="pagenums">20.4 Memory. </span></p></div><div class="biblioentry"><a id="id336949"></a><p><span class="title"><i>The Standard Librarian: What Are Allocators Good
</i>. </span>
austernm
<span class="author"><span class="firstname">Matt</span> <span class="surname">Austern</span>. </span><span class="publisher"><span class="publishername">
@@ -317,28 +317,28 @@
. </span></span><span class="biblioid">
<a class="ulink" href="http://www.cuj.com/documents/s=8000/cujcexp1812austern/" target="_top">
</a>
- . </span></p></div><div class="biblioentry"><a id="id556096"></a><p><span class="title"><i>The Hoard Memory Allocator</i>. </span>
+ . </span></p></div><div class="biblioentry"><a id="id402117"></a><p><span class="title"><i>The Hoard Memory Allocator</i>. </span>
emeryb
<span class="author"><span class="firstname">Emery</span> <span class="surname">Berger</span>. </span><span class="biblioid">
<a class="ulink" href="http://www.cs.umass.edu/~emery/hoard/" target="_top">
</a>
- . </span></p></div><div class="biblioentry"><a id="id571024"></a><p><span class="title"><i>Reconsidering Custom Memory Allocation</i>. </span>
+ . </span></p></div><div class="biblioentry"><a id="id386707"></a><p><span class="title"><i>Reconsidering Custom Memory Allocation</i>. </span>
bergerzorn
<span class="author"><span class="firstname">Emery</span> <span class="surname">Berger</span>. </span><span class="author"><span class="firstname">Ben</span> <span class="surname">Zorn</span>. </span><span class="author"><span class="firstname">Kathryn</span> <span class="surname">McKinley</span>. </span><span class="copyright">Copyright © 2002 OOPSLA. </span><span class="biblioid">
<a class="ulink" href="http://www.cs.umass.edu/~emery/pubs/berger-oopsla2002.pdf" target="_top">
</a>
- . </span></p></div><div class="biblioentry"><a id="id549463"></a><p><span class="title"><i>Allocator Types</i>. </span>
+ . </span></p></div><div class="biblioentry"><a id="id404915"></a><p><span class="title"><i>Allocator Types</i>. </span>
kreftlanger
<span class="author"><span class="firstname">Klaus</span> <span class="surname">Kreft</span>. </span><span class="author"><span class="firstname">Angelika</span> <span class="surname">Langer</span>. </span><span class="publisher"><span class="publishername">
C/C++ Users Journal
. </span></span><span class="biblioid">
<a class="ulink" href="http://www.langer.camelot.de/Articles/C++Report/Allocators/Allocators.html" target="_top">
</a>
- . </span></p></div><div class="biblioentry"><a id="id610752"></a><p><span class="title"><i>The C++ Programming Language</i>. </span>
+ . </span></p></div><div class="biblioentry"><a id="id378638"></a><p><span class="title"><i>The C++ Programming Language</i>. </span>
tcpl
<span class="author"><span class="firstname">Bjarne</span> <span class="surname">Stroustrup</span>. </span><span class="copyright">Copyright © 2000 . </span><span class="pagenums">19.4 Allocators. </span><span class="publisher"><span class="publishername">
Addison Wesley
- . </span></span></p></div><div class="biblioentry"><a id="id552856"></a><p><span class="title"><i>Yalloc: A Recycling C++ Allocator</i>. </span>
+ . </span></span></p></div><div class="biblioentry"><a id="id401191"></a><p><span class="title"><i>Yalloc: A Recycling C++ Allocator</i>. </span>
yenf
<span class="author"><span class="firstname">Felix</span> <span class="surname">Yen</span>. </span><span class="copyright">Copyright © . </span><span class="biblioid">
<a class="ulink" href="http://home.earthlink.net/~brimar/yalloc/" target="_top">
diff --git a/libstdc++-v3/doc/html/manual/bk01pt06ch14.html b/libstdc++-v3/doc/html/manual/bk01pt06ch14.html
index 506ffab9a33..dbfaa8ddf72 100644
--- a/libstdc++-v3/doc/html/manual/bk01pt06ch14.html
+++ b/libstdc++-v3/doc/html/manual/bk01pt06ch14.html
@@ -395,25 +395,25 @@ global locale" (emphasis Paolo), that is:
What should non-required facet instantiations do? If the
generic implementation is provided, then how to end-users
provide specializations?
- </p></li></ul></div></div><div class="bibliography"><div class="titlepage"><div><div><h3 class="title"><a id="locales.locale.biblio"></a>Bibliography</h3></div></div></div><div class="biblioentry"><a id="id563983"></a><p><span class="title"><i>
+ </p></li></ul></div></div><div class="bibliography"><div class="titlepage"><div><div><h3 class="title"><a id="locales.locale.biblio"></a>Bibliography</h3></div></div></div><div class="biblioentry"><a id="id431371"></a><p><span class="title"><i>
The GNU C Library
- </i>. </span><span class="author"><span class="firstname">Roland</span> <span class="surname">McGrath</span>. </span><span class="author"><span class="firstname">Ulrich</span> <span class="surname">Drepper</span>. </span><span class="copyright">Copyright © 2007 FSF. </span><span class="pagenums">Chapters 6 Character Set Handling and 7 Locales and Internationalization. </span></p></div><div class="biblioentry"><a id="id623816"></a><p><span class="title"><i>
+ </i>. </span><span class="author"><span class="firstname">Roland</span> <span class="surname">McGrath</span>. </span><span class="author"><span class="firstname">Ulrich</span> <span class="surname">Drepper</span>. </span><span class="copyright">Copyright © 2007 FSF. </span><span class="pagenums">Chapters 6 Character Set Handling and 7 Locales and Internationalization. </span></p></div><div class="biblioentry"><a id="id446999"></a><p><span class="title"><i>
Correspondence
- </i>. </span><span class="author"><span class="firstname">Ulrich</span> <span class="surname">Drepper</span>. </span><span class="copyright">Copyright © 2002 . </span></p></div><div class="biblioentry"><a id="id571346"></a><p><span class="title"><i>
+ </i>. </span><span class="author"><span class="firstname">Ulrich</span> <span class="surname">Drepper</span>. </span><span class="copyright">Copyright © 2002 . </span></p></div><div class="biblioentry"><a id="id376809"></a><p><span class="title"><i>
ISO/IEC 14882:1998 Programming languages - C++
- </i>. </span><span class="copyright">Copyright © 1998 ISO. </span></p></div><div class="biblioentry"><a id="id571365"></a><p><span class="title"><i>
+ </i>. </span><span class="copyright">Copyright © 1998 ISO. </span></p></div><div class="biblioentry"><a id="id376828"></a><p><span class="title"><i>
ISO/IEC 9899:1999 Programming languages - C
- </i>. </span><span class="copyright">Copyright © 1999 ISO. </span></p></div><div class="biblioentry"><a id="id636643"></a><p><span class="title"><i>
+ </i>. </span><span class="copyright">Copyright © 1999 ISO. </span></p></div><div class="biblioentry"><a id="id401235"></a><p><span class="title"><i>
System Interface Definitions, Issue 6 (IEEE Std. 1003.1-200x)
</i>. </span><span class="copyright">Copyright © 1999
The Open Group/The Institute of Electrical and Electronics Engineers, Inc.. </span><span class="biblioid">
<a class="ulink" href="http://www.opennc.org/austin/docreg.html" target="_top">
</a>
- . </span></p></div><div class="biblioentry"><a id="id636670"></a><p><span class="title"><i>
+ . </span></p></div><div class="biblioentry"><a id="id398149"></a><p><span class="title"><i>
The C++ Programming Language, Special Edition
</i>. </span><span class="author"><span class="firstname">Bjarne</span> <span class="surname">Stroustrup</span>. </span><span class="copyright">Copyright © 2000 Addison Wesley, Inc.. </span><span class="pagenums">Appendix D. </span><span class="publisher"><span class="publishername">
Addison Wesley
- . </span></span></p></div><div class="biblioentry"><a id="id612616"></a><p><span class="title"><i>
+ . </span></span></p></div><div class="biblioentry"><a id="id426390"></a><p><span class="title"><i>
Standard C++ IOStreams and Locales
</i>. </span><span class="subtitle">
Advanced Programmer's Guide and Reference
diff --git a/libstdc++-v3/doc/html/manual/bk01pt06ch15.html b/libstdc++-v3/doc/html/manual/bk01pt06ch15.html
index 65551aa0ab3..948928c1a7c 100644
--- a/libstdc++-v3/doc/html/manual/bk01pt06ch15.html
+++ b/libstdc++-v3/doc/html/manual/bk01pt06ch15.html
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Chapter 15. Facets aka Categories</title><meta name="generator" content="DocBook XSL Stylesheets V1.73.2" /><meta name="keywords" content="&#10; ISO C++&#10; , &#10; library&#10; " /><link rel="start" href="../spine.html" title="The GNU C++ Library Documentation" /><link rel="up" href="localization.html" title="Part VI. Localization" /><link rel="prev" href="bk01pt06ch14.html" title="Chapter 14. Locales" /><link rel="next" href="codecvt.html" title="codecvt" /></head><body><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">Chapter 15. Facets aka Categories</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="bk01pt06ch14.html">Prev</a> </td><th width="60%" align="center">Part VI. Localization</th><td width="20%" align="right"> <a accesskey="n" href="codecvt.html">Next</a></td></tr></table><hr /></div><div class="chapter" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title"><a id="manual.localization.facet"></a>Chapter 15. Facets aka Categories</h2></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="sect1"><a href="bk01pt06ch15.html#manual.localization.facet.ctype">ctype</a></span></dt><dd><dl><dt><span class="sect2"><a href="bk01pt06ch15.html#facet.ctype.impl">Implementation</a></span></dt><dt><span class="sect2"><a href="bk01pt06ch15.html#facet.ctype.future">Future</a></span></dt></dl></dd><dt><span class="sect1"><a href="codecvt.html">codecvt</a></span></dt><dd><dl><dt><span class="sect2"><a href="codecvt.html#facet.codecvt.req">Requirements</a></span></dt><dt><span class="sect2"><a href="codecvt.html#facet.codecvt.design">Design</a></span></dt><dt><span class="sect2"><a href="codecvt.html#facet.codecvt.impl">Implementation</a></span></dt><dt><span class="sect2"><a href="codecvt.html#facet.codecvt.use">Use</a></span></dt><dt><span class="sect2"><a href="codecvt.html#facet.codecvt.future">Future</a></span></dt></dl></dd><dt><span class="sect1"><a href="messages.html">messages</a></span></dt><dd><dl><dt><span class="sect2"><a href="messages.html#facet.messages.req">Requirements</a></span></dt><dt><span class="sect2"><a href="messages.html#facet.messages.design">Design</a></span></dt><dt><span class="sect2"><a href="messages.html#facet.messages.impl">Implementation</a></span></dt><dt><span class="sect2"><a href="messages.html#facet.messages.use">Use</a></span></dt><dt><span class="sect2"><a href="messages.html#facet.messages.future">Future</a></span></dt></dl></dd></dl></div><div class="sect1" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="manual.localization.facet.ctype"></a>ctype</h2></div></div></div><div class="sect2" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="facet.ctype.impl"></a>Implementation</h3></div></div></div><div class="sect3" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="id672533"></a>Specializations</h4></div></div></div><p>
+<html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Chapter 15. Facets aka Categories</title><meta name="generator" content="DocBook XSL Stylesheets V1.73.2" /><meta name="keywords" content="&#10; ISO C++&#10; , &#10; library&#10; " /><link rel="start" href="../spine.html" title="The GNU C++ Library Documentation" /><link rel="up" href="localization.html" title="Part VI. Localization" /><link rel="prev" href="bk01pt06ch14.html" title="Chapter 14. Locales" /><link rel="next" href="codecvt.html" title="codecvt" /></head><body><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">Chapter 15. Facets aka Categories</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="bk01pt06ch14.html">Prev</a> </td><th width="60%" align="center">Part VI. Localization</th><td width="20%" align="right"> <a accesskey="n" href="codecvt.html">Next</a></td></tr></table><hr /></div><div class="chapter" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title"><a id="manual.localization.facet"></a>Chapter 15. Facets aka Categories</h2></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="sect1"><a href="bk01pt06ch15.html#manual.localization.facet.ctype">ctype</a></span></dt><dd><dl><dt><span class="sect2"><a href="bk01pt06ch15.html#facet.ctype.impl">Implementation</a></span></dt><dt><span class="sect2"><a href="bk01pt06ch15.html#facet.ctype.future">Future</a></span></dt></dl></dd><dt><span class="sect1"><a href="codecvt.html">codecvt</a></span></dt><dd><dl><dt><span class="sect2"><a href="codecvt.html#facet.codecvt.req">Requirements</a></span></dt><dt><span class="sect2"><a href="codecvt.html#facet.codecvt.design">Design</a></span></dt><dt><span class="sect2"><a href="codecvt.html#facet.codecvt.impl">Implementation</a></span></dt><dt><span class="sect2"><a href="codecvt.html#facet.codecvt.use">Use</a></span></dt><dt><span class="sect2"><a href="codecvt.html#facet.codecvt.future">Future</a></span></dt></dl></dd><dt><span class="sect1"><a href="messages.html">messages</a></span></dt><dd><dl><dt><span class="sect2"><a href="messages.html#facet.messages.req">Requirements</a></span></dt><dt><span class="sect2"><a href="messages.html#facet.messages.design">Design</a></span></dt><dt><span class="sect2"><a href="messages.html#facet.messages.impl">Implementation</a></span></dt><dt><span class="sect2"><a href="messages.html#facet.messages.use">Use</a></span></dt><dt><span class="sect2"><a href="messages.html#facet.messages.future">Future</a></span></dt></dl></dd></dl></div><div class="sect1" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="manual.localization.facet.ctype"></a>ctype</h2></div></div></div><div class="sect2" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="facet.ctype.impl"></a>Implementation</h3></div></div></div><div class="sect3" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="id373746"></a>Specializations</h4></div></div></div><p>
For the required specialization codecvt&lt;wchar_t, char, mbstate_t&gt; ,
conversions are made between the internal character set (always UCS4
on GNU/Linux) and whatever the currently selected locale for the
@@ -47,25 +47,25 @@ characters.
</p></li><li><p>
Rename abstract base class. See if just smash-overriding is a
better approach. Clarify, add sanity to naming.
- </p></li></ul></div></div><div class="bibliography"><div class="titlepage"><div><div><h3 class="title"><a id="facet.ctype.biblio"></a>Bibliography</h3></div></div></div><div class="biblioentry"><a id="id628452"></a><p><span class="title"><i>
+ </p></li></ul></div></div><div class="bibliography"><div class="titlepage"><div><div><h3 class="title"><a id="facet.ctype.biblio"></a>Bibliography</h3></div></div></div><div class="biblioentry"><a id="id382630"></a><p><span class="title"><i>
The GNU C Library
- </i>. </span><span class="author"><span class="firstname">Roland</span> <span class="surname">McGrath</span>. </span><span class="author"><span class="firstname">Ulrich</span> <span class="surname">Drepper</span>. </span><span class="copyright">Copyright © 2007 FSF. </span><span class="pagenums">Chapters 6 Character Set Handling and 7 Locales and Internationalization. </span></p></div><div class="biblioentry"><a id="id516793"></a><p><span class="title"><i>
+ </i>. </span><span class="author"><span class="firstname">Roland</span> <span class="surname">McGrath</span>. </span><span class="author"><span class="firstname">Ulrich</span> <span class="surname">Drepper</span>. </span><span class="copyright">Copyright © 2007 FSF. </span><span class="pagenums">Chapters 6 Character Set Handling and 7 Locales and Internationalization. </span></p></div><div class="biblioentry"><a id="id336899"></a><p><span class="title"><i>
Correspondence
- </i>. </span><span class="author"><span class="firstname">Ulrich</span> <span class="surname">Drepper</span>. </span><span class="copyright">Copyright © 2002 . </span></p></div><div class="biblioentry"><a id="id567513"></a><p><span class="title"><i>
+ </i>. </span><span class="author"><span class="firstname">Ulrich</span> <span class="surname">Drepper</span>. </span><span class="copyright">Copyright © 2002 . </span></p></div><div class="biblioentry"><a id="id433304"></a><p><span class="title"><i>
ISO/IEC 14882:1998 Programming languages - C++
- </i>. </span><span class="copyright">Copyright © 1998 ISO. </span></p></div><div class="biblioentry"><a id="id567532"></a><p><span class="title"><i>
+ </i>. </span><span class="copyright">Copyright © 1998 ISO. </span></p></div><div class="biblioentry"><a id="id433322"></a><p><span class="title"><i>
ISO/IEC 9899:1999 Programming languages - C
- </i>. </span><span class="copyright">Copyright © 1999 ISO. </span></p></div><div class="biblioentry"><a id="id566828"></a><p><span class="title"><i>
+ </i>. </span><span class="copyright">Copyright © 1999 ISO. </span></p></div><div class="biblioentry"><a id="id428978"></a><p><span class="title"><i>
System Interface Definitions, Issue 6 (IEEE Std. 1003.1-200x)
</i>. </span><span class="copyright">Copyright © 1999
The Open Group/The Institute of Electrical and Electronics Engineers, Inc.. </span><span class="biblioid">
<a class="ulink" href="http://www.opennc.org/austin/docreg.html" target="_top">
</a>
- . </span></p></div><div class="biblioentry"><a id="id571204"></a><p><span class="title"><i>
+ . </span></p></div><div class="biblioentry"><a id="id429006"></a><p><span class="title"><i>
The C++ Programming Language, Special Edition
</i>. </span><span class="author"><span class="firstname">Bjarne</span> <span class="surname">Stroustrup</span>. </span><span class="copyright">Copyright © 2000 Addison Wesley, Inc.. </span><span class="pagenums">Appendix D. </span><span class="publisher"><span class="publishername">
Addison Wesley
- . </span></span></p></div><div class="biblioentry"><a id="id638138"></a><p><span class="title"><i>
+ . </span></span></p></div><div class="biblioentry"><a id="id380310"></a><p><span class="title"><i>
Standard C++ IOStreams and Locales
</i>. </span><span class="subtitle">
Advanced Programmer's Guide and Reference
diff --git a/libstdc++-v3/doc/html/manual/bk01pt09pr02.html b/libstdc++-v3/doc/html/manual/bk01pt09pr02.html
index 4f560caf0c6..93b071c47b7 100644
--- a/libstdc++-v3/doc/html/manual/bk01pt09pr02.html
+++ b/libstdc++-v3/doc/html/manual/bk01pt09pr02.html
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title></title><meta name="generator" content="DocBook XSL Stylesheets V1.73.2" /><meta name="keywords" content="&#10; ISO C++&#10; , &#10; library&#10; , &#10; algorithm&#10; " /><link rel="start" href="../spine.html" title="The GNU C++ Library Documentation" /><link rel="up" href="algorithms.html" title="Part IX. Algorithms" /><link rel="prev" href="algorithms.html" title="Part IX. Algorithms" /><link rel="next" href="bk01pt09ch20.html" title="Chapter 20. Mutating" /></head><body><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center"></th></tr><tr><td width="20%" align="left"><a accesskey="p" href="algorithms.html">Prev</a> </td><th width="60%" align="center">Part IX. Algorithms</th><td width="20%" align="right"> <a accesskey="n" href="bk01pt09ch20.html">Next</a></td></tr></table><hr /></div><div class="preface" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title"><a id="id613410"></a></h2></div></div></div><p>
+<html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title></title><meta name="generator" content="DocBook XSL Stylesheets V1.73.2" /><meta name="keywords" content="&#10; ISO C++&#10; , &#10; library&#10; , &#10; algorithm&#10; " /><link rel="start" href="../spine.html" title="The GNU C++ Library Documentation" /><link rel="up" href="algorithms.html" title="Part IX. Algorithms" /><link rel="prev" href="algorithms.html" title="Part IX. Algorithms" /><link rel="next" href="bk01pt09ch20.html" title="Chapter 20. Mutating" /></head><body><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center"></th></tr><tr><td width="20%" align="left"><a accesskey="p" href="algorithms.html">Prev</a> </td><th width="60%" align="center">Part IX. Algorithms</th><td width="20%" align="right"> <a accesskey="n" href="bk01pt09ch20.html">Next</a></td></tr></table><hr /></div><div class="preface" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title"><a id="id457861"></a></h2></div></div></div><p>
The neatest accomplishment of the algorithms chapter is that all the
work is done via iterators, not containers directly. This means two
important things:
diff --git a/libstdc++-v3/doc/html/manual/bk01pt12ch30s03.html b/libstdc++-v3/doc/html/manual/bk01pt12ch30s03.html
index b13e08bcd78..d3c60f88747 100644
--- a/libstdc++-v3/doc/html/manual/bk01pt12ch30s03.html
+++ b/libstdc++-v3/doc/html/manual/bk01pt12ch30s03.html
@@ -19,6 +19,6 @@
mode or with debug mode. The
following table provides the names and headers of the debugging
containers:
-</p><div class="table"><a id="id552456"></a><p class="title"><b>Table 30.1. Debugging Containers</b></p><div class="table-contents"><table summary="Debugging Containers" border="1"><colgroup><col align="left" /><col align="left" /><col align="left" /><col align="left" /><col /><col /></colgroup><thead><tr><th align="left">Container</th><th align="left">Header</th><th align="left">Debug container</th><th align="left">Debug header</th><td class="auto-generated"> </td><td class="auto-generated"> </td></tr></thead><tbody><tr><td align="left"><code class="classname">std::bitset</code></td><td align="left"><code class="filename">bitset</code></td><td align="left"><code class="classname">__gnu_debug::bitset</code></td><td align="left"><code class="filename">bitset</code></td><td class="auto-generated"> </td><td class="auto-generated"> </td></tr><tr><td align="left"><code class="classname">std::deque</code></td><td align="left"><code class="filename">deque</code></td><td align="left"><code class="classname">__gnu_debug::deque</code></td><td align="left"><code class="filename">deque</code></td><td class="auto-generated"> </td><td class="auto-generated"> </td></tr><tr><td align="left"><code class="classname">std::list</code></td><td align="left"><code class="filename">list</code></td><td align="left"><code class="classname">__gnu_debug::list</code></td><td align="left"><code class="filename">list</code></td><td class="auto-generated"> </td><td class="auto-generated"> </td></tr><tr><td align="left"><code class="classname">std::map</code></td><td align="left"><code class="filename">map</code></td><td align="left"><code class="classname">__gnu_debug::map</code></td><td align="left"><code class="filename">map</code></td><td class="auto-generated"> </td><td class="auto-generated"> </td></tr><tr><td align="left"><code class="classname">std::multimap</code></td><td align="left"><code class="filename">map</code></td><td align="left"><code class="classname">__gnu_debug::multimap</code></td><td align="left"><code class="filename">map</code></td><td class="auto-generated"> </td><td class="auto-generated"> </td></tr><tr><td align="left"><code class="classname">std::multiset</code></td><td align="left"><code class="filename">set</code></td><td align="left"><code class="classname">__gnu_debug::multiset</code></td><td align="left"><code class="filename">set</code></td><td class="auto-generated"> </td><td class="auto-generated"> </td></tr><tr><td align="left"><code class="classname">std::set</code></td><td align="left"><code class="filename">set</code></td><td align="left"><code class="classname">__gnu_debug::set</code></td><td align="left"><code class="filename">set</code></td><td class="auto-generated"> </td><td class="auto-generated"> </td></tr><tr><td align="left"><code class="classname">std::string</code></td><td align="left"><code class="filename">string</code></td><td align="left"><code class="classname">__gnu_debug::string</code></td><td align="left"><code class="filename">string</code></td><td class="auto-generated"> </td><td class="auto-generated"> </td></tr><tr><td align="left"><code class="classname">std::wstring</code></td><td align="left"><code class="filename">string</code></td><td align="left"><code class="classname">__gnu_debug::wstring</code></td><td align="left"><code class="filename">string</code></td><td class="auto-generated"> </td><td class="auto-generated"> </td></tr><tr><td align="left"><code class="classname">std::basic_string</code></td><td align="left"><code class="filename">string</code></td><td align="left"><code class="classname">__gnu_debug::basic_string</code></td><td align="left"><code class="filename">string</code></td><td class="auto-generated"> </td><td class="auto-generated"> </td></tr><tr><td align="left"><code class="classname">std::vector</code></td><td align="left"><code class="filename">vector</code></td><td align="left"><code class="classname">__gnu_debug::vector</code></td><td align="left"><code class="filename">vector</code></td><td class="auto-generated"> </td><td class="auto-generated"> </td></tr></tbody></table></div></div><br class="table-break" /><p>In addition, when compiling in C++0x mode, these additional
+</p><div class="table"><a id="id449953"></a><p class="title"><b>Table 30.1. Debugging Containers</b></p><div class="table-contents"><table summary="Debugging Containers" border="1"><colgroup><col align="left" /><col align="left" /><col align="left" /><col align="left" /><col /><col /></colgroup><thead><tr><th align="left">Container</th><th align="left">Header</th><th align="left">Debug container</th><th align="left">Debug header</th><td class="auto-generated"> </td><td class="auto-generated"> </td></tr></thead><tbody><tr><td align="left"><code class="classname">std::bitset</code></td><td align="left"><code class="filename">bitset</code></td><td align="left"><code class="classname">__gnu_debug::bitset</code></td><td align="left"><code class="filename">bitset</code></td><td class="auto-generated"> </td><td class="auto-generated"> </td></tr><tr><td align="left"><code class="classname">std::deque</code></td><td align="left"><code class="filename">deque</code></td><td align="left"><code class="classname">__gnu_debug::deque</code></td><td align="left"><code class="filename">deque</code></td><td class="auto-generated"> </td><td class="auto-generated"> </td></tr><tr><td align="left"><code class="classname">std::list</code></td><td align="left"><code class="filename">list</code></td><td align="left"><code class="classname">__gnu_debug::list</code></td><td align="left"><code class="filename">list</code></td><td class="auto-generated"> </td><td class="auto-generated"> </td></tr><tr><td align="left"><code class="classname">std::map</code></td><td align="left"><code class="filename">map</code></td><td align="left"><code class="classname">__gnu_debug::map</code></td><td align="left"><code class="filename">map</code></td><td class="auto-generated"> </td><td class="auto-generated"> </td></tr><tr><td align="left"><code class="classname">std::multimap</code></td><td align="left"><code class="filename">map</code></td><td align="left"><code class="classname">__gnu_debug::multimap</code></td><td align="left"><code class="filename">map</code></td><td class="auto-generated"> </td><td class="auto-generated"> </td></tr><tr><td align="left"><code class="classname">std::multiset</code></td><td align="left"><code class="filename">set</code></td><td align="left"><code class="classname">__gnu_debug::multiset</code></td><td align="left"><code class="filename">set</code></td><td class="auto-generated"> </td><td class="auto-generated"> </td></tr><tr><td align="left"><code class="classname">std::set</code></td><td align="left"><code class="filename">set</code></td><td align="left"><code class="classname">__gnu_debug::set</code></td><td align="left"><code class="filename">set</code></td><td class="auto-generated"> </td><td class="auto-generated"> </td></tr><tr><td align="left"><code class="classname">std::string</code></td><td align="left"><code class="filename">string</code></td><td align="left"><code class="classname">__gnu_debug::string</code></td><td align="left"><code class="filename">string</code></td><td class="auto-generated"> </td><td class="auto-generated"> </td></tr><tr><td align="left"><code class="classname">std::wstring</code></td><td align="left"><code class="filename">string</code></td><td align="left"><code class="classname">__gnu_debug::wstring</code></td><td align="left"><code class="filename">string</code></td><td class="auto-generated"> </td><td class="auto-generated"> </td></tr><tr><td align="left"><code class="classname">std::basic_string</code></td><td align="left"><code class="filename">string</code></td><td align="left"><code class="classname">__gnu_debug::basic_string</code></td><td align="left"><code class="filename">string</code></td><td class="auto-generated"> </td><td class="auto-generated"> </td></tr><tr><td align="left"><code class="classname">std::vector</code></td><td align="left"><code class="filename">vector</code></td><td align="left"><code class="classname">__gnu_debug::vector</code></td><td align="left"><code class="filename">vector</code></td><td class="auto-generated"> </td><td class="auto-generated"> </td></tr></tbody></table></div></div><br class="table-break" /><p>In addition, when compiling in C++0x mode, these additional
containers have additional debug capability.
-</p><div class="table"><a id="id566906"></a><p class="title"><b>Table 30.2. Debugging Containers C++0x</b></p><div class="table-contents"><table summary="Debugging Containers C++0x" border="1"><colgroup><col align="left" /><col align="left" /><col align="left" /><col align="left" /><col /><col /></colgroup><thead><tr><th align="left">Container</th><th align="left">Header</th><th align="left">Debug container</th><th align="left">Debug header</th><td class="auto-generated"> </td><td class="auto-generated"> </td></tr></thead><tbody><tr><td align="left"><code class="classname">std::unordered_map</code></td><td align="left"><code class="filename">unordered_map</code></td><td align="left"><code class="classname">__gnu_debug::unordered_map</code></td><td align="left"><code class="filename">unordered_map</code></td><td class="auto-generated"> </td><td class="auto-generated"> </td></tr><tr><td align="left"><code class="classname">std::unordered_multimap</code></td><td align="left"><code class="filename">unordered_map</code></td><td align="left"><code class="classname">__gnu_debug::unordered_multimap</code></td><td align="left"><code class="filename">unordered_map</code></td><td class="auto-generated"> </td><td class="auto-generated"> </td></tr><tr><td align="left"><code class="classname">std::unordered_set</code></td><td align="left"><code class="filename">unordered_set</code></td><td align="left"><code class="classname">__gnu_debug::unordered_set</code></td><td align="left"><code class="filename">unordered_set</code></td><td class="auto-generated"> </td><td class="auto-generated"> </td></tr><tr><td align="left"><code class="classname">std::unordered_multiset</code></td><td align="left"><code class="filename">unordered_set</code></td><td align="left"><code class="classname">__gnu_debug::unordered_multiset</code></td><td align="left"><code class="filename">unordered_set</code></td><td class="auto-generated"> </td><td class="auto-generated"> </td></tr></tbody></table></div></div><br class="table-break" /></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="bk01pt12ch30s02.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="debug_mode.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="bk01pt12ch30s04.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Semantics </td><td width="20%" align="center"><a accesskey="h" href="../spine.html">Home</a></td><td width="40%" align="right" valign="top"> Design</td></tr></table></div></body></html>
+</p><div class="table"><a id="id319073"></a><p class="title"><b>Table 30.2. Debugging Containers C++0x</b></p><div class="table-contents"><table summary="Debugging Containers C++0x" border="1"><colgroup><col align="left" /><col align="left" /><col align="left" /><col align="left" /><col /><col /></colgroup><thead><tr><th align="left">Container</th><th align="left">Header</th><th align="left">Debug container</th><th align="left">Debug header</th><td class="auto-generated"> </td><td class="auto-generated"> </td></tr></thead><tbody><tr><td align="left"><code class="classname">std::unordered_map</code></td><td align="left"><code class="filename">unordered_map</code></td><td align="left"><code class="classname">__gnu_debug::unordered_map</code></td><td align="left"><code class="filename">unordered_map</code></td><td class="auto-generated"> </td><td class="auto-generated"> </td></tr><tr><td align="left"><code class="classname">std::unordered_multimap</code></td><td align="left"><code class="filename">unordered_map</code></td><td align="left"><code class="classname">__gnu_debug::unordered_multimap</code></td><td align="left"><code class="filename">unordered_map</code></td><td class="auto-generated"> </td><td class="auto-generated"> </td></tr><tr><td align="left"><code class="classname">std::unordered_set</code></td><td align="left"><code class="filename">unordered_set</code></td><td align="left"><code class="classname">__gnu_debug::unordered_set</code></td><td align="left"><code class="filename">unordered_set</code></td><td class="auto-generated"> </td><td class="auto-generated"> </td></tr><tr><td align="left"><code class="classname">std::unordered_multiset</code></td><td align="left"><code class="filename">unordered_set</code></td><td align="left"><code class="classname">__gnu_debug::unordered_multiset</code></td><td align="left"><code class="filename">unordered_set</code></td><td class="auto-generated"> </td><td class="auto-generated"> </td></tr></tbody></table></div></div><br class="table-break" /></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="bk01pt12ch30s02.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="debug_mode.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="bk01pt12ch30s04.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Semantics </td><td width="20%" align="center"><a accesskey="h" href="../spine.html">Home</a></td><td width="40%" align="right" valign="top"> Design</td></tr></table></div></body></html>
diff --git a/libstdc++-v3/doc/html/manual/bk01pt12ch31s03.html b/libstdc++-v3/doc/html/manual/bk01pt12ch31s03.html
index 3fc857516f7..53a56bf526c 100644
--- a/libstdc++-v3/doc/html/manual/bk01pt12ch31s03.html
+++ b/libstdc++-v3/doc/html/manual/bk01pt12ch31s03.html
@@ -63,4 +63,4 @@ Then compile this code with the prerequisite compiler flags
flags for atomic operations.)
</p><p> The following table provides the names and headers of all the
parallel algorithms that can be used in a similar manner:
-</p><div class="table"><a id="id619355"></a><p class="title"><b>Table 31.1. Parallel Algorithms</b></p><div class="table-contents"><table summary="Parallel Algorithms" border="1"><colgroup><col align="left" /><col align="left" /><col align="left" /><col align="left" /></colgroup><thead><tr><th align="left">Algorithm</th><th align="left">Header</th><th align="left">Parallel algorithm</th><th align="left">Parallel header</th></tr></thead><tbody><tr><td align="left"><code class="function">std::accumulate</code></td><td align="left"><code class="filename">numeric</code></td><td align="left"><code class="function">__gnu_parallel::accumulate</code></td><td align="left"><code class="filename">parallel/numeric</code></td></tr><tr><td align="left"><code class="function">std::adjacent_difference</code></td><td align="left"><code class="filename">numeric</code></td><td align="left"><code class="function">__gnu_parallel::adjacent_difference</code></td><td align="left"><code class="filename">parallel/numeric</code></td></tr><tr><td align="left"><code class="function">std::inner_product</code></td><td align="left"><code class="filename">numeric</code></td><td align="left"><code class="function">__gnu_parallel::inner_product</code></td><td align="left"><code class="filename">parallel/numeric</code></td></tr><tr><td align="left"><code class="function">std::partial_sum</code></td><td align="left"><code class="filename">numeric</code></td><td align="left"><code class="function">__gnu_parallel::partial_sum</code></td><td align="left"><code class="filename">parallel/numeric</code></td></tr><tr><td align="left"><code class="function">std::adjacent_find</code></td><td align="left"><code class="filename">algorithm</code></td><td align="left"><code class="function">__gnu_parallel::adjacent_find</code></td><td align="left"><code class="filename">parallel/algorithm</code></td></tr><tr><td align="left"><code class="function">std::count</code></td><td align="left"><code class="filename">algorithm</code></td><td align="left"><code class="function">__gnu_parallel::count</code></td><td align="left"><code class="filename">parallel/algorithm</code></td></tr><tr><td align="left"><code class="function">std::count_if</code></td><td align="left"><code class="filename">algorithm</code></td><td align="left"><code class="function">__gnu_parallel::count_if</code></td><td align="left"><code class="filename">parallel/algorithm</code></td></tr><tr><td align="left"><code class="function">std::equal</code></td><td align="left"><code class="filename">algorithm</code></td><td align="left"><code class="function">__gnu_parallel::equal</code></td><td align="left"><code class="filename">parallel/algorithm</code></td></tr><tr><td align="left"><code class="function">std::find</code></td><td align="left"><code class="filename">algorithm</code></td><td align="left"><code class="function">__gnu_parallel::find</code></td><td align="left"><code class="filename">parallel/algorithm</code></td></tr><tr><td align="left"><code class="function">std::find_if</code></td><td align="left"><code class="filename">algorithm</code></td><td align="left"><code class="function">__gnu_parallel::find_if</code></td><td align="left"><code class="filename">parallel/algorithm</code></td></tr><tr><td align="left"><code class="function">std::find_first_of</code></td><td align="left"><code class="filename">algorithm</code></td><td align="left"><code class="function">__gnu_parallel::find_first_of</code></td><td align="left"><code class="filename">parallel/algorithm</code></td></tr><tr><td align="left"><code class="function">std::for_each</code></td><td align="left"><code class="filename">algorithm</code></td><td align="left"><code class="function">__gnu_parallel::for_each</code></td><td align="left"><code class="filename">parallel/algorithm</code></td></tr><tr><td align="left"><code class="function">std::generate</code></td><td align="left"><code class="filename">algorithm</code></td><td align="left"><code class="function">__gnu_parallel::generate</code></td><td align="left"><code class="filename">parallel/algorithm</code></td></tr><tr><td align="left"><code class="function">std::generate_n</code></td><td align="left"><code class="filename">algorithm</code></td><td align="left"><code class="function">__gnu_parallel::generate_n</code></td><td align="left"><code class="filename">parallel/algorithm</code></td></tr><tr><td align="left"><code class="function">std::lexicographical_compare</code></td><td align="left"><code class="filename">algorithm</code></td><td align="left"><code class="function">__gnu_parallel::lexicographical_compare</code></td><td align="left"><code class="filename">parallel/algorithm</code></td></tr><tr><td align="left"><code class="function">std::mismatch</code></td><td align="left"><code class="filename">algorithm</code></td><td align="left"><code class="function">__gnu_parallel::mismatch</code></td><td align="left"><code class="filename">parallel/algorithm</code></td></tr><tr><td align="left"><code class="function">std::search</code></td><td align="left"><code class="filename">algorithm</code></td><td align="left"><code class="function">__gnu_parallel::search</code></td><td align="left"><code class="filename">parallel/algorithm</code></td></tr><tr><td align="left"><code class="function">std::search_n</code></td><td align="left"><code class="filename">algorithm</code></td><td align="left"><code class="function">__gnu_parallel::search_n</code></td><td align="left"><code class="filename">parallel/algorithm</code></td></tr><tr><td align="left"><code class="function">std::transform</code></td><td align="left"><code class="filename">algorithm</code></td><td align="left"><code class="function">__gnu_parallel::transform</code></td><td align="left"><code class="filename">parallel/algorithm</code></td></tr><tr><td align="left"><code class="function">std::replace</code></td><td align="left"><code class="filename">algorithm</code></td><td align="left"><code class="function">__gnu_parallel::replace</code></td><td align="left"><code class="filename">parallel/algorithm</code></td></tr><tr><td align="left"><code class="function">std::replace_if</code></td><td align="left"><code class="filename">algorithm</code></td><td align="left"><code class="function">__gnu_parallel::replace_if</code></td><td align="left"><code class="filename">parallel/algorithm</code></td></tr><tr><td align="left"><code class="function">std::max_element</code></td><td align="left"><code class="filename">algorithm</code></td><td align="left"><code class="function">__gnu_parallel::max_element</code></td><td align="left"><code class="filename">parallel/algorithm</code></td></tr><tr><td align="left"><code class="function">std::merge</code></td><td align="left"><code class="filename">algorithm</code></td><td align="left"><code class="function">__gnu_parallel::merge</code></td><td align="left"><code class="filename">parallel/algorithm</code></td></tr><tr><td align="left"><code class="function">std::min_element</code></td><td align="left"><code class="filename">algorithm</code></td><td align="left"><code class="function">__gnu_parallel::min_element</code></td><td align="left"><code class="filename">parallel/algorithm</code></td></tr><tr><td align="left"><code class="function">std::nth_element</code></td><td align="left"><code class="filename">algorithm</code></td><td align="left"><code class="function">__gnu_parallel::nth_element</code></td><td align="left"><code class="filename">parallel/algorithm</code></td></tr><tr><td align="left"><code class="function">std::partial_sort</code></td><td align="left"><code class="filename">algorithm</code></td><td align="left"><code class="function">__gnu_parallel::partial_sort</code></td><td align="left"><code class="filename">parallel/algorithm</code></td></tr><tr><td align="left"><code class="function">std::partition</code></td><td align="left"><code class="filename">algorithm</code></td><td align="left"><code class="function">__gnu_parallel::partition</code></td><td align="left"><code class="filename">parallel/algorithm</code></td></tr><tr><td align="left"><code class="function">std::random_shuffle</code></td><td align="left"><code class="filename">algorithm</code></td><td align="left"><code class="function">__gnu_parallel::random_shuffle</code></td><td align="left"><code class="filename">parallel/algorithm</code></td></tr><tr><td align="left"><code class="function">std::set_union</code></td><td align="left"><code class="filename">algorithm</code></td><td align="left"><code class="function">__gnu_parallel::set_union</code></td><td align="left"><code class="filename">parallel/algorithm</code></td></tr><tr><td align="left"><code class="function">std::set_intersection</code></td><td align="left"><code class="filename">algorithm</code></td><td align="left"><code class="function">__gnu_parallel::set_intersection</code></td><td align="left"><code class="filename">parallel/algorithm</code></td></tr><tr><td align="left"><code class="function">std::set_symmetric_difference</code></td><td align="left"><code class="filename">algorithm</code></td><td align="left"><code class="function">__gnu_parallel::set_symmetric_difference</code></td><td align="left"><code class="filename">parallel/algorithm</code></td></tr><tr><td align="left"><code class="function">std::set_difference</code></td><td align="left"><code class="filename">algorithm</code></td><td align="left"><code class="function">__gnu_parallel::set_difference</code></td><td align="left"><code class="filename">parallel/algorithm</code></td></tr><tr><td align="left"><code class="function">std::sort</code></td><td align="left"><code class="filename">algorithm</code></td><td align="left"><code class="function">__gnu_parallel::sort</code></td><td align="left"><code class="filename">parallel/algorithm</code></td></tr><tr><td align="left"><code class="function">std::stable_sort</code></td><td align="left"><code class="filename">algorithm</code></td><td align="left"><code class="function">__gnu_parallel::stable_sort</code></td><td align="left"><code class="filename">parallel/algorithm</code></td></tr><tr><td align="left"><code class="function">std::unique_copy</code></td><td align="left"><code class="filename">algorithm</code></td><td align="left"><code class="function">__gnu_parallel::unique_copy</code></td><td align="left"><code class="filename">parallel/algorithm</code></td></tr></tbody></table></div></div><br class="table-break" /></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="bk01pt12ch31s02.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="parallel_mode.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="bk01pt12ch31s04.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Semantics </td><td width="20%" align="center"><a accesskey="h" href="../spine.html">Home</a></td><td width="40%" align="right" valign="top"> Design</td></tr></table></div></body></html>
+</p><div class="table"><a id="id392310"></a><p class="title"><b>Table 31.1. Parallel Algorithms</b></p><div class="table-contents"><table summary="Parallel Algorithms" border="1"><colgroup><col align="left" /><col align="left" /><col align="left" /><col align="left" /></colgroup><thead><tr><th align="left">Algorithm</th><th align="left">Header</th><th align="left">Parallel algorithm</th><th align="left">Parallel header</th></tr></thead><tbody><tr><td align="left"><code class="function">std::accumulate</code></td><td align="left"><code class="filename">numeric</code></td><td align="left"><code class="function">__gnu_parallel::accumulate</code></td><td align="left"><code class="filename">parallel/numeric</code></td></tr><tr><td align="left"><code class="function">std::adjacent_difference</code></td><td align="left"><code class="filename">numeric</code></td><td align="left"><code class="function">__gnu_parallel::adjacent_difference</code></td><td align="left"><code class="filename">parallel/numeric</code></td></tr><tr><td align="left"><code class="function">std::inner_product</code></td><td align="left"><code class="filename">numeric</code></td><td align="left"><code class="function">__gnu_parallel::inner_product</code></td><td align="left"><code class="filename">parallel/numeric</code></td></tr><tr><td align="left"><code class="function">std::partial_sum</code></td><td align="left"><code class="filename">numeric</code></td><td align="left"><code class="function">__gnu_parallel::partial_sum</code></td><td align="left"><code class="filename">parallel/numeric</code></td></tr><tr><td align="left"><code class="function">std::adjacent_find</code></td><td align="left"><code class="filename">algorithm</code></td><td align="left"><code class="function">__gnu_parallel::adjacent_find</code></td><td align="left"><code class="filename">parallel/algorithm</code></td></tr><tr><td align="left"><code class="function">std::count</code></td><td align="left"><code class="filename">algorithm</code></td><td align="left"><code class="function">__gnu_parallel::count</code></td><td align="left"><code class="filename">parallel/algorithm</code></td></tr><tr><td align="left"><code class="function">std::count_if</code></td><td align="left"><code class="filename">algorithm</code></td><td align="left"><code class="function">__gnu_parallel::count_if</code></td><td align="left"><code class="filename">parallel/algorithm</code></td></tr><tr><td align="left"><code class="function">std::equal</code></td><td align="left"><code class="filename">algorithm</code></td><td align="left"><code class="function">__gnu_parallel::equal</code></td><td align="left"><code class="filename">parallel/algorithm</code></td></tr><tr><td align="left"><code class="function">std::find</code></td><td align="left"><code class="filename">algorithm</code></td><td align="left"><code class="function">__gnu_parallel::find</code></td><td align="left"><code class="filename">parallel/algorithm</code></td></tr><tr><td align="left"><code class="function">std::find_if</code></td><td align="left"><code class="filename">algorithm</code></td><td align="left"><code class="function">__gnu_parallel::find_if</code></td><td align="left"><code class="filename">parallel/algorithm</code></td></tr><tr><td align="left"><code class="function">std::find_first_of</code></td><td align="left"><code class="filename">algorithm</code></td><td align="left"><code class="function">__gnu_parallel::find_first_of</code></td><td align="left"><code class="filename">parallel/algorithm</code></td></tr><tr><td align="left"><code class="function">std::for_each</code></td><td align="left"><code class="filename">algorithm</code></td><td align="left"><code class="function">__gnu_parallel::for_each</code></td><td align="left"><code class="filename">parallel/algorithm</code></td></tr><tr><td align="left"><code class="function">std::generate</code></td><td align="left"><code class="filename">algorithm</code></td><td align="left"><code class="function">__gnu_parallel::generate</code></td><td align="left"><code class="filename">parallel/algorithm</code></td></tr><tr><td align="left"><code class="function">std::generate_n</code></td><td align="left"><code class="filename">algorithm</code></td><td align="left"><code class="function">__gnu_parallel::generate_n</code></td><td align="left"><code class="filename">parallel/algorithm</code></td></tr><tr><td align="left"><code class="function">std::lexicographical_compare</code></td><td align="left"><code class="filename">algorithm</code></td><td align="left"><code class="function">__gnu_parallel::lexicographical_compare</code></td><td align="left"><code class="filename">parallel/algorithm</code></td></tr><tr><td align="left"><code class="function">std::mismatch</code></td><td align="left"><code class="filename">algorithm</code></td><td align="left"><code class="function">__gnu_parallel::mismatch</code></td><td align="left"><code class="filename">parallel/algorithm</code></td></tr><tr><td align="left"><code class="function">std::search</code></td><td align="left"><code class="filename">algorithm</code></td><td align="left"><code class="function">__gnu_parallel::search</code></td><td align="left"><code class="filename">parallel/algorithm</code></td></tr><tr><td align="left"><code class="function">std::search_n</code></td><td align="left"><code class="filename">algorithm</code></td><td align="left"><code class="function">__gnu_parallel::search_n</code></td><td align="left"><code class="filename">parallel/algorithm</code></td></tr><tr><td align="left"><code class="function">std::transform</code></td><td align="left"><code class="filename">algorithm</code></td><td align="left"><code class="function">__gnu_parallel::transform</code></td><td align="left"><code class="filename">parallel/algorithm</code></td></tr><tr><td align="left"><code class="function">std::replace</code></td><td align="left"><code class="filename">algorithm</code></td><td align="left"><code class="function">__gnu_parallel::replace</code></td><td align="left"><code class="filename">parallel/algorithm</code></td></tr><tr><td align="left"><code class="function">std::replace_if</code></td><td align="left"><code class="filename">algorithm</code></td><td align="left"><code class="function">__gnu_parallel::replace_if</code></td><td align="left"><code class="filename">parallel/algorithm</code></td></tr><tr><td align="left"><code class="function">std::max_element</code></td><td align="left"><code class="filename">algorithm</code></td><td align="left"><code class="function">__gnu_parallel::max_element</code></td><td align="left"><code class="filename">parallel/algorithm</code></td></tr><tr><td align="left"><code class="function">std::merge</code></td><td align="left"><code class="filename">algorithm</code></td><td align="left"><code class="function">__gnu_parallel::merge</code></td><td align="left"><code class="filename">parallel/algorithm</code></td></tr><tr><td align="left"><code class="function">std::min_element</code></td><td align="left"><code class="filename">algorithm</code></td><td align="left"><code class="function">__gnu_parallel::min_element</code></td><td align="left"><code class="filename">parallel/algorithm</code></td></tr><tr><td align="left"><code class="function">std::nth_element</code></td><td align="left"><code class="filename">algorithm</code></td><td align="left"><code class="function">__gnu_parallel::nth_element</code></td><td align="left"><code class="filename">parallel/algorithm</code></td></tr><tr><td align="left"><code class="function">std::partial_sort</code></td><td align="left"><code class="filename">algorithm</code></td><td align="left"><code class="function">__gnu_parallel::partial_sort</code></td><td align="left"><code class="filename">parallel/algorithm</code></td></tr><tr><td align="left"><code class="function">std::partition</code></td><td align="left"><code class="filename">algorithm</code></td><td align="left"><code class="function">__gnu_parallel::partition</code></td><td align="left"><code class="filename">parallel/algorithm</code></td></tr><tr><td align="left"><code class="function">std::random_shuffle</code></td><td align="left"><code class="filename">algorithm</code></td><td align="left"><code class="function">__gnu_parallel::random_shuffle</code></td><td align="left"><code class="filename">parallel/algorithm</code></td></tr><tr><td align="left"><code class="function">std::set_union</code></td><td align="left"><code class="filename">algorithm</code></td><td align="left"><code class="function">__gnu_parallel::set_union</code></td><td align="left"><code class="filename">parallel/algorithm</code></td></tr><tr><td align="left"><code class="function">std::set_intersection</code></td><td align="left"><code class="filename">algorithm</code></td><td align="left"><code class="function">__gnu_parallel::set_intersection</code></td><td align="left"><code class="filename">parallel/algorithm</code></td></tr><tr><td align="left"><code class="function">std::set_symmetric_difference</code></td><td align="left"><code class="filename">algorithm</code></td><td align="left"><code class="function">__gnu_parallel::set_symmetric_difference</code></td><td align="left"><code class="filename">parallel/algorithm</code></td></tr><tr><td align="left"><code class="function">std::set_difference</code></td><td align="left"><code class="filename">algorithm</code></td><td align="left"><code class="function">__gnu_parallel::set_difference</code></td><td align="left"><code class="filename">parallel/algorithm</code></td></tr><tr><td align="left"><code class="function">std::sort</code></td><td align="left"><code class="filename">algorithm</code></td><td align="left"><code class="function">__gnu_parallel::sort</code></td><td align="left"><code class="filename">parallel/algorithm</code></td></tr><tr><td align="left"><code class="function">std::stable_sort</code></td><td align="left"><code class="filename">algorithm</code></td><td align="left"><code class="function">__gnu_parallel::stable_sort</code></td><td align="left"><code class="filename">parallel/algorithm</code></td></tr><tr><td align="left"><code class="function">std::unique_copy</code></td><td align="left"><code class="filename">algorithm</code></td><td align="left"><code class="function">__gnu_parallel::unique_copy</code></td><td align="left"><code class="filename">parallel/algorithm</code></td></tr></tbody></table></div></div><br class="table-break" /></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="bk01pt12ch31s02.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="parallel_mode.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="bk01pt12ch31s04.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Semantics </td><td width="20%" align="center"><a accesskey="h" href="../spine.html">Home</a></td><td width="40%" align="right" valign="top"> Design</td></tr></table></div></body></html>
diff --git a/libstdc++-v3/doc/html/manual/bk01pt12pr03.html b/libstdc++-v3/doc/html/manual/bk01pt12pr03.html
index e813ee28dfb..fc79407e59b 100644
--- a/libstdc++-v3/doc/html/manual/bk01pt12pr03.html
+++ b/libstdc++-v3/doc/html/manual/bk01pt12pr03.html
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title></title><meta name="generator" content="DocBook XSL Stylesheets V1.73.2" /><meta name="keywords" content="&#10; ISO C++&#10; , &#10; library&#10; " /><link rel="start" href="../spine.html" title="The GNU C++ Library Documentation" /><link rel="up" href="extensions.html" title="Part XII. Extensions" /><link rel="prev" href="extensions.html" title="Part XII. Extensions" /><link rel="next" href="bk01pt12ch29.html" title="Chapter 29. Compile Time Checks" /></head><body><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center"></th></tr><tr><td width="20%" align="left"><a accesskey="p" href="extensions.html">Prev</a> </td><th width="60%" align="center">Part XII. Extensions</th><td width="20%" align="right"> <a accesskey="n" href="bk01pt12ch29.html">Next</a></td></tr></table><hr /></div><div class="preface" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title"><a id="id553784"></a></h2></div></div></div><p>
+<html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title></title><meta name="generator" content="DocBook XSL Stylesheets V1.73.2" /><meta name="keywords" content="&#10; ISO C++&#10; , &#10; library&#10; " /><link rel="start" href="../spine.html" title="The GNU C++ Library Documentation" /><link rel="up" href="extensions.html" title="Part XII. Extensions" /><link rel="prev" href="extensions.html" title="Part XII. Extensions" /><link rel="next" href="bk01pt12ch29.html" title="Chapter 29. Compile Time Checks" /></head><body><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center"></th></tr><tr><td width="20%" align="left"><a accesskey="p" href="extensions.html">Prev</a> </td><th width="60%" align="center">Part XII. Extensions</th><td width="20%" align="right"> <a accesskey="n" href="bk01pt12ch29.html">Next</a></td></tr></table><hr /></div><div class="preface" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title"><a id="id337521"></a></h2></div></div></div><p>
Here we will make an attempt at describing the non-Standard extensions to
the library. Some of these are from SGI's STL, some of these are GNU's,
and some just seemed to appear on the doorstep.
diff --git a/libstdc++-v3/doc/html/manual/codecvt.html b/libstdc++-v3/doc/html/manual/codecvt.html
index a6a66b4ffe3..258acd27814 100644
--- a/libstdc++-v3/doc/html/manual/codecvt.html
+++ b/libstdc++-v3/doc/html/manual/codecvt.html
@@ -337,41 +337,41 @@ codecvt usage.
</p></li><li><p>
wchar_t/char internal buffers and conversions between
internal/external buffers?
- </p></li></ul></div></li></ul></div></div><div class="bibliography"><div class="titlepage"><div><div><h3 class="title"><a id="facet.codecvt.biblio"></a>Bibliography</h3></div></div></div><div class="biblioentry"><a id="id575272"></a><p><span class="title"><i>
+ </p></li></ul></div></li></ul></div></div><div class="bibliography"><div class="titlepage"><div><div><h3 class="title"><a id="facet.codecvt.biblio"></a>Bibliography</h3></div></div></div><div class="biblioentry"><a id="id272734"></a><p><span class="title"><i>
The GNU C Library
- </i>. </span><span class="author"><span class="firstname">Roland</span> <span class="surname">McGrath</span>. </span><span class="author"><span class="firstname">Ulrich</span> <span class="surname">Drepper</span>. </span><span class="copyright">Copyright © 2007 FSF. </span><span class="pagenums">Chapters 6 Character Set Handling and 7 Locales and Internationalization. </span></p></div><div class="biblioentry"><a id="id609952"></a><p><span class="title"><i>
+ </i>. </span><span class="author"><span class="firstname">Roland</span> <span class="surname">McGrath</span>. </span><span class="author"><span class="firstname">Ulrich</span> <span class="surname">Drepper</span>. </span><span class="copyright">Copyright © 2007 FSF. </span><span class="pagenums">Chapters 6 Character Set Handling and 7 Locales and Internationalization. </span></p></div><div class="biblioentry"><a id="id399498"></a><p><span class="title"><i>
Correspondence
- </i>. </span><span class="author"><span class="firstname">Ulrich</span> <span class="surname">Drepper</span>. </span><span class="copyright">Copyright © 2002 . </span></p></div><div class="biblioentry"><a id="id609980"></a><p><span class="title"><i>
+ </i>. </span><span class="author"><span class="firstname">Ulrich</span> <span class="surname">Drepper</span>. </span><span class="copyright">Copyright © 2002 . </span></p></div><div class="biblioentry"><a id="id442423"></a><p><span class="title"><i>
ISO/IEC 14882:1998 Programming languages - C++
- </i>. </span><span class="copyright">Copyright © 1998 ISO. </span></p></div><div class="biblioentry"><a id="id623913"></a><p><span class="title"><i>
+ </i>. </span><span class="copyright">Copyright © 1998 ISO. </span></p></div><div class="biblioentry"><a id="id438296"></a><p><span class="title"><i>
ISO/IEC 9899:1999 Programming languages - C
- </i>. </span><span class="copyright">Copyright © 1999 ISO. </span></p></div><div class="biblioentry"><a id="id623931"></a><p><span class="title"><i>
+ </i>. </span><span class="copyright">Copyright © 1999 ISO. </span></p></div><div class="biblioentry"><a id="id438314"></a><p><span class="title"><i>
System Interface Definitions, Issue 6 (IEEE Std. 1003.1-200x)
</i>. </span><span class="copyright">Copyright © 1999
The Open Group/The Institute of Electrical and Electronics Engineers, Inc.. </span><span class="biblioid">
<a class="ulink" href="http://www.opennc.org/austin/docreg.html" target="_top">
</a>
- . </span></p></div><div class="biblioentry"><a id="id578900"></a><p><span class="title"><i>
+ . </span></p></div><div class="biblioentry"><a id="id436032"></a><p><span class="title"><i>
The C++ Programming Language, Special Edition
</i>. </span><span class="author"><span class="firstname">Bjarne</span> <span class="surname">Stroustrup</span>. </span><span class="copyright">Copyright © 2000 Addison Wesley, Inc.. </span><span class="pagenums">Appendix D. </span><span class="publisher"><span class="publishername">
Addison Wesley
- . </span></span></p></div><div class="biblioentry"><a id="id563010"></a><p><span class="title"><i>
+ . </span></span></p></div><div class="biblioentry"><a id="id400418"></a><p><span class="title"><i>
Standard C++ IOStreams and Locales
</i>. </span><span class="subtitle">
Advanced Programmer's Guide and Reference
. </span><span class="author"><span class="firstname">Angelika</span> <span class="surname">Langer</span>. </span><span class="author"><span class="firstname">Klaus</span> <span class="surname">Kreft</span>. </span><span class="copyright">Copyright © 2000 Addison Wesley Longman, Inc.. </span><span class="publisher"><span class="publishername">
Addison Wesley Longman
- . </span></span></p></div><div class="biblioentry"><a id="id663404"></a><p><span class="title"><i>
+ . </span></span></p></div><div class="biblioentry"><a id="id402869"></a><p><span class="title"><i>
A brief description of Normative Addendum 1
</i>. </span><span class="author"><span class="firstname">Clive</span> <span class="surname">Feather</span>. </span><span class="pagenums">Extended Character Sets. </span><span class="biblioid">
<a class="ulink" href="http://www.lysator.liu.se/c/na1.html" target="_top">
</a>
- . </span></p></div><div class="biblioentry"><a id="id654629"></a><p><span class="title"><i>
+ . </span></p></div><div class="biblioentry"><a id="id435221"></a><p><span class="title"><i>
The Unicode HOWTO
</i>. </span><span class="author"><span class="firstname">Bruno</span> <span class="surname">Haible</span>. </span><span class="biblioid">
<a class="ulink" href="ftp://ftp.ilog.fr/pub/Users/haible/utf8/Unicode-HOWTO.html" target="_top">
</a>
- . </span></p></div><div class="biblioentry"><a id="id573501"></a><p><span class="title"><i>
+ . </span></p></div><div class="biblioentry"><a id="id435248"></a><p><span class="title"><i>
UTF-8 and Unicode FAQ for Unix/Linux
</i>. </span><span class="author"><span class="firstname">Markus</span> <span class="surname">Khun</span>. </span><span class="biblioid">
<a class="ulink" href="http://www.cl.cam.ac.uk/~mgk25/unicode.html" target="_top">
diff --git a/libstdc++-v3/doc/html/manual/messages.html b/libstdc++-v3/doc/html/manual/messages.html
index 16f373c54ed..5284e8f11cc 100644
--- a/libstdc++-v3/doc/html/manual/messages.html
+++ b/libstdc++-v3/doc/html/manual/messages.html
@@ -241,38 +241,38 @@ void test01()
model. As of this writing, it is unknown how to query to see
if a specified message catalog exists using the gettext
package.
- </p></li></ul></div></div><div class="bibliography"><div class="titlepage"><div><div><h3 class="title"><a id="facet.messages.biblio"></a>Bibliography</h3></div></div></div><div class="biblioentry"><a id="id575136"></a><p><span class="title"><i>
+ </p></li></ul></div></div><div class="bibliography"><div class="titlepage"><div><div><h3 class="title"><a id="facet.messages.biblio"></a>Bibliography</h3></div></div></div><div class="biblioentry"><a id="id435992"></a><p><span class="title"><i>
The GNU C Library
</i>. </span><span class="author"><span class="firstname">Roland</span> <span class="surname">McGrath</span>. </span><span class="author"><span class="firstname">Ulrich</span> <span class="surname">Drepper</span>. </span><span class="copyright">Copyright © 2007 FSF. </span><span class="pagenums">Chapters 6 Character Set Handling, and 7 Locales and Internationalization
- . </span></p></div><div class="biblioentry"><a id="id642010"></a><p><span class="title"><i>
+ . </span></p></div><div class="biblioentry"><a id="id375623"></a><p><span class="title"><i>
Correspondence
- </i>. </span><span class="author"><span class="firstname">Ulrich</span> <span class="surname">Drepper</span>. </span><span class="copyright">Copyright © 2002 . </span></p></div><div class="biblioentry"><a id="id548515"></a><p><span class="title"><i>
+ </i>. </span><span class="author"><span class="firstname">Ulrich</span> <span class="surname">Drepper</span>. </span><span class="copyright">Copyright © 2002 . </span></p></div><div class="biblioentry"><a id="id377133"></a><p><span class="title"><i>
ISO/IEC 14882:1998 Programming languages - C++
- </i>. </span><span class="copyright">Copyright © 1998 ISO. </span></p></div><div class="biblioentry"><a id="id548534"></a><p><span class="title"><i>
+ </i>. </span><span class="copyright">Copyright © 1998 ISO. </span></p></div><div class="biblioentry"><a id="id377151"></a><p><span class="title"><i>
ISO/IEC 9899:1999 Programming languages - C
- </i>. </span><span class="copyright">Copyright © 1999 ISO. </span></p></div><div class="biblioentry"><a id="id548552"></a><p><span class="title"><i>
+ </i>. </span><span class="copyright">Copyright © 1999 ISO. </span></p></div><div class="biblioentry"><a id="id430388"></a><p><span class="title"><i>
System Interface Definitions, Issue 6 (IEEE Std. 1003.1-200x)
</i>. </span><span class="copyright">Copyright © 1999
The Open Group/The Institute of Electrical and Electronics Engineers, Inc.. </span><span class="biblioid">
<a class="ulink" href="http://www.opennc.org/austin/docreg.html" target="_top">
</a>
- . </span></p></div><div class="biblioentry"><a id="id515522"></a><p><span class="title"><i>
+ . </span></p></div><div class="biblioentry"><a id="id430416"></a><p><span class="title"><i>
The C++ Programming Language, Special Edition
</i>. </span><span class="author"><span class="firstname">Bjarne</span> <span class="surname">Stroustrup</span>. </span><span class="copyright">Copyright © 2000 Addison Wesley, Inc.. </span><span class="pagenums">Appendix D. </span><span class="publisher"><span class="publishername">
Addison Wesley
- . </span></span></p></div><div class="biblioentry"><a id="id566179"></a><p><span class="title"><i>
+ . </span></span></p></div><div class="biblioentry"><a id="id470349"></a><p><span class="title"><i>
Standard C++ IOStreams and Locales
</i>. </span><span class="subtitle">
Advanced Programmer's Guide and Reference
. </span><span class="author"><span class="firstname">Angelika</span> <span class="surname">Langer</span>. </span><span class="author"><span class="firstname">Klaus</span> <span class="surname">Kreft</span>. </span><span class="copyright">Copyright © 2000 Addison Wesley Longman, Inc.. </span><span class="publisher"><span class="publishername">
Addison Wesley Longman
- . </span></span></p></div><div class="biblioentry"><a id="id648665"></a><p><span class="title"><i>
+ . </span></span></p></div><div class="biblioentry"><a id="id433912"></a><p><span class="title"><i>
Java 2 Platform, Standard Edition, v 1.3.1 API Specification
</i>. </span><span class="pagenums">java.util.Properties, java.text.MessageFormat,
java.util.Locale, java.util.ResourceBundle. </span><span class="biblioid">
<a class="ulink" href="http://java.sun.com/j2se/1.3/docs/api" target="_top">
</a>
- . </span></p></div><div class="biblioentry"><a id="id606764"></a><p><span class="title"><i>
+ . </span></p></div><div class="biblioentry"><a id="id433933"></a><p><span class="title"><i>
GNU gettext tools, version 0.10.38, Native Language Support
Library and Tools.
</i>. </span><span class="biblioid">
diff --git a/libstdc++-v3/doc/html/manual/parallel_mode.html b/libstdc++-v3/doc/html/manual/parallel_mode.html
index 6ee676cf77d..f008aa39bc6 100644
--- a/libstdc++-v3/doc/html/manual/parallel_mode.html
+++ b/libstdc++-v3/doc/html/manual/parallel_mode.html
@@ -10,11 +10,11 @@ explicit source declaration or by compiling existing sources with a
specific compiler flag.
</p><div class="sect1" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="manual.ext.parallel_mode.intro"></a>Intro</h2></div></div></div><p>The following library components in the include
<code class="filename">numeric</code> are included in the parallel mode:</p><div class="itemizedlist"><ul type="disc"><li><p><code class="function">std::accumulate</code></p></li><li><p><code class="function">std::adjacent_difference</code></p></li><li><p><code class="function">std::inner_product</code></p></li><li><p><code class="function">std::partial_sum</code></p></li></ul></div><p>The following library components in the include
-<code class="filename">algorithm</code> are included in the parallel mode:</p><div class="itemizedlist"><ul type="disc"><li><p><code class="function">std::adjacent_find</code></p></li><li><p><code class="function">std::count</code></p></li><li><p><code class="function">std::count_if</code></p></li><li><p><code class="function">std::equal</code></p></li><li><p><code class="function">std::find</code></p></li><li><p><code class="function">std::find_if</code></p></li><li><p><code class="function">std::find_first_of</code></p></li><li><p><code class="function">std::for_each</code></p></li><li><p><code class="function">std::generate</code></p></li><li><p><code class="function">std::generate_n</code></p></li><li><p><code class="function">std::lexicographical_compare</code></p></li><li><p><code class="function">std::mismatch</code></p></li><li><p><code class="function">std::search</code></p></li><li><p><code class="function">std::search_n</code></p></li><li><p><code class="function">std::transform</code></p></li><li><p><code class="function">std::replace</code></p></li><li><p><code class="function">std::replace_if</code></p></li><li><p><code class="function">std::max_element</code></p></li><li><p><code class="function">std::merge</code></p></li><li><p><code class="function">std::min_element</code></p></li><li><p><code class="function">std::nth_element</code></p></li><li><p><code class="function">std::partial_sort</code></p></li><li><p><code class="function">std::partition</code></p></li><li><p><code class="function">std::random_shuffle</code></p></li><li><p><code class="function">std::set_union</code></p></li><li><p><code class="function">std::set_intersection</code></p></li><li><p><code class="function">std::set_symmetric_difference</code></p></li><li><p><code class="function">std::set_difference</code></p></li><li><p><code class="function">std::sort</code></p></li><li><p><code class="function">std::stable_sort</code></p></li><li><p><code class="function">std::unique_copy</code></p></li></ul></div></div><div class="bibliography"><div class="titlepage"><div><div><h2 class="title"><a id="parallel_mode.biblio"></a>Bibliography</h2></div></div></div><div class="biblioentry"><a id="id605457"></a><p><span class="title"><i>
+<code class="filename">algorithm</code> are included in the parallel mode:</p><div class="itemizedlist"><ul type="disc"><li><p><code class="function">std::adjacent_find</code></p></li><li><p><code class="function">std::count</code></p></li><li><p><code class="function">std::count_if</code></p></li><li><p><code class="function">std::equal</code></p></li><li><p><code class="function">std::find</code></p></li><li><p><code class="function">std::find_if</code></p></li><li><p><code class="function">std::find_first_of</code></p></li><li><p><code class="function">std::for_each</code></p></li><li><p><code class="function">std::generate</code></p></li><li><p><code class="function">std::generate_n</code></p></li><li><p><code class="function">std::lexicographical_compare</code></p></li><li><p><code class="function">std::mismatch</code></p></li><li><p><code class="function">std::search</code></p></li><li><p><code class="function">std::search_n</code></p></li><li><p><code class="function">std::transform</code></p></li><li><p><code class="function">std::replace</code></p></li><li><p><code class="function">std::replace_if</code></p></li><li><p><code class="function">std::max_element</code></p></li><li><p><code class="function">std::merge</code></p></li><li><p><code class="function">std::min_element</code></p></li><li><p><code class="function">std::nth_element</code></p></li><li><p><code class="function">std::partial_sort</code></p></li><li><p><code class="function">std::partition</code></p></li><li><p><code class="function">std::random_shuffle</code></p></li><li><p><code class="function">std::set_union</code></p></li><li><p><code class="function">std::set_intersection</code></p></li><li><p><code class="function">std::set_symmetric_difference</code></p></li><li><p><code class="function">std::set_difference</code></p></li><li><p><code class="function">std::sort</code></p></li><li><p><code class="function">std::stable_sort</code></p></li><li><p><code class="function">std::unique_copy</code></p></li></ul></div></div><div class="bibliography"><div class="titlepage"><div><div><h2 class="title"><a id="parallel_mode.biblio"></a>Bibliography</h2></div></div></div><div class="biblioentry"><a id="id470991"></a><p><span class="title"><i>
Parallelization of Bulk Operations for STL Dictionaries
</i>. </span><span class="author"><span class="firstname">Johannes</span> <span class="surname">Singler</span>. </span><span class="author"><span class="firstname">Leonor</span> <span class="surname">Frias</span>. </span><span class="copyright">Copyright © 2007 . </span><span class="publisher"><span class="publishername">
Workshop on Highly Parallel Processing on a Chip (HPPC) 2007. (LNCS)
- . </span></span></p></div><div class="biblioentry"><a id="id566030"></a><p><span class="title"><i>
+ . </span></span></p></div><div class="biblioentry"><a id="id471037"></a><p><span class="title"><i>
The Multi-Core Standard Template Library
</i>. </span><span class="author"><span class="firstname">Johannes</span> <span class="surname">Singler</span>. </span><span class="author"><span class="firstname">Peter</span> <span class="surname">Sanders</span>. </span><span class="author"><span class="firstname">Felix</span> <span class="surname">Putze</span>. </span><span class="copyright">Copyright © 2007 . </span><span class="publisher"><span class="publishername">
Euro-Par 2007: Parallel Processing. (LNCS 4641)
diff --git a/libstdc++-v3/doc/html/manual/shared_ptr.html b/libstdc++-v3/doc/html/manual/shared_ptr.html
index 9bb311412ef..88dc97de6d0 100644
--- a/libstdc++-v3/doc/html/manual/shared_ptr.html
+++ b/libstdc++-v3/doc/html/manual/shared_ptr.html
@@ -29,7 +29,7 @@ drops to zero.
Derived classes override those functions to destroy resources in a context
where the correct dynamic type is known. This is an application of the
technique known as type erasure.
- </p></div><div class="sect2" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="shared_ptr.impl"></a>Implementation</h3></div></div></div><div class="sect3" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="id578202"></a>Class Hierarchy</h4></div></div></div><p>
+ </p></div><div class="sect2" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="shared_ptr.impl"></a>Implementation</h3></div></div></div><div class="sect3" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="id399768"></a>Class Hierarchy</h4></div></div></div><p>
A <code class="classname">shared_ptr&lt;T&gt;</code> contains a pointer of
type <span class="type">T*</span> and an object of type
<code class="classname">__shared_count</code>. The shared_count contains a
@@ -71,7 +71,7 @@ be forwarded to <span class="type">Tp</span>'s constructor.
Unlike the other <code class="classname">_Sp_counted_*</code> classes, this one is parameterized on the
type of object, not the type of pointer; this is purely a convenience
that simplifies the implementation slightly.
- </p></dd></dl></div></div><div class="sect3" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="id625910"></a>Thread Safety</h4></div></div></div><p>
+ </p></dd></dl></div></div><div class="sect3" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="id438247"></a>Thread Safety</h4></div></div></div><p>
The interface of <code class="classname">tr1::shared_ptr</code> was extended for C++0x
with support for rvalue-references and the other features from
N2351. As with other libstdc++ headers shared by TR1 and C++0x,
@@ -129,7 +129,7 @@ compiler, standard library, platform etc. For the version of
shared_ptr in libstdc++ the compiler and library are fixed, which
makes things much simpler: we have an atomic CAS or we don't, see Lock
Policy below for details.
-</p></div><div class="sect3" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="id633694"></a>Selecting Lock Policy</h4></div></div></div><p>
+</p></div><div class="sect3" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="id445836"></a>Selecting Lock Policy</h4></div></div></div><p>
</p><p>
There is a single <code class="classname">_Sp_counted_base</code> class,
which is a template parameterized on the enum
@@ -170,7 +170,7 @@ used when libstdc++ is built without <code class="literal">--enable-threads</cod
<code class="filename">ext/atomicity.h</code>, which detect if the program
is multi-threaded. If only one thread of execution exists in
the program then less expensive non-atomic operations are used.
- </p></div><div class="sect3" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="id573229"></a>Dual C++0x and TR1 Implementation</h4></div></div></div><p>
+ </p></div><div class="sect3" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="id390904"></a>Dual C++0x and TR1 Implementation</h4></div></div></div><p>
The classes derived from <code class="classname">_Sp_counted_base</code> (see Class Hierarchy
below) and <code class="classname">__shared_count</code> are implemented separately for C++0x
and TR1, in <code class="filename">bits/boost_sp_shared_count.h</code> and
@@ -181,7 +181,7 @@ The TR1 implementation is considered relatively stable, so is unlikely to
change unless bug fixes require it. If the code that is common to both
C++0x and TR1 modes needs to diverge further then it might be necessary to
duplicate additional classes and only make changes to the C++0x versions.
-</p></div><div class="sect3" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="id635141"></a>Related functions and classes</h4></div></div></div><div class="variablelist"><dl><dt><span class="term"><code class="code">dynamic_pointer_cast</code>, <code class="code">static_pointer_cast</code>,
+</p></div><div class="sect3" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="id398449"></a>Related functions and classes</h4></div></div></div><div class="variablelist"><dl><dt><span class="term"><code class="code">dynamic_pointer_cast</code>, <code class="code">static_pointer_cast</code>,
<code class="code">const_pointer_cast</code></span></dt><dd><p>
As noted in N2351, these functions can be implemented non-intrusively using
the alias constructor. However the aliasing constructor is only available
@@ -214,10 +214,10 @@ is called. Users should not try to use this.
As well as the extra constructors, this implementation also needs some
members of _Sp_counted_deleter to be protected where they could otherwise
be private.
- </p></dd></dl></div></div></div><div class="sect2" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="shared_ptr.using"></a>Use</h3></div></div></div><div class="sect3" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="id635298"></a>Examples</h4></div></div></div><p>
+ </p></dd></dl></div></div></div><div class="sect2" lang="en" xml:lang="en"><div class="titlepage"><div><div><h3 class="title"><a id="shared_ptr.using"></a>Use</h3></div></div></div><div class="sect3" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="id399153"></a>Examples</h4></div></div></div><p>
Examples of use can be found in the testsuite, under
<code class="filename">testsuite/tr1/2_general_utilities/shared_ptr</code>.
- </p></div><div class="sect3" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="id635314"></a>Unresolved Issues</h4></div></div></div><p>
+ </p></div><div class="sect3" lang="en" xml:lang="en"><div class="titlepage"><div><div><h4 class="title"><a id="id440522"></a>Unresolved Issues</h4></div></div></div><p>
The resolution to C++ Standard Library issue <a class="ulink" href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#674" target="_top">674</a>,
"shared_ptr interface changes for consistency with N1856" will
need to be implemented after it is accepted into the working
@@ -265,7 +265,7 @@ be private.
code to work with, Peter Dimov in particular for his help and
invaluable advice on thread safety. Phillip Jordan and Paolo
Carlini for the lock policy implementation.
- </p></div><div class="bibliography"><div class="titlepage"><div><div><h3 class="title"><a id="shared_ptr.biblio"></a>Bibliography</h3></div></div></div><div class="biblioentry"><a id="id559108"></a><p>[<abbr class="abbrev">
+ </p></div><div class="bibliography"><div class="titlepage"><div><div><h3 class="title"><a id="shared_ptr.biblio"></a>Bibliography</h3></div></div></div><div class="biblioentry"><a id="id372846"></a><p>[<abbr class="abbrev">
n2351
</abbr>] <span class="title"><i>
Improving shared_ptr for C++0x, Revision 2
@@ -274,7 +274,7 @@ be private.
. </span><span class="biblioid">
<a class="ulink" href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2351.htm" target="_top">
</a>
- . </span></p></div><div class="biblioentry"><a id="id566266"></a><p>[<abbr class="abbrev">
+ . </span></p></div><div class="biblioentry"><a id="id372870"></a><p>[<abbr class="abbrev">
n2456
</abbr>] <span class="title"><i>
C++ Standard Library Active Issues List (Revision R52)
@@ -283,7 +283,7 @@ be private.
. </span><span class="biblioid">
<a class="ulink" href="http://open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2456.html" target="_top">
</a>
- . </span></p></div><div class="biblioentry"><a id="id542944"></a><p>[<abbr class="abbrev">
+ . </span></p></div><div class="biblioentry"><a id="id426703"></a><p>[<abbr class="abbrev">
n2461
</abbr>] <span class="title"><i>
Working Draft, Standard for Programming Language C++
@@ -292,7 +292,7 @@ be private.
. </span><span class="biblioid">
<a class="ulink" href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2461.pdf" target="_top">
</a>
- . </span></p></div><div class="biblioentry"><a id="id542968"></a><p>[<abbr class="abbrev">
+ . </span></p></div><div class="biblioentry"><a id="id446795"></a><p>[<abbr class="abbrev">
boostshared_ptr
</abbr>] <span class="title"><i>
Boost C++ Libraries documentation - shared_ptr class template
diff --git a/libstdc++-v3/doc/html/manual/spine.html b/libstdc++-v3/doc/html/manual/spine.html
index 8e79dbc3516..8b932707032 100644
--- a/libstdc++-v3/doc/html/manual/spine.html
+++ b/libstdc++-v3/doc/html/manual/spine.html
@@ -2,6 +2,6 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>The GNU C++ Library</title><meta name="generator" content="DocBook XSL Stylesheets V1.73.2" /><link rel="start" href="../spine.html" title="The GNU C++ Library Documentation" /><link rel="up" href="../spine.html" title="The GNU C++ Library Documentation" /><link rel="prev" href="../spine.html" title="The GNU C++ Library Documentation" /><link rel="next" href="intro.html" title="Part I. Introduction" /></head><body><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">The GNU C++ Library</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="../spine.html">Prev</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="intro.html">Next</a></td></tr></table><hr /></div><div class="book" lang="en" xml:lang="en"><div class="titlepage"><div><div><h1 class="title"><a id="manual-index"></a>The GNU C++ Library</h1></div><div><p class="copyright">Copyright © 2008
<a class="ulink" href="http://fsf.org" target="_top">FSF</a>
- </p></div><div><div class="legalnotice"><a id="id626603"></a><p>
+ </p></div><div><div class="legalnotice"><a id="id441102"></a><p>
<a class="ulink" href="17_intro/license.html" target="_top">License</a>
- </p></div></div></div><hr /></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="part"><a href="intro.html">I. Introduction</a></span></dt><dd><dl><dt><span class="chapter"><a href="bk01pt01ch01.html">1. Status</a></span></dt><dd><dl><dt><span class="sect1"><a href="bk01pt01ch01.html#manual.intro.status.standard">Implementation Status</a></span></dt><dd><dl><dt><span class="sect2"><a href="bk01pt01ch01.html#manual.intro.status.standard.1998">C++ 1998</a></span></dt><dt><span class="sect2"><a href="bk01pt01ch01.html#manual.intro.status.standard.tr1">C++ TR1</a></span></dt><dt><span class="sect2"><a href="bk01pt01ch01.html#manual.intro.status.standard.200x">C++ 200x</a></span></dt></dl></dd><dt><span class="sect1"><a href="bk01pt01ch01s02.html">License</a></span></dt><dd><dl><dt><span class="sect2"><a href="bk01pt01ch01s02.html#manual.intro.status.license.gpl">The Code: GPL</a></span></dt><dt><span class="sect2"><a href="bk01pt01ch01s02.html#manual.intro.status.license.fdl">The Documentation: GPL, FDL</a></span></dt></dl></dd><dt><span class="sect1"><a href="bk01pt01ch01s03.html">Bugs</a></span></dt><dd><dl><dt><span class="sect2"><a href="bk01pt01ch01s03.html#manual.intro.status.bugs.impl">Implementation Bugs</a></span></dt><dt><span class="sect2"><a href="bk01pt01ch01s03.html#manual.intro.status.bugs.iso">Standard Bugs</a></span></dt></dl></dd></dl></dd><dt><span class="chapter"><a href="bk01pt01ch02.html">2. Setup</a></span></dt><dd><dl><dt><span class="sect1"><a href="bk01pt01ch02.html#manual.intro.setup.configure">Configure</a></span></dt><dt><span class="sect1"><a href="build.html">Build</a></span></dt><dd><dl><dt><span class="sect2"><a href="build.html#build.prereq">Prerequisites</a></span></dt><dt><span class="sect2"><a href="build.html#build.configure">Make</a></span></dt></dl></dd><dt><span class="sect1"><a href="test.html">Test</a></span></dt><dd><dl><dt><span class="sect2"><a href="test.html#test.organization">Organization</a></span></dt><dt><span class="sect2"><a href="test.html#test.naming">Naming Conventions</a></span></dt><dt><span class="sect2"><a href="test.html#test.utils">Utilities</a></span></dt><dt><span class="sect2"><a href="test.html#test.run">Running the Testsuite</a></span></dt><dt><span class="sect2"><a href="test.html#test.new_tests">New Test Cases</a></span></dt><dt><span class="sect2"><a href="test.html#test.dejagnu">Test Harness Details</a></span></dt><dt><span class="sect2"><a href="test.html#test.future">Future</a></span></dt></dl></dd></dl></dd><dt><span class="chapter"><a href="using.html">3. Using</a></span></dt><dd><dl><dt><span class="sect1"><a href="using.html#manual.intro.using.lib">Linking Library Binary Files</a></span></dt><dt><span class="sect1"><a href="bk01pt01ch03s02.html">Headers</a></span></dt><dd><dl><dt><span class="sect2"><a href="bk01pt01ch03s02.html#manual.intro.using.headers.all">Header Files</a></span></dt><dt><span class="sect2"><a href="bk01pt01ch03s02.html#manual.intro.using.headers.mixing">Mixing Headers</a></span></dt><dt><span class="sect2"><a href="bk01pt01ch03s02.html#manual.intro.using.headers.cheaders">The C Headers and <code class="code">namespace std</code></a></span></dt><dt><span class="sect2"><a href="bk01pt01ch03s02.html#manual.intro.using.headers.pre">Precompiled Headers</a></span></dt></dl></dd><dt><span class="sect1"><a href="bk01pt01ch03s03.html">Namespaces</a></span></dt><dd><dl><dt><span class="sect2"><a href="bk01pt01ch03s03.html#manual.intro.using.namespaces.all">Available Namespaces</a></span></dt><dt><span class="sect2"><a href="bk01pt01ch03s03.html#manual.intro.using.namespaces.std">namespace std</a></span></dt><dt><span class="sect2"><a href="bk01pt01ch03s03.html#manual.intro.using.namespaces.comp">Using Namespace Composition</a></span></dt></dl></dd><dt><span class="sect1"><a href="bk01pt01ch03s04.html">Macros</a></span></dt><dt><span class="sect1"><a href="bk01pt01ch03s05.html">Concurrency</a></span></dt><dd><dl><dt><span class="sect2"><a href="bk01pt01ch03s05.html#manual.intro.using.concurrency.prereq">Prerequisites</a></span></dt><dt><span class="sect2"><a href="bk01pt01ch03s05.html#manual.intro.using.concurrency.thread_safety">Thread Safety</a></span></dt><dt><span class="sect2"><a href="bk01pt01ch03s05.html#manual.intro.using.concurrency.atomics">Atomics</a></span></dt><dt><span class="sect2"><a href="bk01pt01ch03s05.html#manual.intro.using.concurrency.io">IO</a></span></dt><dt><span class="sect2"><a href="bk01pt01ch03s05.html#manual.intro.using.concurrency.containers">Containers</a></span></dt></dl></dd><dt><span class="sect1"><a href="bk01pt01ch03s06.html">Exceptions</a></span></dt><dd><dl><dt><span class="sect2"><a href="bk01pt01ch03s06.html#intro.using.exception.propagating">Propagating Exceptions aka Exception Neutrality</a></span></dt><dt><span class="sect2"><a href="bk01pt01ch03s06.html#intro.using.exception.safety">Exception Safety</a></span></dt><dt><span class="sect2"><a href="bk01pt01ch03s06.html#intro.using.exception.no">Support for <code class="literal">-fno-exceptions</code></a></span></dt></dl></dd><dt><span class="sect1"><a href="debug.html">Debugging Support</a></span></dt><dd><dl><dt><span class="sect2"><a href="debug.html#debug.compiler">Using <span class="command"><strong>g++</strong></span></a></span></dt><dt><span class="sect2"><a href="debug.html#debug.req">Debug Versions of Library Binary Files</a></span></dt><dt><span class="sect2"><a href="debug.html#debug.memory">Memory Leak Hunting</a></span></dt><dt><span class="sect2"><a href="debug.html#debug.gdb">Using <span class="command"><strong>gdb</strong></span></a></span></dt><dt><span class="sect2"><a href="debug.html#debug.exceptions">Tracking uncaught exceptions</a></span></dt><dt><span class="sect2"><a href="debug.html#debug.debug_mode">Debug Mode</a></span></dt><dt><span class="sect2"><a href="debug.html#debug.compile_time_checks">Compile Time Checking</a></span></dt></dl></dd></dl></dd></dl></dd><dt><span class="part"><a href="support.html">II. Support</a></span></dt><dd><dl><dt><span class="preface"><a href="bk01pt02pr01.html"></a></span></dt><dt><span class="chapter"><a href="bk01pt02ch04.html">4. Types</a></span></dt><dd><dl><dt><span class="sect1"><a href="bk01pt02ch04.html#manual.support.types.fundamental">Fundamental Types</a></span></dt><dt><span class="sect1"><a href="bk01pt02ch04s02.html">Numeric Properties</a></span></dt><dt><span class="sect1"><a href="bk01pt02ch04s03.html">NULL</a></span></dt></dl></dd><dt><span class="chapter"><a href="bk01pt02ch05.html">5. Dynamic Memory</a></span></dt><dt><span class="chapter"><a href="bk01pt02ch06.html">6. Termination</a></span></dt><dd><dl><dt><span class="sect1"><a href="bk01pt02ch06.html#support.termination.handlers">Termination Handlers</a></span></dt><dt><span class="sect1"><a href="bk01pt02ch06s02.html">Verbose Terminate Handler</a></span></dt></dl></dd></dl></dd><dt><span class="part"><a href="diagnostics.html">III. Diagnostics</a></span></dt><dd><dl><dt><span class="chapter"><a href="bk01pt03ch07.html">7. Exceptions</a></span></dt><dd><dl><dt><span class="sect1"><a href="bk01pt03ch07.html#manual.diagnostics.exceptions.hierarchy">Exception Classes</a></span></dt><dt><span class="sect1"><a href="bk01pt03ch07s02.html">Adding Data to Exceptions</a></span></dt><dt><span class="sect1"><a href="bk01pt03ch07s03.html">Cancellation</a></span></dt></dl></dd><dt><span class="chapter"><a href="bk01pt03ch08.html">8. Concept Checking</a></span></dt></dl></dd><dt><span class="part"><a href="utilities.html">IV. Utilities</a></span></dt><dd><dl><dt><span class="chapter"><a href="bk01pt04ch09.html">9. Functors</a></span></dt><dt><span class="chapter"><a href="bk01pt04ch10.html">10. Pairs</a></span></dt><dt><span class="chapter"><a href="bk01pt04ch11.html">11. Memory</a></span></dt><dd><dl><dt><span class="sect1"><a href="bk01pt04ch11.html#manual.util.memory.allocator">Allocators</a></span></dt><dd><dl><dt><span class="sect2"><a href="bk01pt04ch11.html#allocator.req">Requirements</a></span></dt><dt><span class="sect2"><a href="bk01pt04ch11.html#allocator.design_issues">Design Issues</a></span></dt><dt><span class="sect2"><a href="bk01pt04ch11.html#allocator.impl">Implementation</a></span></dt><dt><span class="sect2"><a href="bk01pt04ch11.html#allocator.using">Using a Specific Allocator</a></span></dt><dt><span class="sect2"><a href="bk01pt04ch11.html#allocator.custom">Custom Allocators</a></span></dt><dt><span class="sect2"><a href="bk01pt04ch11.html#allocator.ext">Extension Allocators</a></span></dt></dl></dd><dt><span class="sect1"><a href="auto_ptr.html">auto_ptr</a></span></dt><dd><dl><dt><span class="sect2"><a href="auto_ptr.html#auto_ptr.limitations">Limitations</a></span></dt><dt><span class="sect2"><a href="auto_ptr.html#auto_ptr.using">Use in Containers</a></span></dt></dl></dd><dt><span class="sect1"><a href="shared_ptr.html">shared_ptr</a></span></dt><dd><dl><dt><span class="sect2"><a href="shared_ptr.html#shared_ptr.req">Requirements</a></span></dt><dt><span class="sect2"><a href="shared_ptr.html#shared_ptr.design_issues">Design Issues</a></span></dt><dt><span class="sect2"><a href="shared_ptr.html#shared_ptr.impl">Implementation</a></span></dt><dt><span class="sect2"><a href="shared_ptr.html#shared_ptr.using">Use</a></span></dt><dt><span class="sect2"><a href="shared_ptr.html#shared_ptr.ack">Acknowledgments</a></span></dt></dl></dd></dl></dd><dt><span class="chapter"><a href="bk01pt04ch12.html">12. Traits</a></span></dt></dl></dd><dt><span class="part"><a href="strings.html">V. Strings</a></span></dt><dd><dl><dt><span class="chapter"><a href="bk01pt05ch13.html">13. String Classes</a></span></dt><dd><dl><dt><span class="sect1"><a href="bk01pt05ch13.html#strings.string.simple">Simple Transformations</a></span></dt><dt><span class="sect1"><a href="bk01pt05ch13s02.html">Case Sensitivity</a></span></dt><dt><span class="sect1"><a href="bk01pt05ch13s03.html">Arbitrary Character Types</a></span></dt><dt><span class="sect1"><a href="bk01pt05ch13s04.html">Tokenizing</a></span></dt><dt><span class="sect1"><a href="bk01pt05ch13s05.html">Shrink to Fit</a></span></dt><dt><span class="sect1"><a href="bk01pt05ch13s06.html">CString (MFC)</a></span></dt></dl></dd></dl></dd><dt><span class="part"><a href="localization.html">VI. Localization</a></span></dt><dd><dl><dt><span class="chapter"><a href="bk01pt06ch14.html">14. Locales</a></span></dt><dd><dl><dt><span class="sect1"><a href="bk01pt06ch14.html#manual.localization.locales.locale">locale</a></span></dt><dd><dl><dt><span class="sect2"><a href="bk01pt06ch14.html#locales.locale.req">Requirements</a></span></dt><dt><span class="sect2"><a href="bk01pt06ch14.html#locales.locale.design">Design</a></span></dt><dt><span class="sect2"><a href="bk01pt06ch14.html#locales.locale.impl">Implementation</a></span></dt><dt><span class="sect2"><a href="bk01pt06ch14.html#locales.locale.future">Future</a></span></dt></dl></dd></dl></dd><dt><span class="chapter"><a href="bk01pt06ch15.html">15. Facets aka Categories</a></span></dt><dd><dl><dt><span class="sect1"><a href="bk01pt06ch15.html#manual.localization.facet.ctype">ctype</a></span></dt><dd><dl><dt><span class="sect2"><a href="bk01pt06ch15.html#facet.ctype.impl">Implementation</a></span></dt><dt><span class="sect2"><a href="bk01pt06ch15.html#facet.ctype.future">Future</a></span></dt></dl></dd><dt><span class="sect1"><a href="codecvt.html">codecvt</a></span></dt><dd><dl><dt><span class="sect2"><a href="codecvt.html#facet.codecvt.req">Requirements</a></span></dt><dt><span class="sect2"><a href="codecvt.html#facet.codecvt.design">Design</a></span></dt><dt><span class="sect2"><a href="codecvt.html#facet.codecvt.impl">Implementation</a></span></dt><dt><span class="sect2"><a href="codecvt.html#facet.codecvt.use">Use</a></span></dt><dt><span class="sect2"><a href="codecvt.html#facet.codecvt.future">Future</a></span></dt></dl></dd><dt><span class="sect1"><a href="messages.html">messages</a></span></dt><dd><dl><dt><span class="sect2"><a href="messages.html#facet.messages.req">Requirements</a></span></dt><dt><span class="sect2"><a href="messages.html#facet.messages.design">Design</a></span></dt><dt><span class="sect2"><a href="messages.html#facet.messages.impl">Implementation</a></span></dt><dt><span class="sect2"><a href="messages.html#facet.messages.use">Use</a></span></dt><dt><span class="sect2"><a href="messages.html#facet.messages.future">Future</a></span></dt></dl></dd></dl></dd></dl></dd><dt><span class="part"><a href="containers.html">VII. Containers</a></span></dt><dd><dl><dt><span class="chapter"><a href="bk01pt07ch16.html">16. Sequences</a></span></dt><dd><dl><dt><span class="sect1"><a href="bk01pt07ch16.html#containers.sequences.list">list</a></span></dt><dd><dl><dt><span class="sect2"><a href="bk01pt07ch16.html#sequences.list.size">list::size() is O(n)</a></span></dt></dl></dd><dt><span class="sect1"><a href="bk01pt07ch16s02.html">vector</a></span></dt><dd><dl><dt><span class="sect2"><a href="bk01pt07ch16s02.html#sequences.vector.management">Space Overhead Management</a></span></dt></dl></dd></dl></dd><dt><span class="chapter"><a href="bk01pt07ch17.html">17. Associative</a></span></dt><dd><dl><dt><span class="sect1"><a href="bk01pt07ch17.html#containers.associative.insert_hints">Insertion Hints</a></span></dt><dt><span class="sect1"><a href="bk01pt07ch17s02.html">bitset</a></span></dt><dd><dl><dt><span class="sect2"><a href="bk01pt07ch17s02.html#associative.bitset.size_variable">Size Variable</a></span></dt><dt><span class="sect2"><a href="bk01pt07ch17s02.html#associative.bitset.type_string">Type String</a></span></dt></dl></dd></dl></dd><dt><span class="chapter"><a href="bk01pt07ch18.html">18. Interacting with C</a></span></dt><dd><dl><dt><span class="sect1"><a href="bk01pt07ch18.html#containers.c.vs_array">Containers vs. Arrays</a></span></dt></dl></dd></dl></dd><dt><span class="part"><a href="iterators.html">VIII. Iterators</a></span></dt><dd><dl><dt><span class="chapter"><a href="bk01pt08ch19.html">19. Predefined</a></span></dt><dd><dl><dt><span class="sect1"><a href="bk01pt08ch19.html#iterators.predefined.vs_pointers">Iterators vs. Pointers</a></span></dt><dt><span class="sect1"><a href="bk01pt08ch19s02.html">One Past the End</a></span></dt></dl></dd></dl></dd><dt><span class="part"><a href="algorithms.html">IX. Algorithms</a></span></dt><dd><dl><dt><span class="preface"><a href="bk01pt09pr02.html"></a></span></dt><dt><span class="chapter"><a href="bk01pt09ch20.html">20. Mutating</a></span></dt><dd><dl><dt><span class="sect1"><a href="bk01pt09ch20.html#algorithms.mutating.swap"><code class="function">swap</code></a></span></dt><dd><dl><dt><span class="sect2"><a href="bk01pt09ch20.html#algorithms.swap.specializations">Specializations</a></span></dt></dl></dd></dl></dd></dl></dd><dt><span class="part"><a href="numerics.html">X. Numerics</a></span></dt><dd><dl><dt><span class="chapter"><a href="bk01pt10ch21.html">21. Complex</a></span></dt><dd><dl><dt><span class="sect1"><a href="bk01pt10ch21.html#numerics.complex.processing">complex Processing</a></span></dt></dl></dd><dt><span class="chapter"><a href="bk01pt10ch22.html">22. Generalized Operations</a></span></dt><dt><span class="chapter"><a href="bk01pt10ch23.html">23. Interacting with C</a></span></dt><dd><dl><dt><span class="sect1"><a href="bk01pt10ch23.html#numerics.c.array">Numerics vs. Arrays</a></span></dt><dt><span class="sect1"><a href="bk01pt10ch23s02.html">C99</a></span></dt></dl></dd></dl></dd><dt><span class="part"><a href="io.html">XI. Input and Output</a></span></dt><dd><dl><dt><span class="chapter"><a href="bk01pt11ch24.html">24. Iostream Objects</a></span></dt><dt><span class="chapter"><a href="bk01pt11ch25.html">25. Stream Buffers</a></span></dt><dd><dl><dt><span class="sect1"><a href="bk01pt11ch25.html#io.streambuf.derived">Derived streambuf Classes</a></span></dt><dt><span class="sect1"><a href="bk01pt11ch25s02.html">Buffering</a></span></dt></dl></dd><dt><span class="chapter"><a href="bk01pt11ch26.html">26. Memory Based Streams</a></span></dt><dd><dl><dt><span class="sect1"><a href="bk01pt11ch26.html#manual.io.memstreams.compat">Compatibility With strstream</a></span></dt></dl></dd><dt><span class="chapter"><a href="bk01pt11ch27.html">27. File Based Streams</a></span></dt><dd><dl><dt><span class="sect1"><a href="bk01pt11ch27.html#manual.io.filestreams.copying_a_file">Copying a File</a></span></dt><dt><span class="sect1"><a href="bk01pt11ch27s02.html">Binary Input and Output</a></span></dt><dt><span class="sect1"><a href="bk01pt11ch27s03.html">More Binary Input and Output</a></span></dt></dl></dd><dt><span class="chapter"><a href="bk01pt11ch28.html">28. Interacting with C</a></span></dt><dd><dl><dt><span class="sect1"><a href="bk01pt11ch28.html#manual.io.c.FILE">Using FILE* and file descriptors</a></span></dt><dt><span class="sect1"><a href="bk01pt11ch28s02.html">Performance</a></span></dt></dl></dd></dl></dd><dt><span class="part"><a href="extensions.html">XII. Extensions</a></span></dt><dd><dl><dt><span class="preface"><a href="bk01pt12pr03.html"></a></span></dt><dt><span class="chapter"><a href="bk01pt12ch29.html">29. Compile Time Checks</a></span></dt><dt><span class="chapter"><a href="debug_mode.html">30. Debug Mode</a></span></dt><dd><dl><dt><span class="sect1"><a href="debug_mode.html#manual.ext.debug_mode.intro">Intro</a></span></dt><dt><span class="sect1"><a href="bk01pt12ch30s02.html">Semantics</a></span></dt><dt><span class="sect1"><a href="bk01pt12ch30s03.html">Using</a></span></dt><dd><dl><dt><span class="sect2"><a href="bk01pt12ch30s03.html#debug_mode.using.mode">Using the Debug Mode</a></span></dt><dt><span class="sect2"><a href="bk01pt12ch30s03.html#debug_mode.using.specific">Using a Specific Debug Container</a></span></dt></dl></dd><dt><span class="sect1"><a href="bk01pt12ch30s04.html">Design</a></span></dt><dd><dl><dt><span class="sect2"><a href="bk01pt12ch30s04.html#manual.ext.debug_mode.design.goals">Goals</a></span></dt><dt><span class="sect2"><a href="bk01pt12ch30s04.html#manual.ext.debug_mode.design.methods">Methods</a></span></dt><dt><span class="sect2"><a href="bk01pt12ch30s04.html#manual.ext.debug_mode.design.other">Other Implementations</a></span></dt></dl></dd></dl></dd><dt><span class="chapter"><a href="parallel_mode.html">31. Parallel Mode</a></span></dt><dd><dl><dt><span class="sect1"><a href="parallel_mode.html#manual.ext.parallel_mode.intro">Intro</a></span></dt><dt><span class="sect1"><a href="bk01pt12ch31s02.html">Semantics</a></span></dt><dt><span class="sect1"><a href="bk01pt12ch31s03.html">Using</a></span></dt><dd><dl><dt><span class="sect2"><a href="bk01pt12ch31s03.html#parallel_mode.using.prereq_flags">Prerequisite Compiler Flags</a></span></dt><dt><span class="sect2"><a href="bk01pt12ch31s03.html#parallel_mode.using.parallel_mode">Using Parallel Mode</a></span></dt><dt><span class="sect2"><a href="bk01pt12ch31s03.html#parallel_mode.using.specific">Using Specific Parallel Components</a></span></dt></dl></dd><dt><span class="sect1"><a href="bk01pt12ch31s04.html">Design</a></span></dt><dd><dl><dt><span class="sect2"><a href="bk01pt12ch31s04.html#manual.ext.parallel_mode.design.intro">Interface Basics</a></span></dt><dt><span class="sect2"><a href="bk01pt12ch31s04.html#manual.ext.parallel_mode.design.tuning">Configuration and Tuning</a></span></dt><dt><span class="sect2"><a href="bk01pt12ch31s04.html#manual.ext.parallel_mode.design.impl">Implementation Namespaces</a></span></dt></dl></dd><dt><span class="sect1"><a href="bk01pt12ch31s05.html">Testing</a></span></dt><dt><span class="bibliography"><a href="parallel_mode.html#parallel_mode.biblio">Bibliography</a></span></dt></dl></dd><dt><span class="chapter"><a href="bk01pt12ch32.html">32. Allocators</a></span></dt><dd><dl><dt><span class="sect1"><a href="bk01pt12ch32.html#manual.ext.allocator.mt">mt_allocator</a></span></dt><dd><dl><dt><span class="sect2"><a href="bk01pt12ch32.html#allocator.mt.intro">Intro</a></span></dt><dt><span class="sect2"><a href="bk01pt12ch32.html#allocator.mt.design_issues">Design Issues</a></span></dt><dt><span class="sect2"><a href="bk01pt12ch32.html#allocator.mt.impl">Implementation</a></span></dt><dt><span class="sect2"><a href="bk01pt12ch32.html#allocator.mt.example_single">Single Thread Example</a></span></dt><dt><span class="sect2"><a href="bk01pt12ch32.html#allocator.mt.example_multi">Multiple Thread Example</a></span></dt></dl></dd><dt><span class="sect1"><a href="bitmap_allocator.html">bitmap_allocator</a></span></dt><dd><dl><dt><span class="sect2"><a href="bitmap_allocator.html#allocator.bitmap.design">Design</a></span></dt><dt><span class="sect2"><a href="bitmap_allocator.html#allocator.bitmap.impl">Implementation</a></span></dt></dl></dd></dl></dd><dt><span class="chapter"><a href="bk01pt12ch33.html">33. Containers</a></span></dt><dd><dl><dt><span class="sect1"><a href="bk01pt12ch33.html#manual.ext.containers.pbds">Policy Based Data Structures</a></span></dt><dt><span class="sect1"><a href="bk01pt12ch33s02.html">HP/SGI</a></span></dt><dt><span class="sect1"><a href="bk01pt12ch33s03.html">Deprecated HP/SGI</a></span></dt></dl></dd><dt><span class="chapter"><a href="bk01pt12ch34.html">34. Utilities</a></span></dt><dt><span class="chapter"><a href="bk01pt12ch35.html">35. Algorithms</a></span></dt><dt><span class="chapter"><a href="bk01pt12ch36.html">36. Numerics</a></span></dt><dt><span class="chapter"><a href="bk01pt12ch37.html">37. Iterators</a></span></dt><dt><span class="chapter"><a href="bk01pt12ch38.html">38. Input and Output</a></span></dt><dd><dl><dt><span class="sect1"><a href="bk01pt12ch38.html#manual.ext.io.filebuf_derived">Derived filebufs</a></span></dt></dl></dd><dt><span class="chapter"><a href="bk01pt12ch39.html">39. Demangling</a></span></dt><dt><span class="chapter"><a href="concurrency.html">40. Concurrency</a></span></dt><dd><dl><dt><span class="sect1"><a href="concurrency.html#manual.ext.concurrency.design">Design</a></span></dt><dd><dl><dt><span class="sect2"><a href="concurrency.html#manual.ext.concurrency.design.threads">Interface to Locks and Mutexes</a></span></dt><dt><span class="sect2"><a href="concurrency.html#manual.ext.concurrency.design.atomics">Interface to Atomic Functions</a></span></dt></dl></dd><dt><span class="sect1"><a href="bk01pt12ch40s02.html">Implementation</a></span></dt><dd><dl><dt><span class="sect2"><a href="bk01pt12ch40s02.html#manual.ext.concurrency.impl.atomic_fallbacks">Using Builtin Atomic Functions</a></span></dt><dt><span class="sect2"><a href="bk01pt12ch40s02.html#manual.ext.concurrency.impl.thread">Thread Abstraction</a></span></dt></dl></dd><dt><span class="sect1"><a href="bk01pt12ch40s03.html">Use</a></span></dt></dl></dd></dl></dd><dt><span class="appendix"><a href="appendix_contributing.html">A. Contributing</a></span></dt><dd><dl><dt><span class="sect1"><a href="appendix_contributing.html#contrib.list">Contributor Checklist</a></span></dt><dd><dl><dt><span class="sect2"><a href="appendix_contributing.html#list.reading">Reading</a></span></dt><dt><span class="sect2"><a href="appendix_contributing.html#list.copyright">Assignment</a></span></dt><dt><span class="sect2"><a href="appendix_contributing.html#list.getting">Getting Sources</a></span></dt><dt><span class="sect2"><a href="appendix_contributing.html#list.patches">Submitting Patches</a></span></dt></dl></dd><dt><span class="sect1"><a href="bk01apas02.html">Directory Layout and Source Conventions</a></span></dt><dt><span class="sect1"><a href="bk01apas03.html">Coding Style</a></span></dt><dd><dl><dt><span class="sect2"><a href="bk01apas03.html#coding_style.bad_identifiers">Bad Identifiers</a></span></dt><dt><span class="sect2"><a href="bk01apas03.html#coding_style.example">By Example</a></span></dt></dl></dd><dt><span class="sect1"><a href="bk01apas04.html">Documentation Style</a></span></dt><dd><dl><dt><span class="sect2"><a href="bk01apas04.html#doc_style.doxygen">Doxygen</a></span></dt><dt><span class="sect2"><a href="bk01apas04.html#doc_style.docbook">Docbook</a></span></dt></dl></dd><dt><span class="sect1"><a href="bk01apas05.html">Design Notes</a></span></dt></dl></dd><dt><span class="appendix"><a href="appendix_porting.html">B. Porting and Maintenance</a></span></dt><dd><dl><dt><span class="sect1"><a href="appendix_porting.html#appendix.porting.build_hacking">Configure and Build Hacking</a></span></dt><dd><dl><dt><span class="sect2"><a href="appendix_porting.html#build_hacking.prereq">Prerequisites</a></span></dt><dt><span class="sect2"><a href="appendix_porting.html#build_hacking.map">Overview: What Comes from Where</a></span></dt><dt><span class="sect2"><a href="appendix_porting.html#build_hacking.scripts">Storing Information in non-AC files (like configure.host)</a></span></dt><dt><span class="sect2"><a href="appendix_porting.html#build_hacking.conventions">Coding and Commenting Conventions</a></span></dt><dt><span class="sect2"><a href="appendix_porting.html#build_hacking.acinclude">The acinclude.m4 layout</a></span></dt><dt><span class="sect2"><a href="appendix_porting.html#build_hacking.enable"><code class="constant">GLIBCXX_ENABLE</code>, the <code class="literal">--enable</code> maker</a></span></dt></dl></dd><dt><span class="sect1"><a href="internals.html">Porting to New Hardware or Operating Systems</a></span></dt><dd><dl><dt><span class="sect2"><a href="internals.html#internals.os">Operating System</a></span></dt><dt><span class="sect2"><a href="internals.html#internals.cpu">CPU</a></span></dt><dt><span class="sect2"><a href="internals.html#internals.char_types">Character Types</a></span></dt><dt><span class="sect2"><a href="internals.html#internals.thread_safety">Thread Safety</a></span></dt><dt><span class="sect2"><a href="internals.html#internals.numeric_limits">Numeric Limits</a></span></dt><dt><span class="sect2"><a href="internals.html#internals.libtool">Libtool</a></span></dt></dl></dd><dt><span class="sect1"><a href="abi.html">ABI Policy and Guidelines</a></span></dt><dd><dl><dt><span class="sect2"><a href="abi.html#abi.cxx_interface">The C++ Interface</a></span></dt><dt><span class="sect2"><a href="abi.html#abi.versioning">Versioning</a></span></dt><dt><span class="sect2"><a href="abi.html#abi.changes_allowed">Allowed Changes</a></span></dt><dt><span class="sect2"><a href="abi.html#abi.changes_no">Prohibited Changes</a></span></dt><dt><span class="sect2"><a href="abi.html#abi.impl">Implementation</a></span></dt><dt><span class="sect2"><a href="abi.html#abi.testing">Testing</a></span></dt><dt><span class="sect2"><a href="abi.html#abi.issues">Outstanding Issues</a></span></dt></dl></dd><dt><span class="sect1"><a href="api.html">API Evolution and Deprecation History</a></span></dt><dd><dl><dt><span class="sect2"><a href="api.html#api.rel_300"><code class="constant">3.0</code></a></span></dt><dt><span class="sect2"><a href="api.html#api.rel_310"><code class="constant">3.1</code></a></span></dt><dt><span class="sect2"><a href="api.html#api.rel_320"><code class="constant">3.2</code></a></span></dt><dt><span class="sect2"><a href="api.html#api.rel_330"><code class="constant">3.3</code></a></span></dt><dt><span class="sect2"><a href="api.html#api.rel_340"><code class="constant">3.4</code></a></span></dt><dt><span class="sect2"><a href="api.html#api.rel_400"><code class="constant">4.0</code></a></span></dt><dt><span class="sect2"><a href="api.html#api.rel_410"><code class="constant">4.1</code></a></span></dt><dt><span class="sect2"><a href="api.html#api.rel_420"><code class="constant">4.2</code></a></span></dt><dt><span class="sect2"><a href="api.html#api.rel_430"><code class="constant">4.3</code></a></span></dt></dl></dd><dt><span class="sect1"><a href="backwards.html">Backwards Compatibility</a></span></dt><dd><dl><dt><span class="sect2"><a href="backwards.html#backwards.first">First</a></span></dt><dt><span class="sect2"><a href="backwards.html#backwards.second">Second</a></span></dt><dt><span class="sect2"><a href="backwards.html#backwards.third">Third</a></span></dt></dl></dd></dl></dd><dt><span class="appendix"><a href="appendix_free.html">C. Free Software Needs Free Documentation</a></span></dt><dt><span class="appendix"><a href="bk01apd.html">D. GNU General Public License</a></span></dt><dd><dl><dt><span class="section"><a href="bk01apd.html#gpl-1">Preamble</a></span></dt><dt><span class="section"><a href="bk01apds02.html">TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION</a></span></dt><dd><dl><dt><span class="section"><a href="bk01apds02.html#gpl-2-0">Section 0</a></span></dt><dt><span class="section"><a href="bk01apds02.html#gpl-2-1">Section 1</a></span></dt><dt><span class="section"><a href="bk01apds02.html#gpl-2-2">Section 2</a></span></dt><dt><span class="section"><a href="bk01apds02.html#gpl-2-3">Section 3</a></span></dt><dt><span class="section"><a href="bk01apds02.html#gpl-2-4">Section 4</a></span></dt><dt><span class="section"><a href="bk01apds02.html#gpl-2-5">Section 5</a></span></dt><dt><span class="section"><a href="bk01apds02.html#gpl-2-6">Section 6</a></span></dt><dt><span class="section"><a href="bk01apds02.html#gpl-2-7">Section 7</a></span></dt><dt><span class="section"><a href="bk01apds02.html#gpl-2-8">Section 8</a></span></dt><dt><span class="section"><a href="bk01apds02.html#gpl-2-9">Section 9</a></span></dt><dt><span class="section"><a href="bk01apds02.html#gpl-2-10">Section 10</a></span></dt><dt><span class="section"><a href="bk01apds02.html#gpl-2-11">NO WARRANTY Section 11</a></span></dt><dt><span class="section"><a href="bk01apds02.html#gpl-2-12">Section 12</a></span></dt></dl></dd><dt><span class="section"><a href="bk01apds03.html">How to Apply These Terms to Your New Programs</a></span></dt></dl></dd><dt><span class="appendix"><a href="bk01ape.html">E. GNU Free Documentation License</a></span></dt></dl></div><div class="list-of-tables"><p><b>List of Tables</b></p><dl><dt>1.1. <a href="bk01pt01ch01.html#id619193">C++ TR1 Implementation Status</a></dt><dt>1.2. <a href="bk01pt01ch01.html#id614832">C++ 200x Implementation Status</a></dt><dt>3.1. <a href="bk01pt01ch03s02.html#id559438">C++ 1998 Library Headers</a></dt><dt>3.2. <a href="bk01pt01ch03s02.html#id638001">C++ 1998 Library Headers for C Library Facilities</a></dt><dt>3.3. <a href="bk01pt01ch03s02.html#id573284">C++ 200x Library Headers</a></dt><dt>3.4. <a href="bk01pt01ch03s02.html#id555603">C++ 200x Library Headers for C Library Facilities</a></dt><dt>3.5. <a href="bk01pt01ch03s02.html#id556833">C++ TR1 Library Headers</a></dt><dt>3.6. <a href="bk01pt01ch03s02.html#id548044">C++ TR1 Library Headers for C Library Facilities</a></dt><dt>3.7. <a href="bk01pt01ch03s02.html#id634486">C++ ABI Headers</a></dt><dt>3.8. <a href="bk01pt01ch03s02.html#id624264">Extension Headers</a></dt><dt>3.9. <a href="bk01pt01ch03s02.html#id648609">Extension Debug Headers</a></dt><dt>3.10. <a href="bk01pt01ch03s02.html#id609186">Extension Parallel Headers</a></dt><dt>30.1. <a href="bk01pt12ch30s03.html#id552456">Debugging Containers</a></dt><dt>30.2. <a href="bk01pt12ch30s03.html#id566906">Debugging Containers C++0x</a></dt><dt>31.1. <a href="bk01pt12ch31s03.html#id619355">Parallel Algorithms</a></dt><dt>32.1. <a href="bitmap_allocator.html#id570814">Bitmap Allocator Memory Map</a></dt><dt>B.1. <a href="api.html#id586703">Extension Allocators</a></dt><dt>B.2. <a href="api.html#id596348">Extension Allocators Continued</a></dt></dl></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="../spine.html">Prev</a> </td><td width="20%" align="center"> </td><td width="40%" align="right"> <a accesskey="n" href="intro.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">The GNU C++ Library Documentation </td><td width="20%" align="center"><a accesskey="h" href="../spine.html">Home</a></td><td width="40%" align="right" valign="top"> Part I. Introduction</td></tr></table></div></body></html>
+ </p></div></div></div><hr /></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="part"><a href="intro.html">I. Introduction</a></span></dt><dd><dl><dt><span class="chapter"><a href="bk01pt01ch01.html">1. Status</a></span></dt><dd><dl><dt><span class="sect1"><a href="bk01pt01ch01.html#manual.intro.status.standard">Implementation Status</a></span></dt><dd><dl><dt><span class="sect2"><a href="bk01pt01ch01.html#manual.intro.status.standard.1998">C++ 1998</a></span></dt><dt><span class="sect2"><a href="bk01pt01ch01.html#manual.intro.status.standard.tr1">C++ TR1</a></span></dt><dt><span class="sect2"><a href="bk01pt01ch01.html#manual.intro.status.standard.200x">C++ 200x</a></span></dt></dl></dd><dt><span class="sect1"><a href="bk01pt01ch01s02.html">License</a></span></dt><dd><dl><dt><span class="sect2"><a href="bk01pt01ch01s02.html#manual.intro.status.license.gpl">The Code: GPL</a></span></dt><dt><span class="sect2"><a href="bk01pt01ch01s02.html#manual.intro.status.license.fdl">The Documentation: GPL, FDL</a></span></dt></dl></dd><dt><span class="sect1"><a href="bk01pt01ch01s03.html">Bugs</a></span></dt><dd><dl><dt><span class="sect2"><a href="bk01pt01ch01s03.html#manual.intro.status.bugs.impl">Implementation Bugs</a></span></dt><dt><span class="sect2"><a href="bk01pt01ch01s03.html#manual.intro.status.bugs.iso">Standard Bugs</a></span></dt></dl></dd></dl></dd><dt><span class="chapter"><a href="bk01pt01ch02.html">2. Setup</a></span></dt><dd><dl><dt><span class="sect1"><a href="bk01pt01ch02.html#manual.intro.setup.configure">Configure</a></span></dt><dt><span class="sect1"><a href="build.html">Build</a></span></dt><dd><dl><dt><span class="sect2"><a href="build.html#build.prereq">Prerequisites</a></span></dt><dt><span class="sect2"><a href="build.html#build.configure">Make</a></span></dt></dl></dd><dt><span class="sect1"><a href="test.html">Test</a></span></dt><dd><dl><dt><span class="sect2"><a href="test.html#test.organization">Organization</a></span></dt><dt><span class="sect2"><a href="test.html#test.naming">Naming Conventions</a></span></dt><dt><span class="sect2"><a href="test.html#test.utils">Utilities</a></span></dt><dt><span class="sect2"><a href="test.html#test.run">Running the Testsuite</a></span></dt><dt><span class="sect2"><a href="test.html#test.new_tests">New Test Cases</a></span></dt><dt><span class="sect2"><a href="test.html#test.dejagnu">Test Harness Details</a></span></dt><dt><span class="sect2"><a href="test.html#test.future">Future</a></span></dt></dl></dd></dl></dd><dt><span class="chapter"><a href="using.html">3. Using</a></span></dt><dd><dl><dt><span class="sect1"><a href="using.html#manual.intro.using.lib">Linking Library Binary Files</a></span></dt><dt><span class="sect1"><a href="bk01pt01ch03s02.html">Headers</a></span></dt><dd><dl><dt><span class="sect2"><a href="bk01pt01ch03s02.html#manual.intro.using.headers.all">Header Files</a></span></dt><dt><span class="sect2"><a href="bk01pt01ch03s02.html#manual.intro.using.headers.mixing">Mixing Headers</a></span></dt><dt><span class="sect2"><a href="bk01pt01ch03s02.html#manual.intro.using.headers.cheaders">The C Headers and <code class="code">namespace std</code></a></span></dt><dt><span class="sect2"><a href="bk01pt01ch03s02.html#manual.intro.using.headers.pre">Precompiled Headers</a></span></dt></dl></dd><dt><span class="sect1"><a href="bk01pt01ch03s03.html">Namespaces</a></span></dt><dd><dl><dt><span class="sect2"><a href="bk01pt01ch03s03.html#manual.intro.using.namespaces.all">Available Namespaces</a></span></dt><dt><span class="sect2"><a href="bk01pt01ch03s03.html#manual.intro.using.namespaces.std">namespace std</a></span></dt><dt><span class="sect2"><a href="bk01pt01ch03s03.html#manual.intro.using.namespaces.comp">Using Namespace Composition</a></span></dt></dl></dd><dt><span class="sect1"><a href="bk01pt01ch03s04.html">Macros</a></span></dt><dt><span class="sect1"><a href="bk01pt01ch03s05.html">Concurrency</a></span></dt><dd><dl><dt><span class="sect2"><a href="bk01pt01ch03s05.html#manual.intro.using.concurrency.prereq">Prerequisites</a></span></dt><dt><span class="sect2"><a href="bk01pt01ch03s05.html#manual.intro.using.concurrency.thread_safety">Thread Safety</a></span></dt><dt><span class="sect2"><a href="bk01pt01ch03s05.html#manual.intro.using.concurrency.atomics">Atomics</a></span></dt><dt><span class="sect2"><a href="bk01pt01ch03s05.html#manual.intro.using.concurrency.io">IO</a></span></dt><dt><span class="sect2"><a href="bk01pt01ch03s05.html#manual.intro.using.concurrency.containers">Containers</a></span></dt></dl></dd><dt><span class="sect1"><a href="bk01pt01ch03s06.html">Exceptions</a></span></dt><dd><dl><dt><span class="sect2"><a href="bk01pt01ch03s06.html#intro.using.exception.propagating">Propagating Exceptions aka Exception Neutrality</a></span></dt><dt><span class="sect2"><a href="bk01pt01ch03s06.html#intro.using.exception.safety">Exception Safety</a></span></dt><dt><span class="sect2"><a href="bk01pt01ch03s06.html#intro.using.exception.no">Support for <code class="literal">-fno-exceptions</code></a></span></dt></dl></dd><dt><span class="sect1"><a href="debug.html">Debugging Support</a></span></dt><dd><dl><dt><span class="sect2"><a href="debug.html#debug.compiler">Using <span class="command"><strong>g++</strong></span></a></span></dt><dt><span class="sect2"><a href="debug.html#debug.req">Debug Versions of Library Binary Files</a></span></dt><dt><span class="sect2"><a href="debug.html#debug.memory">Memory Leak Hunting</a></span></dt><dt><span class="sect2"><a href="debug.html#debug.gdb">Using <span class="command"><strong>gdb</strong></span></a></span></dt><dt><span class="sect2"><a href="debug.html#debug.exceptions">Tracking uncaught exceptions</a></span></dt><dt><span class="sect2"><a href="debug.html#debug.debug_mode">Debug Mode</a></span></dt><dt><span class="sect2"><a href="debug.html#debug.compile_time_checks">Compile Time Checking</a></span></dt></dl></dd></dl></dd></dl></dd><dt><span class="part"><a href="support.html">II. Support</a></span></dt><dd><dl><dt><span class="preface"><a href="bk01pt02pr01.html"></a></span></dt><dt><span class="chapter"><a href="bk01pt02ch04.html">4. Types</a></span></dt><dd><dl><dt><span class="sect1"><a href="bk01pt02ch04.html#manual.support.types.fundamental">Fundamental Types</a></span></dt><dt><span class="sect1"><a href="bk01pt02ch04s02.html">Numeric Properties</a></span></dt><dt><span class="sect1"><a href="bk01pt02ch04s03.html">NULL</a></span></dt></dl></dd><dt><span class="chapter"><a href="bk01pt02ch05.html">5. Dynamic Memory</a></span></dt><dt><span class="chapter"><a href="bk01pt02ch06.html">6. Termination</a></span></dt><dd><dl><dt><span class="sect1"><a href="bk01pt02ch06.html#support.termination.handlers">Termination Handlers</a></span></dt><dt><span class="sect1"><a href="bk01pt02ch06s02.html">Verbose Terminate Handler</a></span></dt></dl></dd></dl></dd><dt><span class="part"><a href="diagnostics.html">III. Diagnostics</a></span></dt><dd><dl><dt><span class="chapter"><a href="bk01pt03ch07.html">7. Exceptions</a></span></dt><dd><dl><dt><span class="sect1"><a href="bk01pt03ch07.html#manual.diagnostics.exceptions.hierarchy">Exception Classes</a></span></dt><dt><span class="sect1"><a href="bk01pt03ch07s02.html">Adding Data to Exceptions</a></span></dt><dt><span class="sect1"><a href="bk01pt03ch07s03.html">Cancellation</a></span></dt></dl></dd><dt><span class="chapter"><a href="bk01pt03ch08.html">8. Concept Checking</a></span></dt></dl></dd><dt><span class="part"><a href="utilities.html">IV. Utilities</a></span></dt><dd><dl><dt><span class="chapter"><a href="bk01pt04ch09.html">9. Functors</a></span></dt><dt><span class="chapter"><a href="bk01pt04ch10.html">10. Pairs</a></span></dt><dt><span class="chapter"><a href="bk01pt04ch11.html">11. Memory</a></span></dt><dd><dl><dt><span class="sect1"><a href="bk01pt04ch11.html#manual.util.memory.allocator">Allocators</a></span></dt><dd><dl><dt><span class="sect2"><a href="bk01pt04ch11.html#allocator.req">Requirements</a></span></dt><dt><span class="sect2"><a href="bk01pt04ch11.html#allocator.design_issues">Design Issues</a></span></dt><dt><span class="sect2"><a href="bk01pt04ch11.html#allocator.impl">Implementation</a></span></dt><dt><span class="sect2"><a href="bk01pt04ch11.html#allocator.using">Using a Specific Allocator</a></span></dt><dt><span class="sect2"><a href="bk01pt04ch11.html#allocator.custom">Custom Allocators</a></span></dt><dt><span class="sect2"><a href="bk01pt04ch11.html#allocator.ext">Extension Allocators</a></span></dt></dl></dd><dt><span class="sect1"><a href="auto_ptr.html">auto_ptr</a></span></dt><dd><dl><dt><span class="sect2"><a href="auto_ptr.html#auto_ptr.limitations">Limitations</a></span></dt><dt><span class="sect2"><a href="auto_ptr.html#auto_ptr.using">Use in Containers</a></span></dt></dl></dd><dt><span class="sect1"><a href="shared_ptr.html">shared_ptr</a></span></dt><dd><dl><dt><span class="sect2"><a href="shared_ptr.html#shared_ptr.req">Requirements</a></span></dt><dt><span class="sect2"><a href="shared_ptr.html#shared_ptr.design_issues">Design Issues</a></span></dt><dt><span class="sect2"><a href="shared_ptr.html#shared_ptr.impl">Implementation</a></span></dt><dt><span class="sect2"><a href="shared_ptr.html#shared_ptr.using">Use</a></span></dt><dt><span class="sect2"><a href="shared_ptr.html#shared_ptr.ack">Acknowledgments</a></span></dt></dl></dd></dl></dd><dt><span class="chapter"><a href="bk01pt04ch12.html">12. Traits</a></span></dt></dl></dd><dt><span class="part"><a href="strings.html">V. Strings</a></span></dt><dd><dl><dt><span class="chapter"><a href="bk01pt05ch13.html">13. String Classes</a></span></dt><dd><dl><dt><span class="sect1"><a href="bk01pt05ch13.html#strings.string.simple">Simple Transformations</a></span></dt><dt><span class="sect1"><a href="bk01pt05ch13s02.html">Case Sensitivity</a></span></dt><dt><span class="sect1"><a href="bk01pt05ch13s03.html">Arbitrary Character Types</a></span></dt><dt><span class="sect1"><a href="bk01pt05ch13s04.html">Tokenizing</a></span></dt><dt><span class="sect1"><a href="bk01pt05ch13s05.html">Shrink to Fit</a></span></dt><dt><span class="sect1"><a href="bk01pt05ch13s06.html">CString (MFC)</a></span></dt></dl></dd></dl></dd><dt><span class="part"><a href="localization.html">VI. Localization</a></span></dt><dd><dl><dt><span class="chapter"><a href="bk01pt06ch14.html">14. Locales</a></span></dt><dd><dl><dt><span class="sect1"><a href="bk01pt06ch14.html#manual.localization.locales.locale">locale</a></span></dt><dd><dl><dt><span class="sect2"><a href="bk01pt06ch14.html#locales.locale.req">Requirements</a></span></dt><dt><span class="sect2"><a href="bk01pt06ch14.html#locales.locale.design">Design</a></span></dt><dt><span class="sect2"><a href="bk01pt06ch14.html#locales.locale.impl">Implementation</a></span></dt><dt><span class="sect2"><a href="bk01pt06ch14.html#locales.locale.future">Future</a></span></dt></dl></dd></dl></dd><dt><span class="chapter"><a href="bk01pt06ch15.html">15. Facets aka Categories</a></span></dt><dd><dl><dt><span class="sect1"><a href="bk01pt06ch15.html#manual.localization.facet.ctype">ctype</a></span></dt><dd><dl><dt><span class="sect2"><a href="bk01pt06ch15.html#facet.ctype.impl">Implementation</a></span></dt><dt><span class="sect2"><a href="bk01pt06ch15.html#facet.ctype.future">Future</a></span></dt></dl></dd><dt><span class="sect1"><a href="codecvt.html">codecvt</a></span></dt><dd><dl><dt><span class="sect2"><a href="codecvt.html#facet.codecvt.req">Requirements</a></span></dt><dt><span class="sect2"><a href="codecvt.html#facet.codecvt.design">Design</a></span></dt><dt><span class="sect2"><a href="codecvt.html#facet.codecvt.impl">Implementation</a></span></dt><dt><span class="sect2"><a href="codecvt.html#facet.codecvt.use">Use</a></span></dt><dt><span class="sect2"><a href="codecvt.html#facet.codecvt.future">Future</a></span></dt></dl></dd><dt><span class="sect1"><a href="messages.html">messages</a></span></dt><dd><dl><dt><span class="sect2"><a href="messages.html#facet.messages.req">Requirements</a></span></dt><dt><span class="sect2"><a href="messages.html#facet.messages.design">Design</a></span></dt><dt><span class="sect2"><a href="messages.html#facet.messages.impl">Implementation</a></span></dt><dt><span class="sect2"><a href="messages.html#facet.messages.use">Use</a></span></dt><dt><span class="sect2"><a href="messages.html#facet.messages.future">Future</a></span></dt></dl></dd></dl></dd></dl></dd><dt><span class="part"><a href="containers.html">VII. Containers</a></span></dt><dd><dl><dt><span class="chapter"><a href="bk01pt07ch16.html">16. Sequences</a></span></dt><dd><dl><dt><span class="sect1"><a href="bk01pt07ch16.html#containers.sequences.list">list</a></span></dt><dd><dl><dt><span class="sect2"><a href="bk01pt07ch16.html#sequences.list.size">list::size() is O(n)</a></span></dt></dl></dd><dt><span class="sect1"><a href="bk01pt07ch16s02.html">vector</a></span></dt><dd><dl><dt><span class="sect2"><a href="bk01pt07ch16s02.html#sequences.vector.management">Space Overhead Management</a></span></dt></dl></dd></dl></dd><dt><span class="chapter"><a href="bk01pt07ch17.html">17. Associative</a></span></dt><dd><dl><dt><span class="sect1"><a href="bk01pt07ch17.html#containers.associative.insert_hints">Insertion Hints</a></span></dt><dt><span class="sect1"><a href="bk01pt07ch17s02.html">bitset</a></span></dt><dd><dl><dt><span class="sect2"><a href="bk01pt07ch17s02.html#associative.bitset.size_variable">Size Variable</a></span></dt><dt><span class="sect2"><a href="bk01pt07ch17s02.html#associative.bitset.type_string">Type String</a></span></dt></dl></dd></dl></dd><dt><span class="chapter"><a href="bk01pt07ch18.html">18. Interacting with C</a></span></dt><dd><dl><dt><span class="sect1"><a href="bk01pt07ch18.html#containers.c.vs_array">Containers vs. Arrays</a></span></dt></dl></dd></dl></dd><dt><span class="part"><a href="iterators.html">VIII. Iterators</a></span></dt><dd><dl><dt><span class="chapter"><a href="bk01pt08ch19.html">19. Predefined</a></span></dt><dd><dl><dt><span class="sect1"><a href="bk01pt08ch19.html#iterators.predefined.vs_pointers">Iterators vs. Pointers</a></span></dt><dt><span class="sect1"><a href="bk01pt08ch19s02.html">One Past the End</a></span></dt></dl></dd></dl></dd><dt><span class="part"><a href="algorithms.html">IX. Algorithms</a></span></dt><dd><dl><dt><span class="preface"><a href="bk01pt09pr02.html"></a></span></dt><dt><span class="chapter"><a href="bk01pt09ch20.html">20. Mutating</a></span></dt><dd><dl><dt><span class="sect1"><a href="bk01pt09ch20.html#algorithms.mutating.swap"><code class="function">swap</code></a></span></dt><dd><dl><dt><span class="sect2"><a href="bk01pt09ch20.html#algorithms.swap.specializations">Specializations</a></span></dt></dl></dd></dl></dd></dl></dd><dt><span class="part"><a href="numerics.html">X. Numerics</a></span></dt><dd><dl><dt><span class="chapter"><a href="bk01pt10ch21.html">21. Complex</a></span></dt><dd><dl><dt><span class="sect1"><a href="bk01pt10ch21.html#numerics.complex.processing">complex Processing</a></span></dt></dl></dd><dt><span class="chapter"><a href="bk01pt10ch22.html">22. Generalized Operations</a></span></dt><dt><span class="chapter"><a href="bk01pt10ch23.html">23. Interacting with C</a></span></dt><dd><dl><dt><span class="sect1"><a href="bk01pt10ch23.html#numerics.c.array">Numerics vs. Arrays</a></span></dt><dt><span class="sect1"><a href="bk01pt10ch23s02.html">C99</a></span></dt></dl></dd></dl></dd><dt><span class="part"><a href="io.html">XI. Input and Output</a></span></dt><dd><dl><dt><span class="chapter"><a href="bk01pt11ch24.html">24. Iostream Objects</a></span></dt><dt><span class="chapter"><a href="bk01pt11ch25.html">25. Stream Buffers</a></span></dt><dd><dl><dt><span class="sect1"><a href="bk01pt11ch25.html#io.streambuf.derived">Derived streambuf Classes</a></span></dt><dt><span class="sect1"><a href="bk01pt11ch25s02.html">Buffering</a></span></dt></dl></dd><dt><span class="chapter"><a href="bk01pt11ch26.html">26. Memory Based Streams</a></span></dt><dd><dl><dt><span class="sect1"><a href="bk01pt11ch26.html#manual.io.memstreams.compat">Compatibility With strstream</a></span></dt></dl></dd><dt><span class="chapter"><a href="bk01pt11ch27.html">27. File Based Streams</a></span></dt><dd><dl><dt><span class="sect1"><a href="bk01pt11ch27.html#manual.io.filestreams.copying_a_file">Copying a File</a></span></dt><dt><span class="sect1"><a href="bk01pt11ch27s02.html">Binary Input and Output</a></span></dt><dt><span class="sect1"><a href="bk01pt11ch27s03.html">More Binary Input and Output</a></span></dt></dl></dd><dt><span class="chapter"><a href="bk01pt11ch28.html">28. Interacting with C</a></span></dt><dd><dl><dt><span class="sect1"><a href="bk01pt11ch28.html#manual.io.c.FILE">Using FILE* and file descriptors</a></span></dt><dt><span class="sect1"><a href="bk01pt11ch28s02.html">Performance</a></span></dt></dl></dd></dl></dd><dt><span class="part"><a href="extensions.html">XII. Extensions</a></span></dt><dd><dl><dt><span class="preface"><a href="bk01pt12pr03.html"></a></span></dt><dt><span class="chapter"><a href="bk01pt12ch29.html">29. Compile Time Checks</a></span></dt><dt><span class="chapter"><a href="debug_mode.html">30. Debug Mode</a></span></dt><dd><dl><dt><span class="sect1"><a href="debug_mode.html#manual.ext.debug_mode.intro">Intro</a></span></dt><dt><span class="sect1"><a href="bk01pt12ch30s02.html">Semantics</a></span></dt><dt><span class="sect1"><a href="bk01pt12ch30s03.html">Using</a></span></dt><dd><dl><dt><span class="sect2"><a href="bk01pt12ch30s03.html#debug_mode.using.mode">Using the Debug Mode</a></span></dt><dt><span class="sect2"><a href="bk01pt12ch30s03.html#debug_mode.using.specific">Using a Specific Debug Container</a></span></dt></dl></dd><dt><span class="sect1"><a href="bk01pt12ch30s04.html">Design</a></span></dt><dd><dl><dt><span class="sect2"><a href="bk01pt12ch30s04.html#manual.ext.debug_mode.design.goals">Goals</a></span></dt><dt><span class="sect2"><a href="bk01pt12ch30s04.html#manual.ext.debug_mode.design.methods">Methods</a></span></dt><dt><span class="sect2"><a href="bk01pt12ch30s04.html#manual.ext.debug_mode.design.other">Other Implementations</a></span></dt></dl></dd></dl></dd><dt><span class="chapter"><a href="parallel_mode.html">31. Parallel Mode</a></span></dt><dd><dl><dt><span class="sect1"><a href="parallel_mode.html#manual.ext.parallel_mode.intro">Intro</a></span></dt><dt><span class="sect1"><a href="bk01pt12ch31s02.html">Semantics</a></span></dt><dt><span class="sect1"><a href="bk01pt12ch31s03.html">Using</a></span></dt><dd><dl><dt><span class="sect2"><a href="bk01pt12ch31s03.html#parallel_mode.using.prereq_flags">Prerequisite Compiler Flags</a></span></dt><dt><span class="sect2"><a href="bk01pt12ch31s03.html#parallel_mode.using.parallel_mode">Using Parallel Mode</a></span></dt><dt><span class="sect2"><a href="bk01pt12ch31s03.html#parallel_mode.using.specific">Using Specific Parallel Components</a></span></dt></dl></dd><dt><span class="sect1"><a href="bk01pt12ch31s04.html">Design</a></span></dt><dd><dl><dt><span class="sect2"><a href="bk01pt12ch31s04.html#manual.ext.parallel_mode.design.intro">Interface Basics</a></span></dt><dt><span class="sect2"><a href="bk01pt12ch31s04.html#manual.ext.parallel_mode.design.tuning">Configuration and Tuning</a></span></dt><dt><span class="sect2"><a href="bk01pt12ch31s04.html#manual.ext.parallel_mode.design.impl">Implementation Namespaces</a></span></dt></dl></dd><dt><span class="sect1"><a href="bk01pt12ch31s05.html">Testing</a></span></dt><dt><span class="bibliography"><a href="parallel_mode.html#parallel_mode.biblio">Bibliography</a></span></dt></dl></dd><dt><span class="chapter"><a href="bk01pt12ch32.html">32. Allocators</a></span></dt><dd><dl><dt><span class="sect1"><a href="bk01pt12ch32.html#manual.ext.allocator.mt">mt_allocator</a></span></dt><dd><dl><dt><span class="sect2"><a href="bk01pt12ch32.html#allocator.mt.intro">Intro</a></span></dt><dt><span class="sect2"><a href="bk01pt12ch32.html#allocator.mt.design_issues">Design Issues</a></span></dt><dt><span class="sect2"><a href="bk01pt12ch32.html#allocator.mt.impl">Implementation</a></span></dt><dt><span class="sect2"><a href="bk01pt12ch32.html#allocator.mt.example_single">Single Thread Example</a></span></dt><dt><span class="sect2"><a href="bk01pt12ch32.html#allocator.mt.example_multi">Multiple Thread Example</a></span></dt></dl></dd><dt><span class="sect1"><a href="bitmap_allocator.html">bitmap_allocator</a></span></dt><dd><dl><dt><span class="sect2"><a href="bitmap_allocator.html#allocator.bitmap.design">Design</a></span></dt><dt><span class="sect2"><a href="bitmap_allocator.html#allocator.bitmap.impl">Implementation</a></span></dt></dl></dd></dl></dd><dt><span class="chapter"><a href="bk01pt12ch33.html">33. Containers</a></span></dt><dd><dl><dt><span class="sect1"><a href="bk01pt12ch33.html#manual.ext.containers.pbds">Policy Based Data Structures</a></span></dt><dt><span class="sect1"><a href="bk01pt12ch33s02.html">HP/SGI</a></span></dt><dt><span class="sect1"><a href="bk01pt12ch33s03.html">Deprecated HP/SGI</a></span></dt></dl></dd><dt><span class="chapter"><a href="bk01pt12ch34.html">34. Utilities</a></span></dt><dt><span class="chapter"><a href="bk01pt12ch35.html">35. Algorithms</a></span></dt><dt><span class="chapter"><a href="bk01pt12ch36.html">36. Numerics</a></span></dt><dt><span class="chapter"><a href="bk01pt12ch37.html">37. Iterators</a></span></dt><dt><span class="chapter"><a href="bk01pt12ch38.html">38. Input and Output</a></span></dt><dd><dl><dt><span class="sect1"><a href="bk01pt12ch38.html#manual.ext.io.filebuf_derived">Derived filebufs</a></span></dt></dl></dd><dt><span class="chapter"><a href="bk01pt12ch39.html">39. Demangling</a></span></dt><dt><span class="chapter"><a href="concurrency.html">40. Concurrency</a></span></dt><dd><dl><dt><span class="sect1"><a href="concurrency.html#manual.ext.concurrency.design">Design</a></span></dt><dd><dl><dt><span class="sect2"><a href="concurrency.html#manual.ext.concurrency.design.threads">Interface to Locks and Mutexes</a></span></dt><dt><span class="sect2"><a href="concurrency.html#manual.ext.concurrency.design.atomics">Interface to Atomic Functions</a></span></dt></dl></dd><dt><span class="sect1"><a href="bk01pt12ch40s02.html">Implementation</a></span></dt><dd><dl><dt><span class="sect2"><a href="bk01pt12ch40s02.html#manual.ext.concurrency.impl.atomic_fallbacks">Using Builtin Atomic Functions</a></span></dt><dt><span class="sect2"><a href="bk01pt12ch40s02.html#manual.ext.concurrency.impl.thread">Thread Abstraction</a></span></dt></dl></dd><dt><span class="sect1"><a href="bk01pt12ch40s03.html">Use</a></span></dt></dl></dd></dl></dd><dt><span class="appendix"><a href="appendix_contributing.html">A. Contributing</a></span></dt><dd><dl><dt><span class="sect1"><a href="appendix_contributing.html#contrib.list">Contributor Checklist</a></span></dt><dd><dl><dt><span class="sect2"><a href="appendix_contributing.html#list.reading">Reading</a></span></dt><dt><span class="sect2"><a href="appendix_contributing.html#list.copyright">Assignment</a></span></dt><dt><span class="sect2"><a href="appendix_contributing.html#list.getting">Getting Sources</a></span></dt><dt><span class="sect2"><a href="appendix_contributing.html#list.patches">Submitting Patches</a></span></dt></dl></dd><dt><span class="sect1"><a href="bk01apas02.html">Directory Layout and Source Conventions</a></span></dt><dt><span class="sect1"><a href="bk01apas03.html">Coding Style</a></span></dt><dd><dl><dt><span class="sect2"><a href="bk01apas03.html#coding_style.bad_identifiers">Bad Identifiers</a></span></dt><dt><span class="sect2"><a href="bk01apas03.html#coding_style.example">By Example</a></span></dt></dl></dd><dt><span class="sect1"><a href="bk01apas04.html">Documentation Style</a></span></dt><dd><dl><dt><span class="sect2"><a href="bk01apas04.html#doc_style.doxygen">Doxygen</a></span></dt><dt><span class="sect2"><a href="bk01apas04.html#doc_style.docbook">Docbook</a></span></dt></dl></dd><dt><span class="sect1"><a href="bk01apas05.html">Design Notes</a></span></dt></dl></dd><dt><span class="appendix"><a href="appendix_porting.html">B. Porting and Maintenance</a></span></dt><dd><dl><dt><span class="sect1"><a href="appendix_porting.html#appendix.porting.build_hacking">Configure and Build Hacking</a></span></dt><dd><dl><dt><span class="sect2"><a href="appendix_porting.html#build_hacking.prereq">Prerequisites</a></span></dt><dt><span class="sect2"><a href="appendix_porting.html#build_hacking.map">Overview: What Comes from Where</a></span></dt><dt><span class="sect2"><a href="appendix_porting.html#build_hacking.scripts">Storing Information in non-AC files (like configure.host)</a></span></dt><dt><span class="sect2"><a href="appendix_porting.html#build_hacking.conventions">Coding and Commenting Conventions</a></span></dt><dt><span class="sect2"><a href="appendix_porting.html#build_hacking.acinclude">The acinclude.m4 layout</a></span></dt><dt><span class="sect2"><a href="appendix_porting.html#build_hacking.enable"><code class="constant">GLIBCXX_ENABLE</code>, the <code class="literal">--enable</code> maker</a></span></dt></dl></dd><dt><span class="sect1"><a href="internals.html">Porting to New Hardware or Operating Systems</a></span></dt><dd><dl><dt><span class="sect2"><a href="internals.html#internals.os">Operating System</a></span></dt><dt><span class="sect2"><a href="internals.html#internals.cpu">CPU</a></span></dt><dt><span class="sect2"><a href="internals.html#internals.char_types">Character Types</a></span></dt><dt><span class="sect2"><a href="internals.html#internals.thread_safety">Thread Safety</a></span></dt><dt><span class="sect2"><a href="internals.html#internals.numeric_limits">Numeric Limits</a></span></dt><dt><span class="sect2"><a href="internals.html#internals.libtool">Libtool</a></span></dt></dl></dd><dt><span class="sect1"><a href="abi.html">ABI Policy and Guidelines</a></span></dt><dd><dl><dt><span class="sect2"><a href="abi.html#abi.cxx_interface">The C++ Interface</a></span></dt><dt><span class="sect2"><a href="abi.html#abi.versioning">Versioning</a></span></dt><dt><span class="sect2"><a href="abi.html#abi.changes_allowed">Allowed Changes</a></span></dt><dt><span class="sect2"><a href="abi.html#abi.changes_no">Prohibited Changes</a></span></dt><dt><span class="sect2"><a href="abi.html#abi.impl">Implementation</a></span></dt><dt><span class="sect2"><a href="abi.html#abi.testing">Testing</a></span></dt><dt><span class="sect2"><a href="abi.html#abi.issues">Outstanding Issues</a></span></dt></dl></dd><dt><span class="sect1"><a href="api.html">API Evolution and Deprecation History</a></span></dt><dd><dl><dt><span class="sect2"><a href="api.html#api.rel_300"><code class="constant">3.0</code></a></span></dt><dt><span class="sect2"><a href="api.html#api.rel_310"><code class="constant">3.1</code></a></span></dt><dt><span class="sect2"><a href="api.html#api.rel_320"><code class="constant">3.2</code></a></span></dt><dt><span class="sect2"><a href="api.html#api.rel_330"><code class="constant">3.3</code></a></span></dt><dt><span class="sect2"><a href="api.html#api.rel_340"><code class="constant">3.4</code></a></span></dt><dt><span class="sect2"><a href="api.html#api.rel_400"><code class="constant">4.0</code></a></span></dt><dt><span class="sect2"><a href="api.html#api.rel_410"><code class="constant">4.1</code></a></span></dt><dt><span class="sect2"><a href="api.html#api.rel_420"><code class="constant">4.2</code></a></span></dt><dt><span class="sect2"><a href="api.html#api.rel_430"><code class="constant">4.3</code></a></span></dt></dl></dd><dt><span class="sect1"><a href="backwards.html">Backwards Compatibility</a></span></dt><dd><dl><dt><span class="sect2"><a href="backwards.html#backwards.first">First</a></span></dt><dt><span class="sect2"><a href="backwards.html#backwards.second">Second</a></span></dt><dt><span class="sect2"><a href="backwards.html#backwards.third">Third</a></span></dt></dl></dd></dl></dd><dt><span class="appendix"><a href="appendix_free.html">C. Free Software Needs Free Documentation</a></span></dt><dt><span class="appendix"><a href="bk01apd.html">D. GNU General Public License</a></span></dt><dd><dl><dt><span class="section"><a href="bk01apd.html#gpl-1">Preamble</a></span></dt><dt><span class="section"><a href="bk01apds02.html">TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION</a></span></dt><dd><dl><dt><span class="section"><a href="bk01apds02.html#gpl-2-0">Section 0</a></span></dt><dt><span class="section"><a href="bk01apds02.html#gpl-2-1">Section 1</a></span></dt><dt><span class="section"><a href="bk01apds02.html#gpl-2-2">Section 2</a></span></dt><dt><span class="section"><a href="bk01apds02.html#gpl-2-3">Section 3</a></span></dt><dt><span class="section"><a href="bk01apds02.html#gpl-2-4">Section 4</a></span></dt><dt><span class="section"><a href="bk01apds02.html#gpl-2-5">Section 5</a></span></dt><dt><span class="section"><a href="bk01apds02.html#gpl-2-6">Section 6</a></span></dt><dt><span class="section"><a href="bk01apds02.html#gpl-2-7">Section 7</a></span></dt><dt><span class="section"><a href="bk01apds02.html#gpl-2-8">Section 8</a></span></dt><dt><span class="section"><a href="bk01apds02.html#gpl-2-9">Section 9</a></span></dt><dt><span class="section"><a href="bk01apds02.html#gpl-2-10">Section 10</a></span></dt><dt><span class="section"><a href="bk01apds02.html#gpl-2-11">NO WARRANTY Section 11</a></span></dt><dt><span class="section"><a href="bk01apds02.html#gpl-2-12">Section 12</a></span></dt></dl></dd><dt><span class="section"><a href="bk01apds03.html">How to Apply These Terms to Your New Programs</a></span></dt></dl></dd><dt><span class="appendix"><a href="bk01ape.html">E. GNU Free Documentation License</a></span></dt></dl></div><div class="list-of-tables"><p><b>List of Tables</b></p><dl><dt>1.1. <a href="bk01pt01ch01.html#id337485">C++ TR1 Implementation Status</a></dt><dt>1.2. <a href="bk01pt01ch01.html#id382201">C++ 200x Implementation Status</a></dt><dt>3.1. <a href="bk01pt01ch03s02.html#id394301">C++ 1998 Library Headers</a></dt><dt>3.2. <a href="bk01pt01ch03s02.html#id440630">C++ 1998 Library Headers for C Library Facilities</a></dt><dt>3.3. <a href="bk01pt01ch03s02.html#id382991">C++ 200x Library Headers</a></dt><dt>3.4. <a href="bk01pt01ch03s02.html#id425965">C++ 200x Library Headers for C Library Facilities</a></dt><dt>3.5. <a href="bk01pt01ch03s02.html#id442369">C++ TR1 Library Headers</a></dt><dt>3.6. <a href="bk01pt01ch03s02.html#id401478">C++ TR1 Library Headers for C Library Facilities</a></dt><dt>3.7. <a href="bk01pt01ch03s02.html#id435323">C++ ABI Headers</a></dt><dt>3.8. <a href="bk01pt01ch03s02.html#id432329">Extension Headers</a></dt><dt>3.9. <a href="bk01pt01ch03s02.html#id440887">Extension Debug Headers</a></dt><dt>3.10. <a href="bk01pt01ch03s02.html#id457206">Extension Parallel Headers</a></dt><dt>30.1. <a href="bk01pt12ch30s03.html#id449953">Debugging Containers</a></dt><dt>30.2. <a href="bk01pt12ch30s03.html#id319073">Debugging Containers C++0x</a></dt><dt>31.1. <a href="bk01pt12ch31s03.html#id392310">Parallel Algorithms</a></dt><dt>32.1. <a href="bitmap_allocator.html#id390307">Bitmap Allocator Memory Map</a></dt><dt>B.1. <a href="api.html#id418406">Extension Allocators</a></dt><dt>B.2. <a href="api.html#id476738">Extension Allocators Continued</a></dt></dl></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="../spine.html">Prev</a> </td><td width="20%" align="center"> </td><td width="40%" align="right"> <a accesskey="n" href="intro.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">The GNU C++ Library Documentation </td><td width="20%" align="center"><a accesskey="h" href="../spine.html">Home</a></td><td width="40%" align="right" valign="top"> Part I. Introduction</td></tr></table></div></body></html>
diff --git a/libstdc++-v3/doc/xml/manual/allocator.xml b/libstdc++-v3/doc/xml/manual/allocator.xml
index cc325be0dc1..5aa4f3530f4 100644
--- a/libstdc++-v3/doc/xml/manual/allocator.xml
+++ b/libstdc++-v3/doc/xml/manual/allocator.xml
@@ -472,8 +472,8 @@
<para>
A high-performance fixed-size allocator with
exponentially-increasing allocations. It has its own
- documentation, found <ulink
- url="../ext/mt_allocator.html">here</ulink>.
+ documentation, found <link
+ linkend="manual.ext.allocator.mt">here</link>.
</para>
</listitem>
@@ -484,8 +484,8 @@
<para>
A high-performance allocator that uses a bit-map to keep track
of the used and unused memory locations. It has its own
- documentation, found <ulink
- url="../ext/ballocator_doc.html">here</ulink>.
+ documentation, found <link
+ linkend="manual.ext.allocator.bitmap">here</link>.
</para>
</listitem>
</orderedlist>
diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am
index a8f48c7d282..1249930c80d 100644
--- a/libstdc++-v3/include/Makefile.am
+++ b/libstdc++-v3/include/Makefile.am
@@ -32,9 +32,9 @@ std_headers = \
${std_srcdir}/array \
${std_srcdir}/bitset \
${std_srcdir}/c++0x_warning.h \
+ ${std_srcdir}/chrono \
${std_srcdir}/complex \
${std_srcdir}/condition_variable \
- ${std_srcdir}/date_time \
${std_srcdir}/deque \
${std_srcdir}/fstream \
${std_srcdir}/functional \
@@ -54,6 +54,7 @@ std_headers = \
${std_srcdir}/ostream \
${std_srcdir}/queue \
${std_srcdir}/random \
+ ${std_srcdir}/ratio \
${std_srcdir}/regex \
${std_srcdir}/set \
${std_srcdir}/sstream \
diff --git a/libstdc++-v3/include/Makefile.in b/libstdc++-v3/include/Makefile.in
index 8c1e626934f..cb529671e3a 100644
--- a/libstdc++-v3/include/Makefile.in
+++ b/libstdc++-v3/include/Makefile.in
@@ -285,9 +285,9 @@ std_headers = \
${std_srcdir}/array \
${std_srcdir}/bitset \
${std_srcdir}/c++0x_warning.h \
+ ${std_srcdir}/chrono \
${std_srcdir}/complex \
${std_srcdir}/condition_variable \
- ${std_srcdir}/date_time \
${std_srcdir}/deque \
${std_srcdir}/fstream \
${std_srcdir}/functional \
@@ -307,6 +307,7 @@ std_headers = \
${std_srcdir}/ostream \
${std_srcdir}/queue \
${std_srcdir}/random \
+ ${std_srcdir}/ratio \
${std_srcdir}/regex \
${std_srcdir}/set \
${std_srcdir}/sstream \
diff --git a/libstdc++-v3/include/bits/basic_string.h b/libstdc++-v3/include/bits/basic_string.h
index 19c79d11cf7..de4cf80234d 100644
--- a/libstdc++-v3/include/bits/basic_string.h
+++ b/libstdc++-v3/include/bits/basic_string.h
@@ -45,6 +45,7 @@
#include <ext/atomicity.h>
#include <debug/debug.h>
+#include <initializer_list>
_GLIBCXX_BEGIN_NAMESPACE(std)
@@ -477,6 +478,15 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
*/
basic_string(size_type __n, _CharT __c, const _Alloc& __a = _Alloc());
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ /**
+ * @brief Construct string from an initializer list.
+ * @param l std::initializer_list of characters.
+ * @param a Allocator to use (default is default allocator).
+ */
+ basic_string(initializer_list<_CharT> __l, const _Alloc& __a = _Alloc());
+#endif // __GXX_EXPERIMENTAL_CXX0X__
+
/**
* @brief Construct string as copy of a range.
* @param beg Start of range.
@@ -523,6 +533,19 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
return *this;
}
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ /**
+ * @brief Set value to string constructed from initializer list.
+ * @param l std::initializer_list.
+ */
+ basic_string&
+ operator=(initializer_list<_CharT> __l)
+ {
+ this->assign (__l.begin(), __l.end());
+ return *this;
+ }
+#endif // __GXX_EXPERIMENTAL_CXX0X__
+
// Iterators:
/**
* Returns a read/write iterator that points to the first character in
@@ -794,6 +817,17 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
return *this;
}
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ /**
+ * @brief Append an initializer_list of characters.
+ * @param l The initializer_list of characters to be appended.
+ * @return Reference to this string.
+ */
+ basic_string&
+ operator+=(initializer_list<_CharT> __l)
+ { return this->append(__l.begin(), __l.end()); }
+#endif // __GXX_EXPERIMENTAL_CXX0X__
+
/**
* @brief Append a string to this string.
* @param str The string to append.
@@ -849,6 +883,17 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
basic_string&
append(size_type __n, _CharT __c);
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ /**
+ * @brief Append an initializer_list of characters.
+ * @param l The initializer_list of characters to append.
+ * @return Reference to this string.
+ */
+ basic_string&
+ append(initializer_list<_CharT> __l)
+ { return this->append(__l.begin(), __l.end()); }
+#endif // __GXX_EXPERIMENTAL_CXX0X__
+
/**
* @brief Append a range of characters.
* @param first Iterator referencing the first character to append.
@@ -957,6 +1002,17 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
assign(_InputIterator __first, _InputIterator __last)
{ return this->replace(_M_ibegin(), _M_iend(), __first, __last); }
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ /**
+ * @brief Set value to an initializer_list of characters.
+ * @param l The initializer_list of characters to assign.
+ * @return Reference to this string.
+ */
+ basic_string&
+ assign(initializer_list<_CharT> __l)
+ { return this->assign(__l.begin(), __l.end()); }
+#endif // __GXX_EXPERIMENTAL_CXX0X__
+
/**
* @brief Insert multiple characters.
* @param p Iterator referencing location in string to insert at.
@@ -989,6 +1045,18 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
insert(iterator __p, _InputIterator __beg, _InputIterator __end)
{ this->replace(__p, __p, __beg, __end); }
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ /**
+ * @brief Insert an initializer_list of characters.
+ * @param p Iterator referencing location in string to insert at.
+ * @param l The initializer_list of characters to insert.
+ * @throw std::length_error If new length exceeds @c max_size().
+ */
+ void
+ insert(iterator __p, initializer_list<_CharT> __l)
+ { this->insert(__p, __l.begin(), __l.end()); }
+#endif // __GXX_EXPERIMENTAL_CXX0X__
+
/**
* @brief Insert value of a string.
* @param pos1 Iterator referencing location in string to insert at.
@@ -1434,6 +1502,25 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
__k1.base(), __k2 - __k1);
}
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ /**
+ * @brief Replace range of characters with initializer_list.
+ * @param i1 Iterator referencing start of range to replace.
+ * @param i2 Iterator referencing end of range to replace.
+ * @param l The initializer_list of characters to insert.
+ * @return Reference to this string.
+ * @throw std::length_error If new length exceeds @c max_size().
+ *
+ * Removes the characters in the range [i1,i2). In place, characters
+ * in the range [k1,k2) are inserted. If the length of result exceeds
+ * max_size(), length_error is thrown. The value of the string doesn't
+ * change if an error is thrown.
+ */
+ basic_string& replace(iterator __i1, iterator __i2,
+ initializer_list<_CharT> __l)
+ { return this->replace(__i1, __i2, __l.begin(), __l.end()); }
+#endif // __GXX_EXPERIMENTAL_CXX0X__
+
private:
template<class _Integer>
basic_string&
diff --git a/libstdc++-v3/include/bits/basic_string.tcc b/libstdc++-v3/include/bits/basic_string.tcc
index 062b02b5982..3201e361830 100644
--- a/libstdc++-v3/include/bits/basic_string.tcc
+++ b/libstdc++-v3/include/bits/basic_string.tcc
@@ -235,6 +235,14 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
: _M_dataplus(_S_construct(__beg, __end, __a), __a)
{ }
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ template<typename _CharT, typename _Traits, typename _Alloc>
+ basic_string<_CharT, _Traits, _Alloc>::
+ basic_string(initializer_list<_CharT> __l, const _Alloc& __a)
+ : _M_dataplus(_S_construct(__l.begin(), __l.end(), __a), __a)
+ { }
+#endif
+
template<typename _CharT, typename _Traits, typename _Alloc>
basic_string<_CharT, _Traits, _Alloc>&
basic_string<_CharT, _Traits, _Alloc>::
@@ -1104,7 +1112,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
// Inhibit implicit instantiations for required instantiations,
// which are defined via explicit instantiations elsewhere.
// NB: This syntax is a GNU extension.
-#if _GLIBCXX_EXTERN_TEMPLATE
+#if _GLIBCXX_EXTERN_TEMPLATE > 0
extern template class basic_string<char>;
extern template
basic_istream<char>&
diff --git a/libstdc++-v3/include/bits/c++config b/libstdc++-v3/include/bits/c++config
index f4029b26665..e40d9603a9b 100644
--- a/libstdc++-v3/include/bits/c++config
+++ b/libstdc++-v3/include/bits/c++config
@@ -135,7 +135,7 @@
# define _GLIBCXX_STD __cxx1998
# define _GLIBCXX_BEGIN_NAMESPACE(X) namespace X _GLIBCXX_VISIBILITY_ATTR(default) {
# define _GLIBCXX_END_NAMESPACE }
-# define _GLIBCXX_EXTERN_TEMPLATE 0
+# define _GLIBCXX_EXTERN_TEMPLATE -1
# endif
// parallel
@@ -145,7 +145,7 @@
# define _GLIBCXX_STD __cxx1998
# define _GLIBCXX_BEGIN_NAMESPACE(X) namespace X _GLIBCXX_VISIBILITY_ATTR(default) {
# define _GLIBCXX_END_NAMESPACE }
-# define _GLIBCXX_EXTERN_TEMPLATE 0
+# define _GLIBCXX_EXTERN_TEMPLATE -1
# endif
// debug + parallel
@@ -155,7 +155,7 @@
# define _GLIBCXX_STD __cxx1998
# define _GLIBCXX_BEGIN_NAMESPACE(X) namespace X _GLIBCXX_VISIBILITY_ATTR(default) {
# define _GLIBCXX_END_NAMESPACE }
-# define _GLIBCXX_EXTERN_TEMPLATE 0
+# define _GLIBCXX_EXTERN_TEMPLATE -1
# endif
# if __NO_INLINE__ && !__GXX_WEAK__
diff --git a/libstdc++-v3/include/bits/postypes.h b/libstdc++-v3/include/bits/postypes.h
index 2870a8e59a1..5ead488fa48 100644
--- a/libstdc++-v3/include/bits/postypes.h
+++ b/libstdc++-v3/include/bits/postypes.h
@@ -46,10 +46,6 @@
#include <cwchar> // For mbstate_t
-#ifdef _GLIBCXX_HAVE_STDINT_H
-#include <stdint.h> // For int64_t
-#endif
-
_GLIBCXX_BEGIN_NAMESPACE(std)
// The types streamoff, streampos and wstreampos and the class
@@ -68,7 +64,11 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
* was typedef long.
*/
#ifdef _GLIBCXX_HAVE_INT64_T
- typedef int64_t streamoff;
+# if (__CHAR_BIT__ * __SIZEOF_LONG__ == 64)
+ typedef long streamoff;
+# else
+ typedef long long streamoff;
+# endif
#else
typedef long long streamoff;
#endif
diff --git a/libstdc++-v3/include/bits/stl_bvector.h b/libstdc++-v3/include/bits/stl_bvector.h
index 045f20378a6..ad0ed87a115 100644
--- a/libstdc++-v3/include/bits/stl_bvector.h
+++ b/libstdc++-v3/include/bits/stl_bvector.h
@@ -62,6 +62,8 @@
#ifndef _STL_BVECTOR_H
#define _STL_BVECTOR_H 1
+#include <initializer_list>
+
_GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
typedef unsigned long _Bit_type;
@@ -529,6 +531,14 @@ template<typename _Alloc>
#ifdef __GXX_EXPERIMENTAL_CXX0X__
vector(vector&& __x)
: _Base(std::forward<_Base>(__x)) { }
+
+ vector(initializer_list<bool> __l,
+ const allocator_type& __a = allocator_type())
+ : _Base(__a)
+ {
+ _M_initialize_range(__l.begin(), __l.end(),
+ random_access_iterator_tag());
+ }
#endif
template<typename _InputIterator>
@@ -566,6 +576,13 @@ template<typename _Alloc>
this->swap(__x);
return *this;
}
+
+ vector&
+ operator=(initializer_list<bool> __l)
+ {
+ this->assign (__l.begin(), __l.end());
+ return *this;
+ }
#endif
// assign(), a generalized assignment member function. Two
@@ -584,6 +601,12 @@ template<typename _Alloc>
_M_assign_dispatch(__first, __last, _Integral());
}
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ void
+ assign(initializer_list<bool> __l)
+ { this->assign(__l.begin(), __l.end()); }
+#endif
+
iterator
begin()
{ return this->_M_impl._M_start; }
@@ -777,6 +800,11 @@ template<typename _Alloc>
insert(iterator __position, size_type __n, const bool& __x)
{ _M_fill_insert(__position, __n, __x); }
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ void insert(iterator __p, initializer_list<bool> __l)
+ { this->insert(__p, __l.begin(), __l.end()); }
+#endif
+
void
pop_back()
{ --this->_M_impl._M_finish; }
diff --git a/libstdc++-v3/include/bits/stl_deque.h b/libstdc++-v3/include/bits/stl_deque.h
index b778f15a075..070fc078909 100644
--- a/libstdc++-v3/include/bits/stl_deque.h
+++ b/libstdc++-v3/include/bits/stl_deque.h
@@ -65,6 +65,7 @@
#include <bits/concept_check.h>
#include <bits/stl_iterator_base_types.h>
#include <bits/stl_iterator_base_funcs.h>
+#include <initializer_list>
_GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
@@ -740,6 +741,25 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
*/
deque(deque&& __x)
: _Base(std::forward<_Base>(__x)) { }
+
+ /**
+ * @brief Builds a %deque from an initializer list.
+ * @param l An initializer_list.
+ * @param a An allocator object.
+ *
+ * Create a %deque consisting of copies of the elements in the
+ * initializer_list @a l.
+ *
+ * This will call the element type's copy constructor N times
+ * (where N is l.size()) and do no memory reallocation.
+ */
+ deque(initializer_list<value_type> __l,
+ const allocator_type& __a = allocator_type())
+ : _Base(__a)
+ {
+ _M_range_initialize(__l.begin(), __l.end(),
+ random_access_iterator_tag());
+ }
#endif
/**
@@ -801,6 +821,24 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
this->swap(__x);
return *this;
}
+
+ /**
+ * @brief Assigns an initializer list to a %deque.
+ * @param l An initializer_list.
+ *
+ * This function fills a %deque with copies of the elements in the
+ * initializer_list @a l.
+ *
+ * Note that the assignment completely changes the %deque and that the
+ * resulting %deque's size is the same as the number of elements
+ * assigned. Old data may be lost.
+ */
+ deque&
+ operator=(initializer_list<value_type> __l)
+ {
+ this->assign(__l.begin(), __l.end());
+ return *this;
+ }
#endif
/**
@@ -837,6 +875,23 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
_M_assign_dispatch(__first, __last, _Integral());
}
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ /**
+ * @brief Assigns an initializer list to a %deque.
+ * @param l An initializer_list.
+ *
+ * This function fills a %deque with copies of the elements in the
+ * initializer_list @a l.
+ *
+ * Note that the assignment completely changes the %deque and that the
+ * resulting %deque's size is the same as the number of elements
+ * assigned. Old data may be lost.
+ */
+ void
+ assign(initializer_list<value_type> __l)
+ { this->assign(__l.begin(), __l.end()); }
+#endif
+
/// Get a copy of the memory allocation object.
allocator_type
get_allocator() const
@@ -1253,6 +1308,19 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
iterator
insert(iterator __position, value_type&& __x)
{ return emplace(__position, std::move(__x)); }
+
+ /**
+ * @brief Inserts an initializer list into the %deque.
+ * @param p An iterator into the %deque.
+ * @param l An initializer_list.
+ *
+ * This function will insert copies of the data in the
+ * initializer_list @a l into the %deque before the location
+ * specified by @a p. This is known as "list insert."
+ */
+ void
+ insert(iterator __p, initializer_list<value_type> __l)
+ { this->insert(__p, __l.begin(), __l.end()); }
#endif
/**
diff --git a/libstdc++-v3/include/bits/stl_list.h b/libstdc++-v3/include/bits/stl_list.h
index 08fb89ef117..b38fa55cf79 100644
--- a/libstdc++-v3/include/bits/stl_list.h
+++ b/libstdc++-v3/include/bits/stl_list.h
@@ -63,6 +63,7 @@
#define _STL_LIST_H 1
#include <bits/concept_check.h>
+#include <initializer_list>
_GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
@@ -541,6 +542,19 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
*/
list(list&& __x)
: _Base(std::forward<_Base>(__x)) { }
+
+ /**
+ * @brief Builds a %list from an initializer_list
+ * @param l An initializer_list of value_type.
+ * @param a An allocator object.
+ *
+ * Create a %list consisting of copies of the elements in the
+ * initializer_list @a l. This is linear in l.size().
+ */
+ list(initializer_list<value_type> __l,
+ const allocator_type& __a = allocator_type())
+ : _Base(__a)
+ { _M_initialize_dispatch(__l.begin(), __l.end(), __false_type()); }
#endif
/**
@@ -597,6 +611,20 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
this->swap(__x);
return *this;
}
+
+ /**
+ * @brief %List initializer list assignment operator.
+ * @param l An initializer_list of value_type.
+ *
+ * Replace the contents of the %list with copies of the elements
+ * in the initializer_list @a l. This is linear in l.size().
+ */
+ list&
+ operator=(initializer_list<value_type> __l)
+ {
+ this->assign(__l.begin(), __l.end());
+ return *this;
+ }
#endif
/**
@@ -634,6 +662,19 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
_M_assign_dispatch(__first, __last, _Integral());
}
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ /**
+ * @brief Assigns an initializer_list to a %list.
+ * @param l An initializer_list of value_type.
+ *
+ * Replace the contents of the %list with copies of the elements
+ * in the initializer_list @a l. This is linear in l.size().
+ */
+ void
+ assign(initializer_list<value_type> __l)
+ { this->assign(__l.begin(), __l.end()); }
+#endif
+
/// Get a copy of the memory allocation object.
allocator_type
get_allocator() const
@@ -951,6 +992,23 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
iterator
insert(iterator __position, value_type&& __x)
{ return emplace(__position, std::move(__x)); }
+
+ /**
+ * @brief Inserts the contents of an initializer_list into %list
+ * before specified iterator.
+ * @param p An iterator into the %list.
+ * @param l An initializer_list of value_type.
+ *
+ * This function will insert copies of the data in the
+ * initializer_list @a l into the %list before the location
+ * specified by @a p.
+ *
+ * This operation is linear in the number of elements inserted and
+ * does not invalidate iterators and references.
+ */
+ void
+ insert(iterator __p, initializer_list<value_type> __l)
+ { this->insert(__p, __l.begin(), __l.end()); }
#endif
/**
diff --git a/libstdc++-v3/include/bits/stl_map.h b/libstdc++-v3/include/bits/stl_map.h
index cd85b9ab75d..b402b8292c5 100644
--- a/libstdc++-v3/include/bits/stl_map.h
+++ b/libstdc++-v3/include/bits/stl_map.h
@@ -186,6 +186,23 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
*/
map(map&& __x)
: _M_t(std::forward<_Rep_type>(__x._M_t)) { }
+
+ /**
+ * @brief Builds a %map from an initializer_list.
+ * @param l An initializer_list.
+ * @param comp A comparison object.
+ * @param a An allocator object.
+ *
+ * Create a %map consisting of copies of the elements in the
+ * initializer_list @a l.
+ * This is linear in N if the range is already sorted, and NlogN
+ * otherwise (where N is @a l.size()).
+ */
+ map(initializer_list<value_type> __l,
+ const _Compare& __c = _Compare(),
+ const allocator_type& __a = allocator_type())
+ : _M_t(__c, __a)
+ { _M_t._M_insert_unique(__l.begin(), __l.end()); }
#endif
/**
@@ -259,6 +276,25 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
this->swap(__x);
return *this;
}
+
+ /**
+ * @brief %Map list assignment operator.
+ * @param l An initializer_list.
+ *
+ * This function fills a %map with copies of the elements in the
+ * initializer list @a l.
+ *
+ * Note that the assignment completely changes the %map and
+ * that the resulting %map's size is the same as the number
+ * of elements assigned. Old data may be lost.
+ */
+ map&
+ operator=(initializer_list<value_type> __l)
+ {
+ this->clear();
+ this->insert(__l.begin(), __l.end());
+ return *this;
+ }
#endif
/// Get a copy of the memory allocation object.
@@ -476,7 +512,6 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
* inserted.
*
* Complexity similar to that of the range constructor.
- *
*/
void
insert(std::initializer_list<value_type> __list)
diff --git a/libstdc++-v3/include/bits/stl_multimap.h b/libstdc++-v3/include/bits/stl_multimap.h
index ade2750170f..0834c95cfd6 100644
--- a/libstdc++-v3/include/bits/stl_multimap.h
+++ b/libstdc++-v3/include/bits/stl_multimap.h
@@ -63,6 +63,7 @@
#define _STL_MULTIMAP_H 1
#include <bits/concept_check.h>
+#include <initializer_list>
_GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
@@ -183,6 +184,22 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
*/
multimap(multimap&& __x)
: _M_t(std::forward<_Rep_type>(__x._M_t)) { }
+
+ /**
+ * @brief Builds a %multimap from an initializer_list.
+ * @param l An initializer_list.
+ * @param comp A comparison functor.
+ * @param a An allocator object.
+ *
+ * Create a %multimap consisting of copies of the elements from
+ * the initializer_list. This is linear in N if the list is already
+ * sorted, and NlogN otherwise (where N is @a __l.size()).
+ */
+ multimap(initializer_list<value_type> __l,
+ const _Compare& __comp = _Compare(),
+ const allocator_type& __a = allocator_type())
+ : _M_t(__comp, __a)
+ { _M_t._M_insert_equal(__l.begin(), __l.end()); }
#endif
/**
@@ -256,6 +273,25 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
this->swap(__x);
return *this;
}
+
+ /**
+ * @brief %Multimap list assignment operator.
+ * @param l An initializer_list.
+ *
+ * This function fills a %multimap with copies of the elements
+ * in the initializer list @a l.
+ *
+ * Note that the assignment completely changes the %multimap and
+ * that the resulting %multimap's size is the same as the number
+ * of elements assigned. Old data may be lost.
+ */
+ multimap&
+ operator=(initializer_list<value_type> __l)
+ {
+ this->clear();
+ this->insert(__l.begin(), __l.end());
+ return *this;
+ }
#endif
/// Get a copy of the memory allocation object.
@@ -444,6 +480,19 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
insert(_InputIterator __first, _InputIterator __last)
{ _M_t._M_insert_equal(__first, __last); }
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ /**
+ * @brief Attempts to insert a list of std::pairs into the %multimap.
+ * @param list A std::initializer_list<value_type> of pairs to be
+ * inserted.
+ *
+ * Complexity similar to that of the range constructor.
+ */
+ void
+ insert(initializer_list<value_type> __l)
+ { this->insert(__l.begin(), __l.end()); }
+#endif
+
/**
* @brief Erases an element from a %multimap.
* @param position An iterator pointing to the element to be erased.
diff --git a/libstdc++-v3/include/bits/stl_multiset.h b/libstdc++-v3/include/bits/stl_multiset.h
index 2cdbdfe4cf3..2fea83f847c 100644
--- a/libstdc++-v3/include/bits/stl_multiset.h
+++ b/libstdc++-v3/include/bits/stl_multiset.h
@@ -63,6 +63,7 @@
#define _STL_MULTISET_H 1
#include <bits/concept_check.h>
+#include <initializer_list>
_GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
@@ -196,6 +197,22 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
*/
multiset(multiset&& __x)
: _M_t(std::forward<_Rep_type>(__x._M_t)) { }
+
+ /**
+ * @brief Builds a %multiset from an initializer_list.
+ * @param l An initializer_list.
+ * @param comp A comparison functor.
+ * @param a An allocator object.
+ *
+ * Create a %multiset consisting of copies of the elements from
+ * the list. This is linear in N if the list is already sorted,
+ * and NlogN otherwise (where N is @a l.size()).
+ */
+ multiset(initializer_list<value_type> __l,
+ const _Compare& __comp = _Compare(),
+ const allocator_type& __a = allocator_type())
+ : _M_t(__comp, __a)
+ { _M_t._M_insert_equal(__l.begin(), __l.end()); }
#endif
/**
@@ -228,6 +245,25 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
this->swap(__x);
return *this;
}
+
+ /**
+ * @brief %Multiset list assignment operator.
+ * @param l An initializer_list.
+ *
+ * This function fills a %multiset with copies of the elements in the
+ * initializer list @a l.
+ *
+ * Note that the assignment completely changes the %multiset and
+ * that the resulting %multiset's size is the same as the number
+ * of elements assigned. Old data may be lost.
+ */
+ multiset&
+ operator=(initializer_list<value_type> __l)
+ {
+ this->clear();
+ this->insert(__l.begin(), __l.end());
+ return *this;
+ }
#endif
// accessors:
@@ -406,6 +442,19 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
insert(_InputIterator __first, _InputIterator __last)
{ _M_t._M_insert_equal(__first, __last); }
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ /**
+ * @brief Attempts to insert a list of elements into the %multiset.
+ * @param list A std::initializer_list<value_type> of elements
+ * to be inserted.
+ *
+ * Complexity similar to that of the range constructor.
+ */
+ void
+ insert(initializer_list<value_type> __l)
+ { this->insert(__l.begin(), __l.end()); }
+#endif
+
/**
* @brief Erases an element from a %multiset.
* @param position An iterator pointing to the element to be erased.
diff --git a/libstdc++-v3/include/bits/stl_set.h b/libstdc++-v3/include/bits/stl_set.h
index 2ef51de858f..98c74e9a27c 100644
--- a/libstdc++-v3/include/bits/stl_set.h
+++ b/libstdc++-v3/include/bits/stl_set.h
@@ -63,6 +63,7 @@
#define _STL_SET_H 1
#include <bits/concept_check.h>
+#include <initializer_list>
_GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
@@ -203,6 +204,22 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
*/
set(set&& __x)
: _M_t(std::forward<_Rep_type>(__x._M_t)) { }
+
+ /**
+ * @brief Builds a %set from an initializer_list.
+ * @param l An initializer_list.
+ * @param comp A comparison functor.
+ * @param a An allocator object.
+ *
+ * Create a %set consisting of copies of the elements in the list.
+ * This is linear in N if the list is already sorted, and NlogN
+ * otherwise (where N is @a l.size()).
+ */
+ set(initializer_list<value_type> __l,
+ const _Compare& __comp = _Compare(),
+ const allocator_type& __a = allocator_type())
+ : _M_t(__comp, __a)
+ { _M_t._M_insert_unique(__l.begin(), __l.end()); }
#endif
/**
@@ -235,6 +252,25 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
this->swap(__x);
return *this;
}
+
+ /**
+ * @brief %Set list assignment operator.
+ * @param l An initializer_list.
+ *
+ * This function fills a %set with copies of the elements in the
+ * initializer list @a l.
+ *
+ * Note that the assignment completely changes the %set and
+ * that the resulting %set's size is the same as the number
+ * of elements assigned. Old data may be lost.
+ */
+ set&
+ operator=(initializer_list<value_type> __l)
+ {
+ this->clear();
+ this->insert(__l.begin(), __l.end());
+ return *this;
+ }
#endif
// accessors:
@@ -418,6 +454,19 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
insert(_InputIterator __first, _InputIterator __last)
{ _M_t._M_insert_unique(__first, __last); }
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ /**
+ * @brief Attempts to insert a list of elements into the %set.
+ * @param list A std::initializer_list<value_type> of elements
+ * to be inserted.
+ *
+ * Complexity similar to that of the range constructor.
+ */
+ void
+ insert(initializer_list<value_type> __l)
+ { this->insert(__l.begin(), __l.end()); }
+#endif
+
/**
* @brief Erases an element from a %set.
* @param position An iterator pointing to the element to be erased.
diff --git a/libstdc++-v3/include/bits/stl_vector.h b/libstdc++-v3/include/bits/stl_vector.h
index aa874089d52..9ccd9b8ca23 100644
--- a/libstdc++-v3/include/bits/stl_vector.h
+++ b/libstdc++-v3/include/bits/stl_vector.h
@@ -65,6 +65,7 @@
#include <bits/stl_iterator_base_funcs.h>
#include <bits/functexcept.h>
#include <bits/concept_check.h>
+#include <initializer_list>
_GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
@@ -262,6 +263,25 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
*/
vector(vector&& __x)
: _Base(std::forward<_Base>(__x)) { }
+
+ /**
+ * @brief Builds a %vector from an initializer list.
+ * @param l An initializer_list.
+ * @param a An allocator.
+ *
+ * Create a %vector consisting of copies of the elements in the
+ * initializer_list @a l.
+ *
+ * This will call the element type's copy constructor N times
+ * (where N is @a l.size()) and do no memory reallocation.
+ */
+ vector(initializer_list<value_type> __l,
+ const allocator_type& __a = allocator_type())
+ : _Base(__a)
+ {
+ _M_range_initialize(__l.begin(), __l.end(),
+ random_access_iterator_tag());
+ }
#endif
/**
@@ -327,6 +347,24 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
this->swap(__x);
return *this;
}
+
+ /**
+ * @brief %Vector list assignment operator.
+ * @param l An initializer_list.
+ *
+ * This function fills a %vector with copies of the elements in the
+ * initializer list @a l.
+ *
+ * Note that the assignment completely changes the %vector and
+ * that the resulting %vector's size is the same as the number
+ * of elements assigned. Old data may be lost.
+ */
+ vector&
+ operator=(initializer_list<value_type> __l)
+ {
+ this->assign(__l.begin(), __l.end());
+ return *this;
+ }
#endif
/**
@@ -364,6 +402,23 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
_M_assign_dispatch(__first, __last, _Integral());
}
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ /**
+ * @brief Assigns an initializer list to a %vector.
+ * @param l An initializer_list.
+ *
+ * This function fills a %vector with copies of the elements in the
+ * initializer list @a l.
+ *
+ * Note that the assignment completely changes the %vector and
+ * that the resulting %vector's size is the same as the number
+ * of elements assigned. Old data may be lost.
+ */
+ void
+ assign(initializer_list<value_type> __l)
+ { this->assign(__l.begin(), __l.end()); }
+#endif
+
/// Get a copy of the memory allocation object.
using _Base::get_allocator;
@@ -766,6 +821,23 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
iterator
insert(iterator __position, value_type&& __x)
{ return emplace(__position, std::move(__x)); }
+
+ /**
+ * @brief Inserts an initializer_list into the %vector.
+ * @param position An iterator into the %vector.
+ * @param l An initializer_list.
+ *
+ * This function will insert copies of the data in the
+ * initializer_list @a l into the %vector before the location
+ * specified by @a position.
+ *
+ * Note that this kind of operation could be expensive for a
+ * %vector and if it is frequently used the user should
+ * consider using std::list.
+ */
+ void
+ insert(iterator __position, initializer_list<value_type> __l)
+ { this->insert(__position, __l.begin(), __l.end()); }
#endif
/**
diff --git a/libstdc++-v3/include/bits/unique_ptr.h b/libstdc++-v3/include/bits/unique_ptr.h
index f2c13b5800a..ead0acf9515 100644
--- a/libstdc++-v3/include/bits/unique_ptr.h
+++ b/libstdc++-v3/include/bits/unique_ptr.h
@@ -47,6 +47,7 @@
_GLIBCXX_BEGIN_NAMESPACE(std)
+ /// Primary template, default_delete.
template<typename _Tp>
struct default_delete
{
@@ -66,6 +67,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// DR 740 - omit specialization for array objects with a compile time length
+ /// Specialization, default_delete.
template<typename _Tp>
struct default_delete<_Tp[]>
{
@@ -78,6 +80,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
}
};
+ /// 20.6.11.2 unique_ptr for single objects.
template <typename _Tp, typename _Tp_Deleter = default_delete<_Tp> >
class unique_ptr
{
@@ -224,7 +227,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
__tuple_type _M_t;
};
- // 20.6.11.3 unique_ptr for array objects with a runtime length
+ /// 20.6.11.3 unique_ptr for array objects with a runtime length
// [unique.ptr.runtime]
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// DR 740 - omit specialization for array objects with a compile time length
diff --git a/libstdc++-v3/include/debug/deque b/libstdc++-v3/include/debug/deque
index c37381f084f..845e0dcaaf2 100644
--- a/libstdc++-v3/include/debug/deque
+++ b/libstdc++-v3/include/debug/deque
@@ -94,6 +94,10 @@ namespace __debug
deque(deque&& __x)
: _Base(std::forward<deque>(__x)), _Safe_base()
{ this->_M_swap(__x); }
+
+ deque(initializer_list<value_type> __l,
+ const allocator_type& __a = allocator_type())
+ : _Base(__l, __a), _Safe_base() { }
#endif
~deque() { }
@@ -115,6 +119,14 @@ namespace __debug
swap(__x);
return *this;
}
+
+ deque&
+ operator=(initializer_list<value_type> __l)
+ {
+ *static_cast<_Base*>(this) = __l;
+ this->_M_invalidate_all();
+ return *this;
+ }
#endif
template<class _InputIterator>
@@ -133,6 +145,15 @@ namespace __debug
this->_M_invalidate_all();
}
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ void
+ assign(initializer_list<value_type> __l)
+ {
+ _Base::assign(__l);
+ this->_M_invalidate_all();
+ }
+#endif
+
using _Base::get_allocator;
// iterators:
@@ -318,6 +339,13 @@ namespace __debug
iterator
insert(iterator __position, _Tp&& __x)
{ return emplace(__position, std::move(__x)); }
+
+ void
+ insert(iterator __p, initializer_list<value_type> __l)
+ {
+ _Base::insert(__p, __l);
+ this->_M_invalidate_all();
+ }
#endif
void
diff --git a/libstdc++-v3/include/debug/list b/libstdc++-v3/include/debug/list
index 7ab0bddff99..312aeebef92 100644
--- a/libstdc++-v3/include/debug/list
+++ b/libstdc++-v3/include/debug/list
@@ -123,6 +123,10 @@ namespace __debug
list(list&& __x)
: _Base(std::forward<list>(__x)), _Safe_base()
{ this->_M_swap(__x); }
+
+ list(initializer_list<value_type> __l,
+ const allocator_type& __a = allocator_type())
+ : _Base(__l, __a), _Safe_base() { }
#endif
~list() { }
@@ -144,6 +148,21 @@ namespace __debug
swap(__x);
return *this;
}
+
+ list&
+ operator=(initializer_list<value_type> __l)
+ {
+ static_cast<_Base&>(*this) = __l;
+ this->_M_invalidate_all();
+ return *this;
+ }
+
+ void
+ assign(initializer_list<value_type> __l)
+ {
+ _Base::assign(__l);
+ this->_M_invalidate_all();
+ }
#endif
template<class _InputIterator>
@@ -331,6 +350,13 @@ namespace __debug
iterator
insert(iterator __position, _Tp&& __x)
{ return emplace(__position, std::move(__x)); }
+
+ void
+ insert(iterator __p, initializer_list<value_type> __l)
+ {
+ __glibcxx_check_insert(__p);
+ _Base::insert(__p, __l);
+ }
#endif
void
diff --git a/libstdc++-v3/include/debug/map.h b/libstdc++-v3/include/debug/map.h
index 16575644da2..8232c742a63 100644
--- a/libstdc++-v3/include/debug/map.h
+++ b/libstdc++-v3/include/debug/map.h
@@ -98,6 +98,11 @@ namespace __debug
map(map&& __x)
: _Base(std::forward<map>(__x)), _Safe_base()
{ this->_M_swap(__x); }
+
+ map(initializer_list<value_type> __l,
+ const _Compare& __c = _Compare(),
+ const allocator_type& __a = allocator_type())
+ : _Base(__l, __c, __a), _Safe_base() { }
#endif
~map() { }
@@ -119,6 +124,14 @@ namespace __debug
swap(__x);
return *this;
}
+
+ map&
+ operator=(initializer_list<value_type> __l)
+ {
+ this->clear();
+ this->insert(__l);
+ return *this;
+ }
#endif
// _GLIBCXX_RESOLVE_LIB_DEFECTS
@@ -198,6 +211,12 @@ namespace __debug
__res.second);
}
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ void
+ insert(std::initializer_list<value_type> __list)
+ { _Base::insert(__list); }
+#endif
+
iterator
insert(iterator __position, const value_type& __x)
{
diff --git a/libstdc++-v3/include/debug/multimap.h b/libstdc++-v3/include/debug/multimap.h
index 72f4411685b..b7c5ee7181c 100644
--- a/libstdc++-v3/include/debug/multimap.h
+++ b/libstdc++-v3/include/debug/multimap.h
@@ -99,6 +99,11 @@ namespace __debug
multimap(multimap&& __x)
: _Base(std::forward<multimap>(__x)), _Safe_base()
{ this->_M_swap(__x); }
+
+ multimap(initializer_list<value_type> __l,
+ const _Compare& __c = _Compare(),
+ const allocator_type& __a = allocator_type())
+ : _Base(__l, __c, __a), _Safe_base() { }
#endif
~multimap() { }
@@ -120,6 +125,14 @@ namespace __debug
swap(__x);
return *this;
}
+
+ multimap&
+ operator=(initializer_list<value_type> __l)
+ {
+ this->clear();
+ this->insert(__l);
+ return *this;
+ }
#endif
using _Base::get_allocator;
@@ -185,6 +198,12 @@ namespace __debug
insert(const value_type& __x)
{ return iterator(_Base::insert(__x), this); }
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ void
+ insert(std::initializer_list<value_type> __list)
+ { _Base::insert(__list); }
+#endif
+
iterator
insert(iterator __position, const value_type& __x)
{
diff --git a/libstdc++-v3/include/debug/multiset.h b/libstdc++-v3/include/debug/multiset.h
index ffe5b51548f..f108531638e 100644
--- a/libstdc++-v3/include/debug/multiset.h
+++ b/libstdc++-v3/include/debug/multiset.h
@@ -96,6 +96,11 @@ namespace __debug
multiset(multiset&& __x)
: _Base(std::forward<multiset>(__x)), _Safe_base()
{ this->_M_swap(__x); }
+
+ multiset(initializer_list<value_type> __l,
+ const _Compare& __comp = _Compare(),
+ const allocator_type& __a = allocator_type())
+ : _Base(__l, __comp, __a), _Safe_base() { }
#endif
~multiset() { }
@@ -117,6 +122,14 @@ namespace __debug
swap(__x);
return *this;
}
+
+ multiset&
+ operator=(initializer_list<value_type> __l)
+ {
+ this->clear();
+ this->insert(__l);
+ return *this;
+ }
#endif
using _Base::get_allocator;
@@ -197,6 +210,12 @@ namespace __debug
_Base::insert(__first, __last);
}
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ void
+ insert(initializer_list<value_type> __l)
+ { _Base::insert(__l); }
+#endif
+
void
erase(iterator __position)
{
diff --git a/libstdc++-v3/include/debug/safe_association.h b/libstdc++-v3/include/debug/safe_association.h
index 42c050050b8..a413b01f872 100644
--- a/libstdc++-v3/include/debug/safe_association.h
+++ b/libstdc++-v3/include/debug/safe_association.h
@@ -105,6 +105,14 @@ namespace __gnu_debug
__l, __n, __hf, __eql, __a)
{ }
+ _Safe_association(std::initializer_list<value_type> __l,
+ size_type __n,
+ const hasher& __hf,
+ const key_equal& __eql,
+ const allocator_type& __a = allocator_type())
+ : _Base(__l, __n, __hf, __eql, __a)
+ { }
+
_Safe_association(const _Base& __x) : _Base(__x) { }
_Safe_association(_Safe_association&& __x)
@@ -152,6 +160,10 @@ namespace __gnu_debug
_Base::insert(__first.base(), __last.base());
}
+ void
+ insert(std::initializer_list<value_type> __l)
+ { _Base::insert(__l); }
+
const_iterator
find(const key_type& __key) const
{ return const_iterator(_Base::find(__key), this); }
diff --git a/libstdc++-v3/include/debug/set.h b/libstdc++-v3/include/debug/set.h
index 3115610d1e1..00711cd321d 100644
--- a/libstdc++-v3/include/debug/set.h
+++ b/libstdc++-v3/include/debug/set.h
@@ -96,6 +96,11 @@ namespace __debug
set(set&& __x)
: _Base(std::forward<set>(__x)), _Safe_base()
{ this->_M_swap(__x); }
+
+ set(initializer_list<value_type> __l,
+ const _Compare& __comp = _Compare(),
+ const allocator_type& __a = allocator_type())
+ : _Base(__l, __comp, __a), _Safe_base() { }
#endif
~set() { }
@@ -117,6 +122,14 @@ namespace __debug
swap(__x);
return *this;
}
+
+ set&
+ operator=(initializer_list<value_type> __l)
+ {
+ this->clear();
+ this->insert(__l);
+ return *this;
+ }
#endif
using _Base::get_allocator;
@@ -202,6 +215,12 @@ namespace __debug
_Base::insert(__first, __last);
}
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ void
+ insert(initializer_list<value_type> __l)
+ { _Base::insert(__l); }
+#endif
+
void
erase(iterator __position)
{
diff --git a/libstdc++-v3/include/debug/string b/libstdc++-v3/include/debug/string
index 070ca1fe58b..68882fed581 100644
--- a/libstdc++-v3/include/debug/string
+++ b/libstdc++-v3/include/debug/string
@@ -115,6 +115,12 @@ namespace __gnu_debug
: _Base(__gnu_debug::__check_valid_range(__begin, __end), __end, __a)
{ }
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ basic_string(initializer_list<_CharT> __l, const _Alloc& __a = _Alloc())
+ : _Base(__l, __a)
+ { }
+#endif // __GXX_EXPERIMENTAL_CXX0X__
+
~basic_string() { }
basic_string&
@@ -142,6 +148,16 @@ namespace __gnu_debug
return *this;
}
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ basic_string&
+ operator=(initializer_list<_CharT> __l)
+ {
+ *static_cast<_Base*>(this) = __l;
+ this->_M_invalidate_all();
+ return *this;
+ }
+#endif // __GXX_EXPERIMENTAL_CXX0X__
+
// 21.3.2 iterators:
iterator
begin()
@@ -259,6 +275,16 @@ namespace __gnu_debug
return *this;
}
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ basic_string&
+ operator+=(initializer_list<_CharT> __l)
+ {
+ _M_base() += __l;
+ this->_M_invalidate_all();
+ return *this;
+ }
+#endif // __GXX_EXPERIMENTAL_CXX0X__
+
basic_string&
append(const basic_string& __str)
{
@@ -372,6 +398,16 @@ namespace __gnu_debug
return *this;
}
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ basic_string&
+ assign(initializer_list<_CharT> __l)
+ {
+ _Base::assign(__l);
+ this->_M_invalidate_all();
+ return *this;
+ }
+#endif // __GXX_EXPERIMENTAL_CXX0X__
+
basic_string&
insert(size_type __pos1, const basic_string& __str)
{
@@ -441,6 +477,15 @@ namespace __gnu_debug
this->_M_invalidate_all();
}
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ void
+ insert(iterator __p, initializer_list<_CharT> __l)
+ {
+ _Base::insert(__p, __l);
+ this->_M_invalidate_all();
+ }
+#endif // __GXX_EXPERIMENTAL_CXX0X__
+
basic_string&
erase(size_type __pos = 0, size_type __n = _Base::npos)
{
@@ -564,6 +609,17 @@ namespace __gnu_debug
return *this;
}
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ basic_string& replace(iterator __i1, iterator __i2,
+ initializer_list<_CharT> __l)
+ {
+ __glibcxx_check_erase_range(__i1, __i2);
+ _Base::replace(__i1.base(), __i2.base(), __l);
+ this->_M_invalidate_all();
+ return *this;
+ }
+#endif // __GXX_EXPERIMENTAL_CXX0X__
+
size_type
copy(_CharT* __s, size_type __n, size_type __pos = 0) const
{
diff --git a/libstdc++-v3/include/debug/unordered_map b/libstdc++-v3/include/debug/unordered_map
index 590d4a3478f..79590f56755 100644
--- a/libstdc++-v3/include/debug/unordered_map
+++ b/libstdc++-v3/include/debug/unordered_map
@@ -40,6 +40,7 @@
#else
# include <c++0x_warning.h>
#endif
+#include <initializer_list>
#include <debug/safe_association.h>
#include <debug/safe_iterator.h>
@@ -64,6 +65,7 @@ namespace __debug
public:
typedef typename _Safe_assoc::size_type size_type;
+ typedef typename _Safe_assoc::value_type value_type;
typedef typename _Safe_assoc::hasher hasher;
typedef typename _Safe_assoc::key_equal key_equal;
typedef typename _Safe_assoc::allocator_type allocator_type;
@@ -91,6 +93,13 @@ namespace __debug
unordered_map(unordered_map&& __x)
: _Safe_assoc(std::forward<_Safe_assoc>(__x)), _Safe_base() { }
+ unordered_map(initializer_list<value_type> __l,
+ size_type __n = 10,
+ const hasher& __hf = hasher(),
+ const key_equal& __eql = key_equal(),
+ const allocator_type& __a = allocator_type())
+ : _Safe_assoc(__l, __n, __hf, __eql, __a) { }
+
unordered_map&
operator=(unordered_map&& __x)
{
@@ -100,6 +109,14 @@ namespace __debug
return *this;
}
+ unordered_map&
+ operator=(initializer_list<value_type> __l)
+ {
+ this->clear();
+ this->insert(__l);
+ return *this;
+ }
+
void
swap(unordered_map&& __x)
{
@@ -164,6 +181,7 @@ namespace __debug
public:
typedef typename _Safe_assoc::size_type size_type;
+ typedef typename _Safe_assoc::value_type value_type;
typedef typename _Safe_assoc::hasher hasher;
typedef typename _Safe_assoc::key_equal key_equal;
typedef typename _Safe_assoc::allocator_type allocator_type;
@@ -185,6 +203,13 @@ namespace __debug
: _Safe_assoc(__f, __l, __n, __hf, __eql, __a)
{ }
+ unordered_multimap(initializer_list<value_type> __l,
+ size_type __n = 10,
+ const hasher& __hf = hasher(),
+ const key_equal& __eql = key_equal(),
+ const allocator_type& __a = allocator_type())
+ : _Safe_assoc(__l, __n, __hf, __eql, __a) { }
+
unordered_multimap(const _Safe_assoc& __x)
: _Safe_assoc(__x), _Safe_base() { }
@@ -200,6 +225,14 @@ namespace __debug
return *this;
}
+ unordered_multimap&
+ operator=(initializer_list<value_type> __l)
+ {
+ this->clear();
+ this->insert(__l);
+ return *this;
+ }
+
void
swap(unordered_multimap&& __x)
{
diff --git a/libstdc++-v3/include/debug/unordered_set b/libstdc++-v3/include/debug/unordered_set
index b4b9be8a140..4c5d4d5ce34 100644
--- a/libstdc++-v3/include/debug/unordered_set
+++ b/libstdc++-v3/include/debug/unordered_set
@@ -41,6 +41,7 @@
# include <c++0x_warning.h>
#endif
+#include <initializer_list>
#include <debug/safe_association.h>
#include <debug/safe_iterator.h>
@@ -65,6 +66,7 @@ namespace __debug
public:
typedef typename _Safe_assoc::size_type size_type;
+ typedef typename _Safe_assoc::value_type value_type;
typedef typename _Safe_assoc::hasher hasher;
typedef typename _Safe_assoc::key_equal key_equal;
typedef typename _Safe_assoc::allocator_type allocator_type;
@@ -86,6 +88,13 @@ namespace __debug
: _Safe_assoc(__f, __l, __n, __hf, __eql, __a)
{ }
+ unordered_set(initializer_list<value_type> __l,
+ size_type __n = 10,
+ const hasher& __hf = hasher(),
+ const key_equal& __eql = key_equal(),
+ const allocator_type& __a = allocator_type())
+ : _Safe_assoc(__l, __n, __hf, __eql, __a) { }
+
unordered_set(const _Safe_assoc& __x)
: _Safe_assoc(__x), _Safe_base() { }
@@ -101,6 +110,14 @@ namespace __debug
return *this;
}
+ unordered_set&
+ operator=(initializer_list<value_type> __l)
+ {
+ this->clear();
+ this->insert(__l);
+ return *this;
+ }
+
void
swap(unordered_set&& __x)
{
@@ -162,6 +179,7 @@ namespace __debug
public:
typedef typename _Safe_assoc::size_type size_type;
+ typedef typename _Safe_assoc::value_type value_type;
typedef typename _Safe_assoc::hasher hasher;
typedef typename _Safe_assoc::key_equal key_equal;
typedef typename _Safe_assoc::allocator_type allocator_type;
@@ -183,6 +201,13 @@ namespace __debug
: _Safe_assoc(__f, __l, __n, __hf, __eql, __a)
{ }
+ unordered_multiset(initializer_list<value_type> __l,
+ size_type __n = 10,
+ const hasher& __hf = hasher(),
+ const key_equal& __eql = key_equal(),
+ const allocator_type& __a = allocator_type())
+ : _Safe_assoc(__l, __n, __hf, __eql, __a) { }
+
unordered_multiset(const _Safe_assoc& __x)
: _Safe_assoc(__x), _Safe_base() { }
@@ -198,6 +223,14 @@ namespace __debug
return *this;
}
+ unordered_multiset&
+ operator=(initializer_list<value_type> __l)
+ {
+ this->clear();
+ this->insert(__l);
+ return *this;
+ }
+
void
swap(unordered_multiset&& __x)
{
diff --git a/libstdc++-v3/include/debug/vector b/libstdc++-v3/include/debug/vector
index 12bd52f0b2b..a00419200d0 100644
--- a/libstdc++-v3/include/debug/vector
+++ b/libstdc++-v3/include/debug/vector
@@ -106,6 +106,11 @@ namespace __debug
this->_M_swap(__x);
__x._M_guaranteed_capacity = 0;
}
+
+ vector(initializer_list<value_type> __l,
+ const allocator_type& __a = allocator_type())
+ : _Base(__l, __a), _Safe_base(),
+ _M_guaranteed_capacity(__l.size()) { }
#endif
~vector() { }
@@ -128,6 +133,15 @@ namespace __debug
swap(__x);
return *this;
}
+
+ vector&
+ operator=(initializer_list<value_type> __l)
+ {
+ static_cast<_Base&>(*this) = __l;
+ this->_M_invalidate_all();
+ _M_update_guaranteed_capacity();
+ return *this;
+ }
#endif
template<typename _InputIterator>
@@ -148,6 +162,16 @@ namespace __debug
_M_update_guaranteed_capacity();
}
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ void
+ assign(initializer_list<value_type> __l)
+ {
+ _Base::assign(__l);
+ this->_M_invalidate_all();
+ _M_update_guaranteed_capacity();
+ }
+#endif
+
using _Base::get_allocator;
// iterators:
@@ -300,9 +324,11 @@ namespace __debug
}
#ifdef __GXX_EXPERIMENTAL_CXX0X__
- void
- push_back(_Tp&& __x)
- { emplace_back(std::move(__x)); }
+ template<typename _Up = _Tp>
+ typename __gnu_cxx::__enable_if<!std::__are_same<_Up, bool>::__value,
+ void>::__type
+ push_back(_Tp&& __x)
+ { emplace_back(std::move(__x)); }
template<typename... _Args>
void
@@ -360,9 +386,15 @@ namespace __debug
}
#ifdef __GXX_EXPERIMENTAL_CXX0X__
- iterator
- insert(iterator __position, _Tp&& __x)
- { return emplace(__position, std::move(__x)); }
+ template<typename _Up = _Tp>
+ typename __gnu_cxx::__enable_if<!std::__are_same<_Up, bool>::__value,
+ iterator>::__type
+ insert(iterator __position, _Tp&& __x)
+ { return emplace(__position, std::move(__x)); }
+
+ void
+ insert(iterator __position, initializer_list<value_type> __l)
+ { this->insert(__position, __l.begin(), __l.end()); }
#endif
void
diff --git a/libstdc++-v3/include/ext/pb_ds/detail/binomial_heap_base_/debug_fn_imps.hpp b/libstdc++-v3/include/ext/pb_ds/detail/binomial_heap_base_/debug_fn_imps.hpp
index 200249d8d98..85e5b870ce9 100644
--- a/libstdc++-v3/include/ext/pb_ds/detail/binomial_heap_base_/debug_fn_imps.hpp
+++ b/libstdc++-v3/include/ext/pb_ds/detail/binomial_heap_base_/debug_fn_imps.hpp
@@ -1,6 +1,6 @@
// -*- C++ -*-
-// Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+// Copyright (C) 2005, 2006, 2007, 2008 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
@@ -65,13 +65,15 @@ assert_max() const
return;
_GLIBCXX_DEBUG_ASSERT(base_type::parent(m_p_max) == NULL);
for (const_iterator it = base_type::begin(); it != base_type::end(); ++it)
- _GLIBCXX_DEBUG_ASSERT(!Cmp_Fn::operator()(m_p_max->m_value, it.m_p_nd->m_value));
+ _GLIBCXX_DEBUG_ASSERT(!Cmp_Fn::operator()(m_p_max->m_value,
+ it.m_p_nd->m_value));
}
PB_DS_CLASS_T_DEC
void
PB_DS_CLASS_C_DEC::
-assert_node_consistent(const_node_pointer p_nd, bool strictly_binomial, bool increasing) const
+assert_node_consistent(const_node_pointer p_nd, bool strictly_binomial,
+ bool increasing) const
{
_GLIBCXX_DEBUG_ASSERT(increasing || strictly_binomial);
base_type::assert_node_consistent(p_nd, false);
@@ -83,15 +85,20 @@ assert_node_consistent(const_node_pointer p_nd, bool strictly_binomial, bool inc
assert_node_consistent(p_nd->m_p_next_sibling, strictly_binomial, increasing);
assert_node_consistent(p_nd->m_p_l_child, true, false);
if (p_nd->m_p_next_sibling != NULL)
- if (increasing)
- {
- if (strictly_binomial)
- _GLIBCXX_DEBUG_ASSERT(p_nd->m_metadata < p_nd->m_p_next_sibling->m_metadata);
- else
- _GLIBCXX_DEBUG_ASSERT(p_nd->m_metadata <= p_nd->m_p_next_sibling->m_metadata);
- }
- else
- _GLIBCXX_DEBUG_ASSERT(p_nd->m_metadata > p_nd->m_p_next_sibling->m_metadata);
+ {
+ if (increasing)
+ {
+ if (strictly_binomial)
+ _GLIBCXX_DEBUG_ASSERT(p_nd->m_metadata
+ < p_nd->m_p_next_sibling->m_metadata);
+ else
+ _GLIBCXX_DEBUG_ASSERT(p_nd->m_metadata
+ <= p_nd->m_p_next_sibling->m_metadata);
+ }
+ else
+ _GLIBCXX_DEBUG_ASSERT(p_nd->m_metadata
+ > p_nd->m_p_next_sibling->m_metadata);
+ }
}
-#endif
+#endif
diff --git a/libstdc++-v3/include/ext/pb_ds/detail/debug_map_base.hpp b/libstdc++-v3/include/ext/pb_ds/detail/debug_map_base.hpp
index 086a50fc5fd..5319749128b 100644
--- a/libstdc++-v3/include/ext/pb_ds/detail/debug_map_base.hpp
+++ b/libstdc++-v3/include/ext/pb_ds/detail/debug_map_base.hpp
@@ -1,6 +1,6 @@
// -*- C++ -*-
-// Copyright (C) 2005, 2006, 2007 Free Software Foundation, Inc.
+// Copyright (C) 2005, 2006, 2007, 2008 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
@@ -52,6 +52,7 @@
#include <list>
#include <utility>
#include <cstdlib>
+#include <iostream>
#include <ext/throw_allocator.h>
#include <debug/debug.h>
diff --git a/libstdc++-v3/include/ext/pb_ds/detail/left_child_next_sibling_heap_/null_metadata.hpp b/libstdc++-v3/include/ext/pb_ds/detail/left_child_next_sibling_heap_/null_metadata.hpp
index 290745e533d..fedbf032f6b 100644
--- a/libstdc++-v3/include/ext/pb_ds/detail/left_child_next_sibling_heap_/null_metadata.hpp
+++ b/libstdc++-v3/include/ext/pb_ds/detail/left_child_next_sibling_heap_/null_metadata.hpp
@@ -1,6 +1,6 @@
// -*- C++ -*-
-// Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+// Copyright (C) 2005, 2006, 2008 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
@@ -47,8 +47,6 @@
#ifndef PB_DS_LEFT_CHILD_NEXT_SIBLING_HEAP_NULL_METADATA_HPP
#define PB_DS_LEFT_CHILD_NEXT_SIBLING_HEAP_NULL_METADATA_HPP
-#include <ext/pb_ds/detail/left_child_next_sibling_heap_/null_metadata.hpp>
-
namespace __gnu_pbds
{
namespace detail
diff --git a/libstdc++-v3/include/ext/rc_string_base.h b/libstdc++-v3/include/ext/rc_string_base.h
index 0d3224cea10..213e3cf1c97 100644
--- a/libstdc++-v3/include/ext/rc_string_base.h
+++ b/libstdc++-v3/include/ext/rc_string_base.h
@@ -308,7 +308,7 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
#ifdef __GXX_EXPERIMENTAL_CXX0X__
__rc_string_base(__rc_string_base&& __rcs)
: _M_dataplus(__rcs._M_get_allocator(), __rcs._M_data())
- { __rcs._M_data(_S_empty_rep._M_refcopy()); }
+ { __rcs._M_data(_S_empty_rep._M_refcopy()); }
#endif
__rc_string_base(size_type __n, _CharT __c, const _Alloc& __a);
diff --git a/libstdc++-v3/include/ext/rope b/libstdc++-v3/include/ext/rope
index e39761ec432..b85f98e3be4 100644
--- a/libstdc++-v3/include/ext/rope
+++ b/libstdc++-v3/include/ext/rope
@@ -1,6 +1,6 @@
// SGI's rope class -*- C++ -*-
-// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
// Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
@@ -80,6 +80,22 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
using std::allocator;
using std::_Destroy;
+ // See libstdc++/36832.
+ template<typename _ForwardIterator, typename _Allocator>
+ void
+ _Destroy_const(_ForwardIterator __first,
+ _ForwardIterator __last, _Allocator __alloc)
+ {
+ for (; __first != __last; ++__first)
+ __alloc.destroy(&*__first);
+ }
+
+ template<typename _ForwardIterator, typename _Tp>
+ inline void
+ _Destroy_const(_ForwardIterator __first,
+ _ForwardIterator __last, allocator<_Tp>)
+ { _Destroy(__first, __last); }
+
// The _S_eos function is used for those functions that
// convert to/from C-like strings to detect the end of the string.
@@ -1941,11 +1957,11 @@ protected:
this->_M_tree_ptr = _S_balance(this->_M_tree_ptr);
_S_unref(__old);
}
-
+
void
copy(_CharT* __buffer) const
{
- _Destroy(__buffer, __buffer + size(), _M_get_allocator());
+ _Destroy_const(__buffer, __buffer + size(), _M_get_allocator());
_S_flatten(this->_M_tree_ptr, __buffer);
}
@@ -1959,8 +1975,8 @@ protected:
{
size_t __size = size();
size_t __len = (__pos + __n > __size? __size - __pos : __n);
-
- _Destroy(__buffer, __buffer + __len, _M_get_allocator());
+
+ _Destroy_const(__buffer, __buffer + __len, _M_get_allocator());
_S_flatten(this->_M_tree_ptr, __pos, __len, __buffer);
return __len;
}
diff --git a/libstdc++-v3/include/ext/sso_string_base.h b/libstdc++-v3/include/ext/sso_string_base.h
index 9c8c1bc79d6..73c6a1b2df0 100644
--- a/libstdc++-v3/include/ext/sso_string_base.h
+++ b/libstdc++-v3/include/ext/sso_string_base.h
@@ -1,6 +1,6 @@
// Short-string-optimized versatile string base -*- C++ -*-
-// Copyright (C) 2005, 2006, 2007 Free Software Foundation, Inc.
+// Copyright (C) 2005, 2006, 2007, 2008 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
diff --git a/libstdc++-v3/include/ext/vstring.h b/libstdc++-v3/include/ext/vstring.h
index 0e74bfa8cb2..ea1652db54e 100644
--- a/libstdc++-v3/include/ext/vstring.h
+++ b/libstdc++-v3/include/ext/vstring.h
@@ -36,6 +36,7 @@
#pragma GCC system_header
+#include <initializer_list>
#include <ext/vstring_util.h>
#include <ext/rc_string_base.h>
#include <ext/sso_string_base.h>
@@ -156,6 +157,15 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
*/
__versa_string(__versa_string&& __str)
: __vstring_base(std::forward<__vstring_base>(__str)) { }
+
+ /**
+ * @brief Construct string from an initializer list.
+ * @param l std::initializer_list of characters.
+ * @param a Allocator to use (default is default allocator).
+ */
+ __versa_string(std::initializer_list<_CharT> __l,
+ const _Alloc& __a = _Alloc())
+ : __vstring_base(__l.begin(), __l.end(), __a) { }
#endif
/**
@@ -257,6 +267,17 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
this->swap(__str);
return *this;
}
+
+ /**
+ * @brief Set value to string constructed from initializer list.
+ * @param l std::initializer_list.
+ */
+ __versa_string&
+ operator=(std::initializer_list<_CharT> __l)
+ {
+ this->assign(__l.begin(), __l.end());
+ return *this;
+ }
#endif
/**
@@ -623,6 +644,17 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
return *this;
}
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ /**
+ * @brief Append an initializer_list of characters.
+ * @param l The initializer_list of characters to be appended.
+ * @return Reference to this string.
+ */
+ __versa_string&
+ operator+=(std::initializer_list<_CharT> __l)
+ { return this->append(__l.begin(), __l.end()); }
+#endif // __GXX_EXPERIMENTAL_CXX0X__
+
/**
* @brief Append a string to this string.
* @param str The string to append.
@@ -690,6 +722,17 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
append(size_type __n, _CharT __c)
{ return _M_replace_aux(this->size(), size_type(0), __n, __c); }
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ /**
+ * @brief Append an initializer_list of characters.
+ * @param l The initializer_list of characters to append.
+ * @return Reference to this string.
+ */
+ __versa_string&
+ append(std::initializer_list<_CharT> __l)
+ { return this->append(__l.begin(), __l.end()); }
+#endif // __GXX_EXPERIMENTAL_CXX0X__
+
/**
* @brief Append a range of characters.
* @param first Iterator referencing the first character to append.
@@ -807,6 +850,17 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
assign(_InputIterator __first, _InputIterator __last)
{ return this->replace(_M_ibegin(), _M_iend(), __first, __last); }
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ /**
+ * @brief Set value to an initializer_list of characters.
+ * @param l The initializer_list of characters to assign.
+ * @return Reference to this string.
+ */
+ __versa_string&
+ assign(std::initializer_list<_CharT> __l)
+ { return this->assign(__l.begin(), __l.end()); }
+#endif // __GXX_EXPERIMENTAL_CXX0X__
+
/**
* @brief Insert multiple characters.
* @param p Iterator referencing location in string to insert at.
@@ -839,6 +893,18 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
insert(iterator __p, _InputIterator __beg, _InputIterator __end)
{ this->replace(__p, __p, __beg, __end); }
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ /**
+ * @brief Insert an initializer_list of characters.
+ * @param p Iterator referencing location in string to insert at.
+ * @param l The initializer_list of characters to insert.
+ * @throw std::length_error If new length exceeds @c max_size().
+ */
+ void
+ insert(iterator __p, std::initializer_list<_CharT> __l)
+ { this->insert(__p, __l.begin(), __l.end()); }
+#endif // __GXX_EXPERIMENTAL_CXX0X__
+
/**
* @brief Insert value of a string.
* @param pos1 Iterator referencing location in string to insert at.
@@ -1295,6 +1361,25 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
__k1.base(), __k2 - __k1);
}
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ /**
+ * @brief Replace range of characters with initializer_list.
+ * @param i1 Iterator referencing start of range to replace.
+ * @param i2 Iterator referencing end of range to replace.
+ * @param l The initializer_list of characters to insert.
+ * @return Reference to this string.
+ * @throw std::length_error If new length exceeds @c max_size().
+ *
+ * Removes the characters in the range [i1,i2). In place, characters
+ * in the range [k1,k2) are inserted. If the length of result exceeds
+ * max_size(), length_error is thrown. The value of the string doesn't
+ * change if an error is thrown.
+ */
+ __versa_string& replace(iterator __i1, iterator __i2,
+ std::initializer_list<_CharT> __l)
+ { return this->replace(__i1, __i2, __l.begin(), __l.end()); }
+#endif // __GXX_EXPERIMENTAL_CXX0X__
+
private:
template<class _Integer>
__versa_string&
diff --git a/libstdc++-v3/include/parallel/algo.h b/libstdc++-v3/include/parallel/algo.h
index 4aa4d8af47f..23e7bdcbabc 100644
--- a/libstdc++-v3/include/parallel/algo.h
+++ b/libstdc++-v3/include/parallel/algo.h
@@ -2367,4 +2367,4 @@ namespace __parallel
} // end namespace
} // end namespace
-#endif /* _GLIBCXX_ALGORITHM_H */
+#endif /* _GLIBCXX_PARALLEL_ALGO_H */
diff --git a/libstdc++-v3/include/parallel/algobase.h b/libstdc++-v3/include/parallel/algobase.h
index 821985d49b1..4e77dd7d5dc 100644
--- a/libstdc++-v3/include/parallel/algobase.h
+++ b/libstdc++-v3/include/parallel/algobase.h
@@ -284,4 +284,4 @@ namespace __parallel
} // end namespace
} // end namespace
-#endif /* _GLIBCXX_ALGOBASE_H */
+#endif /* _GLIBCXX_PARALLEL_ALGOBASE_H */
diff --git a/libstdc++-v3/include/parallel/algorithmfwd.h b/libstdc++-v3/include/parallel/algorithmfwd.h
index ea6b245eb7e..3f386a5cdbc 100644
--- a/libstdc++-v3/include/parallel/algorithmfwd.h
+++ b/libstdc++-v3/include/parallel/algorithmfwd.h
@@ -892,4 +892,4 @@ namespace __parallel
} // end namespace __parallel
} // end namespace std
-#endif
+#endif /* _GLIBCXX_PARALLEL_ALGORITHMFWD_H */
diff --git a/libstdc++-v3/include/parallel/balanced_quicksort.h b/libstdc++-v3/include/parallel/balanced_quicksort.h
index d94cf332a73..3fd12642eea 100644
--- a/libstdc++-v3/include/parallel/balanced_quicksort.h
+++ b/libstdc++-v3/include/parallel/balanced_quicksort.h
@@ -45,8 +45,8 @@
// Written by Johannes Singler.
-#ifndef _GLIBCXX_PARALLEL_BAL_QUICKSORT_H
-#define _GLIBCXX_PARALLEL_BAL_QUICKSORT_H 1
+#ifndef _GLIBCXX_PARALLEL_BALANCED_QUICKSORT_H
+#define _GLIBCXX_PARALLEL_BALANCED_QUICKSORT_H 1
#include <parallel/basic_iterator.h>
#include <bits/stl_algo.h>
@@ -122,11 +122,11 @@ template<typename RandomAccessIterator, typename Comparator>
_GLIBCXX_PARALLEL_ASSERT(
(!comp(*pivot_pos, *begin) && !comp(*(begin + n / 2), *pivot_pos))
- || (!comp(*pivot_pos, *begin) && !comp(*end, *pivot_pos))
+ || (!comp(*pivot_pos, *begin) && !comp(*(end - 1), *pivot_pos))
|| (!comp(*pivot_pos, *(begin + n / 2)) && !comp(*begin, *pivot_pos))
- || (!comp(*pivot_pos, *(begin + n / 2)) && !comp(*end, *pivot_pos))
- || (!comp(*pivot_pos, *end) && !comp(*begin, *pivot_pos))
- || (!comp(*pivot_pos, *end) && !comp(*(begin + n / 2), *pivot_pos)));
+ || (!comp(*pivot_pos, *(begin + n / 2)) && !comp(*(end - 1), *pivot_pos))
+ || (!comp(*pivot_pos, *(end - 1)) && !comp(*begin, *pivot_pos))
+ || (!comp(*pivot_pos, *(end - 1)) && !comp(*(begin + n / 2), *pivot_pos)));
#endif
// Swap pivot value to end.
@@ -480,4 +480,4 @@ template<typename RandomAccessIterator, typename Comparator>
}
} // namespace __gnu_parallel
-#endif
+#endif /* _GLIBCXX_PARALLEL_BALANCED_QUICKSORT_H */
diff --git a/libstdc++-v3/include/parallel/base.h b/libstdc++-v3/include/parallel/base.h
index 54c26d8ca6d..45c3327f5af 100644
--- a/libstdc++-v3/include/parallel/base.h
+++ b/libstdc++-v3/include/parallel/base.h
@@ -492,4 +492,4 @@ do \
} //namespace __gnu_parallel
-#endif
+#endif /* _GLIBCXX_PARALLEL_BASE_H */
diff --git a/libstdc++-v3/include/parallel/basic_iterator.h b/libstdc++-v3/include/parallel/basic_iterator.h
index 4b891be80b2..edbecca7a9f 100644
--- a/libstdc++-v3/include/parallel/basic_iterator.h
+++ b/libstdc++-v3/include/parallel/basic_iterator.h
@@ -45,4 +45,4 @@
#include <bits/stl_iterator_base_funcs.h>
#include <bits/stl_iterator.h>
-#endif /* _GLIBCXX_BASIC_ITERATOR_H */
+#endif /* _GLIBCXX_PARALLEL_BASIC_ITERATOR_H */
diff --git a/libstdc++-v3/include/parallel/checkers.h b/libstdc++-v3/include/parallel/checkers.h
index 1c6bc355d17..231cea8892b 100644
--- a/libstdc++-v3/include/parallel/checkers.h
+++ b/libstdc++-v3/include/parallel/checkers.h
@@ -35,8 +35,8 @@
// Written by Johannes Singler.
-#ifndef _GLIBCXX_PARALLEL_CHECKERS
-#define _GLIBCXX_PARALLEL_CHECKERS 1
+#ifndef _GLIBCXX_PARALLEL_CHECKERS_H
+#define _GLIBCXX_PARALLEL_CHECKERS_H 1
#include <functional>
#include <cstdio>
@@ -157,4 +157,4 @@ namespace __gnu_parallel
}
}
-#endif
+#endif /* _GLIBCXX_PARALLEL_CHECKERS_H */
diff --git a/libstdc++-v3/include/parallel/compatibility.h b/libstdc++-v3/include/parallel/compatibility.h
index 18514e6f8a9..840a9201712 100644
--- a/libstdc++-v3/include/parallel/compatibility.h
+++ b/libstdc++-v3/include/parallel/compatibility.h
@@ -353,4 +353,4 @@ namespace __gnu_parallel
}
} // end namespace
-#endif
+#endif /* _GLIBCXX_PARALLEL_COMPATIBILITY_H */
diff --git a/libstdc++-v3/include/parallel/equally_split.h b/libstdc++-v3/include/parallel/equally_split.h
index 37e45816727..e12cb10a040 100644
--- a/libstdc++-v3/include/parallel/equally_split.h
+++ b/libstdc++-v3/include/parallel/equally_split.h
@@ -90,4 +90,4 @@ template<typename difference_type>
}
}
-#endif
+#endif /* _GLIBCXX_PARALLEL_EQUALLY_SPLIT_H */
diff --git a/libstdc++-v3/include/parallel/features.h b/libstdc++-v3/include/parallel/features.h
index 7150c20affc..f0aef51622e 100644
--- a/libstdc++-v3/include/parallel/features.h
+++ b/libstdc++-v3/include/parallel/features.h
@@ -107,4 +107,4 @@
#endif
-#endif
+#endif /* _GLIBCXX_PARALLEL_FEATURES_H */
diff --git a/libstdc++-v3/include/parallel/find.h b/libstdc++-v3/include/parallel/find.h
index 3e0084f68ab..4717c8e570b 100644
--- a/libstdc++-v3/include/parallel/find.h
+++ b/libstdc++-v3/include/parallel/find.h
@@ -404,4 +404,4 @@ template<typename RandomAccessIterator1,
#endif
} // end namespace
-#endif
+#endif /* _GLIBCXX_PARALLEL_FIND_H */
diff --git a/libstdc++-v3/include/parallel/find_selectors.h b/libstdc++-v3/include/parallel/find_selectors.h
index 3076bd2327e..29c6ca09e98 100644
--- a/libstdc++-v3/include/parallel/find_selectors.h
+++ b/libstdc++-v3/include/parallel/find_selectors.h
@@ -36,8 +36,8 @@
// Written by Felix Putze.
-#ifndef _GLIBCXX_PARALLEL_FIND_FUNCTIONS_H
-#define _GLIBCXX_PARALLEL_FIND_FUNCTIONS_H 1
+#ifndef _GLIBCXX_PARALLEL_FIND_SELECTORS_H
+#define _GLIBCXX_PARALLEL_FIND_SELECTORS_H 1
#include <parallel/tags.h>
#include <parallel/basic_iterator.h>
@@ -195,4 +195,4 @@ namespace __gnu_parallel
};
}
-#endif
+#endif /* _GLIBCXX_PARALLEL_FIND_SELECTORS_H */
diff --git a/libstdc++-v3/include/parallel/for_each.h b/libstdc++-v3/include/parallel/for_each.h
index 8a4d702d2d5..df9d4f338a1 100644
--- a/libstdc++-v3/include/parallel/for_each.h
+++ b/libstdc++-v3/include/parallel/for_each.h
@@ -100,4 +100,4 @@ namespace __gnu_parallel
}
}
-#endif
+#endif /* _GLIBCXX_PARALLEL_FOR_EACH_H */
diff --git a/libstdc++-v3/include/parallel/for_each_selectors.h b/libstdc++-v3/include/parallel/for_each_selectors.h
index eaa55fc05c6..651b76bad28 100644
--- a/libstdc++-v3/include/parallel/for_each_selectors.h
+++ b/libstdc++-v3/include/parallel/for_each_selectors.h
@@ -363,4 +363,4 @@ namespace __gnu_parallel
};
}
-#endif
+#endif /* _GLIBCXX_PARALLEL_FOR_EACH_SELECTORS_H */
diff --git a/libstdc++-v3/include/parallel/iterator.h b/libstdc++-v3/include/parallel/iterator.h
index ba20a460d5c..7aaafee8611 100644
--- a/libstdc++-v3/include/parallel/iterator.h
+++ b/libstdc++-v3/include/parallel/iterator.h
@@ -202,4 +202,4 @@ namespace __gnu_parallel
};
}
-#endif
+#endif /* _GLIBCXX_PARALLEL_ITERATOR_H */
diff --git a/libstdc++-v3/include/parallel/list_partition.h b/libstdc++-v3/include/parallel/list_partition.h
index 5adc5c9280d..c9d34e3c8e7 100644
--- a/libstdc++-v3/include/parallel/list_partition.h
+++ b/libstdc++-v3/include/parallel/list_partition.h
@@ -179,4 +179,4 @@ namespace __gnu_parallel
}
}
-#endif
+#endif /* _GLIBCXX_PARALLEL_LIST_PARTITION_H */
diff --git a/libstdc++-v3/include/parallel/losertree.h b/libstdc++-v3/include/parallel/losertree.h
index 3736b908557..b7f8da036ae 100644
--- a/libstdc++-v3/include/parallel/losertree.h
+++ b/libstdc++-v3/include/parallel/losertree.h
@@ -1024,4 +1024,4 @@ public:
} // namespace __gnu_parallel
-#endif
+#endif /* _GLIBCXX_PARALLEL_LOSERTREE_H */
diff --git a/libstdc++-v3/include/parallel/merge.h b/libstdc++-v3/include/parallel/merge.h
index 580b1479329..ca140a5b125 100644
--- a/libstdc++-v3/include/parallel/merge.h
+++ b/libstdc++-v3/include/parallel/merge.h
@@ -264,4 +264,4 @@ namespace __gnu_parallel
}
} //namespace __gnu_parallel
-#endif
+#endif /* _GLIBCXX_PARALLEL_MERGE_H */
diff --git a/libstdc++-v3/include/parallel/multiseq_selection.h b/libstdc++-v3/include/parallel/multiseq_selection.h
index 662204526c9..ee9214f4a22 100644
--- a/libstdc++-v3/include/parallel/multiseq_selection.h
+++ b/libstdc++-v3/include/parallel/multiseq_selection.h
@@ -636,5 +636,4 @@ namespace __gnu_parallel
#undef S
-#endif
-
+#endif /* _GLIBCXX_PARALLEL_MULTISEQ_SELECTION_H */
diff --git a/libstdc++-v3/include/parallel/multiway_merge.h b/libstdc++-v3/include/parallel/multiway_merge.h
index 3c75c70f3c4..4bfad0c9989 100644
--- a/libstdc++-v3/include/parallel/multiway_merge.h
+++ b/libstdc++-v3/include/parallel/multiway_merge.h
@@ -2148,4 +2148,4 @@ stable_multiway_merge_sentinels(RandomAccessIteratorPairIterator seqs_begin
}; // namespace __gnu_parallel
-#endif
+#endif /* _GLIBCXX_PARALLEL_MULTIWAY_MERGE_H */
diff --git a/libstdc++-v3/include/parallel/multiway_mergesort.h b/libstdc++-v3/include/parallel/multiway_mergesort.h
index 9d9733ad05f..c12e58407fd 100644
--- a/libstdc++-v3/include/parallel/multiway_mergesort.h
+++ b/libstdc++-v3/include/parallel/multiway_mergesort.h
@@ -35,8 +35,8 @@
// Written by Johannes Singler.
-#ifndef _GLIBCXX_PARALLEL_MERGESORT_H
-#define _GLIBCXX_PARALLEL_MERGESORT_H 1
+#ifndef _GLIBCXX_PARALLEL_MULTIWAY_MERGESORT_H
+#define _GLIBCXX_PARALLEL_MULTIWAY_MERGESORT_H 1
#include <vector>
@@ -478,4 +478,4 @@ template<bool stable, bool exact, typename RandomAccessIterator,
}
} //namespace __gnu_parallel
-#endif
+#endif /* _GLIBCXX_PARALLEL_MULTIWAY_MERGESORT_H */
diff --git a/libstdc++-v3/include/parallel/numericfwd.h b/libstdc++-v3/include/parallel/numericfwd.h
index 581ceaad6f4..362725b4a67 100644
--- a/libstdc++-v3/include/parallel/numericfwd.h
+++ b/libstdc++-v3/include/parallel/numericfwd.h
@@ -203,4 +203,4 @@ namespace __parallel
} // end namespace
} // end namespace
-#endif
+#endif /* _GLIBCXX_PARALLEL_NUMERICFWD_H */
diff --git a/libstdc++-v3/include/parallel/omp_loop.h b/libstdc++-v3/include/parallel/omp_loop.h
index bc34aed2857..88634c95d4f 100644
--- a/libstdc++-v3/include/parallel/omp_loop.h
+++ b/libstdc++-v3/include/parallel/omp_loop.h
@@ -121,4 +121,4 @@ template<typename RandomAccessIterator,
} // end namespace
-#endif
+#endif /* _GLIBCXX_PARALLEL_OMP_LOOP_H */
diff --git a/libstdc++-v3/include/parallel/omp_loop_static.h b/libstdc++-v3/include/parallel/omp_loop_static.h
index 96692e8645a..dc6c24975b5 100644
--- a/libstdc++-v3/include/parallel/omp_loop_static.h
+++ b/libstdc++-v3/include/parallel/omp_loop_static.h
@@ -120,4 +120,4 @@ template<typename RandomAccessIterator,
} // end namespace
-#endif
+#endif /* _GLIBCXX_PARALLEL_OMP_LOOP_STATIC_H */
diff --git a/libstdc++-v3/include/parallel/par_loop.h b/libstdc++-v3/include/parallel/par_loop.h
index 9e6c2ea641e..c8d2a220ca8 100644
--- a/libstdc++-v3/include/parallel/par_loop.h
+++ b/libstdc++-v3/include/parallel/par_loop.h
@@ -128,4 +128,4 @@ template<typename RandomAccessIterator,
} // end namespace
-#endif
+#endif /* _GLIBCXX_PARALLEL_PAR_LOOP_H */
diff --git a/libstdc++-v3/include/parallel/parallel.h b/libstdc++-v3/include/parallel/parallel.h
index 63246126b8f..f76f67976b6 100644
--- a/libstdc++-v3/include/parallel/parallel.h
+++ b/libstdc++-v3/include/parallel/parallel.h
@@ -45,4 +45,4 @@
#include <parallel/tags.h>
#include <parallel/settings.h>
-#endif
+#endif /* _GLIBCXX_PARALLEL_PARALLEL_H */
diff --git a/libstdc++-v3/include/parallel/partial_sum.h b/libstdc++-v3/include/parallel/partial_sum.h
index fd4954d456d..4551e48e97b 100644
--- a/libstdc++-v3/include/parallel/partial_sum.h
+++ b/libstdc++-v3/include/parallel/partial_sum.h
@@ -223,4 +223,4 @@ template<typename InputIterator,
}
}
-#endif
+#endif /* _GLIBCXX_PARALLEL_PARTIAL_SUM_H */
diff --git a/libstdc++-v3/include/parallel/partition.h b/libstdc++-v3/include/parallel/partition.h
index 7747b7e9980..f7bf3d083c9 100644
--- a/libstdc++-v3/include/parallel/partition.h
+++ b/libstdc++-v3/include/parallel/partition.h
@@ -432,4 +432,4 @@ template<typename RandomAccessIterator, typename Comparator>
#undef _GLIBCXX_VOLATILE
-#endif
+#endif /* _GLIBCXX_PARALLEL_PARTITION_H */
diff --git a/libstdc++-v3/include/parallel/queue.h b/libstdc++-v3/include/parallel/queue.h
index 27a26f3ecaa..fc37f6c8a71 100644
--- a/libstdc++-v3/include/parallel/queue.h
+++ b/libstdc++-v3/include/parallel/queue.h
@@ -152,4 +152,4 @@ namespace __gnu_parallel
#undef _GLIBCXX_VOLATILE
-#endif
+#endif /* _GLIBCXX_PARALLEL_QUEUE_H */
diff --git a/libstdc++-v3/include/parallel/quicksort.h b/libstdc++-v3/include/parallel/quicksort.h
index 844a5bf3ccd..b0201c2c08b 100644
--- a/libstdc++-v3/include/parallel/quicksort.h
+++ b/libstdc++-v3/include/parallel/quicksort.h
@@ -182,4 +182,4 @@ namespace __gnu_parallel
} //namespace __gnu_parallel
-#endif
+#endif /* _GLIBCXX_PARALLEL_QUICKSORT_H */
diff --git a/libstdc++-v3/include/parallel/random_number.h b/libstdc++-v3/include/parallel/random_number.h
index e1e11a8675c..fa91198a990 100644
--- a/libstdc++-v3/include/parallel/random_number.h
+++ b/libstdc++-v3/include/parallel/random_number.h
@@ -127,4 +127,4 @@ namespace __gnu_parallel
} // namespace __gnu_parallel
-#endif
+#endif /* _GLIBCXX_PARALLEL_RANDOM_NUMBER_H */
diff --git a/libstdc++-v3/include/parallel/random_shuffle.h b/libstdc++-v3/include/parallel/random_shuffle.h
index 1f7cc10742d..e6ce95d489d 100644
--- a/libstdc++-v3/include/parallel/random_shuffle.h
+++ b/libstdc++-v3/include/parallel/random_shuffle.h
@@ -491,6 +491,9 @@ template<typename RandomAccessIterator, typename RandomNumberGenerator>
rng);
}
+ // Copy elements back.
+ std::copy(target, target + n, begin);
+
delete[] dist0;
delete[] dist1;
delete[] oracles;
@@ -519,4 +522,4 @@ template<typename RandomAccessIterator, typename RandomNumberGenerator>
}
-#endif
+#endif /* _GLIBCXX_PARALLEL_RANDOM_SHUFFLE_H */
diff --git a/libstdc++-v3/include/parallel/search.h b/libstdc++-v3/include/parallel/search.h
index 86bd2b827b9..acda6a858b5 100644
--- a/libstdc++-v3/include/parallel/search.h
+++ b/libstdc++-v3/include/parallel/search.h
@@ -175,4 +175,4 @@ template<typename _RandomAccessIterator1,
}
} // end namespace
-#endif
+#endif /* _GLIBCXX_PARALLEL_SEARCH_H */
diff --git a/libstdc++-v3/include/parallel/set_operations.h b/libstdc++-v3/include/parallel/set_operations.h
index dccfbd83262..1d747401f8e 100644
--- a/libstdc++-v3/include/parallel/set_operations.h
+++ b/libstdc++-v3/include/parallel/set_operations.h
@@ -527,4 +527,4 @@ template<typename InputIterator,
}
-#endif // _GLIBCXX_SET_ALGORITHM_
+#endif /* _GLIBCXX_PARALLEL_SET_OPERATIONS_H */
diff --git a/libstdc++-v3/include/parallel/settings.h b/libstdc++-v3/include/parallel/settings.h
index ae1ae5ca063..bf7bfdcfb8b 100644
--- a/libstdc++-v3/include/parallel/settings.h
+++ b/libstdc++-v3/include/parallel/settings.h
@@ -284,4 +284,4 @@ namespace __gnu_parallel
};
}
-#endif /* _GLIBCXX_SETTINGS_H */
+#endif /* _GLIBCXX_PARALLEL_SETTINGS_H */
diff --git a/libstdc++-v3/include/parallel/sort.h b/libstdc++-v3/include/parallel/sort.h
index 559ed1cc19e..6e786819b29 100644
--- a/libstdc++-v3/include/parallel/sort.h
+++ b/libstdc++-v3/include/parallel/sort.h
@@ -232,4 +232,4 @@ namespace __gnu_parallel
}
} // end namespace __gnu_parallel
-#endif
+#endif /* _GLIBCXX_PARALLEL_SORT_H */
diff --git a/libstdc++-v3/include/parallel/types.h b/libstdc++-v3/include/parallel/types.h
index 1b646b02084..40afa8a8580 100644
--- a/libstdc++-v3/include/parallel/types.h
+++ b/libstdc++-v3/include/parallel/types.h
@@ -158,4 +158,4 @@ namespace __gnu_parallel
static const lcas_t lcas_t_mask = ((lcas_t(1) << (lcas_t_bits / 2)) - 1);
}
-#endif /* _GLIBCXX_TYPES_H */
+#endif /* _GLIBCXX_PARALLEL_TYPES_H */
diff --git a/libstdc++-v3/include/parallel/unique_copy.h b/libstdc++-v3/include/parallel/unique_copy.h
index 7f51e2603fd..1ef379d1186 100644
--- a/libstdc++-v3/include/parallel/unique_copy.h
+++ b/libstdc++-v3/include/parallel/unique_copy.h
@@ -35,8 +35,8 @@
// Written by Robert Geisberger and Robin Dapp.
-#ifndef _GLIBCXX_PARALLEL_UNIQUE_H
-#define _GLIBCXX_PARALLEL_UNIQUE_H 1
+#ifndef _GLIBCXX_PARALLEL_UNIQUE_COPY_H
+#define _GLIBCXX_PARALLEL_UNIQUE_COPY_H 1
#include <parallel/parallel.h>
#include <parallel/multiseq_selection.h>
@@ -195,4 +195,4 @@ template<typename InputIterator, class OutputIterator>
}//namespace __gnu_parallel
-#endif
+#endif /* _GLIBCXX_PARALLEL_UNIQUE_COPY_H */
diff --git a/libstdc++-v3/include/parallel/workstealing.h b/libstdc++-v3/include/parallel/workstealing.h
index 628f12cca2c..c8d571b0d6c 100644
--- a/libstdc++-v3/include/parallel/workstealing.h
+++ b/libstdc++-v3/include/parallel/workstealing.h
@@ -309,4 +309,4 @@ template<typename RandomAccessIterator,
}
} // end namespace
-#endif
+#endif /* _GLIBCXX_PARALLEL_WORKSTEALING_H */
diff --git a/libstdc++-v3/include/precompiled/stdc++.h b/libstdc++-v3/include/precompiled/stdc++.h
index e4b61106734..b9249353678 100644
--- a/libstdc++-v3/include/precompiled/stdc++.h
+++ b/libstdc++-v3/include/precompiled/stdc++.h
@@ -98,8 +98,9 @@
#ifdef __GXX_EXPERIMENTAL_CXX0X__
#include <array>
-#include <date_time>
+#include <chrono>
#include <random>
+#include <ratio>
#include <regex>
#include <system_error>
#include <tuple>
diff --git a/libstdc++-v3/include/std/chrono b/libstdc++-v3/include/std/chrono
new file mode 100644
index 00000000000..b5fd1fd209e
--- /dev/null
+++ b/libstdc++-v3/include/std/chrono
@@ -0,0 +1,628 @@
+// <chrono> -*- C++ -*-
+
+// Copyright (C) 2008 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 2, 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 COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301, USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+/** @file include/chrono
+ * This is a Standard C++ Library header.
+ */
+
+#ifndef _GLIBCXX_CHRONO
+#define _GLIBCXX_CHRONO 1
+
+#pragma GCC system_header
+
+#ifndef __GXX_EXPERIMENTAL_CXX0X__
+# include <c++0x_warning.h>
+#else
+
+#ifdef _GLIBCXX_INCLUDE_AS_TR1
+# error C++0x header cannot be included from TR1 header
+#endif
+
+#include <ratio>
+#include <type_traits>
+#include <limits>
+#include <ctime>
+
+#ifdef _GLIBCXX_USE_C99_STDINT_TR1
+
+namespace std
+{
+ namespace chrono
+ {
+ template<typename _Rep, typename _Period = ratio<1>>
+ struct duration;
+
+ template<typename _Clock, typename _Duration = typename _Clock::duration>
+ struct time_point;
+ }
+
+ // 20.8.2.3 specialization of common_type (for duration)
+ template<typename _Rep1, typename _Period1, typename _Rep2, typename _Period2>
+ struct common_type<chrono::duration<_Rep1, _Period1>,
+ chrono::duration<_Rep2, _Period2>>
+ {
+ typedef chrono::duration<typename common_type<_Rep1, _Rep2>::type,
+ ratio<__static_gcd<_Period1::num, _Period2::num>::value,
+ (_Period1::den / __static_gcd<_Period1::den, _Period2::den>::value)
+ * _Period2::den>> type;
+ };
+
+ // 20.8.2.3 specialization of common_type (for time_point)
+ template<typename _Clock, typename _Duration1, typename _Duration2>
+ struct common_type<chrono::time_point<_Clock, _Duration1>,
+ chrono::time_point<_Clock, _Duration2>>
+ {
+ typedef chrono::time_point<_Clock,
+ typename common_type<_Duration1, _Duration2>::type> type;
+ };
+
+ namespace chrono
+ {
+ // primary template for duration_cast impl.
+ template<typename _ToDuration, typename _CF, typename _CR,
+ bool _NumIsOne = false, bool _DenIsOne = false>
+ struct __duration_cast_impl
+ {
+ template<typename _Rep, typename _Period>
+ static _ToDuration __cast(const duration<_Rep, _Period>& __d)
+ {
+ return _ToDuration(static_cast<
+ typename _ToDuration::rep>(static_cast<_CR>(__d.count())
+ * static_cast<_CR>(_CF::num)
+ / static_cast<_CR>(_CF::den)));
+ }
+ };
+
+ template<typename _ToDuration, typename _CF, typename _CR>
+ struct __duration_cast_impl<_ToDuration, _CF, _CR, true, true>
+ {
+ template<typename _Rep, typename _Period>
+ static _ToDuration __cast(const duration<_Rep, _Period>& __d)
+ {
+ return _ToDuration(
+ static_cast<typename _ToDuration::rep>(__d.count()));
+ }
+ };
+
+ template<typename _ToDuration, typename _CF, typename _CR>
+ struct __duration_cast_impl<_ToDuration, _CF, _CR, true, false>
+ {
+ template<typename _Rep, typename _Period>
+ static _ToDuration __cast(const duration<_Rep, _Period>& __d)
+ {
+ return _ToDuration(static_cast<typename _ToDuration::rep>(
+ static_cast<_CR>(__d.count()) / static_cast<_CR>(_CF::den)));
+ }
+ };
+
+ template<typename _ToDuration, typename _CF, typename _CR>
+ struct __duration_cast_impl<_ToDuration, _CF, _CR, false, true>
+ {
+ template<typename _Rep, typename _Period>
+ static _ToDuration __cast(const duration<_Rep, _Period>& __d)
+ {
+ return _ToDuration(static_cast<typename _ToDuration::rep>(
+ static_cast<_CR>(__d.count()) * static_cast<_CR>(_CF::num)));
+ }
+ };
+
+ template<typename _ToDuration, typename _Rep, typename _Period>
+ inline _ToDuration
+ duration_cast(const duration<_Rep, _Period>& __d)
+ {
+ typedef typename
+ ratio_divide<_Period, typename _ToDuration::period>::type __cf;
+ typedef typename
+ common_type<typename _ToDuration::rep, _Rep, intmax_t>::type __cr;
+
+ return __duration_cast_impl<_ToDuration, __cf, __cr,
+ __cf::num == 1, __cf::den == 1>::__cast(__d);
+ }
+
+ template<typename _Rep>
+ struct treat_as_floating_point
+ : is_floating_point<_Rep>
+ { };
+
+ template<typename _Rep>
+ struct duration_values
+ {
+ static const _Rep
+ zero()
+ { return _Rep(0); }
+
+ static const _Rep
+ max()
+ { return numeric_limits<_Rep>::max(); }
+
+ static const _Rep
+ min()
+ { return numeric_limits<_Rep>::min(); }
+ };
+
+ /// duration
+ template<typename _Rep, typename _Period>
+ struct duration
+ {
+ static_assert(_Period::num > 0, "period must be positive");
+
+ typedef _Rep rep;
+ typedef _Period period;
+
+ // construction / destruction
+ duration ()
+ : __r(rep(0))
+ { }
+
+ template<typename _Rep2>
+ explicit duration(_Rep2 const& __rep)
+ : __r(static_cast<rep>(__rep))
+ {
+ static_assert(is_convertible<_Rep2,rep>::value == true
+ && (treat_as_floating_point<rep>::value == true
+ || (!treat_as_floating_point<rep>::value
+ && !treat_as_floating_point<_Rep2>::value)),
+ "cannot construct integral duration with floating point type");
+ }
+
+ duration(const duration& __d)
+ : __r(__d.count())
+ { }
+
+ // conversions
+ template<typename _Rep2, typename _Period2>
+ duration(const duration<_Rep2, _Period2>& __d)
+ : __r(duration_cast<duration>(__d).count())
+ {
+ static_assert(treat_as_floating_point<rep>::value == true
+ || ratio_divide<_Period2, period>::type::den == 1,
+ "the resulting duration is not exactly representable");
+ }
+
+ // observer
+ rep
+ count() const
+ { return __r; }
+
+ // arithmetic
+ duration
+ operator+() const
+ { return *this; }
+
+ duration
+ operator-() const
+ { return duration(-__r); }
+
+ duration&
+ operator++()
+ {
+ ++__r;
+ return *this;
+ }
+
+ duration
+ operator++(int)
+ { return duration(__r++); }
+
+ duration&
+ operator--()
+ {
+ --__r;
+ return *this;
+ }
+
+ duration
+ operator--(int)
+ { return duration(__r--); }
+
+ duration&
+ operator+=(const duration& __d)
+ {
+ __r += __d.count();
+ return *this;
+ }
+
+ duration&
+ operator-=(const duration& __d)
+ {
+ __r -= __d.count();
+ return *this;
+ }
+
+ duration&
+ operator*=(const rep& __rhs)
+ {
+ __r *= __rhs;
+ return *this;
+ }
+
+ duration&
+ operator/=(const rep& __rhs)
+ {
+ __r /= __rhs;
+ return *this;
+ }
+
+ // special values
+ // TODO: These should be constexprs.
+ static const duration
+ zero()
+ { return duration(duration_values<rep>::zero()); }
+
+ static const duration
+ min()
+ { return duration(duration_values<rep>::min()); }
+
+ static const duration
+ max()
+ { return duration(duration_values<rep>::max()); }
+
+ private:
+ rep __r;
+ };
+
+ template<typename _Rep1, typename _Period1,
+ typename _Rep2, typename _Period2>
+ inline typename common_type<duration<_Rep1, _Period1>,
+ duration<_Rep2, _Period2>>::type
+ operator+(const duration<_Rep1, _Period1>& __lhs,
+ const duration<_Rep2, _Period2>& __rhs)
+ {
+ typedef typename common_type<duration<_Rep1, _Period1>,
+ duration<_Rep2, _Period2>>::type __ct;
+ return __ct(__lhs) += __rhs;
+ }
+
+ template<typename _Rep1, typename _Period1,
+ typename _Rep2, typename _Period2>
+ inline typename common_type<duration<_Rep1, _Period1>,
+ duration<_Rep2, _Period2>>::type
+ operator-(const duration<_Rep1, _Period1>& __lhs,
+ const duration<_Rep2, _Period2>& __rhs)
+ {
+ typedef typename common_type<duration<_Rep1, _Period1>,
+ duration<_Rep2, _Period2>>::type __ct;
+ return __ct(__lhs) -= __rhs;
+ }
+
+ template<typename _Rep1, typename _Period, typename _Rep2>
+ inline duration<typename common_type<_Rep1, _Rep2>::type, _Period>
+ operator*(const duration<_Rep1, _Period>& __d, const _Rep2& __s)
+ {
+ typedef typename common_type<_Rep1, _Rep2>::type __cr;
+ return duration<__cr, _Period>(__d) *= __s;
+ }
+
+ template<typename _Rep1, typename _Period, typename _Rep2>
+ inline duration<typename common_type<_Rep1, _Rep2>::type, _Period>
+ operator*(const _Rep2& __s, const duration<_Rep1, _Period>& __d)
+ { return __d * __s; }
+
+ template<typename _Tp>
+ struct __is_not_duration
+ : std::true_type
+ { };
+
+ template<typename _Rep, typename _Period>
+ struct __is_not_duration<duration<_Rep, _Period>>
+ : std::false_type
+ { };
+
+ template<typename _Tp, typename _Up, typename _Ep = void>
+ struct __division_impl;
+
+ template<typename _Rep1, typename _Period, typename _Rep2>
+ struct __division_impl<duration<_Rep1, _Period>, _Rep2,
+ typename enable_if<__is_not_duration<_Rep2>::value>::type>
+ {
+ typedef typename common_type<_Rep1, _Rep2>::type __cr;
+ typedef
+ duration<typename common_type<_Rep1, _Rep2>::type, _Period> __rt;
+
+ static __rt
+ __divide(const duration<_Rep1, _Period>& __d, const _Rep2& __s)
+ { return duration<__cr, _Period>(__d) /= __s; }
+ };
+
+ template<typename _Rep1, typename _Period1,
+ typename _Rep2, typename _Period2>
+ struct __division_impl<duration<_Rep1, _Period1>,
+ duration<_Rep2, _Period2>>
+ {
+ typedef typename common_type<duration<_Rep1, _Period1>,
+ duration<_Rep2, _Period2>>::type __ct;
+ typedef typename common_type<_Rep1, _Rep2>::type __rt;
+
+ static __rt
+ __divide(const duration<_Rep1, _Period1>& __lhs,
+ const duration<_Rep2, _Period2>& __rhs)
+ { return __ct(__lhs).count() / __ct(__rhs).count(); }
+ };
+
+ template<typename _Rep, typename _Period, typename _Up>
+ inline typename __division_impl<duration<_Rep, _Period>, _Up>::__rt
+ operator/(const duration<_Rep, _Period>& __d, const _Up& __u)
+ {
+ return
+ __division_impl<duration<_Rep, _Period>, _Up>::__divide(__d, __u);
+ }
+
+ // comparisons
+ template<typename _Rep1, typename _Period1,
+ typename _Rep2, typename _Period2>
+ inline bool
+ operator==(const duration<_Rep1, _Period1>& __lhs,
+ const duration<_Rep2, _Period2>& __rhs)
+ {
+ typedef typename common_type<duration<_Rep1, _Period1>,
+ duration<_Rep2, _Period2>>::type __ct;
+ return __ct(__lhs).count() == __ct(__rhs).count();
+ }
+
+ template<typename _Rep1, typename _Period1,
+ typename _Rep2, typename _Period2>
+ inline bool
+ operator<(const duration<_Rep1, _Period1>& __lhs,
+ const duration<_Rep2, _Period2>& __rhs)
+ {
+ typedef typename common_type<duration<_Rep1, _Period1>,
+ duration<_Rep2, _Period2>>::type __ct;
+ return __ct(__lhs).count() < __ct(__rhs).count();
+ }
+
+ template<typename _Rep1, typename _Period1,
+ typename _Rep2, typename _Period2>
+ inline bool
+ operator!=(const duration<_Rep1, _Period1>& __lhs,
+ const duration<_Rep2, _Period2>& __rhs)
+ { return !(__lhs == __rhs); }
+
+ template<typename _Rep1, typename _Period1,
+ typename _Rep2, typename _Period2>
+ inline bool
+ operator<=(const duration<_Rep1, _Period1>& __lhs,
+ const duration<_Rep2, _Period2>& __rhs)
+ { return !(__rhs < __lhs); }
+
+ template<typename _Rep1, typename _Period1,
+ typename _Rep2, typename _Period2>
+ inline bool
+ operator>(const duration<_Rep1, _Period1>& __lhs,
+ const duration<_Rep2, _Period2>& __rhs)
+ { return __rhs < __lhs; }
+
+ template<typename _Rep1, typename _Period1,
+ typename _Rep2, typename _Period2>
+ inline bool
+ operator>=(const duration<_Rep1, _Period1>& __lhs,
+ const duration<_Rep2, _Period2>& __rhs)
+ { return !(__lhs < __rhs); }
+
+ typedef duration<int64_t, nano> nanoseconds;
+ typedef duration<int64_t, micro> microseconds;
+ typedef duration<int64_t, milli> milliseconds;
+ typedef duration<int64_t > seconds;
+ typedef duration<int, ratio< 60>> minutes;
+ typedef duration<int, ratio<3600>> hours;
+
+ /// time_point
+ template<typename _Clock, typename _Duration>
+ struct time_point
+ {
+ typedef _Clock clock;
+ typedef _Duration duration;
+ typedef typename duration::rep rep;
+ typedef typename duration::period period;
+
+ time_point() : __d(duration::zero())
+ { }
+
+ explicit time_point(const duration& __dur)
+ : __d(duration::zero() + __dur)
+ { }
+
+ // conversions
+ template<typename _Duration2>
+ time_point(const time_point<clock, _Duration2>& __t)
+ : __d(__t.time_since_epoch())
+ { }
+
+ // observer
+ duration
+ time_since_epoch() const
+ { return __d; }
+
+ // arithmetic
+ time_point&
+ operator+=(const duration& __dur)
+ {
+ __d += __dur;
+ return *this;
+ }
+
+ time_point&
+ operator-=(const duration& __dur)
+ {
+ __d -= __dur;
+ return *this;
+ }
+
+ // special values
+ // TODO: These should be constexprs.
+ static const time_point
+ min()
+ { return time_point(duration::min()); }
+
+ static const time_point
+ max()
+ { return time_point(duration::max()); }
+
+ private:
+ duration __d;
+ };
+
+ template<typename _ToDuration, typename _Clock, typename _Duration>
+ inline time_point<_Clock, _ToDuration>
+ time_point_cast(const time_point<_Clock, _Duration>& __t)
+ {
+ return time_point<_Clock, _ToDuration>(
+ duration_cast<_ToDuration>(__t.time_since_epoch()));
+ }
+
+ template<typename _Clock, typename _Duration1,
+ typename _Rep2, typename _Period2>
+ inline time_point<_Clock,
+ typename common_type<_Duration1, duration<_Rep2, _Period2>>::type>
+ operator+(const time_point<_Clock, _Duration1>& __lhs,
+ const duration<_Rep2, _Period2>& __rhs)
+ {
+ typedef time_point<_Clock,
+ typename common_type<_Duration1,
+ duration<_Rep2, _Period2>>::type> __ct;
+ return __ct(__lhs) += __rhs;
+ }
+
+ template<typename _Rep1, typename _Period1,
+ typename _Clock, typename _Duration2>
+ inline time_point<_Clock,
+ typename common_type<duration<_Rep1, _Period1>, _Duration2>::type>
+ operator+(const duration<_Rep1, _Period1>& __lhs,
+ const time_point<_Clock, _Duration2>& __rhs)
+ { return __rhs + __lhs; }
+
+ template<typename _Clock, typename _Duration1,
+ typename _Rep2, typename _Period2>
+ inline time_point<_Clock,
+ typename common_type<_Duration1, duration<_Rep2, _Period2>>::type>
+ operator-(const time_point<_Clock, _Duration1>& __lhs,
+ const duration<_Rep2, _Period2>& __rhs)
+ { return __lhs + (-__rhs); }
+
+ template<typename _Clock, typename _Duration1, typename _Duration2>
+ inline typename common_type<_Duration1, _Duration2>::type
+ operator-(const time_point<_Clock, _Duration1>& __lhs,
+ const time_point<_Clock, _Duration2>& __rhs)
+ { return __lhs.time_since_epoch() - __rhs.time_since_epoch(); }
+
+ template<typename _Clock, typename _Duration1, typename _Duration2>
+ inline bool
+ operator==(const time_point<_Clock, _Duration1>& __lhs,
+ const time_point<_Clock, _Duration2>& __rhs)
+ { return __lhs.time_since_epoch() == __rhs.time_since_epoch(); }
+
+ template<typename _Clock, typename _Duration1, typename _Duration2>
+ inline bool
+ operator!=(const time_point<_Clock, _Duration1>& __lhs,
+ const time_point<_Clock, _Duration2>& __rhs)
+ { return !(__lhs == __rhs); }
+
+ template<typename _Clock, typename _Duration1, typename _Duration2>
+ inline bool
+ operator<(const time_point<_Clock, _Duration1>& __lhs,
+ const time_point<_Clock, _Duration2>& __rhs)
+ { return __lhs.time_since_epoch() < __rhs.time_since_epoch(); }
+
+ template<typename _Clock, typename _Duration1, typename _Duration2>
+ inline bool
+ operator<=(const time_point<_Clock, _Duration1>& __lhs,
+ const time_point<_Clock, _Duration2>& __rhs)
+ { return !(__rhs < __lhs); }
+
+ template<typename _Clock, typename _Duration1, typename _Duration2>
+ inline bool
+ operator>(const time_point<_Clock, _Duration1>& __lhs,
+ const time_point<_Clock, _Duration2>& __rhs)
+ { return __rhs < __lhs; }
+
+ template<typename _Clock, typename _Duration1, typename _Duration2>
+ inline bool
+ operator>=(const time_point<_Clock, _Duration1>& __lhs,
+ const time_point<_Clock, _Duration2>& __rhs)
+ { return !(__lhs < __rhs); }
+
+ /// system_clock
+ struct system_clock
+ {
+#if defined(_GLIBCXX_USE_CLOCK_MONOTONIC) || \
+ defined(_GLIBCXX_USE_CLOCK_REALTIME)
+ typedef chrono::nanoseconds duration;
+#elif defined(_GLIBCXX_USE_GETTIMEOFDAY)
+ typedef chrono::microseconds duration;
+#else
+ typedef chrono::seconds duration;
+#endif
+
+ typedef duration::rep rep;
+ typedef duration::period period;
+ typedef chrono::time_point<system_clock, duration> time_point;
+
+#ifdef _GLIBCXX_USE_CLOCK_MONOTONIC
+ static const bool is_monotonic = true;
+#else
+ static const bool is_monotonic = false;
+#endif
+
+ static time_point
+ now();
+
+ // Map to C API
+ static std::time_t
+ to_time_t(const time_point& __t)
+ {
+ return std::time_t(
+ duration_cast<chrono::seconds>(__t.time_since_epoch()).count());
+ }
+
+ static time_point
+ from_time_t(std::time_t __t)
+ {
+ return time_point_cast<system_clock::duration>(
+ chrono::time_point<system_clock, chrono::seconds>(
+ chrono::seconds(__t)));
+ }
+
+ // TODO: requires constexpr
+ /*
+ static_assert(
+ system_clock::duration::min() <
+ system_clock::duration::zero(),
+ "a clock's minimum duration cannot be less than its epoch");
+ */
+ };
+
+ typedef system_clock high_resolution_clock;
+ typedef system_clock monotonic_clock;
+ }
+}
+
+#endif //_GLIBCXX_USE_C99_STDINT_TR1
+
+#endif //__GXX_EXPERIMENTAL_CXX0X__
+
+#endif //_GLIBCXX_CHRONO
diff --git a/libstdc++-v3/include/std/complex b/libstdc++-v3/include/std/complex
index c8845f6728c..1c48251e350 100644
--- a/libstdc++-v3/include/std/complex
+++ b/libstdc++-v3/include/std/complex
@@ -29,7 +29,7 @@
// invalidate any other reasons why the executable file might be covered by
// the GNU General Public License.
-/** @file complex
+/** @file include/complex
* This is a Standard C++ Library header.
*/
diff --git a/libstdc++-v3/include/std/condition_variable b/libstdc++-v3/include/std/condition_variable
index 1dfb7789499..1a7a7cd1f37 100644
--- a/libstdc++-v3/include/std/condition_variable
+++ b/libstdc++-v3/include/std/condition_variable
@@ -44,8 +44,14 @@
namespace std
{
- // XXX
- class system_time;
+ namespace chrono
+ {
+ template<typename _Rep, typename _Period>
+ struct duration;
+
+ template<typename _Clock, typename _Duration>
+ struct time_point;
+ }
/// condition_variable
class condition_variable
@@ -78,22 +84,27 @@ namespace std
wait(__lock);
}
- template<typename _Duration>
- bool
- timed_wait(unique_lock<mutex>& __lock, const _Duration& __rtime);
-
- bool
- timed_wait(unique_lock<mutex>& __lock, const system_time& __atime);
-
- template<typename _Predicate>
- bool
- timed_wait(unique_lock<mutex>& __lock, const system_time& __atime,
- _Predicate pred);
-
- template<typename _Duration, typename _Predicate>
+ template<typename _Clock, typename _Duration>
bool
- timed_wait(unique_lock<mutex>& __lock, const _Duration& __rtime,
- _Predicate pred);
+ wait_until(unique_lock<mutex>& __lock,
+ const chrono::time_point<_Clock, _Duration>& __atime);
+
+ template<typename _Clock, typename _Duration, typename _Predicate>
+ bool
+ wait_until(unique_lock<mutex>& __lock,
+ const chrono::time_point<_Clock, _Duration>& __atime,
+ _Predicate __p);
+
+ template<typename _Rep, typename _Period>
+ bool
+ wait_for(unique_lock<mutex>& __lock,
+ const chrono::duration<_Rep, _Period>& __rtime);
+
+ template<typename _Rep, typename _Period, typename _Predicate>
+ bool
+ wait_for(unique_lock<mutex>& __lock,
+ const chrono::duration<_Rep, _Period>& __rtime,
+ _Predicate __p);
native_handle_type
native_handle() { return _M_cond; }
@@ -132,21 +143,27 @@ namespace std
void
wait(_Lock& __lock, _Predicate __p);
- template<typename _Lock>
- bool
- timed_wait(_Lock& __lock, const system_time& __atime);
-
- template<typename _Lock, typename _Duration>
- bool
- timed_wait(_Lock& __lock, const _Duration& __rtime);
-
- template<typename _Lock, typename _Predicate>
+ template<typename _Lock, typename _Clock, typename _Duration>
bool
- timed_wait(_Lock& __lock, const system_time& __atime, _Predicate __p);
+ wait_until(_Lock& __lock,
+ const chrono::time_point<_Clock, _Duration>& __atime);
- template<typename _Lock, typename _Duration, typename _Predicate>
+ template<typename _Lock, typename _Clock,
+ typename _Duration, typename _Predicate>
bool
- timed_wait(_Lock& __lock, const _Duration& __rtime, _Predicate __p);
+ wait_until(_Lock& __lock,
+ const chrono::time_point<_Clock, _Duration>& __atime,
+ _Predicate __p);
+
+ template<typename _Lock, typename _Rep, typename _Period>
+ bool
+ wait_for(_Lock& __lock, const chrono::duration<_Rep, _Period>& __rtime);
+
+ template<typename _Lock, typename _Rep,
+ typename _Period, typename _Predicate>
+ bool
+ wait_for(_Lock& __lock,
+ const chrono::duration<_Rep, _Period>& __rtime, _Predicate __p);
native_handle_type
native_handle() { return _M_cond; }
diff --git a/libstdc++-v3/include/std/date_time b/libstdc++-v3/include/std/date_time
deleted file mode 100644
index 2ad95169715..00000000000
--- a/libstdc++-v3/include/std/date_time
+++ /dev/null
@@ -1,245 +0,0 @@
-// <date_time> -*- C++ -*-
-
-// Copyright (C) 2008 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 2, 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 COPYING. If not, write to
-// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
-// Boston, MA 02110-1301, USA.
-
-// As a special exception, you may use this file as part of a free software
-// library without restriction. Specifically, if other files instantiate
-// templates or use macros or inline functions from this file, or you compile
-// this file and link it with other files to produce an executable, this
-// file does not by itself cause the resulting executable to be covered by
-// the GNU General Public License. This exception does not however
-// invalidate any other reasons why the executable file might be covered by
-// the GNU General Public License.
-
-/** @file date_time
- * This is a Standard C++ Library header.
- */
-
-#ifndef _GLIBCXX_DATE_TIME
-#define _GLIBCXX_DATE_TIME 1
-
-#pragma GCC system_header
-
-#ifndef __GXX_EXPERIMENTAL_CXX0X__
-# include <c++0x_warning.h>
-#else
-
-#include <ctime>
-
-namespace std
-{
- // duration types
-
- /// nanoseconds
- class nanoseconds
- {
- public:
-
- // traits information
- typedef long long tick_type;
- static const tick_type ticks_per_second = 1000L * 1000 * 1000;
- static const tick_type seconds_per_tick = 0;
- static const bool is_subsecond = true;
-
- // construct/copy/destroy
- nanoseconds(long long __ns = 0) : _M_ns(__ns) { }
-
- // modifiers
- template<typename _RhsDuration>
- nanoseconds&
- operator+=(const _RhsDuration& __d);
-
- template<typename _RhsDuration>
- nanoseconds&
- operator-=(const _RhsDuration& __d);
-
- nanoseconds&
- operator*=(long __multiplier);
-
- nanoseconds&
- operator/=(long __divisor);
-
- // observers
- tick_type count() const { return _M_ns; }
-
- // operations
- nanoseconds operator-() const { return nanoseconds(-_M_ns); }
-
- private:
- tick_type _M_ns;
- };
-
- class microseconds;
- class milliseconds;
- class seconds;
- class minutes;
- class hours;
-
- /// timepoint type
- class system_time
- {
- public:
-
- // traits information
- typedef nanoseconds::tick_type tick_type;
- static const tick_type ticks_per_second = nanoseconds::ticks_per_second;
- static const tick_type seconds_per_tick = 0;
- static const bool is_subsecond = true;
-
- // create/copy/destroy
-
- system_time() : _M_sec(0), _M_nsec(0) { }
-
- explicit system_time(time_t __s, nanoseconds __ns = 0)
- : _M_sec(__s), _M_nsec(__ns.count()) { }
-
- time_t
- seconds_since_epoch() const { return _M_sec; }
-
- nanoseconds
- nanoseconds_since_epoch() const
- {
- return nanoseconds(_M_nsec + _M_sec * ticks_per_second);
- }
-
- // comparison functions
-
- bool
- operator==(const system_time& __rhs) const
- {
- const tick_type __ns = _M_nsec + _M_sec * ticks_per_second;
- const tick_type __xns = __rhs._M_nsec + __rhs._M_sec * ticks_per_second;
- return __ns == __xns;
- }
-
- bool
- operator!=(const system_time& __rhs) const
- {
- return !(*this == __rhs);
- }
-
- bool
- operator<(const system_time& __rhs) const
- {
- const tick_type __ns = _M_nsec + _M_sec * ticks_per_second;
- const tick_type __xns = __rhs._M_nsec + __rhs._M_sec * ticks_per_second;
- return __ns < __xns;
- }
-
- bool
- operator<=(const system_time& __rhs) const
- {
- return !(__rhs < *this);
- }
-
- bool
- operator>(const system_time& __rhs) const
- {
- return __rhs < *this;
- }
-
- bool
- operator>=(const system_time& __rhs) const
- {
- return !(*this < __rhs);
- }
-
- // arithmetic functions
- nanoseconds
- operator-(const system_time& __rhs) const
- {
- const tick_type __ns = _M_nsec + _M_sec * ticks_per_second;
- const tick_type __xns = __rhs._M_nsec + __rhs._M_sec * ticks_per_second;
- return nanoseconds(__ns - __xns);
- }
-
- template<typename _Duration>
- system_time
- operator+(const _Duration& __td) const;
-
- template<typename _Duration>
- system_time&
- operator+=(const _Duration& __td);
-
- template<typename _Duration>
- system_time
- operator-(const _Duration& __td) const;
-
- template<typename _Duration>
- system_time&
- operator-=(const _Duration& __td);
-
- public:
- std::time_t _M_sec;
- tick_type _M_nsec;
- };
-
- // non-member functions
- system_time
- get_system_time();
-
- template<typename _Duration>
- system_time
- operator+(const _Duration& __td, const system_time& __rhs);
-
- template<class _LhsDuration, class _RhsDuration>
- bool
- operator==(const _LhsDuration& __lhs, const _RhsDuration& __rhs);
- template<class _LhsDuration, class _RhsDuration>
- bool
- operator!=(const _LhsDuration& __lhs, const _RhsDuration& __rhs);
-
- template<class _LhsDuration, class _RhsDuration>
- bool
- operator<(const _LhsDuration& __lhs, const _RhsDuration& __rhs);
- template<class _LhsDuration, class _RhsDuration>
- bool
- operator<=(const _LhsDuration& __lhs, const _RhsDuration& __rhs);
- template<class _LhsDuration, class _RhsDuration>
- bool
- operator>(const _LhsDuration& __lhs, const _RhsDuration& __rhs);
- template<class _LhsDuration, class _RhsDuration>
- bool
- operator>=(const _LhsDuration& __lhs, const _RhsDuration& __rhs);
-
- template<typename _LhsDuration, typename _RhsDuration>
- struct __finest_duration;
-
- template<class _LhsDuration, class _RhsDuration>
- typename __finest_duration<_LhsDuration, _RhsDuration>::type
- operator+(const _LhsDuration& __lhs, const _RhsDuration& __rhs);
- template<class _LhsDuration, class _RhsDuration>
- typename __finest_duration<_LhsDuration, _RhsDuration>::type
- operator-(const _LhsDuration& __lhs, const _RhsDuration& __rhs);
-
- template<class _Duration>
- _Duration
- operator*(_Duration __lhs, long __rhs);
- template<class _Duration>
- _Duration
- operator*(long __lhs, _Duration __rhs);
-
- template<class _Duration>
- _Duration
- operator/(_Duration __lhs, long __rhs);
-}
-
-#endif // __GXX_EXPERIMENTAL_CXX0X__
-
-#endif // _GLIBCXX_DATE_TIME
diff --git a/libstdc++-v3/include/std/mutex b/libstdc++-v3/include/std/mutex
index 5d4e52105f8..779394a5891 100644
--- a/libstdc++-v3/include/std/mutex
+++ b/libstdc++-v3/include/std/mutex
@@ -48,8 +48,14 @@
namespace std
{
- // XXX
- class system_time;
+ namespace chrono
+ {
+ template<typename _Rep, typename _Period>
+ struct duration;
+
+ template<typename _Clock, typename _Duration>
+ struct time_point;
+ }
/// mutex
class mutex
@@ -74,22 +80,22 @@ namespace std
int __e = __gthread_mutex_lock(&_M_mutex);
// EINVAL, EAGAIN, EBUSY, EINVAL, EDEADLK(may)
- if (__e)
- __throw_system_error(__e);
+ if (__e)
+ __throw_system_error(__e);
}
bool
try_lock()
{
- // XXX EINVAL, EAGAIN, EBUSY
- return !__gthread_mutex_trylock(&_M_mutex);
+ // XXX EINVAL, EAGAIN, EBUSY
+ return !__gthread_mutex_trylock(&_M_mutex);
}
void
unlock()
{
// XXX EINVAL, EAGAIN, EPERM
- __gthread_mutex_unlock(&_M_mutex);
+ __gthread_mutex_unlock(&_M_mutex);
}
native_handle_type
@@ -102,7 +108,6 @@ namespace std
mutex& operator=(const mutex&);
};
-
/// recursive_mutex
class recursive_mutex
{
@@ -120,15 +125,14 @@ namespace std
#endif
}
-
void
lock()
{
int __e = __gthread_recursive_mutex_lock(&_M_mutex);
// EINVAL, EAGAIN, EBUSY, EINVAL, EDEADLK(may)
- if (__e)
- __throw_system_error(__e);
+ if (__e)
+ __throw_system_error(__e);
}
bool
@@ -146,7 +150,8 @@ namespace std
}
native_handle_type
- native_handle() { return _M_mutex; }
+ native_handle()
+ { return _M_mutex; }
private:
native_handle_type _M_mutex;
@@ -155,9 +160,65 @@ namespace std
recursive_mutex& operator=(const recursive_mutex&);
};
+ /// timed_mutex
+ class timed_mutex
+ {
+ public:
+ typedef __gthread_mutex_t native_handle_type;
+
+ void lock();
+ bool try_lock();
+
+ template <class _Rep, class _Period>
+ bool
+ try_lock_for(const chrono::duration<_Rep, _Period>& __rtime);
+
+ template <class _Clock, class _Duration>
+ bool
+ try_lock_until(const chrono::time_point<_Clock, _Duration>& __atime);
+
+ void unlock();
+
+ native_handle_type
+ native_handle()
+ { return _M_mutex; }
+
+ private:
+ native_handle_type _M_mutex;
+
+ timed_mutex(const timed_mutex&);
+ timed_mutex& operator=(const timed_mutex&);
+ };
+
+ /// recursive_timed_mutex
+ class recursive_timed_mutex
+ {
+ public:
+ typedef __gthread_mutex_t native_handle_type;
+
+ void lock();
+ bool try_lock();
+
+ template <class _Rep, class _Period>
+ bool
+ try_lock_for(const chrono::duration<_Rep, _Period>& __rtime);
+
+ template <class _Clock, class _Duration>
+ bool
+ try_lock_until(const chrono::time_point<_Clock, _Duration>& __atime);
+
+ void unlock();
+
+ native_handle_type
+ native_handle()
+ { return _M_mutex; }
+
+ private:
+ native_handle_type _M_mutex;
- // class timed_mutex;
- // class recursive_timed_mutex;
+ recursive_timed_mutex(const recursive_timed_mutex&);
+ recursive_timed_mutex& operator=(const recursive_timed_mutex&);
+ };
/// Do not acquire ownership of the mutex.
struct defer_lock_t { };
@@ -212,19 +273,24 @@ namespace std
public:
typedef _Mutex mutex_type;
- unique_lock() : _M_device(NULL), _M_owns(false) { }
+ unique_lock()
+ : _M_device(NULL), _M_owns(false)
+ { }
- explicit unique_lock(mutex_type& __m) : _M_device(&__m)
+ explicit unique_lock(mutex_type& __m)
+ : _M_device(&__m)
{
lock();
_M_owns = true;
}
unique_lock(mutex_type& __m, defer_lock_t)
- : _M_device(&__m), _M_owns(false) { }
+ : _M_device(&__m), _M_owns(false)
+ { }
unique_lock(mutex_type& __m, try_to_lock_t)
- : _M_device(&__m), _M_owns(_M_device->try_lock()) { }
+ : _M_device(&__m), _M_owns(_M_device->try_lock())
+ { }
unique_lock(mutex_type& __m, adopt_lock_t)
: _M_device(&__m), _M_owns(true)
@@ -232,10 +298,13 @@ namespace std
// XXX calling thread owns mutex
}
- unique_lock(mutex_type& __m, const system_time& abs_time);
+ template<typename _Clock, typename _Duration>
+ unique_lock(mutex_type& __m,
+ const chrono::time_point<_Clock, _Duration>& __atime);
- template<typename _Duration>
- unique_lock(mutex_type& __m, const _Duration& rel_time);
+ template<typename _Rep, typename _Period>
+ unique_lock(mutex_type& __m,
+ const chrono::duration<_Rep, _Period>& __rtime);
~unique_lock()
{
@@ -247,7 +316,6 @@ namespace std
unique_lock& operator=(unique_lock&&);
-
void
lock()
{
@@ -277,12 +345,13 @@ namespace std
throw lock_error();
}
+ template<typename _Rep, typename _Period>
+ bool
+ try_lock_for(const chrono::duration<_Rep, _Period>& __rtime);
- template<typename _Duration>
- bool timed_lock(const _Duration& rel_time);
-
- bool
- timed_lock(const system_time& abs_time);
+ template<typename _Clock, typename _Duration>
+ bool
+ try_lock_until(const chrono::time_point<_Clock, _Duration>& __atime);
void
swap(unique_lock&& __u);
@@ -297,9 +366,11 @@ namespace std
}
bool
- owns_lock() const { return _M_owns; }
+ owns_lock() const
+ { return _M_owns; }
- operator bool () const { return owns_lock(); }
+ operator bool () const
+ { return owns_lock(); }
mutex_type*
mutex() const
diff --git a/libstdc++-v3/include/std/ratio b/libstdc++-v3/include/std/ratio
new file mode 100644
index 00000000000..124e9af397a
--- /dev/null
+++ b/libstdc++-v3/include/std/ratio
@@ -0,0 +1,298 @@
+// <ratio> -*- C++ -*-
+
+// Copyright (C) 2008 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 2, 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 COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301, USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+/** @file ratio
+ * This is a Standard C++ Library header.
+ */
+
+#ifndef _GLIBCXX_RATIO
+#define _GLIBCXX_RATIO 1
+
+#pragma GCC system_header
+
+#ifndef __GXX_EXPERIMENTAL_CXX0X__
+# include <c++0x_warning.h>
+#else
+
+#include <type_traits>
+#include <cstdint>
+
+#ifdef _GLIBCXX_USE_C99_STDINT_TR1
+
+namespace std
+{
+ template<intmax_t _Pn>
+ struct __static_sign
+ : integral_constant<intmax_t, (_Pn < 0) ? -1 : 1>
+ { };
+
+ template<intmax_t _Pn>
+ struct __static_abs
+ : integral_constant<intmax_t, _Pn * __static_sign<_Pn>::value>
+ { };
+
+ template<intmax_t _Pn, intmax_t _Qn>
+ struct __static_gcd;
+
+ template<intmax_t _Pn, intmax_t _Qn>
+ struct __static_gcd
+ : __static_gcd<_Qn, (_Pn % _Qn)>
+ { };
+
+ template<intmax_t _Pn>
+ struct __static_gcd<_Pn, 0>
+ : integral_constant<intmax_t, __static_abs<_Pn>::value>
+ { };
+
+ template<intmax_t _Qn>
+ struct __static_gcd<0, _Qn>
+ : integral_constant<intmax_t, __static_abs<_Qn>::value>
+ { };
+
+ // Let c = 2^(half # of bits in an intmax_t)
+ // then we find a1, a0, b1, b0 s.t. N = a1*c + a0, M = b1*c + b0
+ // The multiplication of N and M becomes,
+ // N * M = (a1 * b1)c^2 + (a0 * b1 + b0 * a1)c + a0 * b0
+ // Multiplication is safe if each term and the sum of the terms
+ // is representable by intmax_t.
+ template<intmax_t _Pn, intmax_t _Qn>
+ struct __safe_multiply
+ {
+ private:
+ static const uintmax_t __c = uintmax_t(1) << (sizeof(intmax_t) * 4);
+
+ static const uintmax_t __a0 = __static_abs<_Pn>::value % __c;
+ static const uintmax_t __a1 = __static_abs<_Pn>::value / __c;
+ static const uintmax_t __b0 = __static_abs<_Qn>::value % __c;
+ static const uintmax_t __b1 = __static_abs<_Qn>::value / __c;
+
+ static_assert(__a1 == 0 || __b1 == 0,
+ "overflow in multiplication");
+ static_assert(__a0 * __b1 + __b0 * __a1 < (__c >> 1),
+ "overflow in multiplication");
+ static_assert(__b0 * __a0 <= __INTMAX_MAX__,
+ "overflow in multiplication");
+ static_assert((__a0 * __b1 + __b0 * __a1) * __c <=
+ __INTMAX_MAX__ - __b0 * __a0, "overflow in multiplication");
+
+ public:
+ static const intmax_t value = _Pn * _Qn;
+ };
+
+ // Helpers for __safe_add
+ template<intmax_t _Pn, intmax_t _Qn, bool>
+ struct __add_overflow_check_impl
+ : integral_constant<bool, (_Pn <= __INTMAX_MAX__ - _Qn)>
+ { };
+
+ template<intmax_t _Pn, intmax_t _Qn>
+ struct __add_overflow_check_impl<_Pn, _Qn, false>
+ : integral_constant<bool, (_Pn >= -__INTMAX_MAX__ - _Qn)>
+ { };
+
+ template<intmax_t _Pn, intmax_t _Qn>
+ struct __add_overflow_check
+ : __add_overflow_check_impl<_Pn, _Qn, (_Qn >= 0)>
+ { };
+
+ template<intmax_t _Pn, intmax_t _Qn>
+ struct __safe_add
+ {
+ static_assert(__add_overflow_check<_Pn, _Qn>::value != 0,
+ "overflow in addition");
+
+ static const intmax_t value = _Pn + _Qn;
+ };
+
+ /**
+ * @brief Provides compile-time rational arithmetic.
+ *
+ * This class template represents any finite rational number with a
+ * numerator and denominator representable by compile-time constants of
+ * type intmax_t. The ratio is simplified when instantiated.
+ *
+ * For example:
+ * @code
+ * std::ratio<7,-21>::num == -1;
+ * std::ratio<7,-21>::den == 3;
+ * @endcode
+ *
+ */
+ template<intmax_t _Num, intmax_t _Den = 1>
+ struct ratio
+ {
+ static_assert(_Den != 0, "denominator cannot be zero");
+ static_assert(_Num >= -__INTMAX_MAX__ && _Den >= -__INTMAX_MAX__,
+ "out of range");
+
+ // Note: sign(N) * abs(N) == N
+ static const intmax_t num =
+ _Num * __static_sign<_Den>::value / __static_gcd<_Num, _Den>::value;
+
+ static const intmax_t den =
+ __static_abs<_Den>::value / __static_gcd<_Num, _Den>::value;
+ };
+
+ template<intmax_t _Num, intmax_t _Den>
+ const intmax_t ratio<_Num, _Den>::num;
+
+ template<intmax_t _Num, intmax_t _Den>
+ const intmax_t ratio<_Num, _Den>::den;
+
+ /// ratio_add
+ template<typename _R1, typename _R2>
+ struct ratio_add
+ {
+ private:
+ static const intmax_t __gcd =
+ __static_gcd<_R1::den, _R2::den>::value;
+
+ public:
+ typedef ratio<
+ __safe_add<
+ __safe_multiply<_R1::num, (_R2::den / __gcd)>::value,
+ __safe_multiply<_R2::num, (_R1::den / __gcd)>::value>::value,
+ __safe_multiply<_R1::den, (_R2::den / __gcd)>::value> type;
+ };
+
+ /// ratio_subtract
+ template<typename _R1, typename _R2>
+ struct ratio_subtract
+ {
+ typedef typename ratio_add<
+ _R1,
+ ratio<-_R2::num, _R2::den>>::type type;
+ };
+
+ /// ratio_multiply
+ template<typename _R1, typename _R2>
+ struct ratio_multiply
+ {
+ private:
+ static const intmax_t __gcd1 =
+ __static_gcd<_R1::num, _R2::den>::value;
+ static const intmax_t __gcd2 =
+ __static_gcd<_R2::num, _R1::den>::value;
+
+ public:
+ typedef ratio<
+ __safe_multiply<(_R1::num / __gcd1),
+ (_R2::num / __gcd2)>::value,
+ __safe_multiply<(_R1::den / __gcd2),
+ (_R2::den / __gcd1)>::value> type;
+ };
+
+ /// ratio_divide
+ template<typename _R1, typename _R2>
+ struct ratio_divide
+ {
+ static_assert(_R2::num != 0, "division by 0");
+
+ typedef typename ratio_multiply<
+ _R1,
+ ratio<_R2::den, _R2::num>>::type type;
+ };
+
+ /// ratio_equal
+ template<typename _R1, typename _R2>
+ struct ratio_equal
+ : integral_constant<bool, _R1::num == _R2::num && _R1::den == _R2::den>
+ { };
+
+ /// ratio_not_equal
+ template<typename _R1, typename _R2>
+ struct ratio_not_equal
+ : integral_constant<bool, !ratio_equal<_R1, _R2>::value>
+ { };
+
+ template<typename _R1, typename _R2>
+ struct __ratio_less_simple_impl
+ : integral_constant<bool,
+ (__safe_multiply<_R1::num, _R2::den>::value
+ < __safe_multiply<_R2::num, _R1::den>::value)>
+ { };
+
+ // If the denominators are equal or the signs differ, we can just compare
+ // numerators, otherwise fallback to the simple cross-multiply method.
+ template<typename _R1, typename _R2>
+ struct __ratio_less_impl
+ : conditional<(_R1::den == _R2::den
+ || (__static_sign<_R1::num>::value
+ != __static_sign<_R2::num>::value)),
+ integral_constant<bool, (_R1::num < _R2::num)>,
+ __ratio_less_simple_impl<_R1, _R2>>::type
+ { };
+
+ /// ratio_less
+ template<typename _R1, typename _R2>
+ struct ratio_less
+ : __ratio_less_impl<_R1, _R2>::type
+ { };
+
+ /// ratio_less_equal
+ template<typename _R1, typename _R2>
+ struct ratio_less_equal
+ : integral_constant<bool, !ratio_less<_R2, _R1>::value>
+ { };
+
+ /// ratio_greater
+ template<typename _R1, typename _R2>
+ struct ratio_greater
+ : integral_constant<bool, ratio_less<_R2, _R1>::value>
+ { };
+
+ /// ratio_greater_equal
+ template<typename _R1, typename _R2>
+ struct ratio_greater_equal
+ : integral_constant<bool, !ratio_less<_R1, _R2>::value>
+ { };
+
+ typedef ratio<1, 1000000000000000000> atto;
+ typedef ratio<1, 1000000000000000> femto;
+ typedef ratio<1, 1000000000000> pico;
+ typedef ratio<1, 1000000000> nano;
+ typedef ratio<1, 1000000> micro;
+ typedef ratio<1, 1000> milli;
+ typedef ratio<1, 100> centi;
+ typedef ratio<1, 10> deci;
+ typedef ratio< 10, 1> deca;
+ typedef ratio< 100, 1> hecto;
+ typedef ratio< 1000, 1> kilo;
+ typedef ratio< 1000000, 1> mega;
+ typedef ratio< 1000000000, 1> giga;
+ typedef ratio< 1000000000000, 1> tera;
+ typedef ratio< 1000000000000000, 1> peta;
+ typedef ratio< 1000000000000000000, 1> exa;
+}
+
+#endif //_GLIBCXX_USE_C99_STDINT_TR1
+
+#endif //__GXX_EXPERIMENTAL_CXX0X__
+
+#endif //_GLIBCXX_RATIO
diff --git a/libstdc++-v3/include/std/system_error b/libstdc++-v3/include/std/system_error
index 343eb6e83f7..b0585810663 100644
--- a/libstdc++-v3/include/std/system_error
+++ b/libstdc++-v3/include/std/system_error
@@ -53,7 +53,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
class system_error;
/// is_error_code_enum
- template<typename _T>
+ template<typename _Tp>
struct is_error_code_enum : public false_type { };
template<>
@@ -61,7 +61,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
: public true_type { };
/// is_error_condition_enum
- template<typename _T>
+ template<typename _Tp>
struct is_error_condition_enum : public false_type { };
template<>
diff --git a/libstdc++-v3/include/std/type_traits b/libstdc++-v3/include/std/type_traits
index 5fdc95ecad9..1a759187955 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -203,13 +203,13 @@ namespace std
: public integral_constant<bool, __has_trivial_destructor(_Tp)>
{ };
- /// has_nothrow_default_destructor
+ /// has_nothrow_default_constructor
template<typename _Tp>
struct has_nothrow_default_constructor
: public integral_constant<bool, __has_nothrow_constructor(_Tp)>
{ };
- /// has_nothrow_copy_destructor
+ /// has_nothrow_copy_constructor
template<typename _Tp>
struct has_nothrow_copy_constructor
: public integral_constant<bool, __has_nothrow_copy(_Tp)>
@@ -551,6 +551,41 @@ namespace std
// Integral, but don't define.
template<>
struct make_signed<bool>;
+
+ template<typename... _Tp>
+ struct common_type;
+
+ template<typename _Tp>
+ struct common_type<_Tp>
+ {
+ static_assert(sizeof(_Tp) > 0, "must be complete type");
+ typedef _Tp type;
+ };
+
+ template<typename _Tp, typename _Up>
+ class common_type<_Tp, _Up>
+ {
+ static_assert(sizeof(_Tp) > 0, "must be complete type");
+ static_assert(sizeof(_Up) > 0, "must be complete type");
+
+ static _Tp&& __t();
+ static _Up&& __u();
+
+ // HACK: Prevents optimization of ?: in the decltype
+ // expression when the condition is the literal, "true".
+ // See, PR36628.
+ static bool __true_or_false();
+
+ public:
+ typedef decltype(__true_or_false() ? __t() : __u()) type;
+ };
+
+ template<typename _Tp, typename _Up, typename... _Vp>
+ struct common_type<_Tp, _Up, _Vp...>
+ {
+ typedef typename
+ common_type<typename common_type<_Tp, _Up>::type, _Vp...>::type type;
+ };
}
#endif // __GXX_EXPERIMENTAL_CXX0X__
diff --git a/libstdc++-v3/include/std/unordered_map b/libstdc++-v3/include/std/unordered_map
index e338ef7805c..2b7d328f387 100644
--- a/libstdc++-v3/include/std/unordered_map
+++ b/libstdc++-v3/include/std/unordered_map
@@ -46,6 +46,7 @@
#include <utility>
#include <type_traits>
+#include <initializer_list>
#include <bits/stl_algobase.h>
#include <bits/allocator.h>
#include <bits/stl_function.h> // equal_to, _Identity, _Select1st
diff --git a/libstdc++-v3/include/std/unordered_set b/libstdc++-v3/include/std/unordered_set
index 13b412b1eb5..1cabae987cc 100644
--- a/libstdc++-v3/include/std/unordered_set
+++ b/libstdc++-v3/include/std/unordered_set
@@ -46,6 +46,7 @@
#include <utility>
#include <type_traits>
+#include <initializer_list>
#include <bits/stl_algobase.h>
#include <bits/allocator.h>
#include <bits/stl_function.h> // equal_to, _Identity, _Select1st
diff --git a/libstdc++-v3/include/std/valarray b/libstdc++-v3/include/std/valarray
index 31799c04cce..b0fa5124805 100644
--- a/libstdc++-v3/include/std/valarray
+++ b/libstdc++-v3/include/std/valarray
@@ -45,6 +45,7 @@
#include <cmath>
#include <algorithm>
#include <debug/debug.h>
+#include <initializer_list>
_GLIBCXX_BEGIN_NAMESPACE(std)
@@ -144,6 +145,11 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
/// Construct an array with the same size and values in @a ia.
valarray(const indirect_array<_Tp>&);
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ /// Construct an array with an initializer_list of values.
+ valarray(initializer_list<_Tp>);
+#endif
+
template<class _Dom>
valarray(const _Expr<_Dom, _Tp>& __e);
@@ -209,6 +215,18 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
*/
valarray<_Tp>& operator=(const indirect_array<_Tp>&);
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ /**
+ * @brief Assign elements to an initializer_list.
+ *
+ * Assign elements of array to values in @a l. Results are undefined
+ * if @a l does not have the same size as this array.
+ *
+ * @param l initializer_list to get values from.
+ */
+ valarray& operator=(initializer_list<_Tp>);
+#endif
+
template<class _Dom> valarray<_Tp>&
operator= (const _Expr<_Dom, _Tp>&);
@@ -615,6 +633,14 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
(__ia._M_array, __ia._M_index, _Array<_Tp>(_M_data), _M_size);
}
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ template<typename _Tp>
+ inline
+ valarray<_Tp>::valarray(initializer_list<_Tp> __l)
+ : _M_size(__l.size()), _M_data(__valarray_get_storage<_Tp>(__l.size()))
+ { std::__valarray_copy_construct (__l.begin(), __l.end(), _M_data); }
+#endif
+
template<typename _Tp> template<class _Dom>
inline
valarray<_Tp>::valarray(const _Expr<_Dom, _Tp>& __e)
@@ -638,6 +664,16 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
return *this;
}
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ template<typename _Tp>
+ inline valarray<_Tp>&
+ valarray<_Tp>::operator=(initializer_list<_Tp> __l)
+ {
+ _GLIBCXX_DEBUG_ASSERT(_M_size == __l.size());
+ std::__valarray_copy(__l.begin(), __l.size(), _M_data);
+ }
+#endif
+
template<typename _Tp>
inline valarray<_Tp>&
valarray<_Tp>::operator=(const _Tp& __t)
diff --git a/libstdc++-v3/include/tr1_impl/hashtable b/libstdc++-v3/include/tr1_impl/hashtable
index 55056ef3da8..33857a43ab3 100644
--- a/libstdc++-v3/include/tr1_impl/hashtable
+++ b/libstdc++-v3/include/tr1_impl/hashtable
@@ -434,6 +434,12 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1
void
insert(_InputIterator __first, _InputIterator __last);
+#ifdef _GLIBCXX_INCLUDE_AS_CXX0X
+ void
+ insert(initializer_list<value_type> __l)
+ { this->insert(__l.begin(), __l.end()); }
+#endif
+
iterator
erase(iterator);
diff --git a/libstdc++-v3/include/tr1_impl/regex b/libstdc++-v3/include/tr1_impl/regex
index f99e0067850..d5e80b1b065 100644
--- a/libstdc++-v3/include/tr1_impl/regex
+++ b/libstdc++-v3/include/tr1_impl/regex
@@ -730,6 +730,13 @@ namespace regex_constants
: _M_flags(__f), _M_pattern(__first, __last), _M_mark_count(0)
{ _M_compile(); }
+#ifdef _GLIBCXX_INCLUDE_AS_CXX0X
+ basic_regex(initializer_list<_Ch_type> __l,
+ flag_type __f = regex_constants::ECMAScript)
+ : _M_flags(__f), _M_pattern(__l.begin(), __l.end()), _M_mark_count(0)
+ { _M_compile(); }
+#endif
+
/**
* @brief Destroys a basic regular expression.
*/
@@ -854,6 +861,13 @@ namespace regex_constants
flag_type __flags = regex_constants::ECMAScript)
{ return this->assign(string_type(__first, __last), __flags); }
+#ifdef _GLIBCXX_INCLUDE_AS_CXX0X
+ basic_regex&
+ assign(initializer_list<_Ch_type> __l,
+ flag_type __f = regex_constants::ECMAScript)
+ { return this->assign(__l.begin(), __l.end(), __f); }
+#endif
+
// [7.8.4] const operations
/**
* @brief Gets the number of marked subexpressions within the regular
diff --git a/libstdc++-v3/include/tr1_impl/type_traits b/libstdc++-v3/include/tr1_impl/type_traits
index 5d0824a365f..87633fa9804 100644
--- a/libstdc++-v3/include/tr1_impl/type_traits
+++ b/libstdc++-v3/include/tr1_impl/type_traits
@@ -235,7 +235,7 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1
template<typename _Tp>
struct is_member_pointer;
- /// is_scalal
+ /// is_scalar
template<typename _Tp>
struct is_scalar
: public integral_constant<bool, (is_arithmetic<_Tp>::value
diff --git a/libstdc++-v3/include/tr1_impl/unordered_map b/libstdc++-v3/include/tr1_impl/unordered_map
index bb69479f277..4f914495ddb 100644
--- a/libstdc++-v3/include/tr1_impl/unordered_map
+++ b/libstdc++-v3/include/tr1_impl/unordered_map
@@ -179,6 +179,7 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1
typedef __unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc> _Base;
public:
+ typedef typename _Base::value_type value_type;
typedef typename _Base::size_type size_type;
typedef typename _Base::hasher hasher;
typedef typename _Base::key_equal key_equal;
@@ -205,6 +206,14 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1
unordered_map(unordered_map&& __x)
: _Base(std::forward<_Base>(__x)) { }
+ unordered_map(initializer_list<value_type> __l,
+ size_type __n = 10,
+ const hasher& __hf = hasher(),
+ const key_equal& __eql = key_equal(),
+ const allocator_type& __a = allocator_type())
+ : _Base(__l.begin(), __l.end(), __n, __hf, __eql, __a)
+ { }
+
unordered_map&
operator=(unordered_map&& __x)
{
@@ -213,6 +222,14 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1
this->swap(__x);
return *this;
}
+
+ unordered_map&
+ operator=(initializer_list<value_type> __l)
+ {
+ this->clear();
+ this->insert(__l.begin(), __l.end());
+ return *this;
+ }
#endif
};
@@ -227,6 +244,7 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1
typedef __unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc> _Base;
public:
+ typedef typename _Base::value_type value_type;
typedef typename _Base::size_type size_type;
typedef typename _Base::hasher hasher;
typedef typename _Base::key_equal key_equal;
@@ -254,6 +272,14 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1
unordered_multimap(unordered_multimap&& __x)
: _Base(std::forward<_Base>(__x)) { }
+ unordered_multimap(initializer_list<value_type> __l,
+ size_type __n = 10,
+ const hasher& __hf = hasher(),
+ const key_equal& __eql = key_equal(),
+ const allocator_type& __a = allocator_type())
+ : _Base(__l.begin(), __l.end(), __n, __hf, __eql, __a)
+ { }
+
unordered_multimap&
operator=(unordered_multimap&& __x)
{
@@ -262,6 +288,14 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1
this->swap(__x);
return *this;
}
+
+ unordered_multimap&
+ operator=(initializer_list<value_type> __l)
+ {
+ this->clear();
+ this->insert(__l.begin(), __l.end());
+ return *this;
+ }
#endif
};
diff --git a/libstdc++-v3/include/tr1_impl/unordered_set b/libstdc++-v3/include/tr1_impl/unordered_set
index 80b1ec5f003..5640ebe1f77 100644
--- a/libstdc++-v3/include/tr1_impl/unordered_set
+++ b/libstdc++-v3/include/tr1_impl/unordered_set
@@ -175,6 +175,7 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1
typedef __unordered_set<_Value, _Hash, _Pred, _Alloc> _Base;
public:
+ typedef typename _Base::value_type value_type;
typedef typename _Base::size_type size_type;
typedef typename _Base::hasher hasher;
typedef typename _Base::key_equal key_equal;
@@ -201,6 +202,14 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1
unordered_set(unordered_set&& __x)
: _Base(std::forward<_Base>(__x)) { }
+ unordered_set(initializer_list<value_type> __l,
+ size_type __n = 10,
+ const hasher& __hf = hasher(),
+ const key_equal& __eql = key_equal(),
+ const allocator_type& __a = allocator_type())
+ : _Base(__l.begin(), __l.end(), __n, __hf, __eql, __a)
+ { }
+
unordered_set&
operator=(unordered_set&& __x)
{
@@ -209,6 +218,14 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1
this->swap(__x);
return *this;
}
+
+ unordered_set&
+ operator=(initializer_list<value_type> __l)
+ {
+ this->clear();
+ this->insert(__l.begin(), __l.end());
+ return *this;
+ }
#endif
};
@@ -223,6 +240,7 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1
typedef __unordered_multiset<_Value, _Hash, _Pred, _Alloc> _Base;
public:
+ typedef typename _Base::value_type value_type;
typedef typename _Base::size_type size_type;
typedef typename _Base::hasher hasher;
typedef typename _Base::key_equal key_equal;
@@ -250,6 +268,14 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1
unordered_multiset(unordered_multiset&& __x)
: _Base(std::forward<_Base>(__x)) { }
+ unordered_multiset(initializer_list<value_type> __l,
+ size_type __n = 10,
+ const hasher& __hf = hasher(),
+ const key_equal& __eql = key_equal(),
+ const allocator_type& __a = allocator_type())
+ : _Base(__l.begin(), __l.end(), __n, __hf, __eql, __a)
+ { }
+
unordered_multiset&
operator=(unordered_multiset&& __x)
{
@@ -258,6 +284,14 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1
this->swap(__x);
return *this;
}
+
+ unordered_multiset&
+ operator=(initializer_list<value_type> __l)
+ {
+ this->clear();
+ this->insert(__l.begin(), __l.end());
+ return *this;
+ }
#endif
};
diff --git a/libstdc++-v3/libsupc++/eh_arm.cc b/libstdc++-v3/libsupc++/eh_arm.cc
index e1e4851604b..6f770e95663 100644
--- a/libstdc++-v3/libsupc++/eh_arm.cc
+++ b/libstdc++-v3/libsupc++/eh_arm.cc
@@ -46,12 +46,14 @@ __cxa_type_match(_Unwind_Exception* ue_header,
bool is_reference __attribute__((__unused__)),
void** thrown_ptr_p)
{
- bool foreign_exception = !__is_gxx_exception_class(ue_header->exception_class);
+ bool forced_unwind = __is_gxx_forced_unwind_class(ue_header->exception_class);
+ bool foreign_exception = !forced_unwind && !__is_gxx_exception_class(ue_header->exception_class);
__cxa_exception* xh = __get_exception_header_from_ue(ue_header);
const std::type_info* throw_type;
- // XXX What to do with forced unwind?
- if (foreign_exception)
+ if (forced_unwind)
+ throw_type = &typeid(abi::__forced_unwind);
+ else if (foreign_exception)
throw_type = &typeid(abi::__foreign_exception);
else
throw_type = xh->exceptionType;
diff --git a/libstdc++-v3/libsupc++/eh_personality.cc b/libstdc++-v3/libsupc++/eh_personality.cc
index 86cfbafc229..b7d957c4d37 100644
--- a/libstdc++-v3/libsupc++/eh_personality.cc
+++ b/libstdc++-v3/libsupc++/eh_personality.cc
@@ -544,8 +544,12 @@ PERSONALITY_FUNCTION (int version,
#ifdef __ARM_EABI_UNWINDER__
throw_type = ue_header;
- if ((actions & _UA_FORCE_UNWIND)
- || foreign_exception)
+ if (actions & _UA_FORCE_UNWIND)
+ {
+ __GXX_INIT_FORCED_UNWIND_CLASS(ue_header->exception_class);
+ thrown_ptr = 0;
+ }
+ else if (foreign_exception)
thrown_ptr = 0;
#else
// During forced unwinding, match a magic exception type.
diff --git a/libstdc++-v3/libsupc++/initializer_list b/libstdc++-v3/libsupc++/initializer_list
index 18fb15bc552..e98cd71a1ac 100644
--- a/libstdc++-v3/libsupc++/initializer_list
+++ b/libstdc++-v3/libsupc++/initializer_list
@@ -28,6 +28,10 @@
// invalidate any other reasons why the executable file might be covered by
// the GNU General Public License.
+/** @file initializer_list
+ * This is a Standard C++ Library header.
+ */
+
#ifndef __CXX_INITIALIZER_LIST
#define __CXX_INITIALIZER_LIST
@@ -39,6 +43,7 @@
namespace std
{
+ /// initializer_list
template<class _E>
class initializer_list
{
diff --git a/libstdc++-v3/libsupc++/unwind-cxx.h b/libstdc++-v3/libsupc++/unwind-cxx.h
index c5636556434..75874fc5da4 100644
--- a/libstdc++-v3/libsupc++/unwind-cxx.h
+++ b/libstdc++-v3/libsupc++/unwind-cxx.h
@@ -201,6 +201,32 @@ __GXX_INIT_EXCEPTION_CLASS(_Unwind_Exception_Class c)
c[7] = '\0';
}
+static inline bool
+__is_gxx_forced_unwind_class(_Unwind_Exception_Class c)
+{
+ return c[0] == 'G'
+ && c[1] == 'N'
+ && c[2] == 'U'
+ && c[3] == 'C'
+ && c[4] == 'F'
+ && c[5] == 'O'
+ && c[6] == 'R'
+ && c[7] == '\0';
+}
+
+static inline void
+__GXX_INIT_FORCED_UNWIND_CLASS(_Unwind_Exception_Class c)
+{
+ c[0] = 'G';
+ c[1] = 'N';
+ c[2] = 'U';
+ c[3] = 'C';
+ c[4] = 'F';
+ c[5] = 'O';
+ c[6] = 'R';
+ c[7] = '\0';
+}
+
static inline void*
__gxx_caught_object(_Unwind_Exception* eo)
{
diff --git a/libstdc++-v3/src/Makefile.am b/libstdc++-v3/src/Makefile.am
index f5d99c63525..6ea357f2ce9 100644
--- a/libstdc++-v3/src/Makefile.am
+++ b/libstdc++-v3/src/Makefile.am
@@ -143,7 +143,6 @@ sources = \
compatibility.cc \
complex_io.cc \
ctype.cc \
- date_time.cc \
debug.cc \
functexcept.cc \
hash.cc \
@@ -187,6 +186,7 @@ sources = \
wstring-inst.cc \
mutex.cc \
condition_variable.cc \
+ chrono.cc \
${host_sources} \
${host_sources_extra}
@@ -268,16 +268,26 @@ limits_c++0x.lo: limits_c++0x.cc
limits_c++0x.o: limits_c++0x.cc
$(CXXCOMPILE) -std=gnu++0x -c $<
-date_time.lo: date_time.cc
- $(LTCXXCOMPILE) -std=gnu++0x -c $<
-date_time.o: date_time.cc
- $(CXXCOMPILE) -std=gnu++0x -c $<
-
atomic.lo: atomic.cc
$(LTCXXCOMPILE) -x c++ -std=gnu++0x -c $<
atomic.o: atomic.cc
$(CXXCOMPILE) -x c++ -std=gnu++0x -c $<
+string-inst.lo: string-inst.cc
+ $(LTCXXCOMPILE) -std=gnu++0x -c $<
+string-inst.o: string-inst.cc
+ $(CXXCOMPILE) -std=gnu++0x -c $<
+
+wstring-inst.lo: wstring-inst.cc
+ $(LTCXXCOMPILE) -std=gnu++0x -c $<
+wstring-inst.o: wstring-inst.cc
+ $(CXXCOMPILE) -std=gnu++0x -c $<
+
+chrono.lo: chrono.cc
+ $(LTCXXCOMPILE) -std=gnu++0x -c $<
+chrono.o: chrono.cc
+ $(CXXCOMPILE) -std=gnu++0x -c $<
+
if GLIBCXX_LDBL_COMPAT
# Use special rules for compatibility-ldbl.cc compilation, as we need to
# pass -mlong-double-64.
diff --git a/libstdc++-v3/src/Makefile.in b/libstdc++-v3/src/Makefile.in
index 508a399e7e8..b674061d3a8 100644
--- a/libstdc++-v3/src/Makefile.in
+++ b/libstdc++-v3/src/Makefile.in
@@ -74,17 +74,17 @@ toolexeclibLTLIBRARIES_INSTALL = $(INSTALL)
LTLIBRARIES = $(toolexeclib_LTLIBRARIES)
am__libstdc___la_SOURCES_DIST = atomic.cc bitmap_allocator.cc \
pool_allocator.cc mt_allocator.cc codecvt.cc compatibility.cc \
- complex_io.cc ctype.cc date_time.cc debug.cc functexcept.cc \
- hash.cc hash_c++0x.cc globals_io.cc hashtable.cc \
- hashtable_c++0x.cc ios.cc ios_failure.cc ios_init.cc \
- ios_locale.cc limits.cc limits_c++0x.cc list.cc debug_list.cc \
- locale.cc locale_init.cc locale_facets.cc localename.cc \
- stdexcept.cc strstream.cc system_error.cc tree.cc \
- allocator-inst.cc concept-inst.cc fstream-inst.cc ext-inst.cc \
- ios-inst.cc iostream-inst.cc istream-inst.cc istream.cc \
- locale-inst.cc misc-inst.cc ostream-inst.cc sstream-inst.cc \
- streambuf-inst.cc streambuf.cc string-inst.cc valarray-inst.cc \
- wlocale-inst.cc wstring-inst.cc mutex.cc condition_variable.cc \
+ complex_io.cc ctype.cc debug.cc functexcept.cc hash.cc \
+ hash_c++0x.cc globals_io.cc hashtable.cc hashtable_c++0x.cc \
+ ios.cc ios_failure.cc ios_init.cc ios_locale.cc limits.cc \
+ limits_c++0x.cc list.cc debug_list.cc locale.cc locale_init.cc \
+ locale_facets.cc localename.cc stdexcept.cc strstream.cc \
+ system_error.cc tree.cc allocator-inst.cc concept-inst.cc \
+ fstream-inst.cc ext-inst.cc ios-inst.cc iostream-inst.cc \
+ istream-inst.cc istream.cc locale-inst.cc misc-inst.cc \
+ ostream-inst.cc sstream-inst.cc streambuf-inst.cc streambuf.cc \
+ string-inst.cc valarray-inst.cc wlocale-inst.cc \
+ wstring-inst.cc mutex.cc condition_variable.cc chrono.cc \
atomicity.cc codecvt_members.cc collate_members.cc \
ctype_members.cc messages_members.cc monetary_members.cc \
numeric_members.cc time_members.cc basic_file.cc c++locale.cc \
@@ -99,9 +99,9 @@ am__objects_4 = basic_file.lo c++locale.lo $(am__objects_2) \
$(am__objects_3)
am__objects_5 = atomic.lo bitmap_allocator.lo pool_allocator.lo \
mt_allocator.lo codecvt.lo compatibility.lo complex_io.lo \
- ctype.lo date_time.lo debug.lo functexcept.lo hash.lo \
- hash_c++0x.lo globals_io.lo hashtable.lo hashtable_c++0x.lo \
- ios.lo ios_failure.lo ios_init.lo ios_locale.lo limits.lo \
+ ctype.lo debug.lo functexcept.lo hash.lo hash_c++0x.lo \
+ globals_io.lo hashtable.lo hashtable_c++0x.lo ios.lo \
+ ios_failure.lo ios_init.lo ios_locale.lo limits.lo \
limits_c++0x.lo list.lo debug_list.lo locale.lo locale_init.lo \
locale_facets.lo localename.lo stdexcept.lo strstream.lo \
system_error.lo tree.lo allocator-inst.lo concept-inst.lo \
@@ -109,7 +109,7 @@ am__objects_5 = atomic.lo bitmap_allocator.lo pool_allocator.lo \
istream-inst.lo istream.lo locale-inst.lo misc-inst.lo \
ostream-inst.lo sstream-inst.lo streambuf-inst.lo streambuf.lo \
string-inst.lo valarray-inst.lo wlocale-inst.lo \
- wstring-inst.lo mutex.lo condition_variable.lo \
+ wstring-inst.lo mutex.lo condition_variable.lo chrono.lo \
$(am__objects_1) $(am__objects_4)
am_libstdc___la_OBJECTS = $(am__objects_5)
libstdc___la_OBJECTS = $(am_libstdc___la_OBJECTS)
@@ -379,7 +379,6 @@ sources = \
compatibility.cc \
complex_io.cc \
ctype.cc \
- date_time.cc \
debug.cc \
functexcept.cc \
hash.cc \
@@ -423,6 +422,7 @@ sources = \
wstring-inst.cc \
mutex.cc \
condition_variable.cc \
+ chrono.cc \
${host_sources} \
${host_sources_extra}
@@ -862,16 +862,26 @@ limits_c++0x.lo: limits_c++0x.cc
limits_c++0x.o: limits_c++0x.cc
$(CXXCOMPILE) -std=gnu++0x -c $<
-date_time.lo: date_time.cc
- $(LTCXXCOMPILE) -std=gnu++0x -c $<
-date_time.o: date_time.cc
- $(CXXCOMPILE) -std=gnu++0x -c $<
-
atomic.lo: atomic.cc
$(LTCXXCOMPILE) -x c++ -std=gnu++0x -c $<
atomic.o: atomic.cc
$(CXXCOMPILE) -x c++ -std=gnu++0x -c $<
+string-inst.lo: string-inst.cc
+ $(LTCXXCOMPILE) -std=gnu++0x -c $<
+string-inst.o: string-inst.cc
+ $(CXXCOMPILE) -std=gnu++0x -c $<
+
+wstring-inst.lo: wstring-inst.cc
+ $(LTCXXCOMPILE) -std=gnu++0x -c $<
+wstring-inst.o: wstring-inst.cc
+ $(CXXCOMPILE) -std=gnu++0x -c $<
+
+chrono.lo: chrono.cc
+ $(LTCXXCOMPILE) -std=gnu++0x -c $<
+chrono.o: chrono.cc
+ $(CXXCOMPILE) -std=gnu++0x -c $<
+
# Use special rules for compatibility-ldbl.cc compilation, as we need to
# pass -mlong-double-64.
@GLIBCXX_LDBL_COMPAT_TRUE@compatibility-ldbl.lo: compatibility-ldbl.cc
diff --git a/libstdc++-v3/src/chrono.cc b/libstdc++-v3/src/chrono.cc
new file mode 100644
index 00000000000..88fb4c180e9
--- /dev/null
+++ b/libstdc++-v3/src/chrono.cc
@@ -0,0 +1,76 @@
+// chrono -*- C++ -*-
+
+// Copyright (C) 2008 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 2, 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 COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+#include <chrono>
+
+#ifdef _GLIBCXX_USE_C99_STDINT_TR1
+
+// conditional inclusion of sys/time.h for gettimeofday
+#if !defined(_GLIBCXX_USE_CLOCK_MONOTONIC) && \
+ !defined(_GLIBCXX_USE_CLOCK_REALTIME) && \
+ defined(_GLIBCXX_USE_GETTIMEOFDAY)
+#include <sys/time.h>
+#endif
+
+namespace std
+{
+ namespace chrono
+ {
+ const bool system_clock::is_monotonic;
+
+ system_clock::time_point
+ system_clock::now()
+ {
+#ifdef _GLIBCXX_USE_CLOCK_MONOTONIC
+ timespec tp;
+ // -EINVAL, -EFAULT
+ clock_gettime(CLOCK_MONOTONIC, &tp);
+ return time_point(duration(chrono::seconds(tp.tv_sec)
+ + chrono::nanoseconds(tp.tv_nsec)));
+#elif defined(_GLIBCXX_USE_CLOCK_REALTIME)
+ timespec tp;
+ // -EINVAL, -EFAULT
+ clock_gettime(CLOCK_REALTIME, &tp);
+ return time_point(duration(chrono::seconds(tp.tv_sec)
+ + chrono::nanoseconds(tp.tv_nsec)));
+#elif defined(_GLIBCXX_USE_GETTIMEOFDAY)
+ timeval tv;
+ // EINVAL, EFAULT
+ gettimeofday(&tv, NULL);
+ return time_point(duration(chrono::seconds(tv.tv_sec)
+ + chrono::microseconds(tv.tv_usec)));
+#else
+ std::time_t __sec = std::time(0);
+ return system_clock::from_time_t(__sec);
+#endif
+ }
+ }
+}
+
+#endif // _GLIBCXX_USE_C99_STDINT_TR1
diff --git a/libstdc++-v3/testsuite/17_intro/headers/c++200x/all.cc b/libstdc++-v3/testsuite/17_intro/headers/c++200x/all.cc
index 049f42096d0..4c2e31be081 100644
--- a/libstdc++-v3/testsuite/17_intro/headers/c++200x/all.cc
+++ b/libstdc++-v3/testsuite/17_intro/headers/c++200x/all.cc
@@ -95,9 +95,9 @@
#include <algorithm>
#include <array>
#include <bitset>
+#include <chrono>
#include <condition_variable>
#include <complex>
-#include <date_time>
#include <deque>
#include <exception>
#include <fstream>
@@ -119,6 +119,7 @@
#include <ostream>
#include <queue>
#include <random>
+#include <ratio>
#include <regex>
#include <set>
#include <sstream>
diff --git a/libstdc++-v3/testsuite/17_intro/headers/c++200x/all_multiple_inclusion.cc b/libstdc++-v3/testsuite/17_intro/headers/c++200x/all_multiple_inclusion.cc
index 869fa02675c..f88edc8268a 100644
--- a/libstdc++-v3/testsuite/17_intro/headers/c++200x/all_multiple_inclusion.cc
+++ b/libstdc++-v3/testsuite/17_intro/headers/c++200x/all_multiple_inclusion.cc
@@ -93,8 +93,8 @@
#include <algorithm>
#include <array>
#include <bitset>
+#include <chrono>
#include <complex>
-#include <date_time>
#include <deque>
#include <exception>
#include <fstream>
@@ -115,6 +115,7 @@
#include <ostream>
#include <queue>
#include <random>
+#include <ratio>
#include <regex>
#include <set>
#include <sstream>
@@ -204,8 +205,8 @@
#include <algorithm>
#include <array>
#include <bitset>
+#include <chrono>
#include <complex>
-#include <date_time>
#include <deque>
#include <exception>
#include <fstream>
@@ -221,11 +222,13 @@
#include <locale>
#include <map>
#include <memory>
+#include <mutex>
#include <new>
#include <numeric>
#include <ostream>
#include <queue>
#include <random>
+#include <ratio>
#include <regex>
#include <set>
#include <sstream>
diff --git a/libstdc++-v3/testsuite/31_date_time/nanoseconds/requirements/traits.cc b/libstdc++-v3/testsuite/20_util/clocks/1.cc
index 53f36180ea4..bcbe210d22f 100644
--- a/libstdc++-v3/testsuite/31_date_time/nanoseconds/requirements/traits.cc
+++ b/libstdc++-v3/testsuite/20_util/clocks/1.cc
@@ -1,7 +1,7 @@
-// { dg-do compile }
// { dg-options "-std=gnu++0x" }
+// { dg-require-cstdint "" }
-// Copyright (C) 2008 Free Software Foundation, Inc.
+// Copyright (C) 2008 Free Software Foundation
//
// 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
@@ -19,15 +19,21 @@
// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
// USA.
-#include <date_time>
+// 20.8.5 Clocks [time.clock]
-namespace gnu
+#include <chrono>
+
+// 20.8.5.1 system_clock [time.clock.system]
+int
+main()
{
- void
- test_nanoseconds_traits()
- {
- static_assert(std::nanoseconds::ticks_per_second == 1000L * 1000 * 1000, "FIXME");
- static_assert(std::nanoseconds::seconds_per_tick == 0, "FIXME");
- static_assert(std::nanoseconds::is_subsecond == true, "FIXME");
- }
+ using namespace std::chrono;
+
+ system_clock::time_point t1 = system_clock::now();
+ bool is_monotonic = system_clock::is_monotonic;
+ is_monotonic = is_monotonic; // suppress unused warning
+ std::time_t t2 = system_clock::to_time_t(t1);
+ system_clock::time_point t3 = system_clock::from_time_t(t2);
+
+ return 0;
}
diff --git a/libstdc++-v3/testsuite/20_util/common_type/requirements/explicit_instantiation.cc b/libstdc++-v3/testsuite/20_util/common_type/requirements/explicit_instantiation.cc
new file mode 100644
index 00000000000..fcc5b2adf30
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/common_type/requirements/explicit_instantiation.cc
@@ -0,0 +1,46 @@
+// { dg-options "-std=gnu++0x" }
+// { dg-do compile }
+
+// Copyright (C) 2008 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 2, 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 COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+// NB: This file is for testing type_traits with NO OTHER INCLUDES.
+
+#include <type_traits>
+
+namespace std
+{
+ typedef int test_type1;
+ typedef int& test_type2;
+ typedef double test_type3;
+ typedef float test_type4;
+
+ template struct common_type<test_type1>;
+ template struct common_type<test_type1, test_type2>;
+ template struct common_type<test_type1, test_type2, test_type3>;
+ template struct common_type<test_type1, test_type2, test_type3, test_type4>;
+}
diff --git a/libstdc++-v3/testsuite/20_util/common_type/requirements/typedefs-1.cc b/libstdc++-v3/testsuite/20_util/common_type/requirements/typedefs-1.cc
new file mode 100644
index 00000000000..e4152e51d31
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/common_type/requirements/typedefs-1.cc
@@ -0,0 +1,118 @@
+// { dg-options "-std=gnu++0x" }
+//
+// Copyright (C) 2008 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 2, 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 COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+#include <type_traits>
+#include <testsuite_hooks.h>
+
+#define JOIN( X, Y ) DO_JOIN( X, Y )
+#define DO_JOIN( X, Y ) DO_JOIN2(X,Y)
+#define DO_JOIN2( X, Y ) X##Y
+
+#define COMMON_TYPE_TEST_1(type1, uid) \
+ typedef common_type<type1>::type JOIN(test_t,uid); \
+ VERIFY( (is_same<JOIN(test_t,uid), JOIN(test_t,uid)>::value) ); \
+ typedef common_type<const type1>::type JOIN(test_t,JOIN(uid,c)); \
+ VERIFY( (is_same<JOIN(test_t,JOIN(uid,c)), \
+ JOIN(test_t,JOIN(uid,c))>::value) ); \
+ typedef common_type<volatile type1>::type JOIN(test_t,JOIN(uid,v)); \
+ VERIFY( (is_same<JOIN(test_t,JOIN(uid,v)), \
+ JOIN(test_t,JOIN(uid,v))>::value) ); \
+ typedef common_type<const volatile type1>::type JOIN(test_t,JOIN(uid,cv)); \
+ VERIFY( (is_same<JOIN(test_t,JOIN(uid,cv)), \
+ JOIN(test_t,JOIN(uid,cv))>::value) ); \
+ typedef common_type<type1 &>::type JOIN(test_t,JOIN(uid,l)); \
+ VERIFY( (is_same<JOIN(test_t,JOIN(uid,l)), \
+ JOIN(test_t,JOIN(uid,l))>::value) ); \
+ typedef common_type<const type1 &>::type JOIN(test_t,JOIN(uid,lc)); \
+ VERIFY( (is_same<JOIN(test_t,JOIN(uid,lc)), \
+ JOIN(test_t,JOIN(uid,lc))>::value) ); \
+ typedef common_type<volatile type1 &>::type JOIN(test_t,JOIN(uid,lv)); \
+ VERIFY( (is_same<JOIN(test_t,JOIN(uid,lv)), \
+ JOIN(test_t,JOIN(uid,lv))>::value) ); \
+ typedef common_type<const volatile type1 &>::type JOIN(test_t,JOIN(uid,lcv)); \
+ VERIFY( (is_same<JOIN(test_t,JOIN(uid,lcv)), \
+ JOIN(test_t,JOIN(uid,lcv))>::value) ); \
+ typedef common_type<type1 &&>::type JOIN(test_t,JOIN(uid,r)); \
+ VERIFY( (is_same<JOIN(test_t,JOIN(uid,r)), \
+ JOIN(test_t,JOIN(uid,r))>::value) ); \
+ typedef common_type<const type1 &&>::type JOIN(test_t,JOIN(uid,rc)); \
+ VERIFY( (is_same<JOIN(test_t,JOIN(uid,rc)), \
+ JOIN(test_t,JOIN(uid,rc))>::value) ); \
+ typedef common_type<volatile type1 &&>::type JOIN(test_t,JOIN(uid,rv)); \
+ VERIFY( (is_same<JOIN(test_t,JOIN(uid,rv)), \
+ JOIN(test_t,JOIN(uid,rv))>::value) ); \
+ typedef common_type<const volatile type1 &&>::type JOIN(test_t,JOIN(uid,rcv)); \
+ VERIFY( (is_same<JOIN(test_t,JOIN(uid,rcv)), \
+ JOIN(test_t,JOIN(uid,rcv))>::value) )
+
+struct A { };
+struct B : A { };
+
+void test01()
+{
+ bool test __attribute__((unused)) = true;
+ using std::common_type;
+ using std::is_same;
+
+ // Positive tests.
+ COMMON_TYPE_TEST_1(int, 1);
+ COMMON_TYPE_TEST_1(double, 2);
+ COMMON_TYPE_TEST_1(A, 3);
+ COMMON_TYPE_TEST_1(B, 4);
+}
+
+#define COMMON_TYPE_TEST_2_IMPL(type1, type2, type3, uid) \
+ typedef common_type<type1, type2>::type JOIN(JOIN(test, uid),_t1); \
+ typedef common_type<type2, type1>::type JOIN(JOIN(test, uid),_t2); \
+ VERIFY( (is_same<JOIN(JOIN(test, uid),_t1), type3>::value) ); \
+ VERIFY( (is_same<JOIN(JOIN(test, uid),_t2), type3>::value) )
+
+#define NO_CV
+
+#define COMMON_TYPE_TEST_2(cv_qual, type1, type2, type3, uid) \
+ COMMON_TYPE_TEST_2_IMPL(cv_qual type1, type2, type3, uid); \
+ COMMON_TYPE_TEST_2_IMPL(cv_qual type1 &, type2, type3, JOIN(uid,l)); \
+ COMMON_TYPE_TEST_2_IMPL(cv_qual type1 &&, type2, type3, JOIN(uid,r))
+
+#define COMMON_TYPE_TEST_ALL_2(type1, type2, type3, uid) \
+ COMMON_TYPE_TEST_2(NO_CV, type1, type2, type3, uid); \
+ COMMON_TYPE_TEST_2(const, type1, type2, type3, uid); \
+ COMMON_TYPE_TEST_2(volatile, type1, type2, type3, uid); \
+ COMMON_TYPE_TEST_2(const volatile, type1, type2, type3, uid)
+
+void test02()
+{
+ bool test __attribute__((unused)) = true;
+ using std::common_type;
+ using std::is_same;
+
+ COMMON_TYPE_TEST_ALL_2(int, int, int, 1);
+ COMMON_TYPE_TEST_ALL_2(int, double, double, 2);
+ COMMON_TYPE_TEST_2(NO_CV, A, A, A, 3);
+ COMMON_TYPE_TEST_2(const, A, A, const A, 4);
+ COMMON_TYPE_TEST_2(NO_CV, B, A, A, 5);
+}
+
+int main()
+{
+ test01();
+ test02();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/20_util/duration/arithmetic/1.cc b/libstdc++-v3/testsuite/20_util/duration/arithmetic/1.cc
new file mode 100644
index 00000000000..55533eb1dde
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/duration/arithmetic/1.cc
@@ -0,0 +1,94 @@
+// { dg-options "-std=gnu++0x" }
+// { dg-require-cstdint "" }
+
+// Copyright (C) 2008 Free Software Foundation
+//
+// 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 2, 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 COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// 20.8.3 Class template duration [time.duration]
+
+#include <chrono>
+#include <testsuite_hooks.h>
+
+// 20.8.3.3 duration arithmetic [time.duration.arithmetic] (unary member ops)
+void
+test01()
+{
+ bool test __attribute__((unused)) = true;
+ using namespace std::chrono;
+
+ duration<int> d0(3);
+ duration<int> d1 = -d0;
+ VERIFY(d0.count() == 3);
+ VERIFY(d1.count() == -3);
+
+ duration<int> d2 = (+d0);
+ VERIFY(d2.count() == 3);
+
+ duration<int> d3(++d2);
+ VERIFY(d2.count() == 4);
+ VERIFY(d3.count() == 4);
+
+ duration<int> d4(d3++);
+ VERIFY(d3.count() == 5);
+ VERIFY(d4.count() == 4);
+
+ duration<int> d5(--d4);
+ VERIFY(d4.count() == 3);
+ VERIFY(d5.count() == 3);
+
+ duration<int> d6(d5--);
+ VERIFY(d5.count() == 2);
+ VERIFY(d6.count() == 3);
+}
+
+// 20.8.3.3 duration arithmetic [time.duration.arithmetic] (binary member ops)
+void
+test02()
+{
+ bool test __attribute__((unused)) = true;
+ using namespace std::chrono;
+
+ duration<int> d7(3);
+ duration<int> d8(9);
+ d7 += d8;
+ VERIFY(d7.count() == 12);
+ VERIFY(d8.count() == 9);
+
+ duration<int> d9(3);
+ duration<int> d10(9);
+ d9 -= d10;
+ VERIFY(d9.count() == -6);
+ VERIFY(d10.count() == 9);
+
+ duration<int> d11(9);
+ int i = 3;
+ d11 *= i;
+ VERIFY(d11.count() == 27);
+
+ duration<int> d12(12);
+ d12 /= i;
+ VERIFY(d12.count() == 4);
+}
+
+int
+main()
+{
+ test01();
+ test02();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/20_util/duration/arithmetic/2.cc b/libstdc++-v3/testsuite/20_util/duration/arithmetic/2.cc
new file mode 100644
index 00000000000..e096334c980
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/duration/arithmetic/2.cc
@@ -0,0 +1,62 @@
+// { dg-options "-std=gnu++0x" }
+// { dg-require-cstdint "" }
+
+// Copyright (C) 2008 Free Software Foundation
+//
+// 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 2, 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 COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// 20.8.3 Class template duration [time.duration]
+
+#include <chrono>
+#include <testsuite_hooks.h>
+
+// 20.8.3.5 duration non-member arithmetic [time.duration.nonmember]
+void
+test01()
+{
+ bool test __attribute__((unused)) = true;
+ using namespace std::chrono;
+
+ duration<int> d0(12);
+ duration<int> d1(3);
+ int i = 3;
+
+ duration<int> d2 = d0 + d1;
+ VERIFY(d2.count() == 15);
+
+ duration<int> d3 = d0 - d1;
+ VERIFY(d3.count() == 9);
+
+ duration<int> d4 = d0 * i;
+ VERIFY(d4.count() == 36);
+
+ duration<int> d5 = i * d0;
+ VERIFY(d5.count() == 36);
+
+ duration<int> d6 = d0 / i;
+ VERIFY(d6.count() == 4);
+
+ int j = d0 / d1;
+ VERIFY(j == 4);
+}
+
+int
+main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/31_date_time/nanoseconds/requirements/duration.cc b/libstdc++-v3/testsuite/20_util/duration/comparisons/1.cc
index ca6e2cf374a..31ac42ddcee 100644
--- a/libstdc++-v3/testsuite/31_date_time/nanoseconds/requirements/duration.cc
+++ b/libstdc++-v3/testsuite/20_util/duration/comparisons/1.cc
@@ -1,7 +1,7 @@
-// { dg-do compile }
// { dg-options "-std=gnu++0x" }
+// { dg-require-cstdint "" }
-// Copyright (C) 2008 Free Software Foundation, Inc.
+// Copyright (C) 2008 Free Software Foundation
//
// 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
@@ -19,32 +19,38 @@
// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
// USA.
-#include <date_time>
+// 20.8.3 Class template duration [time.duration]
-namespace gnu
-{
- bool
- test_nanoseconds_is_duration()
- {
- typedef std::nanoseconds D;
- D d;
- D e(d);
- d == e;
- d < e;
- d = e;
-
- typedef D::tick_type tick_type;
- tick_type t1 = D::ticks_per_second;
- tick_type t2 = D::seconds_per_tick;
- bool b1 = D::is_subsecond;
- tick_type t3 = d.count();
- -d;
+#include <chrono>
+#include <testsuite_hooks.h>
- d += e;
- d -= e;
- d *= static_cast<long>(1);
- d /= static_cast<long>(1);
+// 20.8.3.6 duration comparisons [time.duration.comparisons]
+void
+test01()
+{
+ bool test __attribute__((unused)) = true;
+ using namespace std::chrono;
+
+ duration<int> d0(12);
+ duration<int> d1(3);
+ duration<int> d2(3);
+
+ VERIFY(d1 < d0);
+ VERIFY(d0 > d1);
+
+ VERIFY(d0 != d1);
+ VERIFY(d1 == d2);
+
+ VERIFY(d1 <= d2);
+ VERIFY(d1 >= d2);
+
+ VERIFY(d1 <= d0);
+ VERIFY(d0 >= d1);
+}
- return b1 || t1 || t2 || t3;
- }
+int
+main()
+{
+ test01();
+ return 0;
}
diff --git a/libstdc++-v3/testsuite/20_util/duration/cons/1.cc b/libstdc++-v3/testsuite/20_util/duration/cons/1.cc
new file mode 100644
index 00000000000..6d12dbb5bd7
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/duration/cons/1.cc
@@ -0,0 +1,138 @@
+// { dg-options "-std=gnu++0x" }
+// { dg-require-cstdint "" }
+
+// Copyright (C) 2008 Free Software Foundation
+//
+// 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 2, 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 COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// 20.8.3 Class template duration [time.duration]
+
+#include <chrono>
+#include <type_traits>
+#include <testsuite_hooks.h>
+
+template<typename T>
+struct type_emulator
+{
+ type_emulator()
+ : i(T(0)) { }
+
+ type_emulator(T j)
+ : i(j) { }
+
+ type_emulator(const type_emulator& e)
+ : i(e.i) { }
+
+ type_emulator&
+ operator*=(type_emulator a)
+ {
+ i *= a.i;
+ return *this;
+ }
+
+ type_emulator&
+ operator+=(type_emulator a)
+ {
+ i += a.i;
+ return *this;
+ }
+
+ operator T ()
+ { return i; }
+
+ T i;
+};
+
+template<typename T>
+bool
+operator==(type_emulator<T> a, type_emulator<T> b)
+{ return a.i == b.i; }
+
+template<typename T>
+bool
+operator<(type_emulator<T> a, type_emulator<T> b)
+{ return a.i < b.i; }
+
+template<typename T>
+type_emulator<T>
+operator+(type_emulator<T> a, type_emulator<T> b)
+{ return a += b; }
+
+template<typename T>
+type_emulator<T>
+operator*(type_emulator<T> a, type_emulator<T> b)
+{ return a *= b; }
+
+namespace std
+{
+ template<typename T, typename U>
+ struct common_type<type_emulator<T>, U>
+ { typedef typename common_type<T,U>::type type; };
+
+ template<typename T, typename U>
+ struct common_type<U, type_emulator<T>>
+ { typedef typename common_type<U,T>::type type; };
+
+ template<typename T, typename U>
+ struct common_type<type_emulator<T>, type_emulator<U>>
+ { typedef typename common_type<T,U>::type type; };
+
+ namespace chrono
+ {
+ template<typename T>
+ struct treat_as_floating_point<type_emulator<T>>
+ : is_floating_point<T>
+ { };
+ }
+}
+
+typedef type_emulator<int> int_emulator;
+typedef type_emulator<double> dbl_emulator;
+
+// 20.8.3.1 duration constructors [time.duration.cons]
+void
+test01()
+{
+ bool test __attribute__((unused)) = true;
+ using std::chrono::duration;
+
+ duration<int> d0;
+ VERIFY(d0.count() == static_cast<duration<int>::rep>(0));
+
+ int r = 3;
+ duration<int> d1(r);
+ VERIFY(d1.count() == static_cast<duration<int>::rep>(r));
+
+ double s = 8.0;
+ duration<double> d2(s);
+ VERIFY(d2.count() == static_cast<duration<double>::rep>(s));
+
+ int_emulator ie(3);
+ duration<int_emulator> d3(ie);
+ VERIFY(d3.count() == static_cast<duration<int_emulator>::rep>(ie));
+
+ dbl_emulator de(4.0);
+ duration<dbl_emulator> d4(de);
+ VERIFY(d4.count() == static_cast<duration<dbl_emulator>::rep>(de));
+}
+
+int
+main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/20_util/duration/cons/1_neg.cc b/libstdc++-v3/testsuite/20_util/duration/cons/1_neg.cc
new file mode 100644
index 00000000000..fa63dab22b5
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/duration/cons/1_neg.cc
@@ -0,0 +1,46 @@
+// { dg-do compile }
+// { dg-options "-std=gnu++0x" }
+// { dg-require-cstdint "" }
+
+// Copyright (C) 2008 Free Software Foundation
+//
+// 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 2, 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 COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// 20.8.3.1 duration constructors [time.duration.cons]
+
+#include <chrono>
+
+void
+test01()
+{
+ std::chrono::duration<int> d1(1.0);
+}
+
+void
+test02()
+{
+ using namespace std::chrono;
+
+ duration<int, std::micro> d2(8);
+ duration<int, std::milli> d2_copy(d2);
+}
+
+// { dg-error "instantiated from here" "" { target *-*-* } 30 }
+// { dg-error "instantiated from here" "" { target *-*-* } 39 }
+// { dg-error "not exactly representable" "" { target *-*-* } 203 }
+// { dg-error "integral duration with floating point" "" { target *-*-* } 187 }
+// { dg-excess-errors "In instantiation of" }
diff --git a/libstdc++-v3/testsuite/20_util/duration/cons/2.cc b/libstdc++-v3/testsuite/20_util/duration/cons/2.cc
new file mode 100644
index 00000000000..b491224dc48
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/duration/cons/2.cc
@@ -0,0 +1,120 @@
+// { dg-options "-std=gnu++0x" }
+// { dg-require-cstdint "" }
+
+// Copyright (C) 2008 Free Software Foundation
+//
+// 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 2, 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 COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// 20.8.3 Class template duration [time.duration]
+
+#include <chrono>
+#include <type_traits>
+#include <testsuite_hooks.h>
+
+template<typename T>
+struct type_emulator
+{
+ type_emulator() : i(T(0)) { }
+ type_emulator(T j) : i(j) { }
+ type_emulator(const type_emulator& e) : i(e.i) { }
+
+ type_emulator& operator*=(type_emulator a)
+ { i *= a.i; return *this; }
+
+ type_emulator& operator+=(type_emulator a)
+ { i += a.i; return *this; }
+
+ operator T () { return i; }
+ T i;
+};
+
+template<typename T>
+bool operator==(type_emulator<T> a, type_emulator<T> b)
+{ return a.i == b.i; }
+
+template<typename T>
+bool operator<(type_emulator<T> a, type_emulator<T> b)
+{ return a.i < b.i; }
+
+template<typename T>
+type_emulator<T> operator+(type_emulator<T> a, type_emulator<T> b)
+{ return a += b; }
+
+template<typename T>
+type_emulator<T> operator*(type_emulator<T> a, type_emulator<T> b)
+{ return a *= b; }
+
+namespace std
+{
+ template<typename T, typename U>
+ struct common_type<type_emulator<T>, U>
+ { typedef typename common_type<T,U>::type type; };
+
+ template<typename T, typename U>
+ struct common_type<U, type_emulator<T>>
+ { typedef typename common_type<U,T>::type type; };
+
+ template<typename T, typename U>
+ struct common_type<type_emulator<T>, type_emulator<U>>
+ { typedef typename common_type<T,U>::type type; };
+
+ namespace chrono
+ {
+ template<typename T>
+ struct treat_as_floating_point<type_emulator<T>>
+ : is_floating_point<T>
+ { };
+ }
+}
+
+typedef type_emulator<int> int_emulator;
+typedef type_emulator<double> dbl_emulator;
+
+// 20.8.3.1 duration constructors [time.duration.cons]
+void
+test01()
+{
+ bool test __attribute__((unused)) = true;
+ using namespace std::chrono;
+
+ duration<int> d0(3);
+ duration<int> d0_copy(d0);
+ VERIFY(d0_copy.count() == d0.count());
+
+ duration<int, std::milli> d1(5);
+ duration<int, std::micro> d1_copy(d1);
+ VERIFY(d1.count() * 1000 == d1_copy.count());
+
+ duration<double, std::micro> d2(8.0);
+ duration<double, std::milli> d2_copy(d2);
+ VERIFY(d2.count() == d2_copy.count() * 1000.0);
+
+ duration<int_emulator, std::milli> d3(5);
+ duration<int_emulator, std::micro> d3_copy(d3);
+ VERIFY(d3.count() * 1000 == d3_copy.count());
+
+ duration<dbl_emulator, std::micro> d4(5.0);
+ duration<dbl_emulator, std::milli> d4_copy(d4);
+ VERIFY(d4.count() == d4_copy.count() * dbl_emulator(1000.0));
+}
+
+int
+main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/31_date_time/headers/date_time/types_std.cc b/libstdc++-v3/testsuite/20_util/duration/requirements/explicit_instantiation/explicit_instantiation.cc
index f8fc5953c5b..7613411879d 100644
--- a/libstdc++-v3/testsuite/31_date_time/headers/date_time/types_std.cc
+++ b/libstdc++-v3/testsuite/20_util/duration/requirements/explicit_instantiation/explicit_instantiation.cc
@@ -1,7 +1,8 @@
// { dg-do compile }
// { dg-options "-std=gnu++0x" }
+// { dg-require-cstdint "" }
-// Copyright (C) 2008 Free Software Foundation, Inc.
+// Copyright (C) 2008 Free Software Foundation
//
// 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
@@ -14,20 +15,13 @@
// 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 COPYING. If not, write to the Free
-// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
-// USA.
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301, USA.
-#include <date_time>
+#include <ratio>
+#include <chrono>
-namespace gnu
-{
- typedef std::nanoseconds t1;
- typedef std::microseconds t2;
- typedef std::milliseconds t3;
- typedef std::seconds t4;
- typedef std::minutes t5;
- typedef std::hours t6;
- typedef std::system_time t7;
-}
+template class std::chrono::duration<int>;
+template class std::chrono::duration<float, std::ratio<2,3>>;
diff --git a/libstdc++-v3/testsuite/20_util/make_signed/requirements/typedefs-2.cc b/libstdc++-v3/testsuite/20_util/make_signed/requirements/typedefs-2.cc
index 377d1d17758..ea4de372296 100644
--- a/libstdc++-v3/testsuite/20_util/make_signed/requirements/typedefs-2.cc
+++ b/libstdc++-v3/testsuite/20_util/make_signed/requirements/typedefs-2.cc
@@ -1,4 +1,5 @@
// { dg-options "-std=gnu++0x -funsigned-char -fshort-enums" }
+// { dg-options "-std=gnu++0x -funsigned-char -fshort-enums -Wl,--no-enum-size-warning" { target arm*-*-linux*eabi } }
// 2007-05-03 Benjamin Kosnik <bkoz@redhat.com>
//
diff --git a/libstdc++-v3/testsuite/20_util/make_unsigned/requirements/typedefs-2.cc b/libstdc++-v3/testsuite/20_util/make_unsigned/requirements/typedefs-2.cc
index 0789ef55f22..ce318c8a4c2 100644
--- a/libstdc++-v3/testsuite/20_util/make_unsigned/requirements/typedefs-2.cc
+++ b/libstdc++-v3/testsuite/20_util/make_unsigned/requirements/typedefs-2.cc
@@ -1,4 +1,5 @@
// { dg-options "-std=gnu++0x -funsigned-char -fshort-enums" }
+// { dg-options "-std=gnu++0x -funsigned-char -fshort-enums -Wl,--no-enum-size-warning" { target arm*-*-linux*eabi } }
// 2007-05-03 Benjamin Kosnik <bkoz@redhat.com>
//
diff --git a/libstdc++-v3/testsuite/20_util/ratio/comparisons/comp1.cc b/libstdc++-v3/testsuite/20_util/ratio/comparisons/comp1.cc
new file mode 100644
index 00000000000..c916b309998
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/ratio/comparisons/comp1.cc
@@ -0,0 +1,82 @@
+// { dg-options "-std=gnu++0x" }
+// { dg-require-cstdint "" }
+
+// Copyright (C) 2008 Free Software Foundation
+//
+// 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 2, 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 COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301, USA.
+
+#include <ratio>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ VERIFY(( std::ratio_equal<std::ratio<2,6>, std::ratio<1,3>>::value == 1 ));
+ VERIFY(( std::ratio_equal<std::ratio<2,6>, std::ratio<1,4>>::value == 0 ));
+
+ VERIFY( (std::ratio_not_equal<std::ratio<2,6>,
+ std::ratio<1,3>>::value == 0) );
+ VERIFY( (std::ratio_not_equal<std::ratio<2,6>,
+ std::ratio<1,4>>::value == 1) );
+}
+
+void
+test02()
+{
+ bool test __attribute__((unused)) = true;
+
+ VERIFY( (std::ratio_less<std::ratio<1,4>, std::ratio<1,3>>::value == 1) );
+ VERIFY( (std::ratio_less<std::ratio<-1,3>, std::ratio<1,3>>::value == 1) );
+
+ VERIFY( (std::ratio_less<std::ratio<1,3>, std::ratio<1,4>>::value == 0) );
+ VERIFY( (std::ratio_less<std::ratio<1,3>, std::ratio<-1,3>>::value == 0) );
+
+ VERIFY( (std::ratio_less_equal<std::ratio<-1,3>,
+ std::ratio<-1,3>>::value == 1) );
+ VERIFY( ( std::ratio_less_equal<std::ratio<1,4>,
+ std::ratio<1,3>>::value == 1) );
+
+ VERIFY( (std::ratio_less_equal<std::ratio<1,4>,
+ std::ratio<-1,3>>::value == 0) );
+ VERIFY( (std::ratio_less_equal<std::ratio<1,3>,
+ std::ratio<-1,3>>::value == 0) );
+
+ VERIFY( (std::ratio_greater<std::ratio<1,3>, std::ratio<1,4>>::value == 1) );
+ VERIFY( (std::ratio_greater<std::ratio<1,3>, std::ratio<-1,3>>::value == 1) );
+
+ VERIFY( (std::ratio_greater<std::ratio<1,4>, std::ratio<1,3>>::value == 0) );
+ VERIFY( (std::ratio_greater<std::ratio<-1,3>, std::ratio<1,3>>::value == 0) );
+
+ VERIFY( (std::ratio_greater_equal<std::ratio<1,3>,
+ std::ratio<1,3>>::value == 1) );
+ VERIFY( (std::ratio_greater_equal<std::ratio<1,3>,
+ std::ratio<-1,3>>::value == 1) );
+
+ VERIFY( (std::ratio_greater_equal<std::ratio<-1,3>,
+ std::ratio<1,3>>::value == 0) );
+ VERIFY( (std::ratio_greater_equal<std::ratio<1,4>,
+ std::ratio<1,3>>::value == 0) );
+}
+
+int main()
+{
+ test01();
+ test02();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/20_util/ratio/comparisons/comp2.cc b/libstdc++-v3/testsuite/20_util/ratio/comparisons/comp2.cc
new file mode 100644
index 00000000000..56052e45328
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/ratio/comparisons/comp2.cc
@@ -0,0 +1,51 @@
+// { dg-options "-std=gnu++0x" }
+// { dg-require-cstdint "" }
+
+// Copyright (C) 2008 Free Software Foundation
+//
+// 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 2, 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 COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301, USA.
+
+#include <ratio>
+#include <testsuite_hooks.h>
+
+static const std::intmax_t M = INTMAX_MAX;
+
+void
+test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ // No overflow with same denominator
+ VERIFY( (std::ratio_less<std::ratio<M - 2, M>,
+ std::ratio<M - 1, M>>::value == 1) );
+
+ VERIFY( (std::ratio_less<std::ratio<M - 1, M>,
+ std::ratio<M - 2, M>>::value == 0) );
+
+ // No overflow if signs differ
+ VERIFY( (std::ratio_less<std::ratio<-M, M - 1>,
+ std::ratio<M - 1, M - 2>>::value == 1) );
+
+ VERIFY( (std::ratio_less<std::ratio<M - 1, M - 2>,
+ std::ratio<-M, M - 1>>::value == 0) );
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/20_util/ratio/cons/cons1.cc b/libstdc++-v3/testsuite/20_util/ratio/cons/cons1.cc
new file mode 100644
index 00000000000..84860699ac8
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/ratio/cons/cons1.cc
@@ -0,0 +1,52 @@
+// { dg-options "-std=gnu++0x" }
+// { dg-require-cstdint "" }
+
+// 2008-07-03 Chris Fairles <chris.fairles@gmail.com>
+
+// Copyright (C) 2008 Free Software Foundation
+//
+// 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 2, 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 COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301, USA.
+
+#include <ratio>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ std::ratio<1,3> r0;
+ std::ratio<2,6> r1;
+ std::ratio<2,-6> r2;
+ std::ratio<-2,6> r3;
+
+ VERIFY( r0.num == 1 );
+ VERIFY( r0.den == 3 );
+
+ VERIFY( r1.num == r0.num );
+ VERIFY( r1.den == r0.den );
+ VERIFY( r2.num == -r0.num );
+ VERIFY( r2.den == r0.den );
+ VERIFY( r3.num == -r0.num );
+ VERIFY( r3.den == r0.den );
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/20_util/ratio/cons/cons_overflow.cc b/libstdc++-v3/testsuite/20_util/ratio/cons/cons_overflow.cc
new file mode 100644
index 00000000000..570ea6cbc7d
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/ratio/cons/cons_overflow.cc
@@ -0,0 +1,55 @@
+// { dg-do compile }
+// { dg-options "-std=gnu++0x" }
+// { dg-require-cstdint "" }
+
+// Copyright (C) 2008 Free Software Foundation
+//
+// 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 2, 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 COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301, USA.
+
+#include <ratio>
+
+void
+test01()
+{
+ std::ratio<INTMAX_MAX, INTMAX_MAX> r1;
+ std::ratio<-INTMAX_MAX, INTMAX_MAX> r2;
+}
+
+void
+test02()
+{
+ std::ratio<INTMAX_MIN, 1> r1;
+}
+
+void
+test03()
+{
+ std::ratio<1, INTMAX_MIN> r1;
+}
+
+void
+test04()
+{
+ std::ratio<1,0> r1;
+}
+
+// { dg-error "instantiated from here" "" { target *-*-* } 35 }
+// { dg-error "instantiated from here" "" { target *-*-* } 41 }
+// { dg-error "instantiated from here" "" { target *-*-* } 47 }
+// { dg-error "denominator cannot be zero" "" { target *-*-* } 150 }
+// { dg-error "out of range" "" { target *-*-* } 151 }
+// { dg-excess-errors "In instantiation of" }
diff --git a/libstdc++-v3/testsuite/20_util/ratio/operations/ops1.cc b/libstdc++-v3/testsuite/20_util/ratio/operations/ops1.cc
new file mode 100644
index 00000000000..b05092dd8e9
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/ratio/operations/ops1.cc
@@ -0,0 +1,75 @@
+// { dg-options "-std=gnu++0x" }
+// { dg-require-cstdint "" }
+
+// 2008-07-03 Chris Fairles <chris.fairles@gmail.com>
+
+// Copyright (C) 2008 Free Software Foundation
+//
+// 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 2, 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 COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301, USA.
+
+#include <ratio>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ std::ratio_add<std::ratio<3,8>, std::ratio<5,12>>::type r;
+
+ VERIFY( r.num == 19 );
+ VERIFY( r.den == 24 );
+}
+
+void
+test02()
+{
+ bool test __attribute__((unused)) = true;
+ std::ratio_subtract<std::ratio<3,8>, std::ratio<5,12>>::type r;
+
+ VERIFY( r.num == -1 );
+ VERIFY( r.den == 24 );
+}
+
+void
+test03()
+{
+ bool test __attribute__((unused)) = true;
+ std::ratio_multiply<std::ratio<3,8>, std::ratio<5,12>>::type r;
+
+ VERIFY( r.num == 5 );
+ VERIFY( r.den == 32 );
+}
+
+void
+test04()
+{
+ bool test __attribute__((unused)) = true;
+ std::ratio_divide<std::ratio<3,8>, std::ratio<5,12>>::type r;
+
+ VERIFY( r.num == 9 );
+ VERIFY( r.den == 10 );
+}
+
+int main()
+{
+ test01();
+ test02();
+ test03();
+ test04();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/20_util/ratio/operations/ops2.cc b/libstdc++-v3/testsuite/20_util/ratio/operations/ops2.cc
new file mode 100644
index 00000000000..3d3241f3128
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/ratio/operations/ops2.cc
@@ -0,0 +1,73 @@
+// { dg-options "-std=gnu++0x" }
+// { dg-require-cstdint "" }
+
+// 2008-07-03 Chris Fairles <chris.fairles@gmail.com>
+
+// Copyright (C) 2008 Free Software Foundation
+//
+// 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 2, 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 COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301, USA.
+
+#include <ratio>
+#include <testsuite_hooks.h>
+
+typedef std::ratio<1, INTMAX_MAX> one_over_max;
+typedef std::ratio<2, INTMAX_MAX> two_over_max;
+typedef std::ratio<INTMAX_MAX, 1> max_over_one;
+typedef std::ratio<INTMAX_MAX, 2> max_over_two;
+
+void
+test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ std::ratio_add<one_over_max, one_over_max>::type r1;
+
+ VERIFY( r1.num == two_over_max::num);
+ VERIFY( r1.den == two_over_max::den);
+
+ std::ratio_add<
+ std::ratio<INTMAX_MAX / 2, INTMAX_MAX / 2>,
+ std::ratio<INTMAX_MAX / 2 , INTMAX_MAX / 2 + 1>>::type r2;
+
+ VERIFY( r2.num == INTMAX_MAX );
+ VERIFY( r2.den == (INTMAX_MAX / 2) + 1 );
+}
+
+void
+test02()
+{
+ bool test __attribute__((unused)) = true;
+
+ std::ratio_subtract<one_over_max, one_over_max>::type r1;
+
+ VERIFY( r1.num == 0);
+ VERIFY( r1.den == 1);
+
+ std::ratio_subtract<
+ std::ratio<INTMAX_MAX / 2, INTMAX_MAX / 2>,
+ std::ratio<INTMAX_MAX / 2 , INTMAX_MAX / 2 + 1>>::type r2;
+
+ VERIFY( r2.num == 1 );
+ VERIFY( r2.den == (INTMAX_MAX / 2) + 1 );
+}
+
+int main()
+{
+ test01();
+ test02();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/20_util/ratio/operations/ops3.cc b/libstdc++-v3/testsuite/20_util/ratio/operations/ops3.cc
new file mode 100644
index 00000000000..2008275a216
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/ratio/operations/ops3.cc
@@ -0,0 +1,72 @@
+// { dg-options "-std=gnu++0x" }
+// { dg-require-cstdint "" }
+
+// 2008-07-03 Chris Fairles <chris.fairles@gmail.com>
+
+// Copyright (C) 2008 Free Software Foundation
+//
+// 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 2, 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 COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301, USA.
+
+#include <ratio>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ std::ratio_multiply<
+ std::ratio<2, INTMAX_MAX>,
+ std::ratio<INTMAX_MAX, 2>>::type r1;
+
+ VERIFY( r1.num == 1 );
+ VERIFY( r1.den == 1 );
+
+ std::ratio_multiply<
+ std::ratio<INTMAX_MAX, 2>,
+ std::ratio<2 , INTMAX_MAX - 1>>::type r2;
+
+ VERIFY( r2.num == INTMAX_MAX );
+ VERIFY( r2.den == INTMAX_MAX - 1 );
+}
+
+void
+test02()
+{
+ bool test __attribute__((unused)) = true;
+
+ std::ratio_divide<
+ std::ratio<INTMAX_MAX, 2>,
+ std::ratio<INTMAX_MAX, 2>>::type r1;
+
+ VERIFY( r1.num == 1 );
+ VERIFY( r1.den == 1 );
+
+ std::ratio_divide<
+ std::ratio<INTMAX_MAX-1, 2>,
+ std::ratio<INTMAX_MAX, 2>>::type r2;
+
+ VERIFY( r2.num == INTMAX_MAX - 1 );
+ VERIFY( r2.den == INTMAX_MAX );
+}
+
+int main()
+{
+ test01();
+ test02();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/20_util/ratio/operations/ops_overflow.cc b/libstdc++-v3/testsuite/20_util/ratio/operations/ops_overflow.cc
new file mode 100644
index 00000000000..860f9f253b2
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/ratio/operations/ops_overflow.cc
@@ -0,0 +1,48 @@
+// { dg-do compile }
+// { dg-options "-std=gnu++0x" }
+// { dg-require-cstdint "" }
+
+// 2008-07-03 Chris Fairles <chris.fairles@gmail.com>
+
+// Copyright (C) 2008 Free Software Foundation
+//
+// 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 2, 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 COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301, USA.
+
+#include <ratio>
+
+void
+test01()
+{
+ std::ratio_add<std::ratio<INTMAX_MAX, 1>, std::ratio<1>>::type r1;
+}
+
+void
+test02()
+{
+ std::ratio_multiply<std::ratio<-INTMAX_MAX, 2>, std::ratio<3, 2>>::type r1;
+ std::ratio_multiply<std::ratio<INTMAX_MAX>, std::ratio<INTMAX_MAX>>::type r2;
+}
+
+// { dg-error "instantiated from here" "" { target *-*-* } 30 }
+// { dg-error "instantiated from here" "" { target *-*-* } 36 }
+// { dg-error "instantiated from here" "" { target *-*-* } 37 }
+// { dg-error "overflow in addition" "" { target *-*-* } 127 }
+// { dg-error "overflow in multiplication" "" { target *-*-* } 95 }
+// { dg-error "overflow in multiplication" "" { target *-*-* } 97 }
+// { dg-error "overflow in multiplication" "" { target *-*-* } 99 }
+// { dg-excess-errors "In instantiation of" }
+// { dg-excess-errors "out of range" }
diff --git a/libstdc++-v3/testsuite/20_util/time_point/1.cc b/libstdc++-v3/testsuite/20_util/time_point/1.cc
new file mode 100644
index 00000000000..70f4d7800eb
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/time_point/1.cc
@@ -0,0 +1,49 @@
+// { dg-options "-std=gnu++0x" }
+// { dg-require-cstdint "" }
+
+// Copyright (C) 2008 Free Software Foundation
+//
+// 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 2, 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 COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// 20.8.4 Class template time_point [time.point]
+
+#include <chrono>
+#include <testsuite_hooks.h>
+
+// 20.8.4.1 time_point constructors [time.point.cons]
+void
+test01()
+{
+ bool test __attribute__((unused)) = true;
+ using namespace std::chrono;
+
+ time_point<system_clock> t1;
+ VERIFY(t1.time_since_epoch() == system_clock::duration::zero());
+
+ time_point<monotonic_clock> t2;
+ VERIFY(t2.time_since_epoch() == monotonic_clock::duration::zero());
+
+ time_point<high_resolution_clock> t3;
+ VERIFY(t3.time_since_epoch() == high_resolution_clock::duration::zero());
+}
+
+int
+main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/20_util/time_point/2.cc b/libstdc++-v3/testsuite/20_util/time_point/2.cc
new file mode 100644
index 00000000000..91f21a5e0f7
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/time_point/2.cc
@@ -0,0 +1,72 @@
+// { dg-options "-std=gnu++0x" }
+// { dg-require-cstdint "" }
+
+// Copyright (C) 2008 Free Software Foundation
+//
+// 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 2, 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 COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// 20.8.4 Class template time_point [time.point]
+
+#include <chrono>
+#include <testsuite_hooks.h>
+
+// 20.8.4.3 time_point arithmetic [time.point.arithmetic]
+void
+test01()
+{
+ bool test __attribute__((unused)) = true;
+ using namespace std::chrono;
+
+ time_point<system_clock> t1, t2;
+ t1 += seconds(1);
+ VERIFY(t2.time_since_epoch() + seconds(1) == t1.time_since_epoch());
+
+ t1 -= std::chrono::seconds(1);
+ VERIFY(t2.time_since_epoch() == t1.time_since_epoch());
+}
+
+// 20.8.4.5 time_point non-member arithmetic [time.point.nonmember]
+void
+test02()
+{
+ bool test __attribute__((unused)) = true;
+ using namespace std::chrono;
+
+ time_point<system_clock> t1;
+ time_point<system_clock> t2(t1 + seconds(1));
+ VERIFY(t2.time_since_epoch() == t1.time_since_epoch() + seconds(1));
+
+ time_point<system_clock> t3(seconds(1) + t1);
+ VERIFY(t3.time_since_epoch() == t1.time_since_epoch() + seconds(1));
+
+ time_point<system_clock> t4(seconds(1));
+ time_point<system_clock> t5(seconds(2));
+
+ time_point<system_clock> t6(t5 - seconds(1));
+ VERIFY(t6.time_since_epoch() == t4.time_since_epoch());
+
+ time_point<system_clock> t7(t5 - t4);
+ VERIFY(t7.time_since_epoch() == t4.time_since_epoch());
+}
+
+int
+main()
+{
+ test01();
+ test02();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/20_util/time_point/3.cc b/libstdc++-v3/testsuite/20_util/time_point/3.cc
new file mode 100644
index 00000000000..20820cebea1
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/time_point/3.cc
@@ -0,0 +1,53 @@
+// { dg-options "-std=gnu++0x" }
+// { dg-require-cstdint "" }
+
+// Copyright (C) 2008 Free Software Foundation
+//
+// 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 2, 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 COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// 20.8.4 Class template time_point [time.point]
+
+#include <chrono>
+#include <testsuite_hooks.h>
+
+// 20.8.4.6 time_point comparisons [time.point.comparisons]
+void
+test01()
+{
+ bool test __attribute__((unused)) = true;
+ using namespace std::chrono;
+
+ time_point<system_clock> t1(seconds(1));
+ time_point<system_clock> t2(seconds(1));
+ time_point<system_clock> t3(seconds(2));
+
+ VERIFY(t1 == t2);
+ VERIFY(t1 != t3);
+ VERIFY(t1 < t3);
+ VERIFY(t1 <= t3);
+ VERIFY(t1 <= t2);
+ VERIFY(t3 > t1);
+ VERIFY(t3 >= t1);
+ VERIFY(t2 >= t1);
+}
+
+int
+main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/31_date_time/headers/date_time/std_c++0x_neg.cc b/libstdc++-v3/testsuite/20_util/time_point/requirements/explicit_instantiation/explicit_instantiation.cc
index 9b98b628c77..7f9bbdf3d16 100644
--- a/libstdc++-v3/testsuite/31_date_time/headers/date_time/std_c++0x_neg.cc
+++ b/libstdc++-v3/testsuite/20_util/time_point/requirements/explicit_instantiation/explicit_instantiation.cc
@@ -1,7 +1,8 @@
// { dg-do compile }
-// { dg-options "-std=gnu++98" }
+// { dg-options "-std=gnu++0x" }
+// { dg-require-cstdint "" }
-// Copyright (C) 2008 Free Software Foundation, Inc.
+// Copyright (C) 2008 Free Software Foundation
//
// 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
@@ -14,11 +15,11 @@
// 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 COPYING. If not, write to the Free
-// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
-// USA.
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301, USA.
-#include <date_time> // { dg-excess-errors "In file included from" }
+#include <chrono>
-// { dg-error "upcoming ISO" "" { target *-*-* } 36 }
+template class std::chrono::time_point<std::chrono::system_clock>;
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/init-list.cc b/libstdc++-v3/testsuite/21_strings/basic_string/init-list.cc
new file mode 100644
index 00000000000..71e03f1d626
--- /dev/null
+++ b/libstdc++-v3/testsuite/21_strings/basic_string/init-list.cc
@@ -0,0 +1,81 @@
+// Copyright (C) 2008 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 2, 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 COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+//
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+// { dg-options "-std=gnu++0x" }
+
+#include <string>
+#include <testsuite_hooks.h>
+
+using namespace std;
+
+int test01(void)
+{
+ bool test = true;
+
+ string s1 = { 'a', 'b', 'c' };
+ VERIFY(s1 == "abc");
+
+ s1 = { 'd', 'e', 'f' };
+ VERIFY(s1 == "def");
+
+ s1 += { 'g', 'h', 'i' };
+ VERIFY(s1 == "defghi");
+
+ s1.append({ 'j', 'k', 'l' });
+ VERIFY(s1 == "defghijkl");
+
+ s1.assign({ 'm', 'n', 'o' });
+ VERIFY(s1 == "mno");
+
+ // There aren't actually overloads of insert and replace taking size_type
+ // and initializer_list, but test the usage anyway.
+ s1.insert(2, { 'p', 'q', 'r' });
+ VERIFY(s1 == "mnpqro");
+
+ s1.replace(2, 3, { 's', 't', 'u' });
+ VERIFY(s1 == "mnstuo");
+
+ string::iterator i1, i2;
+
+ i1 = s1.begin()+2;
+ s1.insert(i1, { 'v', 'w', 'x' });
+ VERIFY(s1 == "mnvwxstuo");
+
+ i1 = s1.begin()+2;
+ i2 = i1+6;
+ s1.replace(i1, i2, { 'y', 'z' });
+ VERIFY(s1 == "mnyzo");
+
+ return test;
+}
+
+int main()
+{
+ __gnu_test::set_memory_limits();
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/22_locale/time_put/put/char/4.cc b/libstdc++-v3/testsuite/22_locale/time_put/put/char/4.cc
index 2fb6cf6ae74..c28738d742b 100644
--- a/libstdc++-v3/testsuite/22_locale/time_put/put/char/4.cc
+++ b/libstdc++-v3/testsuite/22_locale/time_put/put/char/4.cc
@@ -39,30 +39,22 @@ void test04()
// basic construction and sanity check
locale loc_c = locale::classic();
- locale loc_fr = locale("fr_FR@euro");
- VERIFY( loc_fr != loc_c );
+ locale loc_es = locale("es_ES");
+ VERIFY( loc_es != loc_c );
// create an ostream-derived object, cache the time_put facet
const string empty;
ostringstream oss;
- oss.imbue(loc_fr);
+ oss.imbue(loc_es);
const time_put<char>& tim_put = use_facet<time_put<char> >(oss.getloc());
iterator_type os_it04 = tim_put.put(oss.rdbuf(), oss, '*', &time1, 'a');
string result4 = oss.str();
-#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 7)
- VERIFY( result4 == "dim." );
-#else
- VERIFY( result4 == "dim" );
-#endif
+ VERIFY( result4 == "dom" );
- oss.str(empty); // "%d.%m.%Y"
+ oss.str(empty); // "%d/%m/%y"
iterator_type os_it27 = tim_put.put(oss.rdbuf(), oss, '*', &time1, 'x');
- string result27 = oss.str();
-#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 7)
- VERIFY( result27 == "04/04/1971" );
-#else
- VERIFY( result27 == "04.04.1971" );
-#endif
+ string result27 = oss.str(); // "04/04/71"
+ VERIFY( result27 == "04/04/71" );
oss.str(empty); // "%T"
iterator_type os_it28 = tim_put.put(oss.rdbuf(), oss, '*', &time1, 'X');
@@ -71,12 +63,8 @@ void test04()
oss.str(empty);
iterator_type os_it37 = tim_put.put(oss.rdbuf(), oss, '*', &time1, 'x', 'E');
- string result37 = oss.str();
-#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 7)
- VERIFY( result37 == "04/04/1971" );
-#else
- VERIFY( result37 == "04.04.1971" );
-#endif
+ string result37 = oss.str(); // "04/04/71"
+ VERIFY( result37 == "04/04/71" );
oss.str(empty);
iterator_type os_it38 = tim_put.put(oss.rdbuf(), oss, '*', &time1, 'X', 'E');
diff --git a/libstdc++-v3/testsuite/22_locale/time_put/put/wchar_t/4.cc b/libstdc++-v3/testsuite/22_locale/time_put/put/wchar_t/4.cc
index 09920521945..c3d312da7d7 100644
--- a/libstdc++-v3/testsuite/22_locale/time_put/put/wchar_t/4.cc
+++ b/libstdc++-v3/testsuite/22_locale/time_put/put/wchar_t/4.cc
@@ -39,30 +39,22 @@ void test04()
// basic construction and sanity check
locale loc_c = locale::classic();
- locale loc_fr = locale("fr_FR@euro");
- VERIFY( loc_fr != loc_c );
+ locale loc_es = locale("es_ES");
+ VERIFY( loc_es != loc_c );
// create an ostream-derived object, cache the time_put facet
const wstring empty;
wostringstream oss;
- oss.imbue(loc_fr);
+ oss.imbue(loc_es);
const time_put<wchar_t>& tim_put = use_facet<time_put<wchar_t> >(oss.getloc());
iterator_type os_it04 = tim_put.put(oss.rdbuf(), oss, L'*', &time1, 'a');
wstring result4 = oss.str();
-#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 7)
- VERIFY( result4 == L"dim." );
-#else
- VERIFY( result4 == L"dim" );
-#endif
+ VERIFY( result4 == L"dom" );
- oss.str(empty); // "%d.%m.%Y"
+ oss.str(empty); // "%d/%m/%y"
iterator_type os_it27 = tim_put.put(oss.rdbuf(), oss, L'*', &time1, 'x');
- wstring result27 = oss.str();
-#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 7)
- VERIFY( result27 == L"04/04/1971" );
-#else
- VERIFY( result27 == L"04.04.1971" );
-#endif
+ wstring result27 = oss.str(); // "04/04/71"
+ VERIFY( result27 == L"04/04/71" );
oss.str(empty); // "%T"
iterator_type os_it28 = tim_put.put(oss.rdbuf(), oss, L'*', &time1, 'X');
@@ -71,12 +63,8 @@ void test04()
oss.str(empty);
iterator_type os_it37 = tim_put.put(oss.rdbuf(), oss, L'*', &time1, 'x', 'E');
- wstring result37 = oss.str();
-#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 7)
- VERIFY( result37 == L"04/04/1971" );
-#else
- VERIFY( result37 == L"04.04.1971" );
-#endif
+ wstring result37 = oss.str(); // "04/04/71"
+ VERIFY( result37 == L"04/04/71" );
oss.str(empty);
iterator_type os_it38 = tim_put.put(oss.rdbuf(), oss, L'*', &time1, 'X', 'E');
diff --git a/libstdc++-v3/testsuite/23_containers/deque/init-list.cc b/libstdc++-v3/testsuite/23_containers/deque/init-list.cc
new file mode 100644
index 00000000000..715ff948732
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/deque/init-list.cc
@@ -0,0 +1,69 @@
+// Copyright (C) 2008 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 2, 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 COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+//
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+// { dg-options "-std=gnu++0x" }
+
+#include <deque>
+#include <testsuite_allocator.h>
+
+using namespace __gnu_test;
+
+int main()
+{
+ typedef std::deque<int, tracker_allocator<int> > Container;
+ const int arr10[10] = { 2, 4, 1, 7, 3, 8, 10, 5, 9, 6 };
+ bool ok = true;
+
+ tracker_allocator_counter::reset();
+ {
+ Container c({ 2, 4, 1 });
+ ok = check_construct_destroy("Construct from init-list", 3, 0) && ok;
+ ok &= (c[0] == 2);
+ ok &= (c[1] == 4);
+ }
+ ok = check_construct_destroy("Construct from init-list", 3, 3) && ok;
+
+ {
+ Container c(arr10, arr10 + 10);
+ tracker_allocator_counter::reset();
+ c.insert(c.begin() + 7, { 234, 42, 1 });
+ ok = check_construct_destroy("Insert init-list", 3, 0) && ok;
+ ok &= (c[7] == 234);
+ }
+ ok = check_construct_destroy("Insert init-list", 3, 13) && ok;
+
+ {
+ Container c;
+ tracker_allocator_counter::reset();
+ c = { 13, 0, 42 };
+ ok = check_construct_destroy("Assign init-list", 3, 0) && ok;
+ ok &= (c[0] == 13);
+ }
+ ok = check_construct_destroy("Assign init-list", 3, 3) && ok;
+
+ return ok ? 0 : 1;;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/assign_neg.cc b/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/assign_neg.cc
index 2cb464cb86c..242fc98a030 100644
--- a/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/assign_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/assign_neg.cc
@@ -19,7 +19,7 @@
// USA.
// { dg-do compile }
-// { dg-error "no matching" "" { target *-*-* } 1436 }
+// { dg-error "no matching" "" { target *-*-* } 1504 }
// { dg-excess-errors "" }
#include <deque>
diff --git a/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_1_neg.cc b/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_1_neg.cc
index 57c865f34c0..2664aac468d 100644
--- a/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_1_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_1_neg.cc
@@ -19,7 +19,7 @@
// USA.
// { dg-do compile }
-// { dg-error "no matching" "" { target *-*-* } 1375 }
+// { dg-error "no matching" "" { target *-*-* } 1443 }
// { dg-excess-errors "" }
#include <deque>
diff --git a/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_2_neg.cc b/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_2_neg.cc
index a46674c52dc..66b76b79a49 100644
--- a/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_2_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_2_neg.cc
@@ -19,7 +19,7 @@
// USA.
// { dg-do compile }
-// { dg-error "no matching" "" { target *-*-* } 1375 }
+// { dg-error "no matching" "" { target *-*-* } 1443 }
// { dg-excess-errors "" }
#include <deque>
diff --git a/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/insert_neg.cc b/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/insert_neg.cc
index 3ae748ca316..cff5332deb5 100644
--- a/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/insert_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/insert_neg.cc
@@ -19,7 +19,7 @@
// USA.
// { dg-do compile }
-// { dg-error "no matching" "" { target *-*-* } 1520 }
+// { dg-error "no matching" "" { target *-*-* } 1588 }
// { dg-excess-errors "" }
#include <deque>
diff --git a/libstdc++-v3/testsuite/23_containers/list/init-list.cc b/libstdc++-v3/testsuite/23_containers/list/init-list.cc
new file mode 100644
index 00000000000..0dd5ac919cd
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/list/init-list.cc
@@ -0,0 +1,74 @@
+// Copyright (C) 2008 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 2, 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 COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+//
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+// { dg-options "-std=gnu++0x" }
+
+#include <list>
+#include <testsuite_allocator.h>
+
+using namespace __gnu_test;
+
+int main()
+{
+ typedef std::list<int, tracker_allocator<int> > Container;
+ const int arr10[10] = { 2, 4, 1, 7, 3, 8, 10, 5, 9, 6 };
+ bool ok = true;
+
+ tracker_allocator_counter::reset();
+ {
+ Container c({ 2, 4, 1 });
+ ok = check_construct_destroy("Construct from init-list", 3, 0) && ok;
+ Container::iterator i = c.begin();
+ ok &= (*i++ == 2);
+ ok &= (*i++ == 4);
+ }
+ ok = check_construct_destroy("Construct from init-list", 3, 3) && ok;
+
+ {
+ Container c(arr10, arr10 + 10);
+ tracker_allocator_counter::reset();
+ Container::iterator i = c.begin();
+ ++i; ++i; ++i; ++i; ++i; ++i; ++i;
+ c.insert(i, { 234, 42, 1 });
+ ok = check_construct_destroy("Insert init-list", 3, 0) && ok;
+ ok &= (*--i == 1);
+ ok &= (*--i == 42);
+ }
+ ok = check_construct_destroy("Insert init-list", 3, 13) && ok;
+
+ {
+ Container c;
+ tracker_allocator_counter::reset();
+ c = { 13, 0, 42 };
+ ok = check_construct_destroy("Assign init-list", 3, 0) && ok;
+ Container::iterator i = c.begin();
+ ok &= (*i++ == 13);
+ }
+ ok = check_construct_destroy("Assign init-list", 3, 3) && ok;
+
+ return ok ? 0 : 1;;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/assign_neg.cc b/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/assign_neg.cc
index 8eeff630927..23c541a8d29 100644
--- a/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/assign_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/assign_neg.cc
@@ -19,7 +19,7 @@
// USA.
// { dg-do compile }
-// { dg-error "no matching" "" { target *-*-* } 1325 }
+// { dg-error "no matching" "" { target *-*-* } 1383 }
// { dg-excess-errors "" }
#include <list>
diff --git a/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/constructor_1_neg.cc b/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/constructor_1_neg.cc
index 06b71622421..479c416590f 100644
--- a/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/constructor_1_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/constructor_1_neg.cc
@@ -19,7 +19,7 @@
// USA.
// { dg-do compile }
-// { dg-error "no matching" "" { target *-*-* } 1294 }
+// { dg-error "no matching" "" { target *-*-* } 1352 }
// { dg-excess-errors "" }
#include <list>
diff --git a/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/constructor_2_neg.cc b/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/constructor_2_neg.cc
index bfe871077d7..3fd79856a5e 100644
--- a/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/constructor_2_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/constructor_2_neg.cc
@@ -19,7 +19,7 @@
// USA.
// { dg-do compile }
-// { dg-error "no matching" "" { target *-*-* } 1294 }
+// { dg-error "no matching" "" { target *-*-* } 1352 }
// { dg-excess-errors "" }
#include <list>
diff --git a/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/insert_neg.cc b/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/insert_neg.cc
index d75ed067e24..9b5e13a6e25 100644
--- a/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/insert_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/insert_neg.cc
@@ -19,7 +19,7 @@
// USA.
// { dg-do compile }
-// { dg-error "no matching" "" { target *-*-* } 1294 }
+// { dg-error "no matching" "" { target *-*-* } 1352 }
// { dg-excess-errors "" }
#include <list>
diff --git a/libstdc++-v3/testsuite/23_containers/map/init-list.cc b/libstdc++-v3/testsuite/23_containers/map/init-list.cc
new file mode 100644
index 00000000000..637303e1ac9
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/map/init-list.cc
@@ -0,0 +1,63 @@
+// Copyright (C) 2008 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 2, 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 COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+//
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+// { dg-options "-std=gnu++0x" }
+
+#include <map>
+#include <testsuite_hooks.h>
+
+using namespace std;
+
+int test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ map<int,double> m({ { 1, 1.0 }, { 2, 2.0 }, { 42, 237.0 } });
+ VERIFY(m.size() == 3);
+ VERIFY(m[1] == 1.0);
+ VERIFY(m[2] == 2.0);
+ VERIFY(m[42] == 237.0);
+
+ m = { {5, 55.0}, { 6, 66.0 } };
+ VERIFY(m.size() == 2);
+ VERIFY(m[5] == 55.0);
+ VERIFY(m[6] == 66.0);
+
+ m.insert({ { 7, 77.0 }, { 8, 88.0 } });
+ VERIFY(m.size() == 4);
+ VERIFY(m[5] == 55.0);
+ VERIFY(m[6] == 66.0);
+ VERIFY(m[7] == 77.0);
+ VERIFY(m[8] == 88.0);
+ return test;
+}
+
+int main()
+{
+ __gnu_test::set_memory_limits();
+ test01();
+}
diff --git a/libstdc++-v3/testsuite/23_containers/multimap/init-list.cc b/libstdc++-v3/testsuite/23_containers/multimap/init-list.cc
new file mode 100644
index 00000000000..6043cc17905
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/multimap/init-list.cc
@@ -0,0 +1,72 @@
+// Copyright (C) 2008 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 2, 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 COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+//
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+// { dg-options "-std=gnu++0x" }
+
+#include <map>
+#include <testsuite_hooks.h>
+
+using namespace std;
+
+int test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ typedef multimap<int,double> Container;
+ typedef Container::iterator iterator;
+ typedef pair<iterator,iterator> itpair;
+ Container m({ { 1, 1.0 }, { 1, 2.0 }, { 1, 237.0 } });
+ VERIFY(m.size() == 3);
+ itpair ip = m.equal_range(1);
+ VERIFY(distance(ip.first, ip.second) == 3);
+ iterator i = ip.first;
+ VERIFY((*i++).second == 1.0);
+ VERIFY((*i++).second == 2.0);
+ VERIFY((*i++).second == 237.0);
+
+ m = { {5, 55.0}, { 5, 66.0 }, { 42, 4242.0 } };
+ VERIFY(m.size() == 3);
+ ip = m.equal_range(5);
+ VERIFY(distance(ip.first, ip.second) == 2);
+ i = ip.first;
+ VERIFY((*i++).second == 55.0);
+ VERIFY((*i++).second == 66.0);
+
+ m.insert({ { 7, 77.0 }, { 7, 88.0 } });
+ VERIFY(m.size() == 5);
+ VERIFY(m.count(5) == 2);
+ VERIFY(m.count(42) == 1);
+ VERIFY(m.count(7) == 2);
+
+ return test;
+}
+
+int main()
+{
+ __gnu_test::set_memory_limits();
+ test01();
+}
diff --git a/libstdc++-v3/testsuite/23_containers/multiset/init-list.cc b/libstdc++-v3/testsuite/23_containers/multiset/init-list.cc
new file mode 100644
index 00000000000..9b34f227286
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/multiset/init-list.cc
@@ -0,0 +1,68 @@
+// Copyright (C) 2008 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 2, 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 COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+//
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+// { dg-options "-std=gnu++0x" }
+
+#include <set>
+#include <testsuite_hooks.h>
+
+using namespace std;
+
+int test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ multiset<int> m({ 1, 5, 5, 37 });
+ VERIFY(m.size() == 4);
+ VERIFY(m.count(1) == 1);
+ VERIFY(m.count(5) == 2);
+ VERIFY(m.count(37) == 1);
+ VERIFY(m.count(42) == 0);
+
+ m = { 28, 37, 37, 37, 102 };
+ VERIFY(m.size() == 5);
+ VERIFY(m.count(28) == 1);
+ VERIFY(m.count(37) == 3);
+ VERIFY(m.count(102) == 1);
+ VERIFY(m.count(1) == 0);
+
+ m.insert({ 42, 42 });
+ VERIFY(m.size() == 7);
+ VERIFY(m.count(28) == 1);
+ VERIFY(m.count(37) == 3);
+ VERIFY(m.count(102) == 1);
+ VERIFY(m.count(42) == 2);
+ VERIFY(m.count(1) == 0);
+
+ return test;
+}
+
+int main()
+{
+ __gnu_test::set_memory_limits();
+ test01();
+}
diff --git a/libstdc++-v3/testsuite/23_containers/set/init-list.cc b/libstdc++-v3/testsuite/23_containers/set/init-list.cc
new file mode 100644
index 00000000000..256ecb38aba
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/set/init-list.cc
@@ -0,0 +1,68 @@
+// Copyright (C) 2008 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 2, 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 COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+//
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+// { dg-options "-std=gnu++0x" }
+
+#include <set>
+#include <testsuite_hooks.h>
+
+using namespace std;
+
+int test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ set<int> m({ 1, 5, 37 });
+ VERIFY(m.size() == 3);
+ VERIFY(m.count(1) == 1);
+ VERIFY(m.count(5) == 1);
+ VERIFY(m.count(37) == 1);
+ VERIFY(m.count(42) == 0);
+
+ m = { 28, 37, 102 };
+ VERIFY(m.size() == 3);
+ VERIFY(m.count(28) == 1);
+ VERIFY(m.count(37) == 1);
+ VERIFY(m.count(102) == 1);
+ VERIFY(m.count(1) == 0);
+
+ m.insert({ 42 });
+ VERIFY(m.size() == 4);
+ VERIFY(m.count(28) == 1);
+ VERIFY(m.count(37) == 1);
+ VERIFY(m.count(102) == 1);
+ VERIFY(m.count(42) == 1);
+ VERIFY(m.count(1) == 0);
+
+ return test;
+}
+
+int main()
+{
+ __gnu_test::set_memory_limits();
+ test01();
+}
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_map/init-list.cc b/libstdc++-v3/testsuite/23_containers/unordered_map/init-list.cc
new file mode 100644
index 00000000000..983bf2da3b7
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/unordered_map/init-list.cc
@@ -0,0 +1,63 @@
+// Copyright (C) 2008 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 2, 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 COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+//
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+// { dg-options "-std=gnu++0x" }
+
+#include <unordered_map>
+#include <testsuite_hooks.h>
+
+using namespace std;
+
+int test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ unordered_map<int,double> m({ { 1, 1.0 }, { 2, 2.0 }, { 42, 237.0 } });
+ VERIFY(m.size() == 3);
+ VERIFY(m[1] == 1.0);
+ VERIFY(m[2] == 2.0);
+ VERIFY(m[42] == 237.0);
+
+ m = { {5, 55.0}, { 6, 66.0 } };
+ VERIFY(m.size() == 2);
+ VERIFY(m[5] == 55.0);
+ VERIFY(m[6] == 66.0);
+
+ m.insert({ { 7, 77.0 }, { 8, 88.0 } });
+ VERIFY(m.size() == 4);
+ VERIFY(m[5] == 55.0);
+ VERIFY(m[6] == 66.0);
+ VERIFY(m[7] == 77.0);
+ VERIFY(m[8] == 88.0);
+ return test;
+}
+
+int main()
+{
+ __gnu_test::set_memory_limits();
+ test01();
+}
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multimap/init-list.cc b/libstdc++-v3/testsuite/23_containers/unordered_multimap/init-list.cc
new file mode 100644
index 00000000000..ba35b38d85b
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/unordered_multimap/init-list.cc
@@ -0,0 +1,77 @@
+// Copyright (C) 2008 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 2, 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 COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+//
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+// { dg-options "-std=gnu++0x" }
+// XFAIL this test until debug mode container is fixed.
+// { dg-excess-errors "" }
+
+#include <set>
+#include <unordered_map>
+#include <testsuite_hooks.h>
+
+using namespace std;
+
+int test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ typedef unordered_multimap<int,double> Container;
+ typedef Container::const_iterator iterator;
+ typedef pair<iterator,iterator> itpair;
+
+ Container m({ { 1, 1.0 }, { 1, 2.0 }, { 1, 237.0 } });
+ VERIFY(m.size() == 3);
+ itpair ip = m.equal_range(1);
+ VERIFY(distance(ip.first, ip.second) == 3);
+ set<double> s = { 1.0, 2.0, 237.0 };
+ for (iterator i = ip.first; i != ip.second; ++i)
+ s.erase (i->second);
+ VERIFY(s.empty());
+
+ m = { {5, 55.0}, { 5, 66.0 }, { 42, 4242.0 } };
+ VERIFY(m.size() == 3);
+ ip = m.equal_range(5);
+ VERIFY(distance(ip.first, ip.second) == 2);
+ s = { 55.0, 66.0 };
+ for (iterator i = ip.first; i != ip.second; ++i)
+ s.erase (i->second);
+ VERIFY(s.empty());
+
+ m.insert({ { 7, 77.0 }, { 7, 88.0 } });
+ VERIFY(m.size() == 5);
+ VERIFY(m.count(5) == 2);
+ VERIFY(m.count(42) == 1);
+ VERIFY(m.count(7) == 2);
+
+ return test;
+}
+
+int main()
+{
+ __gnu_test::set_memory_limits();
+ test01();
+}
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multiset/init-list.cc b/libstdc++-v3/testsuite/23_containers/unordered_multiset/init-list.cc
new file mode 100644
index 00000000000..22d9a49b59f
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/unordered_multiset/init-list.cc
@@ -0,0 +1,68 @@
+// Copyright (C) 2008 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 2, 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 COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+//
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+// { dg-options "-std=gnu++0x" }
+
+#include <unordered_set>
+#include <testsuite_hooks.h>
+
+using namespace std;
+
+int test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ unordered_multiset<int> m({ 1, 5, 5, 37 });
+ VERIFY(m.size() == 4);
+ VERIFY(m.count(1) == 1);
+ VERIFY(m.count(5) == 2);
+ VERIFY(m.count(37) == 1);
+ VERIFY(m.count(42) == 0);
+
+ m = { 28, 37, 37, 37, 102 };
+ VERIFY(m.size() == 5);
+ VERIFY(m.count(28) == 1);
+ VERIFY(m.count(37) == 3);
+ VERIFY(m.count(102) == 1);
+ VERIFY(m.count(1) == 0);
+
+ m.insert({ 42, 42 });
+ VERIFY(m.size() == 7);
+ VERIFY(m.count(28) == 1);
+ VERIFY(m.count(37) == 3);
+ VERIFY(m.count(102) == 1);
+ VERIFY(m.count(42) == 2);
+ VERIFY(m.count(1) == 0);
+
+ return test;
+}
+
+int main()
+{
+ __gnu_test::set_memory_limits();
+ test01();
+}
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_set/init-list.cc b/libstdc++-v3/testsuite/23_containers/unordered_set/init-list.cc
new file mode 100644
index 00000000000..8a4b05deebd
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/unordered_set/init-list.cc
@@ -0,0 +1,68 @@
+// Copyright (C) 2008 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 2, 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 COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+//
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+// { dg-options "-std=gnu++0x" }
+
+#include <unordered_set>
+#include <testsuite_hooks.h>
+
+using namespace std;
+
+int test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ unordered_set<int> m({ 1, 5, 37 });
+ VERIFY(m.size() == 3);
+ VERIFY(m.count(1) == 1);
+ VERIFY(m.count(5) == 1);
+ VERIFY(m.count(37) == 1);
+ VERIFY(m.count(42) == 0);
+
+ m = { 28, 37, 102 };
+ VERIFY(m.size() == 3);
+ VERIFY(m.count(28) == 1);
+ VERIFY(m.count(37) == 1);
+ VERIFY(m.count(102) == 1);
+ VERIFY(m.count(1) == 0);
+
+ m.insert({ 42 });
+ VERIFY(m.size() == 4);
+ VERIFY(m.count(28) == 1);
+ VERIFY(m.count(37) == 1);
+ VERIFY(m.count(102) == 1);
+ VERIFY(m.count(42) == 1);
+ VERIFY(m.count(1) == 0);
+
+ return test;
+}
+
+int main()
+{
+ __gnu_test::set_memory_limits();
+ test01();
+}
diff --git a/libstdc++-v3/testsuite/23_containers/vector/init-list.cc b/libstdc++-v3/testsuite/23_containers/vector/init-list.cc
new file mode 100644
index 00000000000..9a3b52c27da
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/vector/init-list.cc
@@ -0,0 +1,69 @@
+// Copyright (C) 2008 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 2, 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 COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+//
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+// { dg-options "-std=gnu++0x" }
+
+#include <vector>
+#include <testsuite_allocator.h>
+
+using namespace __gnu_test;
+
+int main()
+{
+ typedef std::vector<int, tracker_allocator<int> > Container;
+ const int arr10[10] = { 2, 4, 1, 7, 3, 8, 10, 5, 9, 6 };
+ bool ok = true;
+
+ tracker_allocator_counter::reset();
+ {
+ Container c({ 2, 4, 1 });
+ ok = check_construct_destroy("Construct from init-list", 3, 0) && ok;
+ ok &= (c[0] == 2);
+ ok &= (c[1] == 4);
+ }
+ ok = check_construct_destroy("Construct from init-list", 3, 3) && ok;
+
+ {
+ Container c(arr10, arr10 + 10);
+ tracker_allocator_counter::reset();
+ c.insert(c.begin() + 7, { 234, 42, 1 });
+ ok = check_construct_destroy("Insert init-list", 13, 10) && ok;
+ ok &= (c[7] == 234);
+ }
+ ok = check_construct_destroy("Insert init-list", 13, 23) && ok;
+
+ {
+ Container c;
+ tracker_allocator_counter::reset();
+ c = { 13, 0, 42 };
+ ok = check_construct_destroy("Assign init-list", 3, 0) && ok;
+ ok &= (c[0] == 13);
+ }
+ ok = check_construct_destroy("Assign init-list", 3, 3) && ok;
+
+ return ok ? 0 : 1;;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/assign_neg.cc b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/assign_neg.cc
index 64c6a98dfb5..c5e445fa6db 100644
--- a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/assign_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/assign_neg.cc
@@ -19,7 +19,7 @@
// USA.
// { dg-do compile }
-// { dg-error "no matching" "" { target *-*-* } 986 }
+// { dg-error "no matching" "" { target *-*-* } 1058 }
// { dg-excess-errors "" }
#include <vector>
diff --git a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_1_neg.cc b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_1_neg.cc
index 34e602da583..dd115afd520 100644
--- a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_1_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_1_neg.cc
@@ -19,7 +19,7 @@
// USA.
// { dg-do compile }
-// { dg-error "no matching" "" { target *-*-* } 926 }
+// { dg-error "no matching" "" { target *-*-* } 998 }
// { dg-excess-errors "" }
#include <vector>
diff --git a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_2_neg.cc b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_2_neg.cc
index f1af46c43a2..50e51cb8f3f 100644
--- a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_2_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_2_neg.cc
@@ -19,7 +19,7 @@
// USA.
// { dg-do compile }
-// { dg-error "no matching" "" { target *-*-* } 926 }
+// { dg-error "no matching" "" { target *-*-* } 998 }
// { dg-excess-errors "" }
#include <vector>
diff --git a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/insert_neg.cc b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/insert_neg.cc
index a95f57857d8..31642d75c5d 100644
--- a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/insert_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/insert_neg.cc
@@ -19,7 +19,7 @@
// USA.
// { dg-do compile }
-// { dg-error "no matching" "" { target *-*-* } 1027 }
+// { dg-error "no matching" "" { target *-*-* } 1099 }
// { dg-excess-errors "" }
#include <vector>
diff --git a/libstdc++-v3/testsuite/25_algorithms/heap/1.cc b/libstdc++-v3/testsuite/25_algorithms/heap/1.cc
index 571a2936ed2..4032ca82e32 100644
--- a/libstdc++-v3/testsuite/25_algorithms/heap/1.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/heap/1.cc
@@ -89,8 +89,10 @@ test02()
Gt gt;
+#ifndef _GLIBCXX_DEBUG
//const int logN = static_cast<int>(std::log(static_cast<double>(N)) + 0.5);
const int logN = 3;
+#endif
int s1[N];
std::copy(A, A + N, s1);
diff --git a/libstdc++-v3/testsuite/25_algorithms/random_shuffle/1.cc b/libstdc++-v3/testsuite/25_algorithms/random_shuffle/1.cc
new file mode 100644
index 00000000000..4c5836b2e70
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/random_shuffle/1.cc
@@ -0,0 +1,75 @@
+// Copyright (C) 2001 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 2, 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 COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// 25.2.11 random_shuffle()
+
+#include <algorithm>
+#include <testsuite_hooks.h>
+
+bool test __attribute__((unused)) = true;
+
+const int N = 200000;
+int A[N], s1[N];
+
+#if _GLIBCXX_PARALLEL
+#define TAG , __gnu_parallel::sequential_tag()
+#else
+#define TAG
+#endif
+
+void fill_ascending()
+{
+ for (int i = 0; i < N; ++i)
+ A[i] = i;
+}
+
+void
+test01()
+{
+ fill_ascending();
+#if _GLIBCXX_PARALLEL
+ for (int num_threads = 1; num_threads <= 2; ++num_threads)
+ {
+ omp_set_num_threads(num_threads);
+#endif
+ std::copy(A, A + N, s1);
+ VERIFY(std::equal(s1, s1 + N, A TAG));
+
+ std::random_shuffle(s1, s1 + N);
+ // the chance that random_shuffle leaves the order as is by coincidence
+ // is negligible, so we expect it to be permuted
+ VERIFY(!std::equal(s1, s1 + N, A TAG));
+
+ std::sort(s1, s1 + N TAG);
+ VERIFY(std::equal(s1, s1 + N, A TAG));
+#if _GLIBCXX_PARALLEL
+ }
+#endif
+}
+
+int
+main()
+{
+#if _GLIBCXX_PARALLEL
+ __gnu_parallel::_Settings gpms = __gnu_parallel::_Settings::get();
+ gpms.algorithm_strategy = __gnu_parallel::force_parallel;
+ __gnu_parallel::_Settings::set(gpms);
+#endif
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/src/date_time.cc b/libstdc++-v3/testsuite/26_numerics/valarray/init-list.cc
index 0286917b779..3f4ed5bab3a 100644
--- a/libstdc++-v3/src/date_time.cc
+++ b/libstdc++-v3/testsuite/26_numerics/valarray/init-list.cc
@@ -5,17 +5,17 @@
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2, 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 COPYING. If not, write to the Free
// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
// USA.
-
+//
// As a special exception, you may use this file as part of a free software
// library without restriction. Specifically, if other files instantiate
// templates or use macros or inline functions from this file, or you compile
@@ -25,22 +25,34 @@
// invalidate any other reasons why the executable file might be covered by
// the GNU General Public License.
-#include <date_time>
+// { dg-options "-std=gnu++0x" }
+
+#include <valarray>
+#include <testsuite_hooks.h>
+
+using namespace std;
+
+int test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ valarray<int> m({ 1, 5, 37 });
+ VERIFY(m.size() == 3);
+ VERIFY(m[0] == 1);
+ VERIFY(m[1] == 5);
+ VERIFY(m[2] == 37);
+
+ m = { 28, 37, 102 };
+ VERIFY(m.size() == 3);
+ VERIFY(m[0] == 28);
+ VERIFY(m[1] == 37);
+ VERIFY(m[2] == 102);
+
+ return test;
+}
-namespace std
+int main()
{
- system_time
- get_system_time()
- {
- std::time_t sec = std::time(0);
- return system_time(sec);
- }
-
- const nanoseconds::tick_type nanoseconds::ticks_per_second;
- const nanoseconds::tick_type nanoseconds::seconds_per_tick;
- const bool nanoseconds::is_subsecond;
-
- const system_time::tick_type system_time::ticks_per_second;
- const system_time::tick_type system_time::seconds_per_tick;
- const bool system_time::is_subsecond;
+ __gnu_test::set_memory_limits();
+ test01();
}
diff --git a/libstdc++-v3/testsuite/28_regex/init-list.cc b/libstdc++-v3/testsuite/28_regex/init-list.cc
new file mode 100644
index 00000000000..6852507ee0e
--- /dev/null
+++ b/libstdc++-v3/testsuite/28_regex/init-list.cc
@@ -0,0 +1,58 @@
+// Copyright (C) 2008 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 2, 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 COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+//
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+// { dg-options "-std=gnu++0x" }
+
+#include <regex>
+#include <testsuite_hooks.h>
+
+using namespace std;
+
+int test01(void)
+{
+ bool test = true;
+
+ regex r = { 'a', 'b', 'c' };
+ cmatch res;
+ // Enable when regex class actually implemented.
+ // VERIFY(regex_match ("abc", res, r));
+ VERIFY(!regex_match ("ab", res, r));
+
+ r = { 'd', 'e', 'f' };
+ // Enable when regex class actually implemented.
+ // VERIFY(regex_match ("def", res, r));
+ VERIFY(!regex_match ("abc", res, r));
+
+ return test;
+}
+
+int main()
+{
+ __gnu_test::set_memory_limits();
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/30_threads/mutex/cons/assign_neg.cc b/libstdc++-v3/testsuite/30_threads/mutex/cons/assign_neg.cc
index f365d1167c1..8c66bb53cd7 100644
--- a/libstdc++-v3/testsuite/30_threads/mutex/cons/assign_neg.cc
+++ b/libstdc++-v3/testsuite/30_threads/mutex/cons/assign_neg.cc
@@ -39,4 +39,4 @@ void test01()
m1 = m2;
}
// { dg-error "within this context" "" { target *-*-* } 39 }
-// { dg-error "is private" "" { target *-*-* } 102 }
+// { dg-error "is private" "" { target *-*-* } 108 }
diff --git a/libstdc++-v3/testsuite/30_threads/mutex/cons/copy_neg.cc b/libstdc++-v3/testsuite/30_threads/mutex/cons/copy_neg.cc
index d0a91025b54..666506a36b1 100644
--- a/libstdc++-v3/testsuite/30_threads/mutex/cons/copy_neg.cc
+++ b/libstdc++-v3/testsuite/30_threads/mutex/cons/copy_neg.cc
@@ -38,4 +38,4 @@ void test01()
mutex_type m2(m1);
}
// { dg-error "within this context" "" { target *-*-* } 38 }
-// { dg-error "is private" "" { target *-*-* } 101 }
+// { dg-error "is private" "" { target *-*-* } 107 }
diff --git a/libstdc++-v3/testsuite/30_threads/recursive_mutex/cons/assign_neg.cc b/libstdc++-v3/testsuite/30_threads/recursive_mutex/cons/assign_neg.cc
index ca399742287..b7e27847667 100644
--- a/libstdc++-v3/testsuite/30_threads/recursive_mutex/cons/assign_neg.cc
+++ b/libstdc++-v3/testsuite/30_threads/recursive_mutex/cons/assign_neg.cc
@@ -39,4 +39,4 @@ void test01()
m1 = m2;
}
// { dg-error "within this context" "" { target *-*-* } 39 }
-// { dg-error "is private" "" { target *-*-* } 155 }
+// { dg-error "is private" "" { target *-*-* } 160 }
diff --git a/libstdc++-v3/testsuite/30_threads/recursive_mutex/cons/copy_neg.cc b/libstdc++-v3/testsuite/30_threads/recursive_mutex/cons/copy_neg.cc
index 7f530c36e38..2d20cb98c3d 100644
--- a/libstdc++-v3/testsuite/30_threads/recursive_mutex/cons/copy_neg.cc
+++ b/libstdc++-v3/testsuite/30_threads/recursive_mutex/cons/copy_neg.cc
@@ -38,4 +38,4 @@ void test01()
mutex_type m2(m1);
}
// { dg-error "within this context" "" { target *-*-* } 38 }
-// { dg-error "is private" "" { target *-*-* } 154 }
+// { dg-error "is private" "" { target *-*-* } 159 }
diff --git a/libstdc++-v3/testsuite/31_date_time/headers/date_time/synopsis.cc b/libstdc++-v3/testsuite/31_date_time/headers/date_time/synopsis.cc
deleted file mode 100644
index e86c9b784bf..00000000000
--- a/libstdc++-v3/testsuite/31_date_time/headers/date_time/synopsis.cc
+++ /dev/null
@@ -1,70 +0,0 @@
-// { dg-do compile }
-// { dg-options "-std=gnu++0x" }
-
-// Copyright (C) 2008 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 2, 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 COPYING. If not, write to the Free
-// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
-// USA.
-
-#include <date_time>
-
-namespace std {
- // duration types
- class nanoseconds;
- class microseconds;
- class milliseconds;
- class seconds;
- class minutes;
- class hours;
-
- // timepoint type
- class system_time;
-
- // non-member functions
- system_time get_system_time();
-
- template<typename Duration>
- system_time operator+(const Duration& td, const system_time& rhs);
-
- template <class LhsDuration, class RhsDuration>
- bool operator==(const LhsDuration& lhs, const RhsDuration& rhs);
- template <class LhsDuration, class RhsDuration>
- bool operator!=(const LhsDuration& lhs, const RhsDuration& rhs);
-
- template <class LhsDuration, class RhsDuration>
- bool operator< (const LhsDuration& lhs, const RhsDuration& rhs);
- template <class LhsDuration, class RhsDuration>
- bool operator<=(const LhsDuration& lhs, const RhsDuration& rhs);
- template <class LhsDuration, class RhsDuration>
- bool operator> (const LhsDuration& lhs, const RhsDuration& rhs);
- template <class LhsDuration, class RhsDuration>
- bool operator>=(const LhsDuration& lhs, const RhsDuration& rhs);
-
-/*
- template <class LhsDuration, class RhsDuration>
- FinestDuration operator+(const LhsDuration& lhs, const RhsDuration& rhs);
- template <class LhsDuration, class RhsDuration>
- FinestDuration operator-(const LhsDuration& lhs, const RhsDuration& rhs);
-*/
-
- template <class Duration>
- Duration operator*(Duration lhs, long rhs);
- template <class Duration>
- Duration operator*(long lhs, Duration rhs);
-
- template <class Duration>
- Duration operator/(Duration lhs, long rhs);
-}
diff --git a/libstdc++-v3/testsuite/31_date_time/system_time/requirements/traits.cc b/libstdc++-v3/testsuite/31_date_time/system_time/requirements/traits.cc
deleted file mode 100644
index 0310333a620..00000000000
--- a/libstdc++-v3/testsuite/31_date_time/system_time/requirements/traits.cc
+++ /dev/null
@@ -1,33 +0,0 @@
-// { dg-do compile }
-// { dg-options "-std=gnu++0x" }
-
-// Copyright (C) 2008 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 2, 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 COPYING. If not, write to the Free
-// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
-// USA.
-
-#include <date_time>
-
-namespace gnu
-{
- void
- test_system_time_traits()
- {
- static_assert(std::nanoseconds::ticks_per_second == std::nanoseconds::ticks_per_second, "FIXME");
- static_assert(std::system_time::seconds_per_tick == 0, "FIXME");
- static_assert(std::system_time::is_subsecond == true, "FIXME");
- }
-}
diff --git a/libstdc++-v3/testsuite/31_date_time/headers/date_time/functions_std.cc b/libstdc++-v3/testsuite/ext/rope/36832.cc
index 49b4ecac83b..93acfa122bf 100644
--- a/libstdc++-v3/testsuite/31_date_time/headers/date_time/functions_std.cc
+++ b/libstdc++-v3/testsuite/ext/rope/36832.cc
@@ -1,6 +1,3 @@
-// { dg-do compile }
-// { dg-options "-std=gnu++0x" }
-
// Copyright (C) 2008 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
@@ -19,9 +16,21 @@
// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
// USA.
-#include <date_time>
+// rope (SGI extension)
+
+#include <ext/rope>
+
+// libstdc++/36832
+void test01()
+{
+ __gnu_cxx::crope myRope;
+ myRope = "1234567890";
+ char buffer[100];
+ myRope.copy(1, 1, buffer);
+}
-namespace gnu
+int main()
{
- using std::get_system_time;
+ test01();
+ return 0;
}
diff --git a/libstdc++-v3/testsuite/ext/vstring/init-list.cc b/libstdc++-v3/testsuite/ext/vstring/init-list.cc
new file mode 100644
index 00000000000..27da6828193
--- /dev/null
+++ b/libstdc++-v3/testsuite/ext/vstring/init-list.cc
@@ -0,0 +1,79 @@
+// Copyright (C) 2008 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 2, 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 COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+//
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+// { dg-options "-std=gnu++0x" }
+
+#include <ext/vstring.h>
+#include <testsuite_hooks.h>
+
+int test01(void)
+{
+ bool test = true;
+
+ __gnu_cxx::__vstring s1 = { 'a', 'b', 'c' };
+ VERIFY(s1 == "abc");
+
+ s1 = { 'd', 'e', 'f' };
+ VERIFY(s1 == "def");
+
+ s1 += { 'g', 'h', 'i' };
+ VERIFY(s1 == "defghi");
+
+ s1.append({ 'j', 'k', 'l' });
+ VERIFY(s1 == "defghijkl");
+
+ s1.assign({ 'm', 'n', 'o' });
+ VERIFY(s1 == "mno");
+
+ // There aren't actually overloads of insert and replace taking size_type
+ // and initializer_list, but test the usage anyway.
+ s1.insert(2, { 'p', 'q', 'r' });
+ VERIFY(s1 == "mnpqro");
+
+ s1.replace(2, 3, { 's', 't', 'u' });
+ VERIFY(s1 == "mnstuo");
+
+ __gnu_cxx::__vstring::iterator i1, i2;
+
+ i1 = s1.begin()+2;
+ s1.insert(i1, { 'v', 'w', 'x' });
+ VERIFY(s1 == "mnvwxstuo");
+
+ i1 = s1.begin()+2;
+ i2 = i1+6;
+ s1.replace(i1, i2, { 'y', 'z' });
+ VERIFY(s1 == "mnyzo");
+
+ return test;
+}
+
+int main()
+{
+ __gnu_test::set_memory_limits();
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/lib/dg-options.exp b/libstdc++-v3/testsuite/lib/dg-options.exp
index 327b691fc0f..e2d22ae598b 100644
--- a/libstdc++-v3/testsuite/lib/dg-options.exp
+++ b/libstdc++-v3/testsuite/lib/dg-options.exp
@@ -88,3 +88,12 @@ proc dg-require-rvalref { args } {
}
return
}
+
+proc dg-require-cstdint { args } {
+ if { ![ check_v3_target_cstdint ] } {
+ upvar dg-do-what dg-do-what
+ set dg-do-what [list [lindex ${dg-do-what} 0] "N" "P"]
+ return
+ }
+ return
+}
diff --git a/libstdc++-v3/testsuite/lib/libstdc++.exp b/libstdc++-v3/testsuite/lib/libstdc++.exp
index d6b372b80ef..29258c35b4c 100644
--- a/libstdc++-v3/testsuite/lib/libstdc++.exp
+++ b/libstdc++-v3/testsuite/lib/libstdc++.exp
@@ -1,6 +1,6 @@
# libstdc++ "tool init file" for DejaGNU
-# Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+# Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
# Free Software Foundation, Inc.
#
# This program is free software; you can redistribute it and/or modify
@@ -687,7 +687,7 @@ proc check_v3_target_c_std { } {
puts $f " int i = std::tr1::isnan(f);"
puts $f " "
puts $f " using std::wctomb;"
- puts $f " return 0;"
+ puts $f " return i;"
puts $f "}"
close $f
@@ -939,7 +939,7 @@ proc check_v3_target_debug_mode { } {
} else {
set et_debug_mode 0
- # Set up, compile, and execute a C++ test program that depends
+ # Set up and compile a C++ test program that depends
# on debug mode working.
set src debug_mode[pid].cc
set exe debug_mode[pid].exe
@@ -993,7 +993,7 @@ proc check_v3_target_parallel_mode { } {
} else {
set et_parallel_mode 0
- # Set up, compile, and execute a C++ test program that depends
+ # Set up and compile a C++ test program that depends
# on parallel mode working.
set src parallel_mode[pid].cc
set exe parallel_mode[pid].exe
@@ -1021,3 +1021,61 @@ proc check_v3_target_parallel_mode { } {
verbose "check_v3_target_parallel_mode: $et_parallel_mode" 2
return $et_parallel_mode
}
+
+proc check_v3_target_cstdint { } {
+ global cxxflags
+ global DEFAULT_CXXFLAGS
+ global et_cstdint
+
+ global tool
+
+ if { ![info exists et_cstdint_target_name] } {
+ set et_cstdint_target_name ""
+ }
+
+ # If the target has changed since we set the cached value, clear it.
+ set current_target [current_target_name]
+ if { $current_target != $et_cstdint_target_name } {
+ verbose "check_v3_target_cstdint: `$et_cstdint_target_name'" 2
+ set et_cstdint_target_name $current_target
+ if [info exists et_cstdint] {
+ verbose "check_v3_target_cstdint: removing cached result" 2
+ unset et_cstdint
+ }
+ }
+
+ if [info exists et_cstdint] {
+ verbose "check_v3_target_cstdint: using cached result" 2
+ } else {
+ set et_cstdint 0
+
+ # Set up and compile a C++0x test program that depends
+ # on the C99 stdint facilities to be available.
+ set src cstdint[pid].cc
+ set exe cstdint[pid].exe
+
+ set f [open $src "w"]
+ puts $f "#include <cstdint>"
+ puts $f "int main()"
+ puts $f "#ifdef _GLIBCXX_USE_C99_STDINT_TR1"
+ puts $f "{ return 0; }"
+ puts $f "#endif"
+ close $f
+
+ set cxxflags_saved $cxxflags
+ set cxxflags "$cxxflags $DEFAULT_CXXFLAGS -std=gnu++0x -Werror"
+
+ set lines [v3_target_compile $src $exe executable ""]
+ set cxxflags $cxxflags_saved
+ file delete $src
+
+ if [string match "" $lines] {
+ # No error message, compilation succeeded.
+ set et_cstdint 1
+ } else {
+ verbose "check_v3_target_cstdint: compilation failed" 2
+ }
+ }
+ verbose "check_v3_target_cstdint: $et_cstdint" 2
+ return $et_cstdint
+}
diff --git a/libstdc++-v3/testsuite/util/testsuite_abi.cc b/libstdc++-v3/testsuite/util/testsuite_abi.cc
index 6466fbabcd8..c15b8b24447 100644
--- a/libstdc++-v3/testsuite/util/testsuite_abi.cc
+++ b/libstdc++-v3/testsuite/util/testsuite_abi.cc
@@ -199,6 +199,7 @@ check_version(symbol& test, bool added)
known_versions.push_back("CXXABI_1.3");
known_versions.push_back("CXXABI_1.3.1");
known_versions.push_back("CXXABI_1.3.2");
+ known_versions.push_back("CXXABI_1.3.3");
known_versions.push_back("CXXABI_LDBL_1.3");
}
compat_list::iterator begin = known_versions.begin();
diff --git a/maintainer-scripts/ChangeLog b/maintainer-scripts/ChangeLog
index aaa34965ac9..f246a012cf5 100644
--- a/maintainer-scripts/ChangeLog
+++ b/maintainer-scripts/ChangeLog
@@ -1,3 +1,13 @@
+2008-07-04 Joseph Myers <joseph@codesourcery.com>
+
+ * crontab: Remove 4.1 snapshots job.
+ * update_version: Remove.
+ * gcc_release: Remove support for g77 and release status in
+ version.c.
+ * update_version_svn: Ignore 4.1 branch. Remove support for
+ updating files other than DATESTAMP.
+ * update_web_docs_svn: Remove support for g77 manual.
+
2008-02-18 Jakub Jelinek <jakub@redhat.com>
* crontab: Add 4.3 branch. Set trunk to 4.4.
diff --git a/maintainer-scripts/crontab b/maintainer-scripts/crontab
index 6ccf62db2ae..091c24d8249 100644
--- a/maintainer-scripts/crontab
+++ b/maintainer-scripts/crontab
@@ -1,7 +1,6 @@
16 0 * * * sh /home/gccadmin/scripts/update_version_svn
50 0 * * * sh /home/gccadmin/scripts/update_web_docs_svn
55 0 * * * sh /home/gccadmin/scripts/update_web_docs_libstdcxx_svn
-32 22 * * 1 sh /home/gccadmin/scripts/gcc_release -s 4.1:branches/gcc-4_1-branch -l -d /sourceware/snapshot-tmp/gcc all
32 22 * * 3 sh /home/gccadmin/scripts/gcc_release -s 4.2:branches/gcc-4_2-branch -l -d /sourceware/snapshot-tmp/gcc all
32 22 * * 4 sh /home/gccadmin/scripts/gcc_release -s 4.3:branches/gcc-4_3-branch -l -d /sourceware/snapshot-tmp/gcc all
32 22 * * 5 sh /home/gccadmin/scripts/gcc_release -s 4.4:trunk -l -d /sourceware/snapshot-tmp/gcc all
diff --git a/maintainer-scripts/gcc_release b/maintainer-scripts/gcc_release
index bacb25b0ceb..467ec4e4aca 100755
--- a/maintainer-scripts/gcc_release
+++ b/maintainer-scripts/gcc_release
@@ -139,25 +139,14 @@ EOF
fi
done
- # Update gcc/DEV-PHASE if it exists, otherwise gcc/version.c.
-
- if [ -f ${SOURCE_DIRECTORY}/gcc/DEV-PHASE ]; then
- [ `cat ${SOURCE_DIRECTORY}/gcc/BASE-VER` = ${RELEASE} ] || \
- error "Release number ${RELEASE} does not match BASE-VER"
- (changedir ${SOURCE_DIRECTORY}/gcc && \
- : > DEV-PHASE && \
- ${SVN} -q ci -m 'Mark as release' DEV-PHASE) || \
- error "Could not update DEV-PHASE"
- else
- for x in gcc/version.c; do
- y=`basename ${x}`
- (changedir `dirname ${SOURCE_DIRECTORY}/${x}` && \
- sed -e 's|version_string\[\] = \".*\"|version_string\[\] = \"'${RELEASE}'\"|g' < ${y} > ${y}.new && \
- mv ${y}.new ${y} && \
- ${SVN} -q ci -m 'Update version' ${y}) || \
- error "Could not update ${x}"
- done
- fi
+ # Update gcc/DEV-PHASE.
+
+ [ `cat ${SOURCE_DIRECTORY}/gcc/BASE-VER` = ${RELEASE} ] || \
+ error "Release number ${RELEASE} does not match BASE-VER"
+ (changedir ${SOURCE_DIRECTORY}/gcc && \
+ : > DEV-PHASE && \
+ ${SVN} -q ci -m 'Mark as release' DEV-PHASE) || \
+ error "Could not update DEV-PHASE"
# Make sure we tag the sources for a final release.
TAG="tags/gcc_`echo ${RELEASE} | tr . _`_release"
@@ -297,7 +286,6 @@ build_tarfiles() {
# Now, build one for each of the languages.
maybe_build_tarfile gcc-ada-${RELEASE} ${ADA_DIRS}
maybe_build_tarfile gcc-g++-${RELEASE} ${CPLUSPLUS_DIRS}
- maybe_build_tarfile gcc-g77-${RELEASE} ${FORTRAN_DIRS}
maybe_build_tarfile gcc-fortran-${RELEASE} ${FORTRAN95_DIRS}
maybe_build_tarfile gcc-java-${RELEASE} ${JAVA_DIRS}
maybe_build_tarfile gcc-objc-${RELEASE} ${OBJECTIVEC_DIRS}
@@ -305,7 +293,7 @@ build_tarfiles() {
# The core is everything else.
EXCLUDES=""
- for x in ${ADA_DIRS} ${CPLUSPLUS_DIRS} ${FORTRAN_DIRS} ${FORTRAN95_DIRS}\
+ for x in ${ADA_DIRS} ${CPLUSPLUS_DIRS} ${FORTRAN95_DIRS}\
${JAVA_DIRS} ${OBJECTIVEC_DIRS} ${TESTSUITE_DIRS}; do
EXCLUDES="${EXCLUDES} --exclude $x"
done
@@ -328,7 +316,7 @@ build_diffs() {
old_vers=${old_file%.tar.bz2}
old_vers=${old_vers#gcc-}
inform "Building diffs against version $old_vers"
- for f in gcc gcc-ada gcc-g++ gcc-g77 gcc-fortran gcc-java gcc-objc gcc-testsuite gcc-core; do
+ for f in gcc gcc-ada gcc-g++ gcc-fortran gcc-java gcc-objc gcc-testsuite gcc-core; do
old_tar=${old_dir}/${f}-${old_vers}.tar.bz2
new_tar=${WORKING_DIRECTORY}/${f}-${RELEASE}.tar.bz2
if [ ! -e $old_tar ]; then
@@ -453,7 +441,6 @@ with the following options: <code>"svn://gcc.gnu.org/svn/gcc/${SVNBRANCH} revisi
snapshot_print gcc-ada-${RELEASE}.tar.bz2 "Ada front end and runtime"
snapshot_print gcc-fortran-${RELEASE}.tar.bz2 "Fortran front end and runtime"
snapshot_print gcc-g++-${RELEASE}.tar.bz2 "C++ front end and runtime"
- snapshot_print gcc-g77-${RELEASE}.tar.bz2 "Fortran 77 front end and runtime"
snapshot_print gcc-java-${RELEASE}.tar.bz2 "Java front end and runtime"
snapshot_print gcc-objc-${RELEASE}.tar.bz2 "Objective-C front end and runtime"
snapshot_print gcc-testsuite-${RELEASE}.tar.bz2 "The GCC testsuite"
@@ -560,7 +547,6 @@ SOURCE_DIRECTORY=""
# tar files. These are all relative to the top of the source tree.
ADA_DIRS="gcc/ada libada gnattools"
CPLUSPLUS_DIRS="gcc/cp libstdc++-v3"
-FORTRAN_DIRS="gcc/f libf2c"
FORTRAN95_DIRS="gcc/fortran libgfortran"
JAVA_DIRS="gcc/java libjava libffi fastjar zlib boehm-gc"
OBJECTIVEC_DIRS="gcc/objc gcc/objcp libobjc"
@@ -707,7 +693,6 @@ SOURCE_DIRECTORY="${WORKING_DIRECTORY}/gcc-${RELEASE}"
# relative to the WORKING_DIRECTORY.
ADA_DIRS=`adjust_dirs ${ADA_DIRS}`
CPLUSPLUS_DIRS=`adjust_dirs ${CPLUSPLUS_DIRS}`
-FORTRAN_DIRS=`adjust_dirs ${FORTRAN_DIRS}`
FORTRAN95_DIRS=`adjust_dirs ${FORTRAN95_DIRS}`
JAVA_DIRS=`adjust_dirs ${JAVA_DIRS}`
OBJECTIVEC_DIRS=`adjust_dirs ${OBJECTIVEC_DIRS}`
diff --git a/maintainer-scripts/update_version b/maintainer-scripts/update_version
deleted file mode 100755
index 2217052332c..00000000000
--- a/maintainer-scripts/update_version
+++ /dev/null
@@ -1,113 +0,0 @@
-#!/bin/sh
-#
-# Update the current version date in all files in the tree containing
-# it. Consider all release branches except those matching the regular
-# expression in $IGNORE_BRANCHES, and also consider those branches listed
-# in $ADD_BRANCHES.
-
-CVSROOT=${CVSROOT:-/cvs/gcc}
-IGNORE_BRANCHES='gcc-(2_95|3_0|3_1|3_2|3_3)-branch'
-ADD_BRANCHES='HEAD autovect-branch dfp-branch'
-
-# Run this from /tmp.
-export CVSROOT
-/bin/rm -rf /tmp/$$
-/bin/mkdir /tmp/$$
-cd /tmp/$$
-
-# The path to cvs.
-CVS=${CVS:-/usr/local/bin/cvs}
-
-# Compute the branches which we should update.
-$CVS co gcc/ChangeLog
-BRANCHES=`$CVS status -v gcc/ChangeLog \
- | awk '{print $1;}' \
- | egrep 'gcc-[0-9]+_[0-9]+-branch$' \
- | egrep -v $IGNORE_BRANCHES`
-# Always update the mainline.
-BRANCHES="${BRANCHES} ${ADD_BRANCHES}"
-
-# ARGS is passed to 'cvs co'
-CURR_DATE=`/bin/date +"%Y%m%d"`
-
-# version is contained within a char*
-textstring_FILES="gcc/gcc/version.c"
-
-# version is contained within a #define
-cppdefine_FILES="gcc/libstdc++-v3/include/bits/c++config"
-
-# version is all there is
-datestamp_FILES="gcc/gcc/DATESTAMP"
-
-FILES="$textstring_FILES $cppdefine_FILES $datestamp_FILES"
-
-# Assume all will go well.
-RESULT=0
-
-for BRANCH in $BRANCHES; do
- echo "Working on \"$BRANCH\"."
- # Check out the files on the branch. HEAD is a special case; if
- # you check out files with -r HEAD, CVS will not let you check
- # in changes.
- if test "$BRANCH" = HEAD; then
- ${CVS} co $FILES
- else
- ${CVS} co -r $BRANCH $FILES
- fi
-
- # There are no files to commit yet.
- COMMIT_FILES=""
-
- for file in $textstring_FILES; do
- if test -f $file; then
- /bin/sed <$file >$file.new -e \
- "s/\(.*\"[^ ]*\) [0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]/\1 ${CURR_DATE}/"
-
- if /usr/bin/cmp -s $file $file.new; then
- rm -f $file.new
- else
- mv -f $file.new $file
- COMMIT_FILES="$COMMIT_FILES $file"
- fi
- fi
- done
-
- for file in $cppdefine_FILES; do
- if test -f $file; then
- /bin/sed <$file >$file.new -e \
- "s/\(#.*\) [0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]/\1 ${CURR_DATE}/"
-
- if /usr/bin/cmp -s $file $file.new; then
- rm -f $file.new
- else
- mv -f $file.new $file
- COMMIT_FILES="$COMMIT_FILES $file"
- fi
- fi
- done
-
- for file in $datestamp_FILES; do
- if test -f $file; then
- echo ${CURR_DATE} > $file.new
-
- if /usr/bin/cmp -s $file $file.new; then
- rm -f $file.new
- else
- mv -f $file.new $file
- COMMIT_FILES="$COMMIT_FILES $file"
- fi
- fi
- done
-
- if test -n "$COMMIT_FILES" \
- && ! ${CVS} commit -m "Daily bump." $COMMIT_FILES; then
- # If we could not commit the files, indicate failure.
- RESULT=1
- fi
-
- # Remove the files.
- rm -rf gcc
-done
-
-/bin/rm -rf /tmp/$$
-exit $RESULT
diff --git a/maintainer-scripts/update_version_svn b/maintainer-scripts/update_version_svn
index ba47687cd4f..1c87f1c50e9 100755
--- a/maintainer-scripts/update_version_svn
+++ b/maintainer-scripts/update_version_svn
@@ -6,7 +6,7 @@
# in $ADD_BRANCHES.
SVNROOT=${SVNROOT:-"file:///svn/gcc"}
-IGNORE_BRANCHES='gcc-(2_95|3_0|3_1|3_2|3_3|3_4|4_0)-branch'
+IGNORE_BRANCHES='gcc-(2_95|3_0|3_1|3_2|3_3|3_4|4_0|4_1)-branch'
ADD_BRANCHES='HEAD autovect-branch'
# Run this from /tmp.
@@ -29,17 +29,10 @@ BRANCHES="${BRANCHES} ${ADD_BRANCHES}"
# ARGS is passed to 'cvs co'
CURR_DATE=`/bin/date +"%Y%m%d"`
-# version is contained within a char*
-textstring_FILES="gcc/version.c"
-
-# version is contained within a #define
-cppdefine_FILES="libstdc++-v3/include/bits/c++config"
-
# version is all there is
datestamp_FILES="gcc/DATESTAMP"
-FILES="$textstring_FILES $cppdefine_FILES $datestamp_FILES"
-DIRS="$textstring_DIRS $cppdefine_DIRS $datestamp_DIRS"
+FILES="$datestamp_FILES"
# Assume all will go well.
RESULT=0
@@ -60,40 +53,6 @@ for BRANCH in $BRANCHES; do
# There are no files to commit yet.
COMMIT_FILES=""
-
- for file in $textstring_FILES; do
- dirname=`basename $file`
- file=`basename $file`
- file="$dirname/$file"
- if test -f $file; then
- /bin/sed <$file >$file.new -e \
- "s/\(.*\"[^ ]*\) [0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]/\1 ${CURR_DATE}/"
-
- if /usr/bin/cmp -s $file $file.new; then
- rm -f $file.new
- else
- mv -f $file.new $file
- COMMIT_FILES="$COMMIT_FILES $file"
- fi
- fi
- done
-
- for file in $cppdefine_FILES; do
- dirname=`basename $file`
- file=`basename $file`
- file="$dirname/$file"
- if test -f $file; then
- /bin/sed <$file >$file.new -e \
- "s/\(#.*\) [0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]/\1 ${CURR_DATE}/"
-
- if /usr/bin/cmp -s $file $file.new; then
- rm -f $file.new
- else
- mv -f $file.new $file
- COMMIT_FILES="$COMMIT_FILES $file"
- fi
- fi
- done
for file in $datestamp_FILES; do
dirname=`basename $file`
diff --git a/maintainer-scripts/update_web_docs_svn b/maintainer-scripts/update_web_docs_svn
index 0fa9992b399..74098b4ac4d 100755
--- a/maintainer-scripts/update_web_docs_svn
+++ b/maintainer-scripts/update_web_docs_svn
@@ -17,7 +17,6 @@ MANUALS="cpp
gcc
gccint
gcj
- g77
gfortran
gfc-internals
gnat_ug_unx